💄 Enlarge emote when there is only one
This commit is contained in:
parent
6d0145c335
commit
153eabcbf2
@ -297,6 +297,8 @@ class _ChatMessageText extends StatelessWidget {
|
|||||||
child: MarkdownTextContent(
|
child: MarkdownTextContent(
|
||||||
content: data.body['text'],
|
content: data.body['text'],
|
||||||
isAutoWarp: true,
|
isAutoWarp: true,
|
||||||
|
isEnlargeSticker:
|
||||||
|
RegExp(r"^:([-\w]+):$").hasMatch(data.body['text'] ?? ''),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -44,7 +44,9 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
Theme.of(context),
|
Theme.of(context),
|
||||||
).copyWith(
|
).copyWith(
|
||||||
textScaler: textScaler,
|
textScaler: textScaler,
|
||||||
p: textColor != null ? Theme.of(context).textTheme.bodyMedium!.copyWith(color: textColor) : null,
|
p: textColor != null
|
||||||
|
? Theme.of(context).textTheme.bodyMedium!.copyWith(color: textColor)
|
||||||
|
: null,
|
||||||
blockquote: TextStyle(
|
blockquote: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||||
),
|
),
|
||||||
@ -115,7 +117,7 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
final alias = segments[1];
|
final alias = segments[1];
|
||||||
final st = context.read<SnStickerProvider>();
|
final st = context.read<SnStickerProvider>();
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final double size = isEnlargeSticker ? 128 : 32;
|
final double size = isEnlargeSticker ? 96 : 32;
|
||||||
return Container(
|
return Container(
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
@ -131,7 +133,8 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
child: UniversalImage(
|
child: UniversalImage(
|
||||||
sn.getAttachmentUrl(snapshot.data!.attachment.rid),
|
sn.getAttachmentUrl(
|
||||||
|
snapshot.data!.attachment.rid),
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
width: size,
|
width: size,
|
||||||
height: size,
|
height: size,
|
||||||
@ -177,7 +180,9 @@ class MarkdownTextContent extends StatelessWidget {
|
|||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: attachment.metadata['ratio'] ??
|
aspectRatio: attachment.metadata['ratio'] ??
|
||||||
switch (attachment.mimetype.split('/').firstOrNull) {
|
switch (attachment.mimetype
|
||||||
|
.split('/')
|
||||||
|
.firstOrNull) {
|
||||||
'audio' => 16 / 9,
|
'audio' => 16 / 9,
|
||||||
'video' => 16 / 9,
|
'video' => 16 / 9,
|
||||||
_ => 1,
|
_ => 1,
|
||||||
|
@ -92,9 +92,10 @@ class OpenablePostItem extends StatelessWidget {
|
|||||||
openColor: Colors.transparent,
|
openColor: Colors.transparent,
|
||||||
openElevation: 0,
|
openElevation: 0,
|
||||||
transitionType: ContainerTransitionType.fade,
|
transitionType: ContainerTransitionType.fade,
|
||||||
closedColor: Theme.of(context).colorScheme.surfaceContainerLow.withOpacity(
|
closedColor:
|
||||||
cfg.prefs.getBool(kAppBackgroundStoreKey) == true ? 0.75 : 1,
|
Theme.of(context).colorScheme.surfaceContainerLow.withOpacity(
|
||||||
),
|
cfg.prefs.getBool(kAppBackgroundStoreKey) == true ? 0.75 : 1,
|
||||||
|
),
|
||||||
closedShape: const RoundedRectangleBorder(
|
closedShape: const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(16)),
|
borderRadius: BorderRadius.all(Radius.circular(16)),
|
||||||
),
|
),
|
||||||
@ -135,9 +136,11 @@ class PostItem extends StatelessWidget {
|
|||||||
final box = context.findRenderObject() as RenderBox?;
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
final url = 'https://solsynth.dev/posts/${data.id}';
|
final url = 'https://solsynth.dev/posts/${data.id}';
|
||||||
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
if (!kIsWeb && (Platform.isAndroid || Platform.isIOS)) {
|
||||||
Share.shareUri(Uri.parse(url), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
Share.shareUri(Uri.parse(url),
|
||||||
|
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||||
} else {
|
} else {
|
||||||
Share.share(url, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
Share.share(url,
|
||||||
|
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +158,8 @@ class PostItem extends StatelessWidget {
|
|||||||
child: MultiProvider(
|
child: MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
Provider<SnNetworkProvider>(create: (_) => context.read()),
|
||||||
ChangeNotifierProvider<ConfigProvider>(create: (_) => context.read()),
|
ChangeNotifierProvider<ConfigProvider>(
|
||||||
|
create: (_) => context.read()),
|
||||||
],
|
],
|
||||||
child: ResponsiveBreakpoints.builder(
|
child: ResponsiveBreakpoints.builder(
|
||||||
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
breakpoints: ResponsiveBreakpoints.of(context).breakpoints,
|
||||||
@ -183,7 +187,8 @@ class PostItem extends StatelessWidget {
|
|||||||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await FileSaver.instance.saveFile(name: 'Solar Network Post #${data.id}.png', file: imageFile);
|
await FileSaver.instance.saveFile(
|
||||||
|
name: 'Solar Network Post #${data.id}.png', file: imageFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
await imageFile.delete();
|
await imageFile.delete();
|
||||||
@ -197,7 +202,9 @@ class PostItem extends StatelessWidget {
|
|||||||
final isAuthor = ua.isAuthorized && data.publisher.accountId == ua.user?.id;
|
final isAuthor = ua.isAuthorized && data.publisher.accountId == ua.user?.id;
|
||||||
|
|
||||||
// Video full view
|
// Video full view
|
||||||
if (showFullPost && data.type == 'video' && ResponsiveBreakpoints.of(context).largerThan(TABLET)) {
|
if (showFullPost &&
|
||||||
|
data.type == 'video' &&
|
||||||
|
ResponsiveBreakpoints.of(context).largerThan(TABLET)) {
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -217,7 +224,8 @@ class PostItem extends StatelessWidget {
|
|||||||
if (onDeleted != null) {}
|
if (onDeleted != null) {}
|
||||||
},
|
},
|
||||||
).padding(bottom: 8),
|
).padding(bottom: 8),
|
||||||
if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(bottom: 8),
|
if (data.preload?.video != null)
|
||||||
|
_PostVideoPlayer(data: data).padding(bottom: 8),
|
||||||
_PostHeadline(data: data).padding(horizontal: 4, bottom: 8),
|
_PostHeadline(data: data).padding(horizontal: 4, bottom: 8),
|
||||||
_PostFeaturedComment(data: data),
|
_PostFeaturedComment(data: data),
|
||||||
_PostBottomAction(
|
_PostBottomAction(
|
||||||
@ -265,7 +273,8 @@ class PostItem extends StatelessWidget {
|
|||||||
if (onDeleted != null) {}
|
if (onDeleted != null) {}
|
||||||
},
|
},
|
||||||
).padding(horizontal: 12, top: 8, bottom: 8),
|
).padding(horizontal: 12, top: 8, bottom: 8),
|
||||||
if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
if (data.preload?.video != null)
|
||||||
|
_PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
margin: const EdgeInsets.only(bottom: 4, left: 12, right: 12),
|
margin: const EdgeInsets.only(bottom: 4, left: 12, right: 12),
|
||||||
@ -308,8 +317,13 @@ class PostItem extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text('postArticle').tr().fontSize(13).opacity(0.75).padding(horizontal: 24, bottom: 8),
|
Text('postArticle')
|
||||||
_PostFeaturedComment(data: data, maxWidth: maxWidth).padding(horizontal: 12),
|
.tr()
|
||||||
|
.fontSize(13)
|
||||||
|
.opacity(0.75)
|
||||||
|
.padding(horizontal: 24, bottom: 8),
|
||||||
|
_PostFeaturedComment(data: data, maxWidth: maxWidth)
|
||||||
|
.padding(horizontal: 12),
|
||||||
_PostBottomAction(
|
_PostBottomAction(
|
||||||
data: data,
|
data: data,
|
||||||
showComments: showComments,
|
showComments: showComments,
|
||||||
@ -324,7 +338,8 @@ class PostItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final displayableAttachments = data.preload?.attachments
|
final displayableAttachments = data.preload?.attachments
|
||||||
?.where((ele) => ele?.mediaType != SnMediaType.image || data.type != 'article')
|
?.where((ele) =>
|
||||||
|
ele?.mediaType != SnMediaType.image || data.type != 'article')
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final cfg = context.read<ConfigProvider>();
|
final cfg = context.read<ConfigProvider>();
|
||||||
@ -349,9 +364,13 @@ class PostItem extends StatelessWidget {
|
|||||||
if (onDeleted != null) onDeleted!();
|
if (onDeleted != null) onDeleted!();
|
||||||
},
|
},
|
||||||
).padding(horizontal: 12, vertical: 8),
|
).padding(horizontal: 12, vertical: 8),
|
||||||
if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
if (data.preload?.video != null)
|
||||||
if (data.type == 'question') _PostQuestionHint(data: data).padding(horizontal: 16, bottom: 8),
|
_PostVideoPlayer(data: data).padding(horizontal: 12, bottom: 8),
|
||||||
if (data.body['title'] != null || data.body['description'] != null)
|
if (data.type == 'question')
|
||||||
|
_PostQuestionHint(data: data)
|
||||||
|
.padding(horizontal: 16, bottom: 8),
|
||||||
|
if (data.body['title'] != null ||
|
||||||
|
data.body['description'] != null)
|
||||||
_PostHeadline(
|
_PostHeadline(
|
||||||
data: data,
|
data: data,
|
||||||
isEnlarge: data.type == 'article' && showFullPost,
|
isEnlarge: data.type == 'article' && showFullPost,
|
||||||
@ -365,7 +384,8 @@ class PostItem extends StatelessWidget {
|
|||||||
if (data.repostTo != null)
|
if (data.repostTo != null)
|
||||||
_PostQuoteContent(child: data.repostTo!).padding(
|
_PostQuoteContent(child: data.repostTo!).padding(
|
||||||
horizontal: 12,
|
horizontal: 12,
|
||||||
bottom: data.preload?.attachments?.isNotEmpty ?? false ? 12 : 0,
|
bottom:
|
||||||
|
data.preload?.attachments?.isNotEmpty ?? false ? 12 : 0,
|
||||||
),
|
),
|
||||||
if (data.visibility > 0)
|
if (data.visibility > 0)
|
||||||
_PostVisibilityHint(data: data).padding(
|
_PostVisibilityHint(data: data).padding(
|
||||||
@ -377,7 +397,9 @@ class PostItem extends StatelessWidget {
|
|||||||
horizontal: 16,
|
horizontal: 16,
|
||||||
vertical: 4,
|
vertical: 4,
|
||||||
),
|
),
|
||||||
if (data.tags.isNotEmpty) _PostTagsList(data: data).padding(horizontal: 16, top: 4, bottom: 6),
|
if (data.tags.isNotEmpty)
|
||||||
|
_PostTagsList(data: data)
|
||||||
|
.padding(horizontal: 16, top: 4, bottom: 6),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -390,12 +412,16 @@ class PostItem extends StatelessWidget {
|
|||||||
fit: showFullPost ? BoxFit.cover : BoxFit.contain,
|
fit: showFullPost ? BoxFit.cover : BoxFit.contain,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
),
|
),
|
||||||
if (data.preload?.poll != null) PostPoll(poll: data.preload!.poll!).padding(horizontal: 12, vertical: 4),
|
if (data.preload?.poll != null)
|
||||||
if (data.body['content'] != null && (cfg.prefs.getBool(kAppExpandPostLink) ?? true))
|
PostPoll(poll: data.preload!.poll!)
|
||||||
|
.padding(horizontal: 12, vertical: 4),
|
||||||
|
if (data.body['content'] != null &&
|
||||||
|
(cfg.prefs.getBool(kAppExpandPostLink) ?? true))
|
||||||
LinkPreviewWidget(
|
LinkPreviewWidget(
|
||||||
text: data.body['content'],
|
text: data.body['content'],
|
||||||
).padding(horizontal: 4),
|
).padding(horizontal: 4),
|
||||||
_PostFeaturedComment(data: data, maxWidth: maxWidth).padding(horizontal: 12),
|
_PostFeaturedComment(data: data, maxWidth: maxWidth)
|
||||||
|
.padding(horizontal: 12),
|
||||||
Container(
|
Container(
|
||||||
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
|
constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -457,7 +483,8 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
showMenu: false,
|
showMenu: false,
|
||||||
isRelativeDate: false,
|
isRelativeDate: false,
|
||||||
).padding(horizontal: 16, bottom: 8),
|
).padding(horizontal: 16, bottom: 8),
|
||||||
if (data.type == 'question') _PostQuestionHint(data: data).padding(horizontal: 16, bottom: 8),
|
if (data.type == 'question')
|
||||||
|
_PostQuestionHint(data: data).padding(horizontal: 16, bottom: 8),
|
||||||
_PostHeadline(
|
_PostHeadline(
|
||||||
data: data,
|
data: data,
|
||||||
isEnlarge: data.type == 'article',
|
isEnlarge: data.type == 'article',
|
||||||
@ -472,7 +499,8 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
child: data.repostTo!,
|
child: data.repostTo!,
|
||||||
isRelativeDate: false,
|
isRelativeDate: false,
|
||||||
).padding(horizontal: 16, bottom: 8),
|
).padding(horizontal: 16, bottom: 8),
|
||||||
if (data.type != 'article' && (data.preload?.attachments?.isNotEmpty ?? false))
|
if (data.type != 'article' &&
|
||||||
|
(data.preload?.attachments?.isNotEmpty ?? false))
|
||||||
StyledWidget(AttachmentList(
|
StyledWidget(AttachmentList(
|
||||||
data: data.preload!.attachments!,
|
data: data.preload!.attachments!,
|
||||||
columned: true,
|
columned: true,
|
||||||
@ -481,7 +509,8 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (data.visibility > 0) _PostVisibilityHint(data: data),
|
if (data.visibility > 0) _PostVisibilityHint(data: data),
|
||||||
if (data.body['content_truncated'] == true) _PostTruncatedHint(data: data),
|
if (data.body['content_truncated'] == true)
|
||||||
|
_PostTruncatedHint(data: data),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 16),
|
).padding(horizontal: 16),
|
||||||
_PostBottomAction(
|
_PostBottomAction(
|
||||||
@ -541,7 +570,8 @@ class PostShareImageWidget extends StatelessWidget {
|
|||||||
version: QrVersions.auto,
|
version: QrVersions.auto,
|
||||||
size: 100,
|
size: 100,
|
||||||
gapless: true,
|
gapless: true,
|
||||||
embeddedImage: AssetImage('assets/icon/icon-light-radius.png'),
|
embeddedImage:
|
||||||
|
AssetImage('assets/icon/icon-light-radius.png'),
|
||||||
embeddedImageStyle: QrEmbeddedImageStyle(
|
embeddedImageStyle: QrEmbeddedImageStyle(
|
||||||
size: Size(28, 28),
|
size: Size(28, 28),
|
||||||
),
|
),
|
||||||
@ -572,9 +602,11 @@ class _PostQuestionHint extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Icon(data.body['answer'] == null ? Symbols.help : Symbols.check_circle, size: 20),
|
Icon(data.body['answer'] == null ? Symbols.help : Symbols.check_circle,
|
||||||
|
size: 20),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
if (data.body['answer'] == null && data.body['reward']?.toDouble() != null)
|
if (data.body['answer'] == null &&
|
||||||
|
data.body['reward']?.toDouble() != null)
|
||||||
Text('postQuestionUnansweredWithReward'.tr(args: [
|
Text('postQuestionUnansweredWithReward'.tr(args: [
|
||||||
'${data.body['reward']}',
|
'${data.body['reward']}',
|
||||||
])).opacity(0.75)
|
])).opacity(0.75)
|
||||||
@ -610,7 +642,9 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final String? mostTypicalReaction = data.metric.reactionList.isNotEmpty
|
final String? mostTypicalReaction = data.metric.reactionList.isNotEmpty
|
||||||
? data.metric.reactionList.entries.reduce((a, b) => a.value > b.value ? a : b).key
|
? data.metric.reactionList.entries
|
||||||
|
.reduce((a, b) => a.value > b.value ? a : b)
|
||||||
|
.key
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
@ -624,7 +658,8 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
InkWell(
|
InkWell(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
if (mostTypicalReaction == null || kTemplateReactions[mostTypicalReaction] == null)
|
if (mostTypicalReaction == null ||
|
||||||
|
kTemplateReactions[mostTypicalReaction] == null)
|
||||||
Icon(Symbols.add_reaction, size: 20, color: iconColor)
|
Icon(Symbols.add_reaction, size: 20, color: iconColor)
|
||||||
else
|
else
|
||||||
Text(
|
Text(
|
||||||
@ -636,7 +671,8 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Gap(8),
|
const Gap(8),
|
||||||
if (data.totalUpvote > 0 && data.totalUpvote >= data.totalDownvote)
|
if (data.totalUpvote > 0 &&
|
||||||
|
data.totalUpvote >= data.totalDownvote)
|
||||||
Text('postReactionUpvote').plural(
|
Text('postReactionUpvote').plural(
|
||||||
data.totalUpvote,
|
data.totalUpvote,
|
||||||
)
|
)
|
||||||
@ -655,8 +691,12 @@ class _PostBottomAction extends StatelessWidget {
|
|||||||
data: data,
|
data: data,
|
||||||
onChanged: (value, attr, delta) {
|
onChanged: (value, attr, delta) {
|
||||||
onChanged(data.copyWith(
|
onChanged(data.copyWith(
|
||||||
totalUpvote: attr == 1 ? data.totalUpvote + delta : data.totalUpvote,
|
totalUpvote: attr == 1
|
||||||
totalDownvote: attr == 2 ? data.totalDownvote + delta : data.totalDownvote,
|
? data.totalUpvote + delta
|
||||||
|
: data.totalUpvote,
|
||||||
|
totalDownvote: attr == 2
|
||||||
|
? data.totalDownvote + delta
|
||||||
|
: data.totalDownvote,
|
||||||
metric: data.metric.copyWith(reactionList: value),
|
metric: data.metric.copyWith(reactionList: value),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
@ -904,8 +944,10 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text(
|
Text(
|
||||||
isRelativeDate
|
isRelativeDate
|
||||||
? RelativeTime(context).format(data.publishedAt ?? data.createdAt)
|
? RelativeTime(context)
|
||||||
: DateFormat('y/M/d HH:mm').format(data.publishedAt ?? data.createdAt),
|
.format(data.publishedAt ?? data.createdAt)
|
||||||
|
: DateFormat('y/M/d HH:mm')
|
||||||
|
.format(data.publishedAt ?? data.createdAt),
|
||||||
).fontSize(13),
|
).fontSize(13),
|
||||||
],
|
],
|
||||||
).opacity(0.8),
|
).opacity(0.8),
|
||||||
@ -923,8 +965,10 @@ class _PostContentHeader extends StatelessWidget {
|
|||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text(
|
Text(
|
||||||
isRelativeDate
|
isRelativeDate
|
||||||
? RelativeTime(context).format(data.publishedAt ?? data.createdAt)
|
? RelativeTime(context)
|
||||||
: DateFormat('y/M/d HH:mm').format(data.publishedAt ?? data.createdAt),
|
.format(data.publishedAt ?? data.createdAt)
|
||||||
|
: DateFormat('y/M/d HH:mm')
|
||||||
|
.format(data.publishedAt ?? data.createdAt),
|
||||||
).fontSize(13),
|
).fontSize(13),
|
||||||
],
|
],
|
||||||
).opacity(0.8),
|
).opacity(0.8),
|
||||||
@ -1107,7 +1151,8 @@ class _PostContentBody extends StatelessWidget {
|
|||||||
if (data.body['content'] == null) return const SizedBox.shrink();
|
if (data.body['content'] == null) return const SizedBox.shrink();
|
||||||
final content = MarkdownTextContent(
|
final content = MarkdownTextContent(
|
||||||
isAutoWarp: data.type == 'story',
|
isAutoWarp: data.type == 'story',
|
||||||
isEnlargeSticker: true,
|
isEnlargeSticker:
|
||||||
|
RegExp(r"^:([-\w]+):$").hasMatch(data.body['content'] ?? ''),
|
||||||
textScaler: isEnlarge ? TextScaler.linear(1.1) : null,
|
textScaler: isEnlarge ? TextScaler.linear(1.1) : null,
|
||||||
content: data.body['content'],
|
content: data.body['content'],
|
||||||
attachments: data.preload?.attachments,
|
attachments: data.preload?.attachments,
|
||||||
@ -1156,10 +1201,12 @@ class _PostQuoteContent extends StatelessWidget {
|
|||||||
onDeleted: () {},
|
onDeleted: () {},
|
||||||
).padding(bottom: 4),
|
).padding(bottom: 4),
|
||||||
_PostContentBody(data: child),
|
_PostContentBody(data: child),
|
||||||
if (child.visibility > 0) _PostVisibilityHint(data: child).padding(top: 4),
|
if (child.visibility > 0)
|
||||||
|
_PostVisibilityHint(data: child).padding(top: 4),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 16),
|
).padding(horizontal: 16),
|
||||||
if (child.type != 'article' && (child.preload?.attachments?.isNotEmpty ?? false))
|
if (child.type != 'article' &&
|
||||||
|
(child.preload?.attachments?.isNotEmpty ?? false))
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(
|
||||||
bottomLeft: Radius.circular(8),
|
bottomLeft: Radius.circular(8),
|
||||||
@ -1310,7 +1357,9 @@ class _PostTruncatedHint extends StatelessWidget {
|
|||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text('postReadEstimate').tr(args: [
|
Text('postReadEstimate').tr(args: [
|
||||||
'${Duration(
|
'${Duration(
|
||||||
seconds: (data.body['content_length'] as num).toDouble() * 60 ~/ kHumanReadSpeed,
|
seconds: (data.body['content_length'] as num).toDouble() *
|
||||||
|
60 ~/
|
||||||
|
kHumanReadSpeed,
|
||||||
).inSeconds}s',
|
).inSeconds}s',
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
@ -1349,7 +1398,8 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
|||||||
// If this is a answered question, fetch the answer instead
|
// If this is a answered question, fetch the answer instead
|
||||||
if (widget.data.type == 'question' && widget.data.body['answer'] != null) {
|
if (widget.data.type == 'question' && widget.data.body['answer'] != null) {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final resp = await sn.client.get('/cgi/co/posts/${widget.data.body['answer']}');
|
final resp =
|
||||||
|
await sn.client.get('/cgi/co/posts/${widget.data.body['answer']}');
|
||||||
_isAnswer = true;
|
_isAnswer = true;
|
||||||
setState(() => _featuredComment = SnPost.fromJson(resp.data));
|
setState(() => _featuredComment = SnPost.fromJson(resp.data));
|
||||||
return;
|
return;
|
||||||
@ -1357,9 +1407,11 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final sn = context.read<SnNetworkProvider>();
|
final sn = context.read<SnNetworkProvider>();
|
||||||
final resp = await sn.client.get('/cgi/co/posts/${widget.data.id}/replies/featured', queryParameters: {
|
final resp = await sn.client.get(
|
||||||
'take': 1,
|
'/cgi/co/posts/${widget.data.id}/replies/featured',
|
||||||
});
|
queryParameters: {
|
||||||
|
'take': 1,
|
||||||
|
});
|
||||||
setState(() => _featuredComment = SnPost.fromJson(resp.data[0]));
|
setState(() => _featuredComment = SnPost.fromJson(resp.data[0]));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
@ -1388,7 +1440,9 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Material(
|
child: Material(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
color: _isAnswer ? Colors.green.withOpacity(0.5) : Theme.of(context).colorScheme.surfaceContainerHigh,
|
color: _isAnswer
|
||||||
|
? Colors.green.withOpacity(0.5)
|
||||||
|
: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@ -1408,11 +1462,17 @@ class _PostFeaturedCommentState extends State<_PostFeaturedComment> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Gap(2),
|
const Gap(2),
|
||||||
Icon(_isAnswer ? Symbols.task_alt : Symbols.prompt_suggestion, size: 20),
|
Icon(_isAnswer ? Symbols.task_alt : Symbols.prompt_suggestion,
|
||||||
|
size: 20),
|
||||||
const Gap(10),
|
const Gap(10),
|
||||||
Text(
|
Text(
|
||||||
_isAnswer ? 'postQuestionAnswerTitle' : 'postFeaturedComment',
|
_isAnswer
|
||||||
style: Theme.of(context).textTheme.titleMedium!.copyWith(fontSize: 15),
|
? 'postQuestionAnswerTitle'
|
||||||
|
: 'postFeaturedComment',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.titleMedium!
|
||||||
|
.copyWith(fontSize: 15),
|
||||||
).tr(),
|
).tr(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -1550,7 +1610,8 @@ class _PostGetInsightPopupState extends State<_PostGetInsightPopup> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RegExp cleanThinkingRegExp = RegExp(r'<think>[\s\S]*?</think>');
|
RegExp cleanThinkingRegExp = RegExp(r'<think>[\s\S]*?</think>');
|
||||||
setState(() => _response = out.replaceAll(cleanThinkingRegExp, '').trim());
|
setState(
|
||||||
|
() => _response = out.replaceAll(cleanThinkingRegExp, '').trim());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
context.showErrorDialog(err);
|
context.showErrorDialog(err);
|
||||||
@ -1573,11 +1634,16 @@ class _PostGetInsightPopupState extends State<_PostGetInsightPopup> {
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.book_4_spark, size: 24),
|
const Icon(Symbols.book_4_spark, size: 24),
|
||||||
const Gap(16),
|
const Gap(16),
|
||||||
Text('postGetInsightTitle', style: Theme.of(context).textTheme.titleLarge).tr(),
|
Text('postGetInsightTitle',
|
||||||
|
style: Theme.of(context).textTheme.titleLarge)
|
||||||
|
.tr(),
|
||||||
],
|
],
|
||||||
).padding(horizontal: 20, top: 16, bottom: 12),
|
).padding(horizontal: 20, top: 16, bottom: 12),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
Text('postGetInsightDescription', style: Theme.of(context).textTheme.bodySmall).tr().padding(horizontal: 20),
|
Text('postGetInsightDescription',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall)
|
||||||
|
.tr()
|
||||||
|
.padding(horizontal: 20),
|
||||||
const Gap(4),
|
const Gap(4),
|
||||||
if (_response == null)
|
if (_response == null)
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -1595,12 +1661,16 @@ class _PostGetInsightPopupState extends State<_PostGetInsightPopup> {
|
|||||||
leading: const Icon(Symbols.info),
|
leading: const Icon(Symbols.info),
|
||||||
title: Text('aiThinkingProcess'.tr()),
|
title: Text('aiThinkingProcess'.tr()),
|
||||||
tilePadding: const EdgeInsets.symmetric(horizontal: 20),
|
tilePadding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
collapsedBackgroundColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
collapsedBackgroundColor:
|
||||||
|
Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||||
minTileHeight: 32,
|
minTileHeight: 32,
|
||||||
children: [
|
children: [
|
||||||
SelectableText(
|
SelectableText(
|
||||||
_thinkingProcess!,
|
_thinkingProcess!,
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontStyle: FontStyle.italic),
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyMedium!
|
||||||
|
.copyWith(fontStyle: FontStyle.italic),
|
||||||
).padding(horizontal: 20, vertical: 8),
|
).padding(horizontal: 20, vertical: 8),
|
||||||
],
|
],
|
||||||
).padding(vertical: 8),
|
).padding(vertical: 8),
|
||||||
@ -1637,7 +1707,8 @@ class _PostVideoPlayer extends StatelessWidget {
|
|||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
child: AttachmentItem(data: data.preload!.video!, heroTag: 'post-video-${data.id}'),
|
child: AttachmentItem(
|
||||||
|
data: data.preload!.video!, heroTag: 'post-video-${data.id}'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user