diff --git a/lib/pages/full_post/full_post.dart b/lib/pages/full_post/full_post.dart index 3fa19f6..ce8247f 100644 --- a/lib/pages/full_post/full_post.dart +++ b/lib/pages/full_post/full_post.dart @@ -58,19 +58,15 @@ class FullPostPage extends StatelessWidget { ); } - static Jwt? _tryGetJwt(BuildContext context) { - final store = context.read(); - return context - .read() - .defaultUserDataFor(store.instanceHost) - ?.jwt; + static Jwt? _tryGetJwt(BuildContext context, String instanceHost) { + return context.read().defaultUserDataFor(instanceHost)?.jwt; } static Route route(int id, String instanceHost) => MaterialPageRoute( builder: (context) => Provider( create: (context) => FullPostStore(instanceHost: instanceHost, postId: id) - ..refresh(_tryGetJwt(context)), + ..refresh(_tryGetJwt(context, instanceHost)), child: FullPostPage( id: id, instanceHost: instanceHost, @@ -81,14 +77,14 @@ class FullPostPage extends StatelessWidget { static Route fromPostViewRoute(PostView postView) => MaterialPageRoute( builder: (context) => Provider( create: (context) => FullPostStore.fromPostView(postView) - ..refresh(_tryGetJwt(context)), + ..refresh(_tryGetJwt(context, postView.instanceHost)), child: FullPostPage.fromPostView(postView), ), ); static Route fromPostStoreRoute(PostStore postStore) => MaterialPageRoute( builder: (context) => Provider( create: (context) => FullPostStore.fromPostStore(postStore) - ..refresh(_tryGetJwt(context)), + ..refresh(_tryGetJwt(context, postStore.postView.instanceHost)), child: FullPostPage.fromPostStore(postStore)), ); } diff --git a/lib/widgets/post/post_body.dart b/lib/widgets/post/post_body.dart index 535ebbc..c30174e 100644 --- a/lib/widgets/post/post_body.dart +++ b/lib/widgets/post/post_body.dart @@ -16,13 +16,14 @@ class PostBody extends StatelessWidget { final fullPost = context.read(); return ObserverBuilder(builder: (context, store) { - if (store.postView.post.body == null) return const SizedBox(); + final body = store.postView.post.body; + if (body == null) return const SizedBox(); if (fullPost) { return Padding( padding: const EdgeInsets.all(10), child: MarkdownText( - store.postView.post.body!, + body, instanceHost: store.postView.instanceHost, selectable: true, ), @@ -31,7 +32,7 @@ class PostBody extends StatelessWidget { return LayoutBuilder( builder: (context, constraints) { final span = TextSpan( - text: store.postView.post.body, + text: body, ); final tp = TextPainter( text: span, @@ -50,9 +51,10 @@ class PostBody extends StatelessWidget { alignment: Alignment.topCenter, heightFactor: 0.8, child: Padding( - padding: const EdgeInsets.all(10), - child: MarkdownText(store.postView.post.body!, - instanceHost: store.postView.instanceHost)), + padding: const EdgeInsets.all(10), + child: MarkdownText(body, + instanceHost: store.postView.instanceHost), + ), ), ), Container( @@ -74,7 +76,7 @@ class PostBody extends StatelessWidget { } else { return Padding( padding: const EdgeInsets.all(10), - child: MarkdownText(store.postView.post.body!, + child: MarkdownText(body, instanceHost: store.postView.instanceHost)); } }, diff --git a/lib/widgets/post/post_info_section.dart b/lib/widgets/post/post_info_section.dart index eb852ef..eb6f508 100644 --- a/lib/widgets/post/post_info_section.dart +++ b/lib/widgets/post/post_info_section.dart @@ -1,7 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:provider/provider.dart'; import '../../l10n/l10n.dart'; @@ -14,7 +13,7 @@ import 'post_more_menu.dart'; import 'post_status.dart'; import 'post_store.dart'; -class PostInfoSection extends HookWidget { +class PostInfoSection extends StatelessWidget { const PostInfoSection(); @override @@ -31,111 +30,91 @@ class PostInfoSection extends HookWidget { padding: const EdgeInsets.all(10), child: Row( children: [ - Column( - mainAxisSize: MainAxisSize.min, - children: [ - if (post.community.icon != null) - Padding( - padding: const EdgeInsets.only(right: 10), - child: InkWell( - borderRadius: BorderRadius.circular(20), - onTap: () => goToCommunity.byId( - context, instanceHost, post.community.id), - child: Avatar( - url: post.community.icon, - noBlank: true, - radius: 20, - ), - ), + if (post.community.icon != null) + Padding( + padding: const EdgeInsets.only(right: 10), + child: InkWell( + borderRadius: BorderRadius.circular(20), + onTap: () => goToCommunity.byId( + context, instanceHost, post.community.id), + child: Avatar( + url: post.community.icon, + noBlank: true, + radius: 20, ), - ], - ), + ), + ), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - RichText( - overflow: - TextOverflow.ellipsis, // TODO: fix overflowing - text: TextSpan( - style: TextStyle( - fontSize: 15, - color: theme.textTheme.bodyText1?.color), - children: [ - const TextSpan( - text: '!', - style: - TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: post.community.name, - style: const TextStyle( - fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToCommunity.byId(context, - instanceHost, post.community.id)), - const TextSpan( - text: '@', - style: - TextStyle(fontWeight: FontWeight.w300)), - TextSpan( - text: post.post.originInstanceHost, - style: const TextStyle( - fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToInstance( - context, post.post.originInstanceHost)), - ], - ), - ) - ], + RichText( + overflow: TextOverflow.ellipsis, // TODO: fix overflowing + text: TextSpan( + style: TextStyle( + fontSize: 15, + color: theme.textTheme.bodyText1?.color), + children: [ + const TextSpan( + text: '!', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: post.community.name, + style: + const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToCommunity.byId( + context, instanceHost, post.community.id)), + const TextSpan( + text: '@', + style: TextStyle(fontWeight: FontWeight.w300)), + TextSpan( + text: post.post.originInstanceHost, + style: + const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToInstance( + context, post.post.originInstanceHost)), + ], + ), ), - Row( - children: [ - RichText( - overflow: TextOverflow.ellipsis, - text: TextSpan( - style: TextStyle( - fontSize: 13, - color: theme.textTheme.bodyText1?.color), - children: [ - TextSpan( - text: L10n.of(context)!.by, - style: const TextStyle( - fontWeight: FontWeight.w300), - ), - TextSpan( - text: ' ${post.creator.originPreferredName}', - style: const TextStyle( - fontWeight: FontWeight.w600), - recognizer: TapGestureRecognizer() - ..onTap = () => goToUser.fromPersonSafe( - context, - post.creator, - ), - ), - TextSpan( - text: ' 路 ${post.post.published.fancyShort}'), - if (post.post.locked) - const TextSpan(text: ' 路 馃敀'), - if (post.post.stickied) - const TextSpan(text: ' 路 馃搶'), - if (post.post.nsfw) const TextSpan(text: ' 路 '), - if (post.post.nsfw) - TextSpan( - text: L10n.of(context)!.nsfw, - style: const TextStyle(color: Colors.red)), - if (store.urlDomain != null) - TextSpan(text: ' 路 ${store.urlDomain}'), - if (post.post.removed) - const TextSpan(text: ' 路 REMOVED'), - if (post.post.deleted) - const TextSpan(text: ' 路 DELETED'), - ], + RichText( + overflow: TextOverflow.ellipsis, + text: TextSpan( + style: TextStyle( + fontSize: 13, + color: theme.textTheme.bodyText1?.color), + children: [ + TextSpan( + text: L10n.of(context)!.by, + style: const TextStyle(fontWeight: FontWeight.w300), ), - ) - ], - ), + TextSpan( + text: ' ${post.creator.originPreferredName}', + style: const TextStyle(fontWeight: FontWeight.w600), + recognizer: TapGestureRecognizer() + ..onTap = () => goToUser.fromPersonSafe( + context, + post.creator, + ), + ), + TextSpan( + text: ' 路 ${post.post.published.fancyShort}'), + if (post.post.locked) const TextSpan(text: ' 路 馃敀'), + if (post.post.stickied) const TextSpan(text: ' 路 馃搶'), + if (post.post.nsfw) const TextSpan(text: ' 路 '), + if (post.post.nsfw) + TextSpan( + text: L10n.of(context)!.nsfw, + style: const TextStyle(color: Colors.red)), + if (store.urlDomain != null) + TextSpan(text: ' 路 ${store.urlDomain}'), + if (post.post.removed) + const TextSpan(text: ' 路 REMOVED'), + if (post.post.deleted) + const TextSpan(text: ' 路 DELETED'), + ], + ), + ) ], ), const Spacer(), diff --git a/lib/widgets/post/post_link_preview.dart b/lib/widgets/post/post_link_preview.dart index 0134bab..2d2e22a 100644 --- a/lib/widgets/post/post_link_preview.dart +++ b/lib/widgets/post/post_link_preview.dart @@ -11,9 +11,9 @@ class PostLinkPreview extends StatelessWidget { Widget build(BuildContext context) { return ObserverBuilder( builder: (context, store) { - if (store.hasMedia || - store.postView.post.url == null || - store.postView.post.url!.isEmpty) { + final url = store.postView.post.url; + + if (store.hasMedia || url == null || url.isEmpty) { return const SizedBox(); } @@ -24,7 +24,7 @@ class PostLinkPreview extends StatelessWidget { child: InkWell( onTap: () => linkLauncher( context: context, - url: store.postView.post.url!, + url: url, instanceHost: store.postView.instanceHost, ), child: Container( @@ -58,8 +58,8 @@ class PostLinkPreview extends StatelessWidget { ) ], ), - if (store.postView.post.embedDescription != null && - store.postView.post.embedDescription!.isNotEmpty) + if (store.postView.post.embedDescription?.isNotEmpty ?? + false) Row( children: [ Flexible( diff --git a/lib/widgets/post/post_media.dart b/lib/widgets/post/post_media.dart index aabb2d5..2fb1e76 100644 --- a/lib/widgets/post/post_media.dart +++ b/lib/widgets/post/post_media.dart @@ -11,19 +11,23 @@ class PostMedia extends StatelessWidget { @override Widget build(BuildContext context) { - return ObserverBuilder(builder: (context, store) { - final post = store.postView.post; - if (!store.hasMedia) return const SizedBox(); + return ObserverBuilder( + builder: (context, store) { + final post = store.postView.post; + if (!store.hasMedia) return const SizedBox(); - return FullscreenableImage( - url: post.url!, - child: CachedNetworkImage( - imageUrl: post.url!, - errorWidget: (_, __, ___) => const Icon(Icons.warning), - progressIndicatorBuilder: (context, url, progress) => - CircularProgressIndicator(value: progress.progress), - ), - ); - }); + final url = post.url!; // hasMedia returns false if url is null + + return FullscreenableImage( + url: url, + child: CachedNetworkImage( + imageUrl: url, + errorWidget: (_, __, ___) => const Icon(Icons.warning), + progressIndicatorBuilder: (context, url, progress) => + CircularProgressIndicator.adaptive(value: progress.progress), + ), + ); + }, + ); } } diff --git a/lib/widgets/post/post_more_menu.dart b/lib/widgets/post/post_more_menu.dart index e19c836..a7a1d61 100644 --- a/lib/widgets/post/post_more_menu.dart +++ b/lib/widgets/post/post_more_menu.dart @@ -32,19 +32,15 @@ class PostMoreMenuButton extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( - children: [ - IconButton( - onPressed: () => show( - context: context, - postStore: context.read(), - fullPostStore: null, - ), - icon: Icon(moreIcon), - padding: EdgeInsets.zero, - visualDensity: VisualDensity.compact, - ) - ], + return IconButton( + onPressed: () => show( + context: context, + postStore: context.read(), + fullPostStore: null, + ), + icon: Icon(moreIcon), + padding: EdgeInsets.zero, + visualDensity: VisualDensity.compact, ); } } @@ -108,7 +104,7 @@ class PostMoreMenu extends HookWidget { loggedInAction(store.blockUser)(); }, ), - if (fullPostStore != null && fullPostStore!.fullPostView != null) + if (fullPostStore?.fullPostView != null) ObserverBuilder( store: fullPostStore, builder: (context, store) { diff --git a/lib/widgets/post/post_title.dart b/lib/widgets/post/post_title.dart index 58f70ca..a298061 100644 --- a/lib/widgets/post/post_title.dart +++ b/lib/widgets/post/post_title.dart @@ -13,9 +13,11 @@ class PostTitle extends StatelessWidget { return ObserverBuilder( builder: (context, store) { final post = store.postView.post; + final thumbnailUrl = post.thumbnailUrl; + final url = post.url; return Padding( - padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10), + padding: const EdgeInsets.all(10).copyWith(top: 0), child: Row( children: [ Expanded( @@ -28,20 +30,20 @@ class PostTitle extends StatelessWidget { fontSize: 18, fontWeight: FontWeight.w600), ), ), - if (!store.hasMedia && post.thumbnailUrl != null) ...[ + if (!store.hasMedia && thumbnailUrl != null && url != null) ...[ const Spacer(), InkWell( borderRadius: BorderRadius.circular(20), onTap: () => linkLauncher( context: context, - url: post.url!, + url: url, instanceHost: store.postView.instanceHost), child: Stack( children: [ ClipRRect( borderRadius: BorderRadius.circular(20), child: CachedNetworkImage( - imageUrl: post.thumbnailUrl!, + imageUrl: thumbnailUrl, width: 70, height: 70, fit: BoxFit.cover, diff --git a/lib/widgets/post/post_voting.dart b/lib/widgets/post/post_voting.dart index 719cf5e..46a3746 100644 --- a/lib/widgets/post/post_voting.dart +++ b/lib/widgets/post/post_voting.dart @@ -34,10 +34,12 @@ class PostVoting extends HookWidget { ), if (store.votingState.isLoading) const SizedBox( - width: 20, height: 20, child: CircularProgressIndicator()) + width: 20, + height: 20, + child: CircularProgressIndicator.adaptive(), + ) else if (showScores) - Text(compactNumber(store.postView.counts.score + - (store.postView.myVote?.value ?? 0))), + Text(compactNumber(store.postView.counts.score)), IconButton( icon: Icon( Icons.arrow_downward, diff --git a/lib/widgets/post/save_post_button.dart b/lib/widgets/post/save_post_button.dart index f2e0159..d99fca1 100644 --- a/lib/widgets/post/save_post_button.dart +++ b/lib/widgets/post/save_post_button.dart @@ -6,8 +6,6 @@ import '../../hooks/logged_in_action.dart'; import '../../util/observer_consumers.dart'; import 'post_store.dart'; -// TODO: sync this button between post and fullpost. the same with voting - class SavePostButton extends HookWidget { const SavePostButton();