From 5fa9e22cd518aba90ab65c6f49742ec9bb82bcd0 Mon Sep 17 00:00:00 2001 From: krawieck Date: Thu, 10 Sep 2020 23:03:50 +0200 Subject: [PATCH 01/22] Add media view widget --- lib/widgets/media_view.dart | 50 +++++++++++++++++++++++++++++++++++++ pubspec.lock | 7 ++++++ pubspec.yaml | 2 +- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 lib/widgets/media_view.dart diff --git a/lib/widgets/media_view.dart b/lib/widgets/media_view.dart new file mode 100644 index 0000000..ae40dda --- /dev/null +++ b/lib/widgets/media_view.dart @@ -0,0 +1,50 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:photo_view/photo_view.dart'; + +class MediaView extends HookWidget { + final String url; + + const MediaView(this.url); + + @override + Widget build(BuildContext context) { + var showButtons = useState(true); + + return Scaffold( + appBar: AppBar( + backgroundColor: + showButtons.value ? Colors.black38 : Colors.transparent, + shadowColor: Colors.transparent, + leading: showButtons.value ? CloseButton() : Container(), + actions: showButtons.value + ? [ + IconButton( + icon: Icon(Icons.share), + tooltip: 'share', + onPressed: () {}, + ), + IconButton( + icon: Icon(Icons.file_download), + tooltip: 'download', + onPressed: () {}, + ), + ] + : null, + ), + extendBodyBehindAppBar: true, + body: GestureDetector( + onTapUp: (details) => showButtons.value = !showButtons.value, + child: PhotoView( + minScale: PhotoViewComputedScale.contained, + initialScale: PhotoViewComputedScale.contained, + imageProvider: CachedNetworkImageProvider(url), + heroAttributes: PhotoViewHeroAttributes(tag: url), + loadingBuilder: (context, event) => + Center(child: CircularProgressIndicator()), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 1b60dcf..ca46e23 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -471,6 +471,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.9.0" + photo_view: + dependency: "direct main" + description: + name: photo_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.2" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e22a9d3..f511dea 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ environment: sdk: '>=2.7.0 <3.0.0' dependencies: + photo_view: ^0.10.2 url_launcher: ^5.5.1 markdown: ^2.1.8 flutter_markdown: ^0.4.3 @@ -51,7 +52,6 @@ dev_dependencies: mobx_codegen: ^1.1.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec - # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is From 13b1a7ad8bd3bf0b70e65a9b2b878414318b2408 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 10:54:03 +0200 Subject: [PATCH 02/22] Enter fullscreen when hiding buttons --- lib/widgets/media_view.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/widgets/media_view.dart b/lib/widgets/media_view.dart index ae40dda..de94d23 100644 --- a/lib/widgets/media_view.dart +++ b/lib/widgets/media_view.dart @@ -1,5 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:photo_view/photo_view.dart'; @@ -12,6 +13,20 @@ class MediaView extends HookWidget { Widget build(BuildContext context) { var showButtons = useState(true); + useEffect(() => () => SystemChrome.setEnabledSystemUIOverlays([ + SystemUiOverlay.bottom, + SystemUiOverlay.top, + ])); + + if (showButtons.value) { + SystemChrome.setEnabledSystemUIOverlays([ + SystemUiOverlay.bottom, + SystemUiOverlay.top, + ]); + } else { + SystemChrome.setEnabledSystemUIOverlays([]); + } + return Scaffold( appBar: AppBar( backgroundColor: From a8607fd6615debdb456816f54112ced14ce294e3 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 11:00:04 +0200 Subject: [PATCH 03/22] Simplify hiding the appbar --- lib/widgets/media_view.dart | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/widgets/media_view.dart b/lib/widgets/media_view.dart index de94d23..da7de94 100644 --- a/lib/widgets/media_view.dart +++ b/lib/widgets/media_view.dart @@ -28,13 +28,12 @@ class MediaView extends HookWidget { } return Scaffold( - appBar: AppBar( - backgroundColor: - showButtons.value ? Colors.black38 : Colors.transparent, - shadowColor: Colors.transparent, - leading: showButtons.value ? CloseButton() : Container(), - actions: showButtons.value - ? [ + appBar: showButtons.value + ? AppBar( + backgroundColor: Colors.black38, + shadowColor: Colors.transparent, + leading: CloseButton(), + actions: [ IconButton( icon: Icon(Icons.share), tooltip: 'share', @@ -45,9 +44,9 @@ class MediaView extends HookWidget { tooltip: 'download', onPressed: () {}, ), - ] - : null, - ), + ], + ) + : null, extendBodyBehindAppBar: true, body: GestureDetector( onTapUp: (details) => showButtons.value = !showButtons.value, From c7baa125c4e464e05de6cd0912cba393312905ac Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 11:24:06 +0200 Subject: [PATCH 04/22] add basic functionality to share button add bottom sheet that opens when clicking the share button. 2 options are present. share url and share file share url works share file not yet --- lib/widgets/media_view.dart | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/widgets/media_view.dart b/lib/widgets/media_view.dart index da7de94..96d91c2 100644 --- a/lib/widgets/media_view.dart +++ b/lib/widgets/media_view.dart @@ -1,9 +1,12 @@ import 'package:cached_network_image/cached_network_image.dart'; +import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:photo_view/photo_view.dart'; +import 'bottom_modal.dart'; + class MediaView extends HookWidget { final String url; @@ -27,6 +30,35 @@ class MediaView extends HookWidget { SystemChrome.setEnabledSystemUIOverlays([]); } + share() { + showModalBottomSheet( + backgroundColor: Colors.transparent, + context: context, + builder: (context) => BottomModal( + child: Column( + children: [ + ListTile( + leading: Icon(Icons.link), + title: Text('Share link'), + onTap: () { + Navigator.of(context).pop(); + Share.text('Share image url', url, 'text/plain'); + }, + ), + ListTile( + leading: Icon(Icons.image), + title: Text('Share file'), + onTap: () { + Navigator.of(context).pop(); + // TODO: share file + }, + ), + ], + ), + ), + ); + } + return Scaffold( appBar: showButtons.value ? AppBar( @@ -37,7 +69,7 @@ class MediaView extends HookWidget { IconButton( icon: Icon(Icons.share), tooltip: 'share', - onPressed: () {}, + onPressed: share, ), IconButton( icon: Icon(Icons.file_download), From e4e7f1d9a1768202297ac86b6602bb24b443a309 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 15:56:22 +0200 Subject: [PATCH 05/22] add dismiss handling. not perfect and prolly not final --- lib/widgets/media_view.dart | 39 ++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/widgets/media_view.dart b/lib/widgets/media_view.dart index 96d91c2..ccc0b19 100644 --- a/lib/widgets/media_view.dart +++ b/lib/widgets/media_view.dart @@ -14,7 +14,8 @@ class MediaView extends HookWidget { @override Widget build(BuildContext context) { - var showButtons = useState(true); + final showButtons = useState(true); + final isZoomedOut = useState(true); useEffect(() => () => SystemChrome.setEnabledSystemUIOverlays([ SystemUiOverlay.bottom, @@ -60,6 +61,8 @@ class MediaView extends HookWidget { } return Scaffold( + extendBodyBehindAppBar: true, + extendBody: true, appBar: showButtons.value ? AppBar( backgroundColor: Colors.black38, @@ -79,16 +82,30 @@ class MediaView extends HookWidget { ], ) : null, - extendBodyBehindAppBar: true, - body: GestureDetector( - onTapUp: (details) => showButtons.value = !showButtons.value, - child: PhotoView( - minScale: PhotoViewComputedScale.contained, - initialScale: PhotoViewComputedScale.contained, - imageProvider: CachedNetworkImageProvider(url), - heroAttributes: PhotoViewHeroAttributes(tag: url), - loadingBuilder: (context, event) => - Center(child: CircularProgressIndicator()), + body: Dismissible( + direction: DismissDirection.vertical, + onDismissed: (_) => Navigator.of(context).pop(), + key: const Key('media view'), + background: Container(color: Colors.black), + dismissThresholds: { + DismissDirection.vertical: 0, + }, + confirmDismiss: (direction) => Future.value(isZoomedOut.value), + resizeDuration: null, + child: GestureDetector( + onTapUp: (details) => showButtons.value = !showButtons.value, + child: PhotoView( + scaleStateChangedCallback: (value) { + isZoomedOut.value = value == PhotoViewScaleState.zoomedOut || + value == PhotoViewScaleState.initial; + }, + minScale: PhotoViewComputedScale.contained, + initialScale: PhotoViewComputedScale.contained, + imageProvider: CachedNetworkImageProvider(url), + heroAttributes: PhotoViewHeroAttributes(tag: url), + loadingBuilder: (context, event) => + Center(child: CircularProgressIndicator()), + ), ), ), ); From 689b4c41ccfb0fc0f1d71edf295aecde04f67d0e Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 19:20:00 +0200 Subject: [PATCH 06/22] Move media_view to pages, cuz it has a scaffold --- lib/{widgets => pages}/media_view.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename lib/{widgets => pages}/media_view.dart (96%) diff --git a/lib/widgets/media_view.dart b/lib/pages/media_view.dart similarity index 96% rename from lib/widgets/media_view.dart rename to lib/pages/media_view.dart index ccc0b19..aae1f38 100644 --- a/lib/widgets/media_view.dart +++ b/lib/pages/media_view.dart @@ -5,12 +5,12 @@ import 'package:flutter/services.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:photo_view/photo_view.dart'; -import 'bottom_modal.dart'; +import '../widgets/bottom_modal.dart'; -class MediaView extends HookWidget { +class MediaViewPage extends HookWidget { final String url; - const MediaView(this.url); + const MediaViewPage(this.url); @override Widget build(BuildContext context) { From 9e273809858e4ad3b82400115b991f7ae4bd9b24 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 19:21:59 +0200 Subject: [PATCH 07/22] use mediaviewpage in a post --- lib/widgets/post.dart | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index bdea2ab..e626227 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -8,6 +8,7 @@ import 'package:timeago/timeago.dart' as timeago; import 'package:url_launcher/url_launcher.dart' as ul; import '../pages/full_post.dart'; +import '../pages/media_view.dart'; import '../url_launcher.dart'; import '../util/api_extensions.dart'; import '../util/goto.dart'; @@ -25,7 +26,13 @@ MediaType whatType(String url) { if (url == null) return MediaType.other; // TODO: make detection more nuanced - if (url.endsWith('.jpg') || url.endsWith('.png') || url.endsWith('.gif')) { + if (url.endsWith('.jpg') || + url.endsWith('.jpeg') || + url.endsWith('.png') || + url.endsWith('.gif') || + url.endsWith('.webp') || + url.endsWith('.bmp') || + url.endsWith('.wbpm')) { return MediaType.image; } return MediaType.other; @@ -42,10 +49,10 @@ class Post extends StatelessWidget { void _openLink() => urlLauncher(post.url); - void _openFullImage() { - // TODO: fullscreen media view - print('OPEN FULL IMAGE'); - } + void _openFullImage(BuildContext context) => + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => MediaViewPage(post.url), + )); // POST ACTIONS @@ -371,11 +378,14 @@ class Post extends StatelessWidget { assert(post.url != null); return InkWell( - onTap: _openFullImage, - child: CachedNetworkImage( - imageUrl: post.url, - progressIndicatorBuilder: (context, url, progress) => - CircularProgressIndicator(value: progress.progress), + onTap: () => _openFullImage(context), + child: Hero( + tag: post.url, + child: CachedNetworkImage( + imageUrl: post.url, + progressIndicatorBuilder: (context, url, progress) => + CircularProgressIndicator(value: progress.progress), + ), ), ); } From 4a5bb17afbd9e70a56dd5784e6022990f6d80617 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 19:29:17 +0200 Subject: [PATCH 08/22] Make image inside markdown fullscreenable --- lib/widgets/markdown_text.dart | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart index 7ef6878..c0a9702 100644 --- a/lib/widgets/markdown_text.dart +++ b/lib/widgets/markdown_text.dart @@ -1,6 +1,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:lemmur/pages/media_view.dart'; import 'package:markdown/markdown.dart' as md; import '../url_launcher.dart'; @@ -24,13 +25,20 @@ class MarkdownText extends StatelessWidget { ), ))); }, - imageBuilder: (uri, title, alt) => CachedNetworkImage( - imageUrl: uri.toString(), - errorWidget: (context, url, error) => Row( - children: [ - Icon(Icons.warning), - Text("couldn't load image, ${error.toString()}") - ], + imageBuilder: (uri, title, alt) => InkWell( + onTap: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => MediaViewPage(uri.toString()), + )); + }, + child: CachedNetworkImage( + imageUrl: uri.toString(), + errorWidget: (context, url, error) => Row( + children: [ + Icon(Icons.warning), + Text("couldn't load image, ${error.toString()}") + ], + ), ), ), ); From 6cc894be2c163551d9baf2d0a4b9604ac090eeca Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 20:26:06 +0200 Subject: [PATCH 09/22] add widget for wrapping images that can be fullscreened --- lib/widgets/fullscreenable_image.dart | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 lib/widgets/fullscreenable_image.dart diff --git a/lib/widgets/fullscreenable_image.dart b/lib/widgets/fullscreenable_image.dart new file mode 100644 index 0000000..c49b957 --- /dev/null +++ b/lib/widgets/fullscreenable_image.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +import '../pages/media_view.dart'; + +class FullscreenableImage extends StatelessWidget { + final String url; + final Widget child; + + const FullscreenableImage({Key key, this.url, this.child}) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => MediaViewPage(url), + )); + }, + child: Hero( + tag: url, + child: child, + ), + ); + } +} From 1746cc0db5c8b8cc2ea61ff7871b422402a448ab Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 20:36:19 +0200 Subject: [PATCH 10/22] mark props as required and move onTap to a method --- lib/widgets/fullscreenable_image.dart | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/widgets/fullscreenable_image.dart b/lib/widgets/fullscreenable_image.dart index c49b957..dc68740 100644 --- a/lib/widgets/fullscreenable_image.dart +++ b/lib/widgets/fullscreenable_image.dart @@ -6,16 +6,22 @@ class FullscreenableImage extends StatelessWidget { final String url; final Widget child; - const FullscreenableImage({Key key, this.url, this.child}) : super(key: key); + const FullscreenableImage({ + Key key, + @required this.url, + @required this.child, + }) : super(key: key); + + _onTap(BuildContext c) { + Navigator.of(c).push(MaterialPageRoute( + builder: (context) => MediaViewPage(url), + )); + } @override Widget build(BuildContext context) { return InkWell( - onTap: () { - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => MediaViewPage(url), - )); - }, + onTap: () => _onTap(context), child: Hero( tag: url, child: child, From 0f8a846e8a55ad95b88f7e6fb6c95056e8ed2f20 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 20:38:50 +0200 Subject: [PATCH 11/22] Make images in community, instance, markdown fullscreenable --- lib/pages/community.dart | 20 ++++++++++++-------- lib/pages/instance.dart | 12 ++++++++---- lib/widgets/markdown_text.dart | 18 +++++++++++------- lib/widgets/post.dart | 16 +++++++--------- 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/lib/pages/community.dart b/lib/pages/community.dart index adafdc9..63cc5d1 100644 --- a/lib/pages/community.dart +++ b/lib/pages/community.dart @@ -13,6 +13,7 @@ import '../util/intl.dart'; import '../util/text_color.dart'; import '../widgets/badge.dart'; import '../widgets/bottom_modal.dart'; +import '../widgets/fullscreenable_image.dart'; import '../widgets/markdown_text.dart'; class CommunityPage extends HookWidget { @@ -251,14 +252,17 @@ class _CommunityOverview extends StatelessWidget { Container( width: 83, height: 83, - child: CachedNetworkImage( - imageUrl: community.icon, - imageBuilder: (context, imageProvider) => Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - image: DecorationImage( - fit: BoxFit.cover, - image: imageProvider, + child: FullscreenableImage( + url: community.icon, + child: CachedNetworkImage( + imageUrl: community.icon, + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + fit: BoxFit.cover, + image: imageProvider, + ), ), ), ), diff --git a/lib/pages/instance.dart b/lib/pages/instance.dart index e9ee421..6e41a5c 100644 --- a/lib/pages/instance.dart +++ b/lib/pages/instance.dart @@ -11,6 +11,7 @@ import '../util/goto.dart'; import '../util/text_color.dart'; import '../widgets/badge.dart'; import '../widgets/bottom_modal.dart'; +import '../widgets/fullscreenable_image.dart'; import '../widgets/markdown_text.dart'; import 'communities_list.dart'; import 'users_list.dart'; @@ -166,10 +167,13 @@ class InstancePage extends HookWidget { children: [ Padding( padding: const EdgeInsets.only(top: 40), - child: CachedNetworkImage( - width: 100, - height: 100, - imageUrl: site.site.icon), + child: FullscreenableImage( + url: site.site.icon, + child: CachedNetworkImage( + width: 100, + height: 100, + imageUrl: site.site.icon), + ), ), Text(site.site.name, style: theme.textTheme.headline6), diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart index c0a9702..e2dec0d 100644 --- a/lib/widgets/markdown_text.dart +++ b/lib/widgets/markdown_text.dart @@ -5,6 +5,7 @@ import 'package:lemmur/pages/media_view.dart'; import 'package:markdown/markdown.dart' as md; import '../url_launcher.dart'; +import 'fullscreenable_image.dart'; class MarkdownText extends StatelessWidget { final String text; @@ -31,13 +32,16 @@ class MarkdownText extends StatelessWidget { builder: (context) => MediaViewPage(uri.toString()), )); }, - child: CachedNetworkImage( - imageUrl: uri.toString(), - errorWidget: (context, url, error) => Row( - children: [ - Icon(Icons.warning), - Text("couldn't load image, ${error.toString()}") - ], + child: FullscreenableImage( + url: uri.toString(), + child: CachedNetworkImage( + imageUrl: uri.toString(), + errorWidget: (context, url, error) => Row( + children: [ + Icon(Icons.warning), + Text("couldn't load image, ${error.toString()}") + ], + ), ), ), ), diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index e626227..7906057 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -13,6 +13,7 @@ import '../url_launcher.dart'; import '../util/api_extensions.dart'; import '../util/goto.dart'; import 'bottom_modal.dart'; +import 'fullscreenable_image.dart'; import 'markdown_text.dart'; enum MediaType { @@ -377,15 +378,12 @@ class Post extends StatelessWidget { Widget postImage() { assert(post.url != null); - return InkWell( - onTap: () => _openFullImage(context), - child: Hero( - tag: post.url, - child: CachedNetworkImage( - imageUrl: post.url, - progressIndicatorBuilder: (context, url, progress) => - CircularProgressIndicator(value: progress.progress), - ), + return FullscreenableImage( + url: post.url, + child: CachedNetworkImage( + imageUrl: post.url, + progressIndicatorBuilder: (context, url, progress) => + CircularProgressIndicator(value: progress.progress), ), ); } From 4cc1bd56b0849bd015ee98bd9ba296b6b87930ff Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 20:43:00 +0200 Subject: [PATCH 12/22] Make banner fullscreenable --- lib/pages/community.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pages/community.dart b/lib/pages/community.dart index 63cc5d1..7f114e3 100644 --- a/lib/pages/community.dart +++ b/lib/pages/community.dart @@ -275,7 +275,10 @@ class _CommunityOverview extends StatelessWidget { return Stack(children: [ if (community.banner != null) - CachedNetworkImage(imageUrl: community.banner), + FullscreenableImage( + url: community.banner, + child: CachedNetworkImage(imageUrl: community.banner), + ), SafeArea( child: Padding( padding: const EdgeInsets.only(top: 45), From e735f065e107d0366eef4297bd97879aa0fc97aa Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 21:18:45 +0200 Subject: [PATCH 13/22] make instance banner fullscreenable --- lib/pages/instance.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pages/instance.dart b/lib/pages/instance.dart index 6e41a5c..8cf9766 100644 --- a/lib/pages/instance.dart +++ b/lib/pages/instance.dart @@ -160,7 +160,10 @@ class InstancePage extends HookWidget { flexibleSpace: FlexibleSpaceBar( background: Stack(children: [ if (site.site.banner != null) - CachedNetworkImage(imageUrl: site.site.banner), + FullscreenableImage( + url: site.site.banner, + child: CachedNetworkImage(imageUrl: site.site.banner), + ), SafeArea( child: Center( child: Column( From dea677e218dd20c68923c9af138165bcf445ef1a Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 21:20:43 +0200 Subject: [PATCH 14/22] remove dead code --- lib/widgets/post.dart | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 7906057..ce20a50 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -8,7 +8,6 @@ import 'package:timeago/timeago.dart' as timeago; import 'package:url_launcher/url_launcher.dart' as ul; import '../pages/full_post.dart'; -import '../pages/media_view.dart'; import '../url_launcher.dart'; import '../util/api_extensions.dart'; import '../util/goto.dart'; @@ -50,11 +49,6 @@ class Post extends StatelessWidget { void _openLink() => urlLauncher(post.url); - void _openFullImage(BuildContext context) => - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => MediaViewPage(post.url), - )); - // POST ACTIONS void _savePost() { From ac70400c380038d290b4aaabea987489ec2eb84f Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 21:21:47 +0200 Subject: [PATCH 15/22] make import relative --- lib/widgets/markdown_text.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart index e2dec0d..253a8d4 100644 --- a/lib/widgets/markdown_text.dart +++ b/lib/widgets/markdown_text.dart @@ -1,9 +1,9 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; -import 'package:lemmur/pages/media_view.dart'; import 'package:markdown/markdown.dart' as md; +import '../pages/media_view.dart'; import '../url_launcher.dart'; import 'fullscreenable_image.dart'; From 676d1a469609af8a6513c8cd2b2687204109d079 Mon Sep 17 00:00:00 2001 From: krawieck Date: Fri, 11 Sep 2020 21:21:58 +0200 Subject: [PATCH 16/22] turn function into expression --- lib/widgets/fullscreenable_image.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/widgets/fullscreenable_image.dart b/lib/widgets/fullscreenable_image.dart index dc68740..5f23506 100644 --- a/lib/widgets/fullscreenable_image.dart +++ b/lib/widgets/fullscreenable_image.dart @@ -19,13 +19,11 @@ class FullscreenableImage extends StatelessWidget { } @override - Widget build(BuildContext context) { - return InkWell( - onTap: () => _onTap(context), - child: Hero( - tag: url, - child: child, - ), - ); - } + Widget build(BuildContext context) => InkWell( + onTap: () => _onTap(context), + child: Hero( + tag: url, + child: child, + ), + ); } From 450f3373af6af519e157bcdd388f1e671eebc1b9 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 13 Sep 2020 00:31:55 +0200 Subject: [PATCH 17/22] remove dead code --- lib/widgets/post.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index a8933e4..2a4ec37 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -47,8 +47,6 @@ class Post extends StatelessWidget { // == ACTIONS == - void _openLink() => urlLauncher(post.url); - void _savePost() { print('SAVE POST'); } From 4bec0c533a72976df3844d1d9ba6cb0c4557ea3d Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 13 Sep 2020 15:42:39 +0200 Subject: [PATCH 18/22] Remove useless inkwell --- lib/widgets/markdown_text.dart | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/lib/widgets/markdown_text.dart b/lib/widgets/markdown_text.dart index fbe395e..d3b4af2 100644 --- a/lib/widgets/markdown_text.dart +++ b/lib/widgets/markdown_text.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:markdown/markdown.dart' as md; -import '../pages/media_view.dart'; import '../url_launcher.dart'; import 'fullscreenable_image.dart'; @@ -28,22 +27,15 @@ class MarkdownText extends StatelessWidget { ), ))); }, - imageBuilder: (uri, title, alt) => InkWell( - onTap: () { - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => MediaViewPage(uri.toString()), - )); - }, - child: FullscreenableImage( - url: uri.toString(), - child: CachedNetworkImage( - imageUrl: uri.toString(), - errorWidget: (context, url, error) => Row( - children: [ - Icon(Icons.warning), - Text("couldn't load image, ${error.toString()}") - ], - ), + imageBuilder: (uri, title, alt) => FullscreenableImage( + url: uri.toString(), + child: CachedNetworkImage( + imageUrl: uri.toString(), + errorWidget: (context, url, error) => Row( + children: [ + Icon(Icons.warning), + Text("couldn't load image, ${error.toString()}") + ], ), ), ), From 1e0fcf9c67626f877f09b3e6061ed58ace5a3520 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 13 Sep 2020 16:05:17 +0200 Subject: [PATCH 19/22] Fill errorWidget field on every cached network image, cuz otherwise they would break the app --- lib/pages/community.dart | 6 +++++- lib/pages/instance.dart | 18 ++++++++++++++---- lib/pages/users_list.dart | 2 ++ lib/widgets/comment.dart | 1 + lib/widgets/post.dart | 1 + lib/widgets/user_profile.dart | 2 ++ 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/pages/community.dart b/lib/pages/community.dart index 628b500..0f14cc2 100644 --- a/lib/pages/community.dart +++ b/lib/pages/community.dart @@ -265,6 +265,7 @@ class _CommunityOverview extends StatelessWidget { ), ), ), + errorWidget: (_, __, ___) => Icon(Icons.warning), ), ), ), @@ -277,7 +278,10 @@ class _CommunityOverview extends StatelessWidget { if (community.banner != null) FullscreenableImage( url: community.banner, - child: CachedNetworkImage(imageUrl: community.banner), + child: CachedNetworkImage( + imageUrl: community.banner, + errorWidget: (_, __, ___) => Container(), + ), ), SafeArea( child: Padding( diff --git a/lib/pages/instance.dart b/lib/pages/instance.dart index 529c439..d8ec37f 100644 --- a/lib/pages/instance.dart +++ b/lib/pages/instance.dart @@ -162,7 +162,10 @@ class InstancePage extends HookWidget { if (site.site.banner != null) FullscreenableImage( url: site.site.banner, - child: CachedNetworkImage(imageUrl: site.site.banner), + child: CachedNetworkImage( + imageUrl: site.site.banner, + errorWidget: (_, __, ___) => Container(), + ), ), SafeArea( child: Center( @@ -173,9 +176,12 @@ class InstancePage extends HookWidget { child: FullscreenableImage( url: site.site.icon, child: CachedNetworkImage( - width: 100, - height: 100, - imageUrl: site.site.icon), + width: 100, + height: 100, + imageUrl: site.site.icon, + errorWidget: (_, __, ___) => + Icon(Icons.warning), + ), ), ), Text(site.site.name, @@ -332,6 +338,8 @@ class _AboutTab extends HookWidget { height: 50, width: 50, imageUrl: e.icon, + errorWidget: (_, __, ___) => + SizedBox(width: 50, height: 50), imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( shape: BoxShape.circle, @@ -380,6 +388,8 @@ class _AboutTab extends HookWidget { height: 50, width: 50, imageUrl: e.avatar, + errorWidget: (_, __, ___) => + SizedBox(width: 50, height: 50), imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( shape: BoxShape.circle, diff --git a/lib/pages/users_list.dart b/lib/pages/users_list.dart index 16b5259..332b43c 100644 --- a/lib/pages/users_list.dart +++ b/lib/pages/users_list.dart @@ -48,6 +48,8 @@ class UsersListPage extends StatelessWidget { height: 50, width: 50, imageUrl: users[i].avatar, + errorWidget: (_, __, ___) => + SizedBox(height: 50, width: 50), imageBuilder: (context, imageProvider) => Container( decoration: BoxDecoration( shape: BoxShape.circle, diff --git a/lib/widgets/comment.dart b/lib/widgets/comment.dart index 1ae29d6..206c9ec 100644 --- a/lib/widgets/comment.dart +++ b/lib/widgets/comment.dart @@ -200,6 +200,7 @@ class Comment extends StatelessWidget { ), ), ), + errorWidget: (_, __, ___) => Container(), ), ), ), diff --git a/lib/widgets/post.dart b/lib/widgets/post.dart index 2a4ec37..40614a9 100644 --- a/lib/widgets/post.dart +++ b/lib/widgets/post.dart @@ -374,6 +374,7 @@ class Post extends StatelessWidget { url: post.url, child: CachedNetworkImage( imageUrl: post.url, + errorWidget: (_, __, ___) => Icon(Icons.warning), progressIndicatorBuilder: (context, url, progress) => CircularProgressIndicator(value: progress.progress), ), diff --git a/lib/widgets/user_profile.dart b/lib/widgets/user_profile.dart index 346205d..f5afc3a 100644 --- a/lib/widgets/user_profile.dart +++ b/lib/widgets/user_profile.dart @@ -96,6 +96,7 @@ class UserProfile extends HookWidget { if (userViewSnap.data?.banner != null) CachedNetworkImage( imageUrl: userViewSnap.data.banner, + errorWidget: (_, __, ___) => Container(), ) else Container( @@ -154,6 +155,7 @@ class UserProfile extends HookWidget { borderRadius: BorderRadius.all(Radius.circular(12)), child: CachedNetworkImage( imageUrl: userViewSnap.data.avatar, + errorWidget: (_, __, ___) => Container(), ), ), ), From 2e23148532d6bfd5d76ff38c2f15ea35f2b40c6c Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 13 Sep 2020 16:48:40 +0200 Subject: [PATCH 20/22] move ui showing/hiding logic to `useEffect` --- lib/pages/media_view.dart | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/pages/media_view.dart b/lib/pages/media_view.dart index aae1f38..e387d6a 100644 --- a/lib/pages/media_view.dart +++ b/lib/pages/media_view.dart @@ -17,19 +17,20 @@ class MediaViewPage extends HookWidget { final showButtons = useState(true); final isZoomedOut = useState(true); - useEffect(() => () => SystemChrome.setEnabledSystemUIOverlays([ + useEffect(() { + if (showButtons.value) { + SystemChrome.setEnabledSystemUIOverlays([ SystemUiOverlay.bottom, SystemUiOverlay.top, - ])); - - if (showButtons.value) { - SystemChrome.setEnabledSystemUIOverlays([ - SystemUiOverlay.bottom, - SystemUiOverlay.top, - ]); - } else { - SystemChrome.setEnabledSystemUIOverlays([]); - } + ]); + } else { + SystemChrome.setEnabledSystemUIOverlays([]); + } + return () => SystemChrome.setEnabledSystemUIOverlays([ + SystemUiOverlay.bottom, + SystemUiOverlay.top, + ]); + }); share() { showModalBottomSheet( From c89ad2833ae352e607d95aa342248384621abf98 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 13 Sep 2020 18:16:53 +0200 Subject: [PATCH 21/22] Make `useEffect` actually work --- lib/pages/media_view.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pages/media_view.dart b/lib/pages/media_view.dart index e387d6a..b1e4b16 100644 --- a/lib/pages/media_view.dart +++ b/lib/pages/media_view.dart @@ -26,11 +26,14 @@ class MediaViewPage extends HookWidget { } else { SystemChrome.setEnabledSystemUIOverlays([]); } - return () => SystemChrome.setEnabledSystemUIOverlays([ - SystemUiOverlay.bottom, - SystemUiOverlay.top, - ]); - }); + }, [showButtons.value]); + + useEffect( + () => () => SystemChrome.setEnabledSystemUIOverlays([ + SystemUiOverlay.bottom, + SystemUiOverlay.top, + ]), + []); share() { showModalBottomSheet( From f3176128c58f1d3bee8489452393a9520353ca02 Mon Sep 17 00:00:00 2001 From: krawieck Date: Sun, 13 Sep 2020 21:15:20 +0200 Subject: [PATCH 22/22] add `return null` to stfu the linter --- lib/pages/media_view.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/media_view.dart b/lib/pages/media_view.dart index b1e4b16..9cb42ec 100644 --- a/lib/pages/media_view.dart +++ b/lib/pages/media_view.dart @@ -26,6 +26,7 @@ class MediaViewPage extends HookWidget { } else { SystemChrome.setEnabledSystemUIOverlays([]); } + return null; }, [showButtons.value]); useEffect(