💄 Optimize waterfall file list design

This commit is contained in:
2025-11-15 15:54:13 +08:00
parent 07f191171c
commit 1ab7295918

View File

@@ -11,6 +11,7 @@ import 'package:island/models/file.dart';
import 'package:island/pods/file_list.dart'; import 'package:island/pods/file_list.dart';
import 'package:island/pods/network.dart'; import 'package:island/pods/network.dart';
import 'package:island/services/file_uploader.dart'; import 'package:island/services/file_uploader.dart';
import 'package:island/services/responsive.dart';
import 'package:island/utils/file_icon_utils.dart'; import 'package:island/utils/file_icon_utils.dart';
import 'package:island/utils/format.dart'; import 'package:island/utils/format.dart';
import 'package:island/widgets/alert.dart'; import 'package:island/widgets/alert.dart';
@@ -218,15 +219,14 @@ class FileListView extends HookConsumerWidget {
const Gap(8), const Gap(8),
_buildPathNavigation(ref, currentPath), _buildPathNavigation(ref, currentPath),
const Gap(8), const Gap(8),
if (mode.value == FileListMode.normal && currentPath.value == '/')
_buildUnindexedFilesEntry(ref).padding(bottom: 12),
Expanded( Expanded(
child: CustomScrollView( child: CustomScrollView(
slivers: [ slivers: [bodyWidget, const SliverGap(12)],
bodyWidget, ).padding(
const SliverGap(12), horizontal:
if (mode.value == FileListMode.normal && viewMode.value == FileListViewMode.waterfall ? 12 : null,
currentPath.value == '/')
SliverToBoxAdapter(child: _buildUnindexedFilesEntry(ref)),
],
), ),
), ),
], ],
@@ -244,18 +244,34 @@ class FileListView extends HookConsumerWidget {
ValueNotifier<String> currentPath, ValueNotifier<String> currentPath,
ValueNotifier<FileListViewMode> currentViewMode, ValueNotifier<FileListViewMode> currentViewMode,
) { ) {
return switch (currentViewMode.value) { // Check if all files are images
final fileItems = items.whereType<FileItem>();
final allFilesAreImages =
fileItems.isNotEmpty &&
fileItems.every(
(fileItem) =>
fileItem.fileIndex.file.mimeType?.startsWith('image/') == true,
);
return switch (allFilesAreImages
? FileListViewMode.waterfall
: currentViewMode.value) {
// Waterfall mode
FileListViewMode.waterfall => SliverMasonryGrid( FileListViewMode.waterfall => SliverMasonryGrid(
gridDelegate: const SliverSimpleGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverSimpleGridDelegateWithMaxCrossAxisExtent(
crossAxisCount: 3, maxCrossAxisExtent: isWideScreen(context) ? 340 : 240,
), ),
mainAxisSpacing: 8,
crossAxisSpacing: 8, crossAxisSpacing: 8,
mainAxisSpacing: 8,
delegate: SliverChildBuilderDelegate((context, index) { delegate: SliverChildBuilderDelegate((context, index) {
if (index == widgetCount - 1) { if (index == widgetCount - 1) {
return endItemView; return endItemView;
} }
if (index >= items.length) {
return const SizedBox.shrink();
}
final item = items[index]; final item = items[index];
return item.map( return item.map(
file: (fileItem) => _buildWaterfallFileTile(fileItem, ref, context), file: (fileItem) => _buildWaterfallFileTile(fileItem, ref, context),
@@ -267,8 +283,9 @@ class FileListView extends HookConsumerWidget {
return const SizedBox.shrink(); return const SizedBox.shrink();
}, },
); );
}), }, childCount: widgetCount),
), ),
// ListView mode
_ => SliverList.builder( _ => SliverList.builder(
itemCount: widgetCount, itemCount: widgetCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
@@ -721,6 +738,7 @@ class FileListView extends HookConsumerWidget {
BuildContext context, BuildContext context,
) { ) {
return InkWell( return InkWell(
borderRadius: BorderRadius.circular(8),
onTap: () { onTap: () {
final newPath = final newPath =
currentPath.value == '/' currentPath.value == '/'
@@ -731,14 +749,16 @@ class FileListView extends HookConsumerWidget {
child: Container( child: Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
color: Theme.of(context).colorScheme.outline.withOpacity(0.3), color: Theme.of(context).colorScheme.outline.withOpacity(0.3),
), ),
), ),
child: AspectRatio(
aspectRatio: 1,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(
Symbols.folder, Symbols.folder,
@@ -759,6 +779,7 @@ class FileListView extends HookConsumerWidget {
], ],
), ),
), ),
),
); );
} }