Added rel. date sort

This commit is contained in:
Imran Remtulla
2023-02-18 20:47:29 -05:00
parent 191776d0d5
commit 5f7e342e6b
10 changed files with 60 additions and 45 deletions

View File

@@ -216,6 +216,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "App entfernen?", "one": "App entfernen?",
"other": "App entfernen?" "other": "App entfernen?"

View File

@@ -216,6 +216,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Remove App?", "one": "Remove App?",
"other": "Remove Apps?" "other": "Remove Apps?"

View File

@@ -216,6 +216,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "برنامه حذف شود؟", "one": "برنامه حذف شود؟",
"other": "برنامه ها حذف شوند؟" "other": "برنامه ها حذف شوند؟"

View File

@@ -215,6 +215,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Eltávolítja az alkalmazást?", "one": "Eltávolítja az alkalmazást?",
"other": "Eltávolítja az alkalmazást?" "other": "Eltávolítja az alkalmazást?"

View File

@@ -216,6 +216,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "Rimuovere l'App?", "one": "Rimuovere l'App?",
"other": "Rimuovere le App?" "other": "Rimuovere le App?"

View File

@@ -216,6 +216,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "アプリを削除しますか?", "one": "アプリを削除しますか?",
"other": "アプリを削除しますか?" "other": "アプリを削除しますか?"

View File

@@ -216,6 +216,7 @@
"useReleaseDateAsVersion": "Use Release Date as Version", "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.", "releaseDateAsVersionExplanation": "This option should only be used for Apps where version detection does not work correctly, but a release date is available.",
"changes": "Changes", "changes": "Changes",
"releaseDate": "Release Date",
"removeAppQuestion": { "removeAppQuestion": {
"one": "删除应用?", "one": "删除应用?",
"other": "删除应用?" "other": "删除应用?"

View File

@@ -54,12 +54,12 @@ class AppsPageState extends State<AppsPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
var appsProvider = context.watch<AppsProvider>(); var appsProvider = context.watch<AppsProvider>();
var settingsProvider = context.watch<SettingsProvider>(); var settingsProvider = context.watch<SettingsProvider>();
var sortedApps = appsProvider.apps.values.toList(); var listedApps = appsProvider.apps.values.toList();
var currentFilterIsUpdatesOnly = var currentFilterIsUpdatesOnly =
filter.isIdenticalTo(updatesOnlyFilter, settingsProvider); filter.isIdenticalTo(updatesOnlyFilter, settingsProvider);
selectedApps = selectedApps selectedApps = selectedApps
.where((element) => sortedApps.map((e) => e.app).contains(element)) .where((element) => listedApps.map((e) => e.app).contains(element))
.toSet(); .toSet();
toggleAppSelected(App app) { toggleAppSelected(App app) {
@@ -72,7 +72,7 @@ class AppsPageState extends State<AppsPage> {
}); });
} }
sortedApps = sortedApps.where((app) { listedApps = listedApps.where((app) {
if (app.app.installedVersion == app.app.latestVersion && if (app.app.installedVersion == app.app.latestVersion &&
!(filter.includeUptodate)) { !(filter.includeUptodate)) {
return false; return false;
@@ -111,7 +111,7 @@ class AppsPageState extends State<AppsPage> {
return true; return true;
}).toList(); }).toList();
sortedApps.sort((a, b) { listedApps.sort((a, b) {
var nameA = a.installedInfo?.name ?? a.app.name; var nameA = a.installedInfo?.name ?? a.app.name;
var nameB = b.installedInfo?.name ?? b.app.name; var nameB = b.installedInfo?.name ?? b.app.name;
int result = 0; int result = 0;
@@ -119,25 +119,30 @@ class AppsPageState extends State<AppsPage> {
result = (a.app.author + nameA).compareTo(b.app.author + nameB); result = (a.app.author + nameA).compareTo(b.app.author + nameB);
} else if (settingsProvider.sortColumn == SortColumnSettings.nameAuthor) { } else if (settingsProvider.sortColumn == SortColumnSettings.nameAuthor) {
result = (nameA + a.app.author).compareTo(nameB + b.app.author); 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; return result;
}); });
if (settingsProvider.sortOrder == SortOrderSettings.descending) { if (settingsProvider.sortOrder == SortOrderSettings.descending) {
sortedApps = sortedApps.reversed.toList(); listedApps = listedApps.reversed.toList();
} }
var existingUpdates = appsProvider.findExistingUpdates(installedOnly: true); var existingUpdates = appsProvider.findExistingUpdates(installedOnly: true);
var existingUpdateIdsAllOrSelected = existingUpdates var existingUpdateIdsAllOrSelected = existingUpdates
.where((element) => selectedApps.isEmpty .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)) : selectedApps.map((e) => e.id).contains(element))
.toList(); .toList();
var newInstallIdsAllOrSelected = appsProvider var newInstallIdsAllOrSelected = appsProvider
.findExistingUpdates(nonInstalledOnly: true) .findExistingUpdates(nonInstalledOnly: true)
.where((element) => selectedApps.isEmpty .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)) : selectedApps.map((e) => e.id).contains(element))
.toList(); .toList();
@@ -159,26 +164,26 @@ class AppsPageState extends State<AppsPage> {
if (settingsProvider.pinUpdates) { if (settingsProvider.pinUpdates) {
var temp = []; var temp = [];
sortedApps = sortedApps.where((sa) { listedApps = listedApps.where((sa) {
if (existingUpdates.contains(sa.app.id)) { if (existingUpdates.contains(sa.app.id)) {
temp.add(sa); temp.add(sa);
return false; return false;
} }
return true; return true;
}).toList(); }).toList();
sortedApps = [...temp, ...sortedApps]; listedApps = [...temp, ...listedApps];
} }
var tempPinned = []; var tempPinned = [];
var tempNotPinned = []; var tempNotPinned = [];
for (var a in sortedApps) { for (var a in listedApps) {
if (a.app.pinned) { if (a.app.pinned) {
tempPinned.add(a); tempPinned.add(a);
} else { } else {
tempNotPinned.add(a); tempNotPinned.add(a);
} }
} }
sortedApps = [...tempPinned, ...tempNotPinned]; listedApps = [...tempPinned, ...tempNotPinned];
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).colorScheme.surface, backgroundColor: Theme.of(context).colorScheme.surface,
@@ -198,7 +203,7 @@ class AppsPageState extends State<AppsPage> {
}, },
child: CustomScrollView(slivers: <Widget>[ child: CustomScrollView(slivers: <Widget>[
CustomAppBar(title: tr('appsString')), CustomAppBar(title: tr('appsString')),
if (appsProvider.loadingApps || sortedApps.isEmpty) if (appsProvider.loadingApps || listedApps.isEmpty)
SliverFillRemaining( SliverFillRemaining(
child: Center( child: Center(
child: appsProvider.loadingApps child: appsProvider.loadingApps
@@ -225,8 +230,8 @@ class AppsPageState extends State<AppsPage> {
delegate: SliverChildBuilderDelegate( delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) { (BuildContext context, int index) {
String? changesUrl = SourceProvider() String? changesUrl = SourceProvider()
.getSource(sortedApps[index].app.url) .getSource(listedApps[index].app.url)
.changeLogPageFromStandardUrl(sortedApps[index].app.url); .changeLogPageFromStandardUrl(listedApps[index].app.url);
var transparent = const Color.fromARGB(0, 0, 0, 0).value; var transparent = const Color.fromARGB(0, 0, 0, 0).value;
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -234,53 +239,53 @@ class AppsPageState extends State<AppsPage> {
vertical: BorderSide( vertical: BorderSide(
width: 4, width: 4,
color: Color( color: Color(
sortedApps[index].app.categories.isNotEmpty listedApps[index].app.categories.isNotEmpty
? settingsProvider.categories[ ? settingsProvider.categories[
sortedApps[index] listedApps[index]
.app .app
.categories .categories
.first] ?? .first] ??
transparent transparent
: transparent)))), : transparent)))),
child: ListTile( child: ListTile(
tileColor: sortedApps[index].app.pinned tileColor: listedApps[index].app.pinned
? Colors.grey.withOpacity(0.1) ? Colors.grey.withOpacity(0.1)
: Colors.transparent, : Colors.transparent,
selectedTileColor: Theme.of(context) selectedTileColor: Theme.of(context)
.colorScheme .colorScheme
.primary .primary
.withOpacity(sortedApps[index].app.pinned ? 0.2 : 0.1), .withOpacity(listedApps[index].app.pinned ? 0.2 : 0.1),
selected: selectedApps.contains(sortedApps[index].app), selected: selectedApps.contains(listedApps[index].app),
onLongPress: () { onLongPress: () {
toggleAppSelected(sortedApps[index].app); toggleAppSelected(listedApps[index].app);
}, },
leading: sortedApps[index].installedInfo != null leading: listedApps[index].installedInfo != null
? Image.memory( ? Image.memory(
sortedApps[index].installedInfo!.icon!, listedApps[index].installedInfo!.icon!,
gaplessPlayback: true, gaplessPlayback: true,
) )
: null, : null,
title: Text( title: Text(
sortedApps[index].installedInfo?.name ?? listedApps[index].installedInfo?.name ??
sortedApps[index].app.name, listedApps[index].app.name,
style: TextStyle( style: TextStyle(
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
fontWeight: sortedApps[index].app.pinned fontWeight: listedApps[index].app.pinned
? FontWeight.bold ? FontWeight.bold
: FontWeight.normal, : FontWeight.normal,
), ),
), ),
subtitle: Text( subtitle: Text(
tr('byX', args: [sortedApps[index].app.author]), tr('byX', args: [listedApps[index].app.author]),
style: TextStyle( style: TextStyle(
fontWeight: sortedApps[index].app.pinned fontWeight: listedApps[index].app.pinned
? FontWeight.bold ? FontWeight.bold
: FontWeight.normal)), : FontWeight.normal)),
trailing: SingleChildScrollView( trailing: SingleChildScrollView(
reverse: true, reverse: true,
child: sortedApps[index].downloadProgress != null child: listedApps[index].downloadProgress != null
? Text(tr('percentProgress', args: [ ? Text(tr('percentProgress', args: [
sortedApps[index] listedApps[index]
.downloadProgress .downloadProgress
?.toInt() ?.toInt()
.toString() ?? .toString() ??
@@ -294,7 +299,7 @@ class AppsPageState extends State<AppsPage> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( 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, overflow: TextOverflow.ellipsis,
textAlign: TextAlign.end, textAlign: TextAlign.end,
) )
@@ -308,11 +313,11 @@ class AppsPageState extends State<AppsPage> {
.externalApplication); .externalApplication);
}, },
child: Text( child: Text(
sortedApps[index].app.releaseDate == listedApps[index].app.releaseDate ==
null null
? tr('changes') ? tr('changes')
: DateFormat('yyyy-MM-dd').format( : DateFormat('yyyy-MM-dd').format(
sortedApps[index] listedApps[index]
.app .app
.releaseDate!), .releaseDate!),
style: const TextStyle( style: const TextStyle(
@@ -320,12 +325,12 @@ class AppsPageState extends State<AppsPage> {
decoration: decoration:
TextDecoration.underline), TextDecoration.underline),
)), )),
sortedApps[index].app.installedVersion != listedApps[index].app.installedVersion !=
null && null &&
sortedApps[index] listedApps[index]
.app .app
.installedVersion != .installedVersion !=
sortedApps[index] listedApps[index]
.app .app
.latestVersion .latestVersion
? appsProvider.areDownloadsRunning() ? appsProvider.areDownloadsRunning()
@@ -340,7 +345,7 @@ class AppsPageState extends State<AppsPage> {
appsProvider appsProvider
.downloadAndInstallLatestApps( .downloadAndInstallLatestApps(
[ [
sortedApps[index] listedApps[index]
.app .app
.id .id
], ],
@@ -351,7 +356,7 @@ class AppsPageState extends State<AppsPage> {
}); });
}, },
child: Text( child: Text(
sortedApps[index] listedApps[index]
.app .app
.additionalSettings[ .additionalSettings[
'trackOnly'] == 'trackOnly'] ==
@@ -373,18 +378,18 @@ class AppsPageState extends State<AppsPage> {
))), ))),
onTap: () { onTap: () {
if (selectedApps.isNotEmpty) { if (selectedApps.isNotEmpty) {
toggleAppSelected(sortedApps[index].app); toggleAppSelected(listedApps[index].app);
} else { } else {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) =>
AppPage(appId: sortedApps[index].app.id)), AppPage(appId: listedApps[index].app.id)),
); );
} }
}, },
)); ));
}, childCount: sortedApps.length)) }, childCount: listedApps.length))
])), ])),
persistentFooterButtons: appsProvider.apps.isEmpty persistentFooterButtons: appsProvider.apps.isEmpty
? null ? null
@@ -396,20 +401,20 @@ class AppsPageState extends State<AppsPage> {
style: const ButtonStyle( style: const ButtonStyle(
visualDensity: VisualDensity.compact), visualDensity: VisualDensity.compact),
onPressed: () { onPressed: () {
selectThese(sortedApps.map((e) => e.app).toList()); selectThese(listedApps.map((e) => e.app).toList());
}, },
icon: Icon( icon: Icon(
Icons.select_all_outlined, Icons.select_all_outlined,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
label: Text(sortedApps.length.toString())) label: Text(listedApps.length.toString()))
: TextButton.icon( : TextButton.icon(
style: const ButtonStyle( style: const ButtonStyle(
visualDensity: VisualDensity.compact), visualDensity: VisualDensity.compact),
onPressed: () { onPressed: () {
selectedApps.isEmpty selectedApps.isEmpty
? selectThese( ? selectThese(
sortedApps.map((e) => e.app).toList()) listedApps.map((e) => e.app).toList())
: clearSelected(); : clearSelected();
}, },
icon: Icon( icon: Icon(

View File

@@ -101,6 +101,10 @@ class _SettingsPageState extends State<SettingsPage> {
DropdownMenuItem( DropdownMenuItem(
value: SortColumnSettings.added, value: SortColumnSettings.added,
child: Text(tr('asAdded')), child: Text(tr('asAdded')),
),
DropdownMenuItem(
value: SortColumnSettings.releaseDate,
child: Text(tr('releaseDate')),
) )
], ],
onChanged: (value) { onChanged: (value) {

View File

@@ -6,7 +6,6 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:obtainium/app_sources/github.dart'; import 'package:obtainium/app_sources/github.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/main.dart'; import 'package:obtainium/main.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@@ -18,7 +17,7 @@ enum ThemeSettings { system, light, dark }
enum ColourSettings { basic, materialYou } enum ColourSettings { basic, materialYou }
enum SortColumnSettings { added, nameAuthor, authorName } enum SortColumnSettings { added, nameAuthor, authorName, releaseDate }
enum SortOrderSettings { ascending, descending } enum SortOrderSettings { ascending, descending }