From 5f7e342e6bc8b5a10eaf9842a4dde5e0edc4bb43 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sat, 18 Feb 2023 20:47:29 -0500 Subject: [PATCH] Added rel. date sort --- assets/translations/de.json | 1 + assets/translations/en.json | 1 + assets/translations/fa.json | 1 + assets/translations/hu.json | 1 + assets/translations/it.json | 1 + assets/translations/ja.json | 1 + assets/translations/zh.json | 1 + lib/pages/apps.dart | 91 +++++++++++++++------------- lib/pages/settings.dart | 4 ++ lib/providers/settings_provider.dart | 3 +- 10 files changed, 60 insertions(+), 45 deletions(-) diff --git a/assets/translations/de.json b/assets/translations/de.json index 6cff611..3aa50e4 100644 --- a/assets/translations/de.json +++ b/assets/translations/de.json @@ -216,6 +216,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "App entfernen?", "other": "App entfernen?" diff --git a/assets/translations/en.json b/assets/translations/en.json index eeed384..c6c91bd 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -216,6 +216,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "Remove App?", "other": "Remove Apps?" diff --git a/assets/translations/fa.json b/assets/translations/fa.json index fcafb95..999162b 100644 --- a/assets/translations/fa.json +++ b/assets/translations/fa.json @@ -216,6 +216,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "برنامه حذف شود؟", "other": "برنامه ها حذف شوند؟" diff --git a/assets/translations/hu.json b/assets/translations/hu.json index 6982f24..45ee74d 100644 --- a/assets/translations/hu.json +++ b/assets/translations/hu.json @@ -215,6 +215,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "Eltávolítja az alkalmazást?", "other": "Eltávolítja az alkalmazást?" diff --git a/assets/translations/it.json b/assets/translations/it.json index ad67d63..39d8054 100644 --- a/assets/translations/it.json +++ b/assets/translations/it.json @@ -216,6 +216,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "Rimuovere l'App?", "other": "Rimuovere le App?" diff --git a/assets/translations/ja.json b/assets/translations/ja.json index ca15558..fce19ec 100644 --- a/assets/translations/ja.json +++ b/assets/translations/ja.json @@ -216,6 +216,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "アプリを削除しますか?", "other": "アプリを削除しますか?" diff --git a/assets/translations/zh.json b/assets/translations/zh.json index ba97af8..001a3ef 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -216,6 +216,7 @@ "useReleaseDateAsVersion": "Use Release Date as Version", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.", "changes": "Changes", + "releaseDate": "Release Date", "removeAppQuestion": { "one": "删除应用?", "other": "删除应用?" diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index 0b49c0d..3cf8040 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -54,12 +54,12 @@ class AppsPageState extends State { Widget build(BuildContext context) { var appsProvider = context.watch(); var settingsProvider = context.watch(); - var sortedApps = appsProvider.apps.values.toList(); + var listedApps = appsProvider.apps.values.toList(); var currentFilterIsUpdatesOnly = filter.isIdenticalTo(updatesOnlyFilter, settingsProvider); selectedApps = selectedApps - .where((element) => sortedApps.map((e) => e.app).contains(element)) + .where((element) => listedApps.map((e) => e.app).contains(element)) .toSet(); toggleAppSelected(App app) { @@ -72,7 +72,7 @@ class AppsPageState extends State { }); } - sortedApps = sortedApps.where((app) { + listedApps = listedApps.where((app) { if (app.app.installedVersion == app.app.latestVersion && !(filter.includeUptodate)) { return false; @@ -111,7 +111,7 @@ class AppsPageState extends State { return true; }).toList(); - sortedApps.sort((a, b) { + listedApps.sort((a, b) { var nameA = a.installedInfo?.name ?? a.app.name; var nameB = b.installedInfo?.name ?? b.app.name; int result = 0; @@ -119,25 +119,30 @@ class AppsPageState extends State { result = (a.app.author + nameA).compareTo(b.app.author + nameB); } else if (settingsProvider.sortColumn == SortColumnSettings.nameAuthor) { result = (nameA + a.app.author).compareTo(nameB + b.app.author); + } else if (settingsProvider.sortColumn == + SortColumnSettings.releaseDate) { + result = (a.app.releaseDate) + ?.compareTo(b.app.releaseDate ?? DateTime.now()) ?? + 0; } return result; }); if (settingsProvider.sortOrder == SortOrderSettings.descending) { - sortedApps = sortedApps.reversed.toList(); + listedApps = listedApps.reversed.toList(); } var existingUpdates = appsProvider.findExistingUpdates(installedOnly: true); var existingUpdateIdsAllOrSelected = existingUpdates .where((element) => selectedApps.isEmpty - ? sortedApps.where((a) => a.app.id == element).isNotEmpty + ? listedApps.where((a) => a.app.id == element).isNotEmpty : selectedApps.map((e) => e.id).contains(element)) .toList(); var newInstallIdsAllOrSelected = appsProvider .findExistingUpdates(nonInstalledOnly: true) .where((element) => selectedApps.isEmpty - ? sortedApps.where((a) => a.app.id == element).isNotEmpty + ? listedApps.where((a) => a.app.id == element).isNotEmpty : selectedApps.map((e) => e.id).contains(element)) .toList(); @@ -159,26 +164,26 @@ class AppsPageState extends State { if (settingsProvider.pinUpdates) { var temp = []; - sortedApps = sortedApps.where((sa) { + listedApps = listedApps.where((sa) { if (existingUpdates.contains(sa.app.id)) { temp.add(sa); return false; } return true; }).toList(); - sortedApps = [...temp, ...sortedApps]; + listedApps = [...temp, ...listedApps]; } var tempPinned = []; var tempNotPinned = []; - for (var a in sortedApps) { + for (var a in listedApps) { if (a.app.pinned) { tempPinned.add(a); } else { tempNotPinned.add(a); } } - sortedApps = [...tempPinned, ...tempNotPinned]; + listedApps = [...tempPinned, ...tempNotPinned]; return Scaffold( backgroundColor: Theme.of(context).colorScheme.surface, @@ -198,7 +203,7 @@ class AppsPageState extends State { }, child: CustomScrollView(slivers: [ CustomAppBar(title: tr('appsString')), - if (appsProvider.loadingApps || sortedApps.isEmpty) + if (appsProvider.loadingApps || listedApps.isEmpty) SliverFillRemaining( child: Center( child: appsProvider.loadingApps @@ -225,8 +230,8 @@ class AppsPageState extends State { delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { String? changesUrl = SourceProvider() - .getSource(sortedApps[index].app.url) - .changeLogPageFromStandardUrl(sortedApps[index].app.url); + .getSource(listedApps[index].app.url) + .changeLogPageFromStandardUrl(listedApps[index].app.url); var transparent = const Color.fromARGB(0, 0, 0, 0).value; return Container( decoration: BoxDecoration( @@ -234,53 +239,53 @@ class AppsPageState extends State { vertical: BorderSide( width: 4, color: Color( - sortedApps[index].app.categories.isNotEmpty + listedApps[index].app.categories.isNotEmpty ? settingsProvider.categories[ - sortedApps[index] + listedApps[index] .app .categories .first] ?? transparent : transparent)))), child: ListTile( - tileColor: sortedApps[index].app.pinned + tileColor: listedApps[index].app.pinned ? Colors.grey.withOpacity(0.1) : Colors.transparent, selectedTileColor: Theme.of(context) .colorScheme .primary - .withOpacity(sortedApps[index].app.pinned ? 0.2 : 0.1), - selected: selectedApps.contains(sortedApps[index].app), + .withOpacity(listedApps[index].app.pinned ? 0.2 : 0.1), + selected: selectedApps.contains(listedApps[index].app), onLongPress: () { - toggleAppSelected(sortedApps[index].app); + toggleAppSelected(listedApps[index].app); }, - leading: sortedApps[index].installedInfo != null + leading: listedApps[index].installedInfo != null ? Image.memory( - sortedApps[index].installedInfo!.icon!, + listedApps[index].installedInfo!.icon!, gaplessPlayback: true, ) : null, title: Text( - sortedApps[index].installedInfo?.name ?? - sortedApps[index].app.name, + listedApps[index].installedInfo?.name ?? + listedApps[index].app.name, style: TextStyle( overflow: TextOverflow.ellipsis, - fontWeight: sortedApps[index].app.pinned + fontWeight: listedApps[index].app.pinned ? FontWeight.bold : FontWeight.normal, ), ), subtitle: Text( - tr('byX', args: [sortedApps[index].app.author]), + tr('byX', args: [listedApps[index].app.author]), style: TextStyle( - fontWeight: sortedApps[index].app.pinned + fontWeight: listedApps[index].app.pinned ? FontWeight.bold : FontWeight.normal)), trailing: SingleChildScrollView( reverse: true, - child: sortedApps[index].downloadProgress != null + child: listedApps[index].downloadProgress != null ? Text(tr('percentProgress', args: [ - sortedApps[index] + listedApps[index] .downloadProgress ?.toInt() .toString() ?? @@ -294,7 +299,7 @@ class AppsPageState extends State { mainAxisSize: MainAxisSize.min, children: [ Text( - '${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.additionalSettings['trackOnly'] == true ? ' ${tr('estimateInBrackets')}' : ''}', + '${listedApps[index].app.installedVersion ?? tr('notInstalled')}${listedApps[index].app.additionalSettings['trackOnly'] == true ? ' ${tr('estimateInBrackets')}' : ''}', overflow: TextOverflow.ellipsis, textAlign: TextAlign.end, ) @@ -308,11 +313,11 @@ class AppsPageState extends State { .externalApplication); }, child: Text( - sortedApps[index].app.releaseDate == + listedApps[index].app.releaseDate == null ? tr('changes') : DateFormat('yyyy-MM-dd').format( - sortedApps[index] + listedApps[index] .app .releaseDate!), style: const TextStyle( @@ -320,12 +325,12 @@ class AppsPageState extends State { decoration: TextDecoration.underline), )), - sortedApps[index].app.installedVersion != + listedApps[index].app.installedVersion != null && - sortedApps[index] + listedApps[index] .app .installedVersion != - sortedApps[index] + listedApps[index] .app .latestVersion ? appsProvider.areDownloadsRunning() @@ -340,7 +345,7 @@ class AppsPageState extends State { appsProvider .downloadAndInstallLatestApps( [ - sortedApps[index] + listedApps[index] .app .id ], @@ -351,7 +356,7 @@ class AppsPageState extends State { }); }, child: Text( - sortedApps[index] + listedApps[index] .app .additionalSettings[ 'trackOnly'] == @@ -373,18 +378,18 @@ class AppsPageState extends State { ))), onTap: () { if (selectedApps.isNotEmpty) { - toggleAppSelected(sortedApps[index].app); + toggleAppSelected(listedApps[index].app); } else { Navigator.push( context, MaterialPageRoute( builder: (context) => - AppPage(appId: sortedApps[index].app.id)), + AppPage(appId: listedApps[index].app.id)), ); } }, )); - }, childCount: sortedApps.length)) + }, childCount: listedApps.length)) ])), persistentFooterButtons: appsProvider.apps.isEmpty ? null @@ -396,20 +401,20 @@ class AppsPageState extends State { style: const ButtonStyle( visualDensity: VisualDensity.compact), onPressed: () { - selectThese(sortedApps.map((e) => e.app).toList()); + selectThese(listedApps.map((e) => e.app).toList()); }, icon: Icon( Icons.select_all_outlined, color: Theme.of(context).colorScheme.primary, ), - label: Text(sortedApps.length.toString())) + label: Text(listedApps.length.toString())) : TextButton.icon( style: const ButtonStyle( visualDensity: VisualDensity.compact), onPressed: () { selectedApps.isEmpty ? selectThese( - sortedApps.map((e) => e.app).toList()) + listedApps.map((e) => e.app).toList()) : clearSelected(); }, icon: Icon( diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index e43aca4..e2ba218 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -101,6 +101,10 @@ class _SettingsPageState extends State { DropdownMenuItem( value: SortColumnSettings.added, child: Text(tr('asAdded')), + ), + DropdownMenuItem( + value: SortColumnSettings.releaseDate, + child: Text(tr('releaseDate')), ) ], onChanged: (value) { diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 068ebf8..ea6985a 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -6,7 +6,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:obtainium/app_sources/github.dart'; -import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/main.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -18,7 +17,7 @@ enum ThemeSettings { system, light, dark } enum ColourSettings { basic, materialYou } -enum SortColumnSettings { added, nameAuthor, authorName } +enum SortColumnSettings { added, nameAuthor, authorName, releaseDate } enum SortOrderSettings { ascending, descending }