diff --git a/lib/components/home/preview_card.dart b/lib/components/home/preview_card.dart index 0d56b51757..a8abd7b39e 100644 --- a/lib/components/home/preview_card.dart +++ b/lib/components/home/preview_card.dart @@ -78,6 +78,7 @@ class _PreviewCardState extends State { @override Widget build(BuildContext context) { + expanded.value = widget.selected; final theme = Theme.of(context); final colorScheme = theme.colorScheme; final disableAnimations = MediaQuery.disableAnimationsOf(context); diff --git a/lib/components/home/select_all_button.dart b/lib/components/home/select_all_button.dart new file mode 100644 index 0000000000..e0675346d8 --- /dev/null +++ b/lib/components/home/select_all_button.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; +import 'package:saber/i18n/strings.g.dart'; + +class SelectAllNotesButton extends StatelessWidget { + const SelectAllNotesButton({ + super.key, + required this.selectedFiles, + required this.allFiles, + required this.selectAll, + required this.deselectAll, + }); + + final List selectedFiles; + final List allFiles; + final void Function() selectAll; + final void Function() deselectAll; + + bool get areAllFilesSelected { + for (String file in allFiles) { + if (!selectedFiles.contains(file)) return false; + } + return true; + } + + @override + Widget build(BuildContext context) { + return IconButton( + padding: EdgeInsets.zero, + tooltip: + areAllFilesSelected ? t.home.deselectAllNotes : t.home.selectAllNotes, + onPressed: () { + if (areAllFilesSelected) + deselectAll(); + else + selectAll(); + }, + icon: Icon(areAllFilesSelected ? Icons.deselect : Icons.select_all), + ); + } +} diff --git a/lib/i18n/en.i18n.yaml b/lib/i18n/en.i18n.yaml index 2b64a24d27..81afc738e6 100644 --- a/lib/i18n/en.i18n.yaml +++ b/lib/i18n/en.i18n.yaml @@ -48,6 +48,8 @@ home: renamedTo: Note will be renamed to $newName multipleRenamedTo: "The following notes will be renamed:" numberRenamedTo: $n notes will be renamed to avoid conflicts + selectAllNotes: Select all + deselectAllNotes: Deselect all deleteNote: Delete note renameFolder: renameFolder: Rename folder diff --git a/lib/i18n/it.i18n.yaml b/lib/i18n/it.i18n.yaml index c1527e4216..eed8f547cd 100644 --- a/lib/i18n/it.i18n.yaml +++ b/lib/i18n/it.i18n.yaml @@ -47,6 +47,8 @@ home: renamedTo: La nota verrĂ  rinominata in $newName multipleRenamedTo: "Le note seguenti verranno rinominate:" numberRenamedTo: $n le note verranno rinominate per evitare conflitti + selectAllNotes: Seleziona tutto + deselectAllNotes: Deseleziona tutto deleteNote: Elimina nota renameFolder: renameFolder: Rinomina cartella diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index fae5ccef55..98594f9278 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -77,6 +77,8 @@ class TranslationsHomeEn { late final TranslationsHomeNewFolderEn newFolder = TranslationsHomeNewFolderEn.internal(_root); late final TranslationsHomeRenameNoteEn renameNote = TranslationsHomeRenameNoteEn.internal(_root); late final TranslationsHomeMoveNoteEn moveNote = TranslationsHomeMoveNoteEn.internal(_root); + String get selectAllNotes => 'Select all'; + String get deselectAllNotes => 'Deselect all'; String get deleteNote => 'Delete note'; late final TranslationsHomeRenameFolderEn renameFolder = TranslationsHomeRenameFolderEn.internal(_root); late final TranslationsHomeDeleteFolderEn deleteFolder = TranslationsHomeDeleteFolderEn.internal(_root); diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 34371896bd..7bcd735c8d 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -74,6 +74,8 @@ class _TranslationsHomeIt extends TranslationsHomeEn { @override late final _TranslationsHomeNewFolderIt newFolder = _TranslationsHomeNewFolderIt._(_root); @override late final _TranslationsHomeRenameNoteIt renameNote = _TranslationsHomeRenameNoteIt._(_root); @override late final _TranslationsHomeMoveNoteIt moveNote = _TranslationsHomeMoveNoteIt._(_root); + @override String get selectAllNotes => 'Seleziona tutto'; + @override String get deselectAllNotes => 'Deseleziona tutto'; @override String get deleteNote => 'Elimina nota'; @override late final _TranslationsHomeRenameFolderIt renameFolder = _TranslationsHomeRenameFolderIt._(_root); @override late final _TranslationsHomeDeleteFolderIt deleteFolder = _TranslationsHomeDeleteFolderIt._(_root); diff --git a/lib/pages/home/browse.dart b/lib/pages/home/browse.dart index f4dd9069f5..83d87b6a85 100644 --- a/lib/pages/home/browse.dart +++ b/lib/pages/home/browse.dart @@ -10,6 +10,7 @@ import 'package:saber/components/home/move_note_button.dart'; import 'package:saber/components/home/new_note_button.dart'; import 'package:saber/components/home/no_files.dart'; import 'package:saber/components/home/rename_note_button.dart'; +import 'package:saber/components/home/select_all_button.dart'; import 'package:saber/components/home/syncing_button.dart'; import 'package:saber/data/file_manager/file_manager.dart'; import 'package:saber/data/routes.dart'; @@ -31,6 +32,13 @@ class BrowsePage extends StatefulWidget { class _BrowsePageState extends State { DirectoryChildren? children; + List get notesInCwd { + return [ + for (String filePath in children?.files ?? const []) + "${path ?? ""}/$filePath", + ]; + } + final List pathHistory = []; String? path; @@ -185,10 +193,7 @@ class _BrowsePageState extends State { ), sliver: MasonryFiles( crossAxisCount: crossAxisCount, - files: [ - for (String filePath in children?.files ?? const []) - "${path ?? ""}/$filePath", - ], + files: notesInCwd, selectedFiles: selectedFiles, ), ), @@ -234,6 +239,17 @@ class _BrowsePageState extends State { }, icon: const Icon(Icons.delete_forever), ), + SelectAllNotesButton( + selectedFiles: selectedFiles.value, + allFiles: notesInCwd, + selectAll: () => { + selectedFiles.value.clear(), + for (String filePath in notesInCwd) + selectedFiles.value.add(filePath), + setState(() {}) + }, + deselectAll: () => {selectedFiles.value = []}, + ), ExportNoteButton( selectedFiles: selectedFiles.value, ), diff --git a/lib/pages/home/recent_notes.dart b/lib/pages/home/recent_notes.dart index fe8e26b589..22dabeaf2c 100644 --- a/lib/pages/home/recent_notes.dart +++ b/lib/pages/home/recent_notes.dart @@ -9,6 +9,7 @@ import 'package:saber/components/home/masonry_files.dart'; import 'package:saber/components/home/move_note_button.dart'; import 'package:saber/components/home/new_note_button.dart'; import 'package:saber/components/home/rename_note_button.dart'; +import 'package:saber/components/home/select_all_button.dart'; import 'package:saber/components/home/syncing_button.dart'; import 'package:saber/components/home/welcome.dart'; import 'package:saber/data/file_manager/file_manager.dart'; @@ -203,6 +204,17 @@ class _RecentPageState extends State { }, icon: const Icon(Icons.delete_forever), ), + SelectAllNotesButton( + selectedFiles: selectedFiles.value, + allFiles: filePaths, + selectAll: () => { + selectedFiles.value.clear(), + for (String file in filePaths) + selectedFiles.value.add(file), + setState(() {}), + }, + deselectAll: () => selectedFiles.value = [], + ), ExportNoteButton( selectedFiles: selectedFiles.value, ),