diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 7a4fa238..e9794497 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -1,7 +1,8 @@ { "main": { "dashboardTab": "Dashboard", - "patcherTab": "Patcher" + "patcherTab": "Patcher", + "settingsTab": "Settings" }, "homeView": { "widgetTitle": "Dashboard", @@ -47,5 +48,18 @@ "patchesSelectorView": { "searchBarHint": "Search patches", "fabButton": "Done" + }, + "settingsView": { + "widgetTitle": "Settings", + "languageLabel": "Language", + "themeLabel": "Theme", + "themeHint": "Change the theme of the app", + "dynamicColorsLabel": "Dynamic Colors", + "dynamicColorsHint": "Enable dynamic colors", + "darkThemeLabel": "Dark", + "lightThemeLabel": "Light", + "versionLabel": "Version", + "aboutLabel": "About", + "contributorsLabel": "Contributors" } } \ No newline at end of file diff --git a/lib/app/app.dart b/lib/app/app.dart index fc67f5ed..04795c5f 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -6,6 +6,7 @@ import 'package:revanced_manager/ui/views/patcher/patcher_view.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_view.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; +import 'package:revanced_manager/ui/views/settings/settings_view.dart'; import 'package:stacked/stacked_annotations.dart'; import 'package:stacked_services/stacked_services.dart'; @@ -14,6 +15,7 @@ import 'package:stacked_services/stacked_services.dart'; MaterialRoute(page: AppSelectorView), MaterialRoute(page: PatcherView), MaterialRoute(page: PatchesSelectorView), + MaterialRoute(page: SettingsView) ], dependencies: [ LazySingleton(classType: NavigationService), LazySingleton(classType: PatcherAPI), diff --git a/lib/app/app.locator.dart b/lib/app/app.locator.dart index 6adbad33..ebed2387 100644 --- a/lib/app/app.locator.dart +++ b/lib/app/app.locator.dart @@ -6,9 +6,7 @@ // ignore_for_file: public_member_api_docs -// ignore: depend_on_referenced_packages import 'package:stacked_core/stacked_core.dart'; -// ignore: implementation_imports import 'package:stacked_services/src/navigation/navigation_service.dart'; import '../services/patcher_api.dart'; diff --git a/lib/app/app.router.dart b/lib/app/app.router.dart index f24aabaf..0e19c876 100644 --- a/lib/app/app.router.dart +++ b/lib/app/app.router.dart @@ -7,12 +7,13 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart' as _i1; -import 'package:stacked_services/stacked_services.dart' as _i6; +import 'package:stacked_services/stacked_services.dart' as _i7; import '../ui/views/app_selector/app_selector_view.dart' as _i3; import '../ui/views/home/home_view.dart' as _i2; import '../ui/views/patcher/patcher_view.dart' as _i4; import '../ui/views/patches_selector/patches_selector_view.dart' as _i5; +import '../ui/views/settings/settings_view.dart' as _i6; class Routes { static const homeView = '/home-view'; @@ -23,11 +24,14 @@ class Routes { static const patchesSelectorView = '/patches-selector-view'; + static const settingsView = '/settings-view'; + static const all = { homeView, appSelectorView, patcherView, - patchesSelectorView + patchesSelectorView, + settingsView }; } @@ -36,7 +40,8 @@ class StackedRouter extends _i1.RouterBase { _i1.RouteDef(Routes.homeView, page: _i2.HomeView), _i1.RouteDef(Routes.appSelectorView, page: _i3.AppSelectorView), _i1.RouteDef(Routes.patcherView, page: _i4.PatcherView), - _i1.RouteDef(Routes.patchesSelectorView, page: _i5.PatchesSelectorView) + _i1.RouteDef(Routes.patchesSelectorView, page: _i5.PatchesSelectorView), + _i1.RouteDef(Routes.settingsView, page: _i6.SettingsView) ]; final _pagesMap = { @@ -63,6 +68,12 @@ class StackedRouter extends _i1.RouterBase { builder: (context) => const _i5.PatchesSelectorView(), settings: data, ); + }, + _i6.SettingsView: (data) { + return MaterialPageRoute( + builder: (context) => const _i6.SettingsView(), + settings: data, + ); } }; @@ -72,7 +83,7 @@ class StackedRouter extends _i1.RouterBase { Map get pagesMap => _pagesMap; } -extension NavigatorStateExtension on _i6.NavigationService { +extension NavigatorStateExtension on _i7.NavigationService { Future navigateToHomeView( [int? routerId, bool preventDuplicates = true, @@ -128,4 +139,18 @@ extension NavigatorStateExtension on _i6.NavigationService { parameters: parameters, transition: transition); } + + Future navigateToSettingsView( + [int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function( + BuildContext, Animation, Animation, Widget)? + transition]) async { + navigateTo(Routes.settingsView, + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } } diff --git a/lib/main.dart b/lib/main.dart index 6db54481..77036070 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; + // ignore: depend_on_referenced_packages import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:revanced_manager/app/app.locator.dart'; @@ -8,6 +9,7 @@ import 'package:revanced_manager/main_viewmodel.dart'; import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/ui/views/home/home_view.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_view.dart'; +import 'package:revanced_manager/ui/views/settings/settings_view.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; @@ -71,6 +73,13 @@ class Navigation extends StatelessWidget { 'main.patcherTab', ), ), + NavigationDestination( + icon: const Icon(Icons.settings), + label: FlutterI18n.translate( + context, + 'main.settingsTab', + ), + ), ], ), ), @@ -83,6 +92,8 @@ class Navigation extends StatelessWidget { return const HomeView(); case 1: return const PatcherView(); + case 2: + return const SettingsView(); default: return const HomeView(); } diff --git a/lib/ui/views/settings/settings_view.dart b/lib/ui/views/settings/settings_view.dart new file mode 100644 index 00000000..09d56eea --- /dev/null +++ b/lib/ui/views/settings/settings_view.dart @@ -0,0 +1,99 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; +import 'package:stacked/stacked.dart'; + +class SettingsView extends StatelessWidget { + const SettingsView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return ViewModelBuilder.reactive( + viewModelBuilder: () => SettingsViewModel(), + builder: (context, SettingsViewModel model, child) => Scaffold( + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ListView( + children: [ + I18nText( + 'settingsView.widgetTitle', + child: Text( + '', + style: Theme.of(context).textTheme.headline5, + ), + ), + ListTile( + title: I18nText('settingsView.themeLabel'), + subtitle: I18nText('settingsView.themeHint'), + trailing: Switch( + value: model.isDarkMode, + onChanged: (value) { + model.toggleTheme(); + }, + ), + onTap: () { + model.toggleTheme; + }, + ), + ListTile( + title: I18nText('settingsView.dynamicColorsLabel'), + subtitle: I18nText('settingsView.dynamicColorsHint'), + trailing: Switch( + value: model.isDynamicColors, + onChanged: (value) { + model.toggleDynamicColors(); + }, + ), + onTap: () { + model.toggleDynamicColors(); + }, + ), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + I18nText( + 'settingsView.languageLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 16, + ), + ), + ), + DropdownButton( + value: 'en', + items: const [ + DropdownMenuItem( + value: 'en', + child: Text('English'), + ), + DropdownMenuItem( + value: 'fr', + child: Text('French'), + ), + ], + onChanged: (value) { + value = value; + }, + ), + ], + ), + ), + ListTile( + title: I18nText('settingsView.aboutLabel'), + ), + ListTile( + title: I18nText('settingsView.contributorsLabel'), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/ui/views/settings/settings_viewmodel.dart b/lib/ui/views/settings/settings_viewmodel.dart new file mode 100644 index 00000000..beeff225 --- /dev/null +++ b/lib/ui/views/settings/settings_viewmodel.dart @@ -0,0 +1,20 @@ +import 'package:stacked/stacked.dart'; + +class SettingsViewModel extends BaseViewModel { + bool isDarkMode = true; + bool isDynamicColors = false; + + void toggleDynamicColors() { + isDynamicColors = !isDynamicColors; + notifyListeners(); + } + + void toggleTheme() { + isDarkMode = !isDarkMode; + notifyListeners(); + } + + void setLanguage(String language) { + notifyListeners(); + } +}