Added category add/remove (no recolour/rename for now)

This commit is contained in:
Imran Remtulla
2022-12-21 03:08:56 -05:00
parent e2f99c5e71
commit 99d7595f2d
3 changed files with 126 additions and 3 deletions

View File

@@ -1,8 +1,12 @@
import 'dart:math';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:obtainium/components/custom_app_bar.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/providers/apps_provider.dart';
import 'package:obtainium/providers/logs_provider.dart';
import 'package:obtainium/providers/settings_provider.dart';
import 'package:obtainium/providers/source_provider.dart';
@@ -17,11 +21,27 @@ class SettingsPage extends StatefulWidget {
State<SettingsPage> createState() => _SettingsPageState();
}
// Generates a random light color
// Courtesy of ChatGPT 😭 (with a bugfix 🥳)
Color generateRandomLightColor() {
// Create a random number generator
final Random random = Random();
// Generate random hue, saturation, and value values
final double hue = random.nextDouble() * 360;
final double saturation = 0.5 + random.nextDouble() * 0.5;
final double value = 0.9 + random.nextDouble() * 0.1;
// Create a HSV color with the random values
return HSVColor.fromAHSV(1.0, hue, saturation, value).toColor();
}
class _SettingsPageState extends State<SettingsPage> {
@override
Widget build(BuildContext context) {
SettingsProvider settingsProvider = context.watch<SettingsProvider>();
SourceProvider sourceProvider = SourceProvider();
AppsProvider appsProvider = context.read<AppsProvider>();
if (settingsProvider.prefs == null) {
settingsProvider.initializeSettings();
}
@@ -157,6 +177,8 @@ class _SettingsPageState extends State<SettingsPage> {
height: 16,
);
var categories = settingsProvider.categories;
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.surface,
body: CustomScrollView(slivers: <Widget>[
@@ -232,6 +254,94 @@ class _SettingsPageState extends State<SettingsPage> {
color: Theme.of(context).colorScheme.primary),
),
...sourceSpecificFields,
intervalDropdown,
const Divider(
height: 48,
),
Text(
'Categories', // TODO
style: TextStyle(
color: Theme.of(context).colorScheme.primary),
),
height16,
Wrap(
children: [
...categories.entries.toList().map((e) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4),
child: Chip(
label: Text(e.key),
backgroundColor: Color(e.value),
visualDensity: VisualDensity.compact,
onDeleted: () {
showDialog<Map<String, String>?>(
context: context,
builder: (BuildContext ctx) {
return GeneratedFormModal(
// TODO
title: 'Delete Category?',
message:
'All Apps in ${e.key} will be set to uncategorized.',
items: []);
}).then((value) {
if (value != null) {
setState(() {
categories.remove(e.key);
settingsProvider.categories =
categories;
});
appsProvider.saveApps(appsProvider
.apps.values
.where((element) =>
element.app.category ==
e.key)
.map((e) {
var a = e.app;
a.category = null;
return a;
}).toList());
}
});
},
));
}),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 4),
child: IconButton(
onPressed: () {
showDialog<Map<String, String>?>(
context: context,
builder: (BuildContext ctx) {
// TODO
return GeneratedFormModal(
title: 'Add Category',
items: [
[
GeneratedFormItem('label',
label: 'Label')
]
]);
}).then((value) {
String? label = value?['label'];
if (label != null) {
setState(() {
categories[label] =
generateRandomLightColor()
.value;
settingsProvider.categories =
categories;
});
}
});
},
icon: const Icon(Icons.add),
visualDensity: VisualDensity.compact,
tooltip: tr('add'),
))
],
)
],
))),
SliverToBoxAdapter(

View File

@@ -1,5 +1,7 @@
// Exposes functions used to save/load app settings
import 'dart:convert';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
@@ -144,4 +146,11 @@ class SettingsProvider with ChangeNotifier {
prefs?.setString(settingId, value);
notifyListeners();
}
Map<String, int> get categories =>
Map<String, int>.from(jsonDecode(prefs?.getString('categories') ?? '{}'));
set categories(Map<String, int> cats) {
prefs?.setString('categories', jsonEncode(cats));
}
}

View File

@@ -47,6 +47,7 @@ class App {
late Map<String, String> additionalSettings;
late DateTime? lastUpdateCheck;
bool pinned = false;
String? category;
App(
this.id,
this.url,
@@ -58,7 +59,8 @@ class App {
this.preferredApkIndex,
this.additionalSettings,
this.lastUpdateCheck,
this.pinned);
this.pinned,
{this.category});
@override
String toString() {
@@ -107,7 +109,8 @@ class App {
json['lastUpdateCheck'] == null
? null
: DateTime.fromMicrosecondsSinceEpoch(json['lastUpdateCheck']),
json['pinned'] ?? false);
json['pinned'] ?? false,
category: json['category']);
}
Map<String, dynamic> toJson() => {
@@ -121,7 +124,8 @@ class App {
'preferredApkIndex': preferredApkIndex,
'additionalSettings': jsonEncode(additionalSettings),
'lastUpdateCheck': lastUpdateCheck?.microsecondsSinceEpoch,
'pinned': pinned
'pinned': pinned,
'category': category
};
}