diff --git a/lib/constants/enums.dart b/lib/constants/enums.dart index 102e340..45adff2 100644 --- a/lib/constants/enums.dart +++ b/lib/constants/enums.dart @@ -9,3 +9,7 @@ enum AuthResult { success, invalidToken, other } enum FilteredBookmarksMode { tag, shared, archived } enum ReadStatus { all, unread, read } + +enum SortingType { date, title } + +enum SortingWay { descendant, ascendant } diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 2f8a4b0..36c523b 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 2 -/// Strings: 364 (182 per locale) +/// Strings: 374 (187 per locale) /// -/// Built on 2024-03-01 at 13:46 UTC +/// Built on 2024-03-03 at 16:11 UTC // coverage:ignore-file // ignore_for_file: type=lint @@ -235,6 +235,11 @@ class _StringsBookmarksEn { String get unread => 'Unread'; String get read => 'Read'; String get filterSort => 'Filter and sort'; + String get sorting => 'Sorting'; + String get date => 'Date'; + String get title => 'Title'; + String get ascendant => 'Ascendant'; + String get descendant => 'Descendant'; late final _StringsBookmarksAddBookmarkEn addBookmark = _StringsBookmarksAddBookmarkEn._(_root); late final _StringsBookmarksSearchEn search = _StringsBookmarksSearchEn._(_root); late final _StringsBookmarksBookmarkOptionsEn bookmarkOptions = _StringsBookmarksBookmarkOptionsEn._(_root); @@ -613,6 +618,11 @@ class _StringsBookmarksEs implements _StringsBookmarksEn { @override String get unread => 'No leídos'; @override String get read => 'Leídos'; @override String get filterSort => 'Filtrar y ordenar'; + @override String get sorting => 'Ordenación'; + @override String get date => 'Fecha'; + @override String get title => 'Título'; + @override String get ascendant => 'Ascendiente'; + @override String get descendant => 'Descendiente'; @override late final _StringsBookmarksAddBookmarkEs addBookmark = _StringsBookmarksAddBookmarkEs._(_root); @override late final _StringsBookmarksSearchEs search = _StringsBookmarksSearchEs._(_root); @override late final _StringsBookmarksBookmarkOptionsEs bookmarkOptions = _StringsBookmarksBookmarkOptionsEs._(_root); @@ -940,6 +950,11 @@ extension on Translations { case 'bookmarks.unread': return 'Unread'; case 'bookmarks.read': return 'Read'; case 'bookmarks.filterSort': return 'Filter and sort'; + case 'bookmarks.sorting': return 'Sorting'; + case 'bookmarks.date': return 'Date'; + case 'bookmarks.title': return 'Title'; + case 'bookmarks.ascendant': return 'Ascendant'; + case 'bookmarks.descendant': return 'Descendant'; case 'bookmarks.addBookmark.addBookmark': return 'Add new bookmark'; case 'bookmarks.addBookmark.editBookmark': return 'Edit bookmark'; case 'bookmarks.addBookmark.bookmarkUrl': return 'Bookmark URL'; @@ -1130,6 +1145,11 @@ extension on _StringsEs { case 'bookmarks.unread': return 'No leídos'; case 'bookmarks.read': return 'Leídos'; case 'bookmarks.filterSort': return 'Filtrar y ordenar'; + case 'bookmarks.sorting': return 'Ordenación'; + case 'bookmarks.date': return 'Fecha'; + case 'bookmarks.title': return 'Título'; + case 'bookmarks.ascendant': return 'Ascendiente'; + case 'bookmarks.descendant': return 'Descendiente'; case 'bookmarks.addBookmark.addBookmark': return 'Añadir nuevo marcador'; case 'bookmarks.addBookmark.editBookmark': return 'Editar marcador'; case 'bookmarks.addBookmark.url': return 'URL'; diff --git a/lib/i18n/strings_en.i18n.json b/lib/i18n/strings_en.i18n.json index 03876e1..9de4131 100644 --- a/lib/i18n/strings_en.i18n.json +++ b/lib/i18n/strings_en.i18n.json @@ -60,6 +60,11 @@ "unread": "Unread", "read": "Read", "filterSort": "Filter and sort", + "sorting": "Sorting", + "date": "Date", + "title": "Title", + "ascendant": "Ascendant", + "descendant": "Descendant", "addBookmark": { "addBookmark": "Add new bookmark", "editBookmark": "Edit bookmark", diff --git a/lib/i18n/strings_es.i18n.json b/lib/i18n/strings_es.i18n.json index 5b5b78a..cacdb98 100644 --- a/lib/i18n/strings_es.i18n.json +++ b/lib/i18n/strings_es.i18n.json @@ -60,6 +60,11 @@ "unread": "No leídos", "read": "Leídos", "filterSort": "Filtrar y ordenar", + "sorting": "Ordenación", + "date": "Fecha", + "title": "Título", + "ascendant": "Ascendiente", + "descendant": "Descendiente", "addBookmark": { "addBookmark": "Añadir nuevo marcador", "editBookmark": "Editar marcador", diff --git a/lib/screens/bookmarks/model/bookmarks.model.dart b/lib/screens/bookmarks/model/bookmarks.model.dart index 7a3be17..deba735 100644 --- a/lib/screens/bookmarks/model/bookmarks.model.dart +++ b/lib/screens/bookmarks/model/bookmarks.model.dart @@ -14,6 +14,8 @@ class BookmarksModel { ReadStatus readStatus; Bookmark? selectedBookmark; final GoRouter webViewRouter; + SortingType sortingType; + SortingWay sortingWay; BookmarksModel({ this.currentPage = 0, @@ -25,5 +27,7 @@ class BookmarksModel { this.readStatus = ReadStatus.all, this.selectedBookmark, required this.webViewRouter, + this.sortingType = SortingType.date, + this.sortingWay = SortingWay.descendant, }); } diff --git a/lib/screens/bookmarks/provider/bookmarks.provider.dart b/lib/screens/bookmarks/provider/bookmarks.provider.dart index 96f8cf9..4b8d6e9 100644 --- a/lib/screens/bookmarks/provider/bookmarks.provider.dart +++ b/lib/screens/bookmarks/provider/bookmarks.provider.dart @@ -19,12 +19,27 @@ import 'package:linkdy/constants/enums.dart'; part 'bookmarks.provider.g.dart'; +String sortingMethod(SortingType type, SortingWay way) { + if (type == SortingType.date && way == SortingWay.descendant) { + return ""; + } else { + return "${type == SortingType.title ? "title" : "date"}_${way == SortingWay.ascendant ? "asc" : "desc"}"; + } +} + @riverpod -FutureOr bookmarksRequest(BookmarksRequestRef ref, ReadStatus readStatus, int limit) async { +FutureOr bookmarksRequest( + BookmarksRequestRef ref, + ReadStatus readStatus, + SortingType type, + SortingWay way, + int limit, +) async { final result = await ref.watch(apiClientProvider)!.fetchBookmarks( limit: limit, offset: 0, unread: readStatus, + sort: sortingMethod(type, way), ); if (result.successful == true) { @@ -44,12 +59,16 @@ FutureOr bookmarksRequest(BookmarksRequestRef ref, ReadStatus readStatus, FutureOr bookmarksRequestLoadMore(BookmarksRequestLoadMoreRef ref) async { final provider = ref.watch(bookmarksProvider); + final sortingType = ref.watch(bookmarksProvider).sortingType; + final sortingWay = ref.watch(bookmarksProvider).sortingWay; + final newOffset = provider.limit * (provider.currentPage + 1); final result = await ref.watch(apiClientProvider)!.fetchBookmarks( limit: provider.limit, offset: newOffset, unread: ref.read(bookmarksProvider).readStatus, + sort: sortingMethod(sortingType, sortingWay), ); if (result.successful == true) { @@ -89,7 +108,7 @@ class Bookmarks extends _$Bookmarks { ], ), ); - ref.read(bookmarksRequestProvider(model.readStatus, model.limit)); + ref.read(bookmarksRequestProvider(model.readStatus, model.sortingType, model.sortingWay, model.limit)); return model; } @@ -117,7 +136,19 @@ class Bookmarks extends _$Bookmarks { void setReadStatus(ReadStatus status) { state.readStatus = status; - ref.read(bookmarksRequestProvider(status, state.limit)); + ref.read(bookmarksRequestProvider(status, state.sortingType, state.sortingWay, state.limit)); + ref.notifyListeners(); + } + + void setSortingType(SortingType type) { + state.sortingType = type; + ref.read(bookmarksRequestProvider(state.readStatus, type, state.sortingWay, state.limit)); + ref.notifyListeners(); + } + + void setSortingWay(SortingWay way) { + state.sortingWay = way; + ref.read(bookmarksRequestProvider(state.readStatus, state.sortingType, way, state.limit)); ref.notifyListeners(); } @@ -148,7 +179,7 @@ class Bookmarks extends _$Bookmarks { } Future refresh() async { - await ref.read(bookmarksRequestProvider(state.readStatus, state.limit).future); + await ref.read(bookmarksRequestProvider(state.readStatus, state.sortingType, state.sortingWay, state.limit).future); } void deleteBookmark(Bookmark bookmark) async { diff --git a/lib/screens/bookmarks/provider/bookmarks.provider.g.dart b/lib/screens/bookmarks/provider/bookmarks.provider.g.dart index fbc8cb8..0b6895e 100644 --- a/lib/screens/bookmarks/provider/bookmarks.provider.g.dart +++ b/lib/screens/bookmarks/provider/bookmarks.provider.g.dart @@ -6,7 +6,7 @@ part of 'bookmarks.provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$bookmarksRequestHash() => r'eb1ddffb83edc0fa433fae76859bde4206e59940'; +String _$bookmarksRequestHash() => r'c89579d46046980542ed9898867bfb39e85d1d6c'; /// Copied from Dart SDK class _SystemHash { @@ -41,10 +41,14 @@ class BookmarksRequestFamily extends Family> { /// See also [bookmarksRequest]. BookmarksRequestProvider call( ReadStatus readStatus, + SortingType type, + SortingWay way, int limit, ) { return BookmarksRequestProvider( readStatus, + type, + way, limit, ); } @@ -55,6 +59,8 @@ class BookmarksRequestFamily extends Family> { ) { return call( provider.readStatus, + provider.type, + provider.way, provider.limit, ); } @@ -79,11 +85,15 @@ class BookmarksRequestProvider extends AutoDisposeFutureProvider { /// See also [bookmarksRequest]. BookmarksRequestProvider( ReadStatus readStatus, + SortingType type, + SortingWay way, int limit, ) : this._internal( (ref) => bookmarksRequest( ref as BookmarksRequestRef, readStatus, + type, + way, limit, ), from: bookmarksRequestProvider, @@ -96,6 +106,8 @@ class BookmarksRequestProvider extends AutoDisposeFutureProvider { allTransitiveDependencies: BookmarksRequestFamily._allTransitiveDependencies, readStatus: readStatus, + type: type, + way: way, limit: limit, ); @@ -107,10 +119,14 @@ class BookmarksRequestProvider extends AutoDisposeFutureProvider { required super.debugGetCreateSourceHash, required super.from, required this.readStatus, + required this.type, + required this.way, required this.limit, }) : super.internal(); final ReadStatus readStatus; + final SortingType type; + final SortingWay way; final int limit; @override @@ -127,6 +143,8 @@ class BookmarksRequestProvider extends AutoDisposeFutureProvider { allTransitiveDependencies: null, debugGetCreateSourceHash: null, readStatus: readStatus, + type: type, + way: way, limit: limit, ), ); @@ -141,6 +159,8 @@ class BookmarksRequestProvider extends AutoDisposeFutureProvider { bool operator ==(Object other) { return other is BookmarksRequestProvider && other.readStatus == readStatus && + other.type == type && + other.way == way && other.limit == limit; } @@ -148,6 +168,8 @@ class BookmarksRequestProvider extends AutoDisposeFutureProvider { int get hashCode { var hash = _SystemHash.combine(0, runtimeType.hashCode); hash = _SystemHash.combine(hash, readStatus.hashCode); + hash = _SystemHash.combine(hash, type.hashCode); + hash = _SystemHash.combine(hash, way.hashCode); hash = _SystemHash.combine(hash, limit.hashCode); return _SystemHash.finish(hash); @@ -158,6 +180,12 @@ mixin BookmarksRequestRef on AutoDisposeFutureProviderRef { /// The parameter `readStatus` of this provider. ReadStatus get readStatus; + /// The parameter `type` of this provider. + SortingType get type; + + /// The parameter `way` of this provider. + SortingWay get way; + /// The parameter `limit` of this provider. int get limit; } @@ -169,11 +197,15 @@ class _BookmarksRequestProviderElement @override ReadStatus get readStatus => (origin as BookmarksRequestProvider).readStatus; @override + SortingType get type => (origin as BookmarksRequestProvider).type; + @override + SortingWay get way => (origin as BookmarksRequestProvider).way; + @override int get limit => (origin as BookmarksRequestProvider).limit; } String _$bookmarksRequestLoadMoreHash() => - r'1a206bd974677fd862eb4d5b5f453df9f566d995'; + r'cea7de930dc5cb77281b68e91dfa66ff3ecf57b5'; /// See also [bookmarksRequestLoadMore]. @ProviderFor(bookmarksRequestLoadMore) @@ -189,7 +221,7 @@ final bookmarksRequestLoadMoreProvider = ); typedef BookmarksRequestLoadMoreRef = AutoDisposeFutureProviderRef; -String _$bookmarksHash() => r'84c91bf9112343e4680040bfe25b5e17fb2f92d2'; +String _$bookmarksHash() => r'ed3a350dc6f4818adf146c1dab84005fec8c9be4'; /// See also [Bookmarks]. @ProviderFor(Bookmarks) diff --git a/lib/screens/bookmarks/provider/favicon_loader.provider.g.dart b/lib/screens/bookmarks/provider/favicon_loader.provider.g.dart index 73226b8..031fe1e 100644 --- a/lib/screens/bookmarks/provider/favicon_loader.provider.g.dart +++ b/lib/screens/bookmarks/provider/favicon_loader.provider.g.dart @@ -6,7 +6,7 @@ part of 'favicon_loader.provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$faviconStoreHash() => r'459949315bf6a236946c8b03ba90ce047b691b7e'; +String _$faviconStoreHash() => r'5575f5daff34748e6cae0143c8633cbbe19b6009'; /// See also [FaviconStore]. @ProviderFor(FaviconStore) diff --git a/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart b/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart index f36e40f..5aee3b3 100644 --- a/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart +++ b/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart @@ -174,7 +174,7 @@ final fetchSearchBookmarksLoadMoreProvider = ); typedef FetchSearchBookmarksLoadMoreRef = AutoDisposeFutureProviderRef; -String _$searchBookmarksHash() => r'5ebbd8dbfe705cbca9552fc60d251372c771d738'; +String _$searchBookmarksHash() => r'a70324693484f2c7731fcebf4df007443f1c30e9'; /// See also [SearchBookmarks]. @ProviderFor(SearchBookmarks) diff --git a/lib/screens/bookmarks/ui/visualization_modal.dart b/lib/screens/bookmarks/ui/visualization_modal.dart index 00443e4..3a7e6bc 100644 --- a/lib/screens/bookmarks/ui/visualization_modal.dart +++ b/lib/screens/bookmarks/ui/visualization_modal.dart @@ -70,6 +70,45 @@ class VisualizationModal extends ConsumerWidget { hoverColor: Theme.of(context).colorScheme.onSurfaceVariant, ), ), + const SizedBox(height: 8), + SectionLabel( + label: t.bookmarks.sorting, + padding: const EdgeInsets.symmetric( + horizontal: 0, + vertical: 16, + ), + ), + SegmentedButtonSlide( + entries: [ + SegmentedButtonSlideEntry(label: t.bookmarks.date), + SegmentedButtonSlideEntry(label: t.bookmarks.title), + ], + selectedEntry: ref.watch(bookmarksProvider).sortingType.index, + onChange: (v) => ref.read(bookmarksProvider.notifier).setSortingType(SortingType.values[v]), + colors: SegmentedButtonSlideColors( + barColor: Theme.of(context).colorScheme.primary.withOpacity(0.2), + backgroundSelectedColor: Theme.of(context).colorScheme.primary, + foregroundSelectedColor: Theme.of(context).colorScheme.onPrimary, + foregroundUnselectedColor: Theme.of(context).colorScheme.onSurface, + hoverColor: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + const SizedBox(height: 16), + SegmentedButtonSlide( + entries: [ + SegmentedButtonSlideEntry(label: t.bookmarks.descendant), + SegmentedButtonSlideEntry(label: t.bookmarks.ascendant), + ], + selectedEntry: ref.watch(bookmarksProvider).sortingWay.index, + onChange: (v) => ref.read(bookmarksProvider.notifier).setSortingWay(SortingWay.values[v]), + colors: SegmentedButtonSlideColors( + barColor: Theme.of(context).colorScheme.primary.withOpacity(0.2), + backgroundSelectedColor: Theme.of(context).colorScheme.primary, + foregroundSelectedColor: Theme.of(context).colorScheme.onPrimary, + foregroundUnselectedColor: Theme.of(context).colorScheme.onSurface, + hoverColor: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), ], ), ), diff --git a/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart b/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart index a447a95..7ec88c5 100644 --- a/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart +++ b/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart @@ -372,7 +372,7 @@ final filteredBookmarksRequestLoadMoreProvider = typedef FilteredBookmarksRequestLoadMoreRef = AutoDisposeFutureProviderRef; -String _$filteredBookmarksHash() => r'e58baf5c41c61233e76edea16830f1a47d6a645a'; +String _$filteredBookmarksHash() => r'2239ac5e2eb27ffee118a5c513f191702faea8de'; /// See also [FilteredBookmarks]. @ProviderFor(FilteredBookmarks) diff --git a/lib/screens/webview/provider/webview.provider.g.dart b/lib/screens/webview/provider/webview.provider.g.dart index ccd84d6..7980799 100644 --- a/lib/screens/webview/provider/webview.provider.g.dart +++ b/lib/screens/webview/provider/webview.provider.g.dart @@ -6,7 +6,7 @@ part of 'webview.provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$webViewHash() => r'ae307e7a5014a44777bd6af7fd9cae7f96970610'; +String _$webViewHash() => r'777a5c7245e32f3334c676aa2bf18d953be1233a'; /// See also [WebView]. @ProviderFor(WebView) diff --git a/lib/services/api_client.dart b/lib/services/api_client.dart index 79bfa1d..68f255a 100644 --- a/lib/services/api_client.dart +++ b/lib/services/api_client.dart @@ -52,6 +52,7 @@ class ApiClientService { int? limit, int? offset, ReadStatus? unread, + String? sort, }) async { try { final response = await dioInstance.get( @@ -65,6 +66,7 @@ class ApiClientService { : unread == ReadStatus.read ? "no" : null, + "sort": sort, }, ); return ApiResponse(