simplified code across the app and consolidated duplicated helpers

This commit is contained in:
2026-09-27 17:29:54 +02:00
parent 3e856d0b1c
commit ee1240f71a
155 changed files with 1772 additions and 2546 deletions
+10 -46
View File
@@ -11,10 +11,10 @@ import '../../../state/app/infrastructure/loadable_state/view/loadable_state_con
import '../../../state/app/infrastructure/utility_widgets/bloc_module.dart';
import '../../../state/app/modules/files/bloc/files_bloc.dart';
import '../../../state/app/modules/files/bloc/files_state.dart';
import '../../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../../utils/cache_invalidation_bus.dart';
import '../../../widget/placeholder_view.dart';
import 'data/sort_options.dart';
import 'data/file_sort.dart';
import 'data/webdav_path.dart';
import 'files_upload_dialog.dart';
import 'search/files_search_delegate.dart';
import 'widgets/add_file_menu.dart';
@@ -44,9 +44,6 @@ class _FilesView extends StatefulWidget {
}
class _FilesViewState extends State<_FilesView> {
late final SettingsCubit settings;
late SortOption currentSort;
late bool currentSortDirection;
late final StreamSubscription<String> _invalidationSub;
// The list builder also runs for loading flips and parent rebuilds; only a
@@ -54,32 +51,16 @@ class _FilesViewState extends State<_FilesView> {
Object? _sortedKey;
List<CacheableFile> _sortedFiles = const [];
List<CacheableFile> _sorted(ListFilesResponse listing, bool foldersToTop) {
final key = (listing, currentSort, currentSortDirection, foldersToTop);
List<CacheableFile> _sorted(ListFilesResponse listing, FileSort sort) {
final key = (listing, sort);
if (key == _sortedKey) return _sortedFiles;
_sortedKey = key;
return _sortedFiles = listing.sortBy(
sortOption: currentSort,
foldersToTop: foldersToTop,
reversed: currentSortDirection,
);
return _sortedFiles = listing.sortedBy(sort);
}
// Cache key in FilesBloc's pathString format: '/' for root, otherwise
// segments joined without leading/trailing slash.
String get _myPathString => widget.path.isEmpty ? '/' : widget.path.join('/');
// Relative folder path matching the WebDAV format used by `CacheableFile.path`
// (no leading slash; trailing slash for non-root). Empty string means root.
String get _currentFolderPath =>
widget.path.isEmpty ? '' : '${widget.path.join('/')}/';
@override
void initState() {
super.initState();
settings = context.read<SettingsCubit>();
currentSort = settings.val().fileSettings.sortBy;
currentSortDirection = settings.val().fileSettings.ascending;
_invalidationSub = CacheInvalidationBus.listFilesStream.listen(
_onInvalidation,
);
@@ -87,7 +68,7 @@ class _FilesViewState extends State<_FilesView> {
void _onInvalidation(String invalidatedPath) {
if (!mounted) return;
if (invalidatedPath != _myPathString) return;
if (invalidatedPath != listFilesCacheKey(widget.path)) return;
context.read<FilesBloc>().refresh();
}
@@ -118,29 +99,12 @@ class _FilesViewState extends State<_FilesView> {
final bloc = context.read<FilesBloc>();
// Selected here, not in the LoadableStateConsumer child: that closure runs
// during the consumer's build, where this context may not subscribe.
final foldersToTop = context.select(
(SettingsCubit c) => c.state.fileSettings.sortFoldersToTop,
);
final sort = context.select(fileSortOf);
return Scaffold(
appBar: AppBar(
title: Text(widget.path.isNotEmpty ? widget.path.last : 'Dateien'),
actions: [
FilesSortActions(
currentSort: currentSort,
ascending: currentSortDirection,
onDirectionChanged: (e) {
setState(() {
currentSortDirection = e;
settings.val(write: true).fileSettings.ascending = e;
});
},
onSortChanged: (e) {
setState(() {
currentSort = e;
settings.val(write: true).fileSettings.sortBy = e;
});
},
),
const FilesSortActions(),
IconButton(
tooltip: 'Suchen',
icon: const Icon(Icons.search),
@@ -162,7 +126,7 @@ class _FilesViewState extends State<_FilesView> {
body: Column(
children: [
ClipboardBanner(
currentFolder: _currentFolderPath,
currentFolder: webdavFolderPath(widget.path),
onPasteDone: bloc.refresh,
),
Expanded(
@@ -176,7 +140,7 @@ class _FilesViewState extends State<_FilesView> {
text: 'Der Ordner ist leer',
);
}
final files = _sorted(listing, foldersToTop);
final files = _sorted(listing, sort);
return ListView.builder(
padding: EdgeInsets.zero,
itemCount: files.length,