💄 Optimized reaction sheet
This commit is contained in:
@@ -710,5 +710,16 @@
|
|||||||
"fileIdHint": "The file ID is the ID you get after upload the file via the Solar Network Drive.",
|
"fileIdHint": "The file ID is the ID you get after upload the file via the Solar Network Drive.",
|
||||||
"translate": "Translate",
|
"translate": "Translate",
|
||||||
"translating": "Translating",
|
"translating": "Translating",
|
||||||
"translated": "Translated"
|
"translated": "Translated",
|
||||||
|
"reactionThumbUp": "Thumbs Up",
|
||||||
|
"reactionThumbDown": "Thumbs Down",
|
||||||
|
"reactionJustOkay": "Just Okay",
|
||||||
|
"reactionCry": "Cry",
|
||||||
|
"reactionConfuse": "Confused",
|
||||||
|
"reactionClap": "Clap",
|
||||||
|
"reactionLaugh": "Laugh",
|
||||||
|
"reactionAngry": "Angry",
|
||||||
|
"reactionParty": "Party",
|
||||||
|
"reactionPray": "Pray",
|
||||||
|
"reactionHeart": "Heart"
|
||||||
}
|
}
|
@@ -78,6 +78,13 @@ sealed class SnSubscriptionStatus with _$SnSubscriptionStatus {
|
|||||||
sealed class ReactInfo with _$ReactInfo {
|
sealed class ReactInfo with _$ReactInfo {
|
||||||
const factory ReactInfo({required String icon, required int attitude}) =
|
const factory ReactInfo({required String icon, required int attitude}) =
|
||||||
_ReactInfo;
|
_ReactInfo;
|
||||||
|
|
||||||
|
static String getTranslationKey(String templateKey) {
|
||||||
|
final parts = templateKey.split('_');
|
||||||
|
final camelCase =
|
||||||
|
parts.map((p) => p[0].toUpperCase() + p.substring(1)).join();
|
||||||
|
return 'reaction$camelCase';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Map<String, ReactInfo> kReactionTemplates = {
|
const Map<String, ReactInfo> kReactionTemplates = {
|
||||||
|
@@ -383,6 +383,7 @@ class PostItem extends HookConsumerWidget {
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return _PostReactionSheet(
|
return _PostReactionSheet(
|
||||||
reactionsCount: item.reactionsCount,
|
reactionsCount: item.reactionsCount,
|
||||||
|
reactionsMade: item.reactionsMade,
|
||||||
onReact: (symbol, attitude) {
|
onReact: (symbol, attitude) {
|
||||||
reactPost(symbol, attitude);
|
reactPost(symbol, attitude);
|
||||||
},
|
},
|
||||||
@@ -701,12 +702,14 @@ Widget _buildReferencePost(
|
|||||||
class PostReactionList extends HookConsumerWidget {
|
class PostReactionList extends HookConsumerWidget {
|
||||||
final String parentId;
|
final String parentId;
|
||||||
final Map<String, int> reactions;
|
final Map<String, int> reactions;
|
||||||
|
final Map<String, bool> reactionsMade;
|
||||||
final Function(String symbol, int attitude, int delta)? onReact;
|
final Function(String symbol, int attitude, int delta)? onReact;
|
||||||
final EdgeInsets? padding;
|
final EdgeInsets? padding;
|
||||||
const PostReactionList({
|
const PostReactionList({
|
||||||
super.key,
|
super.key,
|
||||||
required this.parentId,
|
required this.parentId,
|
||||||
required this.reactions,
|
required this.reactions,
|
||||||
|
required this.reactionsMade,
|
||||||
this.padding,
|
this.padding,
|
||||||
this.onReact,
|
this.onReact,
|
||||||
});
|
});
|
||||||
@@ -760,6 +763,7 @@ class PostReactionList extends HookConsumerWidget {
|
|||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return _PostReactionSheet(
|
return _PostReactionSheet(
|
||||||
reactionsCount: reactions,
|
reactionsCount: reactions,
|
||||||
|
reactionsMade: reactionsMade,
|
||||||
onReact: (symbol, attitude) {
|
onReact: (symbol, attitude) {
|
||||||
reactPost(symbol, attitude);
|
reactPost(symbol, attitude);
|
||||||
},
|
},
|
||||||
@@ -804,9 +808,11 @@ class PostReactionList extends HookConsumerWidget {
|
|||||||
|
|
||||||
class _PostReactionSheet extends StatelessWidget {
|
class _PostReactionSheet extends StatelessWidget {
|
||||||
final Map<String, int> reactionsCount;
|
final Map<String, int> reactionsCount;
|
||||||
|
final Map<String, bool> reactionsMade;
|
||||||
final Function(String symbol, int attitude) onReact;
|
final Function(String symbol, int attitude) onReact;
|
||||||
const _PostReactionSheet({
|
const _PostReactionSheet({
|
||||||
required this.reactionsCount,
|
required this.reactionsCount,
|
||||||
|
required this.reactionsMade,
|
||||||
required this.onReact,
|
required this.onReact,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -843,9 +849,24 @@ class _PostReactionSheet extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
_buildReactionSection(context, 'Positive Reactions', 0),
|
_buildReactionSection(
|
||||||
_buildReactionSection(context, 'Neutral Reactions', 1),
|
context,
|
||||||
_buildReactionSection(context, 'Negative Reactions', 2),
|
Symbols.mood,
|
||||||
|
'reactionPositive'.tr(),
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
_buildReactionSection(
|
||||||
|
context,
|
||||||
|
Symbols.sentiment_neutral,
|
||||||
|
'reactionNeutral'.tr(),
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
_buildReactionSection(
|
||||||
|
context,
|
||||||
|
Symbols.mood_bad,
|
||||||
|
'reactionNegative'.tr(),
|
||||||
|
2,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -855,6 +876,7 @@ class _PostReactionSheet extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildReactionSection(
|
Widget _buildReactionSection(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
|
IconData icon,
|
||||||
String title,
|
String title,
|
||||||
int attitude,
|
int attitude,
|
||||||
) {
|
) {
|
||||||
@@ -867,38 +889,58 @@ class _PostReactionSheet extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(title).fontSize(20).bold().padding(horizontal: 20, vertical: 12),
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
spacing: 8,
|
||||||
|
children: [Icon(icon), Text(title).fontSize(17).bold()],
|
||||||
|
).padding(horizontal: 24, top: 16, bottom: 6),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 84,
|
height: 120,
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 1,
|
crossAxisCount: 1,
|
||||||
mainAxisExtent: 100,
|
mainAxisExtent: 120,
|
||||||
mainAxisSpacing: 8.0,
|
mainAxisSpacing: 8.0,
|
||||||
crossAxisSpacing: 8.0,
|
crossAxisSpacing: 8.0,
|
||||||
childAspectRatio: 2.0,
|
childAspectRatio: 1.0,
|
||||||
),
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||||
itemCount: allReactions.length,
|
itemCount: allReactions.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final symbol = allReactions[index];
|
final symbol = allReactions[index];
|
||||||
final count = reactionsCount[symbol] ?? 0;
|
final count = reactionsCount[symbol] ?? 0;
|
||||||
return InkWell(
|
return Card(
|
||||||
onTap: () {
|
margin: EdgeInsets.symmetric(vertical: 4),
|
||||||
onReact(symbol, attitude);
|
color:
|
||||||
Navigator.pop(context);
|
(reactionsMade[symbol] ?? false)
|
||||||
},
|
? Theme.of(context).colorScheme.primaryContainer
|
||||||
child: GridTile(
|
: Theme.of(context).colorScheme.surfaceContainerLowest,
|
||||||
header: Text(
|
child: InkWell(
|
||||||
kReactionTemplates[symbol]?.icon ?? '',
|
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||||
textAlign: TextAlign.center,
|
onTap: () {
|
||||||
).fontSize(24),
|
onReact(symbol, attitude);
|
||||||
footer: Text(
|
Navigator.pop(context);
|
||||||
count > 0 ? 'x$count' : '',
|
},
|
||||||
textAlign: TextAlign.center,
|
child: Column(
|
||||||
).bold().padding(bottom: 12),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
child: Center(
|
children: [
|
||||||
child: Text(symbol, textAlign: TextAlign.center),
|
Text(
|
||||||
|
kReactionTemplates[symbol]?.icon ?? '',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).fontSize(24),
|
||||||
|
Text(
|
||||||
|
ReactInfo.getTranslationKey(symbol),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).tr(),
|
||||||
|
if (count > 0)
|
||||||
|
Text(
|
||||||
|
'x$count',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
).bold().padding(bottom: 4)
|
||||||
|
else
|
||||||
|
const Gap(20),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@@ -370,6 +370,7 @@ class PostItemCreator extends HookConsumerWidget {
|
|||||||
PostReactionList(
|
PostReactionList(
|
||||||
parentId: item.id,
|
parentId: item.id,
|
||||||
reactions: item.reactionsCount,
|
reactions: item.reactionsCount,
|
||||||
|
reactionsMade: item.reactionsMade,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
const Gap(16),
|
const Gap(16),
|
||||||
|
Reference in New Issue
Block a user