Added settings page

This commit is contained in:
Imran Remtulla
2022-08-23 21:41:45 -04:00
parent 1a56806113
commit 0f7e3ec41d
6 changed files with 293 additions and 18 deletions

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:obtainium/pages/home.dart';
import 'package:obtainium/services/apps_provider.dart';
import 'package:obtainium/services/settings_provider.dart';
import 'package:obtainium/services/source_service.dart';
import 'package:provider/provider.dart';
import 'package:workmanager/workmanager.dart';
@@ -16,8 +17,8 @@ void backgroundUpdateCheck() {
String message = updates.length == 1
? '${updates[0].name} has an update.'
: '${(updates.length == 2 ? '${updates[0].name} and ${updates[1].name}' : '${updates[0].name} and ${updates.length - 1} more apps')} have updates.';
appsProvider.downloaderNotifications.cancel(2);
appsProvider.notify(
await appsProvider.downloaderNotifications.cancel(2);
await appsProvider.notify(
2,
'Updates Available',
message,
@@ -45,7 +46,10 @@ void main() async {
initialDelay: const Duration(minutes: 15),
constraints: Constraints(networkType: NetworkType.connected));
runApp(MultiProvider(
providers: [ChangeNotifierProvider(create: (context) => AppsProvider())],
providers: [
ChangeNotifierProvider(create: (context) => AppsProvider()),
ChangeNotifierProvider(create: (context) => SettingsProvider())
],
child: const MyApp(),
));
}
@@ -59,9 +63,34 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
// Initialize the settings provider (if needed) and perform first-run actions if needed
SettingsProvider settingsProvider = context.watch<SettingsProvider>();
if (settingsProvider.prefs == null) {
settingsProvider.initializeSettings().then((_) {
bool isFirstRun = settingsProvider.checkAndFlipFirstRun();
if (isFirstRun) {
AppsProvider appsProvider = context.read<AppsProvider>();
appsProvider
.notify(
3,
'Permission Notification',
'This is a transient notification used to trigger the Android 13 notification permission prompt',
'PERMISSION_NOTIFICATION',
'Permission Notifications',
'A transient notification used to trigger the Android 13 notification permission prompt',
important: false)
.whenComplete(() {
appsProvider.downloaderNotifications.cancel(3);
});
}
});
}
ColorScheme lightColorScheme;
ColorScheme darkColorScheme;
if (lightDynamic != null && darkDynamic != null) {
if (lightDynamic != null &&
darkDynamic != null &&
settingsProvider.colour == ColourSettings.materialYou) {
lightColorScheme = lightDynamic.harmonized();
darkColorScheme = darkDynamic.harmonized();
} else {
@@ -74,10 +103,15 @@ class MyApp extends StatelessWidget {
title: 'Obtainium',
theme: ThemeData(
useMaterial3: true,
colorScheme: lightColorScheme,
colorScheme: settingsProvider.theme == ThemeSettings.dark
? darkColorScheme
: lightColorScheme,
fontFamily: 'Metropolis'),
darkTheme:
ThemeData(useMaterial3: true, colorScheme: darkColorScheme),
darkTheme: ThemeData(
useMaterial3: true,
colorScheme: settingsProvider.theme == ThemeSettings.light
? lightColorScheme
: darkColorScheme),
home: const HomePage());
});
}

View File

@@ -1,4 +1,7 @@
import 'package:flutter/material.dart';
import 'package:obtainium/services/settings_provider.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher_string.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({super.key});
@@ -10,11 +13,74 @@ class SettingsPage extends StatefulWidget {
class _SettingsPageState extends State<SettingsPage> {
@override
Widget build(BuildContext context) {
return Center(
child: Text(
'No Configurable Settings Yet.',
style: Theme.of(context).textTheme.bodyLarge,
textAlign: TextAlign.center,
SettingsProvider settingsProvider = context.watch<SettingsProvider>();
if (settingsProvider.prefs == null) {
settingsProvider.initializeSettings();
}
return Padding(
padding: const EdgeInsets.all(16),
child: settingsProvider.prefs == null
? Container()
: Column(
children: [
DropdownButtonFormField(
decoration: const InputDecoration(labelText: 'Theme'),
value: settingsProvider.theme,
items: const [
DropdownMenuItem(
value: ThemeSettings.dark,
child: Text('Dark'),
),
DropdownMenuItem(
value: ThemeSettings.light,
child: Text('Light'),
),
DropdownMenuItem(
value: ThemeSettings.system,
child: Text('Follow System'),
)
],
onChanged: (value) {
if (value != null) {
settingsProvider.theme = value;
}
}),
const SizedBox(
height: 16,
),
DropdownButtonFormField(
decoration: const InputDecoration(labelText: 'Colour'),
value: settingsProvider.colour,
items: const [
DropdownMenuItem(
value: ColourSettings.basic,
child: Text('Obtainium'),
),
DropdownMenuItem(
value: ColourSettings.materialYou,
child: Text('Material You'),
)
],
onChanged: (value) {
if (value != null) {
settingsProvider.colour = value;
}
}),
const Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
ElevatedButton.icon(
onPressed: () {
launchUrlString(settingsProvider.sourceUrl,
mode: LaunchMode.externalApplication);
},
icon: const Icon(Icons.code),
label: const Text('Source'),
)
],
),
],
));
}
}

View File

@@ -51,7 +51,8 @@ class AppsProvider with ChangeNotifier {
}
Future<void> notify(int id, String title, String message, String channelCode,
String channelName, String channelDescription) {
String channelName, String channelDescription,
{bool important = true}) {
return downloaderNotifications.show(
id,
title,
@@ -59,8 +60,8 @@ class AppsProvider with ChangeNotifier {
NotificationDetails(
android: AndroidNotificationDetails(channelCode, channelName,
channelDescription: channelDescription,
importance: Importance.max,
priority: Priority.max,
importance: important ? Importance.max : Importance.min,
priority: important ? Priority.max : Priority.min,
groupKey: 'dev.imranr.obtainium.$channelCode')));
}
@@ -98,6 +99,7 @@ class AppsProvider with ChangeNotifier {
}
if (!isForeground) {
await downloaderNotifications.cancel(1);
await notify(
1,
'Complete App Installation',

View File

@@ -0,0 +1,47 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
enum ThemeSettings { system, light, dark }
enum ColourSettings { basic, materialYou }
class SettingsProvider with ChangeNotifier {
SharedPreferences? prefs;
String sourceUrl = 'https://github.com/ImranR98/Obtainium';
// Not done in constructor as we want to be able to await it
Future<void> initializeSettings() async {
prefs = await SharedPreferences.getInstance();
notifyListeners();
}
ThemeSettings get theme {
return ThemeSettings
.values[prefs?.getInt('theme') ?? ThemeSettings.system.index];
}
set theme(ThemeSettings t) {
print(t);
prefs?.setInt('theme', t.index);
notifyListeners();
}
ColourSettings get colour {
return ColourSettings
.values[prefs?.getInt('colour') ?? ColourSettings.basic.index];
}
set colour(ColourSettings t) {
prefs?.setInt('colour', t.index);
notifyListeners();
}
checkAndFlipFirstRun() {
bool result = prefs?.getBool('firstRun') ?? true;
if (result) {
prefs?.setBool('firstRun', false);
}
return result;
}
}

View File

@@ -172,6 +172,11 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
html:
dependency: "direct main"
description:
@@ -207,6 +212,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
json_annotation:
dependency: transitive
description:
@@ -340,6 +352,62 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.3"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.15"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.12"
shared_preferences_ios:
dependency: transitive
description:
name: shared_preferences_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
shared_preferences_macos:
dependency: transitive
description:
name: shared_preferences_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
sky_engine:
dependency: transitive
description: flutter
@@ -401,6 +469,62 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.5"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.17"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.17"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
vector_math:
dependency: transitive
description:

View File

@@ -37,15 +37,17 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
path_provider: ^2.0.11
flutter_fgbg: ^0.2.0
flutter_fgbg: ^0.2.0 # Try removing reliance on this
flutter_local_notifications: ^9.7.0
provider: ^6.0.3
http: ^0.13.5
webview_flutter: ^3.0.4
workmanager: ^0.5.0
dynamic_color: ^1.5.3
install_plugin_v2: ^1.0.0
install_plugin_v2: ^1.0.0 # Try replacing this
html: ^0.15.0
shared_preferences: ^2.0.15
url_launcher: ^6.1.5
dev_dependencies: