Category displayed on App/Apps pages

+ category save bugfix
This commit is contained in:
Imran Remtulla
2022-12-21 03:57:08 -05:00
parent 99d7595f2d
commit 26f953dbb0
3 changed files with 168 additions and 90 deletions

View File

@@ -1,6 +1,7 @@
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/components/generated_form_modal.dart';
import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/main.dart'; import 'package:obtainium/main.dart';
@@ -33,6 +34,7 @@ class _AppPageState extends State<AppPage> {
}); });
} }
var categories = settingsProvider.categories;
var sourceProvider = SourceProvider(); var sourceProvider = SourceProvider();
AppInMemory? app = appsProvider.apps[widget.appId]; AppInMemory? app = appsProvider.apps[widget.appId];
var source = app != null ? sourceProvider.getSource(app.app.url) : null; var source = app != null ? sourceProvider.getSource(app.app.url) : null;
@@ -148,7 +150,63 @@ class _AppPageState extends State<AppPage> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontStyle: FontStyle.italic, fontSize: 12), fontStyle: FontStyle.italic, fontSize: 12),
) ),
const SizedBox(
height: 32,
),
app?.app.category != null
? Chip(
label: Text(app!.app.category!),
backgroundColor:
Color(categories[app.app.category!] ?? 0x0),
onDeleted: () {
app.app.category = null;
appsProvider.saveApps([app.app]);
},
visualDensity: VisualDensity.compact,
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
showDialog<Map<String, String>?>(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
title: 'Pick a Category',
items: [
[
GeneratedFormItem(
'category', // TODO
label: 'Category',
opts: [
MapEntry('',
'No Category'),
...categories
.entries
.map((e) =>
MapEntry(
e.key,
e.key))
.toList()
])
]
]);
}).then((value) {
if (value != null && app != null) {
String? cat = (value['category']
?.isNotEmpty ??
false)
? value['category']
: null;
app.app.category = cat;
appsProvider.saveApps([app.app]);
}
});
},
child: const Text('Categorize')) // TODO
])
], ],
)), )),
], ],

View File

@@ -225,96 +225,114 @@ class AppsPageState extends State<AppsPage> {
String? changesUrl = SourceProvider() String? changesUrl = SourceProvider()
.getSource(sortedApps[index].app.url) .getSource(sortedApps[index].app.url)
.changeLogPageFromStandardUrl(sortedApps[index].app.url); .changeLogPageFromStandardUrl(sortedApps[index].app.url);
return ListTile( return Container(
tileColor: sortedApps[index].app.pinned decoration: BoxDecoration(
? Colors.grey.withOpacity(0.1) border: Border.symmetric(
: Colors.transparent, vertical: BorderSide(
selectedTileColor: Theme.of(context) width: 3,
.colorScheme color: Color(settingsProvider.categories[
.primary sortedApps[index].app.category] ??
.withOpacity(sortedApps[index].app.pinned ? 0.2 : 0.1), const Color.fromARGB(0, 0, 0, 0).value)))),
selected: selectedApps.contains(sortedApps[index].app), child: ListTile(
onLongPress: () { tileColor: sortedApps[index].app.pinned
toggleAppSelected(sortedApps[index].app); ? Colors.grey.withOpacity(0.1)
}, : Colors.transparent,
leading: sortedApps[index].installedInfo != null selectedTileColor: Theme.of(context)
? Image.memory( .colorScheme
sortedApps[index].installedInfo!.icon!, .primary
gaplessPlayback: true, .withOpacity(sortedApps[index].app.pinned ? 0.2 : 0.1),
) selected: selectedApps.contains(sortedApps[index].app),
: null, onLongPress: () {
title: Text( toggleAppSelected(sortedApps[index].app);
sortedApps[index].installedInfo?.name ?? },
sortedApps[index].app.name, leading: sortedApps[index].installedInfo != null
style: TextStyle( ? Image.memory(
fontWeight: sortedApps[index].app.pinned sortedApps[index].installedInfo!.icon!,
? FontWeight.bold gaplessPlayback: true,
: FontWeight.normal), )
), : null,
subtitle: Text(tr('byX', args: [sortedApps[index].app.author]), title: Text(
style: TextStyle( sortedApps[index].installedInfo?.name ??
sortedApps[index].app.name,
style: TextStyle(
fontWeight: sortedApps[index].app.pinned fontWeight: sortedApps[index].app.pinned
? FontWeight.bold ? FontWeight.bold
: FontWeight.normal)), : FontWeight.normal,
trailing: SingleChildScrollView( ),
reverse: true, ),
child: sortedApps[index].downloadProgress != null subtitle: Text(
? Text(tr('percentProgress', args: [ tr('byX', args: [sortedApps[index].app.author]),
sortedApps[index] style: TextStyle(
.downloadProgress fontWeight: sortedApps[index].app.pinned
?.toInt() ? FontWeight.bold
.toString() ?? : FontWeight.normal)),
'100' trailing: SingleChildScrollView(
])) reverse: true,
: (Column( child: sortedApps[index].downloadProgress != null
mainAxisAlignment: MainAxisAlignment.center, ? Text(tr('percentProgress', args: [
crossAxisAlignment: CrossAxisAlignment.end, sortedApps[index]
children: [ .downloadProgress
SizedBox( ?.toInt()
width: 100, .toString() ??
child: Text( '100'
'${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBrackets')}' : ''}', ]))
overflow: TextOverflow.fade, : (Column(
textAlign: TextAlign.end, mainAxisAlignment: MainAxisAlignment.center,
)), crossAxisAlignment: CrossAxisAlignment.end,
sortedApps[index].app.installedVersion != null && children: [
sortedApps[index].app.installedVersion != SizedBox(
sortedApps[index].app.latestVersion width: 100,
? GestureDetector( child: Text(
onTap: changesUrl == null '${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBrackets')}' : ''}',
? null overflow: TextOverflow.fade,
: () { textAlign: TextAlign.end,
launchUrlString(changesUrl, )),
mode: LaunchMode sortedApps[index].app.installedVersion !=
.externalApplication); null &&
}, sortedApps[index]
child: appsProvider.areDownloadsRunning() .app
? Text(tr('pleaseWait')) .installedVersion !=
: Text( sortedApps[index]
'${tr('updateAvailable')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBracketsShort')}' : ''}', .app
style: TextStyle( .latestVersion
fontStyle: FontStyle.italic, ? GestureDetector(
decoration: changesUrl == null onTap: changesUrl == null
? TextDecoration.none ? null
: TextDecoration : () {
.underline), launchUrlString(changesUrl,
)) mode: LaunchMode
: const SizedBox(), .externalApplication);
], },
))), child: appsProvider
onTap: () { .areDownloadsRunning()
if (selectedApps.isNotEmpty) { ? Text(tr('pleaseWait'))
toggleAppSelected(sortedApps[index].app); : Text(
} else { '${tr('updateAvailable')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBracketsShort')}' : ''}',
Navigator.push( style: TextStyle(
context, fontStyle:
MaterialPageRoute( FontStyle.italic,
builder: (context) => decoration: changesUrl ==
AppPage(appId: sortedApps[index].app.id)), null
); ? TextDecoration.none
} : TextDecoration
}, .underline),
); ))
: const SizedBox(),
],
))),
onTap: () {
if (selectedApps.isNotEmpty) {
toggleAppSelected(sortedApps[index].app);
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AppPage(appId: sortedApps[index].app.id)),
);
}
},
));
}, childCount: sortedApps.length)) }, childCount: sortedApps.length))
])), ])),
persistentFooterButtons: [ persistentFooterButtons: [

View File

@@ -19,6 +19,7 @@ import 'package:obtainium/app_sources/steammobile.dart';
import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form.dart';
import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/custom_errors.dart';
import 'package:obtainium/mass_app_sources/githubstars.dart'; import 'package:obtainium/mass_app_sources/githubstars.dart';
import 'package:obtainium/providers/settings_provider.dart';
class AppNames { class AppNames {
late String author; late String author;
@@ -354,7 +355,8 @@ class SourceProvider {
apk.apkUrls.length - 1, apk.apkUrls.length - 1,
additionalSettings, additionalSettings,
DateTime.now(), DateTime.now(),
currentApp?.pinned ?? false); currentApp?.pinned ?? false,
category: currentApp?.category);
} }
// Returns errors in [results, errors] instead of throwing them // Returns errors in [results, errors] instead of throwing them