diff --git a/mobile/assets/i18n/en-US.json b/mobile/assets/i18n/en-US.json index bc62a48a61..25220eb269 100644 --- a/mobile/assets/i18n/en-US.json +++ b/mobile/assets/i18n/en-US.json @@ -12,6 +12,10 @@ "album_viewer_appbar_share_leave": "Leave album", "album_viewer_appbar_share_remove": "Remove from album", "album_viewer_page_share_add_users": "Add users", + "asset_list_layout_settings_dynamic_layout_title": "Dynamic layout", + "asset_list_layout_settings_group_by": "Group assets by", + "asset_list_layout_settings_group_by_month_day": "Month + day", + "asset_list_layout_settings_group_by_month": "Month", "asset_list_settings_subtitle": "Photo grid layout settings", "asset_list_settings_title": "Photo Grid", "backup_album_selection_page_albums_device": "Albums on device ({})", @@ -199,4 +203,4 @@ "version_announcement_overlay_text_2": "please take your time to visit the ", "version_announcement_overlay_text_3": " and ensure your docker-compose and .env setup is up-to-date to prevent any misconfigurations, especially if you use WatchTower or any mechanism that handles updating your server application automatically.", "version_announcement_overlay_title": "New Server Version Available \uD83C\uDF89" -} \ No newline at end of file +} diff --git a/mobile/lib/modules/home/ui/asset_grid/asset_grid_data_structure.dart b/mobile/lib/modules/home/ui/asset_grid/asset_grid_data_structure.dart index 9c68cf7cbd..6c652409f1 100644 --- a/mobile/lib/modules/home/ui/asset_grid/asset_grid_data_structure.dart +++ b/mobile/lib/modules/home/ui/asset_grid/asset_grid_data_structure.dart @@ -1,5 +1,6 @@ import 'dart:math'; +import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:immich_mobile/shared/models/asset.dart'; @@ -9,14 +10,15 @@ final log = Logger('AssetGridDataStructure'); enum RenderAssetGridElementType { assetRow, - dayTitle, + groupDividerTitle, monthTitle; } class RenderAssetGridRow { final List assets; + final List widthDistribution; - RenderAssetGridRow(this.assets); + RenderAssetGridRow(this.assets, this.widthDistribution); } class RenderAssetGridElement { @@ -35,19 +37,36 @@ class RenderAssetGridElement { }); } +enum GroupAssetsBy { + day, + month; +} + +class AssetGridLayoutParameters { + final int perRow; + final bool dynamicLayout; + final GroupAssetsBy groupBy; + + AssetGridLayoutParameters( + this.perRow, + this.dynamicLayout, + this.groupBy, + ); +} + class _AssetGroupsToRenderListComputeParameters { final String monthFormat; final String dayFormat; final String dayFormatYear; - final Map> groups; - final int perRow; + final List assets; + final AssetGridLayoutParameters layout; _AssetGroupsToRenderListComputeParameters( this.monthFormat, this.dayFormat, this.dayFormatYear, - this.groups, - this.perRow, + this.assets, + this.layout, ); } @@ -56,62 +75,75 @@ class RenderList { RenderList(this.elements); + static Map> _groupAssets( + List assets, + GroupAssetsBy groupBy, + ) { + assets.sortByCompare( + (e) => e.createdAt, + (a, b) => b.compareTo(a), + ); + + if (groupBy == GroupAssetsBy.day) { + return assets.groupListsBy( + (element) => DateFormat('y-MM-dd').format(element.createdAt.toLocal()), + ); + } else if (groupBy == GroupAssetsBy.month) { + return assets.groupListsBy( + (element) => DateFormat('y-MM').format(element.createdAt.toLocal()), + ); + } + + return {}; + } + static Future _processAssetGroupData( _AssetGroupsToRenderListComputeParameters data, ) async { final monthFormat = DateFormat(data.monthFormat); final dayFormatSameYear = DateFormat(data.dayFormat); final dayFormatOtherYear = DateFormat(data.dayFormatYear); - final groups = data.groups; - final perRow = data.perRow; + final allAssets = data.assets; + final perRow = data.layout.perRow; + final dynamicLayout = data.layout.dynamicLayout; + final groupBy = data.layout.groupBy; List elements = []; DateTime? lastDate; + final groups = _groupAssets(allAssets, groupBy); + groups.forEach((groupName, assets) { try { - final date = DateTime.parse(groupName); - - if (lastDate == null || lastDate!.month != date.month) { - // Month title - - var monthTitleText = groupName; - - var groupDate = DateTime.tryParse(groupName); - if (groupDate != null) { - monthTitleText = monthFormat.format(groupDate); - } else { - log.severe("Failed to format date for day title: $groupName"); - } + final date = assets.first.createdAt.toLocal(); + // Month title + if (groupBy == GroupAssetsBy.day && + (lastDate == null || lastDate!.month != date.month)) { elements.add( RenderAssetGridElement( RenderAssetGridElementType.monthTitle, - title: monthTitleText, + title: monthFormat.format(date), date: date, ), ); } - // Add group title - var currentYear = DateTime.now().year; - var groupYear = DateTime.parse(groupName).year; - var formatDate = - currentYear == groupYear ? dayFormatSameYear : dayFormatOtherYear; + // Group divider title (day or month) + var formatDate = dayFormatOtherYear; - var dateText = groupName; + if (DateTime.now().year == date.year) { + formatDate = dayFormatSameYear; + } - var groupDate = DateTime.tryParse(groupName); - if (groupDate != null) { - dateText = formatDate.format(groupDate); - } else { - log.severe("Failed to format date for day title: $groupName"); + if (groupBy == GroupAssetsBy.month) { + formatDate = monthFormat; } elements.add( RenderAssetGridElement( - RenderAssetGridElementType.dayTitle, - title: dateText, + RenderAssetGridElementType.groupDividerTitle, + title: formatDate.format(date), date: date, relatedAssetList: assets, ), @@ -121,12 +153,37 @@ class RenderList { int cursor = 0; while (cursor < assets.length) { int rowElements = min(assets.length - cursor, perRow); + final rowAssets = assets.sublist(cursor, cursor + rowElements); + + // Default: All assets have the same width + var widthDistribution = List.filled(rowElements, 1.0); + + if (dynamicLayout) { + final aspectRatios = + rowAssets.map((e) => (e.width ?? 1) / (e.height ?? 1)).toList(); + final meanAspectRatio = aspectRatios.sum / rowElements; + + // 1: mean width + // 0.5: width < mean - threshold + // 1.5: width > mean + threshold + final arConfiguration = aspectRatios.map((e) { + if (e - meanAspectRatio > 0.3) return 1.5; + if (e - meanAspectRatio < -0.3) return 0.5; + return 1.0; + }); + + // Normalize: + final sum = arConfiguration.sum; + widthDistribution = + arConfiguration.map((e) => (e * rowElements) / sum).toList(); + } final rowElement = RenderAssetGridElement( RenderAssetGridElementType.assetRow, date: date, assetRow: RenderAssetGridRow( - assets.sublist(cursor, cursor + rowElements), + rowAssets, + widthDistribution, ), ); @@ -143,9 +200,9 @@ class RenderList { return RenderList(elements); } - static Future fromAssetGroups( - Map> assetGroups, - int assetsPerRow, + static Future fromAssets( + List assets, + AssetGridLayoutParameters layout, ) async { // Compute only allows for one parameter. Therefore we pass all parameters in a map return compute( @@ -154,8 +211,8 @@ class RenderList { "monthly_title_text_date_format".tr(), "daily_title_text_date".tr(), "daily_title_text_date_year".tr(), - assetGroups, - assetsPerRow, + assets, + layout, ), ); } diff --git a/mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart b/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart similarity index 94% rename from mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart rename to mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart index 7cee410a19..6a92c9e21f 100644 --- a/mobile/lib/modules/home/ui/asset_grid/daily_title_text.dart +++ b/mobile/lib/modules/home/ui/asset_grid/group_divider_title.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -class DailyTitleText extends ConsumerWidget { - const DailyTitleText({ +class GroupDividerTitle extends ConsumerWidget { + const GroupDividerTitle({ Key? key, required this.text, required this.multiselectEnabled, diff --git a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart index 3db0da6753..c7fdf84836 100644 --- a/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart +++ b/mobile/lib/modules/home/ui/asset_grid/immich_asset_grid.dart @@ -7,7 +7,7 @@ import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart'; import 'package:immich_mobile/shared/models/asset.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'asset_grid_data_structure.dart'; -import 'daily_title_text.dart'; +import 'group_divider_title.dart'; import 'disable_multi_select_button.dart'; import 'draggable_scrollbar_custom.dart'; @@ -99,12 +99,12 @@ class ImmichAssetGridState extends State { widget.margin * (widget.assetsPerRow - 1) / widget.assetsPerRow; return Row( key: Key("asset-row-${row.assets.first.id}"), - children: row.assets.map((Asset asset) { + children: row.assets.mapIndexed((int index, Asset asset) { bool last = asset.id == row.assets.last.id; return Container( key: Key("asset-${asset.id}"), - width: size, + width: size * row.widthDistribution[index], height: size, margin: EdgeInsets.only( top: widget.margin, @@ -123,7 +123,7 @@ class ImmichAssetGridState extends State { String title, List assets, ) { - return DailyTitleText( + return GroupDividerTitle( text: title, multiselectEnabled: widget.selectionActive, onSelect: () => _selectAssets(assets), @@ -150,7 +150,7 @@ class ImmichAssetGridState extends State { Widget _itemBuilder(BuildContext c, int position) { final item = widget.renderList.elements[position]; - if (item.type == RenderAssetGridElementType.dayTitle) { + if (item.type == RenderAssetGridElementType.groupDividerTitle) { return _buildTitle(c, item.title!, item.relatedAssetList!); } else if (item.type == RenderAssetGridElementType.monthTitle) { return _buildMonthTitle(c, item.title!); diff --git a/mobile/lib/modules/home/views/home_page.dart b/mobile/lib/modules/home/views/home_page.dart index a409ce73cf..298fb4e496 100644 --- a/mobile/lib/modules/home/views/home_page.dart +++ b/mobile/lib/modules/home/views/home_page.dart @@ -220,8 +220,8 @@ class HomePage extends HookConsumerWidget { top: true, child: Stack( children: [ - ref.watch(assetProvider).renderList == null || - ref.watch(assetProvider).allAssets.isEmpty + ref.watch(assetProvider).renderList == null + || ref.watch(assetProvider).allAssets.isEmpty ? buildLoadingIndicator() : ImmichAssetGrid( renderList: ref.watch(assetProvider).renderList!, diff --git a/mobile/lib/modules/search/providers/search_result_page.provider.dart b/mobile/lib/modules/search/providers/search_result_page.provider.dart index cbc7633999..102573bcad 100644 --- a/mobile/lib/modules/search/providers/search_result_page.provider.dart +++ b/mobile/lib/modules/search/providers/search_result_page.provider.dart @@ -1,4 +1,3 @@ -import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/asset_grid_data_structure.dart'; import 'package:immich_mobile/modules/search/models/search_result_page_state.model.dart'; @@ -7,7 +6,6 @@ import 'package:immich_mobile/modules/search/services/search.service.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/models/asset.dart'; -import 'package:intl/intl.dart'; class SearchResultPageNotifier extends StateNotifier { SearchResultPageNotifier(this._searchService) @@ -56,23 +54,16 @@ final searchResultPageProvider = return SearchResultPageNotifier(ref.watch(searchServiceProvider)); }); -final searchResultGroupByDateTimeProvider = StateProvider((ref) { - var assets = ref.watch(searchResultPageProvider).searchResult; - - assets.sortByCompare( - (e) => e.createdAt, - (a, b) => b.compareTo(a), - ); - return assets.groupListsBy( - (element) => DateFormat('y-MM-dd').format(element.createdAt.toLocal()), - ); -}); - final searchRenderListProvider = FutureProvider((ref) { - var assetGroups = ref.watch(searchResultGroupByDateTimeProvider); - var settings = ref.watch(appSettingsServiceProvider); - final assetsPerRow = settings.getSetting(AppSettingsEnum.tilesPerRow); - return RenderList.fromAssetGroups(assetGroups, assetsPerRow); + final assets = ref.watch(searchResultPageProvider).searchResult; + + final layout = AssetGridLayoutParameters( + settings.getSetting(AppSettingsEnum.tilesPerRow), + settings.getSetting(AppSettingsEnum.dynamicLayout), + GroupAssetsBy.values[settings.getSetting(AppSettingsEnum.groupAssetsBy)], + ); + + return RenderList.fromAssets(assets, layout); }); diff --git a/mobile/lib/modules/settings/services/app_settings.service.dart b/mobile/lib/modules/settings/services/app_settings.service.dart index 67bfedf774..d2f4b10648 100644 --- a/mobile/lib/modules/settings/services/app_settings.service.dart +++ b/mobile/lib/modules/settings/services/app_settings.service.dart @@ -6,6 +6,8 @@ enum AppSettingsEnum { loadOriginal("loadOriginal", false), themeMode("themeMode", "system"), // "light","dark","system" tilesPerRow("tilesPerRow", 4), + dynamicLayout("dynamicLayout", false), + groupAssetsBy("groupBy", 0), uploadErrorNotificationGracePeriod( "uploadErrorNotificationGracePeriod", 2, diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart new file mode 100644 index 0000000000..dec1f09f4c --- /dev/null +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart @@ -0,0 +1,99 @@ +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/asset_grid/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'; + +class LayoutSettings extends HookConsumerWidget { + const LayoutSettings({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final appSettingService = ref.watch(appSettingsServiceProvider); + + final useDynamicLayout = useState(true); + final groupBy = useState(GroupAssetsBy.day); + + void switchChanged(bool value) { + appSettingService.setSetting(AppSettingsEnum.dynamicLayout, value); + useDynamicLayout.value = value; + ref.watch(assetProvider.notifier).rebuildAssetGridDataStructure(); + } + + void changeGroupValue(GroupAssetsBy? value) { + if (value != null) { + appSettingService.setSetting(AppSettingsEnum.groupAssetsBy, value.index); + groupBy.value = value; + ref.watch(assetProvider.notifier).rebuildAssetGridDataStructure(); + } + } + + useEffect( + () { + useDynamicLayout.value = + appSettingService.getSetting(AppSettingsEnum.dynamicLayout); + groupBy.value = + GroupAssetsBy.values[appSettingService.getSetting(AppSettingsEnum.groupAssetsBy)]; + + return null; + }, + [], + ); + + return Column( + children: [ + SwitchListTile.adaptive( + activeColor: Theme.of(context).primaryColor, + title: const Text( + "asset_list_layout_settings_dynamic_layout_title", + style: TextStyle( + fontSize: 12, + ), + ).tr(), + onChanged: switchChanged, + value: useDynamicLayout.value, + ), + ListTile( + title: const Text( + "asset_list_layout_settings_group_by", + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ).tr(), + ), + RadioListTile( + activeColor: Theme.of(context).primaryColor, + title: const Text( + "asset_list_layout_settings_group_by_month_day", + style: TextStyle( + fontSize: 12, + ), + ).tr(), + value: GroupAssetsBy.day, + groupValue: groupBy.value, + onChanged: changeGroupValue, + controlAffinity: ListTileControlAffinity.trailing, + ), + RadioListTile( + activeColor: Theme.of(context).primaryColor, + title: const Text( + "asset_list_layout_settings_group_by_month", + style: TextStyle( + fontSize: 12, + ), + ).tr(), + value: GroupAssetsBy.month, + groupValue: groupBy.value, + onChanged: changeGroupValue, + controlAffinity: ListTileControlAffinity.trailing, + ), + ], + ); + } +} diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_settings.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_settings.dart index 350022fcbf..ef7afb0432 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_settings.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_settings.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:immich_mobile/modules/settings/ui/asset_list_settings/asset_list_layout_settings.dart'; import 'package:immich_mobile/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart'; import 'asset_list_tiles_per_row.dart'; @@ -27,6 +28,7 @@ class AssetListSettings extends StatelessWidget { children: const [ TilesPerRow(), StorageIndicator(), + LayoutSettings(), ], ); } diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart index 44301447d4..9cd8ee5e9c 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_storage_indicator.dart @@ -20,8 +20,7 @@ class StorageIndicator extends HookConsumerWidget { void switchChanged(bool value) { appSettingService.setSetting(AppSettingsEnum.storageIndicator, value); showStorageIndicator.value = value; - - ref.invalidate(assetProvider); + ref.watch(assetProvider.notifier).rebuildAssetGridDataStructure(); } useEffect( diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart index 80b18ca96c..5e25dfce4f 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart @@ -23,8 +23,7 @@ class TilesPerRow extends HookConsumerWidget { } void sliderChangedEnd(double _) { - ref.invalidate(assetProvider); - ref.watch(assetProvider.notifier).getAllAsset(); + ref.watch(assetProvider.notifier).rebuildAssetGridDataStructure(); } useEffect( diff --git a/mobile/lib/shared/providers/asset.provider.dart b/mobile/lib/shared/providers/asset.provider.dart index 1f90f07763..c124418943 100644 --- a/mobile/lib/shared/providers/asset.provider.dart +++ b/mobile/lib/shared/providers/asset.provider.dart @@ -25,11 +25,15 @@ class AssetsState { AssetsState(this.allAssets, {this.renderList}); - Future withRenderDataStructure(int groupSize) async { + Future withRenderDataStructure( + AssetGridLayoutParameters layout, + ) async { return AssetsState( allAssets, - renderList: - await RenderList.fromAssetGroups(await _groupByDate(), groupSize), + renderList: await RenderList.fromAssets( + allAssets, + layout, + ), ); } @@ -37,20 +41,6 @@ class AssetsState { return AssetsState([...allAssets, ...toAdd]); } - Future>> _groupByDate() async { - sortCompare(List assets) { - assets.sortByCompare( - (e) => e.createdAt, - (a, b) => b.compareTo(a), - ); - return assets.groupListsBy( - (element) => DateFormat('y-MM-dd').format(element.createdAt.toLocal()), - ); - } - - return await compute(sortCompare, allAssets.toList()); - } - static AssetsState fromAssetList(List assets) { return AssetsState(assets); } @@ -91,10 +81,19 @@ class AssetNotifier extends StateNotifier { _assetCacheService.put(newAssetList); } - state = - await AssetsState.fromAssetList(newAssetList).withRenderDataStructure( + final layout = AssetGridLayoutParameters( _settingsService.getSetting(AppSettingsEnum.tilesPerRow), + _settingsService.getSetting(AppSettingsEnum.dynamicLayout), + GroupAssetsBy.values[_settingsService.getSetting(AppSettingsEnum.groupAssetsBy)], ); + + state = await AssetsState.fromAssetList(newAssetList) + .withRenderDataStructure(layout); + } + + // Just a little helper to trigger a rebuild of the state object + Future rebuildAssetGridDataStructure() async { + await _updateAssetsState(state.allAssets, cache: false); } getAllAsset() async { diff --git a/mobile/test/asset_grid_data_structure_test.dart b/mobile/test/asset_grid_data_structure_test.dart index 20aa2b64d3..6b715d20b4 100644 --- a/mobile/test/asset_grid_data_structure_test.dart +++ b/mobile/test/asset_grid_data_structure_test.dart @@ -25,46 +25,61 @@ void main() { ); } - final Map> groups = { - '2022-01-05': testAssets.sublist(0, 5).map((e) { + final List assets = []; + + assets.addAll( + testAssets.sublist(0, 5).map((e) { e.createdAt = DateTime(2022, 1, 5); return e; }).toList(), - '2022-01-10': testAssets.sublist(5, 10).map((e) { + ); + assets.addAll( + testAssets.sublist(5, 10).map((e) { e.createdAt = DateTime(2022, 1, 10); return e; }).toList(), - '2022-02-17': testAssets.sublist(10, 15).map((e) { + ); + assets.addAll( + testAssets.sublist(10, 15).map((e) { e.createdAt = DateTime(2022, 2, 17); return e; }).toList(), - '2022-10-15': testAssets.sublist(15, 30).map((e) { + ); + assets.addAll( + testAssets.sublist(15, 30).map((e) { e.createdAt = DateTime(2022, 10, 15); return e; - }).toList() - }; + }).toList(), + ); group('Test grouped', () { test('test grouped check months', () async { - final renderList = await RenderList.fromAssetGroups(groups, 3); + final renderList = await RenderList.fromAssets( + assets, + AssetGridLayoutParameters( + 3, + false, + GroupAssetsBy.day, + ), + ); - // Jan - // Day 1 - // 5 Assets => 2 Rows - // Day 2 - // 5 Assets => 2 Rows - // Feb - // Day 1 - // 5 Assets => 2 Rows // Oct // Day 1 // 15 Assets => 5 Rows + // Feb + // Day 1 + // 5 Assets => 2 Rows + // Jan + // Day 2 + // 5 Assets => 2 Rows + // Day 1 + // 5 Assets => 2 Rows expect(renderList.elements.length, 18); expect( renderList.elements[0].type, RenderAssetGridElementType.monthTitle, ); - expect(renderList.elements[0].date.month, 1); + expect(renderList.elements[0].date.month, 10); expect( renderList.elements[7].type, RenderAssetGridElementType.monthTitle, @@ -74,38 +89,44 @@ void main() { renderList.elements[11].type, RenderAssetGridElementType.monthTitle, ); - expect(renderList.elements[11].date.month, 10); + expect(renderList.elements[11].date.month, 1); }); test('test grouped check types', () async { - final renderList = await RenderList.fromAssetGroups(groups, 5); + final renderList = await RenderList.fromAssets( + assets, + AssetGridLayoutParameters( + 5, + false, + GroupAssetsBy.day, + ), + ); - // Jan - // Day 1 - // 5 Assets - // Day 2 - // 5 Assets - // Feb - // Day 1 - // 5 Assets // Oct // Day 1 // 15 Assets => 3 Rows - + // Feb + // Day 1 + // 5 Assets => 1 Row + // Jan + // Day 2 + // 5 Assets => 1 Row + // Day 1 + // 5 Assets => 1 Row final types = [ RenderAssetGridElementType.monthTitle, - RenderAssetGridElementType.dayTitle, + RenderAssetGridElementType.groupDividerTitle, + RenderAssetGridElementType.assetRow, RenderAssetGridElementType.assetRow, - RenderAssetGridElementType.dayTitle, RenderAssetGridElementType.assetRow, RenderAssetGridElementType.monthTitle, - RenderAssetGridElementType.dayTitle, + RenderAssetGridElementType.groupDividerTitle, RenderAssetGridElementType.assetRow, RenderAssetGridElementType.monthTitle, - RenderAssetGridElementType.dayTitle, + RenderAssetGridElementType.groupDividerTitle, RenderAssetGridElementType.assetRow, + RenderAssetGridElementType.groupDividerTitle, RenderAssetGridElementType.assetRow, - RenderAssetGridElementType.assetRow ]; expect(renderList.elements.length, types.length);