diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 828fd7a7..2cfd566e 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -71,7 +71,10 @@ "aboutLabel": "About", "contributorsLabel": "Contributors", "rootModeLabel": "Root Mode", - "rootModeHint": "Enable this if you want to patch applications as rooted." + "rootModeHint": "Enable this if you want to patch applications as rooted.", + "organizationLabel": "Organization", + "patchesSourceLabel" : "Patches Source", + "integrationsSourceLabel": "Integrations Source" }, "rootCheckerView": { "widgetTitle": "Is your device rooted?", diff --git a/lib/constants.dart b/lib/constants.dart index 668449d6..bd318280 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -19,9 +19,9 @@ final kSettingItemSubtitleTextStyle = GoogleFonts.roboto( fontWeight: FontWeight.w300, ); -const ghOrg = 'revanced'; -const patchesRepo = 'revanced-patches'; -const integrationsRepo = 'revanced-integrations'; +String ghOrg = 'revanced'; +String patchesRepo = 'revanced-patches'; +String integrationsRepo = 'revanced-integrations'; const patcherRepo = 'revanced-patcher'; const cliRepo = 'revanced-cli'; const managerRepo = 'revanced-manager'; diff --git a/lib/main.dart b/lib/main.dart index 037a7bf4..536c3d8b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -128,7 +128,7 @@ class Navigation extends StatelessWidget { case 1: return const PatcherView(); case 2: - return const SettingsView(); + return SettingsView(); default: return const HomeView(); } diff --git a/lib/ui/views/settings/settings_view.dart b/lib/ui/views/settings/settings_view.dart index a3fb2fb2..b4684b3c 100644 --- a/lib/ui/views/settings/settings_view.dart +++ b/lib/ui/views/settings/settings_view.dart @@ -5,12 +5,18 @@ import 'package:revanced_manager/constants.dart'; import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/about_info_widget.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/custom_text_field.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_switch_item.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_themes/stacked_themes.dart'; class SettingsView extends StatelessWidget { - const SettingsView({Key? key}) : super(key: key); + final TextEditingController organizationController = TextEditingController(); + final TextEditingController patchesSourceController = TextEditingController(); + final TextEditingController integrationsSourceController = + TextEditingController(); + + SettingsView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -19,102 +25,128 @@ class SettingsView extends StatelessWidget { viewModelBuilder: () => SettingsViewModel(), onModelReady: (model) => model.initialize(), builder: (context, SettingsViewModel model, child) => Scaffold( - body: SafeArea( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 60), - I18nText( - 'settingsView.widgetTitle', - child: Text( - '', - style: GoogleFonts.inter( - fontSize: 28, - fontWeight: FontWeight.w500, - ), - ), - ), - const SizedBox(height: 12), - SettingsSwitchItem( - title: 'settingsView.themeLabel', - subtitle: 'settingsView.themeHint', - value: isDark, - onTap: (value) { - isDark = value; - getThemeManager(context).toggleDarkLightTheme(); - }, - ), - ListTile( - title: I18nText( - 'settingsView.rootModeLabel', + body: SingleChildScrollView( + child: SafeArea( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 60), + I18nText( + 'settingsView.widgetTitle', child: Text( '', - style: kSettingItemTextStyle, + style: GoogleFonts.inter( + fontSize: 28, + fontWeight: FontWeight.w500, + ), ), ), - subtitle: I18nText('settingsView.rootModeHint'), - trailing: GestureDetector( - onTap: () { - model.navigateToRootChecker(); + const SizedBox(height: 12), + SettingsSwitchItem( + title: 'settingsView.themeLabel', + subtitle: 'settingsView.themeHint', + value: isDark, + onTap: (value) { + isDark = value; + getThemeManager(context).toggleDarkLightTheme(); }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, vertical: 8), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - border: Border.all( - width: 1, - color: Theme.of(context).colorScheme.secondary, + ), + ListTile( + title: I18nText( + 'settingsView.rootModeLabel', + child: Text( + '', + style: kSettingItemTextStyle, + ), + ), + subtitle: I18nText('settingsView.rootModeHint'), + trailing: GestureDetector( + onTap: () { + model.navigateToRootChecker(); + }, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all( + width: 1, + color: Theme.of(context).colorScheme.secondary, + ), + ), + child: Text( + model.isRooted ? 'Rooted' : 'Not rooted', ), ), - child: Text( - model.isRooted ? 'Rooted' : 'Not rooted', - ), ), ), - ), - Container( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, + CustomTextField( + inputController: organizationController, + label: 'settingsView.organizationLabel', + hint: ghOrg, + onChanged: (value) { + ghOrg = value; + }, ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - I18nText( - 'settingsView.languageLabel', - child: Text('', style: kSettingItemTextStyle), - ), - DropdownButton( - value: 'en', - items: const [ - DropdownMenuItem( - value: 'en', - child: Text('English'), - ), - DropdownMenuItem( - value: 'fr', - child: Text('French'), - ), - ], - onChanged: (value) { - value = value; - }, - ), - ], + CustomTextField( + inputController: patchesSourceController, + label: 'settingsView.patchesSourceLabel', + hint: patchesRepo, + onChanged: (value) { + patchesRepo = value; + }, ), - ), - ListTile( - title: I18nText( - 'settingsView.contributorsLabel', - child: Text('', style: kSettingItemTextStyle), + CustomTextField( + inputController: integrationsSourceController, + label: 'settingsView.integrationsSourceLabel', + hint: integrationsRepo, + onChanged: (value) { + integrationsRepo = value; + }, ), - onTap: model.navigateToContributors, - ), - const AboutWidget(), - ], + Container( + padding: const EdgeInsets.symmetric( + horizontal: 16.0, + vertical: 8.0, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + I18nText( + 'settingsView.languageLabel', + child: Text('', style: kSettingItemTextStyle), + ), + 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.contributorsLabel', + child: Text('', style: kSettingItemTextStyle), + ), + onTap: model.navigateToContributors, + ), + const AboutWidget(), + ], + ), ), ), ), diff --git a/lib/ui/widgets/settingsView/custom_switch.dart b/lib/ui/widgets/settingsView/custom_switch.dart index 9976fd83..236b4936 100644 --- a/lib/ui/widgets/settingsView/custom_switch.dart +++ b/lib/ui/widgets/settingsView/custom_switch.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:fluttertoast/fluttertoast.dart'; class CustomSwitch extends StatelessWidget { final ValueChanged onChanged; diff --git a/lib/ui/widgets/settingsView/custom_text_field.dart b/lib/ui/widgets/settingsView/custom_text_field.dart new file mode 100644 index 00000000..270f7e75 --- /dev/null +++ b/lib/ui/widgets/settingsView/custom_text_field.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/theme.dart'; + +class CustomTextField extends StatelessWidget { + final TextEditingController inputController; + final String label; + final String hint; + final Function(String)? onChanged; + + const CustomTextField({ + Key? key, + required this.inputController, + required this.label, + required this.hint, + required this.onChanged, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + const errorColor = Color(0xffEF4444); + + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 8, + ), + TextField( + controller: inputController, + onChanged: onChanged, + keyboardType: TextInputType.text, + style: TextStyle( + fontSize: 14, + color: isDark ? Colors.grey[300] : Colors.black, + ), + decoration: InputDecoration( + label: I18nText(label), + labelStyle: + TextStyle(color: isDark ? Colors.grey[300] : Colors.black), + filled: true, + fillColor: Theme.of(context).colorScheme.primary, + hintText: hint, + hintStyle: TextStyle(color: Colors.grey.withOpacity(.75)), + contentPadding: + const EdgeInsets.symmetric(vertical: 0.0, horizontal: 20.0), + border: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.tertiary, + width: 1.0, + ), + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + gapPadding: 4.0, + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.secondary, + width: 2.0, + ), + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + ), + errorBorder: const OutlineInputBorder( + borderSide: BorderSide(color: errorColor, width: 1.0), + borderRadius: BorderRadius.all(Radius.circular(10.0)), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.tertiary, + width: 1.0, + ), + borderRadius: const BorderRadius.all(Radius.circular(10.0)), + ), + ), + ), + ], + ), + ); + } +}