✨ Replies sheet is back
🗑️ The silver paging helper is merged, remove the one inside the own codebase
This commit is contained in:
parent
89fd80bcb8
commit
8d855867c1
@ -100,6 +100,11 @@
|
||||
"permissionModerator": "Moderator",
|
||||
"permissionMember": "Member",
|
||||
"reply": "Reply",
|
||||
"repliesCount": {
|
||||
"zero": "No reply",
|
||||
"one": "{} reply",
|
||||
"other": "{} replies"
|
||||
},
|
||||
"forward": "Forward",
|
||||
"repliedTo": "Replied to",
|
||||
"forwarded": "Forwarded",
|
||||
|
@ -22,6 +22,7 @@ sealed class SnPost with _$SnPost {
|
||||
required int viewsTotal,
|
||||
required int upvotes,
|
||||
required int downvotes,
|
||||
required int repliesCount,
|
||||
required String? threadedPostId,
|
||||
required SnPost? threadedPost,
|
||||
required String? repliedPostId,
|
||||
|
@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
|
||||
/// @nodoc
|
||||
mixin _$SnPost {
|
||||
|
||||
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime get publishedAt; int get visibility; String? get content; int get type; Map<String, dynamic>? get meta; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; List<dynamic> get reactions; List<dynamic> get tags; List<dynamic> get categories; List<dynamic> get collections; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||
String get id; String? get title; String? get description; String? get language; DateTime? get editedAt; DateTime get publishedAt; int get visibility; String? get content; int get type; Map<String, dynamic>? get meta; int get viewsUnique; int get viewsTotal; int get upvotes; int get downvotes; int get repliesCount; String? get threadedPostId; SnPost? get threadedPost; String? get repliedPostId; SnPost? get repliedPost; String? get forwardedPostId; SnPost? get forwardedPost; List<SnCloudFile> get attachments; SnPublisher get publisher; Map<String, int> get reactionsCount; List<dynamic> get reactions; List<dynamic> get tags; List<dynamic> get categories; List<dynamic> get collections; DateTime get createdAt; DateTime get updatedAt; DateTime? get deletedAt;
|
||||
/// Create a copy of SnPost
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@ -29,16 +29,16 @@ $SnPostCopyWith<SnPost> get copyWith => _$SnPostCopyWithImpl<SnPost>(this as SnP
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other.meta, meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&const DeepCollectionEquality().equals(other.attachments, attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other.reactionsCount, reactionsCount)&&const DeepCollectionEquality().equals(other.reactions, reactions)&&const DeepCollectionEquality().equals(other.tags, tags)&&const DeepCollectionEquality().equals(other.categories, categories)&&const DeepCollectionEquality().equals(other.collections, collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,type,const DeepCollectionEquality().hash(meta),viewsUnique,viewsTotal,upvotes,downvotes,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt]);
|
||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,type,const DeepCollectionEquality().hash(meta),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,const DeepCollectionEquality().hash(attachments),publisher,const DeepCollectionEquality().hash(reactionsCount),const DeepCollectionEquality().hash(reactions),const DeepCollectionEquality().hash(tags),const DeepCollectionEquality().hash(categories),const DeepCollectionEquality().hash(collections),createdAt,updatedAt,deletedAt]);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||
}
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ abstract mixin class $SnPostCopyWith<$Res> {
|
||||
factory $SnPostCopyWith(SnPost value, $Res Function(SnPost) _then) = _$SnPostCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime publishedAt, int visibility, String? content, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<dynamic> tags, List<dynamic> categories, List<dynamic> collections, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime publishedAt, int visibility, String? content, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<dynamic> tags, List<dynamic> categories, List<dynamic> collections, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
});
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ class _$SnPostCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SnPost
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = null,Object? visibility = null,Object? content = freezed,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = null,Object? visibility = null,Object? content = freezed,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
@ -82,6 +82,7 @@ as Map<String, dynamic>?,viewsUnique: null == viewsUnique ? _self.viewsUnique :
|
||||
as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable
|
||||
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
||||
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
||||
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
||||
as SnPost?,repliedPostId: freezed == repliedPostId ? _self.repliedPostId : repliedPostId // ignore: cast_nullable_to_non_nullable
|
||||
@ -154,7 +155,7 @@ $SnPublisherCopyWith<$Res> get publisher {
|
||||
@JsonSerializable()
|
||||
|
||||
class _SnPost implements SnPost {
|
||||
const _SnPost({required this.id, required this.title, required this.description, required this.language, required this.editedAt, required this.publishedAt, required this.visibility, required this.content, required this.type, required final Map<String, dynamic>? meta, required this.viewsUnique, required this.viewsTotal, required this.upvotes, required this.downvotes, required this.threadedPostId, required this.threadedPost, required this.repliedPostId, required this.repliedPost, required this.forwardedPostId, required this.forwardedPost, required final List<SnCloudFile> attachments, required this.publisher, final Map<String, int> reactionsCount = const {}, required final List<dynamic> reactions, required final List<dynamic> tags, required final List<dynamic> categories, required final List<dynamic> collections, required this.createdAt, required this.updatedAt, required this.deletedAt}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
|
||||
const _SnPost({required this.id, required this.title, required this.description, required this.language, required this.editedAt, required this.publishedAt, required this.visibility, required this.content, required this.type, required final Map<String, dynamic>? meta, required this.viewsUnique, required this.viewsTotal, required this.upvotes, required this.downvotes, required this.repliesCount, required this.threadedPostId, required this.threadedPost, required this.repliedPostId, required this.repliedPost, required this.forwardedPostId, required this.forwardedPost, required final List<SnCloudFile> attachments, required this.publisher, final Map<String, int> reactionsCount = const {}, required final List<dynamic> reactions, required final List<dynamic> tags, required final List<dynamic> categories, required final List<dynamic> collections, required this.createdAt, required this.updatedAt, required this.deletedAt}): _meta = meta,_attachments = attachments,_reactionsCount = reactionsCount,_reactions = reactions,_tags = tags,_categories = categories,_collections = collections;
|
||||
factory _SnPost.fromJson(Map<String, dynamic> json) => _$SnPostFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@ -179,6 +180,7 @@ class _SnPost implements SnPost {
|
||||
@override final int viewsTotal;
|
||||
@override final int upvotes;
|
||||
@override final int downvotes;
|
||||
@override final int repliesCount;
|
||||
@override final String? threadedPostId;
|
||||
@override final SnPost? threadedPost;
|
||||
@override final String? repliedPostId;
|
||||
@ -245,16 +247,16 @@ Map<String, dynamic> toJson() {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SnPost&&(identical(other.id, id) || other.id == id)&&(identical(other.title, title) || other.title == title)&&(identical(other.description, description) || other.description == description)&&(identical(other.language, language) || other.language == language)&&(identical(other.editedAt, editedAt) || other.editedAt == editedAt)&&(identical(other.publishedAt, publishedAt) || other.publishedAt == publishedAt)&&(identical(other.visibility, visibility) || other.visibility == visibility)&&(identical(other.content, content) || other.content == content)&&(identical(other.type, type) || other.type == type)&&const DeepCollectionEquality().equals(other._meta, _meta)&&(identical(other.viewsUnique, viewsUnique) || other.viewsUnique == viewsUnique)&&(identical(other.viewsTotal, viewsTotal) || other.viewsTotal == viewsTotal)&&(identical(other.upvotes, upvotes) || other.upvotes == upvotes)&&(identical(other.downvotes, downvotes) || other.downvotes == downvotes)&&(identical(other.repliesCount, repliesCount) || other.repliesCount == repliesCount)&&(identical(other.threadedPostId, threadedPostId) || other.threadedPostId == threadedPostId)&&(identical(other.threadedPost, threadedPost) || other.threadedPost == threadedPost)&&(identical(other.repliedPostId, repliedPostId) || other.repliedPostId == repliedPostId)&&(identical(other.repliedPost, repliedPost) || other.repliedPost == repliedPost)&&(identical(other.forwardedPostId, forwardedPostId) || other.forwardedPostId == forwardedPostId)&&(identical(other.forwardedPost, forwardedPost) || other.forwardedPost == forwardedPost)&&const DeepCollectionEquality().equals(other._attachments, _attachments)&&(identical(other.publisher, publisher) || other.publisher == publisher)&&const DeepCollectionEquality().equals(other._reactionsCount, _reactionsCount)&&const DeepCollectionEquality().equals(other._reactions, _reactions)&&const DeepCollectionEquality().equals(other._tags, _tags)&&const DeepCollectionEquality().equals(other._categories, _categories)&&const DeepCollectionEquality().equals(other._collections, _collections)&&(identical(other.createdAt, createdAt) || other.createdAt == createdAt)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.deletedAt, deletedAt) || other.deletedAt == deletedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,type,const DeepCollectionEquality().hash(_meta),viewsUnique,viewsTotal,upvotes,downvotes,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt]);
|
||||
int get hashCode => Object.hashAll([runtimeType,id,title,description,language,editedAt,publishedAt,visibility,content,type,const DeepCollectionEquality().hash(_meta),viewsUnique,viewsTotal,upvotes,downvotes,repliesCount,threadedPostId,threadedPost,repliedPostId,repliedPost,forwardedPostId,forwardedPost,const DeepCollectionEquality().hash(_attachments),publisher,const DeepCollectionEquality().hash(_reactionsCount),const DeepCollectionEquality().hash(_reactions),const DeepCollectionEquality().hash(_tags),const DeepCollectionEquality().hash(_categories),const DeepCollectionEquality().hash(_collections),createdAt,updatedAt,deletedAt]);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||
return 'SnPost(id: $id, title: $title, description: $description, language: $language, editedAt: $editedAt, publishedAt: $publishedAt, visibility: $visibility, content: $content, type: $type, meta: $meta, viewsUnique: $viewsUnique, viewsTotal: $viewsTotal, upvotes: $upvotes, downvotes: $downvotes, repliesCount: $repliesCount, threadedPostId: $threadedPostId, threadedPost: $threadedPost, repliedPostId: $repliedPostId, repliedPost: $repliedPost, forwardedPostId: $forwardedPostId, forwardedPost: $forwardedPost, attachments: $attachments, publisher: $publisher, reactionsCount: $reactionsCount, reactions: $reactions, tags: $tags, categories: $categories, collections: $collections, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt)';
|
||||
}
|
||||
|
||||
|
||||
@ -265,7 +267,7 @@ abstract mixin class _$SnPostCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
||||
factory _$SnPostCopyWith(_SnPost value, $Res Function(_SnPost) _then) = __$SnPostCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime publishedAt, int visibility, String? content, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<dynamic> tags, List<dynamic> categories, List<dynamic> collections, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
String id, String? title, String? description, String? language, DateTime? editedAt, DateTime publishedAt, int visibility, String? content, int type, Map<String, dynamic>? meta, int viewsUnique, int viewsTotal, int upvotes, int downvotes, int repliesCount, String? threadedPostId, SnPost? threadedPost, String? repliedPostId, SnPost? repliedPost, String? forwardedPostId, SnPost? forwardedPost, List<SnCloudFile> attachments, SnPublisher publisher, Map<String, int> reactionsCount, List<dynamic> reactions, List<dynamic> tags, List<dynamic> categories, List<dynamic> collections, DateTime createdAt, DateTime updatedAt, DateTime? deletedAt
|
||||
});
|
||||
|
||||
|
||||
@ -282,7 +284,7 @@ class __$SnPostCopyWithImpl<$Res>
|
||||
|
||||
/// Create a copy of SnPost
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = null,Object? visibility = null,Object? content = freezed,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? title = freezed,Object? description = freezed,Object? language = freezed,Object? editedAt = freezed,Object? publishedAt = null,Object? visibility = null,Object? content = freezed,Object? type = null,Object? meta = freezed,Object? viewsUnique = null,Object? viewsTotal = null,Object? upvotes = null,Object? downvotes = null,Object? repliesCount = null,Object? threadedPostId = freezed,Object? threadedPost = freezed,Object? repliedPostId = freezed,Object? repliedPost = freezed,Object? forwardedPostId = freezed,Object? forwardedPost = freezed,Object? attachments = null,Object? publisher = null,Object? reactionsCount = null,Object? reactions = null,Object? tags = null,Object? categories = null,Object? collections = null,Object? createdAt = null,Object? updatedAt = null,Object? deletedAt = freezed,}) {
|
||||
return _then(_SnPost(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,title: freezed == title ? _self.title : title // ignore: cast_nullable_to_non_nullable
|
||||
@ -298,6 +300,7 @@ as Map<String, dynamic>?,viewsUnique: null == viewsUnique ? _self.viewsUnique :
|
||||
as int,viewsTotal: null == viewsTotal ? _self.viewsTotal : viewsTotal // ignore: cast_nullable_to_non_nullable
|
||||
as int,upvotes: null == upvotes ? _self.upvotes : upvotes // ignore: cast_nullable_to_non_nullable
|
||||
as int,downvotes: null == downvotes ? _self.downvotes : downvotes // ignore: cast_nullable_to_non_nullable
|
||||
as int,repliesCount: null == repliesCount ? _self.repliesCount : repliesCount // ignore: cast_nullable_to_non_nullable
|
||||
as int,threadedPostId: freezed == threadedPostId ? _self.threadedPostId : threadedPostId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,threadedPost: freezed == threadedPost ? _self.threadedPost : threadedPost // ignore: cast_nullable_to_non_nullable
|
||||
as SnPost?,repliedPostId: freezed == repliedPostId ? _self.repliedPostId : repliedPostId // ignore: cast_nullable_to_non_nullable
|
||||
|
@ -24,6 +24,7 @@ _SnPost _$SnPostFromJson(Map<String, dynamic> json) => _SnPost(
|
||||
viewsTotal: (json['views_total'] as num).toInt(),
|
||||
upvotes: (json['upvotes'] as num).toInt(),
|
||||
downvotes: (json['downvotes'] as num).toInt(),
|
||||
repliesCount: (json['replies_count'] as num).toInt(),
|
||||
threadedPostId: json['threaded_post_id'] as String?,
|
||||
threadedPost:
|
||||
json['threaded_post'] == null
|
||||
@ -76,6 +77,7 @@ Map<String, dynamic> _$SnPostToJson(_SnPost instance) => <String, dynamic>{
|
||||
'views_total': instance.viewsTotal,
|
||||
'upvotes': instance.upvotes,
|
||||
'downvotes': instance.downvotes,
|
||||
'replies_count': instance.repliesCount,
|
||||
'threaded_post_id': instance.threadedPostId,
|
||||
'threaded_post': instance.threadedPost?.toJson(),
|
||||
'replied_post_id': instance.repliedPostId,
|
||||
|
@ -182,17 +182,10 @@ class ArticleComposeRoute extends _i29.PageRouteInfo<ArticleComposeRouteArgs> {
|
||||
ArticleComposeRoute({
|
||||
_i30.Key? key,
|
||||
_i32.SnPost? originalPost,
|
||||
_i32.SnPost? repliedPost,
|
||||
_i32.SnPost? forwardedPost,
|
||||
List<_i29.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
ArticleComposeRoute.name,
|
||||
args: ArticleComposeRouteArgs(
|
||||
key: key,
|
||||
originalPost: originalPost,
|
||||
repliedPost: repliedPost,
|
||||
forwardedPost: forwardedPost,
|
||||
),
|
||||
args: ArticleComposeRouteArgs(key: key, originalPost: originalPost),
|
||||
initialChildren: children,
|
||||
);
|
||||
|
||||
@ -213,42 +206,26 @@ class ArticleComposeRoute extends _i29.PageRouteInfo<ArticleComposeRouteArgs> {
|
||||
}
|
||||
|
||||
class ArticleComposeRouteArgs {
|
||||
const ArticleComposeRouteArgs({
|
||||
this.key,
|
||||
this.originalPost,
|
||||
this.repliedPost,
|
||||
this.forwardedPost,
|
||||
});
|
||||
const ArticleComposeRouteArgs({this.key, this.originalPost});
|
||||
|
||||
final _i30.Key? key;
|
||||
|
||||
final _i32.SnPost? originalPost;
|
||||
|
||||
final _i32.SnPost? repliedPost;
|
||||
|
||||
final _i32.SnPost? forwardedPost;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ArticleComposeRouteArgs{key: $key, originalPost: $originalPost, repliedPost: $repliedPost, forwardedPost: $forwardedPost}';
|
||||
return 'ArticleComposeRouteArgs{key: $key, originalPost: $originalPost}';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
if (other is! ArticleComposeRouteArgs) return false;
|
||||
return key == other.key &&
|
||||
originalPost == other.originalPost &&
|
||||
repliedPost == other.repliedPost &&
|
||||
forwardedPost == other.forwardedPost;
|
||||
return key == other.key && originalPost == other.originalPost;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
key.hashCode ^
|
||||
originalPost.hashCode ^
|
||||
repliedPost.hashCode ^
|
||||
forwardedPost.hashCode;
|
||||
int get hashCode => key.hashCode ^ originalPost.hashCode;
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
|
@ -1,236 +0,0 @@
|
||||
// ignore_for_file: implementation_imports, invalid_use_of_internal_member
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:riverpod_paging_utils/src/paging_data.dart';
|
||||
import 'package:riverpod_paging_utils/src/paging_helper_view_theme.dart';
|
||||
import 'package:riverpod_paging_utils/src/paging_notifier_mixin.dart';
|
||||
import 'package:visibility_detector/visibility_detector.dart';
|
||||
|
||||
/// A generic widget for pagination.
|
||||
///
|
||||
/// Main features:
|
||||
/// 1. Displays the widget created by [contentBuilder] when data is available.
|
||||
/// 2. Shows a CircularProgressIndicator while loading the first page.
|
||||
/// 3. Displays an error widget when there is an error on the first page.
|
||||
/// 4. Shows error messages using a SnackBar.
|
||||
/// 5. Loads the next page when the last item is displayed.
|
||||
/// 6. Supports pull-to-refresh functionality.
|
||||
///
|
||||
/// You can customize the appearance of the loading view, error view, and endItemView using [PagingHelperViewTheme].
|
||||
final class PagingHelperSliverView<D extends PagingData<I>, I>
|
||||
extends ConsumerWidget {
|
||||
const PagingHelperSliverView({
|
||||
required this.provider,
|
||||
required this.futureRefreshable,
|
||||
required this.notifierRefreshable,
|
||||
required this.contentBuilder,
|
||||
this.showSecondPageError = true,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final ProviderListenable<AsyncValue<D>> provider;
|
||||
final Refreshable<Future<D>> futureRefreshable;
|
||||
final Refreshable<PagingNotifierMixin<D, I>> notifierRefreshable;
|
||||
|
||||
/// Specifies a function that returns a widget to display when data is available.
|
||||
/// endItemView is a widget to detect when the last displayed item is visible.
|
||||
/// If endItemView is non-null, it is displayed at the end of the list.
|
||||
final Widget Function(D data, int widgetCount, Widget endItemView)
|
||||
contentBuilder;
|
||||
|
||||
final bool showSecondPageError;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = Theme.of(context).extension<PagingHelperViewTheme>();
|
||||
|
||||
final loadingBuilder =
|
||||
theme?.loadingViewBuilder ??
|
||||
(context) => SliverFillRemaining(
|
||||
child: const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
final errorBuilder =
|
||||
theme?.errorViewBuilder ??
|
||||
(context, e, st, onPressed) => SliverFillRemaining(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: onPressed,
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
Text(e.toString()),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return ref
|
||||
.watch(provider)
|
||||
.whenIgnorableError(
|
||||
data: (
|
||||
data, {
|
||||
required hasError,
|
||||
required isLoading,
|
||||
required error,
|
||||
}) {
|
||||
final content = contentBuilder(
|
||||
data,
|
||||
// Add 1 to the length to include the endItemView
|
||||
data.items.length + 1,
|
||||
switch ((data.hasMore, hasError, isLoading)) {
|
||||
// Display a widget to detect when the last element is reached
|
||||
// if there are more pages and no errors
|
||||
(true, false, _) => _EndVDLoadingItemView(
|
||||
onScrollEnd:
|
||||
() async => ref.read(notifierRefreshable).loadNext(),
|
||||
),
|
||||
(true, true, false) when showSecondPageError =>
|
||||
_EndErrorItemView(
|
||||
error: error,
|
||||
onRetryButtonPressed:
|
||||
() async => ref.read(notifierRefreshable).loadNext(),
|
||||
),
|
||||
(true, true, true) => const _EndLoadingItemView(),
|
||||
_ => const SizedBox.shrink(),
|
||||
},
|
||||
);
|
||||
|
||||
return content;
|
||||
},
|
||||
// Loading state for the first page
|
||||
loading: () => loadingBuilder(context),
|
||||
// Error state for the first page
|
||||
error:
|
||||
(e, st) => errorBuilder(
|
||||
context,
|
||||
e,
|
||||
st,
|
||||
() => ref.read(notifierRefreshable).forceRefresh(),
|
||||
),
|
||||
// Prioritize data for errors on the second page and beyond
|
||||
skipErrorOnHasValue: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final class _EndLoadingItemView extends StatelessWidget {
|
||||
const _EndLoadingItemView();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context).extension<PagingHelperViewTheme>();
|
||||
final childBuilder =
|
||||
theme?.endLoadingViewBuilder ??
|
||||
(context) => const Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
|
||||
return childBuilder(context);
|
||||
}
|
||||
}
|
||||
|
||||
final class _EndVDLoadingItemView extends StatelessWidget {
|
||||
const _EndVDLoadingItemView({required this.onScrollEnd});
|
||||
final VoidCallback onScrollEnd;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return VisibilityDetector(
|
||||
key: key ?? const Key('EndItem'),
|
||||
onVisibilityChanged: (info) {
|
||||
if (info.visibleFraction > 0.1) {
|
||||
onScrollEnd();
|
||||
}
|
||||
},
|
||||
child: const _EndLoadingItemView(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final class _EndErrorItemView extends StatelessWidget {
|
||||
const _EndErrorItemView({
|
||||
required this.error,
|
||||
required this.onRetryButtonPressed,
|
||||
});
|
||||
final Object? error;
|
||||
final VoidCallback onRetryButtonPressed;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context).extension<PagingHelperViewTheme>();
|
||||
final childBuilder =
|
||||
theme?.endErrorViewBuilder ??
|
||||
(context, e, onPressed) => Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: onPressed,
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
Text(error.toString()),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return childBuilder(context, error, onRetryButtonPressed);
|
||||
}
|
||||
}
|
||||
|
||||
extension _AsyncValueX<T> on AsyncValue<T> {
|
||||
/// Extends the [when] method to handle async data states more effectively,
|
||||
/// especially when maintaining data integrity despite errors.
|
||||
///
|
||||
/// Use `skipErrorOnHasValue` to retain and display existing data
|
||||
/// even if subsequent fetch attempts result in errors,
|
||||
/// ideal for maintaining a seamless user experience.
|
||||
R whenIgnorableError<R>({
|
||||
required R Function(
|
||||
T data, {
|
||||
required bool hasError,
|
||||
required bool isLoading,
|
||||
required Object? error,
|
||||
})
|
||||
data,
|
||||
required R Function(Object error, StackTrace stackTrace) error,
|
||||
required R Function() loading,
|
||||
bool skipLoadingOnReload = false,
|
||||
bool skipLoadingOnRefresh = true,
|
||||
bool skipError = false,
|
||||
bool skipErrorOnHasValue = false,
|
||||
}) {
|
||||
if (skipErrorOnHasValue) {
|
||||
if (hasValue && hasError) {
|
||||
return data(
|
||||
requireValue,
|
||||
hasError: true,
|
||||
isLoading: isLoading,
|
||||
error: this.error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return when(
|
||||
skipLoadingOnReload: skipLoadingOnReload,
|
||||
skipLoadingOnRefresh: skipLoadingOnRefresh,
|
||||
skipError: skipError,
|
||||
data:
|
||||
(d) => data(
|
||||
d,
|
||||
hasError: hasError,
|
||||
isLoading: isLoading,
|
||||
error: this.error,
|
||||
),
|
||||
error: error,
|
||||
loading: loading,
|
||||
);
|
||||
}
|
||||
}
|
@ -213,7 +213,7 @@ class ComposeLogic {
|
||||
// Prepare API request
|
||||
final client = ref.watch(apiClientProvider);
|
||||
final isNewPost = originalPost == null;
|
||||
final endpoint = isNewPost ? '/posts' : '/posts/${originalPost!.id}';
|
||||
final endpoint = isNewPost ? '/posts' : '/posts/${originalPost.id}';
|
||||
|
||||
// Create request payload
|
||||
final payload = {
|
||||
|
@ -19,6 +19,7 @@ import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/content/cloud_file_collection.dart';
|
||||
import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:island/widgets/content/markdown.dart';
|
||||
import 'package:island/widgets/post/post_replies_sheet.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
import 'package:super_context_menu/super_context_menu.dart';
|
||||
@ -235,19 +236,53 @@ class PostItem extends HookConsumerWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
PostReactionList(
|
||||
Row(
|
||||
children: [
|
||||
// Replies count button
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 48, right: 12),
|
||||
child: ActionChip(
|
||||
avatar: Icon(Symbols.reply, size: 16),
|
||||
label: Text(
|
||||
(item.repliesCount > 0)
|
||||
? 'repliesCount'.plural(item.repliesCount)
|
||||
: 'reply'.tr(),
|
||||
),
|
||||
visualDensity: const VisualDensity(
|
||||
horizontal: VisualDensity.minimumDensity,
|
||||
vertical: VisualDensity.minimumDensity,
|
||||
),
|
||||
onPressed: () {
|
||||
if (isOpenable) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
builder: (context) => PostRepliesSheet(post: item),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
// Reactions list
|
||||
Expanded(
|
||||
child: PostReactionList(
|
||||
parentId: item.id,
|
||||
reactions: item.reactionsCount,
|
||||
padding: EdgeInsets.only(left: 48),
|
||||
padding: EdgeInsets.zero,
|
||||
onReact: (symbol, attitude, delta) {
|
||||
final reactionsCount = Map<String, int>.from(
|
||||
item.reactionsCount,
|
||||
);
|
||||
reactionsCount[symbol] =
|
||||
(reactionsCount[symbol] ?? 0) + delta;
|
||||
onUpdate?.call(item.copyWith(reactionsCount: reactionsCount));
|
||||
onUpdate?.call(
|
||||
item.copyWith(reactionsCount: reactionsCount),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/post.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/widgets/content/paging_helper_ext.dart';
|
||||
import 'package:island/widgets/post/post_item.dart';
|
||||
import 'package:island/widgets/post/post_item_creator.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
@ -3,7 +3,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/post.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/widgets/content/paging_helper_ext.dart';
|
||||
import 'package:island/widgets/post/post_item.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
|
||||
@ -57,7 +56,8 @@ class PostRepliesNotifier extends _$PostRepliesNotifier
|
||||
|
||||
class PostRepliesList extends HookConsumerWidget {
|
||||
final String postId;
|
||||
const PostRepliesList({super.key, required this.postId});
|
||||
final Color? backgroundColor;
|
||||
const PostRepliesList({super.key, required this.postId, this.backgroundColor});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@ -93,7 +93,7 @@ class PostRepliesList extends HookConsumerWidget {
|
||||
children: [
|
||||
PostItem(
|
||||
item: data.items[index],
|
||||
backgroundColor: isWide ? Colors.transparent : null,
|
||||
backgroundColor: backgroundColor ?? (isWide ? Colors.transparent : null),
|
||||
showReferencePost: false,
|
||||
),
|
||||
const Divider(height: 1),
|
||||
|
48
lib/widgets/post/post_replies_sheet.dart
Normal file
48
lib/widgets/post/post_replies_sheet.dart
Normal file
@ -0,0 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/models/post.dart';
|
||||
import 'package:island/widgets/content/sheet.dart';
|
||||
import 'package:island/widgets/post/post_replies.dart';
|
||||
import 'package:island/widgets/post/post_quick_reply.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class PostRepliesSheet extends HookConsumerWidget {
|
||||
final SnPost post;
|
||||
|
||||
const PostRepliesSheet({super.key, required this.post});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return SheetScaffold(
|
||||
titleText: 'repliesCount'.plural(post.repliesCount),
|
||||
child: Column(
|
||||
children: [
|
||||
// Replies list
|
||||
Expanded(
|
||||
child: CustomScrollView(
|
||||
slivers: [PostRepliesList(
|
||||
postId: post.id.toString(),
|
||||
backgroundColor: Colors.transparent,
|
||||
)],
|
||||
),
|
||||
),
|
||||
// Quick reply section
|
||||
Material(
|
||||
elevation: 2,
|
||||
child: PostQuickReply(
|
||||
parent: post,
|
||||
onPosted: () {
|
||||
ref.invalidate(postRepliesNotifierProvider(post.id));
|
||||
},
|
||||
).padding(
|
||||
bottom: MediaQuery.of(context).padding.bottom + 16,
|
||||
top: 16,
|
||||
horizontal: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
38
pubspec.lock
38
pubspec.lock
@ -149,10 +149,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
sha256: cef23f1eda9b57566c81e2133d196f8e3df48f244b317368d65c5943d91148f0
|
||||
sha256: "7cf79af8eb6023bee797a77b067fb6e63ac5650f3789546e023958098feb776e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.5.2"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -173,26 +173,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
sha256: b9e4fda21d846e192628e7a4f6deda6888c36b5b69ba02ff291a01fd529140f0
|
||||
sha256: "7a507e6026abe52074836d51a945bfad456daa7493eb7a6cac565e490e7d5b54"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.4"
|
||||
version: "2.5.2"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "058fe9dce1de7d69c4b84fada934df3e0153dd000758c4d65964d0166779aa99"
|
||||
sha256: "1ce1e5063b564f26c27bda54c82a3d38339df69ec58f90e0017f447de77e4839"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.15"
|
||||
version: "2.5.2"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: "22e3aa1c80e0ada3722fe5b63fd43d9c8990759d0a2cf489c8c5d7b2bdebc021"
|
||||
sha256: "564230f3fd9363df7870058fef11ec5502ee620aec3b1ee8106b943be5c63a76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
version: "9.1.0"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -453,18 +453,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53"
|
||||
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.4.0"
|
||||
version: "11.5.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
|
||||
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
version: "7.0.3"
|
||||
dio:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -895,10 +895,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_svg
|
||||
sha256: d44bf546b13025ec7353091516f6881f1d4c633993cb109c3916c3a0159dadf1
|
||||
sha256: cd57f7969b4679317c17af6fd16ee233c1e60a82ed209d8a475c54fd6fd6f845
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.2.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
@ -1217,10 +1217,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lean_builder
|
||||
sha256: ac129cd2173aa4e53e1327bcee2233d738d68ee446f3c797135633deafe6ca8a
|
||||
sha256: dca2165cfe681c69ae903a0880cab90ee93d730777605a0f44c9dd08cec7e1b9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.0-alpha.12"
|
||||
version: "0.1.0-alpha.13"
|
||||
lint:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1769,10 +1769,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: riverpod_paging_utils
|
||||
sha256: "18f59960807835b1d3cb993e825442d7b09928d0f55ad50bda65c002b5893bdc"
|
||||
sha256: a3eb7cc87d53d90dac9bf0b0d695ecdc049aae5dd6debd7d2d62ab3682cf5841
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.0"
|
||||
version: "0.8.1"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -2509,4 +2509,4 @@ packages:
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.27.4"
|
||||
flutter: ">=3.29.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user