Merge pull request #707 from revanced/dev

chore: merge branch `dev` to `flutter`
This commit is contained in:
EvadeMaster 2023-03-14 22:07:35 +07:00 committed by GitHub
commit c10e5848bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 447 additions and 479 deletions

3
.env
View File

@ -1,3 +0,0 @@
sentryDSN=
apiKey=
appId=

View File

@ -1,35 +1,104 @@
name: "Android CI Actions" name: Android Release
on: on:
push: push:
branches: branches:
- "**" - "**"
tags-ignore: tags-ignore:
- "v*" # Ignore tags that start with "v" (e.g. v1.0.0) because they are handled by release-build.yml - "v*"
pull_request:
branches:
- "**"
workflow_dispatch:
jobs: jobs:
release: version:
name: Create version number
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Set env
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Set up JDK 12
uses: actions/setup-java@v3
with: with:
java-version: '12' fetch-depth: 0
- name: Fetch all history for all tags and branches
run: |
git config remote.origin.url https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git fetch --prune --depth=10000
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0.9.7
with:
versionSpec: "5.x"
- name: Use GitVersion
id: gitversion
uses: gittools/actions/gitversion/execute@v0.9.7
- name: Create version.txt with nuGetVersion
run: echo ${{ steps.gitversion.outputs.nuGetVersion }} > version.txt
- name: Upload version.txt
uses: actions/upload-artifact@v2
with:
name: gitversion
path: version.txt
build:
name: Create Android Build
needs: version
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Get version.txt
uses: actions/download-artifact@v2
with:
name: gitversion
- name: Create new file without newline char from version.txt
run: tr -d '\n' < version.txt > version1.txt
- name: Read version
id: version
uses: juliangruber/read-file-action@v1
with:
path: version1.txt
- name: Update version in YAML
run: sed -i 's/99.99.99+99/${{ steps.version.outputs.content }}+${{ github.run_number }}/g' pubspec.yaml
- name: Download Android keystore
id: android_keystore
uses: timheuer/base64-to-file@v1.0.3
with:
fileName: upload-keystore.jks
encodedString: ${{ secrets.SIGNING_KEYSTORE }}
- name: Create key.properties
run: |
echo "storeFile=${{ steps.android_keystore.outputs.filePath }}" > android/key.properties
echo "storePassword=${{ secrets.SIGNING_KEYSTORE_PASSWORD }}" >> android/key.properties
echo "keyPassword=${{ secrets.SIGNING_KEY_PASSWORD }}" >> android/key.properties
echo "keyAlias=${{ secrets.SIGNING_KEY_ALIAS }}" >> android/key.properties
- uses: actions/setup-java@v3
with:
distribution: 'zulu' distribution: 'zulu'
java-version: "12.x"
cache: gradle
- uses: subosito/flutter-action@v2 - uses: subosito/flutter-action@v2
with: with:
channel: 'stable' channel: 'stable'
- name: Set environment variables cache: true
run: echo $SECRETS | base64 -d > lib/utils/environment.dart
env: - name: Get dependencies
SECRETS: ${{ secrets.SECRETS }}
- name: Set up Flutter
run: flutter pub get run: flutter pub get
- name: Generate files with Builder - name: Generate files with Builder
run: flutter packages pub run build_runner build --delete-conflicting-outputs run: flutter packages pub run build_runner build --delete-conflicting-outputs
- name: Build with Flutter - name: Build with Flutter
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -37,6 +106,7 @@ jobs:
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }} SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_KEYSTORE_PASSWORD }} SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_KEYSTORE_PASSWORD }}
run: flutter build apk run: flutter build apk
- name: Sign APK - name: Sign APK
id: sign_apk id: sign_apk
uses: ilharp/sign-android-release@v1 uses: ilharp/sign-android-release@v1
@ -46,10 +116,26 @@ jobs:
keyStorePassword: ${{ secrets.SIGNING_KEYSTORE_PASSWORD }} keyStorePassword: ${{ secrets.SIGNING_KEYSTORE_PASSWORD }}
keyAlias: ${{ secrets.SIGNING_KEY_ALIAS }} keyAlias: ${{ secrets.SIGNING_KEY_ALIAS }}
keyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }} keyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
- name: Add version to APK - name: Add version to APK
run: mv ${{ steps.sign_apk.outputs.signedFile }} revanced-manager-${{ env.RELEASE_VERSION }}.apk run: mv ${{ steps.sign_apk.outputs.signedFile }} revanced-manager-${{ env.RELEASE_VERSION }}.apk
- name: Upload APK - name: Upload APK
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: revanced-manager-${{ env.RELEASE_VERSION }} name: revanced-manager-${{ env.RELEASE_VERSION }}
path: revanced-manager-${{ env.RELEASE_VERSION }}.apk path: revanced-manager-${{ env.RELEASE_VERSION }}.apk
# deploy:
# name: Deploy Android Build
# needs: build
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v1
# - name: Get Android Build from artifacts
# uses: actions/download-artifact@v2
# with:
# name: android-release
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true

View File

@ -20,10 +20,6 @@ jobs:
- uses: subosito/flutter-action@v2 - uses: subosito/flutter-action@v2
with: with:
channel: 'stable' channel: 'stable'
- name: Set environment variables
run: echo $SECRETS | base64 -d > lib/utils/environment.dart
env:
SECRETS: ${{ secrets.SECRETS }}
- name: Set up Flutter - name: Set up Flutter
run: flutter pub get run: flutter pub get
- name: Generate files with Builder - name: Generate files with Builder

View File

@ -20,10 +20,6 @@ jobs:
- uses: subosito/flutter-action@v2 - uses: subosito/flutter-action@v2
with: with:
channel: 'stable' channel: 'stable'
- name: Set environment variables
run: echo $SECRETS | base64 -d > lib/utils/environment.dart
env:
SECRETS: ${{ secrets.SECRETS }}
- name: Set up Flutter - name: Set up Flutter
run: flutter pub get run: flutter pub get
- name: Generate files with Builder - name: Generate files with Builder

View File

@ -71,7 +71,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// ReVanced // ReVanced
implementation "app.revanced:revanced-patcher:6.4.3" implementation "app.revanced:revanced-patcher:7.0.0"
// Signing & aligning // Signing & aligning
implementation("org.bouncycastle:bcpkix-jdk15on:1.70") implementation("org.bouncycastle:bcpkix-jdk15on:1.70")

View File

@ -43,7 +43,6 @@ class MainActivity : FlutterActivity() {
val integrationsPath = call.argument<String>("integrationsPath") val integrationsPath = call.argument<String>("integrationsPath")
val selectedPatches = call.argument<List<String>>("selectedPatches") val selectedPatches = call.argument<List<String>>("selectedPatches")
val cacheDirPath = call.argument<String>("cacheDirPath") val cacheDirPath = call.argument<String>("cacheDirPath")
val mergeIntegrations = call.argument<Boolean>("mergeIntegrations")
val keyStoreFilePath = call.argument<String>("keyStoreFilePath") val keyStoreFilePath = call.argument<String>("keyStoreFilePath")
if (patchBundleFilePath != null && if (patchBundleFilePath != null &&
originalFilePath != null && originalFilePath != null &&
@ -53,7 +52,6 @@ class MainActivity : FlutterActivity() {
integrationsPath != null && integrationsPath != null &&
selectedPatches != null && selectedPatches != null &&
cacheDirPath != null && cacheDirPath != null &&
mergeIntegrations != null &&
keyStoreFilePath != null keyStoreFilePath != null
) { ) {
runPatcher( runPatcher(
@ -66,7 +64,6 @@ class MainActivity : FlutterActivity() {
integrationsPath, integrationsPath,
selectedPatches, selectedPatches,
cacheDirPath, cacheDirPath,
mergeIntegrations,
keyStoreFilePath keyStoreFilePath
) )
} else { } else {
@ -88,7 +85,6 @@ class MainActivity : FlutterActivity() {
integrationsPath: String, integrationsPath: String,
selectedPatches: List<String>, selectedPatches: List<String>,
cacheDirPath: String, cacheDirPath: String,
mergeIntegrations: Boolean,
keyStoreFilePath: String keyStoreFilePath: String
) { ) {
val originalFile = File(originalFilePath) val originalFile = File(originalFilePath)
@ -139,19 +135,17 @@ class MainActivity : FlutterActivity() {
mapOf("progress" to 0.3, "header" to "", "log" to "") mapOf("progress" to 0.3, "header" to "", "log" to "")
) )
} }
if (mergeIntegrations) { handler.post {
handler.post { installerChannel.invokeMethod(
installerChannel.invokeMethod( "update",
"update", mapOf(
mapOf( "progress" to 0.4,
"progress" to 0.4, "header" to "Merging integrations...",
"header" to "Merging integrations...", "log" to "Merging integrations"
"log" to "Merging integrations"
)
) )
} )
patcher.addFiles(listOf(integrations)) {}
} }
patcher.addIntegrations(listOf(integrations)) {}
handler.post { handler.post {
installerChannel.invokeMethod( installerChannel.invokeMethod(

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 814 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/> <monochrome android:drawable="@drawable/ic_launcher_monochrome"/>
</adaptive-icon> </adaptive-icon>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#1B1B1B</color>
</resources>

View File

@ -1,6 +1,6 @@
buildscript { buildscript {
ext.cronetVersion = '102.5005.125' ext.cronetVersion = '102.5005.125'
ext.kotlin_version = '1.8.0' ext.kotlin_version = '1.7.10'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()

View File

@ -1,6 +1,6 @@
#Mon May 09 12:07:41 MSK 2022
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-rc-1-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -79,8 +79,11 @@
"searchBarHint": "Search patches", "searchBarHint": "Search patches",
"doneButton": "Done", "doneButton": "Done",
"recommended": "Recommended", "recommended": "Recommended",
"recommendedTooltip": "Select all recommended patches",
"all": "All", "all": "All",
"allTooltip": "Select all patches",
"none": "None", "none": "None",
"noneTooltip": "Deselect all patches",
"loadPatchesSelection": "Load patches selection", "loadPatchesSelection": "Load patches selection",
"noSavedPatches": "No saved patches for the selected app.\nPress Done to save current selection.", "noSavedPatches": "No saved patches for the selected app.\nPress Done to save current selection.",
"noPatchesFound": "No patches found for the selected app", "noPatchesFound": "No patches found for the selected app",
@ -145,8 +148,6 @@
"exportSectionTitle": "Import & export", "exportSectionTitle": "Import & export",
"aboutLabel": "About", "aboutLabel": "About",
"snackbarMessage": "Copied to clipboard", "snackbarMessage": "Copied to clipboard",
"sentryLabel": "Sentry logging",
"sentryHint": "Send anonymous logs to help us improve ReVanced Manager",
"restartAppForChanges": "Restart the app to apply changes", "restartAppForChanges": "Restart the app to apply changes",
"deleteKeystoreLabel": "Delete keystore", "deleteKeystoreLabel": "Delete keystore",
"deleteKeystoreHint": "Delete the keystore used to sign the app", "deleteKeystoreHint": "Delete the keystore used to sign the app",

View File

@ -1,4 +1,3 @@
import 'package:revanced_manager/services/crowdin_api.dart';
import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/github_api.dart';
import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/services/patcher_api.dart'; import 'package:revanced_manager/services/patcher_api.dart';
@ -38,7 +37,6 @@ import 'package:stacked_services/stacked_services.dart';
LazySingleton(classType: PatcherAPI), LazySingleton(classType: PatcherAPI),
LazySingleton(classType: RevancedAPI), LazySingleton(classType: RevancedAPI),
LazySingleton(classType: GithubAPI), LazySingleton(classType: GithubAPI),
LazySingleton(classType: CrowdinAPI),
LazySingleton(classType: Toast), LazySingleton(classType: Toast),
], ],
) )

View File

@ -4,15 +4,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/services/crowdin_api.dart';
import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/github_api.dart';
import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/services/patcher_api.dart'; import 'package:revanced_manager/services/patcher_api.dart';
import 'package:revanced_manager/services/revanced_api.dart'; import 'package:revanced_manager/services/revanced_api.dart';
import 'package:revanced_manager/ui/theme/dynamic_theme_builder.dart'; import 'package:revanced_manager/ui/theme/dynamic_theme_builder.dart';
import 'package:revanced_manager/ui/views/navigation/navigation_view.dart'; import 'package:revanced_manager/ui/views/navigation/navigation_view.dart';
import 'package:revanced_manager/utils/environment.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:stacked_themes/stacked_themes.dart'; import 'package:stacked_themes/stacked_themes.dart';
import 'package:timezone/data/latest.dart' as tz; import 'package:timezone/data/latest.dart' as tz;
@ -25,36 +22,12 @@ Future main() async {
await locator<ManagerAPI>().initialize(); await locator<ManagerAPI>().initialize();
final String apiUrl = locator<ManagerAPI>().getApiUrl(); final String apiUrl = locator<ManagerAPI>().getApiUrl();
await locator<RevancedAPI>().initialize(apiUrl); await locator<RevancedAPI>().initialize(apiUrl);
await locator<CrowdinAPI>().initialize();
final bool isSentryEnabled = locator<ManagerAPI>().isSentryEnabled();
final String repoUrl = locator<ManagerAPI>().getRepoUrl(); final String repoUrl = locator<ManagerAPI>().getRepoUrl();
locator<GithubAPI>().initialize(repoUrl); locator<GithubAPI>().initialize(repoUrl);
await locator<PatcherAPI>().initialize(); await locator<PatcherAPI>().initialize();
tz.initializeTimeZones(); tz.initializeTimeZones();
prefs = await SharedPreferences.getInstance(); prefs = await SharedPreferences.getInstance();
await SentryFlutter.init(
(options) {
options
..dsn = isSentryEnabled ? Environment.sentryDSN : ''
..environment = 'alpha'
..release = '0.1'
..tracesSampleRate = 1.0
..anrEnabled = true
..enableOutOfMemoryTracking = true
..sampleRate = isSentryEnabled ? 1.0 : 0.0
..beforeSend = (event, hint) {
if (isSentryEnabled) {
return event;
} else {
return null;
}
} as BeforeSendCallback?;
},
appRunner: () {
runApp(const MyApp());
},
);
runApp(const MyApp()); runApp(const MyApp());
} }

View File

@ -1,63 +0,0 @@
import 'package:dio/dio.dart';
import 'package:dio_http_cache_lts/dio_http_cache_lts.dart';
import 'package:injectable/injectable.dart' hide Environment;
import 'package:revanced_manager/utils/environment.dart';
import 'package:sentry_dio/sentry_dio.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
@lazySingleton
class CrowdinAPI {
late Dio _dio = Dio();
final DioCacheManager _dioCacheManager = DioCacheManager(CacheConfig());
final apiKey = Environment.crowdinKEY;
Future<void> initialize() async {
try {
_dio = Dio(
BaseOptions(
baseUrl: 'https://api.crowdin.com/api/v2',
),
);
_dio.interceptors.add(_dioCacheManager.interceptor);
_dio.addSentry(
captureFailedRequests: true,
);
} on Exception catch (e, s) {
await Sentry.captureException(e, stackTrace: s);
}
}
Future<void> clearAllCache() async {
try {
await _dioCacheManager.clearAll();
} on Exception catch (e, s) {
await Sentry.captureException(e, stackTrace: s);
}
}
Future<List> getLanguages() async {
try {
final response = await _dio.get(
'/projects',
options: buildCacheOptions(
const Duration(hours: 6),
maxStale: const Duration(days: 1),
options: Options(
headers: {
'Authorization': 'Bearer $apiKey',
},
contentType: 'application/json',
),
),
);
final List targetLanguages =
await response.data['data'][0]['data']['targetLanguages'];
return targetLanguages;
} on Exception catch (e, s) {
await Sentry.captureException(e, stackTrace: s);
return [];
}
}
}

View File

@ -4,11 +4,10 @@ import 'dart:io';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:dio_http_cache_lts/dio_http_cache_lts.dart'; import 'package:dio_http_cache_lts/dio_http_cache_lts.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patch.dart';
import 'package:sentry_dio/sentry_dio.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
@lazySingleton @lazySingleton
class GithubAPI { class GithubAPI {
@ -38,19 +37,20 @@ class GithubAPI {
); );
_dio.interceptors.add(_dioCacheManager.interceptor); _dio.interceptors.add(_dioCacheManager.interceptor);
_dio.addSentry( } on Exception catch (e) {
captureFailedRequests: true, if (kDebugMode) {
); print(e);
} on Exception catch (e, s) { }
await Sentry.captureException(e, stackTrace: s);
} }
} }
Future<void> clearAllCache() async { Future<void> clearAllCache() async {
try { try {
await _dioCacheManager.clearAll(); await _dioCacheManager.clearAll();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
@ -61,8 +61,10 @@ class GithubAPI {
options: _cacheOptions, options: _cacheOptions,
); );
return response.data[0]; return response.data[0];
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
} }
@ -92,10 +94,12 @@ class GithubAPI {
'\n' as String, '\n' as String,
) )
.toList(); .toList();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
return List.empty(); print(e);
}
} }
return [];
} }
Future<File?> getLatestReleaseFile(String extension, String repoName) async { Future<File?> getLatestReleaseFile(String extension, String repoName) async {
@ -112,9 +116,10 @@ class GithubAPI {
); );
} }
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
return null; print(e);
}
} }
return null; return null;
} }
@ -127,10 +132,12 @@ class GithubAPI {
final List<dynamic> list = jsonDecode(f.readAsStringSync()); final List<dynamic> list = jsonDecode(f.readAsStringSync());
patches = list.map((patch) => Patch.fromJson(patch)).toList(); patches = list.map((patch) => Patch.fromJson(patch)).toList();
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
return List.empty(); print(e);
}
} }
return patches; return patches;
} }
@ -142,9 +149,12 @@ class GithubAPI {
} else { } else {
return 'Unknown'; return 'Unknown';
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
return ''; print(e);
}
return 'Unknown';
} }
} }
} }

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:device_apps/device_apps.dart'; import 'package:device_apps/device_apps.dart';
import 'package:flutter/foundation.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -10,7 +11,6 @@ import 'package:revanced_manager/models/patched_application.dart';
import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/github_api.dart';
import 'package:revanced_manager/services/revanced_api.dart'; import 'package:revanced_manager/services/revanced_api.dart';
import 'package:revanced_manager/services/root_api.dart'; import 'package:revanced_manager/services/root_api.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@lazySingleton @lazySingleton
@ -98,14 +98,6 @@ class ManagerAPI {
await _prefs.setBool('useDarkTheme', value); await _prefs.setBool('useDarkTheme', value);
} }
bool isSentryEnabled() {
return _prefs.getBool('sentryEnabled') ?? true;
}
Future<void> setSentryStatus(bool value) async {
await _prefs.setBool('sentryEnabled', value);
}
bool areUniversalPatchesEnabled() { bool areUniversalPatchesEnabled() {
return _prefs.getBool('universalPatchesEnabled') ?? false; return _prefs.getBool('universalPatchesEnabled') ?? false;
} }
@ -179,8 +171,10 @@ class ManagerAPI {
try { try {
_revancedAPI.clearAllCache(); _revancedAPI.clearAllCache();
_githubAPI.clearAllCache(); _githubAPI.clearAllCache();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
@ -196,8 +190,10 @@ class ManagerAPI {
} else { } else {
return await _githubAPI.getPatches(repoName); return await _githubAPI.getPatches(repoName);
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return []; return [];
} }
} }
@ -213,8 +209,10 @@ class ManagerAPI {
} else { } else {
return await _githubAPI.getLatestReleaseFile('.jar', repoName); return await _githubAPI.getLatestReleaseFile('.jar', repoName);
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
} }
@ -230,8 +228,10 @@ class ManagerAPI {
} else { } else {
return await _githubAPI.getLatestReleaseFile('.apk', repoName); return await _githubAPI.getLatestReleaseFile('.apk', repoName);
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
} }

View File

@ -13,7 +13,6 @@ import 'package:revanced_manager/models/patch.dart';
import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/models/patched_application.dart';
import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/services/root_api.dart'; import 'package:revanced_manager/services/root_api.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:share_extend/share_extend.dart'; import 'package:share_extend/share_extend.dart';
@lazySingleton @lazySingleton
@ -49,8 +48,10 @@ class PatcherAPI {
if (_patches.isEmpty) { if (_patches.isEmpty) {
_patches = await _managerAPI.getPatches(); _patches = await _managerAPI.getPatches();
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
_patches = List.empty(); _patches = List.empty();
} }
} }
@ -91,9 +92,10 @@ class PatcherAPI {
filteredApps.add(app); filteredApps.add(app);
} }
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
continue; print(e);
}
} }
} }
} }
@ -122,25 +124,6 @@ class PatcherAPI {
.toList(); .toList();
} }
bool dependencyNeedsIntegrations(String name) {
return name.contains('integrations') ||
_patches.any(
(patch) =>
patch.name == name &&
(patch.dependencies.any(
(dep) => dependencyNeedsIntegrations(dep),
)),
);
}
Future<bool> needsIntegrations(List<Patch> selectedPatches) async {
return selectedPatches.any(
(patch) => patch.dependencies.any(
(dep) => dependencyNeedsIntegrations(dep),
),
);
}
Future<bool> needsResourcePatching(List<Patch> selectedPatches) async { Future<bool> needsResourcePatching(List<Patch> selectedPatches) async {
return selectedPatches.any( return selectedPatches.any(
(patch) => patch.dependencies.any( (patch) => patch.dependencies.any(
@ -170,8 +153,10 @@ class PatcherAPI {
); );
} }
return originalFilePath; return originalFilePath;
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return originalFilePath; return originalFilePath;
} }
} }
@ -181,7 +166,6 @@ class PatcherAPI {
String originalFilePath, String originalFilePath,
List<Patch> selectedPatches, List<Patch> selectedPatches,
) async { ) async {
final bool mergeIntegrations = await needsIntegrations(selectedPatches);
final bool includeSettings = await needsSettingsPatch(selectedPatches); final bool includeSettings = await needsSettingsPatch(selectedPatches);
if (includeSettings) { if (includeSettings) {
try { try {
@ -193,16 +177,14 @@ class PatcherAPI {
if (settingsPatch != null) { if (settingsPatch != null) {
selectedPatches.add(settingsPatch); selectedPatches.add(settingsPatch);
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
// ignore print(e);
}
} }
} }
final File? patchBundleFile = await _managerAPI.downloadPatches(); final File? patchBundleFile = await _managerAPI.downloadPatches();
File? integrationsFile; final File? integrationsFile = await _managerAPI.downloadIntegrations();
if (mergeIntegrations) {
integrationsFile = await _managerAPI.downloadIntegrations();
}
if (patchBundleFile != null) { if (patchBundleFile != null) {
_dataDir.createSync(); _dataDir.createSync();
_tmpDir.createSync(); _tmpDir.createSync();
@ -224,18 +206,16 @@ class PatcherAPI {
'inputFilePath': inputFile.path, 'inputFilePath': inputFile.path,
'patchedFilePath': patchedFile.path, 'patchedFilePath': patchedFile.path,
'outFilePath': _outFile!.path, 'outFilePath': _outFile!.path,
'integrationsPath': mergeIntegrations ? integrationsFile!.path : '', 'integrationsPath': integrationsFile!.path,
'selectedPatches': selectedPatches.map((p) => p.name).toList(), 'selectedPatches': selectedPatches.map((p) => p.name).toList(),
'cacheDirPath': cacheDir.path, 'cacheDirPath': cacheDir.path,
'mergeIntegrations': mergeIntegrations,
'keyStoreFilePath': _keyStoreFile.path, 'keyStoreFilePath': _keyStoreFile.path,
}, },
); );
} on Exception catch (e, s) { } on Exception catch (e) {
if (kDebugMode) { if (kDebugMode) {
print(e); print(e);
} }
throw await Sentry.captureException(e, stackTrace: s);
} }
} }
} }
@ -256,8 +236,10 @@ class PatcherAPI {
await AppInstaller.installApk(_outFile!.path); await AppInstaller.installApk(_outFile!.path);
return await DeviceApps.isAppInstalled(patchedApp.packageName); return await DeviceApps.isAppInstalled(patchedApp.packageName);
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return false; return false;
} }
} }
@ -268,11 +250,17 @@ class PatcherAPI {
try { try {
if (_outFile != null) { if (_outFile != null) {
final String newName = _getFileName(appName, version); final String newName = _getFileName(appName, version);
CRFileSaver.saveFileWithDialog(SaveFileDialogParams( CRFileSaver.saveFileWithDialog(
sourceFilePath: _outFile!.path, destinationFileName: newName,),); SaveFileDialogParams(
sourceFilePath: _outFile!.path,
destinationFileName: newName,
),
);
}
} on Exception catch (e) {
if (kDebugMode) {
print(e);
} }
} on Exception catch (e, s) {
Sentry.captureException(e, stackTrace: s);
} }
} }
@ -286,8 +274,10 @@ class PatcherAPI {
final File shareFile = _outFile!.copySync(newPath); final File shareFile = _outFile!.copySync(newPath);
ShareExtend.share(shareFile.path, 'file'); ShareExtend.share(shareFile.path, 'file');
} }
} on Exception catch (e, s) { } on Exception catch (e) {
Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }

View File

@ -4,13 +4,12 @@ import 'dart:io';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:dio_http_cache_lts/dio_http_cache_lts.dart'; import 'package:dio_http_cache_lts/dio_http_cache_lts.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:native_dio_client/native_dio_client.dart'; import 'package:native_dio_client/native_dio_client.dart';
import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patch.dart';
import 'package:revanced_manager/utils/check_for_gms.dart'; import 'package:revanced_manager/utils/check_for_gms.dart';
import 'package:sentry_dio/sentry_dio.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:timeago/timeago.dart'; import 'package:timeago/timeago.dart';
@lazySingleton @lazySingleton
@ -42,19 +41,20 @@ class RevancedAPI {
log('ReVanced API: Using CronetEngine + $isGMSInstalled'); log('ReVanced API: Using CronetEngine + $isGMSInstalled');
} }
_dio.interceptors.add(_dioCacheManager.interceptor); _dio.interceptors.add(_dioCacheManager.interceptor);
_dio.addSentry( } on Exception catch (e) {
captureFailedRequests: true, if (kDebugMode) {
); print(e);
} on Exception catch (e, s) { }
await Sentry.captureException(e, stackTrace: s);
} }
} }
Future<void> clearAllCache() async { Future<void> clearAllCache() async {
try { try {
await _dioCacheManager.clearAll(); await _dioCacheManager.clearAll();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
@ -67,8 +67,10 @@ class RevancedAPI {
final String name = repo['name']; final String name = repo['name'];
contributors[name] = repo['contributors']; contributors[name] = repo['contributors'];
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return {}; return {};
} }
return contributors; return contributors;
@ -79,8 +81,10 @@ class RevancedAPI {
final response = await _dio.get('/patches', options: _cacheOptions); final response = await _dio.get('/patches', options: _cacheOptions);
final List<dynamic> patches = response.data; final List<dynamic> patches = response.data;
return patches.map((patch) => Patch.fromJson(patch)).toList(); return patches.map((patch) => Patch.fromJson(patch)).toList();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return List.empty(); return List.empty();
} }
} }
@ -97,8 +101,10 @@ class RevancedAPI {
t['repository'] == repoName && t['repository'] == repoName &&
(t['name'] as String).endsWith(extension), (t['name'] as String).endsWith(extension),
); );
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
} }
@ -115,8 +121,10 @@ class RevancedAPI {
if (release != null) { if (release != null) {
return release['version']; return release['version'];
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
return null; return null;
@ -132,8 +140,10 @@ class RevancedAPI {
final String url = release['browser_download_url']; final String url = release['browser_download_url'];
return await DefaultCacheManager().getSingleFile(url); return await DefaultCacheManager().getSingleFile(url);
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
return null; return null;
@ -153,8 +163,10 @@ class RevancedAPI {
DateTime.parse(release['timestamp'] as String); DateTime.parse(release['timestamp'] as String);
return format(timestamp, locale: 'en_short'); return format(timestamp, locale: 'en_short');
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return null; return null;
} }
return null; return null;

View File

@ -1,5 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:root/root.dart'; import 'package:root/root.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
class RootAPI { class RootAPI {
final String _managerDirPath = '/data/local/tmp/revanced-manager'; final String _managerDirPath = '/data/local/tmp/revanced-manager';
@ -10,8 +10,10 @@ class RootAPI {
try { try {
final bool? isRooted = await Root.isRootAvailable(); final bool? isRooted = await Root.isRootAvailable();
return isRooted != null && isRooted; return isRooted != null && isRooted;
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return false; return false;
} }
} }
@ -24,8 +26,10 @@ class RootAPI {
return isRooted != null && isRooted; return isRooted != null && isRooted;
} }
return false; return false;
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return false; return false;
} }
} }
@ -78,8 +82,10 @@ class RootAPI {
apps.removeWhere((pack) => pack.isEmpty); apps.removeWhere((pack) => pack.isEmpty);
return apps.map((pack) => pack.trim()).toList(); return apps.map((pack) => pack.trim()).toList();
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return List.empty(); return List.empty();
} }
return List.empty(); return List.empty();
@ -125,8 +131,10 @@ class RootAPI {
await installApk(packageName, patchedFilePath); await installApk(packageName, patchedFilePath);
await mountApk(packageName, originalFilePath); await mountApk(packageName, originalFilePath);
return true; return true;
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return false; return false;
} }
} }

View File

@ -12,7 +12,7 @@ var lightCustomTheme = ThemeData(
navigationBarTheme: NavigationBarThemeData( navigationBarTheme: NavigationBarThemeData(
labelTextStyle: MaterialStateProperty.all( labelTextStyle: MaterialStateProperty.all(
TextStyle( TextStyle(
color: lightCustomColorScheme.secondary, color: lightCustomColorScheme.onSurface,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
@ -33,13 +33,12 @@ var darkCustomTheme = ThemeData(
navigationBarTheme: NavigationBarThemeData( navigationBarTheme: NavigationBarThemeData(
labelTextStyle: MaterialStateProperty.all( labelTextStyle: MaterialStateProperty.all(
TextStyle( TextStyle(
color: darkCustomColorScheme.secondary, color: darkCustomColorScheme.onSurface,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
), ),
canvasColor: const Color(0xff1B1A1D), canvasColor: const Color(0xff1B1A1D),
scaffoldBackgroundColor: const Color(0xff1B1A1D), scaffoldBackgroundColor: const Color(0xff1B1A1D),
toggleableActiveColor: const Color(0xffA5CAFF),
textTheme: GoogleFonts.robotoTextTheme(ThemeData.dark().textTheme), textTheme: GoogleFonts.robotoTextTheme(ThemeData.dark().textTheme),
); );

View File

@ -23,48 +23,28 @@ class DynamicThemeBuilder extends StatelessWidget {
builder: (lightColorScheme, darkColorScheme) { builder: (lightColorScheme, darkColorScheme) {
final ThemeData lightDynamicTheme = ThemeData( final ThemeData lightDynamicTheme = ThemeData(
useMaterial3: true, useMaterial3: true,
canvasColor: lightColorScheme?.surface,
navigationBarTheme: NavigationBarThemeData( navigationBarTheme: NavigationBarThemeData(
backgroundColor: lightColorScheme?.surface,
indicatorColor: lightColorScheme?.secondaryContainer,
labelTextStyle: MaterialStateProperty.all( labelTextStyle: MaterialStateProperty.all(
GoogleFonts.roboto( GoogleFonts.roboto(
color: lightColorScheme?.onSurface, color: lightColorScheme?.onSurface,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
iconTheme: MaterialStateProperty.all(
IconThemeData(
color: lightColorScheme?.onSecondaryContainer,
),
),
), ),
scaffoldBackgroundColor: lightColorScheme?.surface,
colorScheme: lightColorScheme?.harmonized(), colorScheme: lightColorScheme?.harmonized(),
toggleableActiveColor: lightColorScheme?.primary,
textTheme: GoogleFonts.robotoTextTheme(ThemeData.light().textTheme), textTheme: GoogleFonts.robotoTextTheme(ThemeData.light().textTheme),
); );
final ThemeData darkDynamicTheme = ThemeData( final ThemeData darkDynamicTheme = ThemeData(
useMaterial3: true, useMaterial3: true,
canvasColor: darkColorScheme?.surface,
navigationBarTheme: NavigationBarThemeData( navigationBarTheme: NavigationBarThemeData(
backgroundColor: darkColorScheme?.surface,
indicatorColor: darkColorScheme?.secondaryContainer,
labelTextStyle: MaterialStateProperty.all( labelTextStyle: MaterialStateProperty.all(
GoogleFonts.roboto( GoogleFonts.roboto(
color: darkColorScheme?.onSurface, color: darkColorScheme?.onSurface,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
iconTheme: MaterialStateProperty.all(
IconThemeData(
color: darkColorScheme?.onSecondaryContainer,
),
),
), ),
scaffoldBackgroundColor: darkColorScheme?.surface,
colorScheme: darkColorScheme?.harmonized(), colorScheme: darkColorScheme?.harmonized(),
toggleableActiveColor: darkColorScheme?.primary,
textTheme: GoogleFonts.robotoTextTheme(ThemeData.dark().textTheme), textTheme: GoogleFonts.robotoTextTheme(ThemeData.dark().textTheme),
); );
return DynamicTheme( return DynamicTheme(
@ -90,4 +70,4 @@ class DynamicThemeBuilder extends StatelessWidget {
}, },
); );
} }
} }

View File

@ -41,14 +41,14 @@ class _AppSelectorViewState extends State<AppSelectorView> {
child: Text( child: Text(
'', '',
style: TextStyle( style: TextStyle(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),
leading: IconButton( leading: IconButton(
icon: Icon( icon: Icon(
Icons.arrow_back, Icons.arrow_back,
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
), ),

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:device_apps/device_apps.dart'; import 'package:device_apps/device_apps.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/models/patched_application.dart';
@ -9,7 +10,6 @@ import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/services/patcher_api.dart'; import 'package:revanced_manager/services/patcher_api.dart';
import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/services/toast.dart';
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
class AppSelectorViewModel extends BaseViewModel { class AppSelectorViewModel extends BaseViewModel {
@ -87,8 +87,10 @@ class AppSelectorViewModel extends BaseViewModel {
locator<PatcherViewModel>().loadLastSelectedPatches(); locator<PatcherViewModel>().loadLastSelectedPatches();
} }
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
_toast.showBottom('appSelectorView.errorMessage'); _toast.showBottom('appSelectorView.errorMessage');
} }
} }

View File

@ -23,7 +23,7 @@ class ContributorsView extends StatelessWidget {
child: Text( child: Text(
'', '',
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),

View File

@ -7,7 +7,6 @@ import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/homeView/available_updates_card.dart'; import 'package:revanced_manager/ui/widgets/homeView/available_updates_card.dart';
import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart'; import 'package:revanced_manager/ui/widgets/homeView/installed_apps_card.dart';
import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart'; import 'package:revanced_manager/ui/widgets/homeView/latest_commit_card.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_chip.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
@ -22,8 +21,6 @@ class HomeView extends StatelessWidget {
viewModelBuilder: () => locator<HomeViewModel>(), viewModelBuilder: () => locator<HomeViewModel>(),
builder: (context, model, child) => Scaffold( builder: (context, model, child) => Scaffold(
body: RefreshIndicator( body: RefreshIndicator(
color: Theme.of(context).colorScheme.secondary,
backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
onRefresh: () => model.forceRefresh(context), onRefresh: () => model.forceRefresh(context),
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
@ -34,7 +31,7 @@ class HomeView extends StatelessWidget {
child: Text( child: Text(
'', '',
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),
@ -48,7 +45,7 @@ class HomeView extends StatelessWidget {
'homeView.updatesSubtitle', 'homeView.updatesSubtitle',
child: Text( child: Text(
'', '',
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
@ -61,27 +58,53 @@ class HomeView extends StatelessWidget {
'homeView.patchedSubtitle', 'homeView.patchedSubtitle',
child: Text( child: Text(
'', '',
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
children: <Widget>[ children: <Widget>[
CustomChip( ActionChip(
avatar: const Icon(Icons.grid_view),
label: I18nText('homeView.installed'), label: I18nText('homeView.installed'),
isSelected: !model.showUpdatableApps, side: BorderSide(
onSelected: (value) { color: model.showUpdatableApps
? Theme.of(context).colorScheme.outline
: Theme.of(context)
.colorScheme
.secondaryContainer,
width: model.showUpdatableApps ? 1 : 1,
),
backgroundColor: model.showUpdatableApps
? Theme.of(context).colorScheme.background
: Theme.of(context)
.colorScheme
.secondaryContainer,
onPressed: () {
model.toggleUpdatableApps(false); model.toggleUpdatableApps(false);
}, },
), ),
const SizedBox(width: 10), const SizedBox(width: 10),
CustomChip( ActionChip(
avatar: const Icon(Icons.update),
label: I18nText('homeView.updatesAvailable'), label: I18nText('homeView.updatesAvailable'),
isSelected: model.showUpdatableApps, side: BorderSide(
onSelected: (value) { color: !model.showUpdatableApps
? Theme.of(context).colorScheme.outline
: Theme.of(context)
.colorScheme
.secondaryContainer,
width: !model.showUpdatableApps ? 1 : 1,
),
backgroundColor: !model.showUpdatableApps
? Theme.of(context).colorScheme.background
: Theme.of(context)
.colorScheme
.secondaryContainer,
onPressed: () {
model.toggleUpdatableApps(true); model.toggleUpdatableApps(true);
}, },
) ),
], ],
), ),
const SizedBox(height: 14), const SizedBox(height: 14),

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'package:app_installer/app_installer.dart'; import 'package:app_installer/app_installer.dart';
import 'package:cross_connectivity/cross_connectivity.dart'; import 'package:cross_connectivity/cross_connectivity.dart';
import 'package:device_apps/device_apps.dart'; import 'package:device_apps/device_apps.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
@ -18,7 +19,6 @@ import 'package:revanced_manager/services/toast.dart';
import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.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/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_dialog.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import 'package:timezone/timezone.dart' as tz; import 'package:timezone/timezone.dart' as tz;
@ -95,8 +95,10 @@ class HomeViewModel extends BaseViewModel {
final int currentVersionInt = final int currentVersionInt =
int.parse(currentVersion.replaceAll(RegExp('[^0-9]'), '')); int.parse(currentVersion.replaceAll(RegExp('[^0-9]'), ''));
return latestVersionInt > currentVersionInt; return latestVersionInt > currentVersionInt;
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
return false; return false;
} }
} }
@ -137,8 +139,10 @@ class HomeViewModel extends BaseViewModel {
} else { } else {
_toast.showBottom('homeView.errorDownloadMessage'); _toast.showBottom('homeView.errorDownloadMessage');
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
_toast.showBottom('homeView.errorInstallMessage'); _toast.showBottom('homeView.errorInstallMessage');
} }
} }

View File

@ -28,7 +28,7 @@ class InstallerView extends StatelessWidget {
title: Text( title: Text(
model.headerLogs, model.headerLogs,
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
onBackButtonPressed: () => model.onWillPop(context), onBackButtonPressed: () => model.onWillPop(context),

View File

@ -1,5 +1,6 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'package:device_apps/device_apps.dart'; import 'package:device_apps/device_apps.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_background/flutter_background.dart'; import 'package:flutter_background/flutter_background.dart';
@ -14,7 +15,6 @@ import 'package:revanced_manager/services/root_api.dart';
import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/services/toast.dart';
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:wakelock/wakelock.dart'; import 'package:wakelock/wakelock.dart';
@ -56,9 +56,10 @@ class InstallerViewModel extends BaseViewModel {
), ),
), ),
).then((value) => FlutterBackground.enableBackgroundExecution()); ).then((value) => FlutterBackground.enableBackgroundExecution());
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
// ignore print(e);
} // ignore
} }
} }
await Wakelock.enable(); await Wakelock.enable();
@ -131,14 +132,15 @@ class InstallerViewModel extends BaseViewModel {
_app.apkFilePath, _app.apkFilePath,
_patches, _patches,
); );
} on Exception catch (e, s) { } on Exception catch (e) {
update( update(
-100.0, -100.0,
'Aborting...', 'Aborting...',
'An error occurred! Aborting\nError:\n$e', 'An error occurred! Aborting\nError:\n$e',
); );
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
throw await Sentry.captureException(e, stackTrace: s); print(e);
}
} }
} else { } else {
update(-100.0, 'Aborting...', 'No app or patches selected! Aborting'); update(-100.0, 'Aborting...', 'No app or patches selected! Aborting');
@ -146,14 +148,17 @@ class InstallerViewModel extends BaseViewModel {
if (FlutterBackground.isBackgroundExecutionEnabled) { if (FlutterBackground.isBackgroundExecutionEnabled) {
try { try {
FlutterBackground.disableBackgroundExecution(); FlutterBackground.disableBackgroundExecution();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
// ignore print(e);
} // ignore
} }
} }
await Wakelock.disable(); await Wakelock.disable();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
@ -211,24 +216,30 @@ class InstallerViewModel extends BaseViewModel {
await _managerAPI.savePatchedApp(_app); await _managerAPI.savePatchedApp(_app);
} }
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
void exportResult() { void exportResult() {
try { try {
_patcherAPI.exportPatchedFile(_app.name, _app.version); _patcherAPI.exportPatchedFile(_app.name, _app.version);
} on Exception catch (e, s) { } on Exception catch (e) {
Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
void shareResult() { void shareResult() {
try { try {
_patcherAPI.sharePatchedFile(_app.name, _app.version); _patcherAPI.sharePatchedFile(_app.name, _app.version);
} on Exception catch (e, s) { } on Exception catch (e) {
Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
@ -242,8 +253,10 @@ class InstallerViewModel extends BaseViewModel {
locator<PatcherViewModel>().selectedApp = null; locator<PatcherViewModel>().selectedApp = null;
locator<PatcherViewModel>().selectedPatches.clear(); locator<PatcherViewModel>().selectedPatches.clear();
locator<PatcherViewModel>().notifyListeners(); locator<PatcherViewModel>().notifyListeners();
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }

View File

@ -42,7 +42,6 @@ class NavigationView extends StatelessWidget {
context, context,
'navigationView.dashboardTab', 'navigationView.dashboardTab',
), ),
tooltip: '',
), ),
NavigationDestination( NavigationDestination(
icon: model.isIndexSelected(1) icon: model.isIndexSelected(1)
@ -52,7 +51,6 @@ class NavigationView extends StatelessWidget {
context, context,
'navigationView.patcherTab', 'navigationView.patcherTab',
), ),
tooltip: '',
), ),
NavigationDestination( NavigationDestination(
icon: model.isIndexSelected(2) icon: model.isIndexSelected(2)
@ -62,7 +60,6 @@ class NavigationView extends StatelessWidget {
context, context,
'navigationView.settingsTab', 'navigationView.settingsTab',
), ),
tooltip: '',
), ),
], ],
), ),

View File

@ -34,7 +34,7 @@ class PatcherView extends StatelessWidget {
child: Text( child: Text(
'', '',
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),

View File

@ -52,31 +52,33 @@ class PatcherViewModel extends BaseViewModel {
Future<void> showPatchConfirmationDialog(BuildContext context) async { Future<void> showPatchConfirmationDialog(BuildContext context) async {
final bool isValid = await isValidPatchConfig(); final bool isValid = await isValidPatchConfig();
if (isValid) { if (context.mounted) {
navigateToInstaller(); if (isValid) {
} else { navigateToInstaller();
return showDialog( } else {
context: context, return showDialog(
builder: (context) => AlertDialog( context: context,
title: I18nText('warning'), builder: (context) => AlertDialog(
backgroundColor: Theme.of(context).colorScheme.secondaryContainer, title: I18nText('warning'),
content: I18nText('patcherView.patchDialogText'), backgroundColor: Theme.of(context).colorScheme.secondaryContainer,
actions: <Widget>[ content: I18nText('patcherView.patchDialogText'),
CustomMaterialButton( actions: <Widget>[
isFilled: false, CustomMaterialButton(
label: I18nText('noButton'), isFilled: false,
onPressed: () => Navigator.of(context).pop(), label: I18nText('noButton'),
), onPressed: () => Navigator.of(context).pop(),
CustomMaterialButton( ),
label: I18nText('yesButton'), CustomMaterialButton(
onPressed: () { label: I18nText('yesButton'),
Navigator.of(context).pop(); onPressed: () {
navigateToInstaller(); Navigator.of(context).pop();
}, navigateToInstaller();
) },
], )
), ],
); ),
);
}
} }
} }
@ -114,7 +116,8 @@ class PatcherViewModel extends BaseViewModel {
await _managerAPI.getSelectedPatches(selectedApp!.originalPackageName); await _managerAPI.getSelectedPatches(selectedApp!.originalPackageName);
final List<Patch> patches = final List<Patch> patches =
_patcherAPI.getFilteredPatches(selectedApp!.originalPackageName); _patcherAPI.getFilteredPatches(selectedApp!.originalPackageName);
this.selectedPatches this
.selectedPatches
.addAll(patches.where((patch) => selectedPatches.contains(patch.name))); .addAll(patches.where((patch) => selectedPatches.contains(patch.name)));
notifyListeners(); notifyListeners();
} }

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/ui/views/patches_selector/patches_selector_viewmodel.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/patchesSelectorView/patch_item.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_chip.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_popup_menu.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/ui/widgets/shared/search_bar.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
@ -50,14 +49,14 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
child: Text( child: Text(
'', '',
style: TextStyle( style: TextStyle(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),
leading: IconButton( leading: IconButton(
icon: Icon( icon: Icon(
Icons.arrow_back, Icons.arrow_back,
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
), ),
@ -74,7 +73,7 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
child: Text( child: Text(
model.patchesVersion!, model.patchesVersion!,
style: TextStyle( style: TextStyle(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),
@ -135,27 +134,36 @@ class _PatchesSelectorViewState extends State<PatchesSelectorView> {
children: [ children: [
Row( Row(
children: [ children: [
CustomChip( ActionChip(
label: label: I18nText('patchesSelectorView.recommended'),
I18nText('patchesSelectorView.recommended'), tooltip: FlutterI18n.translate(
onSelected: (value) { context,
'patchesSelectorView.recommendedTooltip',
),
onPressed: () {
model.selectRecommendedPatches(); model.selectRecommendedPatches();
}, },
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
CustomChip( ActionChip(
label: I18nText('patchesSelectorView.all'), label: I18nText('patchesSelectorView.all'),
onSelected: (value) { tooltip: FlutterI18n.translate(
if (value) { context,
model.selectAllPatcherWarning(context); 'patchesSelectorView.allTooltip',
} ),
onPressed: () {
model.selectAllPatcherWarning(context);
model.selectAllPatches(true); model.selectAllPatches(true);
}, },
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
CustomChip( ActionChip(
label: I18nText('patchesSelectorView.none'), label: I18nText('patchesSelectorView.none'),
onSelected: (value) { tooltip: FlutterI18n.translate(
context,
'patchesSelectorView.noneTooltip',
),
onPressed: () {
model.clearPatches(); model.clearPatches();
}, },
), ),

View File

@ -152,8 +152,6 @@ class SManageSources extends BaseViewModel {
_managerAPI.setPatchesRepo(''); _managerAPI.setPatchesRepo('');
_managerAPI.setIntegrationsRepo(''); _managerAPI.setIntegrationsRepo('');
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
}, },
) )
], ],

View File

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/main.dart'; import 'package:revanced_manager/main.dart';
import 'package:revanced_manager/services/crowdin_api.dart';
import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/services/toast.dart';
import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart'; import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
@ -16,7 +15,6 @@ import 'package:timeago/timeago.dart' as timeago;
final _settingViewModel = SettingsViewModel(); final _settingViewModel = SettingsViewModel();
class SUpdateLanguage extends BaseViewModel { class SUpdateLanguage extends BaseViewModel {
final CrowdinAPI _crowdinAPI = locator<CrowdinAPI>();
final Toast _toast = locator<Toast>(); final Toast _toast = locator<Toast>();
late SharedPreferences _prefs; late SharedPreferences _prefs;
String selectedLanguage = 'English'; String selectedLanguage = 'English';
@ -43,7 +41,6 @@ class SUpdateLanguage extends BaseViewModel {
} }
Future<void> initLang() async { Future<void> initLang() async {
languages = await _crowdinAPI.getLanguages();
languages.sort((a, b) => a['name'].compareTo(b['name'])); languages.sort((a, b) => a['name'].compareTo(b['name']));
notifyListeners(); notifyListeners();
} }

View File

@ -7,7 +7,6 @@ import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_switch_tile.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
@ -64,8 +63,8 @@ class SUpdateThemeUI extends StatelessWidget {
return SettingsSection( return SettingsSection(
title: 'settingsView.appearanceSectionTitle', title: 'settingsView.appearanceSectionTitle',
children: <Widget>[ children: <Widget>[
CustomSwitchTile( SwitchListTile(
padding: const EdgeInsets.symmetric(horizontal: 20.0), contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: I18nText( title: I18nText(
'settingsView.darkThemeLabel', 'settingsView.darkThemeLabel',
child: const Text( child: const Text(
@ -78,7 +77,7 @@ class SUpdateThemeUI extends StatelessWidget {
), ),
subtitle: I18nText('settingsView.darkThemeHint'), subtitle: I18nText('settingsView.darkThemeHint'),
value: SUpdateTheme().getDarkThemeStatus(), value: SUpdateTheme().getDarkThemeStatus(),
onTap: (value) => SUpdateTheme().setUseDarkTheme( onChanged: (value) => SUpdateTheme().setUseDarkTheme(
context, context,
value, value,
), ),
@ -88,8 +87,8 @@ class SUpdateThemeUI extends StatelessWidget {
builder: (context, snapshot) => Visibility( builder: (context, snapshot) => Visibility(
visible: visible:
snapshot.hasData && snapshot.data! >= ANDROID_12_SDK_VERSION, snapshot.hasData && snapshot.data! >= ANDROID_12_SDK_VERSION,
child: CustomSwitchTile( child: SwitchListTile(
padding: const EdgeInsets.symmetric(horizontal: 20.0), contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: I18nText( title: I18nText(
'settingsView.dynamicThemeLabel', 'settingsView.dynamicThemeLabel',
child: const Text( child: const Text(
@ -102,11 +101,12 @@ class SUpdateThemeUI extends StatelessWidget {
), ),
subtitle: I18nText('settingsView.dynamicThemeHint'), subtitle: I18nText('settingsView.dynamicThemeHint'),
value: _settingViewModel.sUpdateTheme.getDynamicThemeStatus(), value: _settingViewModel.sUpdateTheme.getDynamicThemeStatus(),
onTap: (value) => onChanged: (value) => {
_settingViewModel.sUpdateTheme.setUseDynamicTheme( _settingViewModel.sUpdateTheme.setUseDynamicTheme(
context, context,
value, value,
), ),
},
), ),
), ),
), ),

View File

@ -3,7 +3,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragement/settings_update_theme.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/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_export_section.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_export_section.dart';
@ -32,7 +32,7 @@ class SettingsView extends StatelessWidget {
child: Text( child: Text(
'', '',
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),
@ -49,8 +49,6 @@ class SettingsView extends StatelessWidget {
_settingsDivider, _settingsDivider,
SExportSection(), SExportSection(),
_settingsDivider, _settingsDivider,
// SLoggingSection(),
// _settingsDivider,
SInfoSection(), SInfoSection(),
], ],
), ),

View File

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:cr_file_saver/file_saver.dart'; import 'package:cr_file_saver/file_saver.dart';
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:logcat/logcat.dart'; import 'package:logcat/logcat.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:revanced_manager/app/app.locator.dart'; import 'package:revanced_manager/app/app.locator.dart';
@ -9,9 +10,8 @@ import 'package:revanced_manager/app/app.router.dart';
import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/services/toast.dart';
import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragement/settings_update_language.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_language.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragement/settings_update_theme.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:share_extend/share_extend.dart'; import 'package:share_extend/share_extend.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
@ -28,16 +28,6 @@ class SettingsViewModel extends BaseViewModel {
_navigationService.navigateTo(Routes.contributorsView); _navigationService.navigateTo(Routes.contributorsView);
} }
bool isSentryEnabled() {
return _managerAPI.isSentryEnabled();
}
void useSentry(bool value) {
_managerAPI.setSentryStatus(value);
_toast.showBottom('settingsView.restartAppForChanges');
notifyListeners();
}
bool areUniversalPatchesEnabled() { bool areUniversalPatchesEnabled() {
return _managerAPI.areUniversalPatchesEnabled(); return _managerAPI.areUniversalPatchesEnabled();
} }
@ -74,14 +64,20 @@ class SettingsViewModel extends BaseViewModel {
if (outFile.existsSync()) { if (outFile.existsSync()) {
final String dateTime = final String dateTime =
DateTime.now().toString().replaceAll(' ', '_').split('.').first; DateTime.now().toString().replaceAll(' ', '_').split('.').first;
await CRFileSaver.saveFileWithDialog(SaveFileDialogParams( await CRFileSaver.saveFileWithDialog(
sourceFilePath: outFile.path, destinationFileName: 'selected_patches_$dateTime.json',),); SaveFileDialogParams(
sourceFilePath: outFile.path,
destinationFileName: 'selected_patches_$dateTime.json',
),
);
_toast.showBottom('settingsView.exportedPatches'); _toast.showBottom('settingsView.exportedPatches');
} else { } else {
_toast.showBottom('settingsView.noExportFileFound'); _toast.showBottom('settingsView.noExportFileFound');
} }
} on Exception catch (e, s) { } on Exception catch (e) {
Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
} }
} }
@ -100,8 +96,10 @@ class SettingsViewModel extends BaseViewModel {
} }
_toast.showBottom('settingsView.importedPatches'); _toast.showBottom('settingsView.importedPatches');
} }
} on Exception catch (e, s) { } on Exception catch (e) {
await Sentry.captureException(e, stackTrace: s); if (kDebugMode) {
print(e);
}
_toast.showBottom('settingsView.jsonSelectorErrorMessage'); _toast.showBottom('settingsView.jsonSelectorErrorMessage');
} }
} }

View File

@ -27,7 +27,7 @@ class AppInfoView extends StatelessWidget {
child: Text( child: Text(
'', '',
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
), ),
), ),
@ -51,13 +51,13 @@ class AppInfoView extends StatelessWidget {
Text( Text(
app.name, app.name,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
app.version, app.version,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleLarge,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
Padding( Padding(

View File

@ -28,7 +28,7 @@ class AvailableUpdatesCard extends StatelessWidget {
child: Text( child: Text(
'', '',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1!.copyWith( style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
), ),
), ),
@ -53,7 +53,7 @@ class AvailableUpdatesCard extends StatelessWidget {
// child: Text( // child: Text(
// '', // '',
// textAlign: TextAlign.center, // textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1!.copyWith( // style: Theme.of(context).textTheme.titleMedium!.copyWith(
// color: Theme.of(context).colorScheme.secondary, // color: Theme.of(context).colorScheme.secondary,
// ), // ),
// ), // ),

View File

@ -30,7 +30,7 @@ class InstalledAppsCard extends StatelessWidget {
child: Text( child: Text(
'', '',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.subtitle1!.copyWith( style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
), ),
), ),

View File

@ -61,7 +61,7 @@ class OptionsFilePicker extends StatelessWidget {
child: Text( child: Text(
'Select File', 'Select File',
style: TextStyle( style: TextStyle(
color: Theme.of(context).textTheme.bodyText1?.color, color: Theme.of(context).textTheme.bodyLarge?.color,
), ),
), ),
), ),

View File

@ -2,8 +2,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragement/settings_manage_api_url.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragement/settings_manage_sources.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/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_patches.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_experimental_universal_patches.dart';

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_switch_tile.dart';
class SExperimentalPatches extends StatefulWidget { class SExperimentalPatches extends StatefulWidget {
const SExperimentalPatches({super.key}); const SExperimentalPatches({super.key});
@ -15,8 +14,8 @@ final _settingsViewModel = SettingsViewModel();
class _SExperimentalPatchesState extends State<SExperimentalPatches> { class _SExperimentalPatchesState extends State<SExperimentalPatches> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CustomSwitchTile( return SwitchListTile(
padding: const EdgeInsets.symmetric(horizontal: 20.0), contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: I18nText( title: I18nText(
'settingsView.experimentalPatchesLabel', 'settingsView.experimentalPatchesLabel',
child: const Text( child: const Text(
@ -29,7 +28,7 @@ class _SExperimentalPatchesState extends State<SExperimentalPatches> {
), ),
subtitle: I18nText('settingsView.experimentalPatchesHint'), subtitle: I18nText('settingsView.experimentalPatchesHint'),
value: _settingsViewModel.areExperimentalPatchesEnabled(), value: _settingsViewModel.areExperimentalPatchesEnabled(),
onTap: (value) { onChanged: (value) {
setState(() { setState(() {
_settingsViewModel.useExperimentalPatches(value); _settingsViewModel.useExperimentalPatches(value);
}); });

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:flutter_i18n/widgets/I18nText.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/settingsView/custom_switch_tile.dart';
class SExperimentalUniversalPatches extends StatefulWidget { class SExperimentalUniversalPatches extends StatefulWidget {
const SExperimentalUniversalPatches({super.key}); const SExperimentalUniversalPatches({super.key});
@ -17,8 +16,8 @@ class _SExperimentalUniversalPatchesState
extends State<SExperimentalUniversalPatches> { extends State<SExperimentalUniversalPatches> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CustomSwitchTile( return SwitchListTile(
padding: const EdgeInsets.symmetric(horizontal: 20.0), contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: I18nText( title: I18nText(
'settingsView.experimentalUniversalPatchesLabel', 'settingsView.experimentalUniversalPatchesLabel',
child: const Text( child: const Text(
@ -31,7 +30,7 @@ class _SExperimentalUniversalPatchesState
), ),
subtitle: I18nText('settingsView.experimentalUniversalPatchesHint'), subtitle: I18nText('settingsView.experimentalUniversalPatchesHint'),
value: _settingsViewModel.areUniversalPatchesEnabled(), value: _settingsViewModel.areUniversalPatchesEnabled(),
onTap: (value) { onChanged: (value) {
setState(() { setState(() {
_settingsViewModel.showUniversalPatches(value); _settingsViewModel.showUniversalPatches(value);
}); });

View File

@ -1,36 +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/custom_switch_tile.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
final _settingsViewModel = SettingsViewModel();
class SLoggingSection extends StatelessWidget {
const SLoggingSection({super.key});
@override
Widget build(BuildContext context) {
return SettingsSection(
title: 'settingsView.logsSectionTitle',
children: <Widget>[
CustomSwitchTile(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
title: I18nText(
'settingsView.sentryLabel',
child: const Text(
'',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
),
subtitle: I18nText('settingsView.sentryHint'),
value: _settingsViewModel.isSentryEnabled(),
onTap: (value) => _settingsViewModel.useSentry(value),
),
],
);
}
}

View File

@ -17,7 +17,7 @@ class CustomChip extends StatelessWidget {
showCheckmark: false, showCheckmark: false,
label: label, label: label,
selected: isSelected, selected: isSelected,
labelStyle: Theme.of(context).textTheme.subtitle2!.copyWith( labelStyle: Theme.of(context).textTheme.titleSmall!.copyWith(
color: isSelected color: isSelected
? Theme.of(context).colorScheme.primary ? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.secondary, : Theme.of(context).colorScheme.secondary,

View File

@ -33,7 +33,7 @@ class CustomSliverAppBar extends StatelessWidget {
: IconButton( : IconButton(
icon: Icon( icon: Icon(
Icons.arrow_back, Icons.arrow_back,
color: Theme.of(context).textTheme.headline6!.color, color: Theme.of(context).textTheme.titleLarge!.color,
), ),
onPressed: onPressed:
onBackButtonPressed ?? () => Navigator.of(context).pop(), onBackButtonPressed ?? () => Navigator.of(context).pop(),

View File

@ -1,5 +0,0 @@
// Dummy environment variables used for building the app locally. These automatically get set with correct values during workflow builds.
class Environment {
static const sentryDSN = '';
static const crowdinKEY = '';
}

View File

@ -10,7 +10,6 @@ environment:
sdk: ">=2.17.5 <3.0.0" sdk: ">=2.17.5 <3.0.0"
dependencies: dependencies:
sentry_flutter: ^6.12.2
animations: ^2.0.4 animations: ^2.0.4
app_installer: ^1.1.0 app_installer: ^1.1.0
collection: ^1.16.0 collection: ^1.16.0
@ -73,7 +72,6 @@ dependencies:
timezone: ^0.8.0 timezone: ^0.8.0
url_launcher: ^6.1.5 url_launcher: ^6.1.5
wakelock: ^0.6.2 wakelock: ^0.6.2
sentry_dio: ^6.12.2
flutter_dotenv: ^5.0.2 flutter_dotenv: ^5.0.2
pub_release: ^8.0.3 pub_release: ^8.0.3
flutter_markdown: ^0.6.13 flutter_markdown: ^0.6.13
@ -92,5 +90,4 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
assets: assets:
- assets/i18n/ - assets/i18n/
- .env