diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 5fb9a8c8..56e7c6f5 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -16,6 +16,8 @@ "noShowAgain": "Don't show this again", "add": "Add", "remove": "Remove", + "showChangelogButton": "Show changelog", + "showUpdateButton": "Show update", "navigationView": { "dashboardTab": "Dashboard", "patcherTab": "Patcher", @@ -27,6 +29,7 @@ "updatesSubtitle": "Updates", "patchedSubtitle": "Patched apps", + "changeLaterSubtitle": "You can change this in the settings at a later time.", "noUpdates": "No updates available", @@ -35,20 +38,25 @@ "noInstallations": "No patched apps installed", "installUpdate": "Continue to install the update?", - "updateDialogTitle": "Update Manager", - "updatePatchesDialogTitle": "Update ReVanced Patches", + "updateSheetTitle": "Update ReVanced Manager", + "updateDialogTitle": "New update available", + "updatePatchesSheetTitle": "Update ReVanced Patches", "updateChangelogTitle": "Changelog", - "patchesConsentDialogText": "ReVanced Patches needs to be downloaded.", - "patchesConsentDialogText2": "This will connect you to {url}.", - "patchesConsentDialogText3": "Auto update?", - "patchesConsentDialogText3Sub": "You can change this in settings at a later time.", + "updateDialogText": "A new update is available for {file}.\n\nThe currently installed version is {version}.", + + "downloadConsentDialogTitle": "Download necessary files?", + "downloadConsentDialogText": "ReVanced Manager needs to download necessary files to work properly.", + "downloadConsentDialogText2": "This will connect you to {url}.", + + "checkUpdateDialogTitle": "Check for updates?", + "checkUpdateDialogText": "Do you want ReVanced Manager to check for updates automatically?", "notificationTitle": "Update downloaded", "notificationText": "Tap to install the update", "downloadingMessage": "Downloading update...", - "downloadedMessage": "Update downloaded!", + "downloadedMessage": "Update downloaded", "installingMessage": "Installing update...", @@ -157,7 +165,7 @@ "unsupportedPatchVersion": "Patch is not supported for this app version.", "unsupportedRequiredOption": "This patch contains a required option that is not supported by this app", - "patchesChangeWarningDialogText": "It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou'll need to turn on \"Allow changing patch selection\" in settings before changing any patch selection.", + "patchesChangeWarningDialogText": "It is recommended to use the default patch selection and options. Changing them may result in unexpected issues.\n\nYou'll need to turn on \"Allow changing patch selection\" in the settings before changing any patch selection.", "patchesChangeWarningDialogButton": "Use default selection" }, "installerView": { @@ -235,6 +243,8 @@ "autoUpdatePatchesLabel": "Auto update patches", "autoUpdatePatchesHint": "Automatically update patches to the latest version", + "showUpdateDialogLabel": "Show update dialog", + "showUpdateDialogHint": "Show a dialog when a new update is available", "universalPatchesLabel": "Show universal patches", "universalPatchesHint": "Display all apps and universal patches (may slow down the app list)", diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index add2424d..51856f88 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -81,7 +81,7 @@ class GithubAPI { int updates = 0; final String currentVersion = await _managerAPI.getCurrentManagerVersion(); - while (response.data[updates]['tag_name'] != 'v$currentVersion') { + while (response.data[updates]['tag_name'] != currentVersion) { updates++; } for (int i = 1; i < updates; i++) { diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 1e9b4606..4b2af7fc 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -128,12 +128,12 @@ class ManagerAPI { await _prefs.setString('patchesRepo', value); } - bool getPatchesConsent() { - return _prefs.getBool('patchesConsent') ?? false; + bool getDownloadConsent() { + return _prefs.getBool('downloadConsent') ?? false; } - Future setPatchesConsent(bool consent) async { - await _prefs.setBool('patchesConsent', consent); + void setDownloadConsent(bool consent) { + _prefs.setBool('downloadConsent', consent); } bool isPatchesAutoUpdate() { @@ -156,6 +156,14 @@ class ManagerAPI { _prefs.setBool('showPatchesChangeWarning', !value); } + bool showUpdateDialog() { + return _prefs.getBool('showUpdateDialog') ?? true; + } + + void setShowUpdateDialog(bool value) { + _prefs.setBool('showUpdateDialog', value); + } + bool isChangingToggleModified() { return _prefs.getBool('isChangingToggleModified') ?? false; } @@ -164,8 +172,8 @@ class ManagerAPI { _prefs.setBool('isChangingToggleModified', value); } - Future setPatchesAutoUpdate(bool value) async { - await _prefs.setBool('patchesAutoUpdate', value); + void setPatchesAutoUpdate(bool value) { + _prefs.setBool('patchesAutoUpdate', value); } List getSavedPatches(String packageName) { @@ -508,7 +516,11 @@ class ManagerAPI { Future getCurrentManagerVersion() async { final PackageInfo packageInfo = await PackageInfo.fromPlatform(); - return packageInfo.version; + String version = packageInfo.version; + if (!version.startsWith('v')) { + version = 'v$version'; + } + return version; } Future getCurrentPatchesVersion() async { diff --git a/lib/services/revanced_api.dart b/lib/services/revanced_api.dart index 2f5c210b..2c22d23e 100644 --- a/lib/services/revanced_api.dart +++ b/lib/services/revanced_api.dart @@ -8,6 +8,7 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:injectable/injectable.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/services/download_manager.dart'; +import 'package:revanced_manager/services/manager_api.dart'; import 'package:synchronized/synchronized.dart'; import 'package:timeago/timeago.dart'; @@ -48,6 +49,9 @@ class RevancedAPI { String extension, String repoName, ) { + if (!locator().getDownloadConsent()) { + return Future(() => null); + } return getToolsLock.synchronized(() async { try { final response = await _dio.get('/tools'); diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 242305af..5f1eabaf 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -19,7 +19,7 @@ import 'package:revanced_manager/services/revanced_api.dart'; import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; -import 'package:revanced_manager/ui/widgets/homeView/update_confirmation_dialog.dart'; +import 'package:revanced_manager/ui/widgets/homeView/update_confirmation_sheet.dart'; import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_checkbox_list_tile.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; @@ -35,15 +35,28 @@ class HomeViewModel extends BaseViewModel { final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); bool showUpdatableApps = false; List patchedInstalledApps = []; + String _currentManagerVersion = ''; + String _currentPatchesVersion = ''; String? _latestManagerVersion = ''; File? downloadedApk; Future initialize(BuildContext context) async { _managerAPI.rePatchedSavedApps().then((_) => _getPatchedApps()); - + _currentManagerVersion = await _managerAPI.getCurrentManagerVersion(); + if (!_managerAPI.getDownloadConsent()) { + await showDownloadConsent(context); + await forceRefresh(context); + return; + } _latestManagerVersion = await _managerAPI.getLatestManagerVersion(); - if (!_managerAPI.getPatchesConsent()) { - await showPatchesConsent(context); + _currentPatchesVersion = await _managerAPI.getCurrentPatchesVersion(); + if (_managerAPI.showUpdateDialog() && await hasManagerUpdates()) { + showUpdateDialog(context, false); + } + if (!_managerAPI.isPatchesAutoUpdate() && + _managerAPI.showUpdateDialog() && + await hasPatchesUpdates()) { + showUpdateDialog(context, true); } await _patcherAPI.initialize(); @@ -114,17 +127,10 @@ class HomeViewModel extends BaseViewModel { } Future hasManagerUpdates() async { - String currentVersion = await _managerAPI.getCurrentManagerVersion(); - - // add v to current version - if (!currentVersion.startsWith('v')) { - currentVersion = 'v$currentVersion'; - } - _latestManagerVersion = - await _managerAPI.getLatestManagerVersion() ?? currentVersion; + await _managerAPI.getLatestManagerVersion() ?? _currentManagerVersion; - if (_latestManagerVersion != currentVersion) { + if (_latestManagerVersion != _currentManagerVersion) { return true; } return false; @@ -132,13 +138,12 @@ class HomeViewModel extends BaseViewModel { Future hasPatchesUpdates() async { final String? latestVersion = await _managerAPI.getLatestPatchesVersion(); - final String currentVersion = await _managerAPI.getCurrentPatchesVersion(); if (latestVersion != null) { try { final int latestVersionInt = int.parse(latestVersion.replaceAll(RegExp('[^0-9]'), '')); final int currentVersionInt = - int.parse(currentVersion.replaceAll(RegExp('[^0-9]'), '')); + int.parse(_currentPatchesVersion.replaceAll(RegExp('[^0-9]'), '')); return latestVersionInt > currentVersionInt; } on Exception catch (e) { if (kDebugMode) { @@ -166,22 +171,98 @@ class HomeViewModel extends BaseViewModel { } } - Future showPatchesConsent(BuildContext context) async { + Future showDownloadConsent(BuildContext context) async { final ValueNotifier autoUpdate = ValueNotifier(true); await showDialog( context: context, barrierDismissible: false, - builder: (context) => AlertDialog( - title: const Text('Download ReVanced Patches?'), + builder: (context) => PopScope( + canPop: false, + child: AlertDialog( + title: I18nText('homeView.downloadConsentDialogTitle'), + content: ValueListenableBuilder( + valueListenable: autoUpdate, + builder: (context, value, child) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + I18nText( + 'homeView.downloadConsentDialogText', + child: Text( + '', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.secondary, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: I18nText( + 'homeView.downloadConsentDialogText2', + translationParams: { + 'url': _managerAPI.defaultApiUrl.split('/')[2], + }, + child: Text( + '', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.error, + ), + ), + ), + ), + ], + ); + }, + ), + actions: [ + TextButton( + onPressed: () async { + _managerAPI.setDownloadConsent(false); + SystemNavigator.pop(); + }, + child: I18nText('quitButton'), + ), + FilledButton( + onPressed: () async { + _managerAPI.setDownloadConsent(true); + _managerAPI.setPatchesAutoUpdate(autoUpdate.value); + Navigator.of(context).pop(); + }, + child: I18nText('okButton'), + ), + ], + ), + ), + ); + } + + void showUpdateDialog(BuildContext context, bool isPatches) { + final ValueNotifier noShow = + ValueNotifier(!_managerAPI.showUpdateDialog()); + showDialog( + context: context, + builder: (innerContext) => AlertDialog( + title: I18nText('homeView.updateDialogTitle'), content: ValueListenableBuilder( - valueListenable: autoUpdate, + valueListenable: noShow, builder: (context, value, child) { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ I18nText( - 'homeView.patchesConsentDialogText', + 'homeView.updateDialogText', + translationParams: { + 'file': isPatches ? 'ReVanced Patches' : 'ReVanced Manager', + 'version': isPatches + ? _currentPatchesVersion + : _currentManagerVersion, + }, child: Text( '', style: TextStyle( @@ -191,34 +272,18 @@ class HomeViewModel extends BaseViewModel { ), ), ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: I18nText( - 'homeView.patchesConsentDialogText2', - translationParams: { - 'url': _managerAPI.defaultApiUrl.split('/')[2], - }, - child: Text( - '', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.error, - ), - ), - ), - ), + const SizedBox(height: 10), HapticCheckboxListTile( value: value, contentPadding: EdgeInsets.zero, title: I18nText( - 'homeView.patchesConsentDialogText3', + 'noShowAgain', ), subtitle: I18nText( - 'homeView.patchesConsentDialogText3Sub', + 'homeView.changeLaterSubtitle', ), onChanged: (selected) { - autoUpdate.value = selected!; + noShow.value = selected!; }, ), ], @@ -228,18 +293,18 @@ class HomeViewModel extends BaseViewModel { actions: [ TextButton( onPressed: () async { - await _managerAPI.setPatchesConsent(false); - SystemNavigator.pop(); + _managerAPI.setShowUpdateDialog(!noShow.value); + Navigator.pop(innerContext); }, - child: I18nText('quitButton'), + child: I18nText('dismissButton'), // Decide later ), FilledButton( onPressed: () async { - await _managerAPI.setPatchesConsent(true); - await _managerAPI.setPatchesAutoUpdate(autoUpdate.value); - Navigator.of(context).pop(); + _managerAPI.setShowUpdateDialog(!noShow.value); + Navigator.pop(innerContext); + await showUpdateConfirmationDialog(context, isPatches); }, - child: I18nText('okButton'), + child: I18nText('showUpdateButton'), ), ], ), @@ -271,120 +336,91 @@ class HomeViewModel extends BaseViewModel { builder: (context) => ValueListenableBuilder( valueListenable: downloaded, builder: (context, value, child) { - return SimpleDialog( - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - contentPadding: const EdgeInsets.all(16.0), + return AlertDialog( title: I18nText( !value ? 'homeView.downloadingMessage' : 'homeView.downloadedMessage', - child: Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, - ), - ), ), - children: [ - Column( - children: [ - Row( + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (!value) + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon( - Icons.new_releases_outlined, - color: Theme.of(context).colorScheme.secondary, + StreamBuilder( + initialData: 0.0, + stream: _revancedAPI.managerUpdateProgress.stream, + builder: (context, snapshot) { + return LinearProgressIndicator( + value: snapshot.data! * 0.01, + valueColor: AlwaysStoppedAnimation( + Theme.of(context).colorScheme.secondary, + ), + ); + }, ), - const SizedBox(width: 8.0), - Text( - '$_latestManagerVersion', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, + const SizedBox(height: 16.0), + Align( + alignment: Alignment.centerRight, + child: FilledButton( + onPressed: () { + _revancedAPI.disposeManagerUpdateProgress(); + Navigator.of(context).pop(); + }, + child: I18nText('cancelButton'), ), ), ], ), - const SizedBox(height: 16.0), - if (!value) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - StreamBuilder( - initialData: 0.0, - stream: _revancedAPI.managerUpdateProgress.stream, - builder: (context, snapshot) { - return LinearProgressIndicator( - value: snapshot.data! * 0.01, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).colorScheme.secondary, - ), - ); - }, - ), - const SizedBox(height: 16.0), - Align( - alignment: Alignment.centerRight, - child: FilledButton( - onPressed: () { - _revancedAPI.disposeManagerUpdateProgress(); - Navigator.of(context).pop(); - }, - child: I18nText('cancelButton'), + if (value) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + I18nText( + 'homeView.installUpdate', + child: Text( + '', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.secondary, ), ), - ], - ), - if (value) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - I18nText( - 'homeView.installUpdate', - child: Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - color: Theme.of(context).colorScheme.secondary, + ), + const SizedBox(height: 16.0), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: I18nText('cancelButton'), ), ), - ), - const SizedBox(height: 16.0), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Align( - alignment: Alignment.centerRight, - child: TextButton( - onPressed: () { - Navigator.of(context).pop(); - }, - child: I18nText('cancelButton'), - ), + const SizedBox(width: 8.0), + Align( + alignment: Alignment.centerRight, + child: FilledButton( + onPressed: () async { + await _patcherAPI.installApk( + context, + downloadedApk!.path, + ); + }, + child: I18nText('updateButton'), ), - const SizedBox(width: 8.0), - Align( - alignment: Alignment.centerRight, - child: FilledButton( - onPressed: () async { - await _patcherAPI.installApk( - context, - downloadedApk!.path, - ); - }, - child: I18nText('updateButton'), - ), - ), - ], - ), - ], - ), - ], - ), - ], + ), + ], + ), + ], + ), + ], + ), ); }, ), @@ -436,16 +472,18 @@ class HomeViewModel extends BaseViewModel { Future showUpdateConfirmationDialog( BuildContext parentContext, - bool isPatches, - ) { + bool isPatches, [ + bool changelog = false, + ]) { return showModalBottomSheet( context: parentContext, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(24.0)), ), - builder: (context) => UpdateConfirmationDialog( + builder: (context) => UpdateConfirmationSheet( isPatches: isPatches, + changelog: changelog, ), ); } diff --git a/lib/ui/views/settings/settings_viewmodel.dart b/lib/ui/views/settings/settings_viewmodel.dart index 6fa85730..4bf3605b 100644 --- a/lib/ui/views/settings/settings_viewmodel.dart +++ b/lib/ui/views/settings/settings_viewmodel.dart @@ -39,6 +39,15 @@ class SettingsViewModel extends BaseViewModel { notifyListeners(); } + bool showUpdateDialog() { + return _managerAPI.showUpdateDialog(); + } + + void setShowUpdateDialog(bool value) { + _managerAPI.setShowUpdateDialog(value); + notifyListeners(); + } + bool isPatchesChangeEnabled() { return _managerAPI.isPatchesChangeEnabled(); } diff --git a/lib/ui/widgets/homeView/latest_commit_card.dart b/lib/ui/widgets/homeView/latest_commit_card.dart index 55252698..e209d42c 100644 --- a/lib/ui/widgets/homeView/latest_commit_card.dart +++ b/lib/ui/widgets/homeView/latest_commit_card.dart @@ -55,17 +55,15 @@ class _LatestCommitCardState extends State { FutureBuilder( future: model.hasManagerUpdates(), initialData: false, - builder: (context, snapshot) => Opacity( - opacity: snapshot.hasData && snapshot.data! ? 1.0 : 0.25, - child: FilledButton( - onPressed: snapshot.hasData && snapshot.data! - ? () => widget.model.showUpdateConfirmationDialog( - widget.parentContext, - false, - ) - : () => {}, - child: I18nText('updateButton'), + builder: (context, snapshot) => FilledButton( + onPressed: () => widget.model.showUpdateConfirmationDialog( + widget.parentContext, + false, + !snapshot.data!, ), + child: (snapshot.hasData && !snapshot.data!) + ? I18nText('showChangelogButton') + : I18nText('showUpdateButton'), ), ), ], @@ -83,7 +81,7 @@ class _LatestCommitCardState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('Patches'), + const Text('ReVanced Patches'), const SizedBox(height: 4), Row( children: [ @@ -108,19 +106,17 @@ class _LatestCommitCardState extends State { ), ), FutureBuilder( - future: locator().hasPatchesUpdates(), + future: model.hasPatchesUpdates(), initialData: false, - builder: (context, snapshot) => Opacity( - opacity: snapshot.hasData && snapshot.data! ? 1.0 : 0.25, - child: FilledButton( - onPressed: snapshot.hasData && snapshot.data! - ? () => widget.model.showUpdateConfirmationDialog( - widget.parentContext, - true, - ) - : () => {}, - child: I18nText('updateButton'), + builder: (context, snapshot) => FilledButton( + onPressed: () => widget.model.showUpdateConfirmationDialog( + widget.parentContext, + true, + !snapshot.data!, ), + child: (snapshot.hasData && !snapshot.data!) + ? I18nText('showChangelogButton') + : I18nText('showUpdateButton'), ), ), ], diff --git a/lib/ui/widgets/homeView/update_confirmation_dialog.dart b/lib/ui/widgets/homeView/update_confirmation_sheet.dart similarity index 93% rename from lib/ui/widgets/homeView/update_confirmation_dialog.dart rename to lib/ui/widgets/homeView/update_confirmation_sheet.dart index de5b72a0..c9d6f7bc 100644 --- a/lib/ui/widgets/homeView/update_confirmation_dialog.dart +++ b/lib/ui/widgets/homeView/update_confirmation_sheet.dart @@ -4,10 +4,11 @@ import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; -class UpdateConfirmationDialog extends StatelessWidget { - const UpdateConfirmationDialog({super.key, required this.isPatches}); +class UpdateConfirmationSheet extends StatelessWidget { + const UpdateConfirmationSheet({super.key, required this.isPatches, this.changelog = false}); final bool isPatches; + final bool changelog; @override Widget build(BuildContext context) { final HomeViewModel model = locator(); @@ -36,6 +37,7 @@ class UpdateConfirmationDialog extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + if (!changelog) Padding( padding: const EdgeInsets.only( top: 40.0, @@ -51,8 +53,8 @@ class UpdateConfirmationDialog extends StatelessWidget { children: [ I18nText( isPatches - ? 'homeView.updatePatchesDialogTitle' - : 'homeView.updateDialogTitle', + ? 'homeView.updatePatchesSheetTitle' + : 'homeView.updateSheetTitle', child: const Text( '', style: TextStyle( diff --git a/lib/ui/widgets/settingsView/settings_advanced_section.dart b/lib/ui/widgets/settingsView/settings_advanced_section.dart index 4182b7a0..5ab7b034 100644 --- a/lib/ui/widgets/settingsView/settings_advanced_section.dart +++ b/lib/ui/widgets/settingsView/settings_advanced_section.dart @@ -7,6 +7,7 @@ import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_pa import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_require_suggested_app_version.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/settings_show_update_dialog.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_universal_patches.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_version_compatibility_check.dart'; @@ -19,6 +20,7 @@ class SAdvancedSection extends StatelessWidget { title: 'settingsView.advancedSectionTitle', children: const [ SAutoUpdatePatches(), + SShowUpdateDialog(), SEnablePatchesSelection(), SRequireSuggestedAppVersion(), SVersionCompatibilityCheck(), diff --git a/lib/ui/widgets/settingsView/settings_show_update_dialog.dart b/lib/ui/widgets/settingsView/settings_show_update_dialog.dart new file mode 100644 index 00000000..42b90dac --- /dev/null +++ b/lib/ui/widgets/settingsView/settings_show_update_dialog.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/widgets/I18nText.dart'; +import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; +import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart'; + +class SShowUpdateDialog extends StatefulWidget { + const SShowUpdateDialog({super.key}); + + @override + State createState() => _SShowUpdateDialogState(); +} + +final _settingsViewModel = SettingsViewModel(); + +class _SShowUpdateDialogState extends State { + @override + Widget build(BuildContext context) { + return HapticSwitchListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.showUpdateDialogLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + subtitle: I18nText('settingsView.showUpdateDialogHint'), + value: _settingsViewModel.showUpdateDialog(), + onChanged: (value) { + setState(() { + _settingsViewModel.setShowUpdateDialog(value); + }); + }, + ); + } +}