diff --git a/mobile/lib/modules/album/views/album_viewer_page.dart b/mobile/lib/modules/album/views/album_viewer_page.dart index c525c9922b..5ebd2a11d1 100644 --- a/mobile/lib/modules/album/views/album_viewer_page.dart +++ b/mobile/lib/modules/album/views/album_viewer_page.dart @@ -1,9 +1,12 @@ +import 'dart:math'; + import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/home/ui/draggable_scrollbar.dart'; +import 'package:immich_mobile/modules/home/ui/asset_list_v2/asset_grid_data_structure.dart'; +import 'package:immich_mobile/modules/home/ui/asset_list_v2/immich_asset_grid.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/album/models/asset_selection_page_result.model.dart'; import 'package:immich_mobile/modules/album/providers/asset_selection.provider.dart'; @@ -12,12 +15,10 @@ import 'package:immich_mobile/modules/album/services/album.service.dart'; import 'package:immich_mobile/modules/album/ui/album_action_outlined_button.dart'; import 'package:immich_mobile/modules/album/ui/album_viewer_appbar.dart'; import 'package:immich_mobile/modules/album/ui/album_viewer_editable_title.dart'; -import 'package:immich_mobile/modules/album/ui/album_viewer_thumbnail.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/ui/immich_loading_indicator.dart'; -import 'package:immich_mobile/shared/ui/immich_sliver_persistent_app_bar_delegate.dart'; import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; import 'package:openapi/api.dart'; @@ -28,6 +29,7 @@ class AlbumViewerPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final appSettingService = ref.watch(appSettingsServiceProvider); FocusNode titleFocusNode = useFocusNode(); ScrollController scrollController = useScrollController(); var albumInfo = ref.watch(sharedAlbumDetailProvider(albumId)); @@ -188,34 +190,17 @@ class AlbumViewerPage extends HookConsumerWidget { } Widget _buildImageGrid(AlbumResponseDto albumInfo) { - final appSettingService = ref.watch(appSettingsServiceProvider); + final assetsPerRow = + appSettingService.getSetting(AppSettingsEnum.tilesPerRow); final bool showStorageIndicator = appSettingService.getSetting(AppSettingsEnum.storageIndicator); + final renderList = assetsToRenderList(albumInfo.assets, assetsPerRow); - if (albumInfo.assets.isNotEmpty) { - return SliverPadding( - padding: const EdgeInsets.only(top: 10.0), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: - appSettingService.getSetting(AppSettingsEnum.tilesPerRow), - crossAxisSpacing: 5.0, - mainAxisSpacing: 5, - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - return AlbumViewerThumbnail( - asset: albumInfo.assets[index], - assetList: albumInfo.assets, - showStorageIndicator: showStorageIndicator, - ); - }, - childCount: albumInfo.assetCount, - ), - ), - ); - } - return const SliverToBoxAdapter(); + return ImmichAssetGrid( + assetsPerRow: assetsPerRow, + renderList: renderList, + showStorageIndicator: showStorageIndicator, + ); } Widget _buildControlButton(AlbumResponseDto albumInfo) { @@ -248,29 +233,7 @@ class AlbumViewerPage extends HookConsumerWidget { onTap: () { titleFocusNode.unfocus(); }, - child: DraggableScrollbar.semicircle( - backgroundColor: Theme.of(context).hintColor, - controller: scrollController, - heightScrollThumb: 48.0, - child: CustomScrollView( - controller: scrollController, - slivers: [ - _buildHeader(albumInfo), - SliverPersistentHeader( - pinned: true, - delegate: ImmichSliverPersistentAppBarDelegate( - minHeight: 50, - maxHeight: 50, - child: Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: _buildControlButton(albumInfo), - ), - ), - ), - _buildImageGrid(albumInfo) - ], - ), - ), + child: _buildImageGrid(albumInfo), ); } diff --git a/mobile/lib/modules/home/providers/home_page_render_list_provider.dart b/mobile/lib/modules/home/providers/home_page_render_list_provider.dart index edb6733624..a0e4c1eef7 100644 --- a/mobile/lib/modules/home/providers/home_page_render_list_provider.dart +++ b/mobile/lib/modules/home/providers/home_page_render_list_provider.dart @@ -1,38 +1,10 @@ import 'dart:math'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/modules/home/ui/asset_list_v2/asset_grid_data_structure.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; import 'package:immich_mobile/shared/providers/asset.provider.dart'; -import 'package:openapi/api.dart'; - -enum RenderAssetGridElementType { - assetRow, - dayTitle, - monthTitle; -} - -class RenderAssetGridRow { - final List assets; - - RenderAssetGridRow(this.assets); -} - -class RenderAssetGridElement { - final RenderAssetGridElementType type; - final RenderAssetGridRow? assetRow; - final String? title; - final DateTime date; - final List? relatedAssetList; - - RenderAssetGridElement( - this.type, { - this.assetRow, - this.title, - required this.date, - this.relatedAssetList, - }); -} final renderListProvider = StateProvider((ref) { var assetGroups = ref.watch(assetGroupByDateTimeProvider); diff --git a/mobile/lib/modules/home/ui/asset_list_v2/asset_grid_data_structure.dart b/mobile/lib/modules/home/ui/asset_list_v2/asset_grid_data_structure.dart new file mode 100644 index 0000000000..c008680eb1 --- /dev/null +++ b/mobile/lib/modules/home/ui/asset_list_v2/asset_grid_data_structure.dart @@ -0,0 +1,55 @@ +import 'dart:math'; + +import 'package:openapi/api.dart'; + +enum RenderAssetGridElementType { + assetRow, + dayTitle, + monthTitle; +} + +class RenderAssetGridRow { + final List assets; + + RenderAssetGridRow(this.assets); +} + +class RenderAssetGridElement { + final RenderAssetGridElementType type; + final RenderAssetGridRow? assetRow; + final String? title; + final DateTime date; + final List? relatedAssetList; + + RenderAssetGridElement( + this.type, { + this.assetRow, + this.title, + required this.date, + this.relatedAssetList, + }); +} + +List assetsToRenderList( + List assets, int assetsPerRow) { + List elements = []; + + int cursor = 0; + while (cursor < assets.length) { + int rowElements = min(assets.length - cursor, assetsPerRow); + final date = DateTime.parse(assets[cursor].createdAt); + + final rowElement = RenderAssetGridElement( + RenderAssetGridElementType.assetRow, + date: date, + assetRow: RenderAssetGridRow( + assets.sublist(cursor, cursor + rowElements), + ), + ); + + elements.add(rowElement); + cursor += rowElements; + } + + return elements; +} diff --git a/mobile/lib/modules/home/ui/asset_list_v2/immich_asset_grid.dart b/mobile/lib/modules/home/ui/asset_list_v2/immich_asset_grid.dart index 4a085f3bf2..2916e5f423 100644 --- a/mobile/lib/modules/home/ui/asset_list_v2/immich_asset_grid.dart +++ b/mobile/lib/modules/home/ui/asset_list_v2/immich_asset_grid.dart @@ -7,13 +7,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/home/providers/home_page_render_list_provider.dart'; import 'package:immich_mobile/modules/home/ui/asset_list_v2/daily_title_text.dart'; import 'package:immich_mobile/modules/home/ui/asset_list_v2/draggable_scrollbar_custom.dart'; import 'package:openapi/api.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import '../thumbnail_image.dart'; +import 'asset_grid_data_structure.dart'; class ImmichAssetGrid extends HookConsumerWidget { final ItemScrollController _itemScrollController = ItemScrollController();