feat: overall UI rework in Settings View (#53)

This commit is contained in:
Alberto Ponces 2022-09-02 14:35:25 +01:00 committed by GitHub
parent 036e8c99b3
commit 4f7b1d4520
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 485 additions and 361 deletions

View File

@ -11,7 +11,7 @@
"patchedSubtitle": "Patched Applications", "patchedSubtitle": "Patched Applications",
"updatesAvailable": "Updates Available", "updatesAvailable": "Updates Available",
"noUpdates": "No updates available", "noUpdates": "No updates available",
"noInstallations": "No patched apps installed", "noInstallations": "No patched applications installed",
"installed": "Installed", "installed": "Installed",
"notificationTitle": "ReVanced Manager was updated!", "notificationTitle": "ReVanced Manager was updated!",
"notificationText": "Tap to open the app", "notificationText": "Tap to open the app",
@ -40,7 +40,7 @@
"widgetTitle": "Select application", "widgetTitle": "Select application",
"widgetTitleSelected": "Selected application", "widgetTitleSelected": "Selected application",
"widgetSubtitle": "No application selected.", "widgetSubtitle": "No application selected.",
"noAppsLabel": "No apps found." "noAppsLabel": "No applications found."
}, },
"patchSelectorCard": { "patchSelectorCard": {
"widgetTitle": "Select patches", "widgetTitle": "Select patches",
@ -48,8 +48,16 @@
"widgetSubtitle": "Select an application first.", "widgetSubtitle": "Select an application first.",
"widgetEmptySubtitle": "No patches selected." "widgetEmptySubtitle": "No patches selected."
}, },
"socialMediaCards": { "socialMediaCard": {
"widgetTitle": "Social Media" "widgetTitle": "Social Media",
"widgetSubtitle": "We are online!"
},
"sourcesCard": {
"widgetTitle": "Sources",
"widgetSubtitle": "Add your custom sources",
"organizationLabel": "Organization",
"patchesSourceLabel" : "Patches Source",
"integrationsSourceLabel": "Integrations Source"
}, },
"appSelectorView": { "appSelectorView": {
"searchBarHint": "Search applications", "searchBarHint": "Search applications",
@ -75,19 +83,21 @@
}, },
"settingsView": { "settingsView": {
"widgetTitle": "Settings", "widgetTitle": "Settings",
"languageLabel": "Language", "appearanceSectionTitle": "Appearance",
"patcherSectionTitle": "Patcher",
"teamSectionTitle": "Team",
"infoSectionTitle": "Info",
"themeLabel": "Theme", "themeLabel": "Theme",
"themeHint": "Change the theme of the app", "themeHint": "Change the theme of the app",
"darkThemeLabel": "Dark", "languageLabel": "Language",
"lightThemeLabel": "Light", "englishOption": "English",
"versionLabel": "Version", "frenchOption": "French",
"aboutLabel": "About",
"contributorsLabel": "Contributors",
"rootModeLabel": "Root Mode", "rootModeLabel": "Root Mode",
"rootModeHint": "Enable this if you want to patch applications as rooted.", "rootModeHint": "Do you want to patch applications as rooted?",
"organizationLabel": "Organization", "contributorsLabel": "Contributors",
"patchesSourceLabel" : "Patches Source", "contributorsHint": "A list of contributors of ReVanced",
"integrationsSourceLabel": "Integrations Source" "aboutLabel": "About",
"versionLabel": "Version"
}, },
"rootCheckerView": { "rootCheckerView": {
"widgetTitle": "Is your device rooted?", "widgetTitle": "Is your device rooted?",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -32,6 +32,7 @@ var lightTheme = ThemeData.light().copyWith(
), ),
), ),
), ),
toggleableActiveColor: const Color(0xff3868AF),
colorScheme: const ColorScheme.light( colorScheme: const ColorScheme.light(
primary: Color.fromRGBO(154, 193, 252, 0.18), primary: Color.fromRGBO(154, 193, 252, 0.18),
secondary: Color(0xff3868AF), secondary: Color(0xff3868AF),
@ -69,6 +70,7 @@ var darkTheme = ThemeData.dark().copyWith(
), ),
), ),
), ),
toggleableActiveColor: const Color(0xff7792BA),
colorScheme: const ColorScheme.dark( colorScheme: const ColorScheme.dark(
primary: Color(0xff11161C), primary: Color(0xff11161C),
secondary: Color(0xff7792BA), secondary: Color(0xff7792BA),

View File

@ -50,7 +50,7 @@ class _AppSelectorViewState extends State<AppSelectorView> {
), ),
) )
: Column( : Column(
children: [ children: <Widget>[
SearchBar( SearchBar(
showSelectIcon: false, showSelectIcon: false,
fillColor: isDark fillColor: isDark

View File

@ -15,7 +15,7 @@ class ContributorsView extends StatelessWidget {
body: SafeArea( body: SafeArea(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
children: [ children: <Widget>[
ContributorsCard( ContributorsCard(
title: 'Patcher Contributors', title: 'Patcher Contributors',
contributors: model.patcherContributors, contributors: model.patcherContributors,

View File

@ -8,6 +8,7 @@ import 'package:revanced_manager/ui/widgets/homeView/available_updates_card.dart
import 'package:revanced_manager/ui/widgets/homeView/dashboard_raw_chip.dart'; import 'package:revanced_manager/ui/widgets/homeView/dashboard_raw_chip.dart';
import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart'; import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart';
import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart'; import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
class HomeView extends StatelessWidget { class HomeView extends StatelessWidget {
@ -22,24 +23,7 @@ class HomeView extends StatelessWidget {
builder: (context, model, child) => Scaffold( builder: (context, model, child) => Scaffold(
body: CustomScrollView( body: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
SliverAppBar( CustomSliverAppBar(
pinned: true,
snap: false,
floating: false,
expandedHeight: 100.0,
automaticallyImplyLeading: false,
backgroundColor: MaterialStateColor.resolveWith(
(states) => states.contains(MaterialState.scrolledUnder)
? isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!
: Theme.of(context).scaffoldBackgroundColor,
),
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.symmetric(
vertical: 23.0,
horizontal: 20.0,
),
title: I18nText( title: I18nText(
'homeView.widgetTitle', 'homeView.widgetTitle',
child: Text( child: Text(
@ -51,7 +35,6 @@ class HomeView extends StatelessWidget {
), ),
), ),
), ),
),
SliverPadding( SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 20.0), padding: const EdgeInsets.symmetric(horizontal: 20.0),
sliver: SliverList( sliver: SliverList(
@ -89,9 +72,9 @@ class HomeView extends StatelessWidget {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
children: [ children: <Widget>[
DashboardChip( DashboardChip(
label: 'homeView.updatesAvailable', label: I18nText('homeView.updatesAvailable'),
isSelected: model.showUpdatableApps, isSelected: model.showUpdatableApps,
onSelected: (value) { onSelected: (value) {
model.toggleUpdatableApps(true); model.toggleUpdatableApps(true);
@ -99,7 +82,7 @@ class HomeView extends StatelessWidget {
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
DashboardChip( DashboardChip(
label: 'homeView.installed', label: I18nText('homeView.installed'),
isSelected: !model.showUpdatableApps, isSelected: !model.showUpdatableApps,
onSelected: (value) { onSelected: (value) {
model.toggleUpdatableApps(false); model.toggleUpdatableApps(false);

View File

@ -1,8 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:revanced_manager/theme.dart';
import 'package:revanced_manager/ui/views/installer/installer_viewmodel.dart'; import 'package:revanced_manager/ui/views/installer/installer_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/installerView/custom_material_button.dart'; import 'package:revanced_manager/ui/widgets/installerView/custom_material_button.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
class InstallerView extends StatelessWidget { class InstallerView extends StatelessWidget {
@ -18,26 +19,7 @@ class InstallerView extends StatelessWidget {
body: CustomScrollView( body: CustomScrollView(
controller: model.scrollController, controller: model.scrollController,
slivers: <Widget>[ slivers: <Widget>[
SliverAppBar( CustomSliverAppBar(
pinned: true,
snap: false,
floating: false,
expandedHeight: 100.0,
automaticallyImplyLeading: false,
backgroundColor: MaterialStateColor.resolveWith(
(states) => states.contains(MaterialState.scrolledUnder)
? isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context)
.navigationBarTheme
.backgroundColor!
: Theme.of(context).scaffoldBackgroundColor,
),
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.symmetric(
vertical: 23.0,
horizontal: 20.0,
),
title: Text( title: Text(
model.headerLogs, model.headerLogs,
style: GoogleFonts.inter( style: GoogleFonts.inter(
@ -45,7 +27,6 @@ class InstallerView extends StatelessWidget {
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
),
bottom: PreferredSize( bottom: PreferredSize(
preferredSize: const Size(double.infinity, 1.0), preferredSize: const Size(double.infinity, 1.0),
child: LinearProgressIndicator( child: LinearProgressIndicator(
@ -84,17 +65,17 @@ class InstallerView extends StatelessWidget {
visible: !model.isPatching, visible: !model.isPatching,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: <Widget>[
CustomMaterialButton( CustomMaterialButton(
text: 'installerView.shareButton', label: I18nText('installerView.shareButton'),
isFilled: false, isFilled: false,
onPressed: () => model.shareResult(), onPressed: () => model.shareResult(),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
CustomMaterialButton( CustomMaterialButton(
text: model.isInstalled label: model.isInstalled
? 'installerView.openButton' ? I18nText('installerView.openButton')
: 'installerView.installButton', : I18nText('installerView.installButton'),
isFilled: true, isFilled: true,
isExpanded: true, isExpanded: true,
onPressed: () { onPressed: () {

View File

@ -9,6 +9,7 @@ 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_view.dart';
import 'package:revanced_manager/ui/widgets/patcherView/app_selector_card.dart'; import 'package:revanced_manager/ui/widgets/patcherView/app_selector_card.dart';
import 'package:revanced_manager/ui/widgets/patcherView/patch_selector_card.dart'; import 'package:revanced_manager/ui/widgets/patcherView/patch_selector_card.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
import 'package:revanced_manager/ui/widgets/shared/open_container_wrapper.dart'; import 'package:revanced_manager/ui/widgets/shared/open_container_wrapper.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
@ -39,24 +40,7 @@ class PatcherView extends StatelessWidget {
), ),
body: CustomScrollView( body: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
SliverAppBar( CustomSliverAppBar(
pinned: true,
snap: false,
floating: false,
expandedHeight: 100.0,
automaticallyImplyLeading: false,
backgroundColor: MaterialStateColor.resolveWith(
(states) => states.contains(MaterialState.scrolledUnder)
? isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!
: Theme.of(context).scaffoldBackgroundColor,
),
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.symmetric(
vertical: 23.0,
horizontal: 20.0,
),
title: I18nText( title: I18nText(
'patcherView.widgetTitle', 'patcherView.widgetTitle',
child: Text( child: Text(
@ -68,7 +52,6 @@ class PatcherView extends StatelessWidget {
), ),
), ),
), ),
),
SliverPadding( SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 20.0), padding: const EdgeInsets.symmetric(horizontal: 20.0),
sliver: SliverList( sliver: SliverList(

View File

@ -49,7 +49,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
), ),
) )
: Column( : Column(
children: [ children: <Widget>[
SearchBar( SearchBar(
showSelectIcon: true, showSelectIcon: true,
fillColor: fillColor:

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:revanced_manager/ui/views/root_checker/root_checker_viewmodel.dart'; import 'package:revanced_manager/ui/views/root_checker/root_checker_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/rootCheckerView/magisk_button.dart'; import 'package:revanced_manager/ui/widgets/rootCheckerView/magisk_button.dart';
@ -27,7 +27,7 @@ class RootCheckerView extends StatelessWidget {
height: double.infinity, height: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 28.0), padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 28.0),
child: Column( child: Column(
children: [ children: <Widget>[
const SizedBox(height: 120), const SizedBox(height: 120),
I18nText( I18nText(
'rootCheckerView.widgetTitle', 'rootCheckerView.widgetTitle',
@ -53,7 +53,7 @@ class RootCheckerView extends StatelessWidget {
Expanded( Expanded(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: <Widget>[
MagiskButton( MagiskButton(
onPressed: () => model.navigateAsRoot(), onPressed: () => model.navigateAsRoot(),
), ),

View File

@ -3,11 +3,16 @@ import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:revanced_manager/constants.dart'; import 'package:revanced_manager/constants.dart';
import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/theme.dart';
import 'package:revanced_manager/ui/views/contributors/contributors_view.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.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/about_widget.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_text_field.dart'; import 'package:revanced_manager/ui/widgets/settingsView/custom_switch_tile.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_switch_item.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.dart';
import 'package:revanced_manager/ui/widgets/settingsView/social_media_cards.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/social_media_widget.dart';
import 'package:revanced_manager/ui/widgets/settingsView/sources_widget.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
import 'package:revanced_manager/ui/widgets/shared/open_container_wrapper.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_themes/stacked_themes.dart'; import 'package:stacked_themes/stacked_themes.dart';
@ -22,30 +27,11 @@ class SettingsView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ViewModelBuilder<SettingsViewModel>.reactive( return ViewModelBuilder<SettingsViewModel>.reactive(
disposeViewModel: false,
viewModelBuilder: () => SettingsViewModel(), viewModelBuilder: () => SettingsViewModel(),
onModelReady: (model) => model.initialize(),
builder: (context, SettingsViewModel model, child) => Scaffold( builder: (context, SettingsViewModel model, child) => Scaffold(
body: CustomScrollView( body: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
SliverAppBar( CustomSliverAppBar(
pinned: true,
snap: false,
floating: false,
expandedHeight: 100.0,
automaticallyImplyLeading: false,
backgroundColor: MaterialStateColor.resolveWith(
(states) => states.contains(MaterialState.scrolledUnder)
? isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!
: Theme.of(context).scaffoldBackgroundColor,
),
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.symmetric(
vertical: 23.0,
horizontal: 20.0,
),
title: I18nText( title: I18nText(
'settingsView.widgetTitle', 'settingsView.widgetTitle',
child: Text( child: Text(
@ -57,22 +43,63 @@ class SettingsView extends StatelessWidget {
), ),
), ),
), ),
),
SliverPadding( SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 20.0), padding: const EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
sliver: SliverList( sliver: SliverList(
delegate: SliverChildListDelegate.fixed( delegate: SliverChildListDelegate.fixed(
<Widget>[ <Widget>[
SettingsSwitchItem( SettingsSection(
title: 'settingsView.themeLabel', title: 'settingsView.appearanceSectionTitle',
subtitle: 'settingsView.themeHint', children: <Widget>[
CustomSwitchTile(
title: I18nText(
'settingsView.themeLabel',
child: Text(
'',
style: kSettingItemTextStyle,
),
),
subtitle: I18nText('settingsView.themeHint'),
value: isDark, value: isDark,
onTap: (value) { onTap: (value) {
isDark = value; isDark = value;
getThemeManager(context).toggleDarkLightTheme(); getThemeManager(context).toggleDarkLightTheme();
}, },
), ),
],
),
SettingsTileDialog(
title: 'settingsView.languageLabel',
subtitle: 'English',
children: <Widget>[
RadioListTile<String>(
title: I18nText('settingsView.englishOption'),
value: 'en',
groupValue: 'en',
onChanged: (value) {
model.updateLanguage(context, value);
Navigator.of(context).pop();
},
),
RadioListTile<String>(
title: I18nText('settingsView.frenchOption'),
value: 'fr',
groupValue: 'en',
onChanged: (value) {
model.updateLanguage(context, value);
Navigator.of(context).pop();
},
),
]),
const Divider(thickness: 1.0),
SettingsSection(
title: 'settingsView.patcherSectionTitle',
children: <Widget>[
ListTile( ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText( title: I18nText(
'settingsView.rootModeLabel', 'settingsView.rootModeLabel',
child: Text( child: Text(
@ -81,90 +108,43 @@ class SettingsView extends StatelessWidget {
), ),
), ),
subtitle: I18nText('settingsView.rootModeHint'), subtitle: I18nText('settingsView.rootModeHint'),
trailing: GestureDetector( onTap: () => model.navigateToRootChecker(),
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,
), ),
), SourcesWidget(
child: Text( title: 'settingsView.sourcesLabel',
model.isRooted ? 'Rooted' : 'Not rooted', organizationController: organizationController,
), patchesSourceController: patchesSourceController,
), integrationsSourceController:
), integrationsSourceController,
),
CustomTextField(
inputController: organizationController,
label: 'settingsView.organizationLabel',
hint: ghOrg,
onChanged: (value) {
ghOrg = value;
},
),
CustomTextField(
inputController: patchesSourceController,
label: 'settingsView.patchesSourceLabel',
hint: patchesRepo,
onChanged: (value) {
patchesRepo = value;
},
),
CustomTextField(
inputController: integrationsSourceController,
label: 'settingsView.integrationsSourceLabel',
hint: integrationsRepo,
onChanged: (value) {
integrationsRepo = value;
},
),
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;
},
), ),
], ],
), ),
), const Divider(thickness: 1.0),
ListTile( SettingsSection(
title: 'settingsView.teamSectionTitle',
children: <Widget>[
OpenContainerWrapper(
openBuilder: (_, __) => const ContributorsView(),
closedBuilder: (_, openContainer) => ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText( title: I18nText(
'settingsView.contributorsLabel', 'settingsView.contributorsLabel',
child: Text('', style: kSettingItemTextStyle), child: Text('', style: kSettingItemTextStyle),
), ),
onTap: model.navigateToContributors, subtitle: I18nText('settingsView.contributorsHint'),
onTap: openContainer,
),
),
const SocialMediaWidget(),
],
),
const Divider(thickness: 1.0),
const SettingsSection(
title: 'settingsView.infoSectionTitle',
children: <Widget>[
AboutWidget(),
],
), ),
const SocialMediaCards(),
const AboutWidget(),
], ],
), ),
), ),

View File

@ -1,29 +1,26 @@
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/app/app.router.dart'; import 'package:revanced_manager/app/app.router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import 'package:timeago/timeago.dart';
class SettingsViewModel extends BaseViewModel { class SettingsViewModel extends BaseViewModel {
bool isRooted = false;
Future<void> initialize() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
isRooted = prefs.getBool('isRooted') ?? false;
notifyListeners();
}
final NavigationService _navigationService = locator<NavigationService>(); final NavigationService _navigationService = locator<NavigationService>();
void setLanguage(String language) { void setLanguage(String language) {
notifyListeners(); notifyListeners();
} }
void navigateToContributors() {
_navigationService.navigateTo(Routes.contributorsView);
}
void navigateToRootChecker() { void navigateToRootChecker() {
_navigationService.navigateTo(Routes.rootCheckerView); _navigationService.navigateTo(Routes.rootCheckerView);
} }
Future<void> updateLanguage(BuildContext context, String? value) async {
if (value != null) {
await FlutterI18n.refresh(context, Locale(value));
setLocaleMessages(value, EnMessages());
}
}
} }

View File

@ -32,7 +32,7 @@ class _InstalledAppItemState extends State<InstalledAppItem> {
), ),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
Container( Container(
width: 48, width: 48,
height: 48, height: 48,
@ -47,7 +47,7 @@ class _InstalledAppItemState extends State<InstalledAppItem> {
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Text( Text(
widget.name, widget.name,
maxLines: 2, maxLines: 2,

View File

@ -24,7 +24,7 @@ class _ContributorsCardState extends State<ContributorsCard> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 4.0), padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 4.0),
child: Text( child: Text(

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/models/patched_application.dart';
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
@ -22,7 +22,7 @@ class AvailableUpdatesCard extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20), padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20),
child: Center( child: Center(
child: Column( child: Column(
children: [ children: <Widget>[
Icon( Icon(
Icons.update_disabled, Icons.update_disabled,
size: 40, size: 40,

View File

@ -1,10 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/theme.dart';
class DashboardChip extends StatelessWidget { class DashboardChip extends StatelessWidget {
final String label; final Widget label;
final bool isSelected; final bool isSelected;
final Function(bool)? onSelected; final Function(bool)? onSelected;
@ -19,7 +18,7 @@ class DashboardChip extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return RawChip( return RawChip(
showCheckmark: false, showCheckmark: false,
label: I18nText(label), label: label,
selected: isSelected, selected: isSelected,
labelStyle: GoogleFonts.inter( labelStyle: GoogleFonts.inter(
color: isSelected color: isSelected

View File

@ -23,7 +23,7 @@ class InstalledAppsCard extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20), padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20),
child: Center( child: Center(
child: Column( child: Column(
children: [ children: <Widget>[
Icon( Icon(
Icons.file_download_off, Icons.file_download_off,
size: 40, size: 40,

View File

@ -32,12 +32,12 @@ class _LatestCommitCardState extends State<LatestCommitCard> {
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20), padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Row( Row(
children: [ children: <Widget>[
I18nText( I18nText(
'latestCommitCard.patcherLabel', 'latestCommitCard.patcherLabel',
child: Text( child: Text(
@ -67,7 +67,7 @@ class _LatestCommitCardState extends State<LatestCommitCard> {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
children: [ children: <Widget>[
I18nText( I18nText(
'latestCommitCard.managerLabel', 'latestCommitCard.managerLabel',
child: Text( child: Text(

View File

@ -1,16 +1,15 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/theme.dart';
class CustomMaterialButton extends StatelessWidget { class CustomMaterialButton extends StatelessWidget {
final String text; final Widget label;
final bool isFilled; final bool isFilled;
final bool isExpanded; final bool isExpanded;
final Function()? onPressed; final Function()? onPressed;
const CustomMaterialButton({ const CustomMaterialButton({
Key? key, Key? key,
required this.text, required this.label,
this.isFilled = true, this.isFilled = true,
this.isExpanded = false, this.isExpanded = false,
required this.onPressed, required this.onPressed,
@ -62,7 +61,7 @@ class CustomMaterialButton extends StatelessWidget {
), ),
), ),
onPressed: onPressed, onPressed: onPressed,
child: I18nText(text), child: label,
); );
} }
} }

View File

@ -27,7 +27,7 @@ class AppSelectorCard extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20), padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
I18nText( I18nText(
locator<PatcherViewModel>().selectedApp == null locator<PatcherViewModel>().selectedApp == null
? 'appSelectorCard.widgetTitle' ? 'appSelectorCard.widgetTitle'
@ -50,7 +50,7 @@ class AppSelectorCard extends StatelessWidget {
), ),
) )
: Row( : Row(
children: [ children: <Widget>[
SizedBox( SizedBox(
height: 16.0, height: 16.0,
child: ClipOval( child: ClipOval(

View File

@ -27,7 +27,7 @@ class PatchSelectorCard extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20), padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 20),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
I18nText( I18nText(
locator<PatcherViewModel>().selectedPatches.isEmpty locator<PatcherViewModel>().selectedPatches.isEmpty
? 'patchSelectorCard.widgetTitle' ? 'patchSelectorCard.widgetTitle'

View File

@ -48,17 +48,17 @@ class _PatchItemState extends State<PatchItem> {
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: Column( child: Column(
children: [ children: <Widget>[
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: <Widget>[
Flexible( Flexible(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: <Widget>[
Text( Text(
widget.simpleName, widget.simpleName,
style: GoogleFonts.inter( style: GoogleFonts.inter(
@ -98,7 +98,7 @@ class _PatchItemState extends State<PatchItem> {
), ),
widget.isUnsupported widget.isUnsupported
? Row( ? Row(
children: [ children: <Widget>[
Padding( Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8),
child: TextButton.icon( child: TextButton.icon(

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
@ -15,7 +15,7 @@ class MagiskButton extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: <Widget>[
GestureDetector( GestureDetector(
onTap: onPressed, onTap: onPressed,
child: CircleAvatar( child: CircleAvatar(

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/constants.dart'; import 'package:revanced_manager/constants.dart';
import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/theme.dart';
import 'package:revanced_manager/utils/about_info.dart'; import 'package:revanced_manager/utils/about_info.dart';
@ -16,10 +16,10 @@ class _AboutWidgetState extends State<AboutWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
I18nText( I18nText(
'settingsView.aboutLabel', 'settingsView.aboutLabel',
child: Text('', style: kSettingItemTextStyle), child: Text('', style: kSettingItemTextStyle),
@ -54,7 +54,7 @@ class _AboutWidgetState extends State<AboutWidget> {
}, },
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Text('Version: ${snapshot.data!['version']}', Text('Version: ${snapshot.data!['version']}',
style: kSettingItemSubtitleTextStyle), style: kSettingItemSubtitleTextStyle),
Text('Build: ${snapshot.data!['buildNumber']}', Text('Build: ${snapshot.data!['buildNumber']}',

View File

@ -20,12 +20,12 @@ class CustomSwitch extends StatelessWidget {
height: 25, height: 25,
width: 50, width: 50,
child: Stack( child: Stack(
children: [ children: <Widget>[
AnimatedContainer( AnimatedContainer(
height: 25, height: 25,
width: 50, width: 50,
curve: Curves.ease, curve: Curves.ease,
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 400),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all( borderRadius: const BorderRadius.all(
Radius.circular(25.0), Radius.circular(25.0),
@ -35,7 +35,7 @@ class CustomSwitch extends StatelessWidget {
), ),
AnimatedAlign( AnimatedAlign(
curve: Curves.ease, curve: Curves.ease,
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 400),
alignment: !value ? Alignment.centerLeft : Alignment.centerRight, alignment: !value ? Alignment.centerLeft : Alignment.centerRight,
child: Container( child: Container(
height: 20, height: 20,

View File

@ -1,15 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/constants.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_switch.dart'; import 'package:revanced_manager/ui/widgets/settingsView/custom_switch.dart';
class SettingsSwitchItem extends StatelessWidget { class CustomSwitchTile extends StatelessWidget {
final String title; final Widget title;
final String subtitle; final Widget subtitle;
final bool value; final bool value;
final Function(bool) onTap; final Function(bool) onTap;
const SettingsSwitchItem({ const CustomSwitchTile({
Key? key, Key? key,
required this.title, required this.title,
required this.subtitle, required this.subtitle,
@ -20,14 +18,9 @@ class SettingsSwitchItem extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ListTile( return ListTile(
title: I18nText( contentPadding: EdgeInsets.zero,
title, title: title,
child: Text( subtitle: subtitle,
'',
style: kSettingItemTextStyle,
),
),
subtitle: I18nText(subtitle),
trailing: CustomSwitch( trailing: CustomSwitch(
value: value, value: value,
onChanged: onTap, onChanged: onTap,

View File

@ -1,10 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/theme.dart'; import 'package:revanced_manager/theme.dart';
class CustomTextField extends StatelessWidget { class CustomTextField extends StatelessWidget {
final TextEditingController inputController; final TextEditingController inputController;
final String label; final Widget label;
final String hint; final String hint;
final Function(String)? onChanged; final Function(String)? onChanged;
@ -18,40 +17,42 @@ class CustomTextField extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const errorColor = Color(0xffEF4444);
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
const SizedBox( const SizedBox(height: 8),
height: 8,
),
TextField( TextField(
controller: inputController, controller: inputController,
onChanged: onChanged, onChanged: onChanged,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Theme.of(context).textTheme.headline5!.color,
),
cursorColor: Theme.of(context).textTheme.headline5!.color,
decoration: InputDecoration(
label: label,
labelStyle: TextStyle(
color: isDark ? Colors.grey[300] : Colors.black, color: isDark ? Colors.grey[300] : Colors.black,
), ),
decoration: InputDecoration(
label: I18nText(label),
labelStyle:
TextStyle(color: isDark ? Colors.grey[300] : Colors.black),
filled: true, filled: true,
fillColor: Theme.of(context).colorScheme.primary, fillColor: Theme.of(context).colorScheme.primary,
hintText: hint, hintText: hint,
hintStyle: TextStyle(color: Colors.grey.withOpacity(.75)), hintStyle: TextStyle(
contentPadding: color: Colors.grey.withOpacity(.75),
const EdgeInsets.symmetric(vertical: 0.0, horizontal: 20.0), ),
contentPadding: const EdgeInsets.symmetric(
vertical: 0.0,
horizontal: 20.0,
),
border: OutlineInputBorder( border: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary, color: Theme.of(context).colorScheme.tertiary,
width: 1.0, width: 1.0,
), ),
borderRadius: const BorderRadius.all(Radius.circular(10.0)), borderRadius: BorderRadius.circular(10),
gapPadding: 4.0, gapPadding: 4.0,
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
@ -59,18 +60,21 @@ class CustomTextField extends StatelessWidget {
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
width: 2.0, width: 2.0,
), ),
borderRadius: const BorderRadius.all(Radius.circular(10.0)), borderRadius: BorderRadius.circular(10),
), ),
errorBorder: const OutlineInputBorder( errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: errorColor, width: 1.0), borderSide: const BorderSide(
borderRadius: BorderRadius.all(Radius.circular(10.0)), color: Color(0xffEF4444),
width: 1.0,
),
borderRadius: BorderRadius.circular(10),
), ),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary, color: Theme.of(context).colorScheme.tertiary,
width: 1.0, width: 1.0,
), ),
borderRadius: const BorderRadius.all(Radius.circular(10.0)), borderRadius: BorderRadius.circular(10),
), ),
), ),
), ),

View File

@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
class SettingsSection extends StatelessWidget {
final String title;
final List<Widget> children;
const SettingsSection({
Key? key,
required this.title,
required this.children,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
padding: const EdgeInsets.only(top: 16.0, bottom: 10.0),
child: I18nText(
title,
child: Text(
'',
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
),
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
),
],
);
}
}

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/constants.dart';
class SettingsTileDialog extends StatelessWidget {
final String title;
final String subtitle;
final List<Widget> children;
const SettingsTileDialog({
Key? key,
required this.title,
required this.subtitle,
required this.children,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText(
title,
child: Text(
'',
style: kSettingItemTextStyle,
),
),
subtitle: I18nText(subtitle),
onTap: () => showDialog(
context: context,
builder: (context) => SimpleDialog(
title: I18nText(title),
backgroundColor: Theme.of(context).colorScheme.surface,
children: children,
),
),
);
}
}

View File

@ -1,11 +1,13 @@
import 'package:expandable/expandable.dart'; import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:revanced_manager/constants.dart'; import 'package:revanced_manager/constants.dart';
import 'package:revanced_manager/theme.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class SocialMediaCards extends StatelessWidget { class SocialMediaWidget extends StatelessWidget {
const SocialMediaCards({Key? key}) : super(key: key); const SocialMediaWidget({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -13,30 +15,39 @@ class SocialMediaCards extends StatelessWidget {
theme: ExpandableThemeData( theme: ExpandableThemeData(
hasIcon: true, hasIcon: true,
iconColor: Theme.of(context).iconTheme.color, iconColor: Theme.of(context).iconTheme.color,
animationDuration: const Duration(milliseconds: 450), iconPadding: const EdgeInsets.symmetric(vertical: 16.0),
animationDuration: const Duration(milliseconds: 400),
), ),
header: SizedBox( header: SizedBox(
width: double.infinity, width: double.infinity,
child: ListTile( child: ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText( title: I18nText(
'socialMediaCards.widgetTitle', 'socialMediaCard.widgetTitle',
child: Text('', style: kSettingItemTextStyle), child: Text('', style: kSettingItemTextStyle),
), ),
subtitle: I18nText(
'socialMediaCard.widgetSubtitle',
child: Text(
'',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: isDark ? Colors.grey[400] : Colors.grey[600],
),
),
),
), ),
), ),
expanded: Card( expanded: Card(
color: Theme.of(context).backgroundColor, color: isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!,
child: Column( child: Column(
children: [ children: <Widget>[
ListTile( ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding( leading: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Image.asset( child: FaIcon(
'assets/images/github.png', FontAwesomeIcons.github,
height: 24,
width: 24,
color: Theme.of(context).iconTheme.color, color: Theme.of(context).iconTheme.color,
), ),
), ),
@ -48,29 +59,25 @@ class SocialMediaCards extends StatelessWidget {
), ),
), ),
ListTile( ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding( leading: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0).copyWith(left: 5),
child: Icon( child: FaIcon(
Icons.discord, FontAwesomeIcons.discord,
color: Theme.of(context).iconTheme.color, color: Theme.of(context).iconTheme.color,
), ),
), ),
title: const Text('Discord'), title: const Text('Discord'),
subtitle: const Text('discord.gg/revanced'), subtitle: const Text('discord.gg/revanced'),
onTap: () => launchUrl( onTap: () => launchUrl(
Uri.parse('https://discord.gg/3E2pTWR4Yd'), Uri.parse('https://discord.gg/rF2YcEjcrT'),
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,
), ),
), ),
ListTile( ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding( leading: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Icon( child: FaIcon(
Icons.telegram, FontAwesomeIcons.telegram,
color: Theme.of(context).iconTheme.color, color: Theme.of(context).iconTheme.color,
), ),
), ),
@ -82,12 +89,10 @@ class SocialMediaCards extends StatelessWidget {
), ),
), ),
ListTile( ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding( leading: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Icon( child: FaIcon(
Icons.reddit, FontAwesomeIcons.reddit,
color: Theme.of(context).iconTheme.color, color: Theme.of(context).iconTheme.color,
), ),
), ),
@ -99,48 +104,39 @@ class SocialMediaCards extends StatelessWidget {
), ),
), ),
ListTile( ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding( leading: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Image.asset( child: FaIcon(
'assets/images/twitter.png', FontAwesomeIcons.twitter,
height: 24,
width: 24,
color: Theme.of(context).iconTheme.color, color: Theme.of(context).iconTheme.color,
), ),
), ),
title: const Text('Twitter'), title: const Text('Twitter'),
subtitle: const Text('@revancedapp'), subtitle: const Text('@revancedapp'),
onTap: () => launchUrl( onTap: () => launchUrl(
Uri.parse('https://twitter.com/@revancedapp'), Uri.parse('https://twitter.com/revancedapp'),
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,
), ),
), ),
ListTile( ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding( leading: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Image.asset( child: FaIcon(
'assets/images/youtube.png', FontAwesomeIcons.youtube,
height: 24,
width: 24,
color: Theme.of(context).iconTheme.color, color: Theme.of(context).iconTheme.color,
), ),
), ),
title: const Text('YouTube'), title: const Text('YouTube'),
subtitle: const Text('youtube.com/revanced'), subtitle: const Text('youtube.com/revanced'),
onTap: () => launchUrl( onTap: () => launchUrl(
Uri.parse( Uri.parse('https://youtube.com/revanced'),
'https://www.youtube.com/channel/UCLktAUh5Gza9zAJBStwxNdw'),
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,
), ),
), ),
], ],
), ),
), ),
collapsed: const Text(''), collapsed: Container(),
); );
} }
} }

View File

@ -0,0 +1,80 @@
import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/constants.dart';
import 'package:revanced_manager/theme.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_text_field.dart';
class SourcesWidget extends StatelessWidget {
final String title;
final TextEditingController organizationController;
final TextEditingController patchesSourceController;
final TextEditingController integrationsSourceController;
const SourcesWidget({
Key? key,
required this.title,
required this.organizationController,
required this.patchesSourceController,
required this.integrationsSourceController,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ExpandablePanel(
theme: ExpandableThemeData(
hasIcon: true,
iconColor: Theme.of(context).iconTheme.color,
iconPadding: const EdgeInsets.symmetric(vertical: 16.0),
animationDuration: const Duration(milliseconds: 400),
),
header: SizedBox(
width: double.infinity,
child: ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText(
'sourcesCard.widgetTitle',
child: Text('', style: kSettingItemTextStyle),
),
subtitle: I18nText(
'sourcesCard.widgetSubtitle',
child: Text(
'',
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: isDark ? Colors.grey[400] : Colors.grey[600],
),
),
),
),
),
expanded: Card(
color: isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!,
child: Column(
children: <Widget>[
CustomTextField(
inputController: organizationController,
label: I18nText('sourcesCard.organizationLabel'),
hint: ghOrg,
onChanged: (value) => ghOrg = value,
),
CustomTextField(
inputController: patchesSourceController,
label: I18nText('sourcesCard.patchesSourceLabel'),
hint: patchesRepo,
onChanged: (value) => patchesRepo = value,
),
CustomTextField(
inputController: integrationsSourceController,
label: I18nText('sourcesCard.integrationsSourceLabel'),
hint: integrationsRepo,
onChanged: (value) => integrationsRepo = value,
),
],
),
),
collapsed: Container(),
);
}
}

View File

@ -41,7 +41,7 @@ class ApplicationItem extends StatelessWidget {
), ),
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 12.0), padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 12.0),
child: Row( child: Row(
children: [ children: <Widget>[
SizedBox( SizedBox(
width: 60, width: 60,
child: Image.memory( child: Image.memory(
@ -55,7 +55,7 @@ class ApplicationItem extends StatelessWidget {
width: MediaQuery.of(context).size.width - 250, width: MediaQuery.of(context).size.width - 250,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
Text( Text(
name, name,
style: GoogleFonts.roboto( style: GoogleFonts.roboto(
@ -93,7 +93,7 @@ class ApplicationItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0), padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: <Widget>[
I18nText( I18nText(
'applicationItem.changelogLabel', 'applicationItem.changelogLabel',
child: Text( child: Text(

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:revanced_manager/theme.dart';
class CustomSliverAppBar extends StatelessWidget {
final Widget title;
final PreferredSizeWidget? bottom;
const CustomSliverAppBar({
Key? key,
required this.title,
this.bottom,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SliverAppBar(
pinned: true,
snap: false,
floating: false,
expandedHeight: 100.0,
automaticallyImplyLeading: false,
backgroundColor: MaterialStateColor.resolveWith(
(states) => states.contains(MaterialState.scrolledUnder)
? isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!
: Theme.of(context).scaffoldBackgroundColor,
),
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.symmetric(
vertical: 23.0,
horizontal: 20.0,
),
title: title,
),
bottom: bottom,
);
}
}

View File

@ -44,7 +44,7 @@ class _SearchBarState extends State<SearchBar> {
), ),
), ),
child: Row( child: Row(
children: [ children: <Widget>[
Expanded( Expanded(
child: TextFormField( child: TextFormField(
onChanged: widget.onQueryChanged, onChanged: widget.onQueryChanged,

View File

@ -28,6 +28,7 @@ dependencies:
flutter_local_notifications: ^9.8.0+1 flutter_local_notifications: ^9.8.0+1
flutter_svg: ^1.1.1+1 flutter_svg: ^1.1.1+1
fluttertoast: ^8.0.9 fluttertoast: ^8.0.9
font_awesome_flutter: ^10.1.0
get_it: ^7.2.0 get_it: ^7.2.0
github: ^9.4.0 github: ^9.4.0
google_fonts: ^3.0.1 google_fonts: ^3.0.1