mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-12 01:50:15 +02:00
Added settings page
This commit is contained in:
@@ -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());
|
||||
});
|
||||
}
|
||||
|
@@ -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'),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@@ -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',
|
||||
|
47
lib/services/settings_provider.dart
Normal file
47
lib/services/settings_provider.dart
Normal 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;
|
||||
}
|
||||
}
|
124
pubspec.lock
124
pubspec.lock
@@ -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:
|
||||
|
@@ -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:
|
||||
|
Reference in New Issue
Block a user