mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-01 05:10:15 +02:00
Added rel. date sort
This commit is contained in:
@@ -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?"
|
||||
|
@@ -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?"
|
||||
|
@@ -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": "برنامه ها حذف شوند؟"
|
||||
|
@@ -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?"
|
||||
|
@@ -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?"
|
||||
|
@@ -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": "アプリを削除しますか?"
|
||||
|
@@ -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": "删除应用?"
|
||||
|
@@ -54,12 +54,12 @@ class AppsPageState extends State<AppsPage> {
|
||||
Widget build(BuildContext context) {
|
||||
var appsProvider = context.watch<AppsProvider>();
|
||||
var settingsProvider = context.watch<SettingsProvider>();
|
||||
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<AppsPage> {
|
||||
});
|
||||
}
|
||||
|
||||
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<AppsPage> {
|
||||
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<AppsPage> {
|
||||
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<AppsPage> {
|
||||
|
||||
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<AppsPage> {
|
||||
},
|
||||
child: CustomScrollView(slivers: <Widget>[
|
||||
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<AppsPage> {
|
||||
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<AppsPage> {
|
||||
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<AppsPage> {
|
||||
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<AppsPage> {
|
||||
.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<AppsPage> {
|
||||
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<AppsPage> {
|
||||
appsProvider
|
||||
.downloadAndInstallLatestApps(
|
||||
[
|
||||
sortedApps[index]
|
||||
listedApps[index]
|
||||
.app
|
||||
.id
|
||||
],
|
||||
@@ -351,7 +356,7 @@ class AppsPageState extends State<AppsPage> {
|
||||
});
|
||||
},
|
||||
child: Text(
|
||||
sortedApps[index]
|
||||
listedApps[index]
|
||||
.app
|
||||
.additionalSettings[
|
||||
'trackOnly'] ==
|
||||
@@ -373,18 +378,18 @@ class AppsPageState extends State<AppsPage> {
|
||||
))),
|
||||
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<AppsPage> {
|
||||
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(
|
||||
|
@@ -101,6 +101,10 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
DropdownMenuItem(
|
||||
value: SortColumnSettings.added,
|
||||
child: Text(tr('asAdded')),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: SortColumnSettings.releaseDate,
|
||||
child: Text(tr('releaseDate')),
|
||||
)
|
||||
],
|
||||
onChanged: (value) {
|
||||
|
@@ -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 }
|
||||
|
||||
|
Reference in New Issue
Block a user