From 2dc92e26d32dcf5a8f6314beca01632b2f1a896e Mon Sep 17 00:00:00 2001 From: aAbed <39409020+TheAabedKhan@users.noreply.github.com> Date: Sat, 14 Oct 2023 12:43:18 +0000 Subject: [PATCH 1/9] fix(patches-selector): ignore punctuation marks when searching for patch (#1377) --- lib/ui/views/patches_selector/patches_selector_viewmodel.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart index c164e66506..bfd64c3d3f 100644 --- a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart +++ b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart @@ -209,7 +209,7 @@ class PatchesSelectorViewModel extends BaseViewModel { query.isEmpty || query.length < 2 || patch.name.toLowerCase().contains(query.toLowerCase()) || - patch.getSimpleName().toLowerCase().contains(query.toLowerCase()), + patch.name.replaceAll(RegExp(r'[^\w\s]+'), '').toLowerCase().contains(query.toLowerCase()), ) .toList(); if (_managerAPI.areUniversalPatchesEnabled()) { From d577e97758f318d20d66a59318ceb0afae55f215 Mon Sep 17 00:00:00 2001 From: aAbed <39409020+TheAabedKhan@users.noreply.github.com> Date: Sun, 15 Oct 2023 09:16:55 +0000 Subject: [PATCH 2/9] fix(app-bar): title not hiding completely (#1376) --- .../views/app_selector/app_selector_view.dart | 8 ++-- .../patches_selector_view.dart | 45 +++++++++---------- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/lib/ui/views/app_selector/app_selector_view.dart b/lib/ui/views/app_selector/app_selector_view.dart index 387a658db7..bca6df76ce 100644 --- a/lib/ui/views/app_selector/app_selector_view.dart +++ b/lib/ui/views/app_selector/app_selector_view.dart @@ -38,13 +38,11 @@ class _AppSelectorViewState extends State { floating: true, title: I18nText( 'appSelectorView.viewTitle', - child: Text( - '', - style: TextStyle( + ), + titleTextStyle: TextStyle( + fontSize: 22.0, color: Theme.of(context).textTheme.titleLarge!.color, ), - ), - ), leading: IconButton( icon: Icon( Icons.arrow_back, diff --git a/lib/ui/views/patches_selector/patches_selector_view.dart b/lib/ui/views/patches_selector/patches_selector_view.dart index 31f3a9365e..de7469bae4 100644 --- a/lib/ui/views/patches_selector/patches_selector_view.dart +++ b/lib/ui/views/patches_selector/patches_selector_view.dart @@ -62,12 +62,10 @@ class _PatchesSelectorViewState extends State { floating: true, title: I18nText( 'patchesSelectorView.viewTitle', - child: Text( - '', - style: TextStyle( - color: Theme.of(context).textTheme.titleLarge!.color, - ), - ), + ), + titleTextStyle: TextStyle( + fontSize: 22.0, + color: Theme.of(context).textTheme.titleLarge!.color, ), leading: IconButton( icon: Icon( @@ -80,24 +78,19 @@ class _PatchesSelectorViewState extends State { }, ), actions: [ - FittedBox( - fit: BoxFit.scaleDown, - child: Container( - margin: const EdgeInsets.only(top: 12, bottom: 12), - padding: - const EdgeInsets.symmetric(horizontal: 6, vertical: 6), - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .tertiary - .withOpacity(0.5), - borderRadius: BorderRadius.circular(6), - ), - child: Text( - model.patchesVersion!, - style: TextStyle( - color: Theme.of(context).textTheme.titleLarge!.color, - ), + Container( + margin: const EdgeInsets.symmetric(vertical: 12), + padding: const EdgeInsets.symmetric(horizontal: 6), + decoration: BoxDecoration( + color: + Theme.of(context).colorScheme.tertiary.withOpacity(0.5), + borderRadius: BorderRadius.circular(6), + ), + alignment: Alignment.center, + child: Text( + model.patchesVersion!, + style: TextStyle( + color: Theme.of(context).textTheme.titleLarge!.color, ), ), ), @@ -294,7 +287,9 @@ class _PatchesSelectorViewState extends State { _managerAPI.isPatchesChangeEnabled(), hasUnsupportedPatchOption: hasUnsupportedRequiredOption( - patch.options, patch), + patch.options, + patch, + ), options: patch.options, isSelected: model.isSelected(patch), navigateToOptions: (options) => From 5d5f311e36b2e711c543d9590ca7f3dc81c1c181 Mon Sep 17 00:00:00 2001 From: aAbed <39409020+TheAabedKhan@users.noreply.github.com> Date: Sun, 15 Oct 2023 09:17:28 +0000 Subject: [PATCH 3/9] fix(settings-view): list items jumping on scroll up (#1375) --- lib/ui/views/settings/settings_view.dart | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/ui/views/settings/settings_view.dart b/lib/ui/views/settings/settings_view.dart index e1002b404a..a806ee557a 100644 --- a/lib/ui/views/settings/settings_view.dart +++ b/lib/ui/views/settings/settings_view.dart @@ -40,16 +40,23 @@ class SettingsView extends StatelessWidget { SliverList( delegate: SliverChildListDelegate.fixed( [ - SUpdateThemeUI(), - // SUpdateLanguageUI(), - // _settingsDivider, - STeamSection(), - _settingsDivider, - SAdvancedSection(), - _settingsDivider, - SExportSection(), - _settingsDivider, - SInfoSection(), + ListView( + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + children: const [ + SUpdateThemeUI(), + // SUpdateLanguageUI(), + // _settingsDivider, + STeamSection(), + _settingsDivider, + SAdvancedSection(), + _settingsDivider, + SExportSection(), + _settingsDivider, + SInfoSection(), + ], + ), ], ), ), From f334da95ff14248f5c37c868c6e5cf1ce6d9da1d Mon Sep 17 00:00:00 2001 From: Benjamin <73490201+BenjaminHalko@users.noreply.github.com> Date: Sun, 15 Oct 2023 02:44:11 -0700 Subject: [PATCH 4/9] feat: Remove full external storage access (#1381) --- lib/ui/views/navigation/navigation_viewmodel.dart | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/ui/views/navigation/navigation_viewmodel.dart b/lib/ui/views/navigation/navigation_viewmodel.dart index a911f070e0..50b7697a3d 100644 --- a/lib/ui/views/navigation/navigation_viewmodel.dart +++ b/lib/ui/views/navigation/navigation_viewmodel.dart @@ -19,7 +19,6 @@ class NavigationViewModel extends IndexTrackingViewModel { Future initialize(BuildContext context) async { locator().initialize(context); final SharedPreferences prefs = await SharedPreferences.getInstance(); - await requestManageExternalStorage(); if (prefs.getBool('permissionsRequested') == null) { await Permission.storage.request(); @@ -60,17 +59,6 @@ class NavigationViewModel extends IndexTrackingViewModel { ); } - Future requestManageExternalStorage() async { - final manageExternalStorageStatus = - await Permission.manageExternalStorage.status; - if (manageExternalStorageStatus.isDenied) { - await Permission.manageExternalStorage.request(); - } - if (manageExternalStorageStatus.isPermanentlyDenied) { - await openAppSettings(); - } - } - Widget getViewForIndex(int index) { switch (index) { case 0: From e960fcc303d9d976c44680afe21c539457c5ae56 Mon Sep 17 00:00:00 2001 From: Benjamin <73490201+BenjaminHalko@users.noreply.github.com> Date: Sun, 15 Oct 2023 02:51:31 -0700 Subject: [PATCH 5/9] feat: add user agent (#1380) Co-authored-by: Pun Butrach --- lib/app/app.dart | 2 + lib/main.dart | 2 + lib/services/download_manager.dart | 75 +++++++++++++++++++ lib/services/github_api.dart | 42 +++-------- lib/services/revanced_api.dart | 41 +++------- .../contributorsView/contributors_card.dart | 4 +- 6 files changed, 99 insertions(+), 67 deletions(-) create mode 100644 lib/services/download_manager.dart diff --git a/lib/app/app.dart b/lib/app/app.dart index 0ed666d2d7..462ee00b81 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -1,3 +1,4 @@ +import 'package:revanced_manager/services/download_manager.dart'; import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/patcher_api.dart'; @@ -41,6 +42,7 @@ import 'package:stacked_services/stacked_services.dart'; LazySingleton(classType: PatcherAPI), LazySingleton(classType: RevancedAPI), LazySingleton(classType: GithubAPI), + LazySingleton(classType: DownloadManager), LazySingleton(classType: Toast), ], ) diff --git a/lib/main.dart b/lib/main.dart index 29b715b9a9..956f1c30b7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/services/download_manager.dart'; import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/revanced_api.dart'; @@ -19,6 +20,7 @@ Future main() async { await setupLocator(); WidgetsFlutterBinding.ensureInitialized(); await locator().initialize(); + await locator().initialize(); final String apiUrl = locator().getApiUrl(); await locator().initialize(apiUrl); final String repoUrl = locator().getRepoUrl(); diff --git a/lib/services/download_manager.dart b/lib/services/download_manager.dart new file mode 100644 index 0000000000..4c0919b984 --- /dev/null +++ b/lib/services/download_manager.dart @@ -0,0 +1,75 @@ +import 'package:dio/dio.dart'; +import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_cache_manager/file.dart'; +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/manager_api.dart'; + +@lazySingleton +class DownloadManager { + final ManagerAPI _managerAPI = locator(); + late final String _userAgent; + + final _cacheOptions = CacheOptions( + store: MemCacheStore(), + maxStale: const Duration(days: 1), + priority: CachePriority.high, + ); + + Future initialize() async { + _userAgent = 'ReVanced-Manager/${await _managerAPI.getCurrentManagerVersion()}'; + } + + Dio initDio(String url) { + var dio = Dio(); + try { + dio = Dio( + BaseOptions( + baseUrl: url, + headers: { + 'User-Agent': _userAgent, + }, + ), + ); + } on Exception catch (e) { + if (kDebugMode) { + print(e); + } + } + + dio.interceptors.add(DioCacheInterceptor(options: _cacheOptions)); + return dio; + } + + Future clearAllCache() async { + try { + await _cacheOptions.store!.clean(); + } on Exception catch (e) { + if (kDebugMode) { + print(e); + } + } + } + + Future getSingleFile(String url) async { + return DefaultCacheManager().getSingleFile( + url, + headers: { + 'User-Agent': _userAgent, + }, + ); + } + + Stream getFileStream(String url) { + return DefaultCacheManager().getFileStream( + url, + withProgress: true, + headers: { + 'User-Agent': _userAgent, + }, + ); + } +} + diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index 8d3244b3b6..add2424dfb 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -1,48 +1,24 @@ import 'dart:io'; import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; -import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; import 'package:flutter/foundation.dart'; -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'; @lazySingleton class GithubAPI { - late Dio _dio = Dio(); + late final Dio _dio; late final ManagerAPI _managerAPI = locator(); - - final _cacheOptions = CacheOptions( - store: MemCacheStore(), - maxStale: const Duration(days: 1), - priority: CachePriority.high, - ); + late final DownloadManager _downloadManager = locator(); Future initialize(String repoUrl) async { - try { - _dio = Dio( - BaseOptions( - baseUrl: repoUrl, - ), - ); - - _dio.interceptors.add(DioCacheInterceptor(options: _cacheOptions)); - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } + _dio = _downloadManager.initDio(repoUrl); } Future clearAllCache() async { - try { - await _cacheOptions.store!.clean(); - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } + await _downloadManager.clearAllCache(); } Future?> getLatestRelease( @@ -104,7 +80,7 @@ class GithubAPI { final Map releases = response.data[0]; int updates = 0; final String currentVersion = - await ManagerAPI().getCurrentManagerVersion(); + await _managerAPI.getCurrentManagerVersion(); while (response.data[updates]['tag_name'] != 'v$currentVersion') { updates++; } @@ -141,7 +117,7 @@ class GithubAPI { (asset) => (asset['name'] as String).endsWith(extension), ); if (asset != null) { - return await DefaultCacheManager().getSingleFile( + return await _downloadManager.getSingleFile( asset['browser_download_url'], ); } @@ -162,7 +138,7 @@ class GithubAPI { ) async { try { if (url.isNotEmpty) { - return await DefaultCacheManager().getSingleFile( + return await _downloadManager.getSingleFile( url, ); } @@ -180,7 +156,7 @@ class GithubAPI { } else { _managerAPI.setPatchesDownloadURL(downloadUrl); } - return await DefaultCacheManager().getSingleFile( + return await _downloadManager.getSingleFile( downloadUrl, ); } diff --git a/lib/services/revanced_api.dart b/lib/services/revanced_api.dart index fca17c0e85..70d2064c98 100644 --- a/lib/services/revanced_api.dart +++ b/lib/services/revanced_api.dart @@ -3,49 +3,27 @@ import 'dart:io'; import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; -import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; import 'package:flutter/foundation.dart'; 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:synchronized/synchronized.dart'; import 'package:timeago/timeago.dart'; @lazySingleton class RevancedAPI { - late Dio _dio = Dio(); + late final Dio _dio; + late final DownloadManager _downloadManager = locator(); final Lock getToolsLock = Lock(); - final _cacheOptions = CacheOptions( - store: MemCacheStore(), - maxStale: const Duration(days: 1), - priority: CachePriority.high, - ); - - Future initialize(String apiUrl) async { - try { - _dio = Dio( - BaseOptions( - baseUrl: apiUrl, - ), - ); - - _dio.interceptors.add(DioCacheInterceptor(options: _cacheOptions)); - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } + Future initialize(String repoUrl) async { + _dio = _downloadManager.initDio(repoUrl); } Future clearAllCache() async { - try { - await _cacheOptions.store!.clean(); - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } + await _downloadManager.clearAllCache(); } Future>> getContributors() async { @@ -120,7 +98,7 @@ class RevancedAPI { ); if (release != null) { final String url = release['browser_download_url']; - return await DefaultCacheManager().getSingleFile(url); + return await _downloadManager.getSingleFile(url); } } on Exception catch (e) { if (kDebugMode) { @@ -152,9 +130,8 @@ class RevancedAPI { 'revanced/revanced-manager', ); File? outputFile; - await for (final result in DefaultCacheManager().getFileStream( + await for (final result in _downloadManager.getFileStream( release!['browser_download_url'] as String, - withProgress: true, )) { if (result is DownloadProgress) { final totalSize = result.totalSize ?? 10000000; diff --git a/lib/ui/widgets/contributorsView/contributors_card.dart b/lib/ui/widgets/contributorsView/contributors_card.dart index 574699a84b..d0a4c624ef 100644 --- a/lib/ui/widgets/contributorsView/contributors_card.dart +++ b/lib/ui/widgets/contributorsView/contributors_card.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/file.dart'; -import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:revanced_manager/services/download_manager.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -58,7 +58,7 @@ class _ContributorsCardState extends State { mode: LaunchMode.externalApplication, ), child: FutureBuilder( - future: DefaultCacheManager().getSingleFile( + future: DownloadManager().getSingleFile( widget.contributors[index]['avatar_url'], ), builder: (context, snapshot) => snapshot.hasData From 196d9fe4d2a4b74198000cebd11e8c2917d6c33e Mon Sep 17 00:00:00 2001 From: KobeW50 <84587632+KobeW50@users.noreply.github.com> Date: Sun, 15 Oct 2023 05:56:02 -0400 Subject: [PATCH 6/9] refactor: reorganize and rename settings (#1307) Co-authored-by: Pun Butrach Co-authored-by: Ushie --- assets/i18n/en_US.json | 96 ++++++++---------- docs/2_4_settings.md | 34 ++++--- fonts/custom-icons.ttf | Bin 0 -> 1892 bytes lib/services/manager_api.dart | 10 +- .../views/installer/installer_viewmodel.dart | 6 +- lib/ui/views/patcher/patcher_viewmodel.dart | 2 +- .../patches_selector_viewmodel.dart | 4 +- lib/ui/views/settings/settings_view.dart | 9 +- lib/ui/views/settings/settings_viewmodel.dart | 8 +- .../widgets/homeView/latest_commit_card.dart | 4 +- .../patchesSelectorView/patch_item.dart | 15 ++- .../settings_advanced_section.dart | 89 ++-------------- .../settingsView/settings_debug_section.dart | 68 +++++++++++++ .../settingsView/settings_export_section.dart | 95 ++++++++++++----- .../settingsView/settings_info_section.dart | 38 ------- ...s.dart => settings_universal_patches.dart} | 16 +-- ...settings_version_compatibility_check.dart} | 16 +-- .../settingsView/social_media_widget.dart | 7 ++ lib/ui/widgets/shared/custom_icon.dart | 9 ++ pubspec.yaml | 4 + 20 files changed, 272 insertions(+), 258 deletions(-) create mode 100644 fonts/custom-icons.ttf create mode 100644 lib/ui/widgets/settingsView/settings_debug_section.dart delete mode 100644 lib/ui/widgets/settingsView/settings_info_section.dart rename lib/ui/widgets/settingsView/{settings_experimental_universal_patches.dart => settings_universal_patches.dart} (75%) rename lib/ui/widgets/settingsView/{settings_experimental_patches.dart => settings_version_compatibility_check.dart} (69%) create mode 100644 lib/ui/widgets/shared/custom_icon.dart diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index f61c619226..9185c6d051 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -128,12 +128,10 @@ "none": "None", "noneTooltip": "Deselect all patches", - "loadPatchesSelection": "Load patches selection", - "noSavedPatches": "No saved patches for the selected app.\nPress Done to save current selection.", + "loadPatchesSelection": "Load patch selection", + "noSavedPatches": "No saved patch selection for the selected app.\nPress Done to save the current selection.", "noPatchesFound": "No patches found for the selected app", - "setRequiredOption": "Some patches require options to be set:\n\n{patches}\n\nPlease set them before continuing.", - - "selectAllPatchesWarningContent": "You are about to select all patches, that includes non-suggested patches and can cause unwanted behavior." + "setRequiredOption": "Some patches require options to be set:\n\n{patches}\n\nPlease set them before continuing." }, "patchOptionsView": { "viewTitle": "Patch options", @@ -152,10 +150,10 @@ }, "patchItem": { "unsupportedDialogText": "Selecting this patch may result in patching errors.\n\nApp version: {packageVersion}\nSupported versions:\n{supportedVersions}", - "unsupportedPatchVersion": "Patch is not supported for this app version. Enable the experimental toggle in settings to proceed.", + "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 selection of patches because changing it may cause unexpected issues.\n\nIf you know what you are doing, you can enable \"Enable changing selection\" in the settings.", + "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.", "patchesChangeWarningDialogButton": "Use default selection" }, "installerView": { @@ -187,10 +185,9 @@ "appearanceSectionTitle": "Appearance", "teamSectionTitle": "Team", - "infoSectionTitle": "Info", + "debugSectionTitle": "Debugging", "advancedSectionTitle": "Advanced", "exportSectionTitle": "Import & export", - "logsSectionTitle": "Logs", "themeModeLabel": "App theme", "systemThemeLabel": "System", @@ -204,15 +201,15 @@ "englishOption": "English", "sourcesLabel": "Sources", - "sourcesLabelHint": "Configure your custom sources", + "sourcesLabelHint": "Configure your sources", "sourcesIntegrationsLabel": "Integrations source", "sourcesResetDialogTitle": "Reset", - "sourcesResetDialogText": "Are you sure you want to reset custom sources to their default values?", - "apiURLResetDialogText": "Are you sure you want to reset API URL to its default value?", - "sourcesUpdateNote": "Note: ReVanced Patches will be updated to the latest version automatically.\n\nThis will reveal your IP address to the server.", + "sourcesResetDialogText": "Are you sure you want to reset your sources to their default values?", + "apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?", + "sourcesUpdateNote": "Note: Patches will be updated to the latest version automatically.\n\nThis will reveal your IP address to the server.", "apiURLLabel": "API URL", - "apiURLHint": "Configure your custom API URL", + "apiURLHint": "Configure your API URL", "selectApiURL": "API URL", "hostRepositoryLabel": "Repository API", "orgPatchesLabel": "Patches organization", @@ -222,21 +219,20 @@ "contributorsLabel": "Contributors", "contributorsHint": "A list of contributors of ReVanced", - "logsLabel": "Logs", - "logsHint": "Share Manager's logs", + "logsLabel": "Share logs", + "logsHint": "Share ReVanced Manager logs", - "enablePatchesSelectionLabel": "Enable changing selection", - "enablePatchesSelectionHint": "Enable changing the selection of patches.", - "enablePatchesSelectionWarningText": "Changing the default selection of patches may cause unexpected issues.\n\nEnable anyways?", + "enablePatchesSelectionLabel": "Allow changing patch selection", + "enablePatchesSelectionHint": "Allow changing the selection of patches", + "enablePatchesSelectionWarningText": "Changing the selection of patches may cause unexpected issues.\n\nEnable anyways?", "disablePatchesSelectionWarningText": "You are about to disable changing the selection of patches.\nThe default selection of patches will be restored.\n\nDisable anyways?", "autoUpdatePatchesLabel": "Auto update patches", - "autoUpdatePatchesHint": "Automatically update ReVanced Patches to the latest version", - "experimentalUniversalPatchesLabel": "Experimental universal patches support", - "experimentalUniversalPatchesHint": "Display all applications to use with universal patches, loading list of apps may be slower", - "experimentalPatchesLabel": "Experimental patches support", - "experimentalPatchesHint": "Enable usage of unsupported patches in any app version", - "enabledExperimentalPatches": "Experimental patches support enabled", + "autoUpdatePatchesHint": "Automatically update patches to the latest version", + "universalPatchesLabel": "Show universal patches", + "universalPatchesHint": "Display all apps and universal patches (may slow down the app list)", + "versionCompatibilityCheckLabel": "Version compatibility check", + "versionCompatibilityCheckHint": "Restricts patches to supported versions", "aboutLabel": "About", "snackbarMessage": "Copied to clipboard", @@ -246,54 +242,52 @@ "deleteTempDirHint": "Delete unused temporary files", "deletedTempDir": "Temporary files deleted", - "exportPatchesLabel": "Export patches selection", - "exportPatchesHint": "Export patches selection to a JSON file", - "exportedPatches": "Patches selection exported", - "noExportFileFound": "No patches selection to export", + "exportPatchesLabel": "Export patch selection", + "exportPatchesHint": "Export patch selection to a JSON file", + "exportedPatches": "Patch selection exported", + "noExportFileFound": "No patch selection to export", - "importPatchesLabel": "Import patches selection", - "importPatchesHint": "Import patches selection from a JSON file", - "importedPatches": "Patches selection imported", + "importPatchesLabel": "Import patch selection", + "importPatchesHint": "Import patch selection from a JSON file", + "importedPatches": "Patch selection imported", - "resetStoredPatchesLabel": "Reset patches", - "resetStoredPatchesHint": "Reset the stored patches selection", + "resetStoredPatchesLabel": "Reset patch selection", + "resetStoredPatchesHint": "Reset the stored patch selection", + "resetStoredPatchesDialogTitle": "Reset patch selection?", + "resetStoredPatchesDialogText": "The default selection of patches will be restored..", + "resetStoredPatches": "Patch selection has been reset", - "resetStoredOptionsLabel": "Reset options", + "resetStoredOptionsLabel": "Reset patch options", "resetStoredOptionsHint": "Reset all patch options", - - "resetStoredPatchesDialogTitle": "Reset patches selection?", - "resetStoredPatchesDialogText": "Resetting patches selection will remove all selected patches.", - "resetStoredPatches": "Patches selection has been reset", - - "resetStoredOptionsDialogTitle": "Reset options?", - "resetStoredOptionsDialogText": "Resetting options will remove all saved options.", + "resetStoredOptionsDialogTitle": "Reset patch options?", + "resetStoredOptionsDialogText": "Resetting patch options will remove all saved options.", "resetStoredOptions": "Options have been reset", - "deleteLogsLabel": "Delete logs", - "deleteLogsHint": "Delete collected manager logs", + "deleteLogsLabel": "Clear logs", + "deleteLogsHint": "Delete collected ReVanced Manager logs", "deletedLogs": "Logs deleted", "regenerateKeystoreLabel": "Regenerate keystore", - "regenerateKeystoreHint": "Regenerate the keystore used to sign the app", + "regenerateKeystoreHint": "Regenerate the keystore used to sign apps", "regenerateKeystoreDialogTitle": "Regenerate keystore?", - "regenerateKeystoreDialogText": "Patched apps signed with the old keystore will no longer be able to update.", + "regenerateKeystoreDialogText": "Patched apps signed with the old keystore will no longer be able to be updated.", "regeneratedKeystore": "Keystore regenerated", "exportKeystoreLabel": "Export keystore", - "exportKeystoreHint": "Export keystore used to sign apps", + "exportKeystoreHint": "Export the keystore used to sign apps", "exportedKeystore": "Keystore exported", "noKeystoreExportFileFound": "No keystore to export", "importKeystoreLabel": "Import keystore", - "importKeystoreHint": "Import keystore used to sign apps", + "importKeystoreHint": "Import a keystore used to sign apps", "importedKeystore": "Keystore imported", - "selectKeystorePassword": "Keystore Password", - "selectKeystorePasswordHint": "Select keystore password used to sign the apk", + "selectKeystorePassword": "Keystore password", + "selectKeystorePasswordHint": "Select keystore password used to sign apps", "jsonSelectorErrorMessage": "Unable to use selected JSON file", - "keystoreSelectorErrorMessage": "Unable to use selected KEYSTORE file" + "keystoreSelectorErrorMessage": "Unable to use selected keystore file" }, "appInfoView": { "widgetTitle": "App info", diff --git a/docs/2_4_settings.md b/docs/2_4_settings.md index 6f72fdf32b..3134a7c378 100644 --- a/docs/2_4_settings.md +++ b/docs/2_4_settings.md @@ -2,37 +2,41 @@ ReVanced Manager has settings that can be configured to your liking. -## โญ Essential settings +## ๐ŸŽ›๏ธ Essential settings -- ### ๐Ÿ”— API URL +- ### ๐Ÿช› Allow changing patch selection - API to use to fetch updates and ReVanced Patches from. + Allows the user to change the patch selection from the default selection. -- ### ๐Ÿงฌ Sources +- ### ๐Ÿ” Version compatibility check - Override the API and download ReVanced Patches from a different source. + Constrains patches to supported app versions. Disable this to patch any version of an app. -- ### ๐Ÿงช Experimental ReVanced Patches support + > [!WARNING] + > Disabling this may cause issues if the patches are not compatible with the app version. - Disable checking for the version of the app when applying ReVanced Patches. +- ### ๐Ÿง‘โ€๐Ÿ”ฌ Show universal patches + + Reveals patches which can be applied to any app. > [!WARNING] - > This may cause issues if the ReVanced Patches are not compatible with the app version. + > These patches may not work on all apps. -- ### ๐Ÿง‘โ€๐Ÿ”ฌ Experimental universal support +- ### ๐Ÿงฌ Sources - This will show or hide ReVanced Patches, which are not meant for any app in particular but apply to all apps + Override the API and download patches from a different source. - > [!WARNING] - > Because the patches generalize the app, they may not work on all apps. +- ### ๐Ÿ”— API URL + + API to use to fetch updates and patches from. - ### ๐Ÿ’พ Imports & Exports You can import, export or reset the following settings: - ๐Ÿ”‘ Keystore - - ๐Ÿ“„ ReVanced Patches selection - - โš™๏ธ Options + - ๐Ÿ“„ Patch selection + - โš™๏ธ Patch options > [!NOTE] > This is particularly useful if you want to backup or reset your settings. @@ -45,4 +49,4 @@ ReVanced Manager has settings that can be configured to your liking. The next page will bring you back to the usage page. -Continue: [๐Ÿ› ๏ธ Usage](2_usage.md) +Continue: [๐Ÿ› ๏ธ Usage](2_usage.md) \ No newline at end of file diff --git a/fonts/custom-icons.ttf b/fonts/custom-icons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b240c33f610b8ef9d80cc9cd546c60aa21b9dc2f GIT binary patch literal 1892 zcmd^9-)kII7(I9H?#?C~BQ}_pqB4zXn%M2`W&=@bjj6F43$03;1{9&4?#}*Vc4nNN zjY;vrN5K>V1rY=v1hIF@&WdT^ih{U( zcI4qGQbYPM7H+FybAKim_f+gD$OvTqW@TUOBF%%Z8>(VE$t?CTFBpM=bR094yV~>h zb2TjY(NF5}B6E3@F1i{j<0NafH*Xrqvokueu6>>*tGx4^nI-uYredFz;``WV-pNQ? zY3~tIXIk+jZSF@&Z``i2FNIRPrR|YLPE^F^R zC^M$9WM<@B^2y9SnLocwrwMY|!MVXhrEFF{Joq%7{#e{sHgh?1@P~@(5Ps0{0TtRw ztO8@S5^TW4n#Pj+3mT`09gWlcbG)o^hWx7e4^g2)CkYn!B-j!91&|8 z8yFXDjV1XljZ?(C8mBQSZfTq$|Aoe**bv`ooWqQfU-5(Ou+?Zr*6hlhRW6kmtZUnr zPpakFu4VV4rXO~#WvlM?qR0tbRo^RA{Z8Jh`(EU@uCJ_%+m%E<8w6`kqvzV;Fg1)f zoUq&SJ!`&D8m3nr&k60wsj1_;n~ic5)vbEycdUv&#|lEf?Np;eGm3)K#p3Y!Sb>iK z+X&G@15HG*FiUohbD960G8Txg(Zix=;?;r&8!j0eJ+5fRN|*LBd!346Bi^6#uTu3; zi02N!eC44SrMrCmf3%A{rSh-UXBk_-_rqaqJt{VLJjm-Hej|>f%ShCz7Up?g>A+o9 z>FvcU>^Q<2S0veYvB@aPac1>6i;z2Zh$?sGV=-o>wYg7~{)M=%5!ury@;NAfe!p>3 f|NsALhA@Q0MCfeVUe&3ca{Y#Xs@t>!C-(je$-Not literal 0 HcmV?d00001 diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 5636778d61..ad3067611b 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -244,12 +244,12 @@ class ManagerAPI { await _prefs.setBool('universalPatchesEnabled', value); } - bool areExperimentalPatchesEnabled() { - return _prefs.getBool('experimentalPatchesEnabled') ?? false; + bool isVersionCompatibilityCheckEnabled() { + return _prefs.getBool('versionCompatibilityCheckEnabled') ?? true; } - Future enableExperimentalPatchesStatus(bool value) async { - await _prefs.setBool('experimentalPatchesEnabled', value); + Future enableVersionCompatibilityCheckStatus(bool value) async { + await _prefs.setBool('versionCompatibilityCheckEnabled', value); } Future setKeystorePassword(String password) async { @@ -677,7 +677,7 @@ class ManagerAPI { Future> getDefaultPatches() async { final List patches = await getPatches(); final List defaultPatches = []; - if (areExperimentalPatchesEnabled() == false) { + if (isVersionCompatibilityCheckEnabled() == false) { defaultPatches.addAll( patches .where( diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 054002ff29..05cbfda3b6 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -198,9 +198,9 @@ class InstallerViewModel extends BaseViewModel { 'Patches: ${_patches.map((p) => p.name).toList().join(", ")}', '\n~ Settings', - 'Enabled changing patches: ${_managerAPI.isPatchesChangeEnabled()}', - 'Enabled universal patches: ${_managerAPI.areUniversalPatchesEnabled()}', - 'Enabled experimental patches: ${_managerAPI.areExperimentalPatchesEnabled()}', + 'Allow changing patch selection: ${_managerAPI.isPatchesChangeEnabled()}', + 'Show universal patches: ${_managerAPI.areUniversalPatchesEnabled()}', + 'Version compatibility check: ${_managerAPI.isVersionCompatibilityCheckEnabled()}', 'Patches source: ${_managerAPI.getPatchesRepo()}', 'Integration source: ${_managerAPI.getIntegrationsRepo()}', diff --git a/lib/ui/views/patcher/patcher_viewmodel.dart b/lib/ui/views/patcher/patcher_viewmodel.dart index e57accef41..ec7d81288a 100644 --- a/lib/ui/views/patcher/patcher_viewmodel.dart +++ b/lib/ui/views/patcher/patcher_viewmodel.dart @@ -190,7 +190,7 @@ class PatcherViewModel extends BaseViewModel { this.selectedPatches.clear(); this.selectedPatches.addAll(patches.where((patch) => !patch.excluded)); } - if (!_managerAPI.areExperimentalPatchesEnabled()) { + if (!_managerAPI.isVersionCompatibilityCheckEnabled()) { this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch)); } if (!_managerAPI.areUniversalPatchesEnabled()) { diff --git a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart index bfd64c3d3f..6719cdceb7 100644 --- a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart +++ b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart @@ -169,7 +169,7 @@ class PatchesSelectorViewModel extends BaseViewModel { .where( (element) => !element.excluded && - (_managerAPI.areExperimentalPatchesEnabled() || + (_managerAPI.isVersionCompatibilityCheckEnabled() || isPatchSupported(element)), ), ); @@ -281,7 +281,7 @@ class PatchesSelectorViewModel extends BaseViewModel { this.selectedPatches.addAll( patches.where((patch) => selectedPatches.contains(patch.name)), ); - if (!_managerAPI.areExperimentalPatchesEnabled()) { + if (!_managerAPI.isVersionCompatibilityCheckEnabled()) { this.selectedPatches.removeWhere((patch) => !isPatchSupported(patch)); } } else { diff --git a/lib/ui/views/settings/settings_view.dart b/lib/ui/views/settings/settings_view.dart index a806ee557a..fb623440b8 100644 --- a/lib/ui/views/settings/settings_view.dart +++ b/lib/ui/views/settings/settings_view.dart @@ -6,8 +6,8 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/settings_debug_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_export_section.dart'; -import 'package:revanced_manager/ui/widgets/settingsView/settings_info_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_team_section.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart'; import 'package:stacked/stacked.dart'; @@ -46,15 +46,16 @@ class SettingsView extends StatelessWidget { physics: NeverScrollableScrollPhysics(), children: const [ SUpdateThemeUI(), - // SUpdateLanguageUI(), // _settingsDivider, - STeamSection(), + // SUpdateLanguageUI(), _settingsDivider, SAdvancedSection(), _settingsDivider, SExportSection(), _settingsDivider, - SInfoSection(), + STeamSection(), + _settingsDivider, + SDebugSection(), ], ), ], diff --git a/lib/ui/views/settings/settings_viewmodel.dart b/lib/ui/views/settings/settings_viewmodel.dart index 7ae8bdb5e2..409d44ce3d 100644 --- a/lib/ui/views/settings/settings_viewmodel.dart +++ b/lib/ui/views/settings/settings_viewmodel.dart @@ -135,12 +135,12 @@ class SettingsViewModel extends BaseViewModel { notifyListeners(); } - bool areExperimentalPatchesEnabled() { - return _managerAPI.areExperimentalPatchesEnabled(); + bool isVersionCompatibilityCheckEnabled() { + return _managerAPI.isVersionCompatibilityCheckEnabled(); } - void useExperimentalPatches(bool value) { - _managerAPI.enableExperimentalPatchesStatus(value); + void useVersionCompatibilityCheck(bool value) { + _managerAPI.enableVersionCompatibilityCheckStatus(value); notifyListeners(); } diff --git a/lib/ui/widgets/homeView/latest_commit_card.dart b/lib/ui/widgets/homeView/latest_commit_card.dart index 2d62286f52..cb263e259d 100644 --- a/lib/ui/widgets/homeView/latest_commit_card.dart +++ b/lib/ui/widgets/homeView/latest_commit_card.dart @@ -75,7 +75,7 @@ class _LatestCommitCardState extends State { const SizedBox(height: 16), - // ReVanced Patches + // Patches CustomCard( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -84,7 +84,7 @@ class _LatestCommitCardState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('ReVanced Patches'), + const Text('Patches'), const SizedBox(height: 4), Row( children: [ diff --git a/lib/ui/widgets/patchesSelectorView/patch_item.dart b/lib/ui/widgets/patchesSelectorView/patch_item.dart index 74ccd96be2..c5ff597425 100644 --- a/lib/ui/widgets/patchesSelectorView/patch_item.dart +++ b/lib/ui/widgets/patchesSelectorView/patch_item.dart @@ -48,13 +48,12 @@ class _PatchItemState extends State { Widget build(BuildContext context) { widget.isSelected = widget.isSelected && (!widget.isUnsupported || - widget._managerAPI.areExperimentalPatchesEnabled()) && - !widget.hasUnsupportedPatchOption; + widget._managerAPI.isVersionCompatibilityCheckEnabled()) && !widget.hasUnsupportedPatchOption; return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Opacity( opacity: widget.isUnsupported && - widget._managerAPI.areExperimentalPatchesEnabled() == false + widget._managerAPI.isVersionCompatibilityCheckEnabled() == false ? 0.5 : 1, child: CustomCard( @@ -66,7 +65,7 @@ class _PatchItemState extends State { ), onTap: () { if (widget.isUnsupported && - !widget._managerAPI.areExperimentalPatchesEnabled()) { + !widget._managerAPI.isVersionCompatibilityCheckEnabled()) { widget.isSelected = false; widget.toast.showBottom('patchItem.unsupportedPatchVersion'); } else if (widget.isChangeEnabled) { @@ -80,7 +79,7 @@ class _PatchItemState extends State { setState(() {}); } if (!widget.isUnsupported || - widget._managerAPI.areExperimentalPatchesEnabled()) { + widget._managerAPI.isVersionCompatibilityCheckEnabled()) { widget.onChanged(widget.isSelected); } }, @@ -99,7 +98,7 @@ class _PatchItemState extends State { ), onChanged: (newValue) { if (widget.isUnsupported && - !widget._managerAPI.areExperimentalPatchesEnabled()) { + !widget._managerAPI.isVersionCompatibilityCheckEnabled()) { widget.isSelected = false; widget.toast.showBottom( 'patchItem.unsupportedPatchVersion', @@ -115,7 +114,7 @@ class _PatchItemState extends State { setState(() {}); } if (!widget.isUnsupported || - widget._managerAPI.areExperimentalPatchesEnabled()) { + widget._managerAPI.isVersionCompatibilityCheckEnabled()) { widget.onChanged(widget.isSelected); } }, @@ -156,7 +155,7 @@ class _PatchItemState extends State { children: [ if (widget.isUnsupported && widget._managerAPI - .areExperimentalPatchesEnabled()) + .isVersionCompatibilityCheckEnabled()) Padding( padding: const EdgeInsets.only(top: 8), child: TextButton.icon( diff --git a/lib/ui/widgets/settingsView/settings_advanced_section.dart b/lib/ui/widgets/settingsView/settings_advanced_section.dart index f3e838a638..8adce157e0 100644 --- a/lib/ui/widgets/settingsView/settings_advanced_section.dart +++ b/lib/ui/widgets/settingsView/settings_advanced_section.dart @@ -1,18 +1,14 @@ // ignore_for_file: prefer_const_constructors import 'package:flutter/material.dart'; -import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.dart'; -import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart'; -import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_patches.dart'; -import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_universal_patches.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; -import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/settings_universal_patches.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/settings_version_compatibility_check.dart'; -final _settingsViewModel = SettingsViewModel(); class SAdvancedSection extends StatelessWidget { const SAdvancedSection({super.key}); @@ -21,85 +17,14 @@ class SAdvancedSection extends StatelessWidget { Widget build(BuildContext context) { return SettingsSection( title: 'settingsView.advancedSectionTitle', - children: [ - SManageApiUrlUI(), - SManageSourcesUI(), - // SManageKeystorePasswordUI(), + children: const [ SAutoUpdatePatches(), SEnablePatchesSelection(), - SExperimentalUniversalPatches(), - SExperimentalPatches(), - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.regenerateKeystoreLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - subtitle: I18nText('settingsView.regenerateKeystoreHint'), - onTap: () => _showDeleteKeystoreDialog(context), - ), - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.deleteTempDirLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - subtitle: I18nText('settingsView.deleteTempDirHint'), - onTap: () => _settingsViewModel.deleteTempDir(), - ), - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.deleteLogsLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - subtitle: I18nText('settingsView.deleteLogsHint'), - onTap: () => _settingsViewModel.deleteLogs(), - ), + SVersionCompatibilityCheck(), + SUniversalPatches(), + SManageSourcesUI(), + SManageApiUrlUI(), ], ); } - - Future _showDeleteKeystoreDialog(context) { - return showDialog( - context: context, - builder: (context) => AlertDialog( - title: I18nText('settingsView.regenerateKeystoreDialogTitle'), - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('settingsView.regenerateKeystoreDialogText'), - actions: [ - CustomMaterialButton( - isFilled: false, - label: I18nText('noButton'), - onPressed: () => Navigator.of(context).pop(), - ), - CustomMaterialButton( - label: I18nText('yesButton'), - onPressed: () => { - Navigator.of(context).pop(), - _settingsViewModel.deleteKeystore(), - }, - ), - ], - ), - ); - } } diff --git a/lib/ui/widgets/settingsView/settings_debug_section.dart b/lib/ui/widgets/settingsView/settings_debug_section.dart new file mode 100644 index 0000000000..7a155b4e59 --- /dev/null +++ b/lib/ui/widgets/settingsView/settings_debug_section.dart @@ -0,0 +1,68 @@ +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/settingsView/about_widget.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; + +final _settingsViewModel = SettingsViewModel(); + +class SDebugSection extends StatelessWidget { + const SDebugSection({super.key}); + + @override + Widget build(BuildContext context) { + return SettingsSection( + title: 'settingsView.debugSectionTitle', + children: [ + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.logsLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + subtitle: I18nText('settingsView.logsHint'), + onTap: () => _settingsViewModel.exportLogcatLogs(), + ), + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.deleteLogsLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + subtitle: I18nText('settingsView.deleteLogsHint'), + onTap: () => _settingsViewModel.deleteLogs(), + ), + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.deleteTempDirLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), + ), + subtitle: I18nText('settingsView.deleteTempDirHint'), + onTap: () => _settingsViewModel.deleteTempDir(), + ), + const AboutWidget( + padding: EdgeInsets.symmetric(horizontal: 20.0), + ), + ], + ); + } +} diff --git a/lib/ui/widgets/settingsView/settings_export_section.dart b/lib/ui/widgets/settingsView/settings_export_section.dart index 786d22e706..70aaf9b035 100644 --- a/lib/ui/widgets/settingsView/settings_export_section.dart +++ b/lib/ui/widgets/settingsView/settings_export_section.dart @@ -48,7 +48,7 @@ class SExportSection extends StatelessWidget { ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), title: I18nText( - 'settingsView.exportKeystoreLabel', + 'settingsView.resetStoredPatchesLabel', child: const Text( '', style: TextStyle( @@ -57,13 +57,18 @@ class SExportSection extends StatelessWidget { ), ), ), - subtitle: I18nText('settingsView.exportKeystoreHint'), - onTap: () => _settingsViewModel.exportKeystore(), + subtitle: I18nText('settingsView.resetStoredPatchesHint'), + onTap: () => _showResetDialog( + context, + 'settingsView.resetStoredPatchesDialogTitle', + 'settingsView.resetStoredPatchesDialogText', + _settingsViewModel.resetSelectedPatches, + ), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), title: I18nText( - 'settingsView.importKeystoreLabel', + 'settingsView.resetStoredOptionsLabel', child: const Text( '', style: TextStyle( @@ -72,19 +77,18 @@ class SExportSection extends StatelessWidget { ), ), ), - subtitle: I18nText('settingsView.importKeystoreHint'), - onTap: () async { - await _settingsViewModel.importKeystore(); - final sManageKeystorePassword = SManageKeystorePassword(); - if (context.mounted) { - sManageKeystorePassword.showKeystoreDialog(context); - } - }, + subtitle: I18nText('settingsView.resetStoredOptionsHint'), + onTap: () => _showResetDialog( + context, + 'settingsView.resetStoredOptionsDialogTitle', + 'settingsView.resetStoredOptionsDialogText', + _settingsViewModel.resetAllOptions, + ), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), title: I18nText( - 'settingsView.resetStoredPatchesLabel', + 'settingsView.exportKeystoreLabel', child: const Text( '', style: TextStyle( @@ -93,18 +97,13 @@ class SExportSection extends StatelessWidget { ), ), ), - subtitle: I18nText('settingsView.resetStoredPatchesHint'), - onTap: () => _showResetDialog( - context, - 'settingsView.resetStoredPatchesDialogTitle', - 'settingsView.resetStoredPatchesDialogText', - _settingsViewModel.resetSelectedPatches, - ), + subtitle: I18nText('settingsView.exportKeystoreHint'), + onTap: () => _settingsViewModel.exportKeystore(), ), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), title: I18nText( - 'settingsView.resetStoredOptionsLabel', + 'settingsView.importKeystoreLabel', child: const Text( '', style: TextStyle( @@ -113,14 +112,31 @@ class SExportSection extends StatelessWidget { ), ), ), - subtitle: I18nText('settingsView.resetStoredOptionsHint'), - onTap: () => _showResetDialog( - context, - 'settingsView.resetStoredOptionsDialogTitle', - 'settingsView.resetStoredOptionsDialogText', - _settingsViewModel.resetAllOptions, + subtitle: I18nText('settingsView.importKeystoreHint'), + onTap: () async { + await _settingsViewModel.importKeystore(); + final sManageKeystorePassword = SManageKeystorePassword(); + if (context.mounted) { + sManageKeystorePassword.showKeystoreDialog(context); + } + }, + ), + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), + title: I18nText( + 'settingsView.regenerateKeystoreLabel', + child: const Text( + '', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.w500, + ), + ), ), + subtitle: I18nText('settingsView.regenerateKeystoreHint'), + onTap: () => _showDeleteKeystoreDialog(context), ), + // SManageKeystorePasswordUI(), ], ); } @@ -154,4 +170,29 @@ class SExportSection extends StatelessWidget { ), ); } + + Future _showDeleteKeystoreDialog(context) { + return showDialog( + context: context, + builder: (context) => AlertDialog( + title: I18nText('settingsView.regenerateKeystoreDialogTitle'), + backgroundColor: Theme.of(context).colorScheme.secondaryContainer, + content: I18nText('settingsView.regenerateKeystoreDialogText'), + actions: [ + CustomMaterialButton( + isFilled: false, + label: I18nText('noButton'), + onPressed: () => Navigator.of(context).pop(), + ), + CustomMaterialButton( + label: I18nText('yesButton'), + onPressed: () => { + Navigator.of(context).pop(), + _settingsViewModel.deleteKeystore(), + }, + ), + ], + ), + ); + } } diff --git a/lib/ui/widgets/settingsView/settings_info_section.dart b/lib/ui/widgets/settingsView/settings_info_section.dart deleted file mode 100644 index 0a71458101..0000000000 --- a/lib/ui/widgets/settingsView/settings_info_section.dart +++ /dev/null @@ -1,38 +0,0 @@ -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/settingsView/about_widget.dart'; -import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; - -final _settingsViewModel = SettingsViewModel(); - -class SInfoSection extends StatelessWidget { - const SInfoSection({super.key}); - - @override - Widget build(BuildContext context) { - return SettingsSection( - title: 'settingsView.infoSectionTitle', - children: [ - ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'settingsView.logsLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - subtitle: I18nText('settingsView.logsHint'), - onTap: () => _settingsViewModel.exportLogcatLogs(), - ), - const AboutWidget( - padding: EdgeInsets.symmetric(horizontal: 20.0), - ), - ], - ); - } -} diff --git a/lib/ui/widgets/settingsView/settings_experimental_universal_patches.dart b/lib/ui/widgets/settingsView/settings_universal_patches.dart similarity index 75% rename from lib/ui/widgets/settingsView/settings_experimental_universal_patches.dart rename to lib/ui/widgets/settingsView/settings_universal_patches.dart index b8a5841250..1b4c27ee66 100644 --- a/lib/ui/widgets/settingsView/settings_experimental_universal_patches.dart +++ b/lib/ui/widgets/settingsView/settings_universal_patches.dart @@ -4,26 +4,26 @@ import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; -class SExperimentalUniversalPatches extends StatefulWidget { - const SExperimentalUniversalPatches({super.key}); +class SUniversalPatches extends StatefulWidget { + const SUniversalPatches({super.key}); @override - State createState() => - _SExperimentalUniversalPatchesState(); + State createState() => + _SUniversalPatchesState(); } final _settingsViewModel = SettingsViewModel(); final _patchesSelectorViewModel = PatchesSelectorViewModel(); final _patcherViewModel = PatcherViewModel(); -class _SExperimentalUniversalPatchesState - extends State { +class _SUniversalPatchesState + extends State { @override Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), title: I18nText( - 'settingsView.experimentalUniversalPatchesLabel', + 'settingsView.universalPatchesLabel', child: const Text( '', style: TextStyle( @@ -32,7 +32,7 @@ class _SExperimentalUniversalPatchesState ), ), ), - subtitle: I18nText('settingsView.experimentalUniversalPatchesHint'), + subtitle: I18nText('settingsView.universalPatchesHint'), value: _settingsViewModel.areUniversalPatchesEnabled(), onChanged: (value) { setState(() { diff --git a/lib/ui/widgets/settingsView/settings_experimental_patches.dart b/lib/ui/widgets/settingsView/settings_version_compatibility_check.dart similarity index 69% rename from lib/ui/widgets/settingsView/settings_experimental_patches.dart rename to lib/ui/widgets/settingsView/settings_version_compatibility_check.dart index be704c73f5..ead3b07094 100644 --- a/lib/ui/widgets/settingsView/settings_experimental_patches.dart +++ b/lib/ui/widgets/settingsView/settings_version_compatibility_check.dart @@ -5,24 +5,24 @@ import 'package:revanced_manager/ui/views/patches_selector/patches_selector_view import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/utils/check_for_supported_patch.dart'; -class SExperimentalPatches extends StatefulWidget { - const SExperimentalPatches({super.key}); +class SVersionCompatibilityCheck extends StatefulWidget { + const SVersionCompatibilityCheck({super.key}); @override - State createState() => _SExperimentalPatchesState(); + State createState() => _SVersionCompatibilityCheckState(); } final _settingsViewModel = SettingsViewModel(); final _patchesSelectorViewModel = PatchesSelectorViewModel(); final _patcherViewModel = PatcherViewModel(); -class _SExperimentalPatchesState extends State { +class _SVersionCompatibilityCheckState extends State { @override Widget build(BuildContext context) { return SwitchListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), title: I18nText( - 'settingsView.experimentalPatchesLabel', + 'settingsView.versionCompatibilityCheckLabel', child: const Text( '', style: TextStyle( @@ -31,11 +31,11 @@ class _SExperimentalPatchesState extends State { ), ), ), - subtitle: I18nText('settingsView.experimentalPatchesHint'), - value: _settingsViewModel.areExperimentalPatchesEnabled(), + subtitle: I18nText('settingsView.versionCompatibilityCheckHint'), + value: _settingsViewModel.isVersionCompatibilityCheckEnabled(), onChanged: (value) { setState(() { - _settingsViewModel.useExperimentalPatches(value); + _settingsViewModel.useVersionCompatibilityCheck(value); }); if (!value) { _patcherViewModel.selectedPatches diff --git a/lib/ui/widgets/settingsView/social_media_widget.dart b/lib/ui/widgets/settingsView/social_media_widget.dart index 7cc686f111..e64f54aa62 100644 --- a/lib/ui/widgets/settingsView/social_media_widget.dart +++ b/lib/ui/widgets/settingsView/social_media_widget.dart @@ -4,6 +4,7 @@ import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:revanced_manager/ui/widgets/settingsView/social_media_item.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; +import 'package:revanced_manager/ui/widgets/shared/custom_icon.dart'; class SocialMediaWidget extends StatelessWidget { const SocialMediaWidget({ @@ -42,6 +43,12 @@ class SocialMediaWidget extends StatelessWidget { child: const CustomCard( child: Column( children: [ + SocialMediaItem( + icon: Icon(CustomIcon.revancedIcon), + title: Text('Website'), + subtitle: Text('revanced.app'), + url: 'https://revanced.app', + ), SocialMediaItem( icon: FaIcon(FontAwesomeIcons.github), title: Text('GitHub'), diff --git a/lib/ui/widgets/shared/custom_icon.dart b/lib/ui/widgets/shared/custom_icon.dart new file mode 100644 index 0000000000..385b06690f --- /dev/null +++ b/lib/ui/widgets/shared/custom_icon.dart @@ -0,0 +1,9 @@ +import 'package:flutter/widgets.dart'; + +class CustomIcon { + CustomIcon._(); + + static const _kFontFam = 'CustomIcon'; + + static const IconData revancedIcon = IconData(0xe800, fontFamily: _kFontFam); +} diff --git a/pubspec.yaml b/pubspec.yaml index 749d05c401..a15fadf6c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -91,5 +91,9 @@ dev_dependencies: flutter: uses-material-design: true + fonts: + - family: CustomIcon + fonts: + - asset: fonts/custom-icons.ttf assets: - assets/i18n/ From d97192e0eed575f9faa2f679d8c6c24a43ba533e Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Sun, 15 Oct 2023 16:56:43 +0700 Subject: [PATCH 7/9] refactor(patch_options): disable card tap (#1368) --- .../patch_options_fields.dart | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart b/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart index 31c2b1455f..e02021cf90 100644 --- a/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart +++ b/lib/ui/widgets/patchesSelectorView/patch_options_fields.dart @@ -77,7 +77,7 @@ class IntAndStringPatchOption extends StatelessWidget { if (patchOption.required && value == null) { return Column( crossAxisAlignment: CrossAxisAlignment.start, - children:[ + children: [ const SizedBox(height: 8), I18nText( 'patchOptionsView.requiredOption', @@ -139,11 +139,16 @@ class IntStringLongListPatchOption extends StatelessWidget { value: e.toString(), optionType: type, onChanged: (newValue) { - values[index] = type == 'StringListPatchOption' ? newValue : type == 'IntListPatchOption' ? int.parse(newValue) : num.parse(newValue); + values[index] = type == 'StringListPatchOption' + ? newValue + : type == 'IntListPatchOption' + ? int.parse(newValue) + : num.parse(newValue); onChanged(values, patchOption); }, removeValue: (value) { - patchOptionValue.value = List.from(patchOptionValue.value)..removeAt(index); + patchOptionValue.value = List.from(patchOptionValue.value) + ..removeAt(index); values.removeAt(index); onChanged(values, patchOption); }, @@ -154,35 +159,37 @@ class IntStringLongListPatchOption extends StatelessWidget { ), const SizedBox(height: 4), Align( - alignment: Alignment.centerLeft, - child: TextButton( - onPressed: () { - if (type == 'StringListPatchOption') { - patchOptionValue.value = List.from(patchOptionValue.value)..add(''); - values.add(''); - } else { - patchOptionValue.value = List.from(patchOptionValue.value)..add(0); - values.add(0); - } - onChanged(values, patchOption); - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(Icons.add, size: 20), - I18nText( - 'add', - child: const Text( - '', - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - ), + alignment: Alignment.centerLeft, + child: TextButton( + onPressed: () { + if (type == 'StringListPatchOption') { + patchOptionValue.value = List.from(patchOptionValue.value) + ..add(''); + values.add(''); + } else { + patchOptionValue.value = List.from(patchOptionValue.value) + ..add(0); + values.add(0); + } + onChanged(values, patchOption); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.add, size: 20), + I18nText( + 'add', + child: const Text( + '', + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, ), ), - ], - ), + ), + ], ), + ), ), ], ), @@ -239,7 +246,6 @@ class PatchOption extends StatelessWidget { return Padding( padding: const EdgeInsets.all(8.0), child: CustomCard( - onTap: () {}, child: Row( children: [ Expanded( From 72ea33b6debf22b0c9944d2a6850c2e075635862 Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Sun, 15 Oct 2023 17:46:44 +0700 Subject: [PATCH 8/9] fix(patch_selector): correct popup menu style fix: #1372 --- .../patches_selector_view.dart | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/lib/ui/views/patches_selector/patches_selector_view.dart b/lib/ui/views/patches_selector/patches_selector_view.dart index de7469bae4..131c5099d0 100644 --- a/lib/ui/views/patches_selector/patches_selector_view.dart +++ b/lib/ui/views/patches_selector/patches_selector_view.dart @@ -4,7 +4,6 @@ import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/patchesSelectorView/patch_item.dart'; -import 'package:revanced_manager/ui/widgets/shared/custom_popup_menu.dart'; import 'package:revanced_manager/ui/widgets/shared/search_bar.dart'; import 'package:revanced_manager/utils/check_for_supported_patch.dart'; import 'package:stacked/stacked.dart'; @@ -94,20 +93,18 @@ class _PatchesSelectorViewState extends State { ), ), ), - CustomPopupMenu( - onSelected: (value) => - {model.onMenuSelection(value, context)}, - children: { - 0: I18nText( - 'patchesSelectorView.loadPatchesSelection', - child: const Text( - '', - style: TextStyle( - fontWeight: FontWeight.bold, - ), + PopupMenuButton( + onSelected: (value) { + model.onMenuSelection(value, context); + }, + itemBuilder: (BuildContext context) => [ + PopupMenuItem( + value: 0, + child: I18nText( + 'patchesSelectorView.loadPatchesSelection', ), ), - }, + ], ), ], bottom: PreferredSize( From 7a3a6b512fd413b64d839fd36a7c722e223f370c Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Sun, 15 Oct 2023 18:04:19 +0700 Subject: [PATCH 9/9] docs(building): use new highlight format --- docs/4_building.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/4_building.md b/docs/4_building.md index adcf47dd62..d687cfad2c 100644 --- a/docs/4_building.md +++ b/docs/4_building.md @@ -31,7 +31,8 @@ This page will guide you through building ReVanced Manager from source. flutter packages pub run build_runner build --delete-conflicting-outputs ``` - > **Note**: Must be run every time you sync your local repository with the remote repository. + > [!Note] + > Must be run every time you sync your local repository with the remote repository. 7. Build the APK