✨ Post reaction
This commit is contained in:
parent
e5239a6ca0
commit
5368f8ebb0
@ -93,6 +93,14 @@
|
|||||||
"postReplyingNotice": "You're about to reply to a post that posted {}.",
|
"postReplyingNotice": "You're about to reply to a post that posted {}.",
|
||||||
"postRepostingNotice": "You're about to repost a post that posted {}.",
|
"postRepostingNotice": "You're about to repost a post that posted {}.",
|
||||||
"postReact": "React",
|
"postReact": "React",
|
||||||
|
"postReactions": "Reactions of Post",
|
||||||
|
"postReactionPoints": {
|
||||||
|
"zero": "{}pt",
|
||||||
|
"one": "{}pt",
|
||||||
|
"other": "{}pts"
|
||||||
|
},
|
||||||
|
"postReactCompleted": "Reaction has been added.",
|
||||||
|
"postReactUncompleted": "Reaction has been removed.",
|
||||||
"postComments": {
|
"postComments": {
|
||||||
"zero": "Comment",
|
"zero": "Comment",
|
||||||
"one": "{} comment",
|
"one": "{} comment",
|
||||||
|
@ -93,6 +93,14 @@
|
|||||||
"postRepostingNotice": "你正在转发由 {} 发布的帖子。",
|
"postRepostingNotice": "你正在转发由 {} 发布的帖子。",
|
||||||
"postReact": "反应",
|
"postReact": "反应",
|
||||||
"postPosted": "帖子已经发表。",
|
"postPosted": "帖子已经发表。",
|
||||||
|
"postReactions": "帖子的反应",
|
||||||
|
"postReactionPoints": {
|
||||||
|
"zero": "{} 点",
|
||||||
|
"one": "{} 点",
|
||||||
|
"other": "{} 点"
|
||||||
|
},
|
||||||
|
"postReactCompleted": "反应已被添加。",
|
||||||
|
"postReactUncompleted": "反应已被移除。",
|
||||||
"postComments": {
|
"postComments": {
|
||||||
"zero": "评论",
|
"zero": "评论",
|
||||||
"one": "{} 条评论",
|
"one": "{} 条评论",
|
||||||
|
@ -136,6 +136,13 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
|
|||||||
postReplyId: _data!.id,
|
postReplyId: _data!.id,
|
||||||
onPost: () {
|
onPost: () {
|
||||||
_childListKey.currentState!.refresh();
|
_childListKey.currentState!.refresh();
|
||||||
|
setState(() {
|
||||||
|
_data = _data!.copyWith(
|
||||||
|
metric: _data!.metric.copyWith(
|
||||||
|
replyCount: _data!.metric.replyCount + 1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -20,7 +20,6 @@ class SnPost with _$SnPost {
|
|||||||
required String? aliasPrefix,
|
required String? aliasPrefix,
|
||||||
required List<dynamic> tags,
|
required List<dynamic> tags,
|
||||||
required List<dynamic> categories,
|
required List<dynamic> categories,
|
||||||
required dynamic reactions,
|
|
||||||
required dynamic replies,
|
required dynamic replies,
|
||||||
required dynamic replyId,
|
required dynamic replyId,
|
||||||
required dynamic repostId,
|
required dynamic repostId,
|
||||||
@ -37,8 +36,6 @@ class SnPost with _$SnPost {
|
|||||||
required DateTime? publishedUntil,
|
required DateTime? publishedUntil,
|
||||||
required int totalUpvote,
|
required int totalUpvote,
|
||||||
required int totalDownvote,
|
required int totalDownvote,
|
||||||
required int? realmId,
|
|
||||||
required dynamic realm,
|
|
||||||
required int publisherId,
|
required int publisherId,
|
||||||
required SnPublisher publisher,
|
required SnPublisher publisher,
|
||||||
required SnMetric metric,
|
required SnMetric metric,
|
||||||
@ -81,6 +78,7 @@ class SnMetric with _$SnMetric {
|
|||||||
const factory SnMetric({
|
const factory SnMetric({
|
||||||
required int replyCount,
|
required int replyCount,
|
||||||
required int reactionCount,
|
required int reactionCount,
|
||||||
|
@Default({}) Map<String, int> reactionList,
|
||||||
}) = _SnMetric;
|
}) = _SnMetric;
|
||||||
|
|
||||||
factory SnMetric.fromJson(Map<String, Object?> json) =>
|
factory SnMetric.fromJson(Map<String, Object?> json) =>
|
||||||
|
@ -31,7 +31,6 @@ mixin _$SnPost {
|
|||||||
String? get aliasPrefix => throw _privateConstructorUsedError;
|
String? get aliasPrefix => throw _privateConstructorUsedError;
|
||||||
List<dynamic> get tags => throw _privateConstructorUsedError;
|
List<dynamic> get tags => throw _privateConstructorUsedError;
|
||||||
List<dynamic> get categories => throw _privateConstructorUsedError;
|
List<dynamic> get categories => throw _privateConstructorUsedError;
|
||||||
dynamic get reactions => throw _privateConstructorUsedError;
|
|
||||||
dynamic get replies => throw _privateConstructorUsedError;
|
dynamic get replies => throw _privateConstructorUsedError;
|
||||||
dynamic get replyId => throw _privateConstructorUsedError;
|
dynamic get replyId => throw _privateConstructorUsedError;
|
||||||
dynamic get repostId => throw _privateConstructorUsedError;
|
dynamic get repostId => throw _privateConstructorUsedError;
|
||||||
@ -48,8 +47,6 @@ mixin _$SnPost {
|
|||||||
DateTime? get publishedUntil => throw _privateConstructorUsedError;
|
DateTime? get publishedUntil => throw _privateConstructorUsedError;
|
||||||
int get totalUpvote => throw _privateConstructorUsedError;
|
int get totalUpvote => throw _privateConstructorUsedError;
|
||||||
int get totalDownvote => throw _privateConstructorUsedError;
|
int get totalDownvote => throw _privateConstructorUsedError;
|
||||||
int? get realmId => throw _privateConstructorUsedError;
|
|
||||||
dynamic get realm => throw _privateConstructorUsedError;
|
|
||||||
int get publisherId => throw _privateConstructorUsedError;
|
int get publisherId => throw _privateConstructorUsedError;
|
||||||
SnPublisher get publisher => throw _privateConstructorUsedError;
|
SnPublisher get publisher => throw _privateConstructorUsedError;
|
||||||
SnMetric get metric => throw _privateConstructorUsedError;
|
SnMetric get metric => throw _privateConstructorUsedError;
|
||||||
@ -81,7 +78,6 @@ abstract class $SnPostCopyWith<$Res> {
|
|||||||
String? aliasPrefix,
|
String? aliasPrefix,
|
||||||
List<dynamic> tags,
|
List<dynamic> tags,
|
||||||
List<dynamic> categories,
|
List<dynamic> categories,
|
||||||
dynamic reactions,
|
|
||||||
dynamic replies,
|
dynamic replies,
|
||||||
dynamic replyId,
|
dynamic replyId,
|
||||||
dynamic repostId,
|
dynamic repostId,
|
||||||
@ -98,8 +94,6 @@ abstract class $SnPostCopyWith<$Res> {
|
|||||||
DateTime? publishedUntil,
|
DateTime? publishedUntil,
|
||||||
int totalUpvote,
|
int totalUpvote,
|
||||||
int totalDownvote,
|
int totalDownvote,
|
||||||
int? realmId,
|
|
||||||
dynamic realm,
|
|
||||||
int publisherId,
|
int publisherId,
|
||||||
SnPublisher publisher,
|
SnPublisher publisher,
|
||||||
SnMetric metric,
|
SnMetric metric,
|
||||||
@ -136,7 +130,6 @@ class _$SnPostCopyWithImpl<$Res, $Val extends SnPost>
|
|||||||
Object? aliasPrefix = freezed,
|
Object? aliasPrefix = freezed,
|
||||||
Object? tags = null,
|
Object? tags = null,
|
||||||
Object? categories = null,
|
Object? categories = null,
|
||||||
Object? reactions = freezed,
|
|
||||||
Object? replies = freezed,
|
Object? replies = freezed,
|
||||||
Object? replyId = freezed,
|
Object? replyId = freezed,
|
||||||
Object? repostId = freezed,
|
Object? repostId = freezed,
|
||||||
@ -153,8 +146,6 @@ class _$SnPostCopyWithImpl<$Res, $Val extends SnPost>
|
|||||||
Object? publishedUntil = freezed,
|
Object? publishedUntil = freezed,
|
||||||
Object? totalUpvote = null,
|
Object? totalUpvote = null,
|
||||||
Object? totalDownvote = null,
|
Object? totalDownvote = null,
|
||||||
Object? realmId = freezed,
|
|
||||||
Object? realm = freezed,
|
|
||||||
Object? publisherId = null,
|
Object? publisherId = null,
|
||||||
Object? publisher = null,
|
Object? publisher = null,
|
||||||
Object? metric = null,
|
Object? metric = null,
|
||||||
@ -205,10 +196,6 @@ class _$SnPostCopyWithImpl<$Res, $Val extends SnPost>
|
|||||||
? _value.categories
|
? _value.categories
|
||||||
: categories // ignore: cast_nullable_to_non_nullable
|
: categories // ignore: cast_nullable_to_non_nullable
|
||||||
as List<dynamic>,
|
as List<dynamic>,
|
||||||
reactions: freezed == reactions
|
|
||||||
? _value.reactions
|
|
||||||
: reactions // ignore: cast_nullable_to_non_nullable
|
|
||||||
as dynamic,
|
|
||||||
replies: freezed == replies
|
replies: freezed == replies
|
||||||
? _value.replies
|
? _value.replies
|
||||||
: replies // ignore: cast_nullable_to_non_nullable
|
: replies // ignore: cast_nullable_to_non_nullable
|
||||||
@ -273,14 +260,6 @@ class _$SnPostCopyWithImpl<$Res, $Val extends SnPost>
|
|||||||
? _value.totalDownvote
|
? _value.totalDownvote
|
||||||
: totalDownvote // ignore: cast_nullable_to_non_nullable
|
: totalDownvote // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
realmId: freezed == realmId
|
|
||||||
? _value.realmId
|
|
||||||
: realmId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
realm: freezed == realm
|
|
||||||
? _value.realm
|
|
||||||
: realm // ignore: cast_nullable_to_non_nullable
|
|
||||||
as dynamic,
|
|
||||||
publisherId: null == publisherId
|
publisherId: null == publisherId
|
||||||
? _value.publisherId
|
? _value.publisherId
|
||||||
: publisherId // ignore: cast_nullable_to_non_nullable
|
: publisherId // ignore: cast_nullable_to_non_nullable
|
||||||
@ -354,7 +333,6 @@ abstract class _$$SnPostImplCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
String? aliasPrefix,
|
String? aliasPrefix,
|
||||||
List<dynamic> tags,
|
List<dynamic> tags,
|
||||||
List<dynamic> categories,
|
List<dynamic> categories,
|
||||||
dynamic reactions,
|
|
||||||
dynamic replies,
|
dynamic replies,
|
||||||
dynamic replyId,
|
dynamic replyId,
|
||||||
dynamic repostId,
|
dynamic repostId,
|
||||||
@ -371,8 +349,6 @@ abstract class _$$SnPostImplCopyWith<$Res> implements $SnPostCopyWith<$Res> {
|
|||||||
DateTime? publishedUntil,
|
DateTime? publishedUntil,
|
||||||
int totalUpvote,
|
int totalUpvote,
|
||||||
int totalDownvote,
|
int totalDownvote,
|
||||||
int? realmId,
|
|
||||||
dynamic realm,
|
|
||||||
int publisherId,
|
int publisherId,
|
||||||
SnPublisher publisher,
|
SnPublisher publisher,
|
||||||
SnMetric metric,
|
SnMetric metric,
|
||||||
@ -410,7 +386,6 @@ class __$$SnPostImplCopyWithImpl<$Res>
|
|||||||
Object? aliasPrefix = freezed,
|
Object? aliasPrefix = freezed,
|
||||||
Object? tags = null,
|
Object? tags = null,
|
||||||
Object? categories = null,
|
Object? categories = null,
|
||||||
Object? reactions = freezed,
|
|
||||||
Object? replies = freezed,
|
Object? replies = freezed,
|
||||||
Object? replyId = freezed,
|
Object? replyId = freezed,
|
||||||
Object? repostId = freezed,
|
Object? repostId = freezed,
|
||||||
@ -427,8 +402,6 @@ class __$$SnPostImplCopyWithImpl<$Res>
|
|||||||
Object? publishedUntil = freezed,
|
Object? publishedUntil = freezed,
|
||||||
Object? totalUpvote = null,
|
Object? totalUpvote = null,
|
||||||
Object? totalDownvote = null,
|
Object? totalDownvote = null,
|
||||||
Object? realmId = freezed,
|
|
||||||
Object? realm = freezed,
|
|
||||||
Object? publisherId = null,
|
Object? publisherId = null,
|
||||||
Object? publisher = null,
|
Object? publisher = null,
|
||||||
Object? metric = null,
|
Object? metric = null,
|
||||||
@ -479,10 +452,6 @@ class __$$SnPostImplCopyWithImpl<$Res>
|
|||||||
? _value._categories
|
? _value._categories
|
||||||
: categories // ignore: cast_nullable_to_non_nullable
|
: categories // ignore: cast_nullable_to_non_nullable
|
||||||
as List<dynamic>,
|
as List<dynamic>,
|
||||||
reactions: freezed == reactions
|
|
||||||
? _value.reactions
|
|
||||||
: reactions // ignore: cast_nullable_to_non_nullable
|
|
||||||
as dynamic,
|
|
||||||
replies: freezed == replies
|
replies: freezed == replies
|
||||||
? _value.replies
|
? _value.replies
|
||||||
: replies // ignore: cast_nullable_to_non_nullable
|
: replies // ignore: cast_nullable_to_non_nullable
|
||||||
@ -547,14 +516,6 @@ class __$$SnPostImplCopyWithImpl<$Res>
|
|||||||
? _value.totalDownvote
|
? _value.totalDownvote
|
||||||
: totalDownvote // ignore: cast_nullable_to_non_nullable
|
: totalDownvote // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
realmId: freezed == realmId
|
|
||||||
? _value.realmId
|
|
||||||
: realmId // ignore: cast_nullable_to_non_nullable
|
|
||||||
as int?,
|
|
||||||
realm: freezed == realm
|
|
||||||
? _value.realm
|
|
||||||
: realm // ignore: cast_nullable_to_non_nullable
|
|
||||||
as dynamic,
|
|
||||||
publisherId: null == publisherId
|
publisherId: null == publisherId
|
||||||
? _value.publisherId
|
? _value.publisherId
|
||||||
: publisherId // ignore: cast_nullable_to_non_nullable
|
: publisherId // ignore: cast_nullable_to_non_nullable
|
||||||
@ -590,7 +551,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
required this.aliasPrefix,
|
required this.aliasPrefix,
|
||||||
required final List<dynamic> tags,
|
required final List<dynamic> tags,
|
||||||
required final List<dynamic> categories,
|
required final List<dynamic> categories,
|
||||||
required this.reactions,
|
|
||||||
required this.replies,
|
required this.replies,
|
||||||
required this.replyId,
|
required this.replyId,
|
||||||
required this.repostId,
|
required this.repostId,
|
||||||
@ -607,8 +567,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
required this.publishedUntil,
|
required this.publishedUntil,
|
||||||
required this.totalUpvote,
|
required this.totalUpvote,
|
||||||
required this.totalDownvote,
|
required this.totalDownvote,
|
||||||
required this.realmId,
|
|
||||||
required this.realm,
|
|
||||||
required this.publisherId,
|
required this.publisherId,
|
||||||
required this.publisher,
|
required this.publisher,
|
||||||
required this.metric,
|
required this.metric,
|
||||||
@ -661,8 +619,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
return EqualUnmodifiableListView(_categories);
|
return EqualUnmodifiableListView(_categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
final dynamic reactions;
|
|
||||||
@override
|
@override
|
||||||
final dynamic replies;
|
final dynamic replies;
|
||||||
@override
|
@override
|
||||||
@ -696,10 +652,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
@override
|
@override
|
||||||
final int totalDownvote;
|
final int totalDownvote;
|
||||||
@override
|
@override
|
||||||
final int? realmId;
|
|
||||||
@override
|
|
||||||
final dynamic realm;
|
|
||||||
@override
|
|
||||||
final int publisherId;
|
final int publisherId;
|
||||||
@override
|
@override
|
||||||
final SnPublisher publisher;
|
final SnPublisher publisher;
|
||||||
@ -710,7 +662,7 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnPost(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, body: $body, language: $language, alias: $alias, aliasPrefix: $aliasPrefix, tags: $tags, categories: $categories, reactions: $reactions, replies: $replies, replyId: $replyId, repostId: $repostId, replyTo: $replyTo, repostTo: $repostTo, visibleUsersList: $visibleUsersList, invisibleUsersList: $invisibleUsersList, visibility: $visibility, editedAt: $editedAt, pinnedAt: $pinnedAt, lockedAt: $lockedAt, isDraft: $isDraft, publishedAt: $publishedAt, publishedUntil: $publishedUntil, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, realmId: $realmId, realm: $realm, publisherId: $publisherId, publisher: $publisher, metric: $metric, preload: $preload)';
|
return 'SnPost(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, deletedAt: $deletedAt, type: $type, body: $body, language: $language, alias: $alias, aliasPrefix: $aliasPrefix, tags: $tags, categories: $categories, replies: $replies, replyId: $replyId, repostId: $repostId, replyTo: $replyTo, repostTo: $repostTo, visibleUsersList: $visibleUsersList, invisibleUsersList: $invisibleUsersList, visibility: $visibility, editedAt: $editedAt, pinnedAt: $pinnedAt, lockedAt: $lockedAt, isDraft: $isDraft, publishedAt: $publishedAt, publishedUntil: $publishedUntil, totalUpvote: $totalUpvote, totalDownvote: $totalDownvote, publisherId: $publisherId, publisher: $publisher, metric: $metric, preload: $preload)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -735,7 +687,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
const DeepCollectionEquality().equals(other._tags, _tags) &&
|
const DeepCollectionEquality().equals(other._tags, _tags) &&
|
||||||
const DeepCollectionEquality()
|
const DeepCollectionEquality()
|
||||||
.equals(other._categories, _categories) &&
|
.equals(other._categories, _categories) &&
|
||||||
const DeepCollectionEquality().equals(other.reactions, reactions) &&
|
|
||||||
const DeepCollectionEquality().equals(other.replies, replies) &&
|
const DeepCollectionEquality().equals(other.replies, replies) &&
|
||||||
const DeepCollectionEquality().equals(other.replyId, replyId) &&
|
const DeepCollectionEquality().equals(other.replyId, replyId) &&
|
||||||
const DeepCollectionEquality().equals(other.repostId, repostId) &&
|
const DeepCollectionEquality().equals(other.repostId, repostId) &&
|
||||||
@ -762,8 +713,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
other.totalUpvote == totalUpvote) &&
|
other.totalUpvote == totalUpvote) &&
|
||||||
(identical(other.totalDownvote, totalDownvote) ||
|
(identical(other.totalDownvote, totalDownvote) ||
|
||||||
other.totalDownvote == totalDownvote) &&
|
other.totalDownvote == totalDownvote) &&
|
||||||
(identical(other.realmId, realmId) || other.realmId == realmId) &&
|
|
||||||
const DeepCollectionEquality().equals(other.realm, realm) &&
|
|
||||||
(identical(other.publisherId, publisherId) ||
|
(identical(other.publisherId, publisherId) ||
|
||||||
other.publisherId == publisherId) &&
|
other.publisherId == publisherId) &&
|
||||||
(identical(other.publisher, publisher) ||
|
(identical(other.publisher, publisher) ||
|
||||||
@ -787,7 +736,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
aliasPrefix,
|
aliasPrefix,
|
||||||
const DeepCollectionEquality().hash(_tags),
|
const DeepCollectionEquality().hash(_tags),
|
||||||
const DeepCollectionEquality().hash(_categories),
|
const DeepCollectionEquality().hash(_categories),
|
||||||
const DeepCollectionEquality().hash(reactions),
|
|
||||||
const DeepCollectionEquality().hash(replies),
|
const DeepCollectionEquality().hash(replies),
|
||||||
const DeepCollectionEquality().hash(replyId),
|
const DeepCollectionEquality().hash(replyId),
|
||||||
const DeepCollectionEquality().hash(repostId),
|
const DeepCollectionEquality().hash(repostId),
|
||||||
@ -804,8 +752,6 @@ class _$SnPostImpl extends _SnPost {
|
|||||||
publishedUntil,
|
publishedUntil,
|
||||||
totalUpvote,
|
totalUpvote,
|
||||||
totalDownvote,
|
totalDownvote,
|
||||||
realmId,
|
|
||||||
const DeepCollectionEquality().hash(realm),
|
|
||||||
publisherId,
|
publisherId,
|
||||||
publisher,
|
publisher,
|
||||||
metric,
|
metric,
|
||||||
@ -841,7 +787,6 @@ abstract class _SnPost extends SnPost {
|
|||||||
required final String? aliasPrefix,
|
required final String? aliasPrefix,
|
||||||
required final List<dynamic> tags,
|
required final List<dynamic> tags,
|
||||||
required final List<dynamic> categories,
|
required final List<dynamic> categories,
|
||||||
required final dynamic reactions,
|
|
||||||
required final dynamic replies,
|
required final dynamic replies,
|
||||||
required final dynamic replyId,
|
required final dynamic replyId,
|
||||||
required final dynamic repostId,
|
required final dynamic repostId,
|
||||||
@ -858,8 +803,6 @@ abstract class _SnPost extends SnPost {
|
|||||||
required final DateTime? publishedUntil,
|
required final DateTime? publishedUntil,
|
||||||
required final int totalUpvote,
|
required final int totalUpvote,
|
||||||
required final int totalDownvote,
|
required final int totalDownvote,
|
||||||
required final int? realmId,
|
|
||||||
required final dynamic realm,
|
|
||||||
required final int publisherId,
|
required final int publisherId,
|
||||||
required final SnPublisher publisher,
|
required final SnPublisher publisher,
|
||||||
required final SnMetric metric,
|
required final SnMetric metric,
|
||||||
@ -891,8 +834,6 @@ abstract class _SnPost extends SnPost {
|
|||||||
@override
|
@override
|
||||||
List<dynamic> get categories;
|
List<dynamic> get categories;
|
||||||
@override
|
@override
|
||||||
dynamic get reactions;
|
|
||||||
@override
|
|
||||||
dynamic get replies;
|
dynamic get replies;
|
||||||
@override
|
@override
|
||||||
dynamic get replyId;
|
dynamic get replyId;
|
||||||
@ -925,10 +866,6 @@ abstract class _SnPost extends SnPost {
|
|||||||
@override
|
@override
|
||||||
int get totalDownvote;
|
int get totalDownvote;
|
||||||
@override
|
@override
|
||||||
int? get realmId;
|
|
||||||
@override
|
|
||||||
dynamic get realm;
|
|
||||||
@override
|
|
||||||
int get publisherId;
|
int get publisherId;
|
||||||
@override
|
@override
|
||||||
SnPublisher get publisher;
|
SnPublisher get publisher;
|
||||||
@ -1356,6 +1293,7 @@ SnMetric _$SnMetricFromJson(Map<String, dynamic> json) {
|
|||||||
mixin _$SnMetric {
|
mixin _$SnMetric {
|
||||||
int get replyCount => throw _privateConstructorUsedError;
|
int get replyCount => throw _privateConstructorUsedError;
|
||||||
int get reactionCount => throw _privateConstructorUsedError;
|
int get reactionCount => throw _privateConstructorUsedError;
|
||||||
|
Map<String, int> get reactionList => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
/// Serializes this SnMetric to a JSON map.
|
/// Serializes this SnMetric to a JSON map.
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@ -1372,7 +1310,7 @@ abstract class $SnMetricCopyWith<$Res> {
|
|||||||
factory $SnMetricCopyWith(SnMetric value, $Res Function(SnMetric) then) =
|
factory $SnMetricCopyWith(SnMetric value, $Res Function(SnMetric) then) =
|
||||||
_$SnMetricCopyWithImpl<$Res, SnMetric>;
|
_$SnMetricCopyWithImpl<$Res, SnMetric>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({int replyCount, int reactionCount});
|
$Res call({int replyCount, int reactionCount, Map<String, int> reactionList});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -1392,6 +1330,7 @@ class _$SnMetricCopyWithImpl<$Res, $Val extends SnMetric>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? replyCount = null,
|
Object? replyCount = null,
|
||||||
Object? reactionCount = null,
|
Object? reactionCount = null,
|
||||||
|
Object? reactionList = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
replyCount: null == replyCount
|
replyCount: null == replyCount
|
||||||
@ -1402,6 +1341,10 @@ class _$SnMetricCopyWithImpl<$Res, $Val extends SnMetric>
|
|||||||
? _value.reactionCount
|
? _value.reactionCount
|
||||||
: reactionCount // ignore: cast_nullable_to_non_nullable
|
: reactionCount // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
reactionList: null == reactionList
|
||||||
|
? _value.reactionList
|
||||||
|
: reactionList // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, int>,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1414,7 +1357,7 @@ abstract class _$$SnMetricImplCopyWith<$Res>
|
|||||||
__$$SnMetricImplCopyWithImpl<$Res>;
|
__$$SnMetricImplCopyWithImpl<$Res>;
|
||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({int replyCount, int reactionCount});
|
$Res call({int replyCount, int reactionCount, Map<String, int> reactionList});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -1432,6 +1375,7 @@ class __$$SnMetricImplCopyWithImpl<$Res>
|
|||||||
$Res call({
|
$Res call({
|
||||||
Object? replyCount = null,
|
Object? replyCount = null,
|
||||||
Object? reactionCount = null,
|
Object? reactionCount = null,
|
||||||
|
Object? reactionList = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$SnMetricImpl(
|
return _then(_$SnMetricImpl(
|
||||||
replyCount: null == replyCount
|
replyCount: null == replyCount
|
||||||
@ -1442,6 +1386,10 @@ class __$$SnMetricImplCopyWithImpl<$Res>
|
|||||||
? _value.reactionCount
|
? _value.reactionCount
|
||||||
: reactionCount // ignore: cast_nullable_to_non_nullable
|
: reactionCount // ignore: cast_nullable_to_non_nullable
|
||||||
as int,
|
as int,
|
||||||
|
reactionList: null == reactionList
|
||||||
|
? _value._reactionList
|
||||||
|
: reactionList // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Map<String, int>,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1449,7 +1397,11 @@ class __$$SnMetricImplCopyWithImpl<$Res>
|
|||||||
/// @nodoc
|
/// @nodoc
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$SnMetricImpl implements _SnMetric {
|
class _$SnMetricImpl implements _SnMetric {
|
||||||
const _$SnMetricImpl({required this.replyCount, required this.reactionCount});
|
const _$SnMetricImpl(
|
||||||
|
{required this.replyCount,
|
||||||
|
required this.reactionCount,
|
||||||
|
final Map<String, int> reactionList = const {}})
|
||||||
|
: _reactionList = reactionList;
|
||||||
|
|
||||||
factory _$SnMetricImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$SnMetricImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$SnMetricImplFromJson(json);
|
_$$SnMetricImplFromJson(json);
|
||||||
@ -1458,10 +1410,18 @@ class _$SnMetricImpl implements _SnMetric {
|
|||||||
final int replyCount;
|
final int replyCount;
|
||||||
@override
|
@override
|
||||||
final int reactionCount;
|
final int reactionCount;
|
||||||
|
final Map<String, int> _reactionList;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
Map<String, int> get reactionList {
|
||||||
|
if (_reactionList is EqualUnmodifiableMapView) return _reactionList;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableMapView(_reactionList);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'SnMetric(replyCount: $replyCount, reactionCount: $reactionCount)';
|
return 'SnMetric(replyCount: $replyCount, reactionCount: $reactionCount, reactionList: $reactionList)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -1472,12 +1432,15 @@ class _$SnMetricImpl implements _SnMetric {
|
|||||||
(identical(other.replyCount, replyCount) ||
|
(identical(other.replyCount, replyCount) ||
|
||||||
other.replyCount == replyCount) &&
|
other.replyCount == replyCount) &&
|
||||||
(identical(other.reactionCount, reactionCount) ||
|
(identical(other.reactionCount, reactionCount) ||
|
||||||
other.reactionCount == reactionCount));
|
other.reactionCount == reactionCount) &&
|
||||||
|
const DeepCollectionEquality()
|
||||||
|
.equals(other._reactionList, _reactionList));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType, replyCount, reactionCount);
|
int get hashCode => Object.hash(runtimeType, replyCount, reactionCount,
|
||||||
|
const DeepCollectionEquality().hash(_reactionList));
|
||||||
|
|
||||||
/// Create a copy of SnMetric
|
/// Create a copy of SnMetric
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@ -1498,7 +1461,8 @@ class _$SnMetricImpl implements _SnMetric {
|
|||||||
abstract class _SnMetric implements SnMetric {
|
abstract class _SnMetric implements SnMetric {
|
||||||
const factory _SnMetric(
|
const factory _SnMetric(
|
||||||
{required final int replyCount,
|
{required final int replyCount,
|
||||||
required final int reactionCount}) = _$SnMetricImpl;
|
required final int reactionCount,
|
||||||
|
final Map<String, int> reactionList}) = _$SnMetricImpl;
|
||||||
|
|
||||||
factory _SnMetric.fromJson(Map<String, dynamic> json) =
|
factory _SnMetric.fromJson(Map<String, dynamic> json) =
|
||||||
_$SnMetricImpl.fromJson;
|
_$SnMetricImpl.fromJson;
|
||||||
@ -1507,6 +1471,8 @@ abstract class _SnMetric implements SnMetric {
|
|||||||
int get replyCount;
|
int get replyCount;
|
||||||
@override
|
@override
|
||||||
int get reactionCount;
|
int get reactionCount;
|
||||||
|
@override
|
||||||
|
Map<String, int> get reactionList;
|
||||||
|
|
||||||
/// Create a copy of SnMetric
|
/// Create a copy of SnMetric
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@ -20,7 +20,6 @@ _$SnPostImpl _$$SnPostImplFromJson(Map<String, dynamic> json) => _$SnPostImpl(
|
|||||||
aliasPrefix: json['alias_prefix'] as String?,
|
aliasPrefix: json['alias_prefix'] as String?,
|
||||||
tags: json['tags'] as List<dynamic>,
|
tags: json['tags'] as List<dynamic>,
|
||||||
categories: json['categories'] as List<dynamic>,
|
categories: json['categories'] as List<dynamic>,
|
||||||
reactions: json['reactions'],
|
|
||||||
replies: json['replies'],
|
replies: json['replies'],
|
||||||
replyId: json['reply_id'],
|
replyId: json['reply_id'],
|
||||||
repostId: json['repost_id'],
|
repostId: json['repost_id'],
|
||||||
@ -47,8 +46,6 @@ _$SnPostImpl _$$SnPostImplFromJson(Map<String, dynamic> json) => _$SnPostImpl(
|
|||||||
: DateTime.parse(json['published_until'] as String),
|
: DateTime.parse(json['published_until'] as String),
|
||||||
totalUpvote: (json['total_upvote'] as num).toInt(),
|
totalUpvote: (json['total_upvote'] as num).toInt(),
|
||||||
totalDownvote: (json['total_downvote'] as num).toInt(),
|
totalDownvote: (json['total_downvote'] as num).toInt(),
|
||||||
realmId: (json['realm_id'] as num?)?.toInt(),
|
|
||||||
realm: json['realm'],
|
|
||||||
publisherId: (json['publisher_id'] as num).toInt(),
|
publisherId: (json['publisher_id'] as num).toInt(),
|
||||||
publisher:
|
publisher:
|
||||||
SnPublisher.fromJson(json['publisher'] as Map<String, dynamic>),
|
SnPublisher.fromJson(json['publisher'] as Map<String, dynamic>),
|
||||||
@ -71,7 +68,6 @@ Map<String, dynamic> _$$SnPostImplToJson(_$SnPostImpl instance) =>
|
|||||||
'alias_prefix': instance.aliasPrefix,
|
'alias_prefix': instance.aliasPrefix,
|
||||||
'tags': instance.tags,
|
'tags': instance.tags,
|
||||||
'categories': instance.categories,
|
'categories': instance.categories,
|
||||||
'reactions': instance.reactions,
|
|
||||||
'replies': instance.replies,
|
'replies': instance.replies,
|
||||||
'reply_id': instance.replyId,
|
'reply_id': instance.replyId,
|
||||||
'repost_id': instance.repostId,
|
'repost_id': instance.repostId,
|
||||||
@ -88,8 +84,6 @@ Map<String, dynamic> _$$SnPostImplToJson(_$SnPostImpl instance) =>
|
|||||||
'published_until': instance.publishedUntil?.toIso8601String(),
|
'published_until': instance.publishedUntil?.toIso8601String(),
|
||||||
'total_upvote': instance.totalUpvote,
|
'total_upvote': instance.totalUpvote,
|
||||||
'total_downvote': instance.totalDownvote,
|
'total_downvote': instance.totalDownvote,
|
||||||
'realm_id': instance.realmId,
|
|
||||||
'realm': instance.realm,
|
|
||||||
'publisher_id': instance.publisherId,
|
'publisher_id': instance.publisherId,
|
||||||
'publisher': instance.publisher.toJson(),
|
'publisher': instance.publisher.toJson(),
|
||||||
'metric': instance.metric.toJson(),
|
'metric': instance.metric.toJson(),
|
||||||
@ -131,12 +125,17 @@ _$SnMetricImpl _$$SnMetricImplFromJson(Map<String, dynamic> json) =>
|
|||||||
_$SnMetricImpl(
|
_$SnMetricImpl(
|
||||||
replyCount: (json['reply_count'] as num).toInt(),
|
replyCount: (json['reply_count'] as num).toInt(),
|
||||||
reactionCount: (json['reaction_count'] as num).toInt(),
|
reactionCount: (json['reaction_count'] as num).toInt(),
|
||||||
|
reactionList: (json['reaction_list'] as Map<String, dynamic>?)?.map(
|
||||||
|
(k, e) => MapEntry(k, (e as num).toInt()),
|
||||||
|
) ??
|
||||||
|
const {},
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$SnMetricImplToJson(_$SnMetricImpl instance) =>
|
Map<String, dynamic> _$$SnMetricImplToJson(_$SnMetricImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'reply_count': instance.replyCount,
|
'reply_count': instance.replyCount,
|
||||||
'reaction_count': instance.reactionCount,
|
'reaction_count': instance.reactionCount,
|
||||||
|
'reaction_list': instance.reactionList,
|
||||||
};
|
};
|
||||||
|
|
||||||
_$SnPublisherImpl _$$SnPublisherImplFromJson(Map<String, dynamic> json) =>
|
_$SnPublisherImpl _$$SnPublisherImplFromJson(Map<String, dynamic> json) =>
|
||||||
|
20
lib/types/reaction.dart
Normal file
20
lib/types/reaction.dart
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
class ReactInfo {
|
||||||
|
final String icon;
|
||||||
|
final int attitude;
|
||||||
|
|
||||||
|
const ReactInfo({required this.icon, required this.attitude});
|
||||||
|
}
|
||||||
|
|
||||||
|
const Map<String, ReactInfo> kTemplateReactions = {
|
||||||
|
'thumb_up': ReactInfo(icon: '👍', attitude: 1),
|
||||||
|
'thumb_down': ReactInfo(icon: '👎', attitude: 2),
|
||||||
|
'just_okay': ReactInfo(icon: '😅', attitude: 0),
|
||||||
|
'cry': ReactInfo(icon: '😭', attitude: 0),
|
||||||
|
'confuse': ReactInfo(icon: '🧐', attitude: 0),
|
||||||
|
'clap': ReactInfo(icon: '👏', attitude: 1),
|
||||||
|
'laugh': ReactInfo(icon: '😂', attitude: 1),
|
||||||
|
'angry': ReactInfo(icon: '😡', attitude: 2),
|
||||||
|
'party': ReactInfo(icon: '🎉', attitude: 1),
|
||||||
|
'joy': ReactInfo(icon: '🤣', attitude: 1),
|
||||||
|
'pray': ReactInfo(icon: '🙏', attitude: 1),
|
||||||
|
};
|
@ -12,16 +12,25 @@ import 'package:surface/widgets/attachment/attachment_list.dart';
|
|||||||
import 'package:surface/widgets/markdown_content.dart';
|
import 'package:surface/widgets/markdown_content.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:surface/widgets/post/post_comment_list.dart';
|
import 'package:surface/widgets/post/post_comment_list.dart';
|
||||||
|
import 'package:surface/widgets/post/post_reaction.dart';
|
||||||
|
|
||||||
class PostItem extends StatelessWidget {
|
class PostItem extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
|
final bool showReactions;
|
||||||
final bool showComments;
|
final bool showComments;
|
||||||
|
final Function(SnPost data)? onChanged;
|
||||||
const PostItem({
|
const PostItem({
|
||||||
super.key,
|
super.key,
|
||||||
required this.data,
|
required this.data,
|
||||||
|
this.showReactions = true,
|
||||||
this.showComments = true,
|
this.showComments = true,
|
||||||
|
this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
void _onChanged(SnPost data) {
|
||||||
|
if (onChanged != null) onChanged!(data);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Column(
|
||||||
@ -34,8 +43,12 @@ class PostItem extends StatelessWidget {
|
|||||||
data: data.preload!.attachments!,
|
data: data.preload!.attachments!,
|
||||||
bordered: true,
|
bordered: true,
|
||||||
),
|
),
|
||||||
_PostBottomAction(data: data, showComments: showComments)
|
_PostBottomAction(
|
||||||
.padding(left: 12, right: 18),
|
data: data,
|
||||||
|
showComments: showComments,
|
||||||
|
showReactions: showReactions,
|
||||||
|
onChanged: _onChanged,
|
||||||
|
).padding(left: 12, right: 18),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -44,7 +57,14 @@ class PostItem extends StatelessWidget {
|
|||||||
class _PostBottomAction extends StatelessWidget {
|
class _PostBottomAction extends StatelessWidget {
|
||||||
final SnPost data;
|
final SnPost data;
|
||||||
final bool showComments;
|
final bool showComments;
|
||||||
const _PostBottomAction({required this.data, required this.showComments});
|
final bool showReactions;
|
||||||
|
final Function(SnPost data) onChanged;
|
||||||
|
const _PostBottomAction({
|
||||||
|
required this.data,
|
||||||
|
required this.showComments,
|
||||||
|
required this.showReactions,
|
||||||
|
required this.onChanged,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -56,16 +76,40 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
if (showReactions)
|
||||||
child: Row(
|
InkWell(
|
||||||
children: [
|
child: Row(
|
||||||
Icon(Symbols.add_reaction, size: 20, color: iconColor),
|
children: [
|
||||||
const Gap(8),
|
Icon(Symbols.add_reaction, size: 20, color: iconColor),
|
||||||
Text('postReact').tr(),
|
const Gap(8),
|
||||||
],
|
if (data.totalDownvote > 0 || data.totalUpvote > 0)
|
||||||
).padding(horizontal: 8, vertical: 8),
|
Text('postReactionPoints').plural(
|
||||||
onTap: () {},
|
data.totalUpvote - data.totalDownvote,
|
||||||
),
|
)
|
||||||
|
else
|
||||||
|
Text('postReact').tr(),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 8, vertical: 8),
|
||||||
|
onTap: () {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => PostReactionPopup(
|
||||||
|
data: data,
|
||||||
|
onChanged: (value, isPositive, delta) {
|
||||||
|
onChanged(data.copyWith(
|
||||||
|
totalUpvote: isPositive
|
||||||
|
? data.totalUpvote + delta
|
||||||
|
: data.totalUpvote,
|
||||||
|
totalDownvote: !isPositive
|
||||||
|
? data.totalDownvote + delta
|
||||||
|
: data.totalDownvote,
|
||||||
|
metric: data.metric.copyWith(reactionList: value),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
if (showComments)
|
if (showComments)
|
||||||
InkWell(
|
InkWell(
|
||||||
child: Row(
|
child: Row(
|
||||||
|
128
lib/widgets/post/post_reaction.dart
Normal file
128
lib/widgets/post/post_reaction.dart
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'package:surface/providers/sn_network.dart';
|
||||||
|
import 'package:surface/types/post.dart';
|
||||||
|
import 'package:surface/types/reaction.dart';
|
||||||
|
import 'package:surface/widgets/dialog.dart';
|
||||||
|
|
||||||
|
class PostReactionPopup extends StatefulWidget {
|
||||||
|
final SnPost data;
|
||||||
|
final Function(Map<String, int> value, bool isPositive, int delta)? onChanged;
|
||||||
|
const PostReactionPopup({super.key, required this.data, this.onChanged});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PostReactionPopup> createState() => _PostReactionPopupState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PostReactionPopupState extends State<PostReactionPopup> {
|
||||||
|
bool _isSubmitting = false;
|
||||||
|
late Map<String, int> _reactions;
|
||||||
|
|
||||||
|
Future<void> _reactPost(String symbol, int attitude) async {
|
||||||
|
if (_isSubmitting) return;
|
||||||
|
|
||||||
|
final sn = context.read<SnNetworkProvider>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
setState(() => _isSubmitting = true);
|
||||||
|
final resp = await sn.client.post(
|
||||||
|
'/cgi/co/posts/${widget.data.id}/react',
|
||||||
|
data: {
|
||||||
|
'symbol': symbol,
|
||||||
|
'attitude': attitude,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (resp.statusCode == 201) {
|
||||||
|
_reactions[symbol] = (_reactions[symbol] ?? 0) + 1;
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
if (context.mounted) context.showSnackbar('postReactCompleted'.tr());
|
||||||
|
if (widget.onChanged != null) {
|
||||||
|
widget.onChanged!(
|
||||||
|
_reactions,
|
||||||
|
kTemplateReactions[symbol]!.attitude == 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (resp.statusCode == 204) {
|
||||||
|
_reactions[symbol] = (_reactions[symbol] ?? 0) - 1;
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
if (context.mounted) context.showSnackbar('postReactUncompleted'.tr());
|
||||||
|
if (widget.onChanged != null) {
|
||||||
|
widget.onChanged!(
|
||||||
|
_reactions,
|
||||||
|
kTemplateReactions[symbol]!.attitude == 1,
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// ignore: use_build_context_synchronously
|
||||||
|
if (context.mounted) context.showErrorDialog(err);
|
||||||
|
} finally {
|
||||||
|
setState(() => _isSubmitting = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_reactions = Map.from(widget.data.metric.reactionList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Symbols.mood, size: 24),
|
||||||
|
const Gap(16),
|
||||||
|
Text('postReactions')
|
||||||
|
.tr()
|
||||||
|
.textStyle(Theme.of(context).textTheme.titleLarge!),
|
||||||
|
],
|
||||||
|
).padding(horizontal: 20, top: 16, bottom: 12),
|
||||||
|
Expanded(
|
||||||
|
child: GridView.count(
|
||||||
|
crossAxisSpacing: 4,
|
||||||
|
mainAxisSpacing: 4,
|
||||||
|
crossAxisCount: 4,
|
||||||
|
children: kTemplateReactions.entries.map((e) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.onChanged == null) return;
|
||||||
|
_reactPost(e.key, e.value.attitude).then((_) {
|
||||||
|
if (context.mounted) Navigator.pop(context);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(e.value.icon).fontSize(40),
|
||||||
|
Text(
|
||||||
|
e.key,
|
||||||
|
style: const TextStyle(fontFamily: 'monospace'),
|
||||||
|
),
|
||||||
|
const Gap(6),
|
||||||
|
Text(
|
||||||
|
'x${_reactions[e.key]?.toString() ?? '0'}',
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user