mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-26 03:03:45 +01:00 
			
		
		
		
	Category displayed on App/Apps pages
+ category save bugfix
This commit is contained in:
		| @@ -1,6 +1,7 @@ | ||||
| import 'package:easy_localization/easy_localization.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/services.dart'; | ||||
| import 'package:obtainium/components/generated_form.dart'; | ||||
| import 'package:obtainium/components/generated_form_modal.dart'; | ||||
| import 'package:obtainium/custom_errors.dart'; | ||||
| import 'package:obtainium/main.dart'; | ||||
| @@ -33,6 +34,7 @@ class _AppPageState extends State<AppPage> { | ||||
|       }); | ||||
|     } | ||||
|  | ||||
|     var categories = settingsProvider.categories; | ||||
|     var sourceProvider = SourceProvider(); | ||||
|     AppInMemory? app = appsProvider.apps[widget.appId]; | ||||
|     var source = app != null ? sourceProvider.getSource(app.app.url) : null; | ||||
| @@ -148,7 +150,63 @@ class _AppPageState extends State<AppPage> { | ||||
|                           textAlign: TextAlign.center, | ||||
|                           style: const TextStyle( | ||||
|                               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 | ||||
|                                   ]) | ||||
|                       ], | ||||
|                     )), | ||||
|                   ], | ||||
|   | ||||
| @@ -225,96 +225,114 @@ class AppsPageState extends State<AppsPage> { | ||||
|               String? changesUrl = SourceProvider() | ||||
|                   .getSource(sortedApps[index].app.url) | ||||
|                   .changeLogPageFromStandardUrl(sortedApps[index].app.url); | ||||
|               return ListTile( | ||||
|                 tileColor: sortedApps[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), | ||||
|                 onLongPress: () { | ||||
|                   toggleAppSelected(sortedApps[index].app); | ||||
|                 }, | ||||
|                 leading: sortedApps[index].installedInfo != null | ||||
|                     ? Image.memory( | ||||
|                         sortedApps[index].installedInfo!.icon!, | ||||
|                         gaplessPlayback: true, | ||||
|                       ) | ||||
|                     : null, | ||||
|                 title: Text( | ||||
|                   sortedApps[index].installedInfo?.name ?? | ||||
|                       sortedApps[index].app.name, | ||||
|                   style: TextStyle( | ||||
|                       fontWeight: sortedApps[index].app.pinned | ||||
|                           ? FontWeight.bold | ||||
|                           : FontWeight.normal), | ||||
|                 ), | ||||
|                 subtitle: Text(tr('byX', args: [sortedApps[index].app.author]), | ||||
|                     style: TextStyle( | ||||
|               return Container( | ||||
|                   decoration: BoxDecoration( | ||||
|                       border: Border.symmetric( | ||||
|                           vertical: BorderSide( | ||||
|                               width: 3, | ||||
|                               color: Color(settingsProvider.categories[ | ||||
|                                       sortedApps[index].app.category] ?? | ||||
|                                   const Color.fromARGB(0, 0, 0, 0).value)))), | ||||
|                   child: ListTile( | ||||
|                     tileColor: sortedApps[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), | ||||
|                     onLongPress: () { | ||||
|                       toggleAppSelected(sortedApps[index].app); | ||||
|                     }, | ||||
|                     leading: sortedApps[index].installedInfo != null | ||||
|                         ? Image.memory( | ||||
|                             sortedApps[index].installedInfo!.icon!, | ||||
|                             gaplessPlayback: true, | ||||
|                           ) | ||||
|                         : null, | ||||
|                     title: Text( | ||||
|                       sortedApps[index].installedInfo?.name ?? | ||||
|                           sortedApps[index].app.name, | ||||
|                       style: TextStyle( | ||||
|                         fontWeight: sortedApps[index].app.pinned | ||||
|                             ? FontWeight.bold | ||||
|                             : FontWeight.normal)), | ||||
|                 trailing: SingleChildScrollView( | ||||
|                     reverse: true, | ||||
|                     child: sortedApps[index].downloadProgress != null | ||||
|                         ? Text(tr('percentProgress', args: [ | ||||
|                             sortedApps[index] | ||||
|                                     .downloadProgress | ||||
|                                     ?.toInt() | ||||
|                                     .toString() ?? | ||||
|                                 '100' | ||||
|                           ])) | ||||
|                         : (Column( | ||||
|                             mainAxisAlignment: MainAxisAlignment.center, | ||||
|                             crossAxisAlignment: CrossAxisAlignment.end, | ||||
|                             children: [ | ||||
|                               SizedBox( | ||||
|                                   width: 100, | ||||
|                                   child: Text( | ||||
|                                     '${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBrackets')}' : ''}', | ||||
|                                     overflow: TextOverflow.fade, | ||||
|                                     textAlign: TextAlign.end, | ||||
|                                   )), | ||||
|                               sortedApps[index].app.installedVersion != null && | ||||
|                                       sortedApps[index].app.installedVersion != | ||||
|                                           sortedApps[index].app.latestVersion | ||||
|                                   ? GestureDetector( | ||||
|                                       onTap: changesUrl == null | ||||
|                                           ? null | ||||
|                                           : () { | ||||
|                                               launchUrlString(changesUrl, | ||||
|                                                   mode: LaunchMode | ||||
|                                                       .externalApplication); | ||||
|                                             }, | ||||
|                                       child: appsProvider.areDownloadsRunning() | ||||
|                                           ? Text(tr('pleaseWait')) | ||||
|                                           : Text( | ||||
|                                               '${tr('updateAvailable')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBracketsShort')}' : ''}', | ||||
|                                               style: TextStyle( | ||||
|                                                   fontStyle: FontStyle.italic, | ||||
|                                                   decoration: changesUrl == 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)), | ||||
|                     ); | ||||
|                   } | ||||
|                 }, | ||||
|               ); | ||||
|                             : FontWeight.normal, | ||||
|                       ), | ||||
|                     ), | ||||
|                     subtitle: Text( | ||||
|                         tr('byX', args: [sortedApps[index].app.author]), | ||||
|                         style: TextStyle( | ||||
|                             fontWeight: sortedApps[index].app.pinned | ||||
|                                 ? FontWeight.bold | ||||
|                                 : FontWeight.normal)), | ||||
|                     trailing: SingleChildScrollView( | ||||
|                         reverse: true, | ||||
|                         child: sortedApps[index].downloadProgress != null | ||||
|                             ? Text(tr('percentProgress', args: [ | ||||
|                                 sortedApps[index] | ||||
|                                         .downloadProgress | ||||
|                                         ?.toInt() | ||||
|                                         .toString() ?? | ||||
|                                     '100' | ||||
|                               ])) | ||||
|                             : (Column( | ||||
|                                 mainAxisAlignment: MainAxisAlignment.center, | ||||
|                                 crossAxisAlignment: CrossAxisAlignment.end, | ||||
|                                 children: [ | ||||
|                                   SizedBox( | ||||
|                                       width: 100, | ||||
|                                       child: Text( | ||||
|                                         '${sortedApps[index].app.installedVersion ?? tr('notInstalled')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBrackets')}' : ''}', | ||||
|                                         overflow: TextOverflow.fade, | ||||
|                                         textAlign: TextAlign.end, | ||||
|                                       )), | ||||
|                                   sortedApps[index].app.installedVersion != | ||||
|                                               null && | ||||
|                                           sortedApps[index] | ||||
|                                                   .app | ||||
|                                                   .installedVersion != | ||||
|                                               sortedApps[index] | ||||
|                                                   .app | ||||
|                                                   .latestVersion | ||||
|                                       ? GestureDetector( | ||||
|                                           onTap: changesUrl == null | ||||
|                                               ? null | ||||
|                                               : () { | ||||
|                                                   launchUrlString(changesUrl, | ||||
|                                                       mode: LaunchMode | ||||
|                                                           .externalApplication); | ||||
|                                                 }, | ||||
|                                           child: appsProvider | ||||
|                                                   .areDownloadsRunning() | ||||
|                                               ? Text(tr('pleaseWait')) | ||||
|                                               : Text( | ||||
|                                                   '${tr('updateAvailable')}${sortedApps[index].app.additionalSettings['trackOnly'] == 'true' ? ' ${tr('estimateInBracketsShort')}' : ''}', | ||||
|                                                   style: TextStyle( | ||||
|                                                       fontStyle: | ||||
|                                                           FontStyle.italic, | ||||
|                                                       decoration: changesUrl == | ||||
|                                                               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)) | ||||
|           ])), | ||||
|       persistentFooterButtons: [ | ||||
|   | ||||
| @@ -19,6 +19,7 @@ import 'package:obtainium/app_sources/steammobile.dart'; | ||||
| import 'package:obtainium/components/generated_form.dart'; | ||||
| import 'package:obtainium/custom_errors.dart'; | ||||
| import 'package:obtainium/mass_app_sources/githubstars.dart'; | ||||
| import 'package:obtainium/providers/settings_provider.dart'; | ||||
|  | ||||
| class AppNames { | ||||
|   late String author; | ||||
| @@ -354,7 +355,8 @@ class SourceProvider { | ||||
|         apk.apkUrls.length - 1, | ||||
|         additionalSettings, | ||||
|         DateTime.now(), | ||||
|         currentApp?.pinned ?? false); | ||||
|         currentApp?.pinned ?? false, | ||||
|         category: currentApp?.category); | ||||
|   } | ||||
|  | ||||
|   // Returns errors in [results, errors] instead of throwing them | ||||
|   | ||||
		Reference in New Issue
	
	Block a user