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",
"updatesAvailable": "Updates Available",
"noUpdates": "No updates available",
"noInstallations": "No patched apps installed",
"noInstallations": "No patched applications installed",
"installed": "Installed",
"notificationTitle": "ReVanced Manager was updated!",
"notificationText": "Tap to open the app",
@ -40,7 +40,7 @@
"widgetTitle": "Select application",
"widgetTitleSelected": "Selected application",
"widgetSubtitle": "No application selected.",
"noAppsLabel": "No apps found."
"noAppsLabel": "No applications found."
},
"patchSelectorCard": {
"widgetTitle": "Select patches",
@ -48,8 +48,16 @@
"widgetSubtitle": "Select an application first.",
"widgetEmptySubtitle": "No patches selected."
},
"socialMediaCards": {
"widgetTitle": "Social Media"
"socialMediaCard": {
"widgetTitle": "Social Media",
"widgetSubtitle": "We are online!"
},
"sourcesCard": {
"widgetTitle": "Sources",
"widgetSubtitle": "Add your custom sources",
"organizationLabel": "Organization",
"patchesSourceLabel" : "Patches Source",
"integrationsSourceLabel": "Integrations Source"
},
"appSelectorView": {
"searchBarHint": "Search applications",
@ -75,19 +83,21 @@
},
"settingsView": {
"widgetTitle": "Settings",
"languageLabel": "Language",
"appearanceSectionTitle": "Appearance",
"patcherSectionTitle": "Patcher",
"teamSectionTitle": "Team",
"infoSectionTitle": "Info",
"themeLabel": "Theme",
"themeHint": "Change the theme of the app",
"darkThemeLabel": "Dark",
"lightThemeLabel": "Light",
"versionLabel": "Version",
"aboutLabel": "About",
"contributorsLabel": "Contributors",
"languageLabel": "Language",
"englishOption": "English",
"frenchOption": "French",
"rootModeLabel": "Root Mode",
"rootModeHint": "Enable this if you want to patch applications as rooted.",
"organizationLabel": "Organization",
"patchesSourceLabel" : "Patches Source",
"integrationsSourceLabel": "Integrations Source"
"rootModeHint": "Do you want to patch applications as rooted?",
"contributorsLabel": "Contributors",
"contributorsHint": "A list of contributors of ReVanced",
"aboutLabel": "About",
"versionLabel": "Version"
},
"rootCheckerView": {
"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(
primary: Color.fromRGBO(154, 193, 252, 0.18),
secondary: Color(0xff3868AF),
@ -69,6 +70,7 @@ var darkTheme = ThemeData.dark().copyWith(
),
),
),
toggleableActiveColor: const Color(0xff7792BA),
colorScheme: const ColorScheme.dark(
primary: Color(0xff11161C),
secondary: Color(0xff7792BA),

View File

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

View File

@ -15,7 +15,7 @@ class ContributorsView extends StatelessWidget {
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
children: <Widget>[
ContributorsCard(
title: 'Patcher Contributors',
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/installed_apps_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';
class HomeView extends StatelessWidget {
@ -22,32 +23,14 @@ class HomeView extends StatelessWidget {
builder: (context, model, child) => Scaffold(
body: CustomScrollView(
slivers: <Widget>[
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: I18nText(
'homeView.widgetTitle',
child: Text(
'',
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
CustomSliverAppBar(
title: I18nText(
'homeView.widgetTitle',
child: Text(
'',
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
),
),
@ -89,9 +72,9 @@ class HomeView extends StatelessWidget {
),
const SizedBox(height: 8),
Row(
children: [
children: <Widget>[
DashboardChip(
label: 'homeView.updatesAvailable',
label: I18nText('homeView.updatesAvailable'),
isSelected: model.showUpdatableApps,
onSelected: (value) {
model.toggleUpdatableApps(true);
@ -99,7 +82,7 @@ class HomeView extends StatelessWidget {
),
const SizedBox(width: 10),
DashboardChip(
label: 'homeView.installed',
label: I18nText('homeView.installed'),
isSelected: !model.showUpdatableApps,
onSelected: (value) {
model.toggleUpdatableApps(false);

View File

@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.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/widgets/installerView/custom_material_button.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
import 'package:stacked/stacked.dart';
class InstallerView extends StatelessWidget {
@ -18,32 +19,12 @@ class InstallerView extends StatelessWidget {
body: CustomScrollView(
controller: model.scrollController,
slivers: <Widget>[
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: Text(
model.headerLogs,
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
CustomSliverAppBar(
title: Text(
model.headerLogs,
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
),
bottom: PreferredSize(
@ -84,17 +65,17 @@ class InstallerView extends StatelessWidget {
visible: !model.isPatching,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
children: <Widget>[
CustomMaterialButton(
text: 'installerView.shareButton',
label: I18nText('installerView.shareButton'),
isFilled: false,
onPressed: () => model.shareResult(),
),
const SizedBox(width: 16),
CustomMaterialButton(
text: model.isInstalled
? 'installerView.openButton'
: 'installerView.installButton',
label: model.isInstalled
? I18nText('installerView.openButton')
: I18nText('installerView.installButton'),
isFilled: true,
isExpanded: true,
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/widgets/patcherView/app_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:stacked/stacked.dart';
@ -39,32 +40,14 @@ class PatcherView extends StatelessWidget {
),
body: CustomScrollView(
slivers: <Widget>[
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: I18nText(
'patcherView.widgetTitle',
child: Text(
'',
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
CustomSliverAppBar(
title: I18nText(
'patcherView.widgetTitle',
child: Text(
'',
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
),
),

View File

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

View File

@ -1,5 +1,5 @@
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:revanced_manager/ui/views/root_checker/root_checker_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/rootCheckerView/magisk_button.dart';
@ -27,7 +27,7 @@ class RootCheckerView extends StatelessWidget {
height: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 28.0),
child: Column(
children: [
children: <Widget>[
const SizedBox(height: 120),
I18nText(
'rootCheckerView.widgetTitle',
@ -53,7 +53,7 @@ class RootCheckerView extends StatelessWidget {
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
children: <Widget>[
MagiskButton(
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:revanced_manager/constants.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/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:revanced_manager/ui/widgets/settingsView/social_media_cards.dart';
import 'package:revanced_manager/ui/widgets/settingsView/about_widget.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_switch_tile.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_tile_dialog.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_themes/stacked_themes.dart';
@ -22,149 +27,124 @@ class SettingsView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelBuilder<SettingsViewModel>.reactive(
disposeViewModel: false,
viewModelBuilder: () => SettingsViewModel(),
onModelReady: (model) => model.initialize(),
builder: (context, SettingsViewModel model, child) => Scaffold(
body: CustomScrollView(
slivers: <Widget>[
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: I18nText(
'settingsView.widgetTitle',
child: Text(
'',
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
CustomSliverAppBar(
title: I18nText(
'settingsView.widgetTitle',
child: Text(
'',
style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline5!.color,
fontWeight: FontWeight.w500,
),
),
),
),
SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
padding: const EdgeInsets.symmetric(
vertical: 10.0,
horizontal: 20.0,
),
sliver: SliverList(
delegate: SliverChildListDelegate.fixed(
<Widget>[
SettingsSwitchItem(
title: 'settingsView.themeLabel',
subtitle: 'settingsView.themeHint',
value: isDark,
onTap: (value) {
isDark = value;
getThemeManager(context).toggleDarkLightTheme();
},
),
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,
SettingsSection(
title: 'settingsView.appearanceSectionTitle',
children: <Widget>[
CustomSwitchTile(
title: I18nText(
'settingsView.themeLabel',
child: Text(
'',
style: kSettingItemTextStyle,
),
),
child: Text(
model.isRooted ? 'Rooted' : 'Not rooted',
),
subtitle: I18nText('settingsView.themeHint'),
value: isDark,
onTap: (value) {
isDark = value;
getThemeManager(context).toggleDarkLightTheme();
},
),
),
],
),
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(
SettingsTileDialog(
title: 'settingsView.languageLabel',
subtitle: 'English',
children: <Widget>[
RadioListTile<String>(
title: I18nText('settingsView.englishOption'),
value: 'en',
items: const [
DropdownMenuItem(
value: 'en',
child: Text('English'),
),
DropdownMenuItem(
value: 'fr',
child: Text('French'),
),
],
groupValue: 'en',
onChanged: (value) {
value = 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(
contentPadding: EdgeInsets.zero,
title: I18nText(
'settingsView.rootModeLabel',
child: Text(
'',
style: kSettingItemTextStyle,
),
),
subtitle: I18nText('settingsView.rootModeHint'),
onTap: () => model.navigateToRootChecker(),
),
SourcesWidget(
title: 'settingsView.sourcesLabel',
organizationController: organizationController,
patchesSourceController: patchesSourceController,
integrationsSourceController:
integrationsSourceController,
),
],
),
ListTile(
title: I18nText(
'settingsView.contributorsLabel',
child: Text('', style: kSettingItemTextStyle),
),
onTap: model.navigateToContributors,
const Divider(thickness: 1.0),
SettingsSection(
title: 'settingsView.teamSectionTitle',
children: <Widget>[
OpenContainerWrapper(
openBuilder: (_, __) => const ContributorsView(),
closedBuilder: (_, openContainer) => ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText(
'settingsView.contributorsLabel',
child: Text('', style: kSettingItemTextStyle),
),
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.router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:timeago/timeago.dart';
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>();
void setLanguage(String language) {
notifyListeners();
}
void navigateToContributors() {
_navigationService.navigateTo(Routes.contributorsView);
}
void navigateToRootChecker() {
_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(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
children: <Widget>[
Container(
width: 48,
height: 48,
@ -47,7 +47,7 @@ class _InstalledAppItemState extends State<InstalledAppItem> {
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
Text(
widget.name,
maxLines: 2,

View File

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

View File

@ -1,5 +1,5 @@
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/models/patched_application.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),
child: Center(
child: Column(
children: [
children: <Widget>[
Icon(
Icons.update_disabled,
size: 40,

View File

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

View File

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

View File

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

View File

@ -1,16 +1,15 @@
import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/theme.dart';
class CustomMaterialButton extends StatelessWidget {
final String text;
final Widget label;
final bool isFilled;
final bool isExpanded;
final Function()? onPressed;
const CustomMaterialButton({
Key? key,
required this.text,
required this.label,
this.isFilled = true,
this.isExpanded = false,
required this.onPressed,
@ -62,7 +61,7 @@ class CustomMaterialButton extends StatelessWidget {
),
),
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),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
I18nText(
locator<PatcherViewModel>().selectedApp == null
? 'appSelectorCard.widgetTitle'
@ -50,7 +50,7 @@ class AppSelectorCard extends StatelessWidget {
),
)
: Row(
children: [
children: <Widget>[
SizedBox(
height: 16.0,
child: ClipOval(

View File

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

View File

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

View File

@ -1,5 +1,5 @@
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:google_fonts/google_fonts.dart';
@ -15,7 +15,7 @@ class MagiskButton extends StatelessWidget {
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
children: <Widget>[
GestureDetector(
onTap: onPressed,
child: CircleAvatar(

View File

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

View File

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

View File

@ -1,15 +1,13 @@
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';
class SettingsSwitchItem extends StatelessWidget {
final String title;
final String subtitle;
class CustomSwitchTile extends StatelessWidget {
final Widget title;
final Widget subtitle;
final bool value;
final Function(bool) onTap;
const SettingsSwitchItem({
const CustomSwitchTile({
Key? key,
required this.title,
required this.subtitle,
@ -20,14 +18,9 @@ class SettingsSwitchItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListTile(
title: I18nText(
title,
child: Text(
'',
style: kSettingItemTextStyle,
),
),
subtitle: I18nText(subtitle),
contentPadding: EdgeInsets.zero,
title: title,
subtitle: subtitle,
trailing: CustomSwitch(
value: value,
onChanged: onTap,

View File

@ -1,10 +1,9 @@
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 Widget label;
final String hint;
final Function(String)? onChanged;
@ -18,40 +17,42 @@ class CustomTextField extends StatelessWidget {
@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,
),
children: <Widget>[
const SizedBox(height: 8),
TextField(
controller: inputController,
onChanged: onChanged,
keyboardType: TextInputType.text,
style: TextStyle(
fontSize: 14,
color: isDark ? Colors.grey[300] : Colors.black,
color: Theme.of(context).textTheme.headline5!.color,
),
cursorColor: Theme.of(context).textTheme.headline5!.color,
decoration: InputDecoration(
label: I18nText(label),
labelStyle:
TextStyle(color: isDark ? Colors.grey[300] : Colors.black),
label: 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),
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)),
borderRadius: BorderRadius.circular(10),
gapPadding: 4.0,
),
focusedBorder: OutlineInputBorder(
@ -59,18 +60,21 @@ class CustomTextField extends StatelessWidget {
color: Theme.of(context).colorScheme.secondary,
width: 2.0,
),
borderRadius: const BorderRadius.all(Radius.circular(10.0)),
borderRadius: BorderRadius.circular(10),
),
errorBorder: const OutlineInputBorder(
borderSide: BorderSide(color: errorColor, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
errorBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color(0xffEF4444),
width: 1.0,
),
borderRadius: BorderRadius.circular(10),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary,
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: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/theme.dart';
import 'package:url_launcher/url_launcher.dart';
class SocialMediaCards extends StatelessWidget {
const SocialMediaCards({Key? key}) : super(key: key);
class SocialMediaWidget extends StatelessWidget {
const SocialMediaWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -13,30 +15,39 @@ class SocialMediaCards extends StatelessWidget {
theme: ExpandableThemeData(
hasIcon: true,
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(
width: double.infinity,
child: ListTile(
contentPadding: EdgeInsets.zero,
title: I18nText(
'socialMediaCards.widgetTitle',
'socialMediaCard.widgetTitle',
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(
color: Theme.of(context).backgroundColor,
color: isDark
? Theme.of(context).colorScheme.primary
: Theme.of(context).navigationBarTheme.backgroundColor!,
child: Column(
children: [
children: <Widget>[
ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
'assets/images/github.png',
height: 24,
width: 24,
child: FaIcon(
FontAwesomeIcons.github,
color: Theme.of(context).iconTheme.color,
),
),
@ -48,29 +59,25 @@ class SocialMediaCards extends StatelessWidget {
),
),
ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.discord,
padding: const EdgeInsets.all(8.0).copyWith(left: 5),
child: FaIcon(
FontAwesomeIcons.discord,
color: Theme.of(context).iconTheme.color,
),
),
title: const Text('Discord'),
subtitle: const Text('discord.gg/revanced'),
onTap: () => launchUrl(
Uri.parse('https://discord.gg/3E2pTWR4Yd'),
Uri.parse('https://discord.gg/rF2YcEjcrT'),
mode: LaunchMode.externalApplication,
),
),
ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.telegram,
child: FaIcon(
FontAwesomeIcons.telegram,
color: Theme.of(context).iconTheme.color,
),
),
@ -82,12 +89,10 @@ class SocialMediaCards extends StatelessWidget {
),
),
ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.reddit,
child: FaIcon(
FontAwesomeIcons.reddit,
color: Theme.of(context).iconTheme.color,
),
),
@ -99,48 +104,39 @@ class SocialMediaCards extends StatelessWidget {
),
),
ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
'assets/images/twitter.png',
height: 24,
width: 24,
child: FaIcon(
FontAwesomeIcons.twitter,
color: Theme.of(context).iconTheme.color,
),
),
title: const Text('Twitter'),
subtitle: const Text('@revancedapp'),
onTap: () => launchUrl(
Uri.parse('https://twitter.com/@revancedapp'),
Uri.parse('https://twitter.com/revancedapp'),
mode: LaunchMode.externalApplication,
),
),
ListTile(
contentPadding:
const EdgeInsets.symmetric(horizontal: 16).copyWith(top: 0),
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
'assets/images/youtube.png',
height: 24,
width: 24,
child: FaIcon(
FontAwesomeIcons.youtube,
color: Theme.of(context).iconTheme.color,
),
),
title: const Text('YouTube'),
subtitle: const Text('youtube.com/revanced'),
onTap: () => launchUrl(
Uri.parse(
'https://www.youtube.com/channel/UCLktAUh5Gza9zAJBStwxNdw'),
Uri.parse('https://youtube.com/revanced'),
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),
child: Row(
children: [
children: <Widget>[
SizedBox(
width: 60,
child: Image.memory(
@ -55,7 +55,7 @@ class ApplicationItem extends StatelessWidget {
width: MediaQuery.of(context).size.width - 250,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
Text(
name,
style: GoogleFonts.roboto(
@ -93,7 +93,7 @@ class ApplicationItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
children: <Widget>[
I18nText(
'applicationItem.changelogLabel',
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(
children: [
children: <Widget>[
Expanded(
child: TextFormField(
onChanged: widget.onQueryChanged,

View File

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