From c4fc14a9096549e42e9416716bda7a046574d09d Mon Sep 17 00:00:00 2001 From: otsmr Date: Sat, 20 Jun 2026 00:01:14 +0200 Subject: [PATCH] remove unused animations and start pre-caching later --- .../visual/views/chats/media_viewer.view.dart | 45 ++--- lib/src/visual/views/home.view.dart | 12 +- .../components/memory_thumbnail.comp.dart | 185 +++++++----------- 3 files changed, 101 insertions(+), 141 deletions(-) diff --git a/lib/src/visual/views/chats/media_viewer.view.dart b/lib/src/visual/views/chats/media_viewer.view.dart index b04a8fe4..403f0fe4 100644 --- a/lib/src/visual/views/chats/media_viewer.view.dart +++ b/lib/src/visual/views/chats/media_viewer.view.dart @@ -662,6 +662,25 @@ class _MediaViewerViewState extends State { ); } + void _sendTextMessage() { + if (textMessageController.text.isNotEmpty) { + unawaited( + insertAndSendTextMessage( + widget.group.groupId, + textMessageController.text, + currentMessage!.messageId, + ), + ); + textMessageController.clear(); + } + FocusManager.instance.primaryFocus?.unfocus(); + setState(() { + showSendTextMessageInput = false; + showShortReactions = false; + _lastTimeInputClosed = clock.now(); + }); + } + void onScreenTapped() { if (_lastTimeInputClosed != null && clock.now().difference(_lastTimeInputClosed!) < @@ -774,30 +793,8 @@ class _MediaViewerViewState extends State { if (showSendTextMessageInput) MediaViewerMessageInput( controller: textMessageController, - onSubmitted: (value) { - setState(() { - showSendTextMessageInput = false; - showShortReactions = false; - _lastTimeInputClosed = clock.now(); - }); - }, - onSendPressed: () { - if (textMessageController.text.isNotEmpty) { - unawaited( - insertAndSendTextMessage( - widget.group.groupId, - textMessageController.text, - currentMessage!.messageId, - ), - ); - textMessageController.clear(); - } - setState(() { - showSendTextMessageInput = false; - showShortReactions = false; - _lastTimeInputClosed = clock.now(); - }); - }, + onSubmitted: (value) => _sendTextMessage(), + onSendPressed: _sendTextMessage, ), if (currentMessage != null) AdditionalMessageContent(currentMessage!), diff --git a/lib/src/visual/views/home.view.dart b/lib/src/visual/views/home.view.dart index 975e78c6..248cc5ee 100644 --- a/lib/src/visual/views/home.view.dart +++ b/lib/src/visual/views/home.view.dart @@ -39,6 +39,7 @@ class HomeViewState extends State with WidgetsBindingObserver { double _offsetFromOne = 0; bool _isBottomNavVisible = true; Timer? _disableCameraTimer; + bool _startPreloading = false; final MainCameraController _mainCameraController = MainCameraController(); late final PageController _homeViewPageController; @@ -138,6 +139,13 @@ class HomeViewState extends State with WidgetsBindingObserver { widget.initialPage == 0) { streamHomeViewPageIndex.add(0); } + Future.delayed(const Duration(seconds: 1), () { + if (mounted) { + setState(() { + _startPreloading = true; + }); + } + }); }); } @@ -319,7 +327,9 @@ class HomeViewState extends State with WidgetsBindingObserver { scrollDirection: Axis.horizontal, physics: const PageScrollPhysics(), controller: _homeViewPageController, - scrollCacheExtent: const ScrollCacheExtent.viewport(1), + scrollCacheExtent: _startPreloading + ? const ScrollCacheExtent.viewport(1) + : null, slivers: [ SliverFillViewport( delegate: SliverChildListDelegate([ diff --git a/lib/src/visual/views/memories/components/memory_thumbnail.comp.dart b/lib/src/visual/views/memories/components/memory_thumbnail.comp.dart index 10e96fcb..599bc012 100644 --- a/lib/src/visual/views/memories/components/memory_thumbnail.comp.dart +++ b/lib/src/visual/views/memories/components/memory_thumbnail.comp.dart @@ -4,6 +4,7 @@ import 'package:twonly/src/database/tables/mediafiles.table.dart'; import 'package:twonly/src/model/memory_item.model.dart'; import 'package:twonly/src/visual/components/selectable_thumbnail.comp.dart'; import 'package:twonly/src/visual/views/memories/components/memory_transition_painter.dart'; + class MemoriesThumbnailComp extends StatefulWidget { const MemoriesThumbnailComp({ required this.galleryItem, @@ -28,14 +29,7 @@ class MemoriesThumbnailComp extends StatefulWidget { State createState() => _MemoriesThumbnailCompState(); } -final Set _alreadyAnimatedIds = {}; - -class _MemoriesThumbnailCompState extends State - with SingleTickerProviderStateMixin { - late final AnimationController _scaleController; - late final Animation _scaleAnimation; - late final Animation _slideAnimation; - +class _MemoriesThumbnailCompState extends State { ImageProvider? _imageProvider; ImageStream? _imageStream; ImageInfo? _imageInfo; @@ -44,40 +38,6 @@ class _MemoriesThumbnailCompState extends State @override void initState() { super.initState(); - _scaleController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 350), - ); - _scaleAnimation = Tween(begin: 0.94, end: 1).animate( - CurvedAnimation(parent: _scaleController, curve: Curves.easeOutCubic), - ); - _slideAnimation = - Tween( - begin: const Offset(0, 0.125), - end: Offset.zero, - ).animate( - CurvedAnimation(parent: _scaleController, curve: Curves.easeOutCubic), - ); - - final mediaId = widget.galleryItem.mediaService.mediaFile.mediaId; - final shouldAnimate = - widget.index < 20 && !_alreadyAnimatedIds.contains(mediaId); - - if (shouldAnimate) { - _alreadyAnimatedIds.add(mediaId); - final delayMs = widget.index * 10; - if (delayMs > 0) { - Future.delayed(Duration(milliseconds: delayMs), () { - if (mounted) { - _scaleController.forward(); - } - }); - } else { - _scaleController.forward(); - } - } else { - _scaleController.value = 1.0; - } _listener = ImageStreamListener( (info, _) { @@ -101,8 +61,11 @@ class _MemoriesThumbnailCompState extends State void _resolveImage() { final media = widget.galleryItem.mediaService; - final hasThumbnail = media.thumbnailPath.existsSync() && media.thumbnailPath.lengthSync() > 0; - final hasStored = media.storedPath.existsSync() && media.storedPath.lengthSync() > 0; + final hasThumbnail = + media.thumbnailPath.existsSync() && + media.thumbnailPath.lengthSync() > 0; + final hasStored = + media.storedPath.existsSync() && media.storedPath.lengthSync() > 0; final isImageOrGif = media.mediaFile.type == MediaType.image || media.mediaFile.type == MediaType.gif; @@ -136,7 +99,6 @@ class _MemoriesThumbnailCompState extends State @override void dispose() { - _scaleController.dispose(); _imageStream?.removeListener(_listener); super.dispose(); } @@ -169,80 +131,71 @@ class _MemoriesThumbnailCompState extends State ); } : null, - child: SlideTransition( - position: _slideAnimation, - child: ScaleTransition( - scale: _scaleAnimation, - child: FadeTransition( - opacity: _scaleController, - child: SelectableThumbnailComp( - isSelected: widget.isSelected, - selectionMode: widget.selectionMode, - child: Stack( - fit: StackFit.expand, - children: [ - if (cachedInfo != null) - RawImage( - image: cachedInfo.image, - fit: BoxFit.cover, - ) - else if (_imageProvider != null) - Image( - image: _imageProvider!, - fit: BoxFit.cover, - gaplessPlayback: true, - errorBuilder: (context, error, stackTrace) { - return ColoredBox( - color: Colors.grey.shade200, - child: const Center( - child: FaIcon( - FontAwesomeIcons.image, - color: Colors.black26, - ), - ), - ); - }, - ) - else - ColoredBox( - color: Colors.grey.shade200, - child: const Center( - child: FaIcon( - FontAwesomeIcons.image, - color: Colors.black26, - ), + child: SelectableThumbnailComp( + isSelected: widget.isSelected, + selectionMode: widget.selectionMode, + child: Stack( + fit: StackFit.expand, + children: [ + if (cachedInfo != null) + RawImage( + image: cachedInfo.image, + fit: BoxFit.cover, + ) + else if (_imageProvider != null) + Image( + image: _imageProvider!, + fit: BoxFit.cover, + gaplessPlayback: true, + errorBuilder: (context, error, stackTrace) { + return ColoredBox( + color: Colors.grey.shade200, + child: const Center( + child: FaIcon( + FontAwesomeIcons.image, + color: Colors.black26, ), ), - if (isVideo) - const Positioned.fill( - child: Center( - child: FaIcon( - FontAwesomeIcons.circlePlay, - color: Colors.white, - size: 32, - shadows: [ - Shadow(color: Colors.black54, blurRadius: 6), - ], - ), - ), - ), - if (media.mediaFile.isFavorite) - const Positioned( - bottom: 6, - left: 6, - child: Icon( - Icons.favorite, - color: Colors.redAccent, - size: 16, - shadows: [ - Shadow(color: Colors.black54, blurRadius: 4), - ], - ), - ), - ], + ); + }, + ) + else + ColoredBox( + color: Colors.grey.shade200, + child: const Center( + child: FaIcon( + FontAwesomeIcons.image, + color: Colors.black26, + ), + ), ), - ), - ), + if (isVideo) + const Positioned.fill( + child: Center( + child: FaIcon( + FontAwesomeIcons.circlePlay, + color: Colors.white, + size: 32, + shadows: [ + Shadow(color: Colors.black54, blurRadius: 6), + ], + ), + ), + ), + if (media.mediaFile.isFavorite) + const Positioned( + bottom: 6, + left: 6, + child: Icon( + Icons.favorite, + color: Colors.redAccent, + size: 16, + shadows: [ + Shadow(color: Colors.black54, blurRadius: 4), + ], + ), + ), + ], ), ), );