Browse Source

Merge pull request #266 from provokateurin/feature/sort-files

Sort files
pull/268/head
Kate 2 years ago committed by GitHub
parent
commit
f2287a07ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      packages/neon/neon/lib/l10n/en.arb
  2. 24
      packages/neon/neon/lib/l10n/localizations.dart
  3. 12
      packages/neon/neon/lib/l10n/localizations_en.dart
  4. 2
      packages/neon/neon_files/lib/neon_files.dart
  5. 31
      packages/neon/neon_files/lib/options.dart
  6. 13
      packages/neon/neon_files/lib/sort/files.dart
  7. 19
      packages/neon/neon_files/lib/widgets/browser_view.dart
  8. 2
      packages/neon/neon_files/pubspec.yaml

4
packages/neon/neon/lib/l10n/en.arb

@ -194,6 +194,10 @@
}
}
},
"filesOptionsFilesSortPropertyName": "Name",
"filesOptionsFilesSortPropertyModifiedDate": "Last modified",
"filesOptionsFilesSortPropertySize": "Size",
"filesOptionsFilesSortOrder": "Sort order of files",
"filesOptionsShowPreviews": "Show previews for files",
"filesOptionsUploadQueueParallelism": "Upload queue parallelism",
"filesOptionsDownloadQueueParallelism": "Download queue parallelism",

24
packages/neon/neon/lib/l10n/localizations.dart

@ -731,6 +731,30 @@ abstract class AppLocalizations {
/// **'Are you sure you want to download a file that is bigger than {warningSize} ({actualSize})?'**
String filesConfirmDownloadSizeWarning(String warningSize, String actualSize);
/// No description provided for @filesOptionsFilesSortPropertyName.
///
/// In en, this message translates to:
/// **'Name'**
String get filesOptionsFilesSortPropertyName;
/// No description provided for @filesOptionsFilesSortPropertyModifiedDate.
///
/// In en, this message translates to:
/// **'Last modified'**
String get filesOptionsFilesSortPropertyModifiedDate;
/// No description provided for @filesOptionsFilesSortPropertySize.
///
/// In en, this message translates to:
/// **'Size'**
String get filesOptionsFilesSortPropertySize;
/// No description provided for @filesOptionsFilesSortOrder.
///
/// In en, this message translates to:
/// **'Sort order of files'**
String get filesOptionsFilesSortOrder;
/// No description provided for @filesOptionsShowPreviews.
///
/// In en, this message translates to:

12
packages/neon/neon/lib/l10n/localizations_en.dart

@ -366,6 +366,18 @@ class AppLocalizationsEn extends AppLocalizations {
return 'Are you sure you want to download a file that is bigger than $warningSize ($actualSize)?';
}
@override
String get filesOptionsFilesSortPropertyName => 'Name';
@override
String get filesOptionsFilesSortPropertyModifiedDate => 'Last modified';
@override
String get filesOptionsFilesSortPropertySize => 'Size';
@override
String get filesOptionsFilesSortOrder => 'Sort order of files';
@override
String get filesOptionsShowPreviews => 'Show previews for files';

2
packages/neon/neon_files/lib/neon_files.dart

@ -21,6 +21,7 @@ import 'package:provider/provider.dart';
import 'package:queue/queue.dart';
import 'package:rxdart/rxdart.dart';
import 'package:settings/settings.dart';
import 'package:sort_box/sort_box.dart';
part 'blocs/browser.dart';
part 'blocs/files.dart';
@ -31,6 +32,7 @@ part 'models/file_details.dart';
part 'options.dart';
part 'pages/details.dart';
part 'pages/main.dart';
part 'sort/files.dart';
part 'utils/download_task.dart';
part 'utils/upload_task.dart';
part 'widgets/browser_view.dart';

31
packages/neon/neon_files/lib/options.dart

@ -6,6 +6,8 @@ class FilesAppSpecificOptions extends NextcloudAppSpecificOptions {
generalCategory,
];
super.options = [
filesSortPropertyOption,
filesSortBoxOrderOption,
showPreviewsOption,
uploadQueueParallelism,
downloadQueueParallelism,
@ -18,6 +20,29 @@ class FilesAppSpecificOptions extends NextcloudAppSpecificOptions {
name: (final context) => AppLocalizations.of(context).optionsCategoryGeneral,
);
late final filesSortPropertyOption = SelectOption<FilesSortProperty>(
storage: super.storage,
category: generalCategory,
key: 'files-sort-property',
label: (final context) => AppLocalizations.of(context).newsOptionsArticlesSortProperty,
defaultValue: BehaviorSubject.seeded(FilesSortProperty.name),
values: BehaviorSubject.seeded({
FilesSortProperty.name: (final context) => AppLocalizations.of(context).filesOptionsFilesSortPropertyName,
FilesSortProperty.modifiedDate: (final context) =>
AppLocalizations.of(context).filesOptionsFilesSortPropertyModifiedDate,
FilesSortProperty.size: (final context) => AppLocalizations.of(context).filesOptionsFilesSortPropertySize,
}),
);
late final filesSortBoxOrderOption = SelectOption<SortBoxOrder>(
storage: super.storage,
category: generalCategory,
key: 'files-sort-box-order',
label: (final context) => AppLocalizations.of(context).filesOptionsFilesSortOrder,
defaultValue: BehaviorSubject.seeded(SortBoxOrder.ascending),
values: BehaviorSubject.seeded(sortBoxOrderOptionValues),
);
late final showPreviewsOption = ToggleOption(
storage: super.storage,
category: generalCategory,
@ -87,3 +112,9 @@ class FilesAppSpecificOptions extends NextcloudAppSpecificOptions {
values: BehaviorSubject.seeded(_sizeWarningValues),
);
}
enum FilesSortProperty {
name,
modifiedDate,
size,
}

13
packages/neon/neon_files/lib/sort/files.dart

@ -0,0 +1,13 @@
part of '../neon_files.dart';
final filesSortBox = SortBox<FilesSortProperty, WebDavFile>(
{
FilesSortProperty.name: (final file) => file.name.toLowerCase(),
FilesSortProperty.modifiedDate: (final file) => file.lastModified?.millisecondsSinceEpoch ?? 0,
FilesSortProperty.size: (final file) => file.size ?? 0,
},
{
FilesSortProperty.modifiedDate: Box(FilesSortProperty.name, SortBoxOrder.ascending),
FilesSortProperty.size: Box(FilesSortProperty.name, SortBoxOrder.ascending),
},
);

19
packages/neon/neon_files/lib/widgets/browser_view.dart

@ -71,16 +71,20 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
child: const Icon(Icons.add),
)
: null,
body: NeonListView<Widget>(
body: SortBoxBuilder<FilesSortProperty, WebDavFile>(
sortBox: filesSortBox,
sortPropertyOption: widget.bloc.options.filesSortPropertyOption,
sortBoxOrderOption: widget.bloc.options.filesSortBoxOrderOption,
input: files.data,
builder: (final context, final sorted) => NeonListView<Widget>(
scrollKey: 'files-${pathSnapshot.data!.join('/')}',
withFloatingActionButton: true,
items: [
for (final uploadTask in files.data == null
for (final uploadTask in sorted == null
? <UploadTask>[]
: uploadTasksSnapshot.data!.where(
(final task) => files.data!
.where((final file) => _pathMatchesFile(task.path, file.name))
.isEmpty,
(final task) =>
sorted.where((final file) => _pathMatchesFile(task.path, file.name)).isEmpty,
)) ...[
StreamBuilder<int>(
stream: uploadTask.progress,
@ -104,8 +108,8 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
),
),
],
if (files.data != null) ...[
for (final file in files.data!) ...[
if (sorted != null) ...[
for (final file in sorted) ...[
if (!widget.onlyShowDirectories || file.isDirectory) ...[
Builder(
builder: (final context) {
@ -199,6 +203,7 @@ class _FilesBrowserViewState extends State<FilesBrowserView> {
),
),
),
),
);
bool _pathMatchesFile(final List<String> path, final String name) => const ListEquality().equals(

2
packages/neon/neon_files/pubspec.yaml

@ -28,6 +28,8 @@ dependencies:
rxdart: ^0.27.7
settings:
path: ../../settings
sort_box:
path: ../../sort_box
dev_dependencies:
nit_picking:

Loading…
Cancel
Save