From 1c8394549bd54977c207b0db92881b1de1896dd6 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 4 Aug 2020 16:41:07 +0200 Subject: [PATCH 01/90] Add barebones of user endpoint --- lib/client/client.dart | 181 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 lib/client/client.dart diff --git a/lib/client/client.dart b/lib/client/client.dart new file mode 100644 index 0000000..2488037 --- /dev/null +++ b/lib/client/client.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; + +class LemmyAPI { + /// url of this lemmy instance + String instanceUrl; + + /// JSON Web Token (https://jwt.io) + String jwt; + V1 v1; + + /// initialize lemmy api instance + LemmyAPI({@required this.instanceUrl}) + : assert(instanceUrl != null), + v1 = V1(instanceUrl); +} + +class V1 { + String instanceUrl; + UserEndpoint user; + V1(this.instanceUrl) : user = UserEndpoint(instanceUrl); +} + +class UserEndpoint { + String instanceUrl; + UserEndpoint(this.instanceUrl); + + /// POST /user/login + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login + String login({ + String usernameOrEmail, + String password, + }) { + assert(usernameOrEmail != null, password != null); + throw UnimplementedError(); + } + + /// POST /user/register + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#register + String register({ + @required String username, + String email, + String password, + }) { + throw UnimplementedError(); + } + + /// GET /user/get_captcha + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha + String getCaptcha() { + throw UnimplementedError(); + } + + /// GET /user + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details + String getDetails({ + int userId, + String username, + @required String sort, + int page, + int limit, + int communityId, + bool savedOnly, + String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /save_user_settings + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-user-settings + String updateSettings({ + @required bool showNsfw, + @required String theme, + @required int defaultSortType, + @required int defaultListingType, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /user/replies + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-replies--inbox + String getReplies({ + @required String sort, + int page, + int limit, + @required bool unreadOnly, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /user/mentions + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions + String getMentions({ + String sort, + @required int page, + @required int limit, + bool unreadOnly, + String auth, + }) { + throw UnimplementedError(); + } + + /// POST /user/mention/mark_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-user-mention-as-read + String markMentionsAsRead({ + @required int userMentionId, + @required bool read, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /private_message/list + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-private-messages + String getPrivateMessages({ + @required bool unreadOnly, + int page, + int limit, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /private_message + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-private-message + String createPrivateMessage({ + @required String content, + @required int recipientId, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /private_message + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-private-message + String updatePrivateMessage({ + @required int editId, + @required String content, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /private_message/delete + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-private-message + String deletePrivateMessage({ + @required int editId, + @required bool deleted, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /private_message/mark_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-private-message-as-read + String markPrivateMessageAsRead({ + @required int editId, + @required bool read, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /user/mark_all_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-all-as-read + String markAllPrivateMessagesAsRead({ + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /user/delete_account + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-account + String deleteAccount({ + @required String password, + @required String auth, + }) { + throw UnimplementedError(); + } +} From f75bc05a016dd0ea70c191e44beb1c43ea5b8588 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 4 Aug 2020 17:27:44 +0200 Subject: [PATCH 02/90] Add `search` and `listCategories` #6 Add endpoints for: * `GET /categories` * `POST /search` --- lib/client/client.dart | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/client/client.dart b/lib/client/client.dart index 2488037..f3927d0 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -18,6 +18,26 @@ class V1 { String instanceUrl; UserEndpoint user; V1(this.instanceUrl) : user = UserEndpoint(instanceUrl); + + /// GET /categories + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories + String listCategories() { + throw UnimplementedError(); + } + + /// POST /search + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search + String search({ + @required String q, + @required String type, + String communityId, + @required String sort, + int page, + int limit, + String auth, + }) { + throw UnimplementedError(); + } } class UserEndpoint { From a54325649f76d917985043756354ba4151b1cfab Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 4 Aug 2020 17:49:46 +0200 Subject: [PATCH 03/90] removed unneeded `jwt` variable from `LemmyAPI` --- lib/client/client.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/client/client.dart b/lib/client/client.dart index f3927d0..fab9346 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -4,8 +4,6 @@ class LemmyAPI { /// url of this lemmy instance String instanceUrl; - /// JSON Web Token (https://jwt.io) - String jwt; V1 v1; /// initialize lemmy api instance From b5e8620931164d86b91677b1da22e94e00b1e4a1 Mon Sep 17 00:00:00 2001 From: Mikwk Date: Wed, 5 Aug 2020 13:17:52 +0200 Subject: [PATCH 04/90] Implemented PostView class. Added auto generated JSON (de)serialization of PostView class by json_serializable package. Added required packages and dependencies in pubsec.yalm: - json_annotation: ^3.0.1, - json_serializable: ^3.3.0, - build_runner: ^1.10.0. TODO: Implement ParseDateFromJson static method in PostView class. --- lib/mappingClasses/post.dart | 221 ++++++++++++++++++++++ lib/mappingClasses/post.g.dart | 101 ++++++++++ pubspec.lock | 327 +++++++++++++++++++++++++++++++-- pubspec.yaml | 3 + 4 files changed, 632 insertions(+), 20 deletions(-) create mode 100644 lib/mappingClasses/post.dart create mode 100644 lib/mappingClasses/post.g.dart diff --git a/lib/mappingClasses/post.dart b/lib/mappingClasses/post.dart new file mode 100644 index 0000000..e159015 --- /dev/null +++ b/lib/mappingClasses/post.dart @@ -0,0 +1,221 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'post.g.dart'; + +@JsonSerializable() +class PostView { + PostView( + this.id, + this.postName, + this.url, + this.body, + this.creatorId, + this.communityId, + this.removed, + this.locked, + this.published, + this.updated, + this.deleted, + this.nsfw, + this.stickied, + this.embedTitle, + this.embedDescription, + this.embedHtml, + this.thumbnailUrl, + this.apId, + this.local, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPublished, + this.creatorAvatar, + this.banned, + this.bannedFromCommunity, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityRemoved, + this.communityDeleted, + this.communityNsfw, + this.numberOfComments, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.newestActivityTime, + int userId, + int myVote, + bool subscribed, + bool read, + bool saved) { + _userId = userId; + _myVote = myVote; + _subscribed = subscribed; + _read = read; + _saved = saved; + } + + //TODO: Parse date from Json. + static DateTime ParseDateFromJson(t) { + throw Exception("Not implemented exception"); + } + + @JsonKey(name: "id") + final int id; + + @JsonKey(name: "name") + final String postName; + + @JsonKey(name: "url") + final String url; + + @JsonKey(name: "body") + final String body; + + @JsonKey(name: "creator_id") + final int creatorId; + + @JsonKey(name: "community_id") + final int communityId; + + @JsonKey(name: "removed") + final bool removed; + + @JsonKey(name: "locked") + final bool locked; + + @JsonKey(name: "published", fromJson: ParseDateFromJson) + final DateTime published; + + @JsonKey(name: "updated", fromJson: ParseDateFromJson) + final DateTime updated; + + @JsonKey(name: "deleted") + final bool deleted; + + @JsonKey(name: "nsfw") + final bool nsfw; + + @JsonKey(name: "stickied") + final bool stickied; + + @JsonKey(name: "embed_title") + final String embedTitle; + + @JsonKey(name: "embed_description") + final String embedDescription; + + @JsonKey(name: "embed_html") + final String embedHtml; + + @JsonKey(name: "thumbnail_url") + final String thumbnailUrl; + + @JsonKey(name: "ap_id") + final String apId; + + @JsonKey(name: "local") + final bool local; + + @JsonKey(name: "creator_actor_id") + final String creatorActorId; + + @JsonKey(name: "creator_local") + final bool creatorLocal; + + @JsonKey(name: "creator_name") + final String creatorName; + + @JsonKey(name: "creator_published", fromJson: ParseDateFromJson) + final DateTime creatorPublished; + + @JsonKey(name: "creator_avatar") + final String creatorAvatar; + + @JsonKey(name: "banned") + final bool banned; + + @JsonKey(name: "banned_from_community") + final bool bannedFromCommunity; + + @JsonKey(name: "community_actor_id") + final String communityActorId; + + @JsonKey(name: "community_local") + final bool communityLocal; + + @JsonKey(name: "community_name") + final String communityName; + + @JsonKey(name: "community_removed") + final bool communityRemoved; + + @JsonKey(name: "community_deleted") + final bool communityDeleted; + + @JsonKey(name: "community_nsfw") + final bool communityNsfw; + + @JsonKey(name: "number_of_comments") + final int numberOfComments; + + @JsonKey(name: "score") + int score; + + @JsonKey(name: "upvotes") + int upvotes; + + @JsonKey(name: "downvotes") + int downvotes; + + @JsonKey(name: "hot_rank") + final int hotRank; + + @JsonKey(name: "newest_activity_time", fromJson: ParseDateFromJson) + final DateTime newestActivityTime; + + int get userId { + return _userId; + } + + void set userId(int userId) => _userId = userId; + @JsonKey(name: "user_id") + int _userId; + + int get myVote { + return _myVote; + } + + void set myVote(int myVote) => _myVote = myVote>0?1:myVote<0?-1:0; + @JsonKey(name: "my_vote") + int _myVote; + + bool get subscribed { + return _subscribed; + } + + void set subscribed(bool subscribed) => _subscribed = subscribed; + @JsonKey(name: "subscribed") + bool _subscribed; + + bool get read { + return _read; + } + + void set read(bool read) => _read = read; + @JsonKey(name: "read") + bool _read; + + bool get saved { + return _saved; + } + + void set saved(bool saved) => _saved = saved; + @JsonKey(name: "saved") + bool _saved; + + factory PostView.fromJson(Map json) => + _$PostViewFromJson(json); + + Map postViewToJson() => _$PostViewToJson(this); +} diff --git a/lib/mappingClasses/post.g.dart b/lib/mappingClasses/post.g.dart new file mode 100644 index 0000000..c3a6a05 --- /dev/null +++ b/lib/mappingClasses/post.g.dart @@ -0,0 +1,101 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PostView _$PostViewFromJson(Map json) { + return PostView( + json['id'] as int, + json['name'] as String, + json['url'] as String, + json['body'] as String, + json['creator_id'] as int, + json['community_id'] as int, + json['removed'] as bool, + json['locked'] as bool, + PostView.ParseDateFromJson(json['published']), + PostView.ParseDateFromJson(json['updated']), + json['deleted'] as bool, + json['nsfw'] as bool, + json['stickied'] as bool, + json['embed_title'] as String, + json['embed_description'] as String, + json['embed_html'] as String, + json['thumbnail_url'] as String, + json['ap_id'] as String, + json['local'] as bool, + json['creator_actor_id'] as String, + json['creator_local'] as bool, + json['creator_name'] as String, + PostView.ParseDateFromJson(json['creator_published']), + json['creator_avatar'] as String, + json['banned'] as bool, + json['banned_from_community'] as bool, + json['community_actor_id'] as String, + json['community_local'] as bool, + json['community_name'] as String, + json['community_removed'] as bool, + json['community_deleted'] as bool, + json['community_nsfw'] as bool, + json['number_of_comments'] as int, + json['score'] as int, + json['upvotes'] as int, + json['downvotes'] as int, + json['hot_rank'] as int, + PostView.ParseDateFromJson(json['newest_activity_time']), + json['userId'] as int, + json['myVote'] as int, + json['subscribed'] as bool, + json['read'] as bool, + json['saved'] as bool, + ); +} + +Map _$PostViewToJson(PostView instance) => { + 'id': instance.id, + 'name': instance.postName, + 'url': instance.url, + 'body': instance.body, + 'creator_id': instance.creatorId, + 'community_id': instance.communityId, + 'removed': instance.removed, + 'locked': instance.locked, + 'published': instance.published?.toIso8601String(), + 'updated': instance.updated?.toIso8601String(), + 'deleted': instance.deleted, + 'nsfw': instance.nsfw, + 'stickied': instance.stickied, + 'embed_title': instance.embedTitle, + 'embed_description': instance.embedDescription, + 'embed_html': instance.embedHtml, + 'thumbnail_url': instance.thumbnailUrl, + 'ap_id': instance.apId, + 'local': instance.local, + 'creator_actor_id': instance.creatorActorId, + 'creator_local': instance.creatorLocal, + 'creator_name': instance.creatorName, + 'creator_published': instance.creatorPublished?.toIso8601String(), + 'creator_avatar': instance.creatorAvatar, + 'banned': instance.banned, + 'banned_from_community': instance.bannedFromCommunity, + 'community_actor_id': instance.communityActorId, + 'community_local': instance.communityLocal, + 'community_name': instance.communityName, + 'community_removed': instance.communityRemoved, + 'community_deleted': instance.communityDeleted, + 'community_nsfw': instance.communityNsfw, + 'number_of_comments': instance.numberOfComments, + 'score': instance.score, + 'upvotes': instance.upvotes, + 'downvotes': instance.downvotes, + 'hot_rank': instance.hotRank, + 'newest_activity_time': instance.newestActivityTime?.toIso8601String(), + 'userId': instance.userId, + 'myVote': instance.myVote, + 'subscribed': instance.subscribed, + 'read': instance.read, + 'saved': instance.saved, + }; diff --git a/pubspec.lock b/pubspec.lock index dacbe7b..d568d30 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,13 +1,20 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: + _fe_analyzer_shared: dependency: transitive description: - name: archive + name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "2.0.13" + version: "6.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.39.14" args: dependency: transitive description: @@ -21,7 +28,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.4.2" boolean_selector: dependency: transitive description: @@ -29,6 +36,69 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.2" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.4" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.10" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.1" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.0" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "4.3.2" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "7.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" charcode: dependency: transitive description: @@ -36,13 +106,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.3" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "3.4.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.13" convert: dependency: transitive description: @@ -57,6 +155,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.4" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.2" cupertino_icons: dependency: "direct main" description: @@ -64,6 +169,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.3" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.6" effective_dart: dependency: "direct dev" description: @@ -71,6 +183,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.4" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.11" flutter: dependency: "direct main" description: flutter @@ -81,20 +207,83 @@ packages: description: flutter source: sdk version: "0.0.0" - image: + glob: dependency: transitive description: - name: image + name: glob url: "https://pub.dartlang.org" source: hosted - version: "2.1.12" + version: "1.2.0" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0+3" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.4" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.4" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.8" meta: dependency: transitive description: @@ -102,20 +291,69 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.8" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6+3" + node_interop: + dependency: transitive + description: + name: node_interop + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + node_io: + dependency: transitive + description: + name: node_io + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" - petitparser: + version: "1.7.0" + pedantic: dependency: transitive description: - name: petitparser + name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "1.9.0" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5" quiver: dependency: transitive description: @@ -123,11 +361,32 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.3" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.7" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.3" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6" source_span: dependency: transitive description: @@ -141,7 +400,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.5" stream_channel: dependency: transitive description: @@ -149,6 +408,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" string_scanner: dependency: transitive description: @@ -169,14 +435,21 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.17" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1+2" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.2.0" vector_math: dependency: transitive description: @@ -184,12 +457,26 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.8" - xml: + watcher: dependency: transitive description: - name: xml + name: watcher url: "https://pub.dartlang.org" source: hosted - version: "3.6.1" + version: "0.9.7+15" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.9.0-14.0.dev <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2b7d01f..dc1e7f1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ environment: sdk: ">=2.7.0 <3.0.0" dependencies: + json_annotation: ^3.0.1 flutter: sdk: flutter @@ -33,6 +34,8 @@ dev_dependencies: flutter_test: sdk: flutter effective_dart: ^1.0.0 + json_serializable: ^3.3.0 + build_runner: ^1.10.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec From cf09486479a65f5424cd7f6f34b85238396cce14 Mon Sep 17 00:00:00 2001 From: Mikwk Date: Wed, 5 Aug 2020 17:03:21 +0200 Subject: [PATCH 05/90] TODO: Add methods and fields for comments associated with post. --- lib/mappingClasses/post.dart | 90 ++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/lib/mappingClasses/post.dart b/lib/mappingClasses/post.dart index e159015..be65e53 100644 --- a/lib/mappingClasses/post.dart +++ b/lib/mappingClasses/post.dart @@ -2,52 +2,54 @@ import 'package:json_annotation/json_annotation.dart'; part 'post.g.dart'; +//TODO: Add methods and fields for comments associated with post. @JsonSerializable() class PostView { PostView( - this.id, - this.postName, - this.url, - this.body, - this.creatorId, - this.communityId, - this.removed, - this.locked, - this.published, - this.updated, - this.deleted, - this.nsfw, - this.stickied, - this.embedTitle, - this.embedDescription, - this.embedHtml, - this.thumbnailUrl, - this.apId, - this.local, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPublished, - this.creatorAvatar, - this.banned, - this.bannedFromCommunity, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityRemoved, - this.communityDeleted, - this.communityNsfw, - this.numberOfComments, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.newestActivityTime, - int userId, - int myVote, - bool subscribed, - bool read, - bool saved) { + this.id, + this.postName, + this.url, + this.body, + this.creatorId, + this.communityId, + this.removed, + this.locked, + this.published, + this.updated, + this.deleted, + this.nsfw, + this.stickied, + this.embedTitle, + this.embedDescription, + this.embedHtml, + this.thumbnailUrl, + this.apId, + this.local, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPublished, + this.creatorAvatar, + this.banned, + this.bannedFromCommunity, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityRemoved, + this.communityDeleted, + this.communityNsfw, + this.numberOfComments, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.newestActivityTime, + int userId, + int myVote, + bool subscribed, + bool read, + bool saved, + ) { _userId = userId; _myVote = myVote; _subscribed = subscribed; @@ -186,7 +188,7 @@ class PostView { return _myVote; } - void set myVote(int myVote) => _myVote = myVote>0?1:myVote<0?-1:0; + void set myVote(int myVote) => _myVote = myVote > 0 ? 1 : myVote < 0 ? -1 : 0; @JsonKey(name: "my_vote") int _myVote; From a7a0e4bf12b34da9a0299b7f4dbc4586d0d529a5 Mon Sep 17 00:00:00 2001 From: Mikwk Date: Wed, 5 Aug 2020 17:33:59 +0200 Subject: [PATCH 06/90] Added CommentView class along with autogenerated Json (de)serialization. Cleaned code in post.dart for it to be more readable. Moved ParseDateFromJson static method from PostView to UtilityClass in utility.dart, because it's also used by CommentView class. --- lib/mappingClasses/comment.dart | 164 ++++++++++++++++++++++++++++++ lib/mappingClasses/comment.g.dart | 80 +++++++++++++++ lib/mappingClasses/post.dart | 36 +++---- lib/mappingClasses/post.g.dart | 8 +- lib/mappingClasses/utility.dart | 6 ++ 5 files changed, 266 insertions(+), 28 deletions(-) create mode 100644 lib/mappingClasses/comment.dart create mode 100644 lib/mappingClasses/comment.g.dart create mode 100644 lib/mappingClasses/utility.dart diff --git a/lib/mappingClasses/comment.dart b/lib/mappingClasses/comment.dart new file mode 100644 index 0000000..66deac2 --- /dev/null +++ b/lib/mappingClasses/comment.dart @@ -0,0 +1,164 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:lemmur/mappingClasses/utility.dart'; + +part 'comment.g.dart'; + +@JsonSerializable() +class CommentView { + CommentView( + this.id, + this.creatorId, + this.postId, + this.postName, + this.parentId, + this.content, + this.removed, + bool read, + this.published, + this.updated, + this.deleted, + this.apId, + this.local, + this.communityId, + this.communityActorId, + this.communityLocal, + this.communityName, + this.banned, + this.bannedFromCommunity, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPublished, + this.creatorAvatar, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + int userId, + int myVote, + bool subscribed, + bool saved, + ) { + userId = userId; + _myVote = myVote; + _subscribed = subscribed; + _read = read; + _saved = saved; + } + + @JsonKey(name: "id") + final int id; + + @JsonKey(name: "creator_id") + final int creatorId; + + @JsonKey(name: "post_id") + final int postId; + + @JsonKey(name: "post_name") + final String postName; + + @JsonKey(name: "parent_id") + final int parentId; + + @JsonKey(name: "content") + final String content; + + @JsonKey(name: "removed") + final bool removed; + + bool get read => _read; + + void set read(bool read) => _read = read; + @JsonKey(name: "read") + bool _read; + + @JsonKey(name: "published", fromJson: UtilityClass.ParseDateFromJson) + final DateTime published; + + @JsonKey(name: "updated", fromJson: UtilityClass.ParseDateFromJson) + final DateTime updated; + + @JsonKey(name: "deleted") + final bool deleted; + + @JsonKey(name: "ap_id") + final String apId; + + @JsonKey(name: "local") + final bool local; + + @JsonKey(name: "community_id") + final int communityId; + + @JsonKey(name: "community_actor_id") + final String communityActorId; + + @JsonKey(name: "community_local") + final bool communityLocal; + + @JsonKey(name: "community_name") + final String communityName; + + @JsonKey(name: "banned") + final bool banned; + + @JsonKey(name: "banned_from_community") + final bool bannedFromCommunity; + + @JsonKey(name: "creator_actor_id") + final String creatorActorId; + + @JsonKey(name: "creator_local") + final bool creatorLocal; + + @JsonKey(name: "creator_name") + final String creatorName; + + @JsonKey(name: "creator_published", fromJson: UtilityClass.ParseDateFromJson) + final DateTime creatorPublished; + + @JsonKey(name: "creator_avatar") + final String creatorAvatar; + + @JsonKey(name: "score") + int score; + + @JsonKey(name: "upvotes") + int upvotes; + + @JsonKey(name: "downvotes") + int downvotes; + + @JsonKey(name: "hot_rank") + final int hotRank; + + int get userId => _userId; + + void set userId(int userId) => _userId = userId; + @JsonKey(name: "user_id") + int _userId; + + int get myVote => _myVote; + + void set myVote(int myVote) => _myVote = myVote > 0 ? 1 : myVote < 0 ? -1 : 0; + @JsonKey(name: "my_vote") + int _myVote; + + bool get subscribed => _subscribed; + + void set subscribed(bool subscribed) => _subscribed = subscribed; + @JsonKey(name: "subscribed") + bool _subscribed; + + bool get saved => _saved; + + void set saved(bool saved) => _saved = saved; + @JsonKey(name: "saved") + bool _saved; + + factory CommentView.fromJson(Map json) => + _$CommentViewFromJson(json); + + Map commentViewToJson() => _$CommentViewToJson(this); +} diff --git a/lib/mappingClasses/comment.g.dart b/lib/mappingClasses/comment.g.dart new file mode 100644 index 0000000..ecb6c9d --- /dev/null +++ b/lib/mappingClasses/comment.g.dart @@ -0,0 +1,80 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'comment.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CommentView _$CommentViewFromJson(Map json) { + return CommentView( + json['id'] as int, + json['creator_id'] as int, + json['post_id'] as int, + json['post_name'] as String, + json['parent_id'] as int, + json['content'] as String, + json['removed'] as bool, + json['read'] as bool, + UtilityClass.ParseDateFromJson(json['published']), + UtilityClass.ParseDateFromJson(json['updated']), + json['deleted'] as bool, + json['ap_id'] as String, + json['local'] as bool, + json['community_id'] as int, + json['community_actor_id'] as String, + json['community_local'] as bool, + json['community_name'] as String, + json['banned'] as bool, + json['banned_from_community'] as bool, + json['creator_actor_id'] as String, + json['creator_local'] as bool, + json['creator_name'] as String, + UtilityClass.ParseDateFromJson(json['creator_published']), + json['creator_avatar'] as String, + json['score'] as int, + json['upvotes'] as int, + json['downvotes'] as int, + json['hot_rank'] as int, + json['userId'] as int, + json['myVote'] as int, + json['subscribed'] as bool, + json['saved'] as bool, + ); +} + +Map _$CommentViewToJson(CommentView instance) => + { + 'id': instance.id, + 'creator_id': instance.creatorId, + 'post_id': instance.postId, + 'post_name': instance.postName, + 'parent_id': instance.parentId, + 'content': instance.content, + 'removed': instance.removed, + 'read': instance.read, + 'published': instance.published?.toIso8601String(), + 'updated': instance.updated?.toIso8601String(), + 'deleted': instance.deleted, + 'ap_id': instance.apId, + 'local': instance.local, + 'community_id': instance.communityId, + 'community_actor_id': instance.communityActorId, + 'community_local': instance.communityLocal, + 'community_name': instance.communityName, + 'banned': instance.banned, + 'banned_from_community': instance.bannedFromCommunity, + 'creator_actor_id': instance.creatorActorId, + 'creator_local': instance.creatorLocal, + 'creator_name': instance.creatorName, + 'creator_published': instance.creatorPublished?.toIso8601String(), + 'creator_avatar': instance.creatorAvatar, + 'score': instance.score, + 'upvotes': instance.upvotes, + 'downvotes': instance.downvotes, + 'hot_rank': instance.hotRank, + 'userId': instance.userId, + 'myVote': instance.myVote, + 'subscribed': instance.subscribed, + 'saved': instance.saved, + }; diff --git a/lib/mappingClasses/post.dart b/lib/mappingClasses/post.dart index be65e53..e408461 100644 --- a/lib/mappingClasses/post.dart +++ b/lib/mappingClasses/post.dart @@ -1,5 +1,7 @@ import 'package:json_annotation/json_annotation.dart'; +import 'utility.dart'; + part 'post.g.dart'; //TODO: Add methods and fields for comments associated with post. @@ -57,11 +59,6 @@ class PostView { _saved = saved; } - //TODO: Parse date from Json. - static DateTime ParseDateFromJson(t) { - throw Exception("Not implemented exception"); - } - @JsonKey(name: "id") final int id; @@ -86,10 +83,10 @@ class PostView { @JsonKey(name: "locked") final bool locked; - @JsonKey(name: "published", fromJson: ParseDateFromJson) + @JsonKey(name: "published", fromJson: UtilityClass.ParseDateFromJson) final DateTime published; - @JsonKey(name: "updated", fromJson: ParseDateFromJson) + @JsonKey(name: "updated", fromJson: UtilityClass.ParseDateFromJson) final DateTime updated; @JsonKey(name: "deleted") @@ -128,7 +125,7 @@ class PostView { @JsonKey(name: "creator_name") final String creatorName; - @JsonKey(name: "creator_published", fromJson: ParseDateFromJson) + @JsonKey(name: "creator_published", fromJson: UtilityClass.ParseDateFromJson) final DateTime creatorPublished; @JsonKey(name: "creator_avatar") @@ -173,44 +170,35 @@ class PostView { @JsonKey(name: "hot_rank") final int hotRank; - @JsonKey(name: "newest_activity_time", fromJson: ParseDateFromJson) + @JsonKey( + name: "newest_activity_time", fromJson: UtilityClass.ParseDateFromJson) final DateTime newestActivityTime; - int get userId { - return _userId; - } + int get userId => _userId; void set userId(int userId) => _userId = userId; @JsonKey(name: "user_id") int _userId; - int get myVote { - return _myVote; - } + int get myVote => _myVote; void set myVote(int myVote) => _myVote = myVote > 0 ? 1 : myVote < 0 ? -1 : 0; @JsonKey(name: "my_vote") int _myVote; - bool get subscribed { - return _subscribed; - } + bool get subscribed => _subscribed; void set subscribed(bool subscribed) => _subscribed = subscribed; @JsonKey(name: "subscribed") bool _subscribed; - bool get read { - return _read; - } + bool get read => _read; void set read(bool read) => _read = read; @JsonKey(name: "read") bool _read; - bool get saved { - return _saved; - } + bool get saved => _saved; void set saved(bool saved) => _saved = saved; @JsonKey(name: "saved") diff --git a/lib/mappingClasses/post.g.dart b/lib/mappingClasses/post.g.dart index c3a6a05..9190b79 100644 --- a/lib/mappingClasses/post.g.dart +++ b/lib/mappingClasses/post.g.dart @@ -16,8 +16,8 @@ PostView _$PostViewFromJson(Map json) { json['community_id'] as int, json['removed'] as bool, json['locked'] as bool, - PostView.ParseDateFromJson(json['published']), - PostView.ParseDateFromJson(json['updated']), + UtilityClass.ParseDateFromJson(json['published']), + UtilityClass.ParseDateFromJson(json['updated']), json['deleted'] as bool, json['nsfw'] as bool, json['stickied'] as bool, @@ -30,7 +30,7 @@ PostView _$PostViewFromJson(Map json) { json['creator_actor_id'] as String, json['creator_local'] as bool, json['creator_name'] as String, - PostView.ParseDateFromJson(json['creator_published']), + UtilityClass.ParseDateFromJson(json['creator_published']), json['creator_avatar'] as String, json['banned'] as bool, json['banned_from_community'] as bool, @@ -45,7 +45,7 @@ PostView _$PostViewFromJson(Map json) { json['upvotes'] as int, json['downvotes'] as int, json['hot_rank'] as int, - PostView.ParseDateFromJson(json['newest_activity_time']), + UtilityClass.ParseDateFromJson(json['newest_activity_time']), json['userId'] as int, json['myVote'] as int, json['subscribed'] as bool, diff --git a/lib/mappingClasses/utility.dart b/lib/mappingClasses/utility.dart new file mode 100644 index 0000000..9a0a554 --- /dev/null +++ b/lib/mappingClasses/utility.dart @@ -0,0 +1,6 @@ +class UtilityClass { + //TODO: Parse date from Json. + static DateTime ParseDateFromJson(t) { + throw Exception("Not implemented exception"); + } +} From 8c0f211cf2ff68d9c894d682e0369434a19bca05 Mon Sep 17 00:00:00 2001 From: krawieck Date: Wed, 5 Aug 2020 23:06:54 +0200 Subject: [PATCH 07/90] `PostEndpoint` created and with most methods created methods created for: * `POST /post` * `GET /post` * `GET /post/list` * `POST /post/like` * `PUT /post` * `POST /post/delete` * `POST /post/remove` * `POST /post/save` I'm not implementing admin stuff cuz we don't need it for now, and we keep track of what is yet to be added in #6 also we might need to move a bunch of stuff to separate files cuz it's getting cluttered in here --- lib/client/client.dart | 103 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/lib/client/client.dart b/lib/client/client.dart index fab9346..bf2c6eb 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -14,8 +14,13 @@ class LemmyAPI { class V1 { String instanceUrl; + UserEndpoint user; - V1(this.instanceUrl) : user = UserEndpoint(instanceUrl); + PostEndpoint post; + + V1(this.instanceUrl) + : user = UserEndpoint(instanceUrl), + post = PostEndpoint(instanceUrl); /// GET /categories /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories @@ -197,3 +202,99 @@ class UserEndpoint { throw UnimplementedError(); } } + +class PostEndpoint { + String instanceUrl; + PostEndpoint(this.instanceUrl); + + /// POST /post + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#post + String create({ + @required String name, + String url, + String body, + @required bool nsfw, + @required int communityId, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /post + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post + String get({ + @required int id, + String auth, + }) { + throw UnimplementedError(); + } + + /// GET /post/list + /// + String getList({ + @required String type, + @required String sort, + int page, + int limit, + int communityId, + String communityName, + }) { + throw UnimplementedError(); + } + + /// POST /post/like + /// + String vote({ + @required int postId, + @required int score, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /post + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-post + String update({ + @required int editId, + @required String name, + String url, + String body, + @required bool nsfw, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /post/delete + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-post + /// delete a post in a user deleting their own kind of way + String delete({ + @required int editId, + @required bool deleted, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /post/remove + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-post + /// remove post in an admin kind of way + String remove({ + @required int editId, + @required bool removed, + String reason, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /post/save + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-post + String save({ + @required int postId, + @required bool save, + @required String auth, + }) { + throw UnimplementedError(); + } +} From 19c10d27f94d1310a1983a2b3b75e8262a501473 Mon Sep 17 00:00:00 2001 From: krawieck Date: Wed, 5 Aug 2020 23:21:26 +0200 Subject: [PATCH 08/90] Move endponts to separate files to reduce clutter Move `v1` endpoint to it's own directory, and `PostEndpoint`and `UserEndpoint` to their own files --- lib/client/client.dart | 289 +------------------------------ lib/client/v1/main.dart | 34 ++++ lib/client/v1/post_endpoint.dart | 97 +++++++++++ lib/client/v1/user_endpoint.dart | 161 +++++++++++++++++ 4 files changed, 294 insertions(+), 287 deletions(-) create mode 100644 lib/client/v1/main.dart create mode 100644 lib/client/v1/post_endpoint.dart create mode 100644 lib/client/v1/user_endpoint.dart diff --git a/lib/client/client.dart b/lib/client/client.dart index bf2c6eb..e3544b1 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:lemmur/client/v1/main.dart'; +import 'package:lemmur/client/v1/user_endpoint.dart'; class LemmyAPI { /// url of this lemmy instance @@ -11,290 +13,3 @@ class LemmyAPI { : assert(instanceUrl != null), v1 = V1(instanceUrl); } - -class V1 { - String instanceUrl; - - UserEndpoint user; - PostEndpoint post; - - V1(this.instanceUrl) - : user = UserEndpoint(instanceUrl), - post = PostEndpoint(instanceUrl); - - /// GET /categories - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories - String listCategories() { - throw UnimplementedError(); - } - - /// POST /search - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search - String search({ - @required String q, - @required String type, - String communityId, - @required String sort, - int page, - int limit, - String auth, - }) { - throw UnimplementedError(); - } -} - -class UserEndpoint { - String instanceUrl; - UserEndpoint(this.instanceUrl); - - /// POST /user/login - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login - String login({ - String usernameOrEmail, - String password, - }) { - assert(usernameOrEmail != null, password != null); - throw UnimplementedError(); - } - - /// POST /user/register - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#register - String register({ - @required String username, - String email, - String password, - }) { - throw UnimplementedError(); - } - - /// GET /user/get_captcha - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha - String getCaptcha() { - throw UnimplementedError(); - } - - /// GET /user - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details - String getDetails({ - int userId, - String username, - @required String sort, - int page, - int limit, - int communityId, - bool savedOnly, - String auth, - }) { - throw UnimplementedError(); - } - - /// PUT /save_user_settings - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-user-settings - String updateSettings({ - @required bool showNsfw, - @required String theme, - @required int defaultSortType, - @required int defaultListingType, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// GET /user/replies - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-replies--inbox - String getReplies({ - @required String sort, - int page, - int limit, - @required bool unreadOnly, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// GET /user/mentions - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions - String getMentions({ - String sort, - @required int page, - @required int limit, - bool unreadOnly, - String auth, - }) { - throw UnimplementedError(); - } - - /// POST /user/mention/mark_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-user-mention-as-read - String markMentionsAsRead({ - @required int userMentionId, - @required bool read, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// GET /private_message/list - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-private-messages - String getPrivateMessages({ - @required bool unreadOnly, - int page, - int limit, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /private_message - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-private-message - String createPrivateMessage({ - @required String content, - @required int recipientId, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// PUT /private_message - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-private-message - String updatePrivateMessage({ - @required int editId, - @required String content, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /private_message/delete - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-private-message - String deletePrivateMessage({ - @required int editId, - @required bool deleted, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /private_message/mark_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-private-message-as-read - String markPrivateMessageAsRead({ - @required int editId, - @required bool read, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /user/mark_all_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-all-as-read - String markAllPrivateMessagesAsRead({ - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /user/delete_account - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-account - String deleteAccount({ - @required String password, - @required String auth, - }) { - throw UnimplementedError(); - } -} - -class PostEndpoint { - String instanceUrl; - PostEndpoint(this.instanceUrl); - - /// POST /post - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#post - String create({ - @required String name, - String url, - String body, - @required bool nsfw, - @required int communityId, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// GET /post - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post - String get({ - @required int id, - String auth, - }) { - throw UnimplementedError(); - } - - /// GET /post/list - /// - String getList({ - @required String type, - @required String sort, - int page, - int limit, - int communityId, - String communityName, - }) { - throw UnimplementedError(); - } - - /// POST /post/like - /// - String vote({ - @required int postId, - @required int score, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// PUT /post - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-post - String update({ - @required int editId, - @required String name, - String url, - String body, - @required bool nsfw, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /post/delete - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-post - /// delete a post in a user deleting their own kind of way - String delete({ - @required int editId, - @required bool deleted, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /post/remove - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-post - /// remove post in an admin kind of way - String remove({ - @required int editId, - @required bool removed, - String reason, - @required String auth, - }) { - throw UnimplementedError(); - } - - /// POST /post/save - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-post - String save({ - @required int postId, - @required bool save, - @required String auth, - }) { - throw UnimplementedError(); - } -} diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart new file mode 100644 index 0000000..e41b5b8 --- /dev/null +++ b/lib/client/v1/main.dart @@ -0,0 +1,34 @@ +import 'package:flutter/foundation.dart'; +import 'post_endpoint.dart'; +import 'user_endpoint.dart'; + +class V1 { + String instanceUrl; + + UserEndpoint user; + PostEndpoint post; + + V1(this.instanceUrl) + : user = UserEndpoint(instanceUrl), + post = PostEndpoint(instanceUrl); + + /// GET /categories + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories + String listCategories() { + throw UnimplementedError(); + } + + /// POST /search + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search + String search({ + @required String q, + @required String type, + String communityId, + @required String sort, + int page, + int limit, + String auth, + }) { + throw UnimplementedError(); + } +} diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart new file mode 100644 index 0000000..f73cc41 --- /dev/null +++ b/lib/client/v1/post_endpoint.dart @@ -0,0 +1,97 @@ +import 'package:flutter/foundation.dart'; + +class PostEndpoint { + String instanceUrl; + PostEndpoint(this.instanceUrl); + + /// POST /post + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#post + String create({ + @required String name, + String url, + String body, + @required bool nsfw, + @required int communityId, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /post + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post + String get({ + @required int id, + String auth, + }) { + throw UnimplementedError(); + } + + /// GET /post/list + /// + String getList({ + @required String type, + @required String sort, + int page, + int limit, + int communityId, + String communityName, + }) { + throw UnimplementedError(); + } + + /// POST /post/like + /// + String vote({ + @required int postId, + @required int score, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /post + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-post + String update({ + @required int editId, + @required String name, + String url, + String body, + @required bool nsfw, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /post/delete + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-post + /// delete a post in a user deleting their own kind of way + String delete({ + @required int editId, + @required bool deleted, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /post/remove + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-post + /// remove post in an admin kind of way + String remove({ + @required int editId, + @required bool removed, + String reason, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /post/save + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-post + String save({ + @required int postId, + @required bool save, + @required String auth, + }) { + throw UnimplementedError(); + } +} diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart new file mode 100644 index 0000000..89cc418 --- /dev/null +++ b/lib/client/v1/user_endpoint.dart @@ -0,0 +1,161 @@ +import 'package:flutter/foundation.dart'; + +class UserEndpoint { + String instanceUrl; + UserEndpoint(this.instanceUrl); + + /// POST /user/login + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login + String login({ + String usernameOrEmail, + String password, + }) { + assert(usernameOrEmail != null, password != null); + throw UnimplementedError(); + } + + /// POST /user/register + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#register + String register({ + @required String username, + String email, + String password, + }) { + throw UnimplementedError(); + } + + /// GET /user/get_captcha + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha + String getCaptcha() { + throw UnimplementedError(); + } + + /// GET /user + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details + String getDetails({ + int userId, + String username, + @required String sort, + int page, + int limit, + int communityId, + bool savedOnly, + String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /save_user_settings + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-user-settings + String updateSettings({ + @required bool showNsfw, + @required String theme, + @required int defaultSortType, + @required int defaultListingType, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /user/replies + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-replies--inbox + String getReplies({ + @required String sort, + int page, + int limit, + @required bool unreadOnly, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /user/mentions + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions + String getMentions({ + String sort, + @required int page, + @required int limit, + bool unreadOnly, + String auth, + }) { + throw UnimplementedError(); + } + + /// POST /user/mention/mark_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-user-mention-as-read + String markMentionsAsRead({ + @required int userMentionId, + @required bool read, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// GET /private_message/list + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-private-messages + String getPrivateMessages({ + @required bool unreadOnly, + int page, + int limit, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /private_message + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-private-message + String createPrivateMessage({ + @required String content, + @required int recipientId, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /private_message + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-private-message + String updatePrivateMessage({ + @required int editId, + @required String content, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /private_message/delete + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-private-message + String deletePrivateMessage({ + @required int editId, + @required bool deleted, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /private_message/mark_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-private-message-as-read + String markPrivateMessageAsRead({ + @required int editId, + @required bool read, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /user/mark_all_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-all-as-read + String markAllPrivateMessagesAsRead({ + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /user/delete_account + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-account + String deleteAccount({ + @required String password, + @required String auth, + }) { + throw UnimplementedError(); + } +} From 2a89add283a71c32bb38b4e220880c20b82f19fb Mon Sep 17 00:00:00 2001 From: krawieck Date: Wed, 5 Aug 2020 23:59:10 +0200 Subject: [PATCH 09/90] Create `CommentEndpoint` seems like all important endpoints are created, now we can get to implementing them --- lib/client/v1/comment_endpoint.dart | 82 +++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 lib/client/v1/comment_endpoint.dart diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart new file mode 100644 index 0000000..d8f291c --- /dev/null +++ b/lib/client/v1/comment_endpoint.dart @@ -0,0 +1,82 @@ +import 'package:flutter/foundation.dart'; + +class CommentEndpoint { + String instanceUrl; + CommentEndpoint(this.instanceUrl); + + /// POST /comment + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment + String create({ + @required String content, + int parentId, + @required int postId, + int formId, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// PUT /comment + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-comment + String edit({ + @required String content, + @required int editId, + String formId, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /comment/delete + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-comment + /// Only the creator can delete the comment + String delete({ + @required int editId, + @required bool deleted, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /comment/remove + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-comment + /// Only a mod or admin can remove the comment + String remove({ + @required int editId, + @required bool removed, + String reason, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /comment/mark_as_read + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-comment-as-read + String markAsRead({ + @required int editId, + @required bool read, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /comment/save + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-comment + String save({ + @required int commentId, + @required bool save, + @required String auth, + }) { + throw UnimplementedError(); + } + + /// POST /comment/like + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment-like + String vote({ + @required int commentId, + @required int score, + @required String auth, + }) { + throw UnimplementedError(); + } +} From 43ab1990d78c3991f40b6d176e5f6ca75fbc2050 Mon Sep 17 00:00:00 2001 From: Mikwk Date: Thu, 6 Aug 2020 12:03:31 +0200 Subject: [PATCH 10/90] Implemented ParseDateFromJson method. --- lib/mappingClasses/comment.g.dart | 6 +++--- lib/mappingClasses/post.g.dart | 8 ++++---- lib/mappingClasses/utility.dart | 7 ++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/mappingClasses/comment.g.dart b/lib/mappingClasses/comment.g.dart index ecb6c9d..449cdb0 100644 --- a/lib/mappingClasses/comment.g.dart +++ b/lib/mappingClasses/comment.g.dart @@ -16,8 +16,8 @@ CommentView _$CommentViewFromJson(Map json) { json['content'] as String, json['removed'] as bool, json['read'] as bool, - UtilityClass.ParseDateFromJson(json['published']), - UtilityClass.ParseDateFromJson(json['updated']), + UtilityClass.ParseDateFromJson(json['published'] as String), + UtilityClass.ParseDateFromJson(json['updated'] as String), json['deleted'] as bool, json['ap_id'] as String, json['local'] as bool, @@ -30,7 +30,7 @@ CommentView _$CommentViewFromJson(Map json) { json['creator_actor_id'] as String, json['creator_local'] as bool, json['creator_name'] as String, - UtilityClass.ParseDateFromJson(json['creator_published']), + UtilityClass.ParseDateFromJson(json['creator_published'] as String), json['creator_avatar'] as String, json['score'] as int, json['upvotes'] as int, diff --git a/lib/mappingClasses/post.g.dart b/lib/mappingClasses/post.g.dart index 9190b79..0ed5157 100644 --- a/lib/mappingClasses/post.g.dart +++ b/lib/mappingClasses/post.g.dart @@ -16,8 +16,8 @@ PostView _$PostViewFromJson(Map json) { json['community_id'] as int, json['removed'] as bool, json['locked'] as bool, - UtilityClass.ParseDateFromJson(json['published']), - UtilityClass.ParseDateFromJson(json['updated']), + UtilityClass.ParseDateFromJson(json['published'] as String), + UtilityClass.ParseDateFromJson(json['updated'] as String), json['deleted'] as bool, json['nsfw'] as bool, json['stickied'] as bool, @@ -30,7 +30,7 @@ PostView _$PostViewFromJson(Map json) { json['creator_actor_id'] as String, json['creator_local'] as bool, json['creator_name'] as String, - UtilityClass.ParseDateFromJson(json['creator_published']), + UtilityClass.ParseDateFromJson(json['creator_published'] as String), json['creator_avatar'] as String, json['banned'] as bool, json['banned_from_community'] as bool, @@ -45,7 +45,7 @@ PostView _$PostViewFromJson(Map json) { json['upvotes'] as int, json['downvotes'] as int, json['hot_rank'] as int, - UtilityClass.ParseDateFromJson(json['newest_activity_time']), + UtilityClass.ParseDateFromJson(json['newest_activity_time'] as String), json['userId'] as int, json['myVote'] as int, json['subscribed'] as bool, diff --git a/lib/mappingClasses/utility.dart b/lib/mappingClasses/utility.dart index 9a0a554..cdd1180 100644 --- a/lib/mappingClasses/utility.dart +++ b/lib/mappingClasses/utility.dart @@ -1,6 +1,7 @@ class UtilityClass { - //TODO: Parse date from Json. - static DateTime ParseDateFromJson(t) { - throw Exception("Not implemented exception"); + ///Parses date from Json. + ///May return null on wrong argument + static DateTime ParseDateFromJson(String t) { + return DateTime.tryParse(t); } } From 4ad3b8d6fc3afd75e02ae986c1b210b4eba6d1e6 Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 6 Aug 2020 12:11:41 +0200 Subject: [PATCH 11/90] Remove unneeded import and convert local import to relative --- lib/client/client.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/client/client.dart b/lib/client/client.dart index e3544b1..941b36b 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:lemmur/client/v1/main.dart'; -import 'package:lemmur/client/v1/user_endpoint.dart'; +import 'v1/main.dart'; class LemmyAPI { /// url of this lemmy instance From 091070726edcb232c559a056ed44939787ef1ec7 Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 6 Aug 2020 22:06:53 +0200 Subject: [PATCH 12/90] Change methods to be top level with names based on OP codes. classes changed to extensions of `V1` class --- lib/client/v1/comment_endpoint.dart | 19 +++++++++---------- lib/client/v1/main.dart | 13 +++++-------- lib/client/v1/post_endpoint.dart | 25 ++++++++++++------------- lib/client/v1/user_endpoint.dart | 17 ++++++++--------- 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart index d8f291c..187498f 100644 --- a/lib/client/v1/comment_endpoint.dart +++ b/lib/client/v1/comment_endpoint.dart @@ -1,12 +1,11 @@ import 'package:flutter/foundation.dart'; -class CommentEndpoint { - String instanceUrl; - CommentEndpoint(this.instanceUrl); +import 'main.dart'; +extension CommentEndpoint on V1 { /// POST /comment /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment - String create({ + String createComment({ @required String content, int parentId, @required int postId, @@ -18,7 +17,7 @@ class CommentEndpoint { /// PUT /comment /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-comment - String edit({ + String editComment({ @required String content, @required int editId, String formId, @@ -30,7 +29,7 @@ class CommentEndpoint { /// POST /comment/delete /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-comment /// Only the creator can delete the comment - String delete({ + String deleteComment({ @required int editId, @required bool deleted, @required String auth, @@ -41,7 +40,7 @@ class CommentEndpoint { /// POST /comment/remove /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-comment /// Only a mod or admin can remove the comment - String remove({ + String removeComment({ @required int editId, @required bool removed, String reason, @@ -52,7 +51,7 @@ class CommentEndpoint { /// POST /comment/mark_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-comment-as-read - String markAsRead({ + String markCommentAsRead({ @required int editId, @required bool read, @required String auth, @@ -62,7 +61,7 @@ class CommentEndpoint { /// POST /comment/save /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-comment - String save({ + String saveComment({ @required int commentId, @required bool save, @required String auth, @@ -72,7 +71,7 @@ class CommentEndpoint { /// POST /comment/like /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment-like - String vote({ + String createCommentLike({ @required int commentId, @required int score, @required String auth, diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index e41b5b8..c39784e 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -1,16 +1,13 @@ import 'package:flutter/foundation.dart'; -import 'post_endpoint.dart'; -import 'user_endpoint.dart'; + +export 'comment_endpoint.dart'; +export 'post_endpoint.dart'; +export 'user_endpoint.dart'; class V1 { String instanceUrl; - UserEndpoint user; - PostEndpoint post; - - V1(this.instanceUrl) - : user = UserEndpoint(instanceUrl), - post = PostEndpoint(instanceUrl); + V1(this.instanceUrl); /// GET /categories /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index f73cc41..39c6f24 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -1,12 +1,11 @@ import 'package:flutter/foundation.dart'; -class PostEndpoint { - String instanceUrl; - PostEndpoint(this.instanceUrl); +import 'main.dart'; +extension PostEndpoint on V1 { /// POST /post /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#post - String create({ + String createPost({ @required String name, String url, String body, @@ -19,7 +18,7 @@ class PostEndpoint { /// GET /post /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post - String get({ + String getPost({ @required int id, String auth, }) { @@ -27,8 +26,8 @@ class PostEndpoint { } /// GET /post/list - /// - String getList({ + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-posts + String getPosts({ @required String type, @required String sort, int page, @@ -40,8 +39,8 @@ class PostEndpoint { } /// POST /post/like - /// - String vote({ + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-post-like + String createPostLike({ @required int postId, @required int score, @required String auth, @@ -51,7 +50,7 @@ class PostEndpoint { /// PUT /post /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-post - String update({ + String editPost({ @required int editId, @required String name, String url, @@ -65,7 +64,7 @@ class PostEndpoint { /// POST /post/delete /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-post /// delete a post in a user deleting their own kind of way - String delete({ + String deletePost({ @required int editId, @required bool deleted, @required String auth, @@ -76,7 +75,7 @@ class PostEndpoint { /// POST /post/remove /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-post /// remove post in an admin kind of way - String remove({ + String removePost({ @required int editId, @required bool removed, String reason, @@ -87,7 +86,7 @@ class PostEndpoint { /// POST /post/save /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-post - String save({ + String savePost({ @required int postId, @required bool save, @required String auth, diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 89cc418..26b2b97 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -1,9 +1,8 @@ import 'package:flutter/foundation.dart'; -class UserEndpoint { - String instanceUrl; - UserEndpoint(this.instanceUrl); +import 'main.dart'; +extension UserEndpoint on V1 { /// POST /user/login /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login String login({ @@ -32,7 +31,7 @@ class UserEndpoint { /// GET /user /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details - String getDetails({ + String getUserDetails({ int userId, String username, @required String sort, @@ -47,7 +46,7 @@ class UserEndpoint { /// PUT /save_user_settings /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-user-settings - String updateSettings({ + String saveUserSettings({ @required bool showNsfw, @required String theme, @required int defaultSortType, @@ -71,7 +70,7 @@ class UserEndpoint { /// GET /user/mentions /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions - String getMentions({ + String getUserMentions({ String sort, @required int page, @required int limit, @@ -83,7 +82,7 @@ class UserEndpoint { /// POST /user/mention/mark_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-user-mention-as-read - String markMentionsAsRead({ + String markUserMentionAsRead({ @required int userMentionId, @required bool read, @required String auth, @@ -114,7 +113,7 @@ class UserEndpoint { /// PUT /private_message /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-private-message - String updatePrivateMessage({ + String editPrivateMessage({ @required int editId, @required String content, @required String auth, @@ -144,7 +143,7 @@ class UserEndpoint { /// POST /user/mark_all_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-all-as-read - String markAllPrivateMessagesAsRead({ + String markAllAsRead({ @required String auth, }) { throw UnimplementedError(); From 1515c6f397ebb85f1880a5ec3c009b972459f1a2 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sat, 8 Aug 2020 23:24:34 +0200 Subject: [PATCH 13/90] Add Vote enum for upvotes --- lib/client/v1/comment_endpoint.dart | 2 +- lib/client/v1/main.dart | 19 +++++++++++++++++++ lib/client/v1/post_endpoint.dart | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart index 187498f..03880ce 100644 --- a/lib/client/v1/comment_endpoint.dart +++ b/lib/client/v1/comment_endpoint.dart @@ -73,7 +73,7 @@ extension CommentEndpoint on V1 { /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment-like String createCommentLike({ @required int commentId, - @required int score, + @required Vote score, @required String auth, }) { throw UnimplementedError(); diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index c39784e..51a0058 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -29,3 +29,22 @@ class V1 { throw UnimplementedError(); } } + +enum Vote { + up, + none, + down, +} + +extension VoteValue on Vote { + int get value { + switch (this) { + case Vote.up: + return 1; + case Vote.none: + return 0; + case Vote.down: + return -1; + } + } +} diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 39c6f24..3334046 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -42,7 +42,7 @@ extension PostEndpoint on V1 { /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-post-like String createPostLike({ @required int postId, - @required int score, + @required Vote score, @required String auth, }) { throw UnimplementedError(); From b829b30593ef9977e92f0a916c8dfab126a9ccea Mon Sep 17 00:00:00 2001 From: shilangyu Date: Sat, 8 Aug 2020 23:24:25 +0000 Subject: [PATCH 14/90] models cleanup --- lib/client/models/comment.dart | 94 ++++++++ .../models}/comment.g.dart | 0 lib/client/models/post.dart | 122 ++++++++++ .../models}/post.g.dart | 0 lib/mappingClasses/comment.dart | 164 -------------- lib/mappingClasses/post.dart | 211 ------------------ lib/mappingClasses/utility.dart | 7 - 7 files changed, 216 insertions(+), 382 deletions(-) create mode 100644 lib/client/models/comment.dart rename lib/{mappingClasses => client/models}/comment.g.dart (100%) create mode 100644 lib/client/models/post.dart rename lib/{mappingClasses => client/models}/post.g.dart (100%) delete mode 100644 lib/mappingClasses/comment.dart delete mode 100644 lib/mappingClasses/post.dart delete mode 100644 lib/mappingClasses/utility.dart diff --git a/lib/client/models/comment.dart b/lib/client/models/comment.dart new file mode 100644 index 0000000..822f176 --- /dev/null +++ b/lib/client/models/comment.dart @@ -0,0 +1,94 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'comment.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/comment_view.rs#L91 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class CommentView { + final int id; + final int creatorId; + final int postId; + final String postName; + /// can be null + final int parentId; + final String content; + final bool removed; + final bool read; + final DateTime published; + /// can be null + @JsonKey(fromJson: DateTime.tryParse) + final DateTime updated; + final bool deleted; + final String apId; + final bool local; + final int communityId; + final String communityActorId; + final bool communityLocal; + final String communityName; + /// can be null + final String communityIcon; + final bool banned; + final bool bannedFromCommunity; + final String creatorActorId; + final bool creatorLocal; + final String creatorName; + /// can be null + final String creatorPreferredUsername; + final DateTime creatorPublished; + /// can be null + final String creatorAvatar; + final int score; + final int upvotes; + final int downvotes; + final int hotRank; + final int hotRankActive; + /// can be null + final int userId; + /// can be null + final int myVote; + /// can be null + final bool subscribed; + /// can be null + final bool saved; + + const CommentView({ + this.id, + this.creatorId + this.postId, + this.postName, + this.parentId, + this.content + this.removed + this.read, + this.published + this.updated + this.deleted + this.apId, + this.local + this.communityId + this.communityActorId, + this.communityLocal, + this.communityName + this.communityIcon + this.banned, + this.bannedFromCommunity + this.creatorActorId, + this.creatorLocal, + this.creatorName + this.creatorPreferredUsername, + this.creatorPublished, + this.creatorAvatar + this.score + this.upvotes + this.downvotes + this.hotRank + this.hotRankActive + this.userId, + this.myVote, + this.subscribed, + this.saved, + }); + + factory CommentView.fromJson(Map json) => + _$CommentViewFromJson(json); +} diff --git a/lib/mappingClasses/comment.g.dart b/lib/client/models/comment.g.dart similarity index 100% rename from lib/mappingClasses/comment.g.dart rename to lib/client/models/comment.g.dart diff --git a/lib/client/models/post.dart b/lib/client/models/post.dart new file mode 100644 index 0000000..add29b8 --- /dev/null +++ b/lib/client/models/post.dart @@ -0,0 +1,122 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'post.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/post_view.rs#L113 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class PostView { + final int id; + final String name; + /// can be null + final String url; + /// can be null + final String body; + final int creatorId; + final int communityId; + final bool removed; + final bool locked; + final DateTime published; + /// can be null + @JsonKey(fromJson: DateTime.tryParse) + final DateTime updated; + final bool deleted; + final bool nsfw; + final bool stickied; + /// can be null + final String embedTitle; + /// can be null + final String embedDescription; + /// can be null + final String embedHtml; + /// can be null + final String thumbnailUrl; + final String apId; + final bool local; + final String creatorActorId; + final bool creatorLocal; + final String creatorName; + /// can be null + final String creatorPreferredUsername; + final DateTime creatorPublished; + /// can be null + final String creatorAvatar; + final bool banned; + final bool bannedFromCommunity; + final String communityActorId; + final bool communityLocal; + final String communityName; + /// can be null + final String communityIcon; + final bool communityRemoved; + final bool communityDeleted; + final bool communityNsfw; + final int numberOfComments; + final int score; + final int upvotes; + final int downvotes; + final int hotRank; + final int hotRankActive; + final DateTime newestActivityTime; + /// can be null + final int userId; + /// can be null + final int myVote; + /// can be null + final bool subscribed; + /// can be null + final bool read; + /// can be null + final bool saved; + + PostView({ + this.id, + this.name, + this.url, + this.body, + this.creatorId, + this.communityId, + this.removed, + this.locked, + this.published, + this.updated, + this.deleted, + this.nsfw, + this.stickied, + this.embedTitle, + this.embedDescription, + this.embedHtml, + this.thumbnailUrl, + this.apId, + this.local, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPreferredUsername, + this.creatorPublished, + this.creatorAvatar, + this.banned, + this.bannedFromCommunity, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityIcon, + this.communityRemoved, + this.communityDeleted, + this.communityNsfw, + this.numberOfComments, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.hotRankActive, + this.newestActivityTime, + this.userId, + this.myVote, + this.subscribed, + this.read, + this.saved, + }); + + factory PostView.fromJson(Map json) => + _$PostViewFromJson(json); +} diff --git a/lib/mappingClasses/post.g.dart b/lib/client/models/post.g.dart similarity index 100% rename from lib/mappingClasses/post.g.dart rename to lib/client/models/post.g.dart diff --git a/lib/mappingClasses/comment.dart b/lib/mappingClasses/comment.dart deleted file mode 100644 index 66deac2..0000000 --- a/lib/mappingClasses/comment.dart +++ /dev/null @@ -1,164 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:lemmur/mappingClasses/utility.dart'; - -part 'comment.g.dart'; - -@JsonSerializable() -class CommentView { - CommentView( - this.id, - this.creatorId, - this.postId, - this.postName, - this.parentId, - this.content, - this.removed, - bool read, - this.published, - this.updated, - this.deleted, - this.apId, - this.local, - this.communityId, - this.communityActorId, - this.communityLocal, - this.communityName, - this.banned, - this.bannedFromCommunity, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPublished, - this.creatorAvatar, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - int userId, - int myVote, - bool subscribed, - bool saved, - ) { - userId = userId; - _myVote = myVote; - _subscribed = subscribed; - _read = read; - _saved = saved; - } - - @JsonKey(name: "id") - final int id; - - @JsonKey(name: "creator_id") - final int creatorId; - - @JsonKey(name: "post_id") - final int postId; - - @JsonKey(name: "post_name") - final String postName; - - @JsonKey(name: "parent_id") - final int parentId; - - @JsonKey(name: "content") - final String content; - - @JsonKey(name: "removed") - final bool removed; - - bool get read => _read; - - void set read(bool read) => _read = read; - @JsonKey(name: "read") - bool _read; - - @JsonKey(name: "published", fromJson: UtilityClass.ParseDateFromJson) - final DateTime published; - - @JsonKey(name: "updated", fromJson: UtilityClass.ParseDateFromJson) - final DateTime updated; - - @JsonKey(name: "deleted") - final bool deleted; - - @JsonKey(name: "ap_id") - final String apId; - - @JsonKey(name: "local") - final bool local; - - @JsonKey(name: "community_id") - final int communityId; - - @JsonKey(name: "community_actor_id") - final String communityActorId; - - @JsonKey(name: "community_local") - final bool communityLocal; - - @JsonKey(name: "community_name") - final String communityName; - - @JsonKey(name: "banned") - final bool banned; - - @JsonKey(name: "banned_from_community") - final bool bannedFromCommunity; - - @JsonKey(name: "creator_actor_id") - final String creatorActorId; - - @JsonKey(name: "creator_local") - final bool creatorLocal; - - @JsonKey(name: "creator_name") - final String creatorName; - - @JsonKey(name: "creator_published", fromJson: UtilityClass.ParseDateFromJson) - final DateTime creatorPublished; - - @JsonKey(name: "creator_avatar") - final String creatorAvatar; - - @JsonKey(name: "score") - int score; - - @JsonKey(name: "upvotes") - int upvotes; - - @JsonKey(name: "downvotes") - int downvotes; - - @JsonKey(name: "hot_rank") - final int hotRank; - - int get userId => _userId; - - void set userId(int userId) => _userId = userId; - @JsonKey(name: "user_id") - int _userId; - - int get myVote => _myVote; - - void set myVote(int myVote) => _myVote = myVote > 0 ? 1 : myVote < 0 ? -1 : 0; - @JsonKey(name: "my_vote") - int _myVote; - - bool get subscribed => _subscribed; - - void set subscribed(bool subscribed) => _subscribed = subscribed; - @JsonKey(name: "subscribed") - bool _subscribed; - - bool get saved => _saved; - - void set saved(bool saved) => _saved = saved; - @JsonKey(name: "saved") - bool _saved; - - factory CommentView.fromJson(Map json) => - _$CommentViewFromJson(json); - - Map commentViewToJson() => _$CommentViewToJson(this); -} diff --git a/lib/mappingClasses/post.dart b/lib/mappingClasses/post.dart deleted file mode 100644 index e408461..0000000 --- a/lib/mappingClasses/post.dart +++ /dev/null @@ -1,211 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -import 'utility.dart'; - -part 'post.g.dart'; - -//TODO: Add methods and fields for comments associated with post. -@JsonSerializable() -class PostView { - PostView( - this.id, - this.postName, - this.url, - this.body, - this.creatorId, - this.communityId, - this.removed, - this.locked, - this.published, - this.updated, - this.deleted, - this.nsfw, - this.stickied, - this.embedTitle, - this.embedDescription, - this.embedHtml, - this.thumbnailUrl, - this.apId, - this.local, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPublished, - this.creatorAvatar, - this.banned, - this.bannedFromCommunity, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityRemoved, - this.communityDeleted, - this.communityNsfw, - this.numberOfComments, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.newestActivityTime, - int userId, - int myVote, - bool subscribed, - bool read, - bool saved, - ) { - _userId = userId; - _myVote = myVote; - _subscribed = subscribed; - _read = read; - _saved = saved; - } - - @JsonKey(name: "id") - final int id; - - @JsonKey(name: "name") - final String postName; - - @JsonKey(name: "url") - final String url; - - @JsonKey(name: "body") - final String body; - - @JsonKey(name: "creator_id") - final int creatorId; - - @JsonKey(name: "community_id") - final int communityId; - - @JsonKey(name: "removed") - final bool removed; - - @JsonKey(name: "locked") - final bool locked; - - @JsonKey(name: "published", fromJson: UtilityClass.ParseDateFromJson) - final DateTime published; - - @JsonKey(name: "updated", fromJson: UtilityClass.ParseDateFromJson) - final DateTime updated; - - @JsonKey(name: "deleted") - final bool deleted; - - @JsonKey(name: "nsfw") - final bool nsfw; - - @JsonKey(name: "stickied") - final bool stickied; - - @JsonKey(name: "embed_title") - final String embedTitle; - - @JsonKey(name: "embed_description") - final String embedDescription; - - @JsonKey(name: "embed_html") - final String embedHtml; - - @JsonKey(name: "thumbnail_url") - final String thumbnailUrl; - - @JsonKey(name: "ap_id") - final String apId; - - @JsonKey(name: "local") - final bool local; - - @JsonKey(name: "creator_actor_id") - final String creatorActorId; - - @JsonKey(name: "creator_local") - final bool creatorLocal; - - @JsonKey(name: "creator_name") - final String creatorName; - - @JsonKey(name: "creator_published", fromJson: UtilityClass.ParseDateFromJson) - final DateTime creatorPublished; - - @JsonKey(name: "creator_avatar") - final String creatorAvatar; - - @JsonKey(name: "banned") - final bool banned; - - @JsonKey(name: "banned_from_community") - final bool bannedFromCommunity; - - @JsonKey(name: "community_actor_id") - final String communityActorId; - - @JsonKey(name: "community_local") - final bool communityLocal; - - @JsonKey(name: "community_name") - final String communityName; - - @JsonKey(name: "community_removed") - final bool communityRemoved; - - @JsonKey(name: "community_deleted") - final bool communityDeleted; - - @JsonKey(name: "community_nsfw") - final bool communityNsfw; - - @JsonKey(name: "number_of_comments") - final int numberOfComments; - - @JsonKey(name: "score") - int score; - - @JsonKey(name: "upvotes") - int upvotes; - - @JsonKey(name: "downvotes") - int downvotes; - - @JsonKey(name: "hot_rank") - final int hotRank; - - @JsonKey( - name: "newest_activity_time", fromJson: UtilityClass.ParseDateFromJson) - final DateTime newestActivityTime; - - int get userId => _userId; - - void set userId(int userId) => _userId = userId; - @JsonKey(name: "user_id") - int _userId; - - int get myVote => _myVote; - - void set myVote(int myVote) => _myVote = myVote > 0 ? 1 : myVote < 0 ? -1 : 0; - @JsonKey(name: "my_vote") - int _myVote; - - bool get subscribed => _subscribed; - - void set subscribed(bool subscribed) => _subscribed = subscribed; - @JsonKey(name: "subscribed") - bool _subscribed; - - bool get read => _read; - - void set read(bool read) => _read = read; - @JsonKey(name: "read") - bool _read; - - bool get saved => _saved; - - void set saved(bool saved) => _saved = saved; - @JsonKey(name: "saved") - bool _saved; - - factory PostView.fromJson(Map json) => - _$PostViewFromJson(json); - - Map postViewToJson() => _$PostViewToJson(this); -} diff --git a/lib/mappingClasses/utility.dart b/lib/mappingClasses/utility.dart deleted file mode 100644 index cdd1180..0000000 --- a/lib/mappingClasses/utility.dart +++ /dev/null @@ -1,7 +0,0 @@ -class UtilityClass { - ///Parses date from Json. - ///May return null on wrong argument - static DateTime ParseDateFromJson(String t) { - return DateTime.tryParse(t); - } -} From f4f6ddd8fe816711867b35a5308734f009573f53 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Sat, 8 Aug 2020 23:46:27 +0000 Subject: [PATCH 15/90] added missing commas and removed codegen files --- lib/client/models/comment.dart | 36 +++++------ lib/client/models/comment.g.dart | 80 ------------------------ lib/client/models/post.dart | 2 +- lib/client/models/post.g.dart | 101 ------------------------------- 4 files changed, 19 insertions(+), 200 deletions(-) delete mode 100644 lib/client/models/comment.g.dart delete mode 100644 lib/client/models/post.g.dart diff --git a/lib/client/models/comment.dart b/lib/client/models/comment.dart index 822f176..ab322c6 100644 --- a/lib/client/models/comment.dart +++ b/lib/client/models/comment.dart @@ -53,36 +53,36 @@ class CommentView { const CommentView({ this.id, - this.creatorId + this.creatorId, this.postId, this.postName, this.parentId, - this.content - this.removed + this.content, + this.removed, this.read, - this.published - this.updated - this.deleted + this.published, + this.updated, + this.deleted, this.apId, - this.local - this.communityId + this.local, + this.communityId, this.communityActorId, this.communityLocal, - this.communityName - this.communityIcon + this.communityName, + this.communityIcon, this.banned, - this.bannedFromCommunity + this.bannedFromCommunity, this.creatorActorId, this.creatorLocal, - this.creatorName + this.creatorName, this.creatorPreferredUsername, this.creatorPublished, - this.creatorAvatar - this.score - this.upvotes - this.downvotes - this.hotRank - this.hotRankActive + this.creatorAvatar, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.hotRankActive, this.userId, this.myVote, this.subscribed, diff --git a/lib/client/models/comment.g.dart b/lib/client/models/comment.g.dart deleted file mode 100644 index 449cdb0..0000000 --- a/lib/client/models/comment.g.dart +++ /dev/null @@ -1,80 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'comment.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -CommentView _$CommentViewFromJson(Map json) { - return CommentView( - json['id'] as int, - json['creator_id'] as int, - json['post_id'] as int, - json['post_name'] as String, - json['parent_id'] as int, - json['content'] as String, - json['removed'] as bool, - json['read'] as bool, - UtilityClass.ParseDateFromJson(json['published'] as String), - UtilityClass.ParseDateFromJson(json['updated'] as String), - json['deleted'] as bool, - json['ap_id'] as String, - json['local'] as bool, - json['community_id'] as int, - json['community_actor_id'] as String, - json['community_local'] as bool, - json['community_name'] as String, - json['banned'] as bool, - json['banned_from_community'] as bool, - json['creator_actor_id'] as String, - json['creator_local'] as bool, - json['creator_name'] as String, - UtilityClass.ParseDateFromJson(json['creator_published'] as String), - json['creator_avatar'] as String, - json['score'] as int, - json['upvotes'] as int, - json['downvotes'] as int, - json['hot_rank'] as int, - json['userId'] as int, - json['myVote'] as int, - json['subscribed'] as bool, - json['saved'] as bool, - ); -} - -Map _$CommentViewToJson(CommentView instance) => - { - 'id': instance.id, - 'creator_id': instance.creatorId, - 'post_id': instance.postId, - 'post_name': instance.postName, - 'parent_id': instance.parentId, - 'content': instance.content, - 'removed': instance.removed, - 'read': instance.read, - 'published': instance.published?.toIso8601String(), - 'updated': instance.updated?.toIso8601String(), - 'deleted': instance.deleted, - 'ap_id': instance.apId, - 'local': instance.local, - 'community_id': instance.communityId, - 'community_actor_id': instance.communityActorId, - 'community_local': instance.communityLocal, - 'community_name': instance.communityName, - 'banned': instance.banned, - 'banned_from_community': instance.bannedFromCommunity, - 'creator_actor_id': instance.creatorActorId, - 'creator_local': instance.creatorLocal, - 'creator_name': instance.creatorName, - 'creator_published': instance.creatorPublished?.toIso8601String(), - 'creator_avatar': instance.creatorAvatar, - 'score': instance.score, - 'upvotes': instance.upvotes, - 'downvotes': instance.downvotes, - 'hot_rank': instance.hotRank, - 'userId': instance.userId, - 'myVote': instance.myVote, - 'subscribed': instance.subscribed, - 'saved': instance.saved, - }; diff --git a/lib/client/models/post.dart b/lib/client/models/post.dart index add29b8..12b860a 100644 --- a/lib/client/models/post.dart +++ b/lib/client/models/post.dart @@ -68,7 +68,7 @@ class PostView { /// can be null final bool saved; - PostView({ + const PostView({ this.id, this.name, this.url, diff --git a/lib/client/models/post.g.dart b/lib/client/models/post.g.dart deleted file mode 100644 index 0ed5157..0000000 --- a/lib/client/models/post.g.dart +++ /dev/null @@ -1,101 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'post.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -PostView _$PostViewFromJson(Map json) { - return PostView( - json['id'] as int, - json['name'] as String, - json['url'] as String, - json['body'] as String, - json['creator_id'] as int, - json['community_id'] as int, - json['removed'] as bool, - json['locked'] as bool, - UtilityClass.ParseDateFromJson(json['published'] as String), - UtilityClass.ParseDateFromJson(json['updated'] as String), - json['deleted'] as bool, - json['nsfw'] as bool, - json['stickied'] as bool, - json['embed_title'] as String, - json['embed_description'] as String, - json['embed_html'] as String, - json['thumbnail_url'] as String, - json['ap_id'] as String, - json['local'] as bool, - json['creator_actor_id'] as String, - json['creator_local'] as bool, - json['creator_name'] as String, - UtilityClass.ParseDateFromJson(json['creator_published'] as String), - json['creator_avatar'] as String, - json['banned'] as bool, - json['banned_from_community'] as bool, - json['community_actor_id'] as String, - json['community_local'] as bool, - json['community_name'] as String, - json['community_removed'] as bool, - json['community_deleted'] as bool, - json['community_nsfw'] as bool, - json['number_of_comments'] as int, - json['score'] as int, - json['upvotes'] as int, - json['downvotes'] as int, - json['hot_rank'] as int, - UtilityClass.ParseDateFromJson(json['newest_activity_time'] as String), - json['userId'] as int, - json['myVote'] as int, - json['subscribed'] as bool, - json['read'] as bool, - json['saved'] as bool, - ); -} - -Map _$PostViewToJson(PostView instance) => { - 'id': instance.id, - 'name': instance.postName, - 'url': instance.url, - 'body': instance.body, - 'creator_id': instance.creatorId, - 'community_id': instance.communityId, - 'removed': instance.removed, - 'locked': instance.locked, - 'published': instance.published?.toIso8601String(), - 'updated': instance.updated?.toIso8601String(), - 'deleted': instance.deleted, - 'nsfw': instance.nsfw, - 'stickied': instance.stickied, - 'embed_title': instance.embedTitle, - 'embed_description': instance.embedDescription, - 'embed_html': instance.embedHtml, - 'thumbnail_url': instance.thumbnailUrl, - 'ap_id': instance.apId, - 'local': instance.local, - 'creator_actor_id': instance.creatorActorId, - 'creator_local': instance.creatorLocal, - 'creator_name': instance.creatorName, - 'creator_published': instance.creatorPublished?.toIso8601String(), - 'creator_avatar': instance.creatorAvatar, - 'banned': instance.banned, - 'banned_from_community': instance.bannedFromCommunity, - 'community_actor_id': instance.communityActorId, - 'community_local': instance.communityLocal, - 'community_name': instance.communityName, - 'community_removed': instance.communityRemoved, - 'community_deleted': instance.communityDeleted, - 'community_nsfw': instance.communityNsfw, - 'number_of_comments': instance.numberOfComments, - 'score': instance.score, - 'upvotes': instance.upvotes, - 'downvotes': instance.downvotes, - 'hot_rank': instance.hotRank, - 'newest_activity_time': instance.newestActivityTime?.toIso8601String(), - 'userId': instance.userId, - 'myVote': instance.myVote, - 'subscribed': instance.subscribed, - 'read': instance.read, - 'saved': instance.saved, - }; From 8cc0591dfa2462c9c5173c92ab2bfd30e861ab36 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sat, 8 Aug 2020 23:51:17 +0200 Subject: [PATCH 16/90] Add codegen files --- lib/client/models/comment.g.dart | 51 +++++++++++++++++++++++++ lib/client/models/post.g.dart | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 lib/client/models/comment.g.dart create mode 100644 lib/client/models/post.g.dart diff --git a/lib/client/models/comment.g.dart b/lib/client/models/comment.g.dart new file mode 100644 index 0000000..93d366e --- /dev/null +++ b/lib/client/models/comment.g.dart @@ -0,0 +1,51 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'comment.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CommentView _$CommentViewFromJson(Map json) { + return CommentView( + id: json['id'] as int, + creatorId: json['creator_id'] as int, + postId: json['post_id'] as int, + postName: json['post_name'] as String, + parentId: json['parent_id'] as int, + content: json['content'] as String, + removed: json['removed'] as bool, + read: json['read'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: DateTime.tryParse(json['updated'] as String), + deleted: json['deleted'] as bool, + apId: json['ap_id'] as String, + local: json['local'] as bool, + communityId: json['community_id'] as int, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + banned: json['banned'] as bool, + bannedFromCommunity: json['banned_from_community'] as bool, + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorPublished: json['creator_published'] == null + ? null + : DateTime.parse(json['creator_published'] as String), + creatorAvatar: json['creator_avatar'] as String, + score: json['score'] as int, + upvotes: json['upvotes'] as int, + downvotes: json['downvotes'] as int, + hotRank: json['hot_rank'] as int, + hotRankActive: json['hot_rank_active'] as int, + userId: json['user_id'] as int, + myVote: json['my_vote'] as int, + subscribed: json['subscribed'] as bool, + saved: json['saved'] as bool, + ); +} diff --git a/lib/client/models/post.g.dart b/lib/client/models/post.g.dart new file mode 100644 index 0000000..6e12e5a --- /dev/null +++ b/lib/client/models/post.g.dart @@ -0,0 +1,64 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PostView _$PostViewFromJson(Map json) { + return PostView( + id: json['id'] as int, + name: json['name'] as String, + url: json['url'] as String, + body: json['body'] as String, + creatorId: json['creator_id'] as int, + communityId: json['community_id'] as int, + removed: json['removed'] as bool, + locked: json['locked'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: DateTime.tryParse(json['updated'] as String), + deleted: json['deleted'] as bool, + nsfw: json['nsfw'] as bool, + stickied: json['stickied'] as bool, + embedTitle: json['embed_title'] as String, + embedDescription: json['embed_description'] as String, + embedHtml: json['embed_html'] as String, + thumbnailUrl: json['thumbnail_url'] as String, + apId: json['ap_id'] as String, + local: json['local'] as bool, + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorPublished: json['creator_published'] == null + ? null + : DateTime.parse(json['creator_published'] as String), + creatorAvatar: json['creator_avatar'] as String, + banned: json['banned'] as bool, + bannedFromCommunity: json['banned_from_community'] as bool, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + communityRemoved: json['community_removed'] as bool, + communityDeleted: json['community_deleted'] as bool, + communityNsfw: json['community_nsfw'] as bool, + numberOfComments: json['number_of_comments'] as int, + score: json['score'] as int, + upvotes: json['upvotes'] as int, + downvotes: json['downvotes'] as int, + hotRank: json['hot_rank'] as int, + hotRankActive: json['hot_rank_active'] as int, + newestActivityTime: json['newest_activity_time'] == null + ? null + : DateTime.parse(json['newest_activity_time'] as String), + userId: json['user_id'] as int, + myVote: json['my_vote'] as int, + subscribed: json['subscribed'] as bool, + read: json['read'] as bool, + saved: json['saved'] as bool, + ); +} From 7d902ce3529f824acf6ef18d94b87af75fb0a848 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sat, 8 Aug 2020 23:53:04 +0200 Subject: [PATCH 17/90] Update pubspec.lock --- pubspec.lock | 65 +++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index d568d30..6dad3fa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -15,6 +15,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.39.14" + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.13" args: dependency: transitive description: @@ -28,7 +35,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.2" + version: "2.4.1" boolean_selector: dependency: transitive description: @@ -92,13 +99,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "7.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" charcode: dependency: transitive description: @@ -120,13 +120,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.4" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" code_builder: dependency: transitive description: @@ -140,7 +133,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.13" + version: "1.14.12" convert: dependency: transitive description: @@ -183,13 +176,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.4" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" fixnum: dependency: transitive description: @@ -242,6 +228,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.4" + image: + dependency: transitive + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.12" io: dependency: transitive description: @@ -283,7 +276,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.8" + version: "0.12.6" meta: dependency: transitive description: @@ -325,7 +318,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.4" pedantic: dependency: transitive description: @@ -333,6 +326,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" pool: dependency: transitive description: @@ -400,7 +400,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.5" + version: "1.9.3" stream_channel: dependency: transitive description: @@ -435,7 +435,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.17" + version: "0.2.15" timing: dependency: transitive description: @@ -449,7 +449,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.1.6" vector_math: dependency: transitive description: @@ -471,6 +471,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.6.1" yaml: dependency: transitive description: @@ -479,4 +486,4 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.9.0-14.0.dev <3.0.0" + dart: ">=2.7.0 <3.0.0" From 8f0a2b14b7e5039f63ac6a4c4d8112f3608ca1f0 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 00:27:13 +0200 Subject: [PATCH 18/90] Update return types --- lib/client/v1/comment_endpoint.dart | 15 ++++++++------- lib/client/v1/post_endpoint.dart | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart index 03880ce..8dbb14b 100644 --- a/lib/client/v1/comment_endpoint.dart +++ b/lib/client/v1/comment_endpoint.dart @@ -1,11 +1,12 @@ import 'package:flutter/foundation.dart'; +import '../models/comment.dart'; import 'main.dart'; extension CommentEndpoint on V1 { /// POST /comment /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment - String createComment({ + Future createComment({ @required String content, int parentId, @required int postId, @@ -17,7 +18,7 @@ extension CommentEndpoint on V1 { /// PUT /comment /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-comment - String editComment({ + Future editComment({ @required String content, @required int editId, String formId, @@ -29,7 +30,7 @@ extension CommentEndpoint on V1 { /// POST /comment/delete /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-comment /// Only the creator can delete the comment - String deleteComment({ + Future deleteComment({ @required int editId, @required bool deleted, @required String auth, @@ -40,7 +41,7 @@ extension CommentEndpoint on V1 { /// POST /comment/remove /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-comment /// Only a mod or admin can remove the comment - String removeComment({ + Future removeComment({ @required int editId, @required bool removed, String reason, @@ -51,7 +52,7 @@ extension CommentEndpoint on V1 { /// POST /comment/mark_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-comment-as-read - String markCommentAsRead({ + Future markCommentAsRead({ @required int editId, @required bool read, @required String auth, @@ -61,7 +62,7 @@ extension CommentEndpoint on V1 { /// POST /comment/save /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-comment - String saveComment({ + Future saveComment({ @required int commentId, @required bool save, @required String auth, @@ -71,7 +72,7 @@ extension CommentEndpoint on V1 { /// POST /comment/like /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment-like - String createCommentLike({ + Future createCommentLike({ @required int commentId, @required Vote score, @required String auth, diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 3334046..63681cb 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -1,11 +1,12 @@ import 'package:flutter/foundation.dart'; +import '../models/post.dart'; import 'main.dart'; extension PostEndpoint on V1 { /// POST /post /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#post - String createPost({ + Future createPost({ @required String name, String url, String body, @@ -27,7 +28,7 @@ extension PostEndpoint on V1 { /// GET /post/list /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-posts - String getPosts({ + Future getPosts({ @required String type, @required String sort, int page, @@ -40,7 +41,7 @@ extension PostEndpoint on V1 { /// POST /post/like /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-post-like - String createPostLike({ + Future createPostLike({ @required int postId, @required Vote score, @required String auth, @@ -50,7 +51,7 @@ extension PostEndpoint on V1 { /// PUT /post /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-post - String editPost({ + Future editPost({ @required int editId, @required String name, String url, @@ -64,7 +65,7 @@ extension PostEndpoint on V1 { /// POST /post/delete /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-post /// delete a post in a user deleting their own kind of way - String deletePost({ + Future deletePost({ @required int editId, @required bool deleted, @required String auth, @@ -75,7 +76,7 @@ extension PostEndpoint on V1 { /// POST /post/remove /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-post /// remove post in an admin kind of way - String removePost({ + Future removePost({ @required int editId, @required bool removed, String reason, @@ -86,7 +87,7 @@ extension PostEndpoint on V1 { /// POST /post/save /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-post - String savePost({ + Future savePost({ @required int postId, @required bool save, @required String auth, From 1e84b6057b20e0b3bde82631d78640569aa01b55 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 13:17:32 +0200 Subject: [PATCH 19/90] removed `Date.tryParse` cuz it's not what we thought it was --- lib/client/models/comment.dart | 10 +++++++++- lib/client/models/comment.g.dart | 4 +++- lib/client/models/post.dart | 16 +++++++++++++++- lib/client/models/post.g.dart | 4 +++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/client/models/comment.dart b/lib/client/models/comment.dart index ab322c6..663effd 100644 --- a/lib/client/models/comment.dart +++ b/lib/client/models/comment.dart @@ -9,14 +9,15 @@ class CommentView { final int creatorId; final int postId; final String postName; + /// can be null final int parentId; final String content; final bool removed; final bool read; final DateTime published; + /// can be null - @JsonKey(fromJson: DateTime.tryParse) final DateTime updated; final bool deleted; final String apId; @@ -25,6 +26,7 @@ class CommentView { final String communityActorId; final bool communityLocal; final String communityName; + /// can be null final String communityIcon; final bool banned; @@ -32,9 +34,11 @@ class CommentView { final String creatorActorId; final bool creatorLocal; final String creatorName; + /// can be null final String creatorPreferredUsername; final DateTime creatorPublished; + /// can be null final String creatorAvatar; final int score; @@ -42,12 +46,16 @@ class CommentView { final int downvotes; final int hotRank; final int hotRankActive; + /// can be null final int userId; + /// can be null final int myVote; + /// can be null final bool subscribed; + /// can be null final bool saved; diff --git a/lib/client/models/comment.g.dart b/lib/client/models/comment.g.dart index 93d366e..58ad672 100644 --- a/lib/client/models/comment.g.dart +++ b/lib/client/models/comment.g.dart @@ -19,7 +19,9 @@ CommentView _$CommentViewFromJson(Map json) { published: json['published'] == null ? null : DateTime.parse(json['published'] as String), - updated: DateTime.tryParse(json['updated'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), deleted: json['deleted'] as bool, apId: json['ap_id'] as String, local: json['local'] as bool, diff --git a/lib/client/models/post.dart b/lib/client/models/post.dart index 12b860a..74d2e5c 100644 --- a/lib/client/models/post.dart +++ b/lib/client/models/post.dart @@ -7,8 +7,10 @@ part 'post.g.dart'; class PostView { final int id; final String name; + /// can be null final String url; + /// can be null final String body; final int creatorId; @@ -16,18 +18,22 @@ class PostView { final bool removed; final bool locked; final DateTime published; + /// can be null - @JsonKey(fromJson: DateTime.tryParse) final DateTime updated; final bool deleted; final bool nsfw; final bool stickied; + /// can be null final String embedTitle; + /// can be null final String embedDescription; + /// can be null final String embedHtml; + /// can be null final String thumbnailUrl; final String apId; @@ -35,9 +41,11 @@ class PostView { final String creatorActorId; final bool creatorLocal; final String creatorName; + /// can be null final String creatorPreferredUsername; final DateTime creatorPublished; + /// can be null final String creatorAvatar; final bool banned; @@ -45,6 +53,7 @@ class PostView { final String communityActorId; final bool communityLocal; final String communityName; + /// can be null final String communityIcon; final bool communityRemoved; @@ -57,14 +66,19 @@ class PostView { final int hotRank; final int hotRankActive; final DateTime newestActivityTime; + /// can be null final int userId; + /// can be null final int myVote; + /// can be null final bool subscribed; + /// can be null final bool read; + /// can be null final bool saved; diff --git a/lib/client/models/post.g.dart b/lib/client/models/post.g.dart index 6e12e5a..473db0f 100644 --- a/lib/client/models/post.g.dart +++ b/lib/client/models/post.g.dart @@ -19,7 +19,9 @@ PostView _$PostViewFromJson(Map json) { published: json['published'] == null ? null : DateTime.parse(json['published'] as String), - updated: DateTime.tryParse(json['updated'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), deleted: json['deleted'] as bool, nsfw: json['nsfw'] as bool, stickied: json['stickied'] as bool, From fd8ca3caff451d4bc1060c3603038fcf6ab47cb5 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 13:20:15 +0200 Subject: [PATCH 20/90] let's start testing! --- test/models_test.dart | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 test/models_test.dart diff --git a/test/models_test.dart b/test/models_test.dart new file mode 100644 index 0000000..c28d4ae --- /dev/null +++ b/test/models_test.dart @@ -0,0 +1,52 @@ +import 'dart:convert'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:lemmur/client/models/comment.dart'; + +void main() { + test("CommentView test", () { + Map commentFromApi = jsonDecode(""" + { + "id": 14296, + "creator_id": 8218, + "post_id": 38501, + "post_name": "Niklaus Wirth was right and that is a problem", + "parent_id": 14286, + "content": "I think that the same functionality current crop of apps has could be implemented much more cleanly and efficiently if there wasn't a rush to get products to market. If developers could spend the time to think things through and try different approaches to see what works best we'd have much higher quality software today. Instead, everything is rushed to market as fast as possible, and developers are constantly overwhelmed with unreasonable amounts of work with no time to do things properly or clean things up along the way.", + "removed": false, + "read": true, + "published": "2020-08-02T20:31:19.303284", + "updated": null, + "deleted": false, + "ap_id": "https://dev.lemmy.ml/comment/14296", + "local": true, + "community_id": 14680, + "community_actor_id": "https://dev.lemmy.ml/c/programming", + "community_local": true, + "community_name": "programming", + "community_icon": null, + "banned": false, + "banned_from_community": false, + "creator_actor_id": "https://dev.lemmy.ml/u/yogthos", + "creator_local": true, + "creator_name": "yogthos", + "creator_preferred_username": null, + "creator_published": "2020-01-18T04:02:39.254957", + "creator_avatar": "https://dev.lemmy.ml/pictrs/image/bwk1q2.png", + "score": 1, + "upvotes": 1, + "downvotes": 0, + "hot_rank": 0, + "hot_rank_active": 0, + "user_id": 13709, + "my_vote": 0, + "subscribed": false, + "saved": false + }"""); + + var comment = CommentView.fromJson(commentFromApi); + + print(comment); + expect(14296, comment.id); + expect(8218, comment.creatorId); + }); +} From 63fed075ed5bad88add5d7fe87897772430a0f6e Mon Sep 17 00:00:00 2001 From: shilangyu Date: Sun, 9 Aug 2020 13:19:13 +0000 Subject: [PATCH 21/90] Added community and user views --- lib/client/models/community.dart | 78 ++++++++++++++++++++++++++++++++ lib/client/models/user.dart | 36 +++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 lib/client/models/community.dart create mode 100644 lib/client/models/user.dart diff --git a/lib/client/models/community.dart b/lib/client/models/community.dart new file mode 100644 index 0000000..1b395f9 --- /dev/null +++ b/lib/client/models/community.dart @@ -0,0 +1,78 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'community.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L130 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class CommunityView { + final int id; + final String name; + final String title; + /// can be null + final String icon; + /// can be null + final String banner; + /// can be null + final String description; + final int categoryId; + final int creatorId; + final bool removed; + final DateTime published; + /// can be null + final DateTime updated; + final bool deleted; + final bool nsfw; + final String actorId; + final bool local; + final DateTime lastRefreshedAt; + final String creatorActorId; + final bool creatorLocal; + final String creatorName; + /// can be null + final String creatorPreferredUsername; + /// can be null + final String creatorAvatar; + final String categoryName; + final int numberOfSubscribers; + final int numberOfPosts; + final int numberOfComments; + final int hotRank; + /// can be null + final int userId; + /// can be null + final bool subscribed; + + const CommunityView({ + this.id, + this.name, + this.title, + this.icon, + this.banner, + this.description, + this.categoryId, + this.creatorId, + this.removed, + this.published, + this.updated, + this.deleted, + this.nsfw, + this.actorId, + this.local, + this.lastRefreshedAt, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPreferredUsername, + this.creatorAvatar, + this.categoryName, + this.numberOfSubscribers, + this.numberOfPosts, + this.numberOfComments, + this.hotRank, + this.userId, + this.subscribed, + }); + + factory CommunityView.fromJson(Map json) => + _$CommunityViewFromJson(json); +} diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart new file mode 100644 index 0000000..15e3044 --- /dev/null +++ b/lib/client/models/user.dart @@ -0,0 +1,36 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'user.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/user_view.rs#L58 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class UserView { + final int id; + final String actorId; + final String name; + /// can be null + final String preferredUsername; + /// can be null + final String avatar; + /// can be null + final String banner; + /// can be null + final String email; + /// can be null + final String matrixUserId; + /// can be null + final String bio; + final bool local; + final bool admin; + final bool banned; + final bool showAvatars; + final bool sendNotificationsToEmail; + final DateTime published; + final int numberOfPosts; + final int postScore; + final int numberOfComments; + final int commentScore; + + factory UserView.fromJson(Map json) => + _$UserViewFromJson(json); +} From 4de70c8c242c292499900934e8b9296173d49d18 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Sun, 9 Aug 2020 18:14:06 +0000 Subject: [PATCH 22/90] added PrivateMessage and Reply views --- lib/client/models/comment.dart | 92 ++++++++++++++++++++++++++ lib/client/models/private_message.dart | 59 +++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 lib/client/models/private_message.dart diff --git a/lib/client/models/comment.dart b/lib/client/models/comment.dart index 663effd..cf306f3 100644 --- a/lib/client/models/comment.dart +++ b/lib/client/models/comment.dart @@ -100,3 +100,95 @@ class CommentView { factory CommentView.fromJson(Map json) => _$CommentViewFromJson(json); } + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/comment_view.rs#L356 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class ReplyView { + final int id; + final int creatorId; + final int postId; + final String postName; + /// can be null + final int parentId; + final String content; + final bool removed; + final bool read; + final DateTime published; + /// can be null + final DateTime updated; + final bool deleted; + final String apId; + final bool local; + final int communityId; + final String communityActorId; + final bool communityLocal; + final String communityName; + /// can be null + final String communityIcon; + final bool banned; + final bool bannedFromCommunity; + final String creatorActorId; + final bool creatorLocal; + final String creatorName; + /// can be null + final String creatorPreferredUsername; + /// can be null + final String creatorAvatar; + final DateTime creatorPublished; + final int score; + final int upvotes; + final int downvotes; + final int hotRank; + final int hotRankActive; + /// can be null + final int userId; + /// can be null + final int myVote; + /// can be null + final bool subscribed; + /// can be null + final bool saved; + final int recipientId; + + const ReplyView({ + this.id, + this.creatorId, + this.postId, + this.postName, + this.parentId, + this.content, + this.removed, + this.read, + this.published, + this.updated, + this.deleted, + this.apId, + this.local, + this.communityId, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityIcon, + this.banned, + this.bannedFromCommunity, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPreferredUsername, + this.creatorAvatar, + this.creatorPublished, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.hotRankActive, + this.userId, + this.myVote, + this.subscribed, + this.saved, + this.recipientId, + }); + + factory ReplyView.fromJson(Map json) => + _$ReplyViewFromJson(json); +} diff --git a/lib/client/models/private_message.dart b/lib/client/models/private_message.dart new file mode 100644 index 0000000..13c3af8 --- /dev/null +++ b/lib/client/models/private_message.dart @@ -0,0 +1,59 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'private_message.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/private_message_view.rs#L35 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class PrivateMessageView { + final int id; + final int creatorId; + final int recipientId; + final String content; + final bool deleted; + final bool read; + final DateTime published; + /// can be null + final DateTime updated; + final String apId; + final bool local; + final String creatorName; + /// can be null + final String creatorPreferredUsername; + /// can be null + final String creatorAvatar; + final String creatorActorId; + final bool creatorLocal; + final String recipientName; + /// can be null + final String recipientPreferredUsername; + /// can be null + final String recipientAvatar; + final String recipientActorId; + final bool recipientLocal; + + const PrivateMessageView({ + this.id, + this.creatorId, + this.recipientId, + this.content, + this.deleted, + this.read, + this.published, + this.updated, + this.apId, + this.local, + this.creatorName, + this.creatorPreferredUsername, + this.creatorAvatar, + this.creatorActorId, + this.creatorLocal, + this.recipientName, + this.recipientPreferredUsername, + this.recipientAvatar, + this.recipientActorId, + this.recipientLocal, + }); + + factory PrivateMessageView.fromJson(Map json) => + _$PrivateMessageViewFromJson(json); +} From 8dee300ffae11c5c88751422c30806cba82c1d9a Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 21:15:05 +0200 Subject: [PATCH 23/90] Add constructor (+ autoformat) --- lib/client/models/user.dart | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart index 15e3044..279150c 100644 --- a/lib/client/models/user.dart +++ b/lib/client/models/user.dart @@ -8,16 +8,22 @@ class UserView { final int id; final String actorId; final String name; + /// can be null final String preferredUsername; + /// can be null final String avatar; + /// can be null final String banner; + /// can be null final String email; + /// can be null final String matrixUserId; + /// can be null final String bio; final bool local; @@ -31,6 +37,27 @@ class UserView { final int numberOfComments; final int commentScore; + const UserView({ + this.id, + this.actorId, + this.name, + this.preferredUsername, + this.avatar, + this.banner, + this.email, + this.matrixUserId, + this.bio, + this.local, + this.admin, + this.banned, + this.showAvatars, + this.sendNotificationsToEmail, + this.published, + this.numberOfPosts, + this.postScore, + this.numberOfComments, + this.commentScore, + }); factory UserView.fromJson(Map json) => _$UserViewFromJson(json); } From 047274f722f9d2ddb85bb7822e3e38e553b5e7a5 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 21:15:26 +0200 Subject: [PATCH 24/90] Add codegen files --- lib/client/models/community.g.dart | 46 ++++++++++++++++++++++++++++++ lib/client/models/user.g.dart | 33 +++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 lib/client/models/community.g.dart create mode 100644 lib/client/models/user.g.dart diff --git a/lib/client/models/community.g.dart b/lib/client/models/community.g.dart new file mode 100644 index 0000000..9deeb67 --- /dev/null +++ b/lib/client/models/community.g.dart @@ -0,0 +1,46 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'community.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CommunityView _$CommunityViewFromJson(Map json) { + return CommunityView( + id: json['id'] as int, + name: json['name'] as String, + title: json['title'] as String, + icon: json['icon'] as String, + banner: json['banner'] as String, + description: json['description'] as String, + categoryId: json['category_id'] as int, + creatorId: json['creator_id'] as int, + removed: json['removed'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), + deleted: json['deleted'] as bool, + nsfw: json['nsfw'] as bool, + actorId: json['actor_id'] as String, + local: json['local'] as bool, + lastRefreshedAt: json['last_refreshed_at'] == null + ? null + : DateTime.parse(json['last_refreshed_at'] as String), + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorAvatar: json['creator_avatar'] as String, + categoryName: json['category_name'] as String, + numberOfSubscribers: json['number_of_subscribers'] as int, + numberOfPosts: json['number_of_posts'] as int, + numberOfComments: json['number_of_comments'] as int, + hotRank: json['hot_rank'] as int, + userId: json['user_id'] as int, + subscribed: json['subscribed'] as bool, + ); +} diff --git a/lib/client/models/user.g.dart b/lib/client/models/user.g.dart new file mode 100644 index 0000000..4cc61e2 --- /dev/null +++ b/lib/client/models/user.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +UserView _$UserViewFromJson(Map json) { + return UserView( + id: json['id'] as int, + actorId: json['actor_id'] as String, + name: json['name'] as String, + preferredUsername: json['preferred_username'] as String, + avatar: json['avatar'] as String, + banner: json['banner'] as String, + email: json['email'] as String, + matrixUserId: json['matrix_user_id'] as String, + bio: json['bio'] as String, + local: json['local'] as bool, + admin: json['admin'] as bool, + banned: json['banned'] as bool, + showAvatars: json['show_avatars'] as bool, + sendNotificationsToEmail: json['send_notifications_to_email'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + numberOfPosts: json['number_of_posts'] as int, + postScore: json['post_score'] as int, + numberOfComments: json['number_of_comments'] as int, + commentScore: json['comment_score'] as int, + ); +} From 33a00e062868e1a07e9c0155b08cfb69acdf6202 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 21:17:22 +0200 Subject: [PATCH 25/90] Update codegen files --- lib/client/models/comment.g.dart | 47 ++++++++++++++++++++++++ lib/client/models/private_message.g.dart | 36 ++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 lib/client/models/private_message.g.dart diff --git a/lib/client/models/comment.g.dart b/lib/client/models/comment.g.dart index 58ad672..14cb8e3 100644 --- a/lib/client/models/comment.g.dart +++ b/lib/client/models/comment.g.dart @@ -51,3 +51,50 @@ CommentView _$CommentViewFromJson(Map json) { saved: json['saved'] as bool, ); } + +ReplyView _$ReplyViewFromJson(Map json) { + return ReplyView( + id: json['id'] as int, + creatorId: json['creator_id'] as int, + postId: json['post_id'] as int, + postName: json['post_name'] as String, + parentId: json['parent_id'] as int, + content: json['content'] as String, + removed: json['removed'] as bool, + read: json['read'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), + deleted: json['deleted'] as bool, + apId: json['ap_id'] as String, + local: json['local'] as bool, + communityId: json['community_id'] as int, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + banned: json['banned'] as bool, + bannedFromCommunity: json['banned_from_community'] as bool, + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorAvatar: json['creator_avatar'] as String, + creatorPublished: json['creator_published'] == null + ? null + : DateTime.parse(json['creator_published'] as String), + score: json['score'] as int, + upvotes: json['upvotes'] as int, + downvotes: json['downvotes'] as int, + hotRank: json['hot_rank'] as int, + hotRankActive: json['hot_rank_active'] as int, + userId: json['user_id'] as int, + myVote: json['my_vote'] as int, + subscribed: json['subscribed'] as bool, + saved: json['saved'] as bool, + recipientId: json['recipient_id'] as int, + ); +} diff --git a/lib/client/models/private_message.g.dart b/lib/client/models/private_message.g.dart new file mode 100644 index 0000000..6733bff --- /dev/null +++ b/lib/client/models/private_message.g.dart @@ -0,0 +1,36 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'private_message.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PrivateMessageView _$PrivateMessageViewFromJson(Map json) { + return PrivateMessageView( + id: json['id'] as int, + creatorId: json['creator_id'] as int, + recipientId: json['recipient_id'] as int, + content: json['content'] as String, + deleted: json['deleted'] as bool, + read: json['read'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), + apId: json['ap_id'] as String, + local: json['local'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorAvatar: json['creator_avatar'] as String, + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + recipientName: json['recipient_name'] as String, + recipientPreferredUsername: json['recipient_preferred_username'] as String, + recipientAvatar: json['recipient_avatar'] as String, + recipientActorId: json['recipient_actor_id'] as String, + recipientLocal: json['recipient_local'] as bool, + ); +} From 6120cb58f765e159d68c44f71213034084c40b1f Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 21:32:58 +0200 Subject: [PATCH 26/90] Add tests for CommentView --- test/models_test.dart | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/test/models_test.dart b/test/models_test.dart index c28d4ae..f5016b9 100644 --- a/test/models_test.dart +++ b/test/models_test.dart @@ -45,8 +45,43 @@ void main() { var comment = CommentView.fromJson(commentFromApi); - print(comment); - expect(14296, comment.id); - expect(8218, comment.creatorId); + expect(comment.id, 14296); + expect(comment.creatorId, 8218); + expect(comment.postId, 38501); + expect(comment.postName, "Niklaus Wirth was right and that is a problem"); + expect(comment.parentId, 14286); + expect(comment.content, + "I think that the same functionality current crop of apps has could be implemented much more cleanly and efficiently if there wasn't a rush to get products to market. If developers could spend the time to think things through and try different approaches to see what works best we'd have much higher quality software today. Instead, everything is rushed to market as fast as possible, and developers are constantly overwhelmed with unreasonable amounts of work with no time to do things properly or clean things up along the way."); + expect(comment.removed, false); + expect(comment.read, true); + expect(comment.published, DateTime.parse("2020-08-02T20:31:19.303284")); + expect(comment.updated, null); + expect(comment.deleted, false); + expect(comment.apId, "https://dev.lemmy.ml/comment/14296"); + expect(comment.local, true); + expect(comment.communityId, 14680); + expect(comment.communityActorId, "https://dev.lemmy.ml/c/programming"); + expect(comment.communityLocal, true); + expect(comment.communityName, "programming"); + expect(comment.communityIcon, null); + expect(comment.banned, false); + expect(comment.bannedFromCommunity, false); + expect(comment.creatorActorId, "https://dev.lemmy.ml/u/yogthos"); + expect(comment.creatorLocal, true); + expect(comment.creatorName, "yogthos"); + expect(comment.creatorPreferredUsername, null); + expect( + comment.creatorPublished, DateTime.parse("2020-01-18T04:02:39.254957")); + expect( + comment.creatorAvatar, "https://dev.lemmy.ml/pictrs/image/bwk1q2.png"); + expect(comment.score, 1); + expect(comment.upvotes, 1); + expect(comment.downvotes, 0); + expect(comment.hotRank, 0); + expect(comment.hotRankActive, 0); + expect(comment.userId, 13709); + expect(comment.myVote, 0); + expect(comment.subscribed, false); + expect(comment.saved, false); }); } From 03c2669ad3a0866649453d9acff733b0952fb953 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 21:43:08 +0200 Subject: [PATCH 27/90] Add PostView test --- test/models_test.dart | 103 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/test/models_test.dart b/test/models_test.dart index f5016b9..9d45d30 100644 --- a/test/models_test.dart +++ b/test/models_test.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/models/comment.dart'; +import 'package:lemmur/client/models/post.dart'; void main() { test("CommentView test", () { @@ -84,4 +85,106 @@ void main() { expect(comment.subscribed, false); expect(comment.saved, false); }); + test("PostView test", () { + Map postJson = jsonDecode(""" + { + "id": 38501, + "name": "Niklaus Wirth was right and that is a problem", + "url": "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/", + "body": null, + "creator_id": 8218, + "community_id": 14680, + "removed": false, + "locked": false, + "published": "2020-08-02T01:56:28.072727", + "updated": null, + "deleted": false, + "nsfw": false, + "stickied": false, + "embed_title": "Niklaus Wirth was right and that is a problem", + "embed_description": null, + "embed_html": null, + "thumbnail_url": null, + "ap_id": "https://dev.lemmy.ml/post/38501", + "local": true, + "creator_actor_id": "https://dev.lemmy.ml/u/yogthos", + "creator_local": true, + "creator_name": "yogthos", + "creator_preferred_username": null, + "creator_published": "2020-01-18T04:02:39.254957", + "creator_avatar": "https://dev.lemmy.ml/pictrs/image/bwk1q2.png", + "banned": false, + "banned_from_community": false, + "community_actor_id": "https://dev.lemmy.ml/c/programming", + "community_local": true, + "community_name": "programming", + "community_icon": null, + "community_removed": false, + "community_deleted": false, + "community_nsfw": false, + "number_of_comments": 4, + "score": 8, + "upvotes": 8, + "downvotes": 0, + "hot_rank": 1, + "hot_rank_active": 1, + "newest_activity_time": "2020-08-02T20:31:19.303284", + "user_id": 13709, + "my_vote": 0, + "subscribed": false, + "read": false, + "saved": false + }"""); + + var post = PostView.fromJson(postJson); + + expect(post.id, 38501); + expect(post.name, "Niklaus Wirth was right and that is a problem"); + expect(post.url, + "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/"); + expect(post.body, null); + expect(post.creatorId, 8218); + expect(post.communityId, 14680); + expect(post.removed, false); + expect(post.locked, false); + expect(post.published, DateTime.parse("2020-08-02T01:56:28.072727")); + expect(post.updated, null); + expect(post.deleted, false); + expect(post.nsfw, false); + expect(post.stickied, false); + expect(post.embedTitle, "Niklaus Wirth was right and that is a problem"); + expect(post.embedDescription, null); + expect(post.embedHtml, null); + expect(post.thumbnailUrl, null); + expect(post.apId, "https://dev.lemmy.ml/post/38501"); + expect(post.local, true); + expect(post.creatorActorId, "https://dev.lemmy.ml/u/yogthos"); + expect(post.creatorLocal, true); + expect(post.creatorName, "yogthos"); + expect(post.creatorPreferredUsername, null); + expect(post.creatorPublished, DateTime.parse("2020-01-18T04:02:39.254957")); + expect(post.creatorAvatar, "https://dev.lemmy.ml/pictrs/image/bwk1q2.png"); + expect(post.banned, false); + expect(post.bannedFromCommunity, false); + expect(post.communityActorId, "https://dev.lemmy.ml/c/programming"); + expect(post.communityLocal, true); + expect(post.communityName, "programming"); + expect(post.communityIcon, null); + expect(post.communityRemoved, false); + expect(post.communityDeleted, false); + expect(post.communityNsfw, false); + expect(post.numberOfComments, 4); + expect(post.score, 8); + expect(post.upvotes, 8); + expect(post.downvotes, 0); + expect(post.hotRank, 1); + expect(post.hotRankActive, 1); + expect( + post.newestActivityTime, DateTime.parse("2020-08-02T20:31:19.303284")); + expect(post.userId, 13709); + expect(post.myVote, 0); + expect(post.subscribed, false); + expect(post.read, false); + expect(post.saved, false); + }); } From 5adee282b6cfdb777d82715d50f1651f33bcf8e6 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 22:52:17 +0200 Subject: [PATCH 28/90] shuffled tests around --- ...models_test.dart => commentview_test.dart} | 103 ----------------- test/postview_test.dart | 109 ++++++++++++++++++ 2 files changed, 109 insertions(+), 103 deletions(-) rename test/{models_test.dart => commentview_test.dart} (51%) create mode 100644 test/postview_test.dart diff --git a/test/models_test.dart b/test/commentview_test.dart similarity index 51% rename from test/models_test.dart rename to test/commentview_test.dart index 9d45d30..f5016b9 100644 --- a/test/models_test.dart +++ b/test/commentview_test.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/models/comment.dart'; -import 'package:lemmur/client/models/post.dart'; void main() { test("CommentView test", () { @@ -85,106 +84,4 @@ void main() { expect(comment.subscribed, false); expect(comment.saved, false); }); - test("PostView test", () { - Map postJson = jsonDecode(""" - { - "id": 38501, - "name": "Niklaus Wirth was right and that is a problem", - "url": "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/", - "body": null, - "creator_id": 8218, - "community_id": 14680, - "removed": false, - "locked": false, - "published": "2020-08-02T01:56:28.072727", - "updated": null, - "deleted": false, - "nsfw": false, - "stickied": false, - "embed_title": "Niklaus Wirth was right and that is a problem", - "embed_description": null, - "embed_html": null, - "thumbnail_url": null, - "ap_id": "https://dev.lemmy.ml/post/38501", - "local": true, - "creator_actor_id": "https://dev.lemmy.ml/u/yogthos", - "creator_local": true, - "creator_name": "yogthos", - "creator_preferred_username": null, - "creator_published": "2020-01-18T04:02:39.254957", - "creator_avatar": "https://dev.lemmy.ml/pictrs/image/bwk1q2.png", - "banned": false, - "banned_from_community": false, - "community_actor_id": "https://dev.lemmy.ml/c/programming", - "community_local": true, - "community_name": "programming", - "community_icon": null, - "community_removed": false, - "community_deleted": false, - "community_nsfw": false, - "number_of_comments": 4, - "score": 8, - "upvotes": 8, - "downvotes": 0, - "hot_rank": 1, - "hot_rank_active": 1, - "newest_activity_time": "2020-08-02T20:31:19.303284", - "user_id": 13709, - "my_vote": 0, - "subscribed": false, - "read": false, - "saved": false - }"""); - - var post = PostView.fromJson(postJson); - - expect(post.id, 38501); - expect(post.name, "Niklaus Wirth was right and that is a problem"); - expect(post.url, - "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/"); - expect(post.body, null); - expect(post.creatorId, 8218); - expect(post.communityId, 14680); - expect(post.removed, false); - expect(post.locked, false); - expect(post.published, DateTime.parse("2020-08-02T01:56:28.072727")); - expect(post.updated, null); - expect(post.deleted, false); - expect(post.nsfw, false); - expect(post.stickied, false); - expect(post.embedTitle, "Niklaus Wirth was right and that is a problem"); - expect(post.embedDescription, null); - expect(post.embedHtml, null); - expect(post.thumbnailUrl, null); - expect(post.apId, "https://dev.lemmy.ml/post/38501"); - expect(post.local, true); - expect(post.creatorActorId, "https://dev.lemmy.ml/u/yogthos"); - expect(post.creatorLocal, true); - expect(post.creatorName, "yogthos"); - expect(post.creatorPreferredUsername, null); - expect(post.creatorPublished, DateTime.parse("2020-01-18T04:02:39.254957")); - expect(post.creatorAvatar, "https://dev.lemmy.ml/pictrs/image/bwk1q2.png"); - expect(post.banned, false); - expect(post.bannedFromCommunity, false); - expect(post.communityActorId, "https://dev.lemmy.ml/c/programming"); - expect(post.communityLocal, true); - expect(post.communityName, "programming"); - expect(post.communityIcon, null); - expect(post.communityRemoved, false); - expect(post.communityDeleted, false); - expect(post.communityNsfw, false); - expect(post.numberOfComments, 4); - expect(post.score, 8); - expect(post.upvotes, 8); - expect(post.downvotes, 0); - expect(post.hotRank, 1); - expect(post.hotRankActive, 1); - expect( - post.newestActivityTime, DateTime.parse("2020-08-02T20:31:19.303284")); - expect(post.userId, 13709); - expect(post.myVote, 0); - expect(post.subscribed, false); - expect(post.read, false); - expect(post.saved, false); - }); } diff --git a/test/postview_test.dart b/test/postview_test.dart new file mode 100644 index 0000000..d1e2ce2 --- /dev/null +++ b/test/postview_test.dart @@ -0,0 +1,109 @@ +import 'dart:convert'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:lemmur/client/models/post.dart'; + +void main() { + test("PostView test", () { + Map postJson = jsonDecode(""" + { + "id": 38501, + "name": "Niklaus Wirth was right and that is a problem", + "url": "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/", + "body": null, + "creator_id": 8218, + "community_id": 14680, + "removed": false, + "locked": false, + "published": "2020-08-02T01:56:28.072727", + "updated": null, + "deleted": false, + "nsfw": false, + "stickied": false, + "embed_title": "Niklaus Wirth was right and that is a problem", + "embed_description": null, + "embed_html": null, + "thumbnail_url": null, + "ap_id": "https://dev.lemmy.ml/post/38501", + "local": true, + "creator_actor_id": "https://dev.lemmy.ml/u/yogthos", + "creator_local": true, + "creator_name": "yogthos", + "creator_preferred_username": null, + "creator_published": "2020-01-18T04:02:39.254957", + "creator_avatar": "https://dev.lemmy.ml/pictrs/image/bwk1q2.png", + "banned": false, + "banned_from_community": false, + "community_actor_id": "https://dev.lemmy.ml/c/programming", + "community_local": true, + "community_name": "programming", + "community_icon": null, + "community_removed": false, + "community_deleted": false, + "community_nsfw": false, + "number_of_comments": 4, + "score": 8, + "upvotes": 8, + "downvotes": 0, + "hot_rank": 1, + "hot_rank_active": 1, + "newest_activity_time": "2020-08-02T20:31:19.303284", + "user_id": 13709, + "my_vote": 0, + "subscribed": false, + "read": false, + "saved": false + }"""); + + var post = PostView.fromJson(postJson); + + expect(post.id, 38501); + expect(post.name, "Niklaus Wirth was right and that is a problem"); + expect(post.url, + "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/"); + expect(post.body, null); + expect(post.creatorId, 8218); + expect(post.communityId, 14680); + expect(post.removed, false); + expect(post.locked, false); + expect(post.published, DateTime.parse("2020-08-02T01:56:28.072727")); + expect(post.updated, null); + expect(post.deleted, false); + expect(post.nsfw, false); + expect(post.stickied, false); + expect(post.embedTitle, "Niklaus Wirth was right and that is a problem"); + expect(post.embedDescription, null); + expect(post.embedHtml, null); + expect(post.thumbnailUrl, null); + expect(post.apId, "https://dev.lemmy.ml/post/38501"); + expect(post.local, true); + expect(post.creatorActorId, "https://dev.lemmy.ml/u/yogthos"); + expect(post.creatorLocal, true); + expect(post.creatorName, "yogthos"); + expect(post.creatorPreferredUsername, null); + expect(post.creatorPublished, DateTime.parse("2020-01-18T04:02:39.254957")); + expect(post.creatorAvatar, "https://dev.lemmy.ml/pictrs/image/bwk1q2.png"); + expect(post.banned, false); + expect(post.bannedFromCommunity, false); + expect(post.communityActorId, "https://dev.lemmy.ml/c/programming"); + expect(post.communityLocal, true); + expect(post.communityName, "programming"); + expect(post.communityIcon, null); + expect(post.communityRemoved, false); + expect(post.communityDeleted, false); + expect(post.communityNsfw, false); + expect(post.numberOfComments, 4); + expect(post.score, 8); + expect(post.upvotes, 8); + expect(post.downvotes, 0); + expect(post.hotRank, 1); + expect(post.hotRankActive, 1); + expect( + post.newestActivityTime, DateTime.parse("2020-08-02T20:31:19.303284")); + expect(post.userId, 13709); + expect(post.myVote, 0); + expect(post.subscribed, false); + expect(post.read, false); + expect(post.saved, false); + }); +} From 4594632f9a37ccde9f8d9b66dfece274c3deb34d Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 23:01:53 +0200 Subject: [PATCH 29/90] Add `UserView` tests --- test/userview_test.dart | 53 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 test/userview_test.dart diff --git a/test/userview_test.dart b/test/userview_test.dart new file mode 100644 index 0000000..264b1a9 --- /dev/null +++ b/test/userview_test.dart @@ -0,0 +1,53 @@ +import 'dart:convert'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:lemmur/client/models/user.dart'; + +void main() { + test("UserView test", () { + Map userJson = jsonDecode(""" + { + "id": 13709, + "actor_id": "https://dev.lemmy.ml/u/krawieck", + "name": "krawieck", + "preferred_username": null, + "avatar": null, + "banner": null, + "email": null, + "matrix_user_id": null, + "bio": null, + "local": true, + "admin": false, + "banned": false, + "show_avatars": true, + "send_notifications_to_email": false, + "published": "2020-08-03T12:22:12.389085", + "number_of_posts": 0, + "post_score": 0, + "number_of_comments": 0, + "comment_score": 0 + }"""); + + var user = UserView.fromJson(userJson); + + expect(user.id, 13709); + expect(user.actorId, "https://dev.lemmy.ml/u/krawieck"); + expect(user.name, "krawieck"); + expect(user.preferredUsername, null); + expect(user.avatar, null); + expect(user.banner, null); + expect(user.email, null); + expect(user.matrixUserId, null); + expect(user.bio, null); + expect(user.local, true); + expect(user.admin, false); + expect(user.banned, false); + expect(user.showAvatars, true); + expect(user.sendNotificationsToEmail, false); + expect(user.published, DateTime.parse("2020-08-03T12:22:12.389085")); + expect(user.numberOfPosts, 0); + expect(user.postScore, 0); + expect(user.numberOfComments, 0); + expect(user.commentScore, 0); + }); +} From 039fd6e6a05ead3db06a88fff5c6b9e484c962a9 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 23:03:44 +0200 Subject: [PATCH 30/90] Autoformat --- lib/client/models/comment.dart | 9 +++++++++ lib/client/models/community.dart | 8 ++++++++ lib/client/models/private_message.dart | 5 +++++ 3 files changed, 22 insertions(+) diff --git a/lib/client/models/comment.dart b/lib/client/models/comment.dart index cf306f3..d6d157a 100644 --- a/lib/client/models/comment.dart +++ b/lib/client/models/comment.dart @@ -108,12 +108,14 @@ class ReplyView { final int creatorId; final int postId; final String postName; + /// can be null final int parentId; final String content; final bool removed; final bool read; final DateTime published; + /// can be null final DateTime updated; final bool deleted; @@ -123,6 +125,7 @@ class ReplyView { final String communityActorId; final bool communityLocal; final String communityName; + /// can be null final String communityIcon; final bool banned; @@ -130,8 +133,10 @@ class ReplyView { final String creatorActorId; final bool creatorLocal; final String creatorName; + /// can be null final String creatorPreferredUsername; + /// can be null final String creatorAvatar; final DateTime creatorPublished; @@ -140,12 +145,16 @@ class ReplyView { final int downvotes; final int hotRank; final int hotRankActive; + /// can be null final int userId; + /// can be null final int myVote; + /// can be null final bool subscribed; + /// can be null final bool saved; final int recipientId; diff --git a/lib/client/models/community.dart b/lib/client/models/community.dart index 1b395f9..88ad9f6 100644 --- a/lib/client/models/community.dart +++ b/lib/client/models/community.dart @@ -8,16 +8,20 @@ class CommunityView { final int id; final String name; final String title; + /// can be null final String icon; + /// can be null final String banner; + /// can be null final String description; final int categoryId; final int creatorId; final bool removed; final DateTime published; + /// can be null final DateTime updated; final bool deleted; @@ -28,8 +32,10 @@ class CommunityView { final String creatorActorId; final bool creatorLocal; final String creatorName; + /// can be null final String creatorPreferredUsername; + /// can be null final String creatorAvatar; final String categoryName; @@ -37,8 +43,10 @@ class CommunityView { final int numberOfPosts; final int numberOfComments; final int hotRank; + /// can be null final int userId; + /// can be null final bool subscribed; diff --git a/lib/client/models/private_message.dart b/lib/client/models/private_message.dart index 13c3af8..32a6d55 100644 --- a/lib/client/models/private_message.dart +++ b/lib/client/models/private_message.dart @@ -12,20 +12,25 @@ class PrivateMessageView { final bool deleted; final bool read; final DateTime published; + /// can be null final DateTime updated; final String apId; final bool local; final String creatorName; + /// can be null final String creatorPreferredUsername; + /// can be null final String creatorAvatar; final String creatorActorId; final bool creatorLocal; final String recipientName; + /// can be null final String recipientPreferredUsername; + /// can be null final String recipientAvatar; final String recipientActorId; From 1b34add11e24be43191ca59c299393d9adb54138 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 23:09:48 +0200 Subject: [PATCH 31/90] Add `CommunityView` tests --- test/communityview_test.dart | 72 ++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 test/communityview_test.dart diff --git a/test/communityview_test.dart b/test/communityview_test.dart new file mode 100644 index 0000000..87716a0 --- /dev/null +++ b/test/communityview_test.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:lemmur/client/models/community.dart'; + +void main() { + test("PostView test", () { + Map communityJson = jsonDecode(""" + { + "id": 3, + "name": "haskell", + "title": "The Haskell Lemmy Forum", + "icon": null, + "banner": null, + "description": null, + "category_id": 21, + "creator_id": 77, + "removed": false, + "published": "2019-04-22T17:52:37.759443", + "updated": null, + "deleted": false, + "nsfw": false, + "actor_id": "https://dev.lemmy.ml/c/haskell", + "local": true, + "last_refreshed_at": "2020-06-30T00:49:22.589810", + "creator_actor_id": "https://dev.lemmy.ml/u/topos", + "creator_local": true, + "creator_name": "topos", + "creator_preferred_username": null, + "creator_avatar": null, + "category_name": "Programming/Software", + "number_of_subscribers": 85, + "number_of_posts": 0, + "number_of_comments": 0, + "hot_rank": 0, + "user_id": null, + "subscribed": null + }"""); + + var community = CommunityView.fromJson(communityJson); + + expect(community.id, 3); + expect(community.name, "haskell"); + expect(community.title, "The Haskell Lemmy Forum"); + expect(community.icon, null); + expect(community.banner, null); + expect(community.description, null); + expect(community.categoryId, 21); + expect(community.creatorId, 77); + expect(community.removed, false); + expect(community.published, DateTime.parse("2019-04-22T17:52:37.759443")); + expect(community.updated, null); + expect(community.deleted, false); + expect(community.nsfw, false); + expect(community.actorId, "https://dev.lemmy.ml/c/haskell"); + expect(community.local, true); + expect(community.lastRefreshedAt, + DateTime.parse("2020-06-30T00:49:22.589810")); + expect(community.creatorActorId, "https://dev.lemmy.ml/u/topos"); + expect(community.creatorLocal, true); + expect(community.creatorName, "topos"); + expect(community.creatorPreferredUsername, null); + expect(community.creatorAvatar, null); + expect(community.categoryName, "Programming/Software"); + expect(community.numberOfSubscribers, 85); + expect(community.numberOfPosts, 0); + expect(community.numberOfComments, 0); + expect(community.hotRank, 0); + expect(community.userId, null); + expect(community.subscribed, null); + }); +} From 9c101868a3ec70fe8bed359d13e51fe296bc7135 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 23:20:21 +0200 Subject: [PATCH 32/90] stfu mr linter --- lib/client/v1/main.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 51a0058..d18268f 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -46,5 +46,6 @@ extension VoteValue on Vote { case Vote.down: return -1; } + throw Exception("unreachable"); } } From 8ab016076a7c0615294a1b0a8ff8f9578702e4d8 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 23:24:06 +0200 Subject: [PATCH 33/90] Add `Captcha` class and return type --- lib/client/v1/main.dart | 9 +++++++++ lib/client/v1/user_endpoint.dart | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index d18268f..fd200e2 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -49,3 +49,12 @@ extension VoteValue on Vote { throw Exception("unreachable"); } } + +class Captcha { + final String png; + + /// can be null + final String wav; + final String uuid; + Captcha({this.png, this.wav, this.uuid}); +} diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 26b2b97..a5837a8 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -25,7 +25,7 @@ extension UserEndpoint on V1 { /// GET /user/get_captcha /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha - String getCaptcha() { + Future getCaptcha() { throw UnimplementedError(); } From ca9759db47f577dff3072fbfda10d8b52fe617c8 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 9 Aug 2020 23:32:42 +0200 Subject: [PATCH 34/90] Add more return types --- lib/client/v1/user_endpoint.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index a5837a8..a222155 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import '../models/private_message.dart'; import 'main.dart'; @@ -92,7 +93,7 @@ extension UserEndpoint on V1 { /// GET /private_message/list /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-private-messages - String getPrivateMessages({ + Future> getPrivateMessages({ @required bool unreadOnly, int page, int limit, @@ -103,7 +104,7 @@ extension UserEndpoint on V1 { /// POST /private_message /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-private-message - String createPrivateMessage({ + Future createPrivateMessage({ @required String content, @required int recipientId, @required String auth, @@ -113,7 +114,7 @@ extension UserEndpoint on V1 { /// PUT /private_message /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-private-message - String editPrivateMessage({ + Future editPrivateMessage({ @required int editId, @required String content, @required String auth, @@ -123,7 +124,7 @@ extension UserEndpoint on V1 { /// POST /private_message/delete /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-private-message - String deletePrivateMessage({ + Future deletePrivateMessage({ @required int editId, @required bool deleted, @required String auth, @@ -133,7 +134,7 @@ extension UserEndpoint on V1 { /// POST /private_message/mark_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-private-message-as-read - String markPrivateMessageAsRead({ + Future markPrivateMessageAsRead({ @required int editId, @required bool read, @required String auth, From 413b4bef30d94c89ec80fd8f2fadb03980cb7101 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 00:01:10 +0200 Subject: [PATCH 35/90] Add `ReplyView` --- lib/client/models/reply.dart | 104 +++++++++++++++++++++++++++++++++ lib/client/models/reply.g.dart | 54 +++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 lib/client/models/reply.dart create mode 100644 lib/client/models/reply.g.dart diff --git a/lib/client/models/reply.dart b/lib/client/models/reply.dart new file mode 100644 index 0000000..e053f4c --- /dev/null +++ b/lib/client/models/reply.dart @@ -0,0 +1,104 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'reply.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/comment_view.rs#L356 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class ReplyView { + final int id; + final int creatorId; + final int postId; + final String postName; + + /// can be null + final int parentId; + final String content; + final bool removed; + final bool read; + final DateTime published; + + /// can be null + final DateTime updated; + final bool deleted; + final String apId; + final bool local; + final int communityId; + final String communityActorId; + final bool communityLocal; + final String communityName; + + /// can be null + final String communityIcon; + final bool banned; + final bool bannedFromCommunity; + final String creatorActorId; + final bool creatorLocal; + final String creatorName; + + /// can be null + final String creatorPreferredUsername; + + /// can be null + final String creatorAvatar; + final DateTime creatorPublished; + final int score; + final int upvotes; + final int downvotes; + final int hotRank; + final int hotRankActive; + + /// can be null + final int userId; + + /// can be null + final int myVote; + + /// can be null + final bool subscribed; + + /// can be null + final bool saved; + final int recipientId; + + const ReplyView({ + this.id, + this.creatorId, + this.postId, + this.postName, + this.parentId, + this.content, + this.removed, + this.read, + this.published, + this.updated, + this.deleted, + this.apId, + this.local, + this.communityId, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityIcon, + this.banned, + this.bannedFromCommunity, + this.creatorActorId, + this.creatorLocal, + this.creatorName, + this.creatorPreferredUsername, + this.creatorAvatar, + this.creatorPublished, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.hotRankActive, + this.userId, + this.myVote, + this.subscribed, + this.saved, + this.recipientId, + }); + + factory ReplyView.fromJson(Map json) => + _$ReplyViewFromJson(json); +} diff --git a/lib/client/models/reply.g.dart b/lib/client/models/reply.g.dart new file mode 100644 index 0000000..488700b --- /dev/null +++ b/lib/client/models/reply.g.dart @@ -0,0 +1,54 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'reply.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +ReplyView _$ReplyViewFromJson(Map json) { + return ReplyView( + id: json['id'] as int, + creatorId: json['creator_id'] as int, + postId: json['post_id'] as int, + postName: json['post_name'] as String, + parentId: json['parent_id'] as int, + content: json['content'] as String, + removed: json['removed'] as bool, + read: json['read'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), + deleted: json['deleted'] as bool, + apId: json['ap_id'] as String, + local: json['local'] as bool, + communityId: json['community_id'] as int, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + banned: json['banned'] as bool, + bannedFromCommunity: json['banned_from_community'] as bool, + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorAvatar: json['creator_avatar'] as String, + creatorPublished: json['creator_published'] == null + ? null + : DateTime.parse(json['creator_published'] as String), + score: json['score'] as int, + upvotes: json['upvotes'] as int, + downvotes: json['downvotes'] as int, + hotRank: json['hot_rank'] as int, + hotRankActive: json['hot_rank_active'] as int, + userId: json['user_id'] as int, + myVote: json['my_vote'] as int, + subscribed: json['subscribed'] as bool, + saved: json['saved'] as bool, + recipientId: json['recipient_id'] as int, + ); +} From f85b91bb490653af0b6e90a40385a4b6e8d49fad Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 00:34:50 +0200 Subject: [PATCH 36/90] removed unnecesairy duplication --- lib/client/models/reply.dart | 104 --------------------------------- lib/client/models/reply.g.dart | 54 ----------------- 2 files changed, 158 deletions(-) delete mode 100644 lib/client/models/reply.dart delete mode 100644 lib/client/models/reply.g.dart diff --git a/lib/client/models/reply.dart b/lib/client/models/reply.dart deleted file mode 100644 index e053f4c..0000000 --- a/lib/client/models/reply.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'reply.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/comment_view.rs#L356 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class ReplyView { - final int id; - final int creatorId; - final int postId; - final String postName; - - /// can be null - final int parentId; - final String content; - final bool removed; - final bool read; - final DateTime published; - - /// can be null - final DateTime updated; - final bool deleted; - final String apId; - final bool local; - final int communityId; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - final bool banned; - final bool bannedFromCommunity; - final String creatorActorId; - final bool creatorLocal; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - - /// can be null - final String creatorAvatar; - final DateTime creatorPublished; - final int score; - final int upvotes; - final int downvotes; - final int hotRank; - final int hotRankActive; - - /// can be null - final int userId; - - /// can be null - final int myVote; - - /// can be null - final bool subscribed; - - /// can be null - final bool saved; - final int recipientId; - - const ReplyView({ - this.id, - this.creatorId, - this.postId, - this.postName, - this.parentId, - this.content, - this.removed, - this.read, - this.published, - this.updated, - this.deleted, - this.apId, - this.local, - this.communityId, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - this.banned, - this.bannedFromCommunity, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPreferredUsername, - this.creatorAvatar, - this.creatorPublished, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.hotRankActive, - this.userId, - this.myVote, - this.subscribed, - this.saved, - this.recipientId, - }); - - factory ReplyView.fromJson(Map json) => - _$ReplyViewFromJson(json); -} diff --git a/lib/client/models/reply.g.dart b/lib/client/models/reply.g.dart deleted file mode 100644 index 488700b..0000000 --- a/lib/client/models/reply.g.dart +++ /dev/null @@ -1,54 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'reply.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -ReplyView _$ReplyViewFromJson(Map json) { - return ReplyView( - id: json['id'] as int, - creatorId: json['creator_id'] as int, - postId: json['post_id'] as int, - postName: json['post_name'] as String, - parentId: json['parent_id'] as int, - content: json['content'] as String, - removed: json['removed'] as bool, - read: json['read'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - deleted: json['deleted'] as bool, - apId: json['ap_id'] as String, - local: json['local'] as bool, - communityId: json['community_id'] as int, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - banned: json['banned'] as bool, - bannedFromCommunity: json['banned_from_community'] as bool, - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorAvatar: json['creator_avatar'] as String, - creatorPublished: json['creator_published'] == null - ? null - : DateTime.parse(json['creator_published'] as String), - score: json['score'] as int, - upvotes: json['upvotes'] as int, - downvotes: json['downvotes'] as int, - hotRank: json['hot_rank'] as int, - hotRankActive: json['hot_rank_active'] as int, - userId: json['user_id'] as int, - myVote: json['my_vote'] as int, - subscribed: json['subscribed'] as bool, - saved: json['saved'] as bool, - recipientId: json['recipient_id'] as int, - ); -} From f0bfdba132a632b8dca1b05d01d5c05c081670c4 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 00:42:31 +0200 Subject: [PATCH 37/90] Updated placement of `Captcha` in filesystem --- lib/client/models/captcha.dart | 10 ++++++++++ lib/client/v1/main.dart | 9 --------- lib/client/v1/user_endpoint.dart | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 lib/client/models/captcha.dart diff --git a/lib/client/models/captcha.dart b/lib/client/models/captcha.dart new file mode 100644 index 0000000..8c4dae7 --- /dev/null +++ b/lib/client/models/captcha.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class Captcha { + final String png; + + /// can be null + final String wav; + final String uuid; + Captcha({@required this.png, this.wav, @required this.uuid}); +} diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index fd200e2..d18268f 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -49,12 +49,3 @@ extension VoteValue on Vote { throw Exception("unreachable"); } } - -class Captcha { - final String png; - - /// can be null - final String wav; - final String uuid; - Captcha({this.png, this.wav, this.uuid}); -} diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index a222155..5ef4e35 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; +import 'package:lemmur/client/models/captcha.dart'; import '../models/private_message.dart'; import 'main.dart'; From 3aa92f695d51a1396cef4555408b90744966f179 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 11:52:42 +0000 Subject: [PATCH 38/90] added CommunityModerator and CommunityFollower views --- lib/client/models/community.dart | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/lib/client/models/community.dart b/lib/client/models/community.dart index 88ad9f6..c37c318 100644 --- a/lib/client/models/community.dart +++ b/lib/client/models/community.dart @@ -84,3 +84,90 @@ class CommunityView { factory CommunityView.fromJson(Map json) => _$CommunityViewFromJson(json); } + + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L336 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class CommunityFollowerView { + final int id; + final int communityId; + final int userId; + final DateTime published; + final String userActorId; + final bool userLocal; + final String userName; + + /// can be null + final String userPreferredUsername; + + /// can be null + final String avatar; + final String communityActorId; + final bool communityLocal; + final String communityName; + + /// can be null + final String communityIcon; + + const CommunityFollowerView({ + this.id, + this.communityId, + this.userId, + this.published, + this.userActorId, + this.userLocal, + this.userName, + this.userPreferredUsername, + this.avatar, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityIcon, + }); + + factory CommunityFollowerView.fromJson(Map json) => + _$CommunityFollowerViewFromJson(json); +} + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L298 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class CommunityModeratorView { + final int id; + final int communityId; + final int userId; + final DateTime published; + final String userActorId; + final bool userLocal; + final String userName; + + /// can be null + final String userPreferredUsername; + + /// can be null + final String avatar; + final String communityActorId; + final bool communityLocal; + final String communityName; + + /// can be null + final String communityIcon; + + const CommunityModeratorView({ + this.id, + this.communityId, + this.userId, + this.published, + this.userActorId, + this.userLocal, + this.userName, + this.userPreferredUsername, + this.avatar, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityIcon, + }); + + factory CommunityModeratorView.fromJson(Map json) => + _$CommunityModeratorViewFromJson(json); +} From 101c7c4afc09d360e4cc0f4d8df68b7bd1860a97 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 12:22:28 +0000 Subject: [PATCH 39/90] made captcha json-serializable --- lib/client/models/captcha.dart | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/client/models/captcha.dart b/lib/client/models/captcha.dart index 8c4dae7..16f9c35 100644 --- a/lib/client/models/captcha.dart +++ b/lib/client/models/captcha.dart @@ -1,10 +1,22 @@ import 'package:flutter/material.dart'; +part 'captcha.g.dart'; + +/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) class Captcha { final String png; /// can be null final String wav; final String uuid; - Captcha({@required this.png, this.wav, @required this.uuid}); + + const Captcha({ + this.png, + this.wav, + this.uuid + }); + + factory Captcha.fromJson(Map json) => + _$CaptchaFromJson(json); } From 2af364abebac1db16bb0116e163c28a2246f5412 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 12:36:30 +0000 Subject: [PATCH 40/90] fixed import --- lib/client/models/captcha.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/models/captcha.dart b/lib/client/models/captcha.dart index 16f9c35..16a6b49 100644 --- a/lib/client/models/captcha.dart +++ b/lib/client/models/captcha.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:json_annotation/json_annotation.dart'; part 'captcha.g.dart'; From cf59f9f2ae59627d2d134202d6e7d636deed9737 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 12:39:22 +0000 Subject: [PATCH 41/90] added UserMention and Site views --- lib/client/models/site.dart | 62 +++++++++++++++++++++++ lib/client/models/user.dart | 98 +++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 lib/client/models/site.dart diff --git a/lib/client/models/site.dart b/lib/client/models/site.dart new file mode 100644 index 0000000..edb6721 --- /dev/null +++ b/lib/client/models/site.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; + +part 'site.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/site_view.rs#L31 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class SiteView { + final int id; + final String name; + + /// can be null + final String description; + final int creatorId; + final DateTime published; + + /// can be null + final DateTime updated; + final bool enableDownvotes; + final bool openRegistration; + final bool enableNsfw; + + /// can be null + final String icon; + + /// can be null + final String banner; + final String creatorName; + + /// can be null + final String creatorPreferredUsername; + + /// can be null + final String creatorAvatar; + final int numberOfUsers; + final int numberOfPosts; + final int numberOfComments; + final int numberOfCommunities; + + const SiteView({ + this.id, + this.name, + this.description, + this.creatorId, + this.published, + this.updated, + this.enableDownvotes, + this.openRegistration, + this.enableNsfw, + this.icon, + this.banner, + this.creatorName, + this.creatorPreferredUsername, + this.creatorAvatar, + this.numberOfUsers, + this.numberOfPosts, + this.numberOfComments, + this.numberOfCommunities, + }); + + factory SiteView.fromJson(Map json) => + _$SiteViewFromJson(json); +} diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart index 279150c..cb6e954 100644 --- a/lib/client/models/user.dart +++ b/lib/client/models/user.dart @@ -58,6 +58,104 @@ class UserView { this.numberOfComments, this.commentScore, }); + factory UserView.fromJson(Map json) => _$UserViewFromJson(json); } + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/user_mention_view.rs#L90 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class UserMentionView { + final int id; + final int userMentionId; + final int creatorId; + final String creatorActorId; + final bool creatorLocal; + final int postId; + final String postName; + + /// can be null + final int parentId; + final String content; + final bool removed; + final bool read; + final DateTime published; + + /// can be null + final DateTime updated; + final bool deleted; + final int communityId; + final String communityActorId; + final bool communityLocal; + final String communityName; + + /// can be null + final String communityIcon; + final bool banned; + final bool bannedFromCommunity; + final String creatorName; + + /// can be null + final String creatorPreferredUsername; + + /// can be null + final String creatorAvatar; + final int score; + final int upvotes; + final int downvotes; + final int hotRank; + final int hotRankActive; + + /// can be null + final int userId; + + /// can be null + final int myVote; + + /// can be null + final bool saved; + final int recipientId; + final String recipientActorId; + final bool recipientLocal; + + const UserMentionView({ + this.id, + this.userMentionId, + this.creatorId, + this.creatorActorId, + this.creatorLocal, + this.postId, + this.postName, + this.parentId, + this.content, + this.removed, + this.read, + this.published, + this.updated, + this.deleted, + this.communityId, + this.communityActorId, + this.communityLocal, + this.communityName, + this.communityIcon, + this.banned, + this.bannedFromCommunity, + this.creatorName, + this.creatorPreferredUsername, + this.creatorAvatar, + this.score, + this.upvotes, + this.downvotes, + this.hotRank, + this.hotRankActive, + this.userId, + this.myVote, + this.saved, + this.recipientId, + this.recipientActorId, + this.recipientLocal, + }); + + factory UserMentionView.fromJson(Map json) => + _$UserMentionViewFromJson(json); +} From e0a149f688d02e782d17b10b7e3b4d6d1295a164 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 14:07:00 +0000 Subject: [PATCH 42/90] added Category --- lib/client/models/category.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 lib/client/models/category.dart diff --git a/lib/client/models/category.dart b/lib/client/models/category.dart new file mode 100644 index 0000000..6e93d55 --- /dev/null +++ b/lib/client/models/category.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'category.g.dart'; + +/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/category.rs#L10 +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class Category { + final int id; + final String name; + + const Category({ + this.id, + this.name, + }); + + factory Category.fromJson(Map json) => + _$CategoryFromJson(json); +} From 51cc332f7ce3934b600a2725876db7f0f2262804 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 14:47:05 +0000 Subject: [PATCH 43/90] Added FullPost, Search, and UserDetails #1 --- lib/client/models/post.dart | 22 ++++++++++++++++++++++ lib/client/models/search.dart | 30 ++++++++++++++++++++++++++++++ lib/client/models/user.dart | 26 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 lib/client/models/search.dart diff --git a/lib/client/models/post.dart b/lib/client/models/post.dart index 74d2e5c..9e8f8aa 100644 --- a/lib/client/models/post.dart +++ b/lib/client/models/post.dart @@ -1,5 +1,8 @@ import 'package:json_annotation/json_annotation.dart'; +import './comment.dart'; +import './community.dart'; + part 'post.g.dart'; /// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/post_view.rs#L113 @@ -134,3 +137,22 @@ class PostView { factory PostView.fromJson(Map json) => _$PostViewFromJson(json); } + +/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post +@JsonSerializable(createToJson: false) +class FullPost { + final PostView post; + final List comments; + final CommunityView community; + final List moderators; + + const FullPost({ + this.post, + this.comments, + this.community, + this.moderators, + }); + + factory FullPost.fromJson(Map json) => + _$FullPostFromJson(json); +} diff --git a/lib/client/models/search.dart b/lib/client/models/search.dart new file mode 100644 index 0000000..dfa71ca --- /dev/null +++ b/lib/client/models/search.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; + +import './comment.dart'; +import './post.dart'; +import './community.dart'; +import './user.dart'; + +part 'search.g.dart'; + + +/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search +@JsonSerializable(createToJson: false) +class Search { + final String type_; + final List comments; + final List posts; + final List communities; + final List users; + + const Search({ + this.type_, + this.comments, + this.posts, + this.communities, + this.users, + }); + + factory Search.fromJson(Map json) => + _$SearchFromJson(json); +} diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart index cb6e954..f72ee70 100644 --- a/lib/client/models/user.dart +++ b/lib/client/models/user.dart @@ -1,5 +1,9 @@ import 'package:json_annotation/json_annotation.dart'; +import './comment.dart'; +import './post.dart'; +import './community.dart'; + part 'user.g.dart'; /// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/user_view.rs#L58 @@ -159,3 +163,25 @@ class UserMentionView { factory UserMentionView.fromJson(Map json) => _$UserMentionViewFromJson(json); } + + +/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details +@JsonSerializable(createToJson: false) +class UserDetails { + final UserView user; + final List follows; + final List moderates; + final List comments; + final List posts; + + const UserDetails({ + this.user, + this.follows, + this.moderates, + this.comments, + this.posts, + }); + + factory UserDetails.fromJson(Map json) => + _$UserDetailsFromJson(json); +} From 29dd4dcc35ee44cb8fba8f66f31c1c300ffed3cd Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:23:03 +0200 Subject: [PATCH 44/90] Add missing import --- lib/client/models/site.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/client/models/site.dart b/lib/client/models/site.dart index edb6721..3ced449 100644 --- a/lib/client/models/site.dart +++ b/lib/client/models/site.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:json_annotation/json_annotation.dart'; part 'site.g.dart'; @@ -7,28 +7,28 @@ part 'site.g.dart'; class SiteView { final int id; final String name; - + /// can be null final String description; final int creatorId; final DateTime published; - + /// can be null final DateTime updated; final bool enableDownvotes; final bool openRegistration; final bool enableNsfw; - + /// can be null final String icon; - + /// can be null final String banner; final String creatorName; - + /// can be null final String creatorPreferredUsername; - + /// can be null final String creatorAvatar; final int numberOfUsers; From 5902cd8f6faeb55870a2d729b9acd0aacd1875d7 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:23:21 +0200 Subject: [PATCH 45/90] Add codegen files --- lib/client/models/captcha.g.dart | 15 +++++++ lib/client/models/category.g.dart | 14 ++++++ lib/client/models/community.g.dart | 42 ++++++++++++++++++ lib/client/models/post.g.dart | 20 +++++++++ lib/client/models/search.g.dart | 30 +++++++++++++ lib/client/models/site.g.dart | 34 +++++++++++++++ lib/client/models/user.g.dart | 70 ++++++++++++++++++++++++++++++ 7 files changed, 225 insertions(+) create mode 100644 lib/client/models/captcha.g.dart create mode 100644 lib/client/models/category.g.dart create mode 100644 lib/client/models/search.g.dart create mode 100644 lib/client/models/site.g.dart diff --git a/lib/client/models/captcha.g.dart b/lib/client/models/captcha.g.dart new file mode 100644 index 0000000..61bd41b --- /dev/null +++ b/lib/client/models/captcha.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'captcha.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Captcha _$CaptchaFromJson(Map json) { + return Captcha( + png: json['png'] as String, + wav: json['wav'] as String, + uuid: json['uuid'] as String, + ); +} diff --git a/lib/client/models/category.g.dart b/lib/client/models/category.g.dart new file mode 100644 index 0000000..ff4df37 --- /dev/null +++ b/lib/client/models/category.g.dart @@ -0,0 +1,14 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'category.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Category _$CategoryFromJson(Map json) { + return Category( + id: json['id'] as int, + name: json['name'] as String, + ); +} diff --git a/lib/client/models/community.g.dart b/lib/client/models/community.g.dart index 9deeb67..b3c44fd 100644 --- a/lib/client/models/community.g.dart +++ b/lib/client/models/community.g.dart @@ -44,3 +44,45 @@ CommunityView _$CommunityViewFromJson(Map json) { subscribed: json['subscribed'] as bool, ); } + +CommunityFollowerView _$CommunityFollowerViewFromJson( + Map json) { + return CommunityFollowerView( + id: json['id'] as int, + communityId: json['community_id'] as int, + userId: json['user_id'] as int, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + userActorId: json['user_actor_id'] as String, + userLocal: json['user_local'] as bool, + userName: json['user_name'] as String, + userPreferredUsername: json['user_preferred_username'] as String, + avatar: json['avatar'] as String, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + ); +} + +CommunityModeratorView _$CommunityModeratorViewFromJson( + Map json) { + return CommunityModeratorView( + id: json['id'] as int, + communityId: json['community_id'] as int, + userId: json['user_id'] as int, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + userActorId: json['user_actor_id'] as String, + userLocal: json['user_local'] as bool, + userName: json['user_name'] as String, + userPreferredUsername: json['user_preferred_username'] as String, + avatar: json['avatar'] as String, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + ); +} diff --git a/lib/client/models/post.g.dart b/lib/client/models/post.g.dart index 473db0f..204fdd9 100644 --- a/lib/client/models/post.g.dart +++ b/lib/client/models/post.g.dart @@ -64,3 +64,23 @@ PostView _$PostViewFromJson(Map json) { saved: json['saved'] as bool, ); } + +FullPost _$FullPostFromJson(Map json) { + return FullPost( + post: json['post'] == null + ? null + : PostView.fromJson(json['post'] as Map), + comments: (json['comments'] as List) + ?.map((e) => + e == null ? null : CommentView.fromJson(e as Map)) + ?.toList(), + community: json['community'] == null + ? null + : CommunityView.fromJson(json['community'] as Map), + moderators: (json['moderators'] as List) + ?.map((e) => e == null + ? null + : CommunityModeratorView.fromJson(e as Map)) + ?.toList(), + ); +} diff --git a/lib/client/models/search.g.dart b/lib/client/models/search.g.dart new file mode 100644 index 0000000..f0b41fe --- /dev/null +++ b/lib/client/models/search.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'search.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Search _$SearchFromJson(Map json) { + return Search( + type_: json['type_'] as String, + comments: (json['comments'] as List) + ?.map((e) => + e == null ? null : CommentView.fromJson(e as Map)) + ?.toList(), + posts: (json['posts'] as List) + ?.map((e) => + e == null ? null : PostView.fromJson(e as Map)) + ?.toList(), + communities: (json['communities'] as List) + ?.map((e) => e == null + ? null + : CommunityView.fromJson(e as Map)) + ?.toList(), + users: (json['users'] as List) + ?.map((e) => + e == null ? null : UserView.fromJson(e as Map)) + ?.toList(), + ); +} diff --git a/lib/client/models/site.g.dart b/lib/client/models/site.g.dart new file mode 100644 index 0000000..7e94e52 --- /dev/null +++ b/lib/client/models/site.g.dart @@ -0,0 +1,34 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'site.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +SiteView _$SiteViewFromJson(Map json) { + return SiteView( + id: json['id'] as int, + name: json['name'] as String, + description: json['description'] as String, + creatorId: json['creator_id'] as int, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), + enableDownvotes: json['enable_downvotes'] as bool, + openRegistration: json['open_registration'] as bool, + enableNsfw: json['enable_nsfw'] as bool, + icon: json['icon'] as String, + banner: json['banner'] as String, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorAvatar: json['creator_avatar'] as String, + numberOfUsers: json['number_of_users'] as int, + numberOfPosts: json['number_of_posts'] as int, + numberOfComments: json['number_of_comments'] as int, + numberOfCommunities: json['number_of_communities'] as int, + ); +} diff --git a/lib/client/models/user.g.dart b/lib/client/models/user.g.dart index 4cc61e2..eeb804c 100644 --- a/lib/client/models/user.g.dart +++ b/lib/client/models/user.g.dart @@ -31,3 +31,73 @@ UserView _$UserViewFromJson(Map json) { commentScore: json['comment_score'] as int, ); } + +UserMentionView _$UserMentionViewFromJson(Map json) { + return UserMentionView( + id: json['id'] as int, + userMentionId: json['user_mention_id'] as int, + creatorId: json['creator_id'] as int, + creatorActorId: json['creator_actor_id'] as String, + creatorLocal: json['creator_local'] as bool, + postId: json['post_id'] as int, + postName: json['post_name'] as String, + parentId: json['parent_id'] as int, + content: json['content'] as String, + removed: json['removed'] as bool, + read: json['read'] as bool, + published: json['published'] == null + ? null + : DateTime.parse(json['published'] as String), + updated: json['updated'] == null + ? null + : DateTime.parse(json['updated'] as String), + deleted: json['deleted'] as bool, + communityId: json['community_id'] as int, + communityActorId: json['community_actor_id'] as String, + communityLocal: json['community_local'] as bool, + communityName: json['community_name'] as String, + communityIcon: json['community_icon'] as String, + banned: json['banned'] as bool, + bannedFromCommunity: json['banned_from_community'] as bool, + creatorName: json['creator_name'] as String, + creatorPreferredUsername: json['creator_preferred_username'] as String, + creatorAvatar: json['creator_avatar'] as String, + score: json['score'] as int, + upvotes: json['upvotes'] as int, + downvotes: json['downvotes'] as int, + hotRank: json['hot_rank'] as int, + hotRankActive: json['hot_rank_active'] as int, + userId: json['user_id'] as int, + myVote: json['my_vote'] as int, + saved: json['saved'] as bool, + recipientId: json['recipient_id'] as int, + recipientActorId: json['recipient_actor_id'] as String, + recipientLocal: json['recipient_local'] as bool, + ); +} + +UserDetails _$UserDetailsFromJson(Map json) { + return UserDetails( + user: json['user'] == null + ? null + : UserView.fromJson(json['user'] as Map), + follows: (json['follows'] as List) + ?.map((e) => e == null + ? null + : CommunityFollowerView.fromJson(e as Map)) + ?.toList(), + moderates: (json['moderates'] as List) + ?.map((e) => e == null + ? null + : CommunityModeratorView.fromJson(e as Map)) + ?.toList(), + comments: (json['comments'] as List) + ?.map((e) => + e == null ? null : CommentView.fromJson(e as Map)) + ?.toList(), + posts: (json['posts'] as List) + ?.map((e) => + e == null ? null : PostView.fromJson(e as Map)) + ?.toList(), + ); +} From 06230c224874df2054fc4de275ea2df8bf243a96 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:25:13 +0200 Subject: [PATCH 46/90] Autoformat --- lib/client/models/captcha.dart | 4 ++-- lib/client/models/community.dart | 13 ++++++------- lib/client/models/post.dart | 2 +- lib/client/models/search.dart | 4 +--- lib/client/models/user.dart | 19 +++++++++---------- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/lib/client/models/captcha.dart b/lib/client/models/captcha.dart index 16a6b49..7c833f7 100644 --- a/lib/client/models/captcha.dart +++ b/lib/client/models/captcha.dart @@ -10,11 +10,11 @@ class Captcha { /// can be null final String wav; final String uuid; - + const Captcha({ this.png, this.wav, - this.uuid + this.uuid, }); factory Captcha.fromJson(Map json) => diff --git a/lib/client/models/community.dart b/lib/client/models/community.dart index c37c318..1569ad1 100644 --- a/lib/client/models/community.dart +++ b/lib/client/models/community.dart @@ -85,7 +85,6 @@ class CommunityView { _$CommunityViewFromJson(json); } - /// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L336 @JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) class CommunityFollowerView { @@ -96,16 +95,16 @@ class CommunityFollowerView { final String userActorId; final bool userLocal; final String userName; - + /// can be null final String userPreferredUsername; - + /// can be null final String avatar; final String communityActorId; final bool communityLocal; final String communityName; - + /// can be null final String communityIcon; @@ -139,16 +138,16 @@ class CommunityModeratorView { final String userActorId; final bool userLocal; final String userName; - + /// can be null final String userPreferredUsername; - + /// can be null final String avatar; final String communityActorId; final bool communityLocal; final String communityName; - + /// can be null final String communityIcon; diff --git a/lib/client/models/post.dart b/lib/client/models/post.dart index 9e8f8aa..1741729 100644 --- a/lib/client/models/post.dart +++ b/lib/client/models/post.dart @@ -154,5 +154,5 @@ class FullPost { }); factory FullPost.fromJson(Map json) => - _$FullPostFromJson(json); + _$FullPostFromJson(json); } diff --git a/lib/client/models/search.dart b/lib/client/models/search.dart index dfa71ca..457191c 100644 --- a/lib/client/models/search.dart +++ b/lib/client/models/search.dart @@ -7,7 +7,6 @@ import './user.dart'; part 'search.g.dart'; - /// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search @JsonSerializable(createToJson: false) class Search { @@ -25,6 +24,5 @@ class Search { this.users, }); - factory Search.fromJson(Map json) => - _$SearchFromJson(json); + factory Search.fromJson(Map json) => _$SearchFromJson(json); } diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart index f72ee70..81c93a1 100644 --- a/lib/client/models/user.dart +++ b/lib/client/models/user.dart @@ -77,14 +77,14 @@ class UserMentionView { final bool creatorLocal; final int postId; final String postName; - + /// can be null final int parentId; final String content; final bool removed; final bool read; final DateTime published; - + /// can be null final DateTime updated; final bool deleted; @@ -92,16 +92,16 @@ class UserMentionView { final String communityActorId; final bool communityLocal; final String communityName; - + /// can be null final String communityIcon; final bool banned; final bool bannedFromCommunity; final String creatorName; - + /// can be null final String creatorPreferredUsername; - + /// can be null final String creatorAvatar; final int score; @@ -109,13 +109,13 @@ class UserMentionView { final int downvotes; final int hotRank; final int hotRankActive; - + /// can be null final int userId; - + /// can be null final int myVote; - + /// can be null final bool saved; final int recipientId; @@ -164,7 +164,6 @@ class UserMentionView { _$UserMentionViewFromJson(json); } - /// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details @JsonSerializable(createToJson: false) class UserDetails { @@ -183,5 +182,5 @@ class UserDetails { }); factory UserDetails.fromJson(Map json) => - _$UserDetailsFromJson(json); + _$UserDetailsFromJson(json); } From c6361291aac8dc705882bb7f305aaee26fb72291 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:39:53 +0200 Subject: [PATCH 47/90] Make import safer --- lib/client/client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/client.dart b/lib/client/client.dart index 941b36b..3d56010 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart' show required; import 'v1/main.dart'; class LemmyAPI { From c40c72eeaca588840fe27bcb0c4d7009019d4df7 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:47:44 +0200 Subject: [PATCH 48/90] Add even MORE return types! --- lib/client/v1/post_endpoint.dart | 2 +- lib/client/v1/user_endpoint.dart | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 63681cb..0c56767 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -19,7 +19,7 @@ extension PostEndpoint on V1 { /// GET /post /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post - String getPost({ + Future getPost({ @required int id, String auth, }) { diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 5ef4e35..c60ed69 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -1,5 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:lemmur/client/models/captcha.dart'; +import 'package:lemmur/client/models/comment.dart'; +import 'package:lemmur/client/models/user.dart'; import '../models/private_message.dart'; import 'main.dart'; @@ -7,7 +9,8 @@ import 'main.dart'; extension UserEndpoint on V1 { /// POST /user/login /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login - String login({ + /// returns jwt + Future login({ String usernameOrEmail, String password, }) { @@ -17,7 +20,8 @@ extension UserEndpoint on V1 { /// POST /user/register /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#register - String register({ + /// returns jwt + Future register({ @required String username, String email, String password, @@ -33,7 +37,7 @@ extension UserEndpoint on V1 { /// GET /user /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details - String getUserDetails({ + Future getUserDetails({ int userId, String username, @required String sort, @@ -48,7 +52,8 @@ extension UserEndpoint on V1 { /// PUT /save_user_settings /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-user-settings - String saveUserSettings({ + /// returns jwt + Future saveUserSettings({ @required bool showNsfw, @required String theme, @required int defaultSortType, @@ -60,7 +65,7 @@ extension UserEndpoint on V1 { /// GET /user/replies /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-replies--inbox - String getReplies({ + Future> getReplies({ @required String sort, int page, int limit, @@ -72,7 +77,7 @@ extension UserEndpoint on V1 { /// GET /user/mentions /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions - String getUserMentions({ + Future> getUserMentions({ String sort, @required int page, @required int limit, @@ -84,7 +89,7 @@ extension UserEndpoint on V1 { /// POST /user/mention/mark_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-user-mention-as-read - String markUserMentionAsRead({ + Future markUserMentionAsRead({ @required int userMentionId, @required bool read, @required String auth, @@ -145,7 +150,7 @@ extension UserEndpoint on V1 { /// POST /user/mark_all_as_read /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-all-as-read - String markAllAsRead({ + Future> markAllAsRead({ @required String auth, }) { throw UnimplementedError(); @@ -153,7 +158,8 @@ extension UserEndpoint on V1 { /// POST /user/delete_account /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-account - String deleteAccount({ + /// returns jwt + Future deleteAccount({ @required String password, @required String auth, }) { From b5a9d72fb6c4fcb68266ad21d0be4af46362386b Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:48:26 +0200 Subject: [PATCH 49/90] Add some more return types --- lib/client/v1/main.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index d18268f..a7433a3 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -1,4 +1,7 @@ -import 'package:flutter/foundation.dart'; +import 'package:flutter/foundation.dart' show required; +import 'package:lemmur/client/models/search.dart'; + +import '../models/category.dart'; export 'comment_endpoint.dart'; export 'post_endpoint.dart'; @@ -11,13 +14,13 @@ class V1 { /// GET /categories /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories - String listCategories() { + Future> listCategories() { throw UnimplementedError(); } /// POST /search /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search - String search({ + Search search({ @required String q, @required String type, String communityId, From f4206be30208d6a1da54e72c44c678a17307391e Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 19:49:19 +0200 Subject: [PATCH 50/90] Make imports safer --- lib/client/v1/comment_endpoint.dart | 2 +- lib/client/v1/post_endpoint.dart | 2 +- lib/client/v1/user_endpoint.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart index 8dbb14b..beb4964 100644 --- a/lib/client/v1/comment_endpoint.dart +++ b/lib/client/v1/comment_endpoint.dart @@ -1,4 +1,4 @@ -import 'package:flutter/foundation.dart'; +import 'package:flutter/foundation.dart' show required; import '../models/comment.dart'; import 'main.dart'; diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 0c56767..74f9a18 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -1,4 +1,4 @@ -import 'package:flutter/foundation.dart'; +import 'package:flutter/foundation.dart' show required; import '../models/post.dart'; import 'main.dart'; diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index c60ed69..e06e200 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -1,4 +1,4 @@ -import 'package:flutter/foundation.dart'; +import 'package:flutter/foundation.dart' show required; import 'package:lemmur/client/models/captcha.dart'; import 'package:lemmur/client/models/comment.dart'; import 'package:lemmur/client/models/user.dart'; From 9deb17edc7bebbb7117095a4139ca5331c5d3a97 Mon Sep 17 00:00:00 2001 From: krawieck Date: Mon, 10 Aug 2020 23:07:13 +0200 Subject: [PATCH 51/90] Add `PostType` and `SortType` --- lib/client/v1/main.dart | 55 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index a7433a3..499b3d1 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -52,3 +52,58 @@ extension VoteValue on Vote { throw Exception("unreachable"); } } + +enum PostType { + all, + subscribed, + community, +} + +extension PostTypeValue on PostType { + String get value { + switch (this) { + case PostType.all: + return "All"; + case PostType.subscribed: + return "Subscribed"; + case PostType.community: + return "Community"; + } + throw Exception("unreachable"); + } +} + +enum SortType { + active, + hot, + new_, + topDay, + topWeek, + topMonth, + topYear, + topAll, +} + +extension SortTypeValue on SortType { + String get value { + switch (this) { + case SortType.active: + return "Active"; + case SortType.hot: + return "Hot"; + case SortType.new_: + return "New"; + case SortType.topDay: + return "TopDay"; + case SortType.topWeek: + return "TopWeek"; + case SortType.topMonth: + return "TopMonth"; + case SortType.topYear: + return "TopYear"; + case SortType.topAll: + return "TopAll"; + } + throw Exception("unreachable"); + } +} From 13522248d4cd662a4a2f6fc75d51400810b028de Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 00:10:17 +0200 Subject: [PATCH 52/90] Add exports --- lib/client/client.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/client/client.dart b/lib/client/client.dart index 3d56010..59dbe70 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -1,6 +1,10 @@ import 'package:flutter/foundation.dart' show required; import 'v1/main.dart'; +export 'v1/comment_endpoint.dart'; +export 'v1/post_endpoint.dart'; +export 'v1/user_endpoint.dart'; + class LemmyAPI { /// url of this lemmy instance String instanceUrl; @@ -8,7 +12,7 @@ class LemmyAPI { V1 v1; /// initialize lemmy api instance - LemmyAPI({@required this.instanceUrl}) + LemmyAPI(this.instanceUrl) : assert(instanceUrl != null), v1 = V1(instanceUrl); } From bfae0ef57d37bdd61774dc6b0d93ff0678bc48e2 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 02:42:23 +0200 Subject: [PATCH 53/90] Implement `getPosts` --- lib/client/v1/post_endpoint.dart | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 74f9a18..717caf9 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -1,4 +1,7 @@ +import 'dart:convert'; + import 'package:flutter/foundation.dart' show required; +import 'package:http/http.dart' as http; import '../models/post.dart'; import 'main.dart'; @@ -28,15 +31,31 @@ extension PostEndpoint on V1 { /// GET /post/list /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-posts - Future getPosts({ + Future> getPosts({ @required String type, @required String sort, int page, int limit, int communityId, String communityName, - }) { - throw UnimplementedError(); + }) async { + assert(type != null); + assert(sort != null); + + var res = await http.get(Uri.https( + instanceUrl, + "/api/v1/post/list", + { + 'type_': type, + 'sort': sort, + if (page != null) 'page': page.toString(), + if (limit != null) 'limit': limit.toString(), + if (communityId != null) 'community_id': communityId.toString(), + if (communityName != null) 'community_name': communityName, + }, + )); + List json = jsonDecode(res.body)["posts"]; + return json.map((e) => PostView.fromJson(e)).toList(); } /// POST /post/like From 0d42fd44acc0c670f0c897877f01432741fd4f2d Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 02:42:40 +0200 Subject: [PATCH 54/90] Update pubspec --- pubspec.lock | 7 +++++++ pubspec.yaml | 9 ++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 6dad3fa..a1bd223 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -214,6 +214,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.14.0+3" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.2" http_multi_server: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index dc1e7f1..7f7dfcc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,14 +18,14 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=2.7.0 <3.0.0' dependencies: json_annotation: ^3.0.1 + http: ^0.12.2 flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.3 @@ -41,23 +41,18 @@ dev_dependencies: # The following section is specific to Flutter. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a From 6436244b66fdd19f72c17d5903aa9ceeacc0c372 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 02:43:03 +0200 Subject: [PATCH 55/90] Add comments to properties based on web docs --- lib/client/models/captcha.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/client/models/captcha.dart b/lib/client/models/captcha.dart index 7c833f7..3a71ba5 100644 --- a/lib/client/models/captcha.dart +++ b/lib/client/models/captcha.dart @@ -12,7 +12,10 @@ class Captcha { final String uuid; const Captcha({ + /// A Base64 encoded png this.png, + + /// A Base64 encoded wav audio file this.wav, this.uuid, }); From d646a838812aaac127054af8a11c8483052b9c87 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Mon, 10 Aug 2020 23:27:35 +0200 Subject: [PATCH 56/90] disabled undocumented members lint and added effective dart badge --- README.md | 1 + analysis_options.yaml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index 1ae4b24..e2123c4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # lemmur [![](https://github.com/krawieck/lemmur/workflows/ci/badge.svg)](https://github.com/krawieck/lemmur/actions) +[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://pub.dev/packages/effective_dart) A lemmy mobile client diff --git a/analysis_options.yaml b/analysis_options.yaml index d3ee447..05557e9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1 +1,5 @@ include: package:effective_dart/analysis_options.yaml + +linter: + rules: + public_member_api_docs: false From da988f74bdb4725432f4a457894319ea80da0159 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 19:03:24 +0200 Subject: [PATCH 57/90] Change `PostType` to `PostListingType` --- lib/client/v1/main.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 499b3d1..404411c 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -53,20 +53,20 @@ extension VoteValue on Vote { } } -enum PostType { +enum PostListingType { all, subscribed, community, } -extension PostTypeValue on PostType { +extension PostTypeValue on PostListingType { String get value { switch (this) { - case PostType.all: + case PostListingType.all: return "All"; - case PostType.subscribed: + case PostListingType.subscribed: return "Subscribed"; - case PostType.community: + case PostListingType.community: return "Community"; } throw Exception("unreachable"); From 5971a947d6683fadae65f5601f381b32f5b3f0eb Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 19:04:03 +0200 Subject: [PATCH 58/90] Add `SearchType` and implement it --- lib/client/v1/main.dart | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 404411c..cb500fd 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -22,7 +22,7 @@ class V1 { /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search Search search({ @required String q, - @required String type, + @required SearchType type, String communityId, @required String sort, int page, @@ -107,3 +107,32 @@ extension SortTypeValue on SortType { throw Exception("unreachable"); } } + +enum SearchType { + all, + comments, + posts, + communities, + users, + url, +} + +extension SearchTypeValue on SearchType { + String get value { + switch (this) { + case SearchType.all: + return "All"; + case SearchType.comments: + return "Comments"; + case SearchType.posts: + return "Posts"; + case SearchType.communities: + return "Communities"; + case SearchType.users: + return "Users"; + case SearchType.url: + return "Url"; + } + throw Exception("unreachable"); + } +} From 771a5f28ff4ea253afca7ab270387f72b0ed4027 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 19:29:56 +0200 Subject: [PATCH 59/90] implement a bunch of enums --- lib/client/v1/main.dart | 4 ++-- lib/client/v1/post_endpoint.dart | 8 ++++---- lib/client/v1/user_endpoint.dart | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index cb500fd..dd1c46e 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart' show required; -import 'package:lemmur/client/models/search.dart'; import '../models/category.dart'; +import '../models/search.dart'; export 'comment_endpoint.dart'; export 'post_endpoint.dart'; @@ -24,7 +24,7 @@ class V1 { @required String q, @required SearchType type, String communityId, - @required String sort, + @required SortType sort, int page, int limit, String auth, diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 717caf9..5106562 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -32,8 +32,8 @@ extension PostEndpoint on V1 { /// GET /post/list /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-posts Future> getPosts({ - @required String type, - @required String sort, + @required PostListingType type, + @required SortType sort, int page, int limit, int communityId, @@ -46,8 +46,8 @@ extension PostEndpoint on V1 { instanceUrl, "/api/v1/post/list", { - 'type_': type, - 'sort': sort, + 'type_': type.value, + 'sort': sort.value, if (page != null) 'page': page.toString(), if (limit != null) 'limit': limit.toString(), if (communityId != null) 'community_id': communityId.toString(), diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index e06e200..664e9fc 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -2,8 +2,8 @@ import 'package:flutter/foundation.dart' show required; import 'package:lemmur/client/models/captcha.dart'; import 'package:lemmur/client/models/comment.dart'; import 'package:lemmur/client/models/user.dart'; -import '../models/private_message.dart'; +import '../models/private_message.dart'; import 'main.dart'; extension UserEndpoint on V1 { @@ -40,7 +40,7 @@ extension UserEndpoint on V1 { Future getUserDetails({ int userId, String username, - @required String sort, + @required SortType sort, int page, int limit, int communityId, @@ -56,8 +56,8 @@ extension UserEndpoint on V1 { Future saveUserSettings({ @required bool showNsfw, @required String theme, - @required int defaultSortType, - @required int defaultListingType, + @required SortType defaultSortType, + @required PostListingType defaultListingType, @required String auth, }) { throw UnimplementedError(); @@ -66,7 +66,7 @@ extension UserEndpoint on V1 { /// GET /user/replies /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-replies--inbox Future> getReplies({ - @required String sort, + @required SortType sort, int page, int limit, @required bool unreadOnly, From 4a096602b5e931d72051fc8fdb1376e2aecb9ed8 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 19:32:13 +0200 Subject: [PATCH 60/90] Fix up imports --- lib/client/models/search.dart | 2 +- lib/client/models/user.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client/models/search.dart b/lib/client/models/search.dart index 457191c..e60d767 100644 --- a/lib/client/models/search.dart +++ b/lib/client/models/search.dart @@ -1,8 +1,8 @@ import 'package:json_annotation/json_annotation.dart'; import './comment.dart'; -import './post.dart'; import './community.dart'; +import './post.dart'; import './user.dart'; part 'search.g.dart'; diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart index 81c93a1..787cc4e 100644 --- a/lib/client/models/user.dart +++ b/lib/client/models/user.dart @@ -1,8 +1,8 @@ import 'package:json_annotation/json_annotation.dart'; import './comment.dart'; -import './post.dart'; import './community.dart'; +import './post.dart'; part 'user.g.dart'; From be3bd569f4ea2ce8f3ed8c630b57d0f8f17fb22b Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 19:54:12 +0200 Subject: [PATCH 61/90] Replace `type_` with `type` --- lib/client/models/search.dart | 5 +++-- lib/client/models/search.g.dart | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/client/models/search.dart b/lib/client/models/search.dart index e60d767..16f045f 100644 --- a/lib/client/models/search.dart +++ b/lib/client/models/search.dart @@ -10,14 +10,15 @@ part 'search.g.dart'; /// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search @JsonSerializable(createToJson: false) class Search { - final String type_; + @JsonKey(name: "type_") + final String type; final List comments; final List posts; final List communities; final List users; const Search({ - this.type_, + this.type, this.comments, this.posts, this.communities, diff --git a/lib/client/models/search.g.dart b/lib/client/models/search.g.dart index f0b41fe..8e62a57 100644 --- a/lib/client/models/search.g.dart +++ b/lib/client/models/search.g.dart @@ -8,7 +8,7 @@ part of 'search.dart'; Search _$SearchFromJson(Map json) { return Search( - type_: json['type_'] as String, + type: json['type_'] as String, comments: (json['comments'] as List) ?.map((e) => e == null ? null : CommentView.fromJson(e as Map)) From f68467708a70c07e6827231515685335a10abd73 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 11 Aug 2020 19:54:38 +0200 Subject: [PATCH 62/90] yet another imports cleanup --- lib/client/v1/user_endpoint.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 664e9fc..ed81e5f 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -1,9 +1,9 @@ import 'package:flutter/foundation.dart' show required; -import 'package:lemmur/client/models/captcha.dart'; -import 'package:lemmur/client/models/comment.dart'; -import 'package:lemmur/client/models/user.dart'; +import '../models/captcha.dart'; +import '../models/comment.dart'; import '../models/private_message.dart'; +import '../models/user.dart'; import 'main.dart'; extension UserEndpoint on V1 { From 1307b5e5b16af09f26ef4b8a9bb45f54e1845965 Mon Sep 17 00:00:00 2001 From: krawieck Date: Wed, 12 Aug 2020 11:53:17 +0200 Subject: [PATCH 63/90] Add `assert`s for checking required props --- lib/client/v1/post_endpoint.dart | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 5106562..178eba3 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -17,6 +17,11 @@ extension PostEndpoint on V1 { @required int communityId, @required String auth, }) { + assert(name != null); + assert(nsfw != null); + assert(communityId != null); + assert(auth != null); + throw UnimplementedError(); } @@ -26,6 +31,8 @@ extension PostEndpoint on V1 { @required int id, String auth, }) { + assert(id != null); + throw UnimplementedError(); } @@ -65,6 +72,10 @@ extension PostEndpoint on V1 { @required Vote score, @required String auth, }) { + assert(postId != null); + assert(score != null); + assert(auth != null); + throw UnimplementedError(); } @@ -78,6 +89,11 @@ extension PostEndpoint on V1 { @required bool nsfw, @required String auth, }) { + assert(editId != null); + assert(name != null); + assert(nsfw != null); + assert(auth != null); + throw UnimplementedError(); } @@ -89,6 +105,10 @@ extension PostEndpoint on V1 { @required bool deleted, @required String auth, }) { + assert(editId != null); + assert(deleted != null); + assert(auth != null); + throw UnimplementedError(); } @@ -101,6 +121,10 @@ extension PostEndpoint on V1 { String reason, @required String auth, }) { + assert(editId != null); + assert(removed != null); + assert(auth != null); + throw UnimplementedError(); } @@ -111,6 +135,10 @@ extension PostEndpoint on V1 { @required bool save, @required String auth, }) { + assert(postId != null); + assert(save != null); + assert(auth != null); + throw UnimplementedError(); } } From b433bf0971a1591e573a304c5c97841ba26af997 Mon Sep 17 00:00:00 2001 From: krawieck Date: Wed, 12 Aug 2020 11:55:26 +0200 Subject: [PATCH 64/90] Add more `assert`s for checking required props --- lib/client/v1/comment_endpoint.dart | 28 ++++++++++++++++++++++++++++ lib/client/v1/main.dart | 7 ++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart index beb4964..b769593 100644 --- a/lib/client/v1/comment_endpoint.dart +++ b/lib/client/v1/comment_endpoint.dart @@ -13,6 +13,10 @@ extension CommentEndpoint on V1 { int formId, @required String auth, }) { + assert(content != null); + assert(postId != null); + assert(auth != null); + throw UnimplementedError(); } @@ -24,6 +28,10 @@ extension CommentEndpoint on V1 { String formId, @required String auth, }) { + assert(content != null); + assert(editId != null); + assert(auth != null); + throw UnimplementedError(); } @@ -35,6 +43,10 @@ extension CommentEndpoint on V1 { @required bool deleted, @required String auth, }) { + assert(editId != null); + assert(deleted != null); + assert(auth != null); + throw UnimplementedError(); } @@ -47,6 +59,10 @@ extension CommentEndpoint on V1 { String reason, @required String auth, }) { + assert(editId != null); + assert(removed != null); + assert(auth != null); + throw UnimplementedError(); } @@ -57,6 +73,10 @@ extension CommentEndpoint on V1 { @required bool read, @required String auth, }) { + assert(editId != null); + assert(read != null); + assert(auth != null); + throw UnimplementedError(); } @@ -67,6 +87,10 @@ extension CommentEndpoint on V1 { @required bool save, @required String auth, }) { + assert(commentId != null); + assert(save != null); + assert(auth != null); + throw UnimplementedError(); } @@ -77,6 +101,10 @@ extension CommentEndpoint on V1 { @required Vote score, @required String auth, }) { + assert(commentId != null); + assert(score != null); + assert(auth != null); + throw UnimplementedError(); } } diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index dd1c46e..4a04851 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -20,7 +20,7 @@ class V1 { /// POST /search /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search - Search search({ + Future search({ @required String q, @required SearchType type, String communityId, @@ -29,6 +29,10 @@ class V1 { int limit, String auth, }) { + assert(q != null); + assert(type != null); + assert(sort != null); + throw UnimplementedError(); } } @@ -76,6 +80,7 @@ extension PostTypeValue on PostListingType { enum SortType { active, hot, + // ignore: constant_identifier_names new_, topDay, topWeek, From 141b9296614e37ce84b29bd3df5663833637f533 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Wed, 12 Aug 2020 21:00:31 +0200 Subject: [PATCH 65/90] export enums as well --- lib/client/client.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/client/client.dart b/lib/client/client.dart index 59dbe70..bf02604 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -1,9 +1,6 @@ -import 'package:flutter/foundation.dart' show required; import 'v1/main.dart'; -export 'v1/comment_endpoint.dart'; -export 'v1/post_endpoint.dart'; -export 'v1/user_endpoint.dart'; +export 'v1/main.dart'; class LemmyAPI { /// url of this lemmy instance From a0002d0eb65b489fa9635222e80b9f58eeeddaf9 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Wed, 12 Aug 2020 21:01:13 +0200 Subject: [PATCH 66/90] move model tests to a separate folder --- test/{ => client/models}/commentview_test.dart | 0 test/{ => client/models}/communityview_test.dart | 0 test/{ => client/models}/postview_test.dart | 0 test/{ => client/models}/userview_test.dart | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename test/{ => client/models}/commentview_test.dart (100%) rename test/{ => client/models}/communityview_test.dart (100%) rename test/{ => client/models}/postview_test.dart (100%) rename test/{ => client/models}/userview_test.dart (100%) diff --git a/test/commentview_test.dart b/test/client/models/commentview_test.dart similarity index 100% rename from test/commentview_test.dart rename to test/client/models/commentview_test.dart diff --git a/test/communityview_test.dart b/test/client/models/communityview_test.dart similarity index 100% rename from test/communityview_test.dart rename to test/client/models/communityview_test.dart diff --git a/test/postview_test.dart b/test/client/models/postview_test.dart similarity index 100% rename from test/postview_test.dart rename to test/client/models/postview_test.dart diff --git a/test/userview_test.dart b/test/client/models/userview_test.dart similarity index 100% rename from test/userview_test.dart rename to test/client/models/userview_test.dart From 946e77bfddff998cc92bc4043cb864548d72875d Mon Sep 17 00:00:00 2001 From: shilangyu Date: Wed, 12 Aug 2020 21:01:33 +0200 Subject: [PATCH 67/90] getPosts tests --- test/client/v1_test.dart | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/client/v1_test.dart diff --git a/test/client/v1_test.dart b/test/client/v1_test.dart new file mode 100644 index 0000000..65dba69 --- /dev/null +++ b/test/client/v1_test.dart @@ -0,0 +1,39 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:lemmur/client/client.dart'; + +// this is a mock exception +// should be removed as soon as the real one is implemented +class LemmyAPIException implements Exception { + final String _message; + + LemmyAPIException(this._message); + + @override + String toString() => _message; +} + +void main() { + group("lemmy API v1", () { + final lemmy = LemmyAPI('dev.lemmy.ml').v1; + + group("getPosts", () { + test("correctly fetches", () async { + final res = await lemmy.getPosts( + type: PostListingType.all, sort: SortType.active); + + expect(res.length, 10); + }); + + test("gracefully fails", () async { + try { + await lemmy.getPosts( + type: PostListingType.all, sort: SortType.active, page: -1); + } on LemmyAPIException catch (_) { + return; + } + + throw TestFailure("Did not catch the error"); + }); + }); + }); +} From 506b007eeaf580e85a513407d4e84e58220e9039 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Thu, 13 Aug 2020 15:39:53 +0200 Subject: [PATCH 68/90] implemented get/post helpers --- lib/client/client.dart | 10 ++++---- lib/client/http_helper.dart | 39 ++++++++++++++++++++++++++++++++ lib/client/v1/main.dart | 10 +++++--- lib/client/v1/post_endpoint.dart | 28 +++++++++-------------- 4 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 lib/client/http_helper.dart diff --git a/lib/client/client.dart b/lib/client/client.dart index bf02604..7dad408 100644 --- a/lib/client/client.dart +++ b/lib/client/client.dart @@ -3,13 +3,13 @@ import 'v1/main.dart'; export 'v1/main.dart'; class LemmyAPI { - /// url of this lemmy instance - String instanceUrl; + /// host uri of this lemmy instance + String host; V1 v1; /// initialize lemmy api instance - LemmyAPI(this.instanceUrl) - : assert(instanceUrl != null), - v1 = V1(instanceUrl); + LemmyAPI(this.host) + : assert(host != null), + v1 = V1(host); } diff --git a/lib/client/http_helper.dart b/lib/client/http_helper.dart new file mode 100644 index 0000000..f505414 --- /dev/null +++ b/lib/client/http_helper.dart @@ -0,0 +1,39 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:http/http.dart' as http; + +extension OkResponse on http.Response { + bool get ok => statusCode >= 200 && statusCode < 300; +} + +abstract class HttpHelper { + String host; + String extraPath; + + Future> get( + String path, Map query) async { + var res = await http.get(Uri.https(host, "$extraPath$path", query)); + + if (!res.ok) { + // failed request, handle here + } + + return jsonDecode(res.body); + } + + Future> post( + String path, Map body) async { + var res = await http.post( + Uri.https(host, "$extraPath$path"), + body: jsonEncode(body), + headers: {HttpHeaders.contentTypeHeader: ContentType.json.mimeType}, + ); + + if (!res.ok) { + // failed request, handle here + } + + return jsonDecode(res.body); + } +} diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 4a04851..f4f29c8 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/foundation.dart' show required; +import '../http_helper.dart'; import '../models/category.dart'; import '../models/search.dart'; @@ -7,10 +8,13 @@ export 'comment_endpoint.dart'; export 'post_endpoint.dart'; export 'user_endpoint.dart'; -class V1 { - String instanceUrl; +class V1 extends HttpHelper { + @override + final String host; + @override + final String extraPath = "/api/v1"; - V1(this.instanceUrl); + V1(this.host); /// GET /categories /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 178eba3..0e181a4 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -1,7 +1,4 @@ -import 'dart:convert'; - import 'package:flutter/foundation.dart' show required; -import 'package:http/http.dart' as http; import '../models/post.dart'; import 'main.dart'; @@ -49,20 +46,17 @@ extension PostEndpoint on V1 { assert(type != null); assert(sort != null); - var res = await http.get(Uri.https( - instanceUrl, - "/api/v1/post/list", - { - 'type_': type.value, - 'sort': sort.value, - if (page != null) 'page': page.toString(), - if (limit != null) 'limit': limit.toString(), - if (communityId != null) 'community_id': communityId.toString(), - if (communityName != null) 'community_name': communityName, - }, - )); - List json = jsonDecode(res.body)["posts"]; - return json.map((e) => PostView.fromJson(e)).toList(); + var json = await get("/post/list", { + 'type_': type.value, + 'sort': sort.value, + if (page != null) 'page': page.toString(), + if (limit != null) 'limit': limit.toString(), + if (communityId != null) 'community_id': communityId.toString(), + if (communityName != null) 'community_name': communityName, + }); + + List posts = json["posts"]; + return posts.map((e) => PostView.fromJson(e)).toList(); } /// POST /post/like From 9c9de8c41dae867a1b691b691f3394ff25393142 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Thu, 13 Aug 2020 16:18:33 +0200 Subject: [PATCH 69/90] changed abstract class to mixin --- lib/client/http_helper.dart | 2 +- lib/client/v1/main.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client/http_helper.dart b/lib/client/http_helper.dart index f505414..21e1de7 100644 --- a/lib/client/http_helper.dart +++ b/lib/client/http_helper.dart @@ -7,7 +7,7 @@ extension OkResponse on http.Response { bool get ok => statusCode >= 200 && statusCode < 300; } -abstract class HttpHelper { +mixin HttpHelper { String host; String extraPath; diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index f4f29c8..fa1a01d 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -8,7 +8,7 @@ export 'comment_endpoint.dart'; export 'post_endpoint.dart'; export 'user_endpoint.dart'; -class V1 extends HttpHelper { +class V1 with HttpHelper { @override final String host; @override From 9a9a66cd17097c65b7cd6f2700dc63e73cd190d4 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Thu, 13 Aug 2020 16:32:02 +0200 Subject: [PATCH 70/90] tests for main.dart --- test/client/v1_test.dart | 60 ++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/test/client/v1_test.dart b/test/client/v1_test.dart index 65dba69..4e184ff 100644 --- a/test/client/v1_test.dart +++ b/test/client/v1_test.dart @@ -1,12 +1,12 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/client.dart'; -// this is a mock exception +// these are mock exceptions // should be removed as soon as the real one is implemented -class LemmyAPIException implements Exception { +class NotLoggedInException implements Exception { final String _message; - LemmyAPIException(this._message); + NotLoggedInException(this._message); @override String toString() => _message; @@ -20,19 +20,57 @@ void main() { test("correctly fetches", () async { final res = await lemmy.getPosts( type: PostListingType.all, sort: SortType.active); - expect(res.length, 10); }); - test("gracefully fails", () async { - try { + test("forbids illegal numbers", () async { + expect(() async { await lemmy.getPosts( - type: PostListingType.all, sort: SortType.active, page: -1); - } on LemmyAPIException catch (_) { - return; - } + type: PostListingType.all, sort: SortType.active, page: 0); + }, throwsA(isInstanceOf())); - throw TestFailure("Did not catch the error"); + expect(() async { + await lemmy.getPosts( + type: PostListingType.all, sort: SortType.active, limit: -1); + }, throwsA(isInstanceOf())); + }); + }); + + group("listCategories", () { + test("correctly fetches", () async { + await lemmy.listCategories(); + }); + }); + + group("search", () { + test("correctly fetches", () async { + final res = await lemmy.search( + type: SearchType.all, q: "asd", sort: SortType.active); + + expect(res.type, SortType.active.value); + }); + + test("forbids illegal numbers", () async { + expect(() async { + await lemmy.search( + type: SearchType.all, q: "asd", sort: SortType.active, page: 0); + }, throwsA(isInstanceOf())); + + expect(() async { + await lemmy.search( + type: SearchType.all, q: "asd", sort: SortType.active, limit: -1); + }, throwsA(isInstanceOf())); + }); + + test("handles invalid tokens", () async { + expect(() async { + await lemmy.search( + type: SearchType.all, + q: "asd", + sort: SortType.active, + auth: "asd", + ); + }, throwsA(isInstanceOf())); }); }); }); From 120c7554c8b1482c7e8b06433e7d26f8c19bb585 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Thu, 13 Aug 2020 19:37:59 +0200 Subject: [PATCH 71/90] additional linting rules --- analysis_options.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/analysis_options.yaml b/analysis_options.yaml index 05557e9..fedebc3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,3 +3,5 @@ include: package:effective_dart/analysis_options.yaml linter: rules: public_member_api_docs: false + prefer_expression_function_bodies: true + prefer_single_quotes: true From 92d684cbfdb248083b4dfa9c4206e459a5c3f4c5 Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 13 Aug 2020 20:25:48 +0200 Subject: [PATCH 72/90] Change strings to single quotes --- lib/client/http_helper.dart | 4 +-- lib/client/models/search.dart | 2 +- lib/client/v1/main.dart | 44 ++++++++++++------------ lib/client/v1/post_endpoint.dart | 4 +-- test/client/models/commentview_test.dart | 23 +++++++------ 5 files changed, 39 insertions(+), 38 deletions(-) diff --git a/lib/client/http_helper.dart b/lib/client/http_helper.dart index 21e1de7..7a5f304 100644 --- a/lib/client/http_helper.dart +++ b/lib/client/http_helper.dart @@ -13,7 +13,7 @@ mixin HttpHelper { Future> get( String path, Map query) async { - var res = await http.get(Uri.https(host, "$extraPath$path", query)); + var res = await http.get(Uri.https(host, '$extraPath$path', query)); if (!res.ok) { // failed request, handle here @@ -25,7 +25,7 @@ mixin HttpHelper { Future> post( String path, Map body) async { var res = await http.post( - Uri.https(host, "$extraPath$path"), + Uri.https(host, '$extraPath$path'), body: jsonEncode(body), headers: {HttpHeaders.contentTypeHeader: ContentType.json.mimeType}, ); diff --git a/lib/client/models/search.dart b/lib/client/models/search.dart index 16f045f..0abfa3c 100644 --- a/lib/client/models/search.dart +++ b/lib/client/models/search.dart @@ -10,7 +10,7 @@ part 'search.g.dart'; /// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search @JsonSerializable(createToJson: false) class Search { - @JsonKey(name: "type_") + @JsonKey(name: 'type_') final String type; final List comments; final List posts; diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index fa1a01d..3e83137 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -12,7 +12,7 @@ class V1 with HttpHelper { @override final String host; @override - final String extraPath = "/api/v1"; + final String extraPath = '/api/v1'; V1(this.host); @@ -57,7 +57,7 @@ extension VoteValue on Vote { case Vote.down: return -1; } - throw Exception("unreachable"); + throw Exception('unreachable'); } } @@ -71,13 +71,13 @@ extension PostTypeValue on PostListingType { String get value { switch (this) { case PostListingType.all: - return "All"; + return 'All'; case PostListingType.subscribed: - return "Subscribed"; + return 'Subscribed'; case PostListingType.community: - return "Community"; + return 'Community'; } - throw Exception("unreachable"); + throw Exception('unreachable'); } } @@ -97,23 +97,23 @@ extension SortTypeValue on SortType { String get value { switch (this) { case SortType.active: - return "Active"; + return 'Active'; case SortType.hot: - return "Hot"; + return 'Hot'; case SortType.new_: - return "New"; + return 'New'; case SortType.topDay: - return "TopDay"; + return 'TopDay'; case SortType.topWeek: - return "TopWeek"; + return 'TopWeek'; case SortType.topMonth: - return "TopMonth"; + return 'TopMonth'; case SortType.topYear: - return "TopYear"; + return 'TopYear'; case SortType.topAll: - return "TopAll"; + return 'TopAll'; } - throw Exception("unreachable"); + throw Exception('unreachable'); } } @@ -130,18 +130,18 @@ extension SearchTypeValue on SearchType { String get value { switch (this) { case SearchType.all: - return "All"; + return 'All'; case SearchType.comments: - return "Comments"; + return 'Comments'; case SearchType.posts: - return "Posts"; + return 'Posts'; case SearchType.communities: - return "Communities"; + return 'Communities'; case SearchType.users: - return "Users"; + return 'Users'; case SearchType.url: - return "Url"; + return 'Url'; } - throw Exception("unreachable"); + throw Exception('unreachable'); } } diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 0e181a4..ea775cf 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -46,7 +46,7 @@ extension PostEndpoint on V1 { assert(type != null); assert(sort != null); - var json = await get("/post/list", { + var json = await get('/post/list', { 'type_': type.value, 'sort': sort.value, if (page != null) 'page': page.toString(), @@ -55,7 +55,7 @@ extension PostEndpoint on V1 { if (communityName != null) 'community_name': communityName, }); - List posts = json["posts"]; + List posts = json['posts']; return posts.map((e) => PostView.fromJson(e)).toList(); } diff --git a/test/client/models/commentview_test.dart b/test/client/models/commentview_test.dart index f5016b9..a3a0619 100644 --- a/test/client/models/commentview_test.dart +++ b/test/client/models/commentview_test.dart @@ -1,9 +1,10 @@ import 'dart:convert'; + import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/models/comment.dart'; void main() { - test("CommentView test", () { + test('CommentView test', () { Map commentFromApi = jsonDecode(""" { "id": 14296, @@ -48,32 +49,32 @@ void main() { expect(comment.id, 14296); expect(comment.creatorId, 8218); expect(comment.postId, 38501); - expect(comment.postName, "Niklaus Wirth was right and that is a problem"); + expect(comment.postName, 'Niklaus Wirth was right and that is a problem'); expect(comment.parentId, 14286); expect(comment.content, - "I think that the same functionality current crop of apps has could be implemented much more cleanly and efficiently if there wasn't a rush to get products to market. If developers could spend the time to think things through and try different approaches to see what works best we'd have much higher quality software today. Instead, everything is rushed to market as fast as possible, and developers are constantly overwhelmed with unreasonable amounts of work with no time to do things properly or clean things up along the way."); + '''I think that the same functionality current crop of apps has could be implemented much more cleanly and efficiently if there wasn't a rush to get products to market. If developers could spend the time to think things through and try different approaches to see what works best we'd have much higher quality software today. Instead, everything is rushed to market as fast as possible, and developers are constantly overwhelmed with unreasonable amounts of work with no time to do things properly or clean things up along the way.'''); expect(comment.removed, false); expect(comment.read, true); - expect(comment.published, DateTime.parse("2020-08-02T20:31:19.303284")); + expect(comment.published, DateTime.parse('2020-08-02T20:31:19.303284')); expect(comment.updated, null); expect(comment.deleted, false); - expect(comment.apId, "https://dev.lemmy.ml/comment/14296"); + expect(comment.apId, 'https://dev.lemmy.ml/comment/14296'); expect(comment.local, true); expect(comment.communityId, 14680); - expect(comment.communityActorId, "https://dev.lemmy.ml/c/programming"); + expect(comment.communityActorId, 'https://dev.lemmy.ml/c/programming'); expect(comment.communityLocal, true); - expect(comment.communityName, "programming"); + expect(comment.communityName, 'programming'); expect(comment.communityIcon, null); expect(comment.banned, false); expect(comment.bannedFromCommunity, false); - expect(comment.creatorActorId, "https://dev.lemmy.ml/u/yogthos"); + expect(comment.creatorActorId, 'https://dev.lemmy.ml/u/yogthos'); expect(comment.creatorLocal, true); - expect(comment.creatorName, "yogthos"); + expect(comment.creatorName, 'yogthos'); expect(comment.creatorPreferredUsername, null); expect( - comment.creatorPublished, DateTime.parse("2020-01-18T04:02:39.254957")); + comment.creatorPublished, DateTime.parse('2020-01-18T04:02:39.254957')); expect( - comment.creatorAvatar, "https://dev.lemmy.ml/pictrs/image/bwk1q2.png"); + comment.creatorAvatar, 'https://dev.lemmy.ml/pictrs/image/bwk1q2.png'); expect(comment.score, 1); expect(comment.upvotes, 1); expect(comment.downvotes, 0); From 8310db4294cc107cad09371a14355ff5ebaa306e Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 13 Aug 2020 20:49:24 +0200 Subject: [PATCH 73/90] Exclude codegen (`*.g.dart`) files --- analysis_options.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/analysis_options.yaml b/analysis_options.yaml index fedebc3..cc50fe2 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -5,3 +5,6 @@ linter: public_member_api_docs: false prefer_expression_function_bodies: true prefer_single_quotes: true +analyzer: + exclude: + - '**/*.g.dart' From 5e15ddd7bd9b67402350d273feef7eb7488d5f63 Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 13 Aug 2020 23:32:41 +0200 Subject: [PATCH 74/90] Implement `search` method (`GET /search`) --- lib/client/v1/main.dart | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 3e83137..c505337 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -22,7 +22,7 @@ class V1 with HttpHelper { throw UnimplementedError(); } - /// POST /search + /// ~~POST~~ GET /search /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search Future search({ @required String q, @@ -32,12 +32,22 @@ class V1 with HttpHelper { int page, int limit, String auth, - }) { + }) async { assert(q != null); assert(type != null); assert(sort != null); - throw UnimplementedError(); + var res = await get('/search', { + 'q': q, + 'type_': type.value, + if (communityId != null) 'community_id': communityId, + 'sort': sort.value, + if (page != null) 'page': page.toString(), + if (limit != null) 'limit': limit.toString(), + if (auth != null) 'auth': auth, + }); + + return Search.fromJson(res); } } From cbd6a208d37d93075c321a8e039ba56cb3931fd6 Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 13 Aug 2020 23:56:00 +0200 Subject: [PATCH 75/90] Implement `listCategories` (`GET /categories`) --- lib/client/v1/main.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index c505337..71acee3 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -18,8 +18,11 @@ class V1 with HttpHelper { /// GET /categories /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories - Future> listCategories() { - throw UnimplementedError(); + Future> listCategories() async { + var res = await get('/categories'); + List categories = res['categories']; + + return categories.map((e) => Category.fromJson(e)).toList(); } /// ~~POST~~ GET /search From c90a3bdd736de2cc5656bd286897759f41b47f46 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 00:10:46 +0200 Subject: [PATCH 76/90] Make second argument in `get` optional --- lib/client/http_helper.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/client/http_helper.dart b/lib/client/http_helper.dart index 7a5f304..547cb6a 100644 --- a/lib/client/http_helper.dart +++ b/lib/client/http_helper.dart @@ -11,8 +11,8 @@ mixin HttpHelper { String host; String extraPath; - Future> get( - String path, Map query) async { + Future> get(String path, + [Map query]) async { var res = await http.get(Uri.https(host, '$extraPath$path', query)); if (!res.ok) { From 7ea2168d47591a5642543f510a34d1bd8cf60f37 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Fri, 14 Aug 2020 00:12:41 +0200 Subject: [PATCH 77/90] finished tests for all LemmyAPI.v1 client --- test/client/v1_test.dart | 484 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 451 insertions(+), 33 deletions(-) diff --git a/test/client/v1_test.dart b/test/client/v1_test.dart index 4e184ff..b6c1076 100644 --- a/test/client/v1_test.dart +++ b/test/client/v1_test.dart @@ -12,18 +12,177 @@ class NotLoggedInException implements Exception { String toString() => _message; } +class UsernameTakenException implements Exception { + final String _message; + + UsernameTakenException(this._message); + + @override + String toString() => _message; +} + void main() { - group("lemmy API v1", () { + group('lemmy API v1', () { final lemmy = LemmyAPI('dev.lemmy.ml').v1; - group("getPosts", () { - test("correctly fetches", () async { + group('listCategories', () { + test('correctly fetches', () async { + await lemmy.listCategories(); + }); + }); + + group('search', () { + test('correctly fetches', () async { + final res = await lemmy.search( + type: SearchType.all, q: 'asd', sort: SortType.active); + + expect(res.type, SortType.active.value); + }); + + test('forbids illegal numbers', () async { + expect(() async { + await lemmy.search( + type: SearchType.all, q: 'asd', sort: SortType.active, page: 0); + }, throwsA(isInstanceOf())); + + expect(() async { + await lemmy.search( + type: SearchType.all, q: 'asd', sort: SortType.active, limit: -1); + }, throwsA(isInstanceOf())); + }); + + test('handles invalid tokens', () async { + expect(() async { + await lemmy.search( + type: SearchType.all, + q: 'asd', + sort: SortType.active, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('createComment', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.createComment( + content: '123', + postId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('editComment', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.editComment( + content: '123', + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('deleteComment', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.deleteComment( + deleted: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('removeComment', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.removeComment( + removed: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('markCommentAsRead', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.markCommentAsRead( + read: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('saveComment', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.saveComment( + save: true, + commentId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('createCommentLike', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.createCommentLike( + score: Vote.up, + commentId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('createPost', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.createPost( + name: 'asd', + nsfw: false, + communityId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('getPost', () { + test('correctly fetches', () async { + await lemmy.getPost(id: 38936); + }); + + test('handles invalid tokens', () async { + expect(() async { + await lemmy.getPost( + id: 1, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('getPosts', () { + test('correctly fetches', () async { final res = await lemmy.getPosts( type: PostListingType.all, sort: SortType.active); expect(res.length, 10); }); - test("forbids illegal numbers", () async { + test('forbids illegal numbers', () async { expect(() async { await lemmy.getPosts( type: PostListingType.all, sort: SortType.active, page: 0); @@ -36,42 +195,301 @@ void main() { }); }); - group("listCategories", () { - test("correctly fetches", () async { - await lemmy.listCategories(); + group('createPostLike', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.createPostLike( + postId: 1, + score: Vote.up, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); }); }); - group("search", () { - test("correctly fetches", () async { - final res = await lemmy.search( - type: SearchType.all, q: "asd", sort: SortType.active); - - expect(res.type, SortType.active.value); - }); - - test("forbids illegal numbers", () async { + group('editPost', () { + test('handles invalid tokens', () async { expect(() async { - await lemmy.search( - type: SearchType.all, q: "asd", sort: SortType.active, page: 0); - }, throwsA(isInstanceOf())); - - expect(() async { - await lemmy.search( - type: SearchType.all, q: "asd", sort: SortType.active, limit: -1); - }, throwsA(isInstanceOf())); - }); - - test("handles invalid tokens", () async { - expect(() async { - await lemmy.search( - type: SearchType.all, - q: "asd", - sort: SortType.active, - auth: "asd", + await lemmy.editPost( + name: 'asd', + nsfw: false, + editId: 123, + auth: 'asd', ); }, throwsA(isInstanceOf())); }); }); + + group('deletePost', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.deletePost( + deleted: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('removePost', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.removePost( + removed: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('login', () { + test('handles invalid credentials', () async { + expect(() async { + await lemmy.login( + usernameOrEmail: '123', + password: '123', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('register', () { + // TODO(krawieck): the signature seems to be wrong, waiting for correction + // test('handles already existing account', () async { + // expect(() async { + // await lemmy.register( + // usernameOrEmail: '123', + // password: '123', + // ); + // }, throwsA(isInstanceOf())); + // }); + }); + + group('getCaptcha', () { + test('correctly fetches', () async { + await lemmy.getCaptcha(); + }); + }); + + group('getUserDetails', () { + test('correctly fetches', () async { + await lemmy.getUserDetails(sort: SortType.active, username: 'krawieck'); + }); + + test('forbids illegal numbers', () async { + expect(() async { + await lemmy.getUserDetails(sort: SortType.active, page: 0); + }, throwsA(isInstanceOf())); + + expect(() async { + await lemmy.getUserDetails(sort: SortType.active, limit: -1); + }, throwsA(isInstanceOf())); + }); + + test('forbids both username and userId being passed at once', () async { + expect(() async { + await lemmy.getUserDetails( + sort: SortType.active, + username: 'asd', + userId: 123, + ); + }, throwsA(isInstanceOf())); + }); + + test('handles invalid tokens', () async { + expect(() async { + await lemmy.getUserDetails( + sort: SortType.active, + auth: '123', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('saveUserSettings', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.saveUserSettings( + showNsfw: true, + theme: 'asd', + defaultSortType: SortType.active, + defaultListingType: PostListingType.all, + auth: '123', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('getReplies', () { + test('forbids illegal numbers', () async { + expect(() async { + await lemmy.getReplies( + sort: SortType.active, + unreadOnly: false, + auth: 'asd', + page: 0, + ); + }, throwsA(isInstanceOf())); + + expect(() async { + await lemmy.getReplies( + sort: SortType.active, + unreadOnly: false, + auth: 'asd', + limit: -1, + ); + }, throwsA(isInstanceOf())); + }); + + test('handles invalid tokens', () async { + expect(() async { + await lemmy.getReplies( + sort: SortType.active, + unreadOnly: false, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('getUserMentions', () { + // TODO(krawieck): the signature seems to be wrong, waiting for correction + // test('forbids illegal numbers', () async { + // expect(() async { + // await lemmy.getUserMentions( + // sort: SortType.active, + // unreadOnly: false, + // auth: 'asd', + // page: 0, + // ); + // }, throwsA(isInstanceOf())); + + // expect(() async { + // await lemmy.getUserMentions( + // sort: SortType.active, + // unreadOnly: false, + // auth: 'asd', + // limit: -1, + // ); + // }, throwsA(isInstanceOf())); + // }); + + // test('handles invalid tokens', () async { + // expect(() async { + // await lemmy.getUserMentions( + // sort: SortType.active, + // unreadOnly: false, + // auth: 'asd', + // ); + // }, throwsA(isInstanceOf())); + // }); + }); + + group('markUserMentionAsRead', () { + test('handles invalid credentials', () async { + expect(() async { + await lemmy.markUserMentionAsRead( + userMentionId: 123, + read: true, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('getPrivateMessages', () { + test('forbids illegal numbers', () async { + expect(() async { + await lemmy.getPrivateMessages( + unreadOnly: false, + auth: 'asd', + page: 0, + ); + }, throwsA(isInstanceOf())); + + expect(() async { + await lemmy.getPrivateMessages( + unreadOnly: false, + auth: 'asd', + limit: -1, + ); + }, throwsA(isInstanceOf())); + }); + + test('handles invalid tokens', () async { + expect(() async { + await lemmy.getPrivateMessages( + unreadOnly: false, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('createPrivateMessage', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.createPrivateMessage( + content: 'asd', + recipientId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('editPrivateMessage', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.editPrivateMessage( + content: 'asd', + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('deletePrivateMessage', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.deletePrivateMessage( + deleted: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('markPrivateMessageAsRead', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.markPrivateMessageAsRead( + read: true, + editId: 123, + auth: 'asd', + ); + }, throwsA(isInstanceOf())); + }); + }); + + group('markAllAsRead', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.markAllAsRead(auth: 'asd'); + }, throwsA(isInstanceOf())); + }); + }); + + group('deleteAccount', () { + test('handles invalid tokens', () async { + expect(() async { + await lemmy.deleteAccount(password: 'asd', auth: 'asd'); + }, throwsA(isInstanceOf())); + }); + }); }); } From cfae9ba37395b31677d9cb7d9b5a12b27bf521f8 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 00:24:41 +0200 Subject: [PATCH 78/90] Change double quotes to single quotes cuz i want linter to STFU --- test/client/models/communityview_test.dart | 22 ++++++++-------- test/client/models/postview_test.dart | 30 +++++++++++----------- test/client/models/userview_test.dart | 12 ++++----- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/test/client/models/communityview_test.dart b/test/client/models/communityview_test.dart index 87716a0..b705c94 100644 --- a/test/client/models/communityview_test.dart +++ b/test/client/models/communityview_test.dart @@ -4,8 +4,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/models/community.dart'; void main() { - test("PostView test", () { - Map communityJson = jsonDecode(""" + test('PostView test', () { + Map communityJson = jsonDecode(''' { "id": 3, "name": "haskell", @@ -35,33 +35,33 @@ void main() { "hot_rank": 0, "user_id": null, "subscribed": null - }"""); + }'''); var community = CommunityView.fromJson(communityJson); expect(community.id, 3); - expect(community.name, "haskell"); - expect(community.title, "The Haskell Lemmy Forum"); + expect(community.name, 'haskell'); + expect(community.title, 'The Haskell Lemmy Forum'); expect(community.icon, null); expect(community.banner, null); expect(community.description, null); expect(community.categoryId, 21); expect(community.creatorId, 77); expect(community.removed, false); - expect(community.published, DateTime.parse("2019-04-22T17:52:37.759443")); + expect(community.published, DateTime.parse('2019-04-22T17:52:37.759443')); expect(community.updated, null); expect(community.deleted, false); expect(community.nsfw, false); - expect(community.actorId, "https://dev.lemmy.ml/c/haskell"); + expect(community.actorId, 'https://dev.lemmy.ml/c/haskell'); expect(community.local, true); expect(community.lastRefreshedAt, - DateTime.parse("2020-06-30T00:49:22.589810")); - expect(community.creatorActorId, "https://dev.lemmy.ml/u/topos"); + DateTime.parse('2020-06-30T00:49:22.589810')); + expect(community.creatorActorId, 'https://dev.lemmy.ml/u/topos'); expect(community.creatorLocal, true); - expect(community.creatorName, "topos"); + expect(community.creatorName, 'topos'); expect(community.creatorPreferredUsername, null); expect(community.creatorAvatar, null); - expect(community.categoryName, "Programming/Software"); + expect(community.categoryName, 'Programming/Software'); expect(community.numberOfSubscribers, 85); expect(community.numberOfPosts, 0); expect(community.numberOfComments, 0); diff --git a/test/client/models/postview_test.dart b/test/client/models/postview_test.dart index d1e2ce2..bb71c23 100644 --- a/test/client/models/postview_test.dart +++ b/test/client/models/postview_test.dart @@ -4,8 +4,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/models/post.dart'; void main() { - test("PostView test", () { - Map postJson = jsonDecode(""" + test('PostView test', () { + Map postJson = jsonDecode(''' { "id": 38501, "name": "Niklaus Wirth was right and that is a problem", @@ -53,41 +53,41 @@ void main() { "subscribed": false, "read": false, "saved": false - }"""); + }'''); var post = PostView.fromJson(postJson); expect(post.id, 38501); - expect(post.name, "Niklaus Wirth was right and that is a problem"); + expect(post.name, 'Niklaus Wirth was right and that is a problem'); expect(post.url, - "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/"); + 'https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/'); expect(post.body, null); expect(post.creatorId, 8218); expect(post.communityId, 14680); expect(post.removed, false); expect(post.locked, false); - expect(post.published, DateTime.parse("2020-08-02T01:56:28.072727")); + expect(post.published, DateTime.parse('2020-08-02T01:56:28.072727')); expect(post.updated, null); expect(post.deleted, false); expect(post.nsfw, false); expect(post.stickied, false); - expect(post.embedTitle, "Niklaus Wirth was right and that is a problem"); + expect(post.embedTitle, 'Niklaus Wirth was right and that is a problem'); expect(post.embedDescription, null); expect(post.embedHtml, null); expect(post.thumbnailUrl, null); - expect(post.apId, "https://dev.lemmy.ml/post/38501"); + expect(post.apId, 'https://dev.lemmy.ml/post/38501'); expect(post.local, true); - expect(post.creatorActorId, "https://dev.lemmy.ml/u/yogthos"); + expect(post.creatorActorId, 'https://dev.lemmy.ml/u/yogthos'); expect(post.creatorLocal, true); - expect(post.creatorName, "yogthos"); + expect(post.creatorName, 'yogthos'); expect(post.creatorPreferredUsername, null); - expect(post.creatorPublished, DateTime.parse("2020-01-18T04:02:39.254957")); - expect(post.creatorAvatar, "https://dev.lemmy.ml/pictrs/image/bwk1q2.png"); + expect(post.creatorPublished, DateTime.parse('2020-01-18T04:02:39.254957')); + expect(post.creatorAvatar, 'https://dev.lemmy.ml/pictrs/image/bwk1q2.png'); expect(post.banned, false); expect(post.bannedFromCommunity, false); - expect(post.communityActorId, "https://dev.lemmy.ml/c/programming"); + expect(post.communityActorId, 'https://dev.lemmy.ml/c/programming'); expect(post.communityLocal, true); - expect(post.communityName, "programming"); + expect(post.communityName, 'programming'); expect(post.communityIcon, null); expect(post.communityRemoved, false); expect(post.communityDeleted, false); @@ -99,7 +99,7 @@ void main() { expect(post.hotRank, 1); expect(post.hotRankActive, 1); expect( - post.newestActivityTime, DateTime.parse("2020-08-02T20:31:19.303284")); + post.newestActivityTime, DateTime.parse('2020-08-02T20:31:19.303284')); expect(post.userId, 13709); expect(post.myVote, 0); expect(post.subscribed, false); diff --git a/test/client/models/userview_test.dart b/test/client/models/userview_test.dart index 264b1a9..3f4e710 100644 --- a/test/client/models/userview_test.dart +++ b/test/client/models/userview_test.dart @@ -4,8 +4,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:lemmur/client/models/user.dart'; void main() { - test("UserView test", () { - Map userJson = jsonDecode(""" + test('UserView test', () { + Map userJson = jsonDecode(''' { "id": 13709, "actor_id": "https://dev.lemmy.ml/u/krawieck", @@ -26,13 +26,13 @@ void main() { "post_score": 0, "number_of_comments": 0, "comment_score": 0 - }"""); + }'''); var user = UserView.fromJson(userJson); expect(user.id, 13709); - expect(user.actorId, "https://dev.lemmy.ml/u/krawieck"); - expect(user.name, "krawieck"); + expect(user.actorId, 'https://dev.lemmy.ml/u/krawieck'); + expect(user.name, 'krawieck'); expect(user.preferredUsername, null); expect(user.avatar, null); expect(user.banner, null); @@ -44,7 +44,7 @@ void main() { expect(user.banned, false); expect(user.showAvatars, true); expect(user.sendNotificationsToEmail, false); - expect(user.published, DateTime.parse("2020-08-03T12:22:12.389085")); + expect(user.published, DateTime.parse('2020-08-03T12:22:12.389085')); expect(user.numberOfPosts, 0); expect(user.postScore, 0); expect(user.numberOfComments, 0); From 05caba277ea10313f73e31d2cdee3f7f023ff029 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 00:34:09 +0200 Subject: [PATCH 79/90] Implement `login` (`POST /user/login`) --- lib/client/v1/user_endpoint.dart | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index ed81e5f..e1857b2 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -11,11 +11,17 @@ extension UserEndpoint on V1 { /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login /// returns jwt Future login({ - String usernameOrEmail, - String password, - }) { + @required String usernameOrEmail, + @required String password, + }) async { assert(usernameOrEmail != null, password != null); - throw UnimplementedError(); + + final res = await post('/user/login', { + 'username_or_email': usernameOrEmail, + 'password': password, + }); + + return res['jwt']; } /// POST /user/register From 705b90148e30946c17207c79c65dea03e5035ed2 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 13:49:20 +0200 Subject: [PATCH 80/90] Implement `getUserDetails` --- lib/client/v1/user_endpoint.dart | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index e1857b2..26a3263 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -50,10 +50,27 @@ extension UserEndpoint on V1 { int page, int limit, int communityId, - bool savedOnly, + @required bool savedOnly, String auth, - }) { - throw UnimplementedError(); + }) async { + assert(sort != null); + assert(savedOnly != null); + assert((userId != null) ^ (username != null)); + assert(limit == null || limit >= 0); + assert(page == null || page > 0); + + var res = await get('/user', { + if (userId != null) 'user_id': userId.toString(), + if (username != null) 'username': username, + 'sort': sort.value, + if (page != null) 'page': page.toString(), + if (limit != null) 'limit': limit.toString(), + if (communityId != null) 'community_id': communityId.toString(), + if (savedOnly != null) 'saved_only': savedOnly.toString(), + if (auth != null) 'auth': auth, + }); + + return UserDetails.fromJson(res); } /// PUT /save_user_settings From 177b6ea7126049dbd8e2b582ee9c26eb32388ba4 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 14:13:44 +0200 Subject: [PATCH 81/90] Add a bunch of `assert`s --- lib/client/v1/user_endpoint.dart | 52 ++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 26a3263..567f9b1 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -83,6 +83,12 @@ extension UserEndpoint on V1 { @required PostListingType defaultListingType, @required String auth, }) { + assert(showNsfw != null); + assert(theme != null); + assert(defaultSortType != null); + assert(defaultListingType != null); + assert(auth != null); + throw UnimplementedError(); } @@ -95,18 +101,24 @@ extension UserEndpoint on V1 { @required bool unreadOnly, @required String auth, }) { - throw UnimplementedError(); + assert(sort != null); + assert(unreadOnly != null); + assert(auth != null); } /// GET /user/mentions /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions Future> getUserMentions({ - String sort, - @required int page, - @required int limit, - bool unreadOnly, - String auth, + @required String sort, + int page, + int limit, + @required bool unreadOnly, + @required String auth, }) { + assert(sort != null); + assert(unreadOnly != null); + assert(auth != null); + throw UnimplementedError(); } @@ -117,6 +129,10 @@ extension UserEndpoint on V1 { @required bool read, @required String auth, }) { + assert(userMentionId != null); + assert(read != null); + assert(auth != null); + throw UnimplementedError(); } @@ -128,6 +144,9 @@ extension UserEndpoint on V1 { int limit, @required String auth, }) { + assert(unreadOnly != null); + assert(auth != null); + throw UnimplementedError(); } @@ -138,6 +157,10 @@ extension UserEndpoint on V1 { @required int recipientId, @required String auth, }) { + assert(content != null); + assert(recipientId != null); + assert(auth != null); + throw UnimplementedError(); } @@ -148,6 +171,10 @@ extension UserEndpoint on V1 { @required String content, @required String auth, }) { + assert(editId != null); + assert(content != null); + assert(auth != null); + throw UnimplementedError(); } @@ -158,6 +185,10 @@ extension UserEndpoint on V1 { @required bool deleted, @required String auth, }) { + assert(editId != null); + assert(deleted != null); + assert(auth != null); + throw UnimplementedError(); } @@ -168,6 +199,10 @@ extension UserEndpoint on V1 { @required bool read, @required String auth, }) { + assert(editId != null); + assert(read != null); + assert(auth != null); + throw UnimplementedError(); } @@ -176,6 +211,8 @@ extension UserEndpoint on V1 { Future> markAllAsRead({ @required String auth, }) { + assert(auth != null); + throw UnimplementedError(); } @@ -186,6 +223,9 @@ extension UserEndpoint on V1 { @required String password, @required String auth, }) { + assert(password != null); + assert(auth != null); + throw UnimplementedError(); } } From e464a0b922a98595e3d64e4700aa7c94af85469d Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 14:41:35 +0200 Subject: [PATCH 82/90] Implement `getReplies` --- lib/client/v1/user_endpoint.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 567f9b1..290c97a 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -100,10 +100,20 @@ extension UserEndpoint on V1 { int limit, @required bool unreadOnly, @required String auth, - }) { + }) async { assert(sort != null); assert(unreadOnly != null); assert(auth != null); + + var res = await get('/user/replies', { + 'sort': sort.value, + if (page != null) 'page': page.toString(), + if (limit != null) 'limit': limit.toString(), + 'unread_only': unreadOnly.toString(), + 'auth': auth, + }); + List replies = res['replies']; + return replies.map((e) => ReplyView.fromJson(e)).toList(); } /// GET /user/mentions From be71efd3c1ff620e926cbd71ff13180ce454d057 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 15:47:23 +0200 Subject: [PATCH 83/90] Implement `getPost` --- lib/client/v1/post_endpoint.dart | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index ea775cf..519b8bb 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -27,10 +27,15 @@ extension PostEndpoint on V1 { Future getPost({ @required int id, String auth, - }) { + }) async { assert(id != null); - throw UnimplementedError(); + var res = await get('/post', { + 'id': id.toString(), + if (auth != null) 'auth': auth, + }); + + return FullPost.fromJson(res); } /// GET /post/list From f3329b82ffd71991d6a952b9eab3ecf7f5490fd2 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 14 Aug 2020 16:43:42 +0200 Subject: [PATCH 84/90] Update `register` method to be compliant with the docs --- lib/client/v1/user_endpoint.dart | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart index 290c97a..2d71bb1 100644 --- a/lib/client/v1/user_endpoint.dart +++ b/lib/client/v1/user_endpoint.dart @@ -30,8 +30,18 @@ extension UserEndpoint on V1 { Future register({ @required String username, String email, - String password, + @required String password, + @required String passwordVerify, + @required bool admin, + String captchaUuid, + String captchaAnswer, }) { + assert(username != null); + assert(password != null); + assert(passwordVerify != null); + assert(admin != null); + assert(((captchaUuid != null) ^ (captchaAnswer != null))); + throw UnimplementedError(); } From eeac5af15ed626bf9878e64624c8e2c4d6c7ddc3 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 18 Aug 2020 22:22:56 +0200 Subject: [PATCH 85/90] Add 3 endpoints related to communities and 1 model Endpoints: * getCommunity * listCommunities * followCommunity Model: * FullCommunityView --- lib/client/models/community.dart | 11 +++++ lib/client/models/community.g.dart | 13 ++++++ lib/client/v1/community_endpoint.dart | 60 +++++++++++++++++++++++++++ lib/client/v1/main.dart | 1 + 4 files changed, 85 insertions(+) create mode 100644 lib/client/v1/community_endpoint.dart diff --git a/lib/client/models/community.dart b/lib/client/models/community.dart index 1569ad1..b03afba 100644 --- a/lib/client/models/community.dart +++ b/lib/client/models/community.dart @@ -170,3 +170,14 @@ class CommunityModeratorView { factory CommunityModeratorView.fromJson(Map json) => _$CommunityModeratorViewFromJson(json); } + +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class FullCommunityView { + final CommunityView community; + final List moderators; + + FullCommunityView({this.community, this.moderators}); + + factory FullCommunityView.fromJson(Map json) => + _$FullCommunityViewFromJson(json); +} diff --git a/lib/client/models/community.g.dart b/lib/client/models/community.g.dart index b3c44fd..e0ae0cc 100644 --- a/lib/client/models/community.g.dart +++ b/lib/client/models/community.g.dart @@ -86,3 +86,16 @@ CommunityModeratorView _$CommunityModeratorViewFromJson( communityIcon: json['community_icon'] as String, ); } + +FullCommunityView _$FullCommunityViewFromJson(Map json) { + return FullCommunityView( + community: json['community'] == null + ? null + : CommunityView.fromJson(json['community'] as Map), + moderators: (json['moderators'] as List) + ?.map((e) => e == null + ? null + : CommunityModeratorView.fromJson(e as Map)) + ?.toList(), + ); +} diff --git a/lib/client/v1/community_endpoint.dart b/lib/client/v1/community_endpoint.dart new file mode 100644 index 0000000..7edeb19 --- /dev/null +++ b/lib/client/v1/community_endpoint.dart @@ -0,0 +1,60 @@ +import 'package:flutter/foundation.dart' show required; +import 'package:lemmur/client/models/community.dart'; + +import 'main.dart'; + +extension CommunityEndpoint on V1 { + /// GET /community + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-community + Future getCommunity({ + int id, + String name, + String auth, + }) async { + assert(id != null || name != null); + + var res = await get('/community', { + if (id != null) 'id': id.toString(), + if (name != null) 'name': name, + if (auth != null) 'auth': auth, + }); + + return FullCommunityView.fromJson(res); + } + + /// GET /community/list + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-communities + Future> listCommunities({ + @required SortType sort, + int page, + int limit, + String auth, + }) async { + assert(sort != null); + + var res = await get('/community/list', { + 'sort': sort.value, + if (page != null) 'page': page.toString(), + if (limit != null) 'limit': limit.toString(), + if (auth != null) 'auth': auth, + }); + List communities = res['communities']; + return communities.map((e) => CommunityView.fromJson(e)).toList(); + } + + /// POST /community/follow + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#follow-community + Future followCommunity({ + @required int communityId, + @required bool follow, + @required String auth, + }) async { + var res = await post('/community/follow', { + if (communityId != null) 'community_id': communityId, + if (follow != null) 'follow': follow, + if (auth != null) 'auth': auth, + }); + + return CommunityView.fromJson(res['community']); + } +} diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 71acee3..208bc56 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -5,6 +5,7 @@ import '../models/category.dart'; import '../models/search.dart'; export 'comment_endpoint.dart'; +export 'community_endpoint.dart'; export 'post_endpoint.dart'; export 'user_endpoint.dart'; From 8720272ee5f5ba63de92fe9a6333650ff9f3d1c8 Mon Sep 17 00:00:00 2001 From: krawieck Date: Tue, 18 Aug 2020 23:38:57 +0200 Subject: [PATCH 86/90] Implement 3 endpoints and add 1 model endpoints: * createPostLike * getSite * getFollowedCommunities model: * FullSiteView --- lib/client/models/site.dart | 25 +++++++++++++++++++++++++ lib/client/models/site.g.dart | 21 +++++++++++++++++++++ lib/client/v1/community_endpoint.dart | 15 ++++++++++++++- lib/client/v1/main.dart | 1 + lib/client/v1/post_endpoint.dart | 10 ++++++++-- lib/client/v1/site_endpoint.dart | 21 +++++++++++++++++++++ 6 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 lib/client/v1/site_endpoint.dart diff --git a/lib/client/models/site.dart b/lib/client/models/site.dart index 3ced449..77994f2 100644 --- a/lib/client/models/site.dart +++ b/lib/client/models/site.dart @@ -1,5 +1,7 @@ import 'package:json_annotation/json_annotation.dart'; +import '../models/user.dart'; + part 'site.g.dart'; /// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/site_view.rs#L31 @@ -60,3 +62,26 @@ class SiteView { factory SiteView.fromJson(Map json) => _$SiteViewFromJson(json); } + +@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) +class FullSiteView { + /// can be null + final SiteView site; + final List admins; + final List banned; + final int online; + final String version; + final UserView myUser; + + FullSiteView({ + this.site, + this.admins, + this.banned, + this.online, + this.version, + this.myUser, + }); + + factory FullSiteView.fromJson(Map json) => + _$FullSiteViewFromJson(json); +} diff --git a/lib/client/models/site.g.dart b/lib/client/models/site.g.dart index 7e94e52..6134149 100644 --- a/lib/client/models/site.g.dart +++ b/lib/client/models/site.g.dart @@ -32,3 +32,24 @@ SiteView _$SiteViewFromJson(Map json) { numberOfCommunities: json['number_of_communities'] as int, ); } + +FullSiteView _$FullSiteViewFromJson(Map json) { + return FullSiteView( + site: json['site'] == null + ? null + : SiteView.fromJson(json['site'] as Map), + admins: (json['admins'] as List) + ?.map((e) => + e == null ? null : UserView.fromJson(e as Map)) + ?.toList(), + banned: (json['banned'] as List) + ?.map((e) => + e == null ? null : UserView.fromJson(e as Map)) + ?.toList(), + online: json['online'] as int, + version: json['version'] as String, + myUser: json['my_user'] == null + ? null + : UserView.fromJson(json['my_user'] as Map), + ); +} diff --git a/lib/client/v1/community_endpoint.dart b/lib/client/v1/community_endpoint.dart index 7edeb19..bd5445b 100644 --- a/lib/client/v1/community_endpoint.dart +++ b/lib/client/v1/community_endpoint.dart @@ -1,6 +1,6 @@ import 'package:flutter/foundation.dart' show required; -import 'package:lemmur/client/models/community.dart'; +import '../models/community.dart'; import 'main.dart'; extension CommunityEndpoint on V1 { @@ -57,4 +57,17 @@ extension CommunityEndpoint on V1 { return CommunityView.fromJson(res['community']); } + + /// GET /user/followed_communities + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-followed-communities + Future> getFollowedCommunities({ + @required String auth, + }) async { + final res = await get('/user/followed_communities', { + 'auth': auth, + }); + final List communities = res['communities']; + + return communities.map((e) => CommunityFollowerView.fromJson(e)).toList(); + } } diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart index 208bc56..08651a9 100644 --- a/lib/client/v1/main.dart +++ b/lib/client/v1/main.dart @@ -7,6 +7,7 @@ import '../models/search.dart'; export 'comment_endpoint.dart'; export 'community_endpoint.dart'; export 'post_endpoint.dart'; +export 'site_endpoint.dart'; export 'user_endpoint.dart'; class V1 with HttpHelper { diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart index 519b8bb..427398e 100644 --- a/lib/client/v1/post_endpoint.dart +++ b/lib/client/v1/post_endpoint.dart @@ -70,12 +70,18 @@ extension PostEndpoint on V1 { @required int postId, @required Vote score, @required String auth, - }) { + }) async { assert(postId != null); assert(score != null); assert(auth != null); - throw UnimplementedError(); + var res = await post('/post/like', { + 'post_id': postId, + 'score': score.value, + 'auth': auth, + }); + + return PostView.fromJson(res); } /// PUT /post diff --git a/lib/client/v1/site_endpoint.dart b/lib/client/v1/site_endpoint.dart new file mode 100644 index 0000000..acfef30 --- /dev/null +++ b/lib/client/v1/site_endpoint.dart @@ -0,0 +1,21 @@ +import '../models/site.dart'; +import '../v1/main.dart'; + +extension SiteEndpoint on V1 { + /// GET /site + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-site + Future getSite({String auth}) async { + var res = await get('/site', { + if (auth != null) 'auth': auth, + }); + + return FullSiteView.fromJson(res); + } + + /// GET /site/config + /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-site-config + /// admin stuff + Future getSiteConfig() { + throw UnimplementedError(); + } +} From 26b0894943fb6661d94b1ce82e5de3cdaac84e28 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 21 Aug 2020 00:26:32 +0200 Subject: [PATCH 87/90] Update pubspec.lock --- pubspec.lock | 65 +++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index a1bd223..6479730 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -15,13 +15,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.39.14" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.13" args: dependency: transitive description: @@ -35,7 +28,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.4.2" boolean_selector: dependency: transitive description: @@ -99,6 +92,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "7.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" charcode: dependency: transitive description: @@ -120,6 +120,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.4" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" code_builder: dependency: transitive description: @@ -133,7 +140,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.13" convert: dependency: transitive description: @@ -176,6 +183,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.4" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" fixnum: dependency: transitive description: @@ -235,13 +249,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.12" io: dependency: transitive description: @@ -283,7 +290,7 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.8" meta: dependency: transitive description: @@ -325,7 +332,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.7.0" pedantic: dependency: transitive description: @@ -333,13 +340,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" pool: dependency: transitive description: @@ -407,7 +407,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.5" stream_channel: dependency: transitive description: @@ -442,7 +442,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.15" + version: "0.2.17" timing: dependency: transitive description: @@ -456,7 +456,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.2.0" vector_math: dependency: transitive description: @@ -478,13 +478,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.6.1" yaml: dependency: transitive description: @@ -493,4 +486,4 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.9.0-14.0.dev <3.0.0" From 9e1333e462b23fab72a72f6dd32f14c1ad7d0104 Mon Sep 17 00:00:00 2001 From: shilangyu Date: Fri, 21 Aug 2020 00:22:24 +0000 Subject: [PATCH 88/90] removed migrated code (now at krawieck/lemmy_api_client) --- lib/client/client.dart | 15 - lib/client/http_helper.dart | 39 -- lib/client/models/captcha.dart | 25 -- lib/client/models/captcha.g.dart | 15 - lib/client/models/category.dart | 18 - lib/client/models/category.g.dart | 14 - lib/client/models/comment.dart | 203 --------- lib/client/models/comment.g.dart | 100 ----- lib/client/models/community.dart | 183 -------- lib/client/models/community.g.dart | 101 ----- lib/client/models/post.dart | 158 ------- lib/client/models/post.g.dart | 86 ---- lib/client/models/private_message.dart | 64 --- lib/client/models/private_message.g.dart | 36 -- lib/client/models/search.dart | 29 -- lib/client/models/search.g.dart | 30 -- lib/client/models/site.dart | 87 ---- lib/client/models/site.g.dart | 55 --- lib/client/models/user.dart | 186 -------- lib/client/models/user.g.dart | 103 ----- lib/client/v1/comment_endpoint.dart | 110 ----- lib/client/v1/community_endpoint.dart | 73 --- lib/client/v1/main.dart | 162 ------- lib/client/v1/post_endpoint.dart | 149 ------- lib/client/v1/site_endpoint.dart | 21 - lib/client/v1/user_endpoint.dart | 251 ----------- pubspec.yaml | 7 +- test/client/models/commentview_test.dart | 88 ---- test/client/models/communityview_test.dart | 72 --- test/client/models/postview_test.dart | 109 ----- test/client/models/userview_test.dart | 53 --- test/client/v1_test.dart | 495 --------------------- 32 files changed, 2 insertions(+), 3135 deletions(-) delete mode 100644 lib/client/client.dart delete mode 100644 lib/client/http_helper.dart delete mode 100644 lib/client/models/captcha.dart delete mode 100644 lib/client/models/captcha.g.dart delete mode 100644 lib/client/models/category.dart delete mode 100644 lib/client/models/category.g.dart delete mode 100644 lib/client/models/comment.dart delete mode 100644 lib/client/models/comment.g.dart delete mode 100644 lib/client/models/community.dart delete mode 100644 lib/client/models/community.g.dart delete mode 100644 lib/client/models/post.dart delete mode 100644 lib/client/models/post.g.dart delete mode 100644 lib/client/models/private_message.dart delete mode 100644 lib/client/models/private_message.g.dart delete mode 100644 lib/client/models/search.dart delete mode 100644 lib/client/models/search.g.dart delete mode 100644 lib/client/models/site.dart delete mode 100644 lib/client/models/site.g.dart delete mode 100644 lib/client/models/user.dart delete mode 100644 lib/client/models/user.g.dart delete mode 100644 lib/client/v1/comment_endpoint.dart delete mode 100644 lib/client/v1/community_endpoint.dart delete mode 100644 lib/client/v1/main.dart delete mode 100644 lib/client/v1/post_endpoint.dart delete mode 100644 lib/client/v1/site_endpoint.dart delete mode 100644 lib/client/v1/user_endpoint.dart delete mode 100644 test/client/models/commentview_test.dart delete mode 100644 test/client/models/communityview_test.dart delete mode 100644 test/client/models/postview_test.dart delete mode 100644 test/client/models/userview_test.dart delete mode 100644 test/client/v1_test.dart diff --git a/lib/client/client.dart b/lib/client/client.dart deleted file mode 100644 index 7dad408..0000000 --- a/lib/client/client.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'v1/main.dart'; - -export 'v1/main.dart'; - -class LemmyAPI { - /// host uri of this lemmy instance - String host; - - V1 v1; - - /// initialize lemmy api instance - LemmyAPI(this.host) - : assert(host != null), - v1 = V1(host); -} diff --git a/lib/client/http_helper.dart b/lib/client/http_helper.dart deleted file mode 100644 index 547cb6a..0000000 --- a/lib/client/http_helper.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:http/http.dart' as http; - -extension OkResponse on http.Response { - bool get ok => statusCode >= 200 && statusCode < 300; -} - -mixin HttpHelper { - String host; - String extraPath; - - Future> get(String path, - [Map query]) async { - var res = await http.get(Uri.https(host, '$extraPath$path', query)); - - if (!res.ok) { - // failed request, handle here - } - - return jsonDecode(res.body); - } - - Future> post( - String path, Map body) async { - var res = await http.post( - Uri.https(host, '$extraPath$path'), - body: jsonEncode(body), - headers: {HttpHeaders.contentTypeHeader: ContentType.json.mimeType}, - ); - - if (!res.ok) { - // failed request, handle here - } - - return jsonDecode(res.body); - } -} diff --git a/lib/client/models/captcha.dart b/lib/client/models/captcha.dart deleted file mode 100644 index 3a71ba5..0000000 --- a/lib/client/models/captcha.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'captcha.g.dart'; - -/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class Captcha { - final String png; - - /// can be null - final String wav; - final String uuid; - - const Captcha({ - /// A Base64 encoded png - this.png, - - /// A Base64 encoded wav audio file - this.wav, - this.uuid, - }); - - factory Captcha.fromJson(Map json) => - _$CaptchaFromJson(json); -} diff --git a/lib/client/models/captcha.g.dart b/lib/client/models/captcha.g.dart deleted file mode 100644 index 61bd41b..0000000 --- a/lib/client/models/captcha.g.dart +++ /dev/null @@ -1,15 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'captcha.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Captcha _$CaptchaFromJson(Map json) { - return Captcha( - png: json['png'] as String, - wav: json['wav'] as String, - uuid: json['uuid'] as String, - ); -} diff --git a/lib/client/models/category.dart b/lib/client/models/category.dart deleted file mode 100644 index 6e93d55..0000000 --- a/lib/client/models/category.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'category.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/category.rs#L10 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class Category { - final int id; - final String name; - - const Category({ - this.id, - this.name, - }); - - factory Category.fromJson(Map json) => - _$CategoryFromJson(json); -} diff --git a/lib/client/models/category.g.dart b/lib/client/models/category.g.dart deleted file mode 100644 index ff4df37..0000000 --- a/lib/client/models/category.g.dart +++ /dev/null @@ -1,14 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'category.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Category _$CategoryFromJson(Map json) { - return Category( - id: json['id'] as int, - name: json['name'] as String, - ); -} diff --git a/lib/client/models/comment.dart b/lib/client/models/comment.dart deleted file mode 100644 index d6d157a..0000000 --- a/lib/client/models/comment.dart +++ /dev/null @@ -1,203 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'comment.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/comment_view.rs#L91 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class CommentView { - final int id; - final int creatorId; - final int postId; - final String postName; - - /// can be null - final int parentId; - final String content; - final bool removed; - final bool read; - final DateTime published; - - /// can be null - final DateTime updated; - final bool deleted; - final String apId; - final bool local; - final int communityId; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - final bool banned; - final bool bannedFromCommunity; - final String creatorActorId; - final bool creatorLocal; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - final DateTime creatorPublished; - - /// can be null - final String creatorAvatar; - final int score; - final int upvotes; - final int downvotes; - final int hotRank; - final int hotRankActive; - - /// can be null - final int userId; - - /// can be null - final int myVote; - - /// can be null - final bool subscribed; - - /// can be null - final bool saved; - - const CommentView({ - this.id, - this.creatorId, - this.postId, - this.postName, - this.parentId, - this.content, - this.removed, - this.read, - this.published, - this.updated, - this.deleted, - this.apId, - this.local, - this.communityId, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - this.banned, - this.bannedFromCommunity, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPreferredUsername, - this.creatorPublished, - this.creatorAvatar, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.hotRankActive, - this.userId, - this.myVote, - this.subscribed, - this.saved, - }); - - factory CommentView.fromJson(Map json) => - _$CommentViewFromJson(json); -} - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/comment_view.rs#L356 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class ReplyView { - final int id; - final int creatorId; - final int postId; - final String postName; - - /// can be null - final int parentId; - final String content; - final bool removed; - final bool read; - final DateTime published; - - /// can be null - final DateTime updated; - final bool deleted; - final String apId; - final bool local; - final int communityId; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - final bool banned; - final bool bannedFromCommunity; - final String creatorActorId; - final bool creatorLocal; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - - /// can be null - final String creatorAvatar; - final DateTime creatorPublished; - final int score; - final int upvotes; - final int downvotes; - final int hotRank; - final int hotRankActive; - - /// can be null - final int userId; - - /// can be null - final int myVote; - - /// can be null - final bool subscribed; - - /// can be null - final bool saved; - final int recipientId; - - const ReplyView({ - this.id, - this.creatorId, - this.postId, - this.postName, - this.parentId, - this.content, - this.removed, - this.read, - this.published, - this.updated, - this.deleted, - this.apId, - this.local, - this.communityId, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - this.banned, - this.bannedFromCommunity, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPreferredUsername, - this.creatorAvatar, - this.creatorPublished, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.hotRankActive, - this.userId, - this.myVote, - this.subscribed, - this.saved, - this.recipientId, - }); - - factory ReplyView.fromJson(Map json) => - _$ReplyViewFromJson(json); -} diff --git a/lib/client/models/comment.g.dart b/lib/client/models/comment.g.dart deleted file mode 100644 index 14cb8e3..0000000 --- a/lib/client/models/comment.g.dart +++ /dev/null @@ -1,100 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'comment.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -CommentView _$CommentViewFromJson(Map json) { - return CommentView( - id: json['id'] as int, - creatorId: json['creator_id'] as int, - postId: json['post_id'] as int, - postName: json['post_name'] as String, - parentId: json['parent_id'] as int, - content: json['content'] as String, - removed: json['removed'] as bool, - read: json['read'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - deleted: json['deleted'] as bool, - apId: json['ap_id'] as String, - local: json['local'] as bool, - communityId: json['community_id'] as int, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - banned: json['banned'] as bool, - bannedFromCommunity: json['banned_from_community'] as bool, - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorPublished: json['creator_published'] == null - ? null - : DateTime.parse(json['creator_published'] as String), - creatorAvatar: json['creator_avatar'] as String, - score: json['score'] as int, - upvotes: json['upvotes'] as int, - downvotes: json['downvotes'] as int, - hotRank: json['hot_rank'] as int, - hotRankActive: json['hot_rank_active'] as int, - userId: json['user_id'] as int, - myVote: json['my_vote'] as int, - subscribed: json['subscribed'] as bool, - saved: json['saved'] as bool, - ); -} - -ReplyView _$ReplyViewFromJson(Map json) { - return ReplyView( - id: json['id'] as int, - creatorId: json['creator_id'] as int, - postId: json['post_id'] as int, - postName: json['post_name'] as String, - parentId: json['parent_id'] as int, - content: json['content'] as String, - removed: json['removed'] as bool, - read: json['read'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - deleted: json['deleted'] as bool, - apId: json['ap_id'] as String, - local: json['local'] as bool, - communityId: json['community_id'] as int, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - banned: json['banned'] as bool, - bannedFromCommunity: json['banned_from_community'] as bool, - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorAvatar: json['creator_avatar'] as String, - creatorPublished: json['creator_published'] == null - ? null - : DateTime.parse(json['creator_published'] as String), - score: json['score'] as int, - upvotes: json['upvotes'] as int, - downvotes: json['downvotes'] as int, - hotRank: json['hot_rank'] as int, - hotRankActive: json['hot_rank_active'] as int, - userId: json['user_id'] as int, - myVote: json['my_vote'] as int, - subscribed: json['subscribed'] as bool, - saved: json['saved'] as bool, - recipientId: json['recipient_id'] as int, - ); -} diff --git a/lib/client/models/community.dart b/lib/client/models/community.dart deleted file mode 100644 index b03afba..0000000 --- a/lib/client/models/community.dart +++ /dev/null @@ -1,183 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'community.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L130 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class CommunityView { - final int id; - final String name; - final String title; - - /// can be null - final String icon; - - /// can be null - final String banner; - - /// can be null - final String description; - final int categoryId; - final int creatorId; - final bool removed; - final DateTime published; - - /// can be null - final DateTime updated; - final bool deleted; - final bool nsfw; - final String actorId; - final bool local; - final DateTime lastRefreshedAt; - final String creatorActorId; - final bool creatorLocal; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - - /// can be null - final String creatorAvatar; - final String categoryName; - final int numberOfSubscribers; - final int numberOfPosts; - final int numberOfComments; - final int hotRank; - - /// can be null - final int userId; - - /// can be null - final bool subscribed; - - const CommunityView({ - this.id, - this.name, - this.title, - this.icon, - this.banner, - this.description, - this.categoryId, - this.creatorId, - this.removed, - this.published, - this.updated, - this.deleted, - this.nsfw, - this.actorId, - this.local, - this.lastRefreshedAt, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPreferredUsername, - this.creatorAvatar, - this.categoryName, - this.numberOfSubscribers, - this.numberOfPosts, - this.numberOfComments, - this.hotRank, - this.userId, - this.subscribed, - }); - - factory CommunityView.fromJson(Map json) => - _$CommunityViewFromJson(json); -} - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L336 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class CommunityFollowerView { - final int id; - final int communityId; - final int userId; - final DateTime published; - final String userActorId; - final bool userLocal; - final String userName; - - /// can be null - final String userPreferredUsername; - - /// can be null - final String avatar; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - - const CommunityFollowerView({ - this.id, - this.communityId, - this.userId, - this.published, - this.userActorId, - this.userLocal, - this.userName, - this.userPreferredUsername, - this.avatar, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - }); - - factory CommunityFollowerView.fromJson(Map json) => - _$CommunityFollowerViewFromJson(json); -} - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/community_view.rs#L298 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class CommunityModeratorView { - final int id; - final int communityId; - final int userId; - final DateTime published; - final String userActorId; - final bool userLocal; - final String userName; - - /// can be null - final String userPreferredUsername; - - /// can be null - final String avatar; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - - const CommunityModeratorView({ - this.id, - this.communityId, - this.userId, - this.published, - this.userActorId, - this.userLocal, - this.userName, - this.userPreferredUsername, - this.avatar, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - }); - - factory CommunityModeratorView.fromJson(Map json) => - _$CommunityModeratorViewFromJson(json); -} - -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class FullCommunityView { - final CommunityView community; - final List moderators; - - FullCommunityView({this.community, this.moderators}); - - factory FullCommunityView.fromJson(Map json) => - _$FullCommunityViewFromJson(json); -} diff --git a/lib/client/models/community.g.dart b/lib/client/models/community.g.dart deleted file mode 100644 index e0ae0cc..0000000 --- a/lib/client/models/community.g.dart +++ /dev/null @@ -1,101 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'community.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -CommunityView _$CommunityViewFromJson(Map json) { - return CommunityView( - id: json['id'] as int, - name: json['name'] as String, - title: json['title'] as String, - icon: json['icon'] as String, - banner: json['banner'] as String, - description: json['description'] as String, - categoryId: json['category_id'] as int, - creatorId: json['creator_id'] as int, - removed: json['removed'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - deleted: json['deleted'] as bool, - nsfw: json['nsfw'] as bool, - actorId: json['actor_id'] as String, - local: json['local'] as bool, - lastRefreshedAt: json['last_refreshed_at'] == null - ? null - : DateTime.parse(json['last_refreshed_at'] as String), - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorAvatar: json['creator_avatar'] as String, - categoryName: json['category_name'] as String, - numberOfSubscribers: json['number_of_subscribers'] as int, - numberOfPosts: json['number_of_posts'] as int, - numberOfComments: json['number_of_comments'] as int, - hotRank: json['hot_rank'] as int, - userId: json['user_id'] as int, - subscribed: json['subscribed'] as bool, - ); -} - -CommunityFollowerView _$CommunityFollowerViewFromJson( - Map json) { - return CommunityFollowerView( - id: json['id'] as int, - communityId: json['community_id'] as int, - userId: json['user_id'] as int, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - userActorId: json['user_actor_id'] as String, - userLocal: json['user_local'] as bool, - userName: json['user_name'] as String, - userPreferredUsername: json['user_preferred_username'] as String, - avatar: json['avatar'] as String, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - ); -} - -CommunityModeratorView _$CommunityModeratorViewFromJson( - Map json) { - return CommunityModeratorView( - id: json['id'] as int, - communityId: json['community_id'] as int, - userId: json['user_id'] as int, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - userActorId: json['user_actor_id'] as String, - userLocal: json['user_local'] as bool, - userName: json['user_name'] as String, - userPreferredUsername: json['user_preferred_username'] as String, - avatar: json['avatar'] as String, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - ); -} - -FullCommunityView _$FullCommunityViewFromJson(Map json) { - return FullCommunityView( - community: json['community'] == null - ? null - : CommunityView.fromJson(json['community'] as Map), - moderators: (json['moderators'] as List) - ?.map((e) => e == null - ? null - : CommunityModeratorView.fromJson(e as Map)) - ?.toList(), - ); -} diff --git a/lib/client/models/post.dart b/lib/client/models/post.dart deleted file mode 100644 index 1741729..0000000 --- a/lib/client/models/post.dart +++ /dev/null @@ -1,158 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -import './comment.dart'; -import './community.dart'; - -part 'post.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/post_view.rs#L113 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class PostView { - final int id; - final String name; - - /// can be null - final String url; - - /// can be null - final String body; - final int creatorId; - final int communityId; - final bool removed; - final bool locked; - final DateTime published; - - /// can be null - final DateTime updated; - final bool deleted; - final bool nsfw; - final bool stickied; - - /// can be null - final String embedTitle; - - /// can be null - final String embedDescription; - - /// can be null - final String embedHtml; - - /// can be null - final String thumbnailUrl; - final String apId; - final bool local; - final String creatorActorId; - final bool creatorLocal; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - final DateTime creatorPublished; - - /// can be null - final String creatorAvatar; - final bool banned; - final bool bannedFromCommunity; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - final bool communityRemoved; - final bool communityDeleted; - final bool communityNsfw; - final int numberOfComments; - final int score; - final int upvotes; - final int downvotes; - final int hotRank; - final int hotRankActive; - final DateTime newestActivityTime; - - /// can be null - final int userId; - - /// can be null - final int myVote; - - /// can be null - final bool subscribed; - - /// can be null - final bool read; - - /// can be null - final bool saved; - - const PostView({ - this.id, - this.name, - this.url, - this.body, - this.creatorId, - this.communityId, - this.removed, - this.locked, - this.published, - this.updated, - this.deleted, - this.nsfw, - this.stickied, - this.embedTitle, - this.embedDescription, - this.embedHtml, - this.thumbnailUrl, - this.apId, - this.local, - this.creatorActorId, - this.creatorLocal, - this.creatorName, - this.creatorPreferredUsername, - this.creatorPublished, - this.creatorAvatar, - this.banned, - this.bannedFromCommunity, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - this.communityRemoved, - this.communityDeleted, - this.communityNsfw, - this.numberOfComments, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.hotRankActive, - this.newestActivityTime, - this.userId, - this.myVote, - this.subscribed, - this.read, - this.saved, - }); - - factory PostView.fromJson(Map json) => - _$PostViewFromJson(json); -} - -/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post -@JsonSerializable(createToJson: false) -class FullPost { - final PostView post; - final List comments; - final CommunityView community; - final List moderators; - - const FullPost({ - this.post, - this.comments, - this.community, - this.moderators, - }); - - factory FullPost.fromJson(Map json) => - _$FullPostFromJson(json); -} diff --git a/lib/client/models/post.g.dart b/lib/client/models/post.g.dart deleted file mode 100644 index 204fdd9..0000000 --- a/lib/client/models/post.g.dart +++ /dev/null @@ -1,86 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'post.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -PostView _$PostViewFromJson(Map json) { - return PostView( - id: json['id'] as int, - name: json['name'] as String, - url: json['url'] as String, - body: json['body'] as String, - creatorId: json['creator_id'] as int, - communityId: json['community_id'] as int, - removed: json['removed'] as bool, - locked: json['locked'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - deleted: json['deleted'] as bool, - nsfw: json['nsfw'] as bool, - stickied: json['stickied'] as bool, - embedTitle: json['embed_title'] as String, - embedDescription: json['embed_description'] as String, - embedHtml: json['embed_html'] as String, - thumbnailUrl: json['thumbnail_url'] as String, - apId: json['ap_id'] as String, - local: json['local'] as bool, - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorPublished: json['creator_published'] == null - ? null - : DateTime.parse(json['creator_published'] as String), - creatorAvatar: json['creator_avatar'] as String, - banned: json['banned'] as bool, - bannedFromCommunity: json['banned_from_community'] as bool, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - communityRemoved: json['community_removed'] as bool, - communityDeleted: json['community_deleted'] as bool, - communityNsfw: json['community_nsfw'] as bool, - numberOfComments: json['number_of_comments'] as int, - score: json['score'] as int, - upvotes: json['upvotes'] as int, - downvotes: json['downvotes'] as int, - hotRank: json['hot_rank'] as int, - hotRankActive: json['hot_rank_active'] as int, - newestActivityTime: json['newest_activity_time'] == null - ? null - : DateTime.parse(json['newest_activity_time'] as String), - userId: json['user_id'] as int, - myVote: json['my_vote'] as int, - subscribed: json['subscribed'] as bool, - read: json['read'] as bool, - saved: json['saved'] as bool, - ); -} - -FullPost _$FullPostFromJson(Map json) { - return FullPost( - post: json['post'] == null - ? null - : PostView.fromJson(json['post'] as Map), - comments: (json['comments'] as List) - ?.map((e) => - e == null ? null : CommentView.fromJson(e as Map)) - ?.toList(), - community: json['community'] == null - ? null - : CommunityView.fromJson(json['community'] as Map), - moderators: (json['moderators'] as List) - ?.map((e) => e == null - ? null - : CommunityModeratorView.fromJson(e as Map)) - ?.toList(), - ); -} diff --git a/lib/client/models/private_message.dart b/lib/client/models/private_message.dart deleted file mode 100644 index 32a6d55..0000000 --- a/lib/client/models/private_message.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'private_message.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/private_message_view.rs#L35 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class PrivateMessageView { - final int id; - final int creatorId; - final int recipientId; - final String content; - final bool deleted; - final bool read; - final DateTime published; - - /// can be null - final DateTime updated; - final String apId; - final bool local; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - - /// can be null - final String creatorAvatar; - final String creatorActorId; - final bool creatorLocal; - final String recipientName; - - /// can be null - final String recipientPreferredUsername; - - /// can be null - final String recipientAvatar; - final String recipientActorId; - final bool recipientLocal; - - const PrivateMessageView({ - this.id, - this.creatorId, - this.recipientId, - this.content, - this.deleted, - this.read, - this.published, - this.updated, - this.apId, - this.local, - this.creatorName, - this.creatorPreferredUsername, - this.creatorAvatar, - this.creatorActorId, - this.creatorLocal, - this.recipientName, - this.recipientPreferredUsername, - this.recipientAvatar, - this.recipientActorId, - this.recipientLocal, - }); - - factory PrivateMessageView.fromJson(Map json) => - _$PrivateMessageViewFromJson(json); -} diff --git a/lib/client/models/private_message.g.dart b/lib/client/models/private_message.g.dart deleted file mode 100644 index 6733bff..0000000 --- a/lib/client/models/private_message.g.dart +++ /dev/null @@ -1,36 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'private_message.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -PrivateMessageView _$PrivateMessageViewFromJson(Map json) { - return PrivateMessageView( - id: json['id'] as int, - creatorId: json['creator_id'] as int, - recipientId: json['recipient_id'] as int, - content: json['content'] as String, - deleted: json['deleted'] as bool, - read: json['read'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - apId: json['ap_id'] as String, - local: json['local'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorAvatar: json['creator_avatar'] as String, - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - recipientName: json['recipient_name'] as String, - recipientPreferredUsername: json['recipient_preferred_username'] as String, - recipientAvatar: json['recipient_avatar'] as String, - recipientActorId: json['recipient_actor_id'] as String, - recipientLocal: json['recipient_local'] as bool, - ); -} diff --git a/lib/client/models/search.dart b/lib/client/models/search.dart deleted file mode 100644 index 0abfa3c..0000000 --- a/lib/client/models/search.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -import './comment.dart'; -import './community.dart'; -import './post.dart'; -import './user.dart'; - -part 'search.g.dart'; - -/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search -@JsonSerializable(createToJson: false) -class Search { - @JsonKey(name: 'type_') - final String type; - final List comments; - final List posts; - final List communities; - final List users; - - const Search({ - this.type, - this.comments, - this.posts, - this.communities, - this.users, - }); - - factory Search.fromJson(Map json) => _$SearchFromJson(json); -} diff --git a/lib/client/models/search.g.dart b/lib/client/models/search.g.dart deleted file mode 100644 index 8e62a57..0000000 --- a/lib/client/models/search.g.dart +++ /dev/null @@ -1,30 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'search.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Search _$SearchFromJson(Map json) { - return Search( - type: json['type_'] as String, - comments: (json['comments'] as List) - ?.map((e) => - e == null ? null : CommentView.fromJson(e as Map)) - ?.toList(), - posts: (json['posts'] as List) - ?.map((e) => - e == null ? null : PostView.fromJson(e as Map)) - ?.toList(), - communities: (json['communities'] as List) - ?.map((e) => e == null - ? null - : CommunityView.fromJson(e as Map)) - ?.toList(), - users: (json['users'] as List) - ?.map((e) => - e == null ? null : UserView.fromJson(e as Map)) - ?.toList(), - ); -} diff --git a/lib/client/models/site.dart b/lib/client/models/site.dart deleted file mode 100644 index 77994f2..0000000 --- a/lib/client/models/site.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -import '../models/user.dart'; - -part 'site.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/site_view.rs#L31 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class SiteView { - final int id; - final String name; - - /// can be null - final String description; - final int creatorId; - final DateTime published; - - /// can be null - final DateTime updated; - final bool enableDownvotes; - final bool openRegistration; - final bool enableNsfw; - - /// can be null - final String icon; - - /// can be null - final String banner; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - - /// can be null - final String creatorAvatar; - final int numberOfUsers; - final int numberOfPosts; - final int numberOfComments; - final int numberOfCommunities; - - const SiteView({ - this.id, - this.name, - this.description, - this.creatorId, - this.published, - this.updated, - this.enableDownvotes, - this.openRegistration, - this.enableNsfw, - this.icon, - this.banner, - this.creatorName, - this.creatorPreferredUsername, - this.creatorAvatar, - this.numberOfUsers, - this.numberOfPosts, - this.numberOfComments, - this.numberOfCommunities, - }); - - factory SiteView.fromJson(Map json) => - _$SiteViewFromJson(json); -} - -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class FullSiteView { - /// can be null - final SiteView site; - final List admins; - final List banned; - final int online; - final String version; - final UserView myUser; - - FullSiteView({ - this.site, - this.admins, - this.banned, - this.online, - this.version, - this.myUser, - }); - - factory FullSiteView.fromJson(Map json) => - _$FullSiteViewFromJson(json); -} diff --git a/lib/client/models/site.g.dart b/lib/client/models/site.g.dart deleted file mode 100644 index 6134149..0000000 --- a/lib/client/models/site.g.dart +++ /dev/null @@ -1,55 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'site.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SiteView _$SiteViewFromJson(Map json) { - return SiteView( - id: json['id'] as int, - name: json['name'] as String, - description: json['description'] as String, - creatorId: json['creator_id'] as int, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - enableDownvotes: json['enable_downvotes'] as bool, - openRegistration: json['open_registration'] as bool, - enableNsfw: json['enable_nsfw'] as bool, - icon: json['icon'] as String, - banner: json['banner'] as String, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorAvatar: json['creator_avatar'] as String, - numberOfUsers: json['number_of_users'] as int, - numberOfPosts: json['number_of_posts'] as int, - numberOfComments: json['number_of_comments'] as int, - numberOfCommunities: json['number_of_communities'] as int, - ); -} - -FullSiteView _$FullSiteViewFromJson(Map json) { - return FullSiteView( - site: json['site'] == null - ? null - : SiteView.fromJson(json['site'] as Map), - admins: (json['admins'] as List) - ?.map((e) => - e == null ? null : UserView.fromJson(e as Map)) - ?.toList(), - banned: (json['banned'] as List) - ?.map((e) => - e == null ? null : UserView.fromJson(e as Map)) - ?.toList(), - online: json['online'] as int, - version: json['version'] as String, - myUser: json['my_user'] == null - ? null - : UserView.fromJson(json['my_user'] as Map), - ); -} diff --git a/lib/client/models/user.dart b/lib/client/models/user.dart deleted file mode 100644 index 787cc4e..0000000 --- a/lib/client/models/user.dart +++ /dev/null @@ -1,186 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -import './comment.dart'; -import './community.dart'; -import './post.dart'; - -part 'user.g.dart'; - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/user_view.rs#L58 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class UserView { - final int id; - final String actorId; - final String name; - - /// can be null - final String preferredUsername; - - /// can be null - final String avatar; - - /// can be null - final String banner; - - /// can be null - final String email; - - /// can be null - final String matrixUserId; - - /// can be null - final String bio; - final bool local; - final bool admin; - final bool banned; - final bool showAvatars; - final bool sendNotificationsToEmail; - final DateTime published; - final int numberOfPosts; - final int postScore; - final int numberOfComments; - final int commentScore; - - const UserView({ - this.id, - this.actorId, - this.name, - this.preferredUsername, - this.avatar, - this.banner, - this.email, - this.matrixUserId, - this.bio, - this.local, - this.admin, - this.banned, - this.showAvatars, - this.sendNotificationsToEmail, - this.published, - this.numberOfPosts, - this.postScore, - this.numberOfComments, - this.commentScore, - }); - - factory UserView.fromJson(Map json) => - _$UserViewFromJson(json); -} - -/// based on https://github.com/LemmyNet/lemmy/blob/464ea862b10fa7b226b2550268e40d8e685a939c/server/lemmy_db/src/user_mention_view.rs#L90 -@JsonSerializable(fieldRename: FieldRename.snake, createToJson: false) -class UserMentionView { - final int id; - final int userMentionId; - final int creatorId; - final String creatorActorId; - final bool creatorLocal; - final int postId; - final String postName; - - /// can be null - final int parentId; - final String content; - final bool removed; - final bool read; - final DateTime published; - - /// can be null - final DateTime updated; - final bool deleted; - final int communityId; - final String communityActorId; - final bool communityLocal; - final String communityName; - - /// can be null - final String communityIcon; - final bool banned; - final bool bannedFromCommunity; - final String creatorName; - - /// can be null - final String creatorPreferredUsername; - - /// can be null - final String creatorAvatar; - final int score; - final int upvotes; - final int downvotes; - final int hotRank; - final int hotRankActive; - - /// can be null - final int userId; - - /// can be null - final int myVote; - - /// can be null - final bool saved; - final int recipientId; - final String recipientActorId; - final bool recipientLocal; - - const UserMentionView({ - this.id, - this.userMentionId, - this.creatorId, - this.creatorActorId, - this.creatorLocal, - this.postId, - this.postName, - this.parentId, - this.content, - this.removed, - this.read, - this.published, - this.updated, - this.deleted, - this.communityId, - this.communityActorId, - this.communityLocal, - this.communityName, - this.communityIcon, - this.banned, - this.bannedFromCommunity, - this.creatorName, - this.creatorPreferredUsername, - this.creatorAvatar, - this.score, - this.upvotes, - this.downvotes, - this.hotRank, - this.hotRankActive, - this.userId, - this.myVote, - this.saved, - this.recipientId, - this.recipientActorId, - this.recipientLocal, - }); - - factory UserMentionView.fromJson(Map json) => - _$UserMentionViewFromJson(json); -} - -/// based on https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details -@JsonSerializable(createToJson: false) -class UserDetails { - final UserView user; - final List follows; - final List moderates; - final List comments; - final List posts; - - const UserDetails({ - this.user, - this.follows, - this.moderates, - this.comments, - this.posts, - }); - - factory UserDetails.fromJson(Map json) => - _$UserDetailsFromJson(json); -} diff --git a/lib/client/models/user.g.dart b/lib/client/models/user.g.dart deleted file mode 100644 index eeb804c..0000000 --- a/lib/client/models/user.g.dart +++ /dev/null @@ -1,103 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'user.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -UserView _$UserViewFromJson(Map json) { - return UserView( - id: json['id'] as int, - actorId: json['actor_id'] as String, - name: json['name'] as String, - preferredUsername: json['preferred_username'] as String, - avatar: json['avatar'] as String, - banner: json['banner'] as String, - email: json['email'] as String, - matrixUserId: json['matrix_user_id'] as String, - bio: json['bio'] as String, - local: json['local'] as bool, - admin: json['admin'] as bool, - banned: json['banned'] as bool, - showAvatars: json['show_avatars'] as bool, - sendNotificationsToEmail: json['send_notifications_to_email'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - numberOfPosts: json['number_of_posts'] as int, - postScore: json['post_score'] as int, - numberOfComments: json['number_of_comments'] as int, - commentScore: json['comment_score'] as int, - ); -} - -UserMentionView _$UserMentionViewFromJson(Map json) { - return UserMentionView( - id: json['id'] as int, - userMentionId: json['user_mention_id'] as int, - creatorId: json['creator_id'] as int, - creatorActorId: json['creator_actor_id'] as String, - creatorLocal: json['creator_local'] as bool, - postId: json['post_id'] as int, - postName: json['post_name'] as String, - parentId: json['parent_id'] as int, - content: json['content'] as String, - removed: json['removed'] as bool, - read: json['read'] as bool, - published: json['published'] == null - ? null - : DateTime.parse(json['published'] as String), - updated: json['updated'] == null - ? null - : DateTime.parse(json['updated'] as String), - deleted: json['deleted'] as bool, - communityId: json['community_id'] as int, - communityActorId: json['community_actor_id'] as String, - communityLocal: json['community_local'] as bool, - communityName: json['community_name'] as String, - communityIcon: json['community_icon'] as String, - banned: json['banned'] as bool, - bannedFromCommunity: json['banned_from_community'] as bool, - creatorName: json['creator_name'] as String, - creatorPreferredUsername: json['creator_preferred_username'] as String, - creatorAvatar: json['creator_avatar'] as String, - score: json['score'] as int, - upvotes: json['upvotes'] as int, - downvotes: json['downvotes'] as int, - hotRank: json['hot_rank'] as int, - hotRankActive: json['hot_rank_active'] as int, - userId: json['user_id'] as int, - myVote: json['my_vote'] as int, - saved: json['saved'] as bool, - recipientId: json['recipient_id'] as int, - recipientActorId: json['recipient_actor_id'] as String, - recipientLocal: json['recipient_local'] as bool, - ); -} - -UserDetails _$UserDetailsFromJson(Map json) { - return UserDetails( - user: json['user'] == null - ? null - : UserView.fromJson(json['user'] as Map), - follows: (json['follows'] as List) - ?.map((e) => e == null - ? null - : CommunityFollowerView.fromJson(e as Map)) - ?.toList(), - moderates: (json['moderates'] as List) - ?.map((e) => e == null - ? null - : CommunityModeratorView.fromJson(e as Map)) - ?.toList(), - comments: (json['comments'] as List) - ?.map((e) => - e == null ? null : CommentView.fromJson(e as Map)) - ?.toList(), - posts: (json['posts'] as List) - ?.map((e) => - e == null ? null : PostView.fromJson(e as Map)) - ?.toList(), - ); -} diff --git a/lib/client/v1/comment_endpoint.dart b/lib/client/v1/comment_endpoint.dart deleted file mode 100644 index b769593..0000000 --- a/lib/client/v1/comment_endpoint.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:flutter/foundation.dart' show required; - -import '../models/comment.dart'; -import 'main.dart'; - -extension CommentEndpoint on V1 { - /// POST /comment - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment - Future createComment({ - @required String content, - int parentId, - @required int postId, - int formId, - @required String auth, - }) { - assert(content != null); - assert(postId != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// PUT /comment - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-comment - Future editComment({ - @required String content, - @required int editId, - String formId, - @required String auth, - }) { - assert(content != null); - assert(editId != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /comment/delete - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-comment - /// Only the creator can delete the comment - Future deleteComment({ - @required int editId, - @required bool deleted, - @required String auth, - }) { - assert(editId != null); - assert(deleted != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /comment/remove - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-comment - /// Only a mod or admin can remove the comment - Future removeComment({ - @required int editId, - @required bool removed, - String reason, - @required String auth, - }) { - assert(editId != null); - assert(removed != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /comment/mark_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-comment-as-read - Future markCommentAsRead({ - @required int editId, - @required bool read, - @required String auth, - }) { - assert(editId != null); - assert(read != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /comment/save - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-comment - Future saveComment({ - @required int commentId, - @required bool save, - @required String auth, - }) { - assert(commentId != null); - assert(save != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /comment/like - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-comment-like - Future createCommentLike({ - @required int commentId, - @required Vote score, - @required String auth, - }) { - assert(commentId != null); - assert(score != null); - assert(auth != null); - - throw UnimplementedError(); - } -} diff --git a/lib/client/v1/community_endpoint.dart b/lib/client/v1/community_endpoint.dart deleted file mode 100644 index bd5445b..0000000 --- a/lib/client/v1/community_endpoint.dart +++ /dev/null @@ -1,73 +0,0 @@ -import 'package:flutter/foundation.dart' show required; - -import '../models/community.dart'; -import 'main.dart'; - -extension CommunityEndpoint on V1 { - /// GET /community - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-community - Future getCommunity({ - int id, - String name, - String auth, - }) async { - assert(id != null || name != null); - - var res = await get('/community', { - if (id != null) 'id': id.toString(), - if (name != null) 'name': name, - if (auth != null) 'auth': auth, - }); - - return FullCommunityView.fromJson(res); - } - - /// GET /community/list - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-communities - Future> listCommunities({ - @required SortType sort, - int page, - int limit, - String auth, - }) async { - assert(sort != null); - - var res = await get('/community/list', { - 'sort': sort.value, - if (page != null) 'page': page.toString(), - if (limit != null) 'limit': limit.toString(), - if (auth != null) 'auth': auth, - }); - List communities = res['communities']; - return communities.map((e) => CommunityView.fromJson(e)).toList(); - } - - /// POST /community/follow - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#follow-community - Future followCommunity({ - @required int communityId, - @required bool follow, - @required String auth, - }) async { - var res = await post('/community/follow', { - if (communityId != null) 'community_id': communityId, - if (follow != null) 'follow': follow, - if (auth != null) 'auth': auth, - }); - - return CommunityView.fromJson(res['community']); - } - - /// GET /user/followed_communities - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-followed-communities - Future> getFollowedCommunities({ - @required String auth, - }) async { - final res = await get('/user/followed_communities', { - 'auth': auth, - }); - final List communities = res['communities']; - - return communities.map((e) => CommunityFollowerView.fromJson(e)).toList(); - } -} diff --git a/lib/client/v1/main.dart b/lib/client/v1/main.dart deleted file mode 100644 index 08651a9..0000000 --- a/lib/client/v1/main.dart +++ /dev/null @@ -1,162 +0,0 @@ -import 'package:flutter/foundation.dart' show required; - -import '../http_helper.dart'; -import '../models/category.dart'; -import '../models/search.dart'; - -export 'comment_endpoint.dart'; -export 'community_endpoint.dart'; -export 'post_endpoint.dart'; -export 'site_endpoint.dart'; -export 'user_endpoint.dart'; - -class V1 with HttpHelper { - @override - final String host; - @override - final String extraPath = '/api/v1'; - - V1(this.host); - - /// GET /categories - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#list-categories - Future> listCategories() async { - var res = await get('/categories'); - List categories = res['categories']; - - return categories.map((e) => Category.fromJson(e)).toList(); - } - - /// ~~POST~~ GET /search - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#search - Future search({ - @required String q, - @required SearchType type, - String communityId, - @required SortType sort, - int page, - int limit, - String auth, - }) async { - assert(q != null); - assert(type != null); - assert(sort != null); - - var res = await get('/search', { - 'q': q, - 'type_': type.value, - if (communityId != null) 'community_id': communityId, - 'sort': sort.value, - if (page != null) 'page': page.toString(), - if (limit != null) 'limit': limit.toString(), - if (auth != null) 'auth': auth, - }); - - return Search.fromJson(res); - } -} - -enum Vote { - up, - none, - down, -} - -extension VoteValue on Vote { - int get value { - switch (this) { - case Vote.up: - return 1; - case Vote.none: - return 0; - case Vote.down: - return -1; - } - throw Exception('unreachable'); - } -} - -enum PostListingType { - all, - subscribed, - community, -} - -extension PostTypeValue on PostListingType { - String get value { - switch (this) { - case PostListingType.all: - return 'All'; - case PostListingType.subscribed: - return 'Subscribed'; - case PostListingType.community: - return 'Community'; - } - throw Exception('unreachable'); - } -} - -enum SortType { - active, - hot, - // ignore: constant_identifier_names - new_, - topDay, - topWeek, - topMonth, - topYear, - topAll, -} - -extension SortTypeValue on SortType { - String get value { - switch (this) { - case SortType.active: - return 'Active'; - case SortType.hot: - return 'Hot'; - case SortType.new_: - return 'New'; - case SortType.topDay: - return 'TopDay'; - case SortType.topWeek: - return 'TopWeek'; - case SortType.topMonth: - return 'TopMonth'; - case SortType.topYear: - return 'TopYear'; - case SortType.topAll: - return 'TopAll'; - } - throw Exception('unreachable'); - } -} - -enum SearchType { - all, - comments, - posts, - communities, - users, - url, -} - -extension SearchTypeValue on SearchType { - String get value { - switch (this) { - case SearchType.all: - return 'All'; - case SearchType.comments: - return 'Comments'; - case SearchType.posts: - return 'Posts'; - case SearchType.communities: - return 'Communities'; - case SearchType.users: - return 'Users'; - case SearchType.url: - return 'Url'; - } - throw Exception('unreachable'); - } -} diff --git a/lib/client/v1/post_endpoint.dart b/lib/client/v1/post_endpoint.dart deleted file mode 100644 index 427398e..0000000 --- a/lib/client/v1/post_endpoint.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'package:flutter/foundation.dart' show required; - -import '../models/post.dart'; -import 'main.dart'; - -extension PostEndpoint on V1 { - /// POST /post - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#post - Future createPost({ - @required String name, - String url, - String body, - @required bool nsfw, - @required int communityId, - @required String auth, - }) { - assert(name != null); - assert(nsfw != null); - assert(communityId != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// GET /post - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-post - Future getPost({ - @required int id, - String auth, - }) async { - assert(id != null); - - var res = await get('/post', { - 'id': id.toString(), - if (auth != null) 'auth': auth, - }); - - return FullPost.fromJson(res); - } - - /// GET /post/list - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-posts - Future> getPosts({ - @required PostListingType type, - @required SortType sort, - int page, - int limit, - int communityId, - String communityName, - }) async { - assert(type != null); - assert(sort != null); - - var json = await get('/post/list', { - 'type_': type.value, - 'sort': sort.value, - if (page != null) 'page': page.toString(), - if (limit != null) 'limit': limit.toString(), - if (communityId != null) 'community_id': communityId.toString(), - if (communityName != null) 'community_name': communityName, - }); - - List posts = json['posts']; - return posts.map((e) => PostView.fromJson(e)).toList(); - } - - /// POST /post/like - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-post-like - Future createPostLike({ - @required int postId, - @required Vote score, - @required String auth, - }) async { - assert(postId != null); - assert(score != null); - assert(auth != null); - - var res = await post('/post/like', { - 'post_id': postId, - 'score': score.value, - 'auth': auth, - }); - - return PostView.fromJson(res); - } - - /// PUT /post - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-post - Future editPost({ - @required int editId, - @required String name, - String url, - String body, - @required bool nsfw, - @required String auth, - }) { - assert(editId != null); - assert(name != null); - assert(nsfw != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /post/delete - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-post - /// delete a post in a user deleting their own kind of way - Future deletePost({ - @required int editId, - @required bool deleted, - @required String auth, - }) { - assert(editId != null); - assert(deleted != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /post/remove - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#remove-post - /// remove post in an admin kind of way - Future removePost({ - @required int editId, - @required bool removed, - String reason, - @required String auth, - }) { - assert(editId != null); - assert(removed != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /post/save - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-post - Future savePost({ - @required int postId, - @required bool save, - @required String auth, - }) { - assert(postId != null); - assert(save != null); - assert(auth != null); - - throw UnimplementedError(); - } -} diff --git a/lib/client/v1/site_endpoint.dart b/lib/client/v1/site_endpoint.dart deleted file mode 100644 index acfef30..0000000 --- a/lib/client/v1/site_endpoint.dart +++ /dev/null @@ -1,21 +0,0 @@ -import '../models/site.dart'; -import '../v1/main.dart'; - -extension SiteEndpoint on V1 { - /// GET /site - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-site - Future getSite({String auth}) async { - var res = await get('/site', { - if (auth != null) 'auth': auth, - }); - - return FullSiteView.fromJson(res); - } - - /// GET /site/config - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-site-config - /// admin stuff - Future getSiteConfig() { - throw UnimplementedError(); - } -} diff --git a/lib/client/v1/user_endpoint.dart b/lib/client/v1/user_endpoint.dart deleted file mode 100644 index 2d71bb1..0000000 --- a/lib/client/v1/user_endpoint.dart +++ /dev/null @@ -1,251 +0,0 @@ -import 'package:flutter/foundation.dart' show required; - -import '../models/captcha.dart'; -import '../models/comment.dart'; -import '../models/private_message.dart'; -import '../models/user.dart'; -import 'main.dart'; - -extension UserEndpoint on V1 { - /// POST /user/login - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#login - /// returns jwt - Future login({ - @required String usernameOrEmail, - @required String password, - }) async { - assert(usernameOrEmail != null, password != null); - - final res = await post('/user/login', { - 'username_or_email': usernameOrEmail, - 'password': password, - }); - - return res['jwt']; - } - - /// POST /user/register - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#register - /// returns jwt - Future register({ - @required String username, - String email, - @required String password, - @required String passwordVerify, - @required bool admin, - String captchaUuid, - String captchaAnswer, - }) { - assert(username != null); - assert(password != null); - assert(passwordVerify != null); - assert(admin != null); - assert(((captchaUuid != null) ^ (captchaAnswer != null))); - - throw UnimplementedError(); - } - - /// GET /user/get_captcha - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-captcha - Future getCaptcha() { - throw UnimplementedError(); - } - - /// GET /user - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-details - Future getUserDetails({ - int userId, - String username, - @required SortType sort, - int page, - int limit, - int communityId, - @required bool savedOnly, - String auth, - }) async { - assert(sort != null); - assert(savedOnly != null); - assert((userId != null) ^ (username != null)); - assert(limit == null || limit >= 0); - assert(page == null || page > 0); - - var res = await get('/user', { - if (userId != null) 'user_id': userId.toString(), - if (username != null) 'username': username, - 'sort': sort.value, - if (page != null) 'page': page.toString(), - if (limit != null) 'limit': limit.toString(), - if (communityId != null) 'community_id': communityId.toString(), - if (savedOnly != null) 'saved_only': savedOnly.toString(), - if (auth != null) 'auth': auth, - }); - - return UserDetails.fromJson(res); - } - - /// PUT /save_user_settings - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#save-user-settings - /// returns jwt - Future saveUserSettings({ - @required bool showNsfw, - @required String theme, - @required SortType defaultSortType, - @required PostListingType defaultListingType, - @required String auth, - }) { - assert(showNsfw != null); - assert(theme != null); - assert(defaultSortType != null); - assert(defaultListingType != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// GET /user/replies - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-replies--inbox - Future> getReplies({ - @required SortType sort, - int page, - int limit, - @required bool unreadOnly, - @required String auth, - }) async { - assert(sort != null); - assert(unreadOnly != null); - assert(auth != null); - - var res = await get('/user/replies', { - 'sort': sort.value, - if (page != null) 'page': page.toString(), - if (limit != null) 'limit': limit.toString(), - 'unread_only': unreadOnly.toString(), - 'auth': auth, - }); - List replies = res['replies']; - return replies.map((e) => ReplyView.fromJson(e)).toList(); - } - - /// GET /user/mentions - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-user-mentions - Future> getUserMentions({ - @required String sort, - int page, - int limit, - @required bool unreadOnly, - @required String auth, - }) { - assert(sort != null); - assert(unreadOnly != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /user/mention/mark_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-user-mention-as-read - Future markUserMentionAsRead({ - @required int userMentionId, - @required bool read, - @required String auth, - }) { - assert(userMentionId != null); - assert(read != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// GET /private_message/list - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#get-private-messages - Future> getPrivateMessages({ - @required bool unreadOnly, - int page, - int limit, - @required String auth, - }) { - assert(unreadOnly != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /private_message - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#create-private-message - Future createPrivateMessage({ - @required String content, - @required int recipientId, - @required String auth, - }) { - assert(content != null); - assert(recipientId != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// PUT /private_message - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#edit-private-message - Future editPrivateMessage({ - @required int editId, - @required String content, - @required String auth, - }) { - assert(editId != null); - assert(content != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /private_message/delete - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-private-message - Future deletePrivateMessage({ - @required int editId, - @required bool deleted, - @required String auth, - }) { - assert(editId != null); - assert(deleted != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /private_message/mark_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-private-message-as-read - Future markPrivateMessageAsRead({ - @required int editId, - @required bool read, - @required String auth, - }) { - assert(editId != null); - assert(read != null); - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /user/mark_all_as_read - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#mark-all-as-read - Future> markAllAsRead({ - @required String auth, - }) { - assert(auth != null); - - throw UnimplementedError(); - } - - /// POST /user/delete_account - /// https://dev.lemmy.ml/docs/contributing_websocket_http_api.html#delete-account - /// returns jwt - Future deleteAccount({ - @required String password, - @required String auth, - }) { - assert(password != null); - assert(auth != null); - - throw UnimplementedError(); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 7f7dfcc..1b5440e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 @@ -18,11 +18,9 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: '>=2.7.0 <3.0.0' + sdk: ">=2.7.0 <3.0.0" dependencies: - json_annotation: ^3.0.1 - http: ^0.12.2 flutter: sdk: flutter @@ -34,7 +32,6 @@ dev_dependencies: flutter_test: sdk: flutter effective_dart: ^1.0.0 - json_serializable: ^3.3.0 build_runner: ^1.10.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/test/client/models/commentview_test.dart b/test/client/models/commentview_test.dart deleted file mode 100644 index a3a0619..0000000 --- a/test/client/models/commentview_test.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:lemmur/client/models/comment.dart'; - -void main() { - test('CommentView test', () { - Map commentFromApi = jsonDecode(""" - { - "id": 14296, - "creator_id": 8218, - "post_id": 38501, - "post_name": "Niklaus Wirth was right and that is a problem", - "parent_id": 14286, - "content": "I think that the same functionality current crop of apps has could be implemented much more cleanly and efficiently if there wasn't a rush to get products to market. If developers could spend the time to think things through and try different approaches to see what works best we'd have much higher quality software today. Instead, everything is rushed to market as fast as possible, and developers are constantly overwhelmed with unreasonable amounts of work with no time to do things properly or clean things up along the way.", - "removed": false, - "read": true, - "published": "2020-08-02T20:31:19.303284", - "updated": null, - "deleted": false, - "ap_id": "https://dev.lemmy.ml/comment/14296", - "local": true, - "community_id": 14680, - "community_actor_id": "https://dev.lemmy.ml/c/programming", - "community_local": true, - "community_name": "programming", - "community_icon": null, - "banned": false, - "banned_from_community": false, - "creator_actor_id": "https://dev.lemmy.ml/u/yogthos", - "creator_local": true, - "creator_name": "yogthos", - "creator_preferred_username": null, - "creator_published": "2020-01-18T04:02:39.254957", - "creator_avatar": "https://dev.lemmy.ml/pictrs/image/bwk1q2.png", - "score": 1, - "upvotes": 1, - "downvotes": 0, - "hot_rank": 0, - "hot_rank_active": 0, - "user_id": 13709, - "my_vote": 0, - "subscribed": false, - "saved": false - }"""); - - var comment = CommentView.fromJson(commentFromApi); - - expect(comment.id, 14296); - expect(comment.creatorId, 8218); - expect(comment.postId, 38501); - expect(comment.postName, 'Niklaus Wirth was right and that is a problem'); - expect(comment.parentId, 14286); - expect(comment.content, - '''I think that the same functionality current crop of apps has could be implemented much more cleanly and efficiently if there wasn't a rush to get products to market. If developers could spend the time to think things through and try different approaches to see what works best we'd have much higher quality software today. Instead, everything is rushed to market as fast as possible, and developers are constantly overwhelmed with unreasonable amounts of work with no time to do things properly or clean things up along the way.'''); - expect(comment.removed, false); - expect(comment.read, true); - expect(comment.published, DateTime.parse('2020-08-02T20:31:19.303284')); - expect(comment.updated, null); - expect(comment.deleted, false); - expect(comment.apId, 'https://dev.lemmy.ml/comment/14296'); - expect(comment.local, true); - expect(comment.communityId, 14680); - expect(comment.communityActorId, 'https://dev.lemmy.ml/c/programming'); - expect(comment.communityLocal, true); - expect(comment.communityName, 'programming'); - expect(comment.communityIcon, null); - expect(comment.banned, false); - expect(comment.bannedFromCommunity, false); - expect(comment.creatorActorId, 'https://dev.lemmy.ml/u/yogthos'); - expect(comment.creatorLocal, true); - expect(comment.creatorName, 'yogthos'); - expect(comment.creatorPreferredUsername, null); - expect( - comment.creatorPublished, DateTime.parse('2020-01-18T04:02:39.254957')); - expect( - comment.creatorAvatar, 'https://dev.lemmy.ml/pictrs/image/bwk1q2.png'); - expect(comment.score, 1); - expect(comment.upvotes, 1); - expect(comment.downvotes, 0); - expect(comment.hotRank, 0); - expect(comment.hotRankActive, 0); - expect(comment.userId, 13709); - expect(comment.myVote, 0); - expect(comment.subscribed, false); - expect(comment.saved, false); - }); -} diff --git a/test/client/models/communityview_test.dart b/test/client/models/communityview_test.dart deleted file mode 100644 index b705c94..0000000 --- a/test/client/models/communityview_test.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:lemmur/client/models/community.dart'; - -void main() { - test('PostView test', () { - Map communityJson = jsonDecode(''' - { - "id": 3, - "name": "haskell", - "title": "The Haskell Lemmy Forum", - "icon": null, - "banner": null, - "description": null, - "category_id": 21, - "creator_id": 77, - "removed": false, - "published": "2019-04-22T17:52:37.759443", - "updated": null, - "deleted": false, - "nsfw": false, - "actor_id": "https://dev.lemmy.ml/c/haskell", - "local": true, - "last_refreshed_at": "2020-06-30T00:49:22.589810", - "creator_actor_id": "https://dev.lemmy.ml/u/topos", - "creator_local": true, - "creator_name": "topos", - "creator_preferred_username": null, - "creator_avatar": null, - "category_name": "Programming/Software", - "number_of_subscribers": 85, - "number_of_posts": 0, - "number_of_comments": 0, - "hot_rank": 0, - "user_id": null, - "subscribed": null - }'''); - - var community = CommunityView.fromJson(communityJson); - - expect(community.id, 3); - expect(community.name, 'haskell'); - expect(community.title, 'The Haskell Lemmy Forum'); - expect(community.icon, null); - expect(community.banner, null); - expect(community.description, null); - expect(community.categoryId, 21); - expect(community.creatorId, 77); - expect(community.removed, false); - expect(community.published, DateTime.parse('2019-04-22T17:52:37.759443')); - expect(community.updated, null); - expect(community.deleted, false); - expect(community.nsfw, false); - expect(community.actorId, 'https://dev.lemmy.ml/c/haskell'); - expect(community.local, true); - expect(community.lastRefreshedAt, - DateTime.parse('2020-06-30T00:49:22.589810')); - expect(community.creatorActorId, 'https://dev.lemmy.ml/u/topos'); - expect(community.creatorLocal, true); - expect(community.creatorName, 'topos'); - expect(community.creatorPreferredUsername, null); - expect(community.creatorAvatar, null); - expect(community.categoryName, 'Programming/Software'); - expect(community.numberOfSubscribers, 85); - expect(community.numberOfPosts, 0); - expect(community.numberOfComments, 0); - expect(community.hotRank, 0); - expect(community.userId, null); - expect(community.subscribed, null); - }); -} diff --git a/test/client/models/postview_test.dart b/test/client/models/postview_test.dart deleted file mode 100644 index bb71c23..0000000 --- a/test/client/models/postview_test.dart +++ /dev/null @@ -1,109 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:lemmur/client/models/post.dart'; - -void main() { - test('PostView test', () { - Map postJson = jsonDecode(''' - { - "id": 38501, - "name": "Niklaus Wirth was right and that is a problem", - "url": "https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/", - "body": null, - "creator_id": 8218, - "community_id": 14680, - "removed": false, - "locked": false, - "published": "2020-08-02T01:56:28.072727", - "updated": null, - "deleted": false, - "nsfw": false, - "stickied": false, - "embed_title": "Niklaus Wirth was right and that is a problem", - "embed_description": null, - "embed_html": null, - "thumbnail_url": null, - "ap_id": "https://dev.lemmy.ml/post/38501", - "local": true, - "creator_actor_id": "https://dev.lemmy.ml/u/yogthos", - "creator_local": true, - "creator_name": "yogthos", - "creator_preferred_username": null, - "creator_published": "2020-01-18T04:02:39.254957", - "creator_avatar": "https://dev.lemmy.ml/pictrs/image/bwk1q2.png", - "banned": false, - "banned_from_community": false, - "community_actor_id": "https://dev.lemmy.ml/c/programming", - "community_local": true, - "community_name": "programming", - "community_icon": null, - "community_removed": false, - "community_deleted": false, - "community_nsfw": false, - "number_of_comments": 4, - "score": 8, - "upvotes": 8, - "downvotes": 0, - "hot_rank": 1, - "hot_rank_active": 1, - "newest_activity_time": "2020-08-02T20:31:19.303284", - "user_id": 13709, - "my_vote": 0, - "subscribed": false, - "read": false, - "saved": false - }'''); - - var post = PostView.fromJson(postJson); - - expect(post.id, 38501); - expect(post.name, 'Niklaus Wirth was right and that is a problem'); - expect(post.url, - 'https://bowero.nl/blog/2020/07/31/niklaus-wirth-was-right-and-that-is-a-problem/'); - expect(post.body, null); - expect(post.creatorId, 8218); - expect(post.communityId, 14680); - expect(post.removed, false); - expect(post.locked, false); - expect(post.published, DateTime.parse('2020-08-02T01:56:28.072727')); - expect(post.updated, null); - expect(post.deleted, false); - expect(post.nsfw, false); - expect(post.stickied, false); - expect(post.embedTitle, 'Niklaus Wirth was right and that is a problem'); - expect(post.embedDescription, null); - expect(post.embedHtml, null); - expect(post.thumbnailUrl, null); - expect(post.apId, 'https://dev.lemmy.ml/post/38501'); - expect(post.local, true); - expect(post.creatorActorId, 'https://dev.lemmy.ml/u/yogthos'); - expect(post.creatorLocal, true); - expect(post.creatorName, 'yogthos'); - expect(post.creatorPreferredUsername, null); - expect(post.creatorPublished, DateTime.parse('2020-01-18T04:02:39.254957')); - expect(post.creatorAvatar, 'https://dev.lemmy.ml/pictrs/image/bwk1q2.png'); - expect(post.banned, false); - expect(post.bannedFromCommunity, false); - expect(post.communityActorId, 'https://dev.lemmy.ml/c/programming'); - expect(post.communityLocal, true); - expect(post.communityName, 'programming'); - expect(post.communityIcon, null); - expect(post.communityRemoved, false); - expect(post.communityDeleted, false); - expect(post.communityNsfw, false); - expect(post.numberOfComments, 4); - expect(post.score, 8); - expect(post.upvotes, 8); - expect(post.downvotes, 0); - expect(post.hotRank, 1); - expect(post.hotRankActive, 1); - expect( - post.newestActivityTime, DateTime.parse('2020-08-02T20:31:19.303284')); - expect(post.userId, 13709); - expect(post.myVote, 0); - expect(post.subscribed, false); - expect(post.read, false); - expect(post.saved, false); - }); -} diff --git a/test/client/models/userview_test.dart b/test/client/models/userview_test.dart deleted file mode 100644 index 3f4e710..0000000 --- a/test/client/models/userview_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter_test/flutter_test.dart'; -import 'package:lemmur/client/models/user.dart'; - -void main() { - test('UserView test', () { - Map userJson = jsonDecode(''' - { - "id": 13709, - "actor_id": "https://dev.lemmy.ml/u/krawieck", - "name": "krawieck", - "preferred_username": null, - "avatar": null, - "banner": null, - "email": null, - "matrix_user_id": null, - "bio": null, - "local": true, - "admin": false, - "banned": false, - "show_avatars": true, - "send_notifications_to_email": false, - "published": "2020-08-03T12:22:12.389085", - "number_of_posts": 0, - "post_score": 0, - "number_of_comments": 0, - "comment_score": 0 - }'''); - - var user = UserView.fromJson(userJson); - - expect(user.id, 13709); - expect(user.actorId, 'https://dev.lemmy.ml/u/krawieck'); - expect(user.name, 'krawieck'); - expect(user.preferredUsername, null); - expect(user.avatar, null); - expect(user.banner, null); - expect(user.email, null); - expect(user.matrixUserId, null); - expect(user.bio, null); - expect(user.local, true); - expect(user.admin, false); - expect(user.banned, false); - expect(user.showAvatars, true); - expect(user.sendNotificationsToEmail, false); - expect(user.published, DateTime.parse('2020-08-03T12:22:12.389085')); - expect(user.numberOfPosts, 0); - expect(user.postScore, 0); - expect(user.numberOfComments, 0); - expect(user.commentScore, 0); - }); -} diff --git a/test/client/v1_test.dart b/test/client/v1_test.dart deleted file mode 100644 index b6c1076..0000000 --- a/test/client/v1_test.dart +++ /dev/null @@ -1,495 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:lemmur/client/client.dart'; - -// these are mock exceptions -// should be removed as soon as the real one is implemented -class NotLoggedInException implements Exception { - final String _message; - - NotLoggedInException(this._message); - - @override - String toString() => _message; -} - -class UsernameTakenException implements Exception { - final String _message; - - UsernameTakenException(this._message); - - @override - String toString() => _message; -} - -void main() { - group('lemmy API v1', () { - final lemmy = LemmyAPI('dev.lemmy.ml').v1; - - group('listCategories', () { - test('correctly fetches', () async { - await lemmy.listCategories(); - }); - }); - - group('search', () { - test('correctly fetches', () async { - final res = await lemmy.search( - type: SearchType.all, q: 'asd', sort: SortType.active); - - expect(res.type, SortType.active.value); - }); - - test('forbids illegal numbers', () async { - expect(() async { - await lemmy.search( - type: SearchType.all, q: 'asd', sort: SortType.active, page: 0); - }, throwsA(isInstanceOf())); - - expect(() async { - await lemmy.search( - type: SearchType.all, q: 'asd', sort: SortType.active, limit: -1); - }, throwsA(isInstanceOf())); - }); - - test('handles invalid tokens', () async { - expect(() async { - await lemmy.search( - type: SearchType.all, - q: 'asd', - sort: SortType.active, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('createComment', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.createComment( - content: '123', - postId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('editComment', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.editComment( - content: '123', - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('deleteComment', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.deleteComment( - deleted: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('removeComment', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.removeComment( - removed: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('markCommentAsRead', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.markCommentAsRead( - read: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('saveComment', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.saveComment( - save: true, - commentId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('createCommentLike', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.createCommentLike( - score: Vote.up, - commentId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('createPost', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.createPost( - name: 'asd', - nsfw: false, - communityId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('getPost', () { - test('correctly fetches', () async { - await lemmy.getPost(id: 38936); - }); - - test('handles invalid tokens', () async { - expect(() async { - await lemmy.getPost( - id: 1, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('getPosts', () { - test('correctly fetches', () async { - final res = await lemmy.getPosts( - type: PostListingType.all, sort: SortType.active); - expect(res.length, 10); - }); - - test('forbids illegal numbers', () async { - expect(() async { - await lemmy.getPosts( - type: PostListingType.all, sort: SortType.active, page: 0); - }, throwsA(isInstanceOf())); - - expect(() async { - await lemmy.getPosts( - type: PostListingType.all, sort: SortType.active, limit: -1); - }, throwsA(isInstanceOf())); - }); - }); - - group('createPostLike', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.createPostLike( - postId: 1, - score: Vote.up, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('editPost', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.editPost( - name: 'asd', - nsfw: false, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('deletePost', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.deletePost( - deleted: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('removePost', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.removePost( - removed: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('login', () { - test('handles invalid credentials', () async { - expect(() async { - await lemmy.login( - usernameOrEmail: '123', - password: '123', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('register', () { - // TODO(krawieck): the signature seems to be wrong, waiting for correction - // test('handles already existing account', () async { - // expect(() async { - // await lemmy.register( - // usernameOrEmail: '123', - // password: '123', - // ); - // }, throwsA(isInstanceOf())); - // }); - }); - - group('getCaptcha', () { - test('correctly fetches', () async { - await lemmy.getCaptcha(); - }); - }); - - group('getUserDetails', () { - test('correctly fetches', () async { - await lemmy.getUserDetails(sort: SortType.active, username: 'krawieck'); - }); - - test('forbids illegal numbers', () async { - expect(() async { - await lemmy.getUserDetails(sort: SortType.active, page: 0); - }, throwsA(isInstanceOf())); - - expect(() async { - await lemmy.getUserDetails(sort: SortType.active, limit: -1); - }, throwsA(isInstanceOf())); - }); - - test('forbids both username and userId being passed at once', () async { - expect(() async { - await lemmy.getUserDetails( - sort: SortType.active, - username: 'asd', - userId: 123, - ); - }, throwsA(isInstanceOf())); - }); - - test('handles invalid tokens', () async { - expect(() async { - await lemmy.getUserDetails( - sort: SortType.active, - auth: '123', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('saveUserSettings', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.saveUserSettings( - showNsfw: true, - theme: 'asd', - defaultSortType: SortType.active, - defaultListingType: PostListingType.all, - auth: '123', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('getReplies', () { - test('forbids illegal numbers', () async { - expect(() async { - await lemmy.getReplies( - sort: SortType.active, - unreadOnly: false, - auth: 'asd', - page: 0, - ); - }, throwsA(isInstanceOf())); - - expect(() async { - await lemmy.getReplies( - sort: SortType.active, - unreadOnly: false, - auth: 'asd', - limit: -1, - ); - }, throwsA(isInstanceOf())); - }); - - test('handles invalid tokens', () async { - expect(() async { - await lemmy.getReplies( - sort: SortType.active, - unreadOnly: false, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('getUserMentions', () { - // TODO(krawieck): the signature seems to be wrong, waiting for correction - // test('forbids illegal numbers', () async { - // expect(() async { - // await lemmy.getUserMentions( - // sort: SortType.active, - // unreadOnly: false, - // auth: 'asd', - // page: 0, - // ); - // }, throwsA(isInstanceOf())); - - // expect(() async { - // await lemmy.getUserMentions( - // sort: SortType.active, - // unreadOnly: false, - // auth: 'asd', - // limit: -1, - // ); - // }, throwsA(isInstanceOf())); - // }); - - // test('handles invalid tokens', () async { - // expect(() async { - // await lemmy.getUserMentions( - // sort: SortType.active, - // unreadOnly: false, - // auth: 'asd', - // ); - // }, throwsA(isInstanceOf())); - // }); - }); - - group('markUserMentionAsRead', () { - test('handles invalid credentials', () async { - expect(() async { - await lemmy.markUserMentionAsRead( - userMentionId: 123, - read: true, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('getPrivateMessages', () { - test('forbids illegal numbers', () async { - expect(() async { - await lemmy.getPrivateMessages( - unreadOnly: false, - auth: 'asd', - page: 0, - ); - }, throwsA(isInstanceOf())); - - expect(() async { - await lemmy.getPrivateMessages( - unreadOnly: false, - auth: 'asd', - limit: -1, - ); - }, throwsA(isInstanceOf())); - }); - - test('handles invalid tokens', () async { - expect(() async { - await lemmy.getPrivateMessages( - unreadOnly: false, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('createPrivateMessage', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.createPrivateMessage( - content: 'asd', - recipientId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('editPrivateMessage', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.editPrivateMessage( - content: 'asd', - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('deletePrivateMessage', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.deletePrivateMessage( - deleted: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('markPrivateMessageAsRead', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.markPrivateMessageAsRead( - read: true, - editId: 123, - auth: 'asd', - ); - }, throwsA(isInstanceOf())); - }); - }); - - group('markAllAsRead', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.markAllAsRead(auth: 'asd'); - }, throwsA(isInstanceOf())); - }); - }); - - group('deleteAccount', () { - test('handles invalid tokens', () async { - expect(() async { - await lemmy.deleteAccount(password: 'asd', auth: 'asd'); - }, throwsA(isInstanceOf())); - }); - }); - }); -} From 20d7790609b763393fac6277e3696fb0004a7b7b Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 21 Aug 2020 00:28:00 +0200 Subject: [PATCH 89/90] Update pubspec.lock --- pubspec.lock | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 6479730..d6c3b4b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -228,13 +228,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.14.0+3" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.2" http_multi_server: dependency: transitive description: @@ -264,19 +257,12 @@ packages: source: hosted version: "0.6.2" json_annotation: - dependency: "direct main" + dependency: transitive description: name: json_annotation url: "https://pub.dartlang.org" source: hosted version: "3.0.1" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.0" logging: dependency: transitive description: @@ -387,13 +373,6 @@ packages: description: flutter source: sdk version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.6" source_span: dependency: transitive description: From b19e7d50fa5d0e26d424550fd1c65d2a5ad77c3c Mon Sep 17 00:00:00 2001 From: shilangyu Date: Fri, 21 Aug 2020 00:37:51 +0000 Subject: [PATCH 90/90] fix lints --- lib/main.dart | 62 ++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index e4f1c4c..e94c8cd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,16 +6,14 @@ void main() { class MyApp extends StatelessWidget { @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); - } + Widget build(BuildContext context) => MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: MyHomePage(title: 'Flutter Demo Home Page'), + ); } class MyHomePage extends StatefulWidget { @@ -37,28 +35,26 @@ class _MyHomePageState extends State { } @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), + Widget build(BuildContext context) => Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('You have pushed the button this many times:'), + Text( + '$_counter', + style: Theme.of(context).textTheme.headline4, + ), + ], ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('You have pushed the button this many times:'), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), - ); - } + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: Icon(Icons.add), + ), + ); }