diff --git a/lib/screens/photo_viewer/photo_viewer_screen.dart b/lib/screens/photo_viewer/photo_viewer_screen.dart index 9a77b9a..a07068a 100644 --- a/lib/screens/photo_viewer/photo_viewer_screen.dart +++ b/lib/screens/photo_viewer/photo_viewer_screen.dart @@ -88,10 +88,12 @@ class _PhotoViewerScreenState extends ConsumerState with Widg final newItems = await Future.value(widget.loadingItems); - setState(() { - photos = {...photos, ...newItems}.toList(); - loadingItems = false; - }); + if (context.mounted) { + setState(() { + photos = {...photos, ...newItems}.toList(); + loadingItems = false; + }); + } } }, ); diff --git a/lib/screens/shared/adaptive_dialog.dart b/lib/screens/shared/adaptive_dialog.dart index 1e2439f..3c428cf 100644 --- a/lib/screens/shared/adaptive_dialog.dart +++ b/lib/screens/shared/adaptive_dialog.dart @@ -2,9 +2,11 @@ import 'package:flutter/material.dart'; import 'package:fladder/util/adaptive_layout/adaptive_layout.dart'; -Future showDialogAdaptive( - {required BuildContext context, required Widget Function(BuildContext context) builder}) { - if (AdaptiveLayout.of(context).inputDevice == InputDevice.pointer) { +Future showDialogAdaptive({ + required BuildContext context, + required Widget Function(BuildContext context) builder, +}) { + if (AdaptiveLayout.viewSizeOf(context) >= ViewSize.tablet) { return showDialog( context: context, useSafeArea: false, diff --git a/lib/screens/shared/media/components/poster_image.dart b/lib/screens/shared/media/components/poster_image.dart index 02db9da..ab7f847 100644 --- a/lib/screens/shared/media/components/poster_image.dart +++ b/lib/screens/shared/media/components/poster_image.dart @@ -58,7 +58,7 @@ class _PosterImageState extends ConsumerState { late String currentTag = widget.heroTag == true ? widget.poster.id : UniqueKey().toString(); bool hover = false; - void pressedWidget() async { + void pressedWidget(BuildContext context) async { if (widget.heroTag == false) { setState(() { currentTag = widget.poster.id; @@ -67,15 +67,12 @@ class _PosterImageState extends ConsumerState { if (widget.onPressed != null) { widget.onPressed?.call(() async { await navigateToDetails(); - if (context.mounted) { - context.refreshData(); - } + context.refreshData(); }, widget.poster); } else { await navigateToDetails(); - if (context.mounted) { - context.refreshData(); - } + if (!context.mounted) return; + context.refreshData(); } } @@ -319,7 +316,7 @@ class _PosterImageState extends ConsumerState { Focus( onFocusChange: (value) => setState(() => hover = value), child: FlatButton( - onTap: pressedWidget, + onTap: () => pressedWidget(context), onSecondaryTapDown: (details) async { Offset localPosition = details.globalPosition; RelativeRect position = RelativeRect.fromLTRB( @@ -391,7 +388,7 @@ class _PosterImageState extends ConsumerState { Material( color: Colors.transparent, child: InkWell( - onTap: pressedWidget, + onTap: () => pressedWidget(context), onLongPress: () { showBottomSheetPill( context: context, diff --git a/lib/util/fladder_image.dart b/lib/util/fladder_image.dart index b46e30c..23ed50c 100644 --- a/lib/util/fladder_image.dart +++ b/lib/util/fladder_image.dart @@ -52,7 +52,7 @@ class FladderImage extends ConsumerWidget { ), if (!blurOnly) FadeInImage( - placeholder: Image.memory(kTransparentImage).image, + placeholder: MemoryImage(kTransparentImage), fit: fit, placeholderFit: fit, excludeFromSemantics: true, diff --git a/lib/widgets/shared/trick_play_image.dart b/lib/widgets/shared/trick_play_image.dart index c150bf4..1fbdd35 100644 --- a/lib/widgets/shared/trick_play_image.dart +++ b/lib/widgets/shared/trick_play_image.dart @@ -27,12 +27,21 @@ class _TrickPlayImageState extends ConsumerState { late Offset currentOffset = const Offset(0, 0); String? currentUrl; + bool _isMounted = true; + @override void initState() { super.initState(); loadImage(); } + @override + void dispose() { + image?.dispose(); + _isMounted = false; + super.dispose(); + } + @override void didUpdateWidget(covariant TrickPlayImage oldWidget) { super.didUpdateWidget(oldWidget); @@ -55,6 +64,7 @@ class _TrickPlayImageState extends ConsumerState { } Future loadImage() async { + if (!_isMounted) return; if (model.images.isEmpty) return; final newUrl = model.getTile(time); currentOffset = model.offset(time); @@ -76,11 +86,10 @@ class _TrickPlayImageState extends ConsumerState { final Uint8List bytes = response.bodyBytes; final ui.Codec codec = await ui.instantiateImageCodec(bytes); final ui.FrameInfo frameInfo = await codec.getNextFrame(); - if (context.mounted) { - setState(() { - image = frameInfo.image; - }); - } + if (!_isMounted) return; + setState(() { + image = frameInfo.image; + }); } else { throw Exception('Failed to load network image'); } @@ -90,6 +99,7 @@ class _TrickPlayImageState extends ConsumerState { final Uint8List bytes = await File(path).readAsBytes(); final ui.Codec codec = await ui.instantiateImageCodec(bytes); final ui.FrameInfo frameInfo = await codec.getNextFrame(); + if (!_isMounted) return; setState(() { image = frameInfo.image; }); diff --git a/lib/wrappers/media_control_wrapper.dart b/lib/wrappers/media_control_wrapper.dart index ae36272..bb03a5c 100644 --- a/lib/wrappers/media_control_wrapper.dart +++ b/lib/wrappers/media_control_wrapper.dart @@ -53,6 +53,7 @@ class MediaControlsWrapper extends BaseAudioHandler { Future init() async { if (!initMediaControls) { + initMediaControls = true; await AudioService.init( builder: () => this, config: const AudioServiceConfig( @@ -66,7 +67,6 @@ class MediaControlsWrapper extends BaseAudioHandler { androidShowNotificationBadge: true, ), ); - initMediaControls = true; } final player = switch (ref.read(videoPlayerSettingsProvider.select((value) => value.wantedPlayer))) {