mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
chore: update dependencies (#772)
* chore: updated some dependencies * refactor: reimplemented cache interceptor * Revert "Updated dependencies & migrated breaking changes" This reverts commit e6743b0d6b2552fdbf1c99d23e158e682362dd5d. * chore: migrated flutter_local_notifications * revert: reimplemented cache interceptor
This commit is contained in:
parent
37b583f560
commit
197770b68b
10 changed files with 199 additions and 92 deletions
|
@ -30,6 +30,7 @@ android {
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
sourceCompatibility JavaVersion.VERSION_11
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
targetCompatibility JavaVersion.VERSION_11
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
|
@ -48,6 +49,7 @@ android {
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
multiDexEnabled true
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
@ -81,4 +83,11 @@ dependencies {
|
||||||
implementation("org.microg:cronet-common:$cronetVersion")
|
implementation("org.microg:cronet-common:$cronetVersion")
|
||||||
implementation("org.microg:cronet-native:$cronetVersion")
|
implementation("org.microg:cronet-native:$cronetVersion")
|
||||||
|
|
||||||
|
// Core libraries
|
||||||
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
|
// Window
|
||||||
|
implementation 'androidx.window:window:1.0.0'
|
||||||
|
implementation 'androidx.window:window-java:1.0.0'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,9 @@ class GithubAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>?> getLatestRelease(String repoName) async {
|
Future<Map<String, dynamic>?> getLatestRelease(
|
||||||
|
String repoName,
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
final response = await _dio.get(
|
final response = await _dio.get(
|
||||||
'/repos/$repoName/releases',
|
'/repos/$repoName/releases',
|
||||||
|
@ -119,9 +121,13 @@ class GithubAPI {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> getLatestReleaseFile(String extension, String repoName) async {
|
Future<File?> getLatestReleaseFile(
|
||||||
|
String extension,
|
||||||
|
String repoName,
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic>? release = await getLatestRelease(repoName);
|
final Map<String, dynamic>? release =
|
||||||
|
await getLatestRelease(repoName);
|
||||||
if (release != null) {
|
if (release != null) {
|
||||||
final Map<String, dynamic>? asset =
|
final Map<String, dynamic>? asset =
|
||||||
(release['assets'] as List<dynamic>).firstWhereOrNull(
|
(release['assets'] as List<dynamic>).firstWhereOrNull(
|
||||||
|
@ -160,7 +166,8 @@ class GithubAPI {
|
||||||
|
|
||||||
Future<String> getLastestReleaseVersion(String repoName) async {
|
Future<String> getLastestReleaseVersion(String repoName) async {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic>? release = await getLatestRelease(repoName);
|
final Map<String, dynamic>? release =
|
||||||
|
await getLatestRelease(repoName);
|
||||||
if (release != null) {
|
if (release != null) {
|
||||||
return release['tag_name'];
|
return release['tag_name'];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,7 +39,8 @@ class ManagerAPI {
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
_prefs = await SharedPreferences.getInstance();
|
_prefs = await SharedPreferences.getInstance();
|
||||||
storedPatchesFile =
|
storedPatchesFile =
|
||||||
(await getApplicationDocumentsDirectory()).path + storedPatchesFile;
|
(await getApplicationDocumentsDirectory()).path +
|
||||||
|
storedPatchesFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getApiUrl() {
|
String getApiUrl() {
|
||||||
|
@ -78,7 +79,8 @@ class ManagerAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
String getIntegrationsRepo() {
|
String getIntegrationsRepo() {
|
||||||
return _prefs.getString('integrationsRepo') ?? defaultIntegrationsRepo;
|
return _prefs.getString('integrationsRepo') ??
|
||||||
|
defaultIntegrationsRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setIntegrationsRepo(String value) async {
|
Future<void> setIntegrationsRepo(String value) async {
|
||||||
|
@ -146,10 +148,14 @@ class ManagerAPI {
|
||||||
|
|
||||||
List<PatchedApplication> getPatchedApps() {
|
List<PatchedApplication> getPatchedApps() {
|
||||||
final List<String> apps = _prefs.getStringList('patchedApps') ?? [];
|
final List<String> apps = _prefs.getStringList('patchedApps') ?? [];
|
||||||
return apps.map((a) => PatchedApplication.fromJson(jsonDecode(a))).toList();
|
return apps
|
||||||
|
.map((a) => PatchedApplication.fromJson(jsonDecode(a)))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setPatchedApps(List<PatchedApplication> patchedApps) async {
|
Future<void> setPatchedApps(
|
||||||
|
List<PatchedApplication> patchedApps,
|
||||||
|
) async {
|
||||||
if (patchedApps.length > 1) {
|
if (patchedApps.length > 1) {
|
||||||
patchedApps.sort((a, b) => a.name.compareTo(b.name));
|
patchedApps.sort((a, b) => a.name.compareTo(b.name));
|
||||||
}
|
}
|
||||||
|
@ -251,15 +257,24 @@ class ManagerAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> downloadManager() async {
|
Future<File?> downloadManager() async {
|
||||||
return await _revancedAPI.getLatestReleaseFile('.apk', defaultManagerRepo);
|
return await _revancedAPI.getLatestReleaseFile(
|
||||||
|
'.apk',
|
||||||
|
defaultManagerRepo,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestPatcherReleaseTime() async {
|
Future<String?> getLatestPatcherReleaseTime() async {
|
||||||
return await _revancedAPI.getLatestReleaseTime('.gz', defaultPatcherRepo);
|
return await _revancedAPI.getLatestReleaseTime(
|
||||||
|
'.gz',
|
||||||
|
defaultPatcherRepo,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestManagerReleaseTime() async {
|
Future<String?> getLatestManagerReleaseTime() async {
|
||||||
return await _revancedAPI.getLatestReleaseTime('.apk', defaultManagerRepo);
|
return await _revancedAPI.getLatestReleaseTime(
|
||||||
|
'.apk',
|
||||||
|
defaultManagerRepo,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> getLatestManagerVersion() async {
|
Future<String?> getLatestManagerVersion() async {
|
||||||
|
@ -313,10 +328,12 @@ class ManagerAPI {
|
||||||
final List<PatchedApplication> unsavedApps = [];
|
final List<PatchedApplication> unsavedApps = [];
|
||||||
final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
|
final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
|
||||||
if (hasRootPermissions) {
|
if (hasRootPermissions) {
|
||||||
final List<String> installedApps = await _rootAPI.getInstalledApps();
|
final List<String> installedApps =
|
||||||
|
await _rootAPI.getInstalledApps();
|
||||||
for (final String packageName in installedApps) {
|
for (final String packageName in installedApps) {
|
||||||
if (!patchedApps.any((app) => app.packageName == packageName)) {
|
if (!patchedApps.any((app) => app.packageName == packageName)) {
|
||||||
final ApplicationWithIcon? application = await DeviceApps.getApp(
|
final ApplicationWithIcon? application =
|
||||||
|
await DeviceApps.getApp(
|
||||||
packageName,
|
packageName,
|
||||||
true,
|
true,
|
||||||
) as ApplicationWithIcon?;
|
) as ApplicationWithIcon?;
|
||||||
|
@ -342,8 +359,10 @@ class ManagerAPI {
|
||||||
for (final Application app in userApps) {
|
for (final Application app in userApps) {
|
||||||
if (app.packageName.startsWith('app.revanced') &&
|
if (app.packageName.startsWith('app.revanced') &&
|
||||||
!app.packageName.startsWith('app.revanced.manager.') &&
|
!app.packageName.startsWith('app.revanced.manager.') &&
|
||||||
!patchedApps.any((uapp) => uapp.packageName == app.packageName)) {
|
!patchedApps
|
||||||
final ApplicationWithIcon? application = await DeviceApps.getApp(
|
.any((uapp) => uapp.packageName == app.packageName)) {
|
||||||
|
final ApplicationWithIcon? application =
|
||||||
|
await DeviceApps.getApp(
|
||||||
app.packageName,
|
app.packageName,
|
||||||
true,
|
true,
|
||||||
) as ApplicationWithIcon?;
|
) as ApplicationWithIcon?;
|
||||||
|
@ -386,8 +405,9 @@ class ManagerAPI {
|
||||||
final int currentInstalledVersionInt = int.parse(
|
final int currentInstalledVersionInt = int.parse(
|
||||||
currentInstalledVersion.replaceAll(RegExp('[^0-9]'), ''),
|
currentInstalledVersion.replaceAll(RegExp('[^0-9]'), ''),
|
||||||
);
|
);
|
||||||
final int currentSavedVersionInt =
|
final int currentSavedVersionInt = int.parse(
|
||||||
int.parse(currentSavedVersion.replaceAll(RegExp('[^0-9]'), ''));
|
currentSavedVersion.replaceAll(RegExp('[^0-9]'), ''),
|
||||||
|
);
|
||||||
if (currentInstalledVersionInt > currentSavedVersionInt) {
|
if (currentInstalledVersionInt > currentSavedVersionInt) {
|
||||||
app.hasUpdates = true;
|
app.hasUpdates = true;
|
||||||
}
|
}
|
||||||
|
@ -399,9 +419,11 @@ class ManagerAPI {
|
||||||
|
|
||||||
Future<bool> isAppUninstalled(PatchedApplication app) async {
|
Future<bool> isAppUninstalled(PatchedApplication app) async {
|
||||||
bool existsRoot = false;
|
bool existsRoot = false;
|
||||||
final bool existsNonRoot = await DeviceApps.isAppInstalled(app.packageName);
|
final bool existsNonRoot =
|
||||||
|
await DeviceApps.isAppInstalled(app.packageName);
|
||||||
if (app.isRooted) {
|
if (app.isRooted) {
|
||||||
final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
|
final bool hasRootPermissions =
|
||||||
|
await _rootAPI.hasRootPermissions();
|
||||||
if (hasRootPermissions) {
|
if (hasRootPermissions) {
|
||||||
existsRoot = await _rootAPI.isAppInstalled(app.packageName);
|
existsRoot = await _rootAPI.isAppInstalled(app.packageName);
|
||||||
}
|
}
|
||||||
|
@ -410,7 +432,10 @@ class ManagerAPI {
|
||||||
return !existsNonRoot;
|
return !existsNonRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> hasAppUpdates(String packageName, DateTime patchDate) async {
|
Future<bool> hasAppUpdates(
|
||||||
|
String packageName,
|
||||||
|
DateTime patchDate,
|
||||||
|
) async {
|
||||||
final List<String> commits = await _githubAPI.getCommits(
|
final List<String> commits = await _githubAPI.getCommits(
|
||||||
packageName,
|
packageName,
|
||||||
getPatchesRepo(),
|
getPatchesRepo(),
|
||||||
|
@ -448,9 +473,13 @@ class ManagerAPI {
|
||||||
return app != null && app.isSplit;
|
return app != null && app.isSplit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setSelectedPatches(String app, List<String> patches) async {
|
Future<void> setSelectedPatches(
|
||||||
|
String app,
|
||||||
|
List<String> patches,
|
||||||
|
) async {
|
||||||
final File selectedPatchesFile = File(storedPatchesFile);
|
final File selectedPatchesFile = File(storedPatchesFile);
|
||||||
final Map<String, dynamic> patchesMap = await readSelectedPatchesFile();
|
final Map<String, dynamic> patchesMap =
|
||||||
|
await readSelectedPatchesFile();
|
||||||
if (patches.isEmpty) {
|
if (patches.isEmpty) {
|
||||||
patchesMap.remove(app);
|
patchesMap.remove(app);
|
||||||
} else {
|
} else {
|
||||||
|
@ -460,7 +489,8 @@ class ManagerAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<String>> getSelectedPatches(String app) async {
|
Future<List<String>> getSelectedPatches(String app) async {
|
||||||
final Map<String, dynamic> patchesMap = await readSelectedPatchesFile();
|
final Map<String, dynamic> patchesMap =
|
||||||
|
await readSelectedPatchesFile();
|
||||||
return List.from(patchesMap.putIfAbsent(app, () => List.empty()));
|
return List.from(patchesMap.putIfAbsent(app, () => List.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,8 @@ class PatcherAPI {
|
||||||
onlyAppsWithLaunchIntent: true,
|
onlyAppsWithLaunchIntent: true,
|
||||||
);
|
);
|
||||||
for (final pkg in allPackages) {
|
for (final pkg in allPackages) {
|
||||||
if (!filteredApps.any((app) => app.packageName == pkg.packageName)) {
|
if (!filteredApps
|
||||||
|
.any((app) => app.packageName == pkg.packageName)) {
|
||||||
final appInfo = await DeviceApps.getApp(
|
final appInfo = await DeviceApps.getApp(
|
||||||
pkg.packageName,
|
pkg.packageName,
|
||||||
true,
|
true,
|
||||||
|
@ -83,7 +84,8 @@ class PatcherAPI {
|
||||||
for (final Patch patch in _patches) {
|
for (final Patch patch in _patches) {
|
||||||
for (final Package package in patch.compatiblePackages) {
|
for (final Package package in patch.compatiblePackages) {
|
||||||
try {
|
try {
|
||||||
if (!filteredApps.any((app) => app.packageName == package.name)) {
|
if (!filteredApps
|
||||||
|
.any((app) => app.packageName == package.name)) {
|
||||||
final ApplicationWithIcon? app = await DeviceApps.getApp(
|
final ApplicationWithIcon? app = await DeviceApps.getApp(
|
||||||
package.name,
|
package.name,
|
||||||
true,
|
true,
|
||||||
|
@ -118,13 +120,17 @@ class PatcherAPI {
|
||||||
return filteredPatches[packageName];
|
return filteredPatches[packageName];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Patch>> getAppliedPatches(List<String> appliedPatches) async {
|
Future<List<Patch>> getAppliedPatches(
|
||||||
|
List<String> appliedPatches,
|
||||||
|
) async {
|
||||||
return _patches
|
return _patches
|
||||||
.where((patch) => appliedPatches.contains(patch.name))
|
.where((patch) => appliedPatches.contains(patch.name))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
||||||
(dep) => dep.contains('resource-'),
|
(dep) => dep.contains('resource-'),
|
||||||
|
@ -145,7 +151,8 @@ class PatcherAPI {
|
||||||
String originalFilePath,
|
String originalFilePath,
|
||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
|
final bool hasRootPermissions =
|
||||||
|
await _rootAPI.hasRootPermissions();
|
||||||
if (hasRootPermissions) {
|
if (hasRootPermissions) {
|
||||||
originalFilePath = await _rootAPI.getOriginalFilePath(
|
originalFilePath = await _rootAPI.getOriginalFilePath(
|
||||||
packageName,
|
packageName,
|
||||||
|
@ -166,13 +173,15 @@ class PatcherAPI {
|
||||||
String originalFilePath,
|
String originalFilePath,
|
||||||
List<Patch> selectedPatches,
|
List<Patch> selectedPatches,
|
||||||
) async {
|
) async {
|
||||||
final bool includeSettings = await needsSettingsPatch(selectedPatches);
|
final bool includeSettings =
|
||||||
|
await needsSettingsPatch(selectedPatches);
|
||||||
if (includeSettings) {
|
if (includeSettings) {
|
||||||
try {
|
try {
|
||||||
final Patch? settingsPatch = _patches.firstWhereOrNull(
|
final Patch? settingsPatch = _patches.firstWhereOrNull(
|
||||||
(patch) =>
|
(patch) =>
|
||||||
patch.name.contains('settings') &&
|
patch.name.contains('settings') &&
|
||||||
patch.compatiblePackages.any((pack) => pack.name == packageName),
|
patch.compatiblePackages
|
||||||
|
.any((pack) => pack.name == packageName),
|
||||||
);
|
);
|
||||||
if (settingsPatch != null) {
|
if (settingsPatch != null) {
|
||||||
selectedPatches.add(settingsPatch);
|
selectedPatches.add(settingsPatch);
|
||||||
|
@ -184,7 +193,8 @@ class PatcherAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final File? patchBundleFile = await _managerAPI.downloadPatches();
|
final File? patchBundleFile = await _managerAPI.downloadPatches();
|
||||||
final File? integrationsFile = await _managerAPI.downloadIntegrations();
|
final File? integrationsFile =
|
||||||
|
await _managerAPI.downloadIntegrations();
|
||||||
if (patchBundleFile != null) {
|
if (patchBundleFile != null) {
|
||||||
_dataDir.createSync();
|
_dataDir.createSync();
|
||||||
_tmpDir.createSync();
|
_tmpDir.createSync();
|
||||||
|
@ -207,7 +217,8 @@ class PatcherAPI {
|
||||||
'patchedFilePath': patchedFile.path,
|
'patchedFilePath': patchedFile.path,
|
||||||
'outFilePath': _outFile!.path,
|
'outFilePath': _outFile!.path,
|
||||||
'integrationsPath': 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,
|
||||||
'keyStoreFilePath': _keyStoreFile.path,
|
'keyStoreFilePath': _keyStoreFile.path,
|
||||||
'keystorePassword': _managerAPI.getKeystorePassword(),
|
'keystorePassword': _managerAPI.getKeystorePassword(),
|
||||||
|
@ -225,7 +236,8 @@ class PatcherAPI {
|
||||||
if (_outFile != null) {
|
if (_outFile != null) {
|
||||||
try {
|
try {
|
||||||
if (patchedApp.isRooted) {
|
if (patchedApp.isRooted) {
|
||||||
final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
|
final bool hasRootPermissions =
|
||||||
|
await _rootAPI.hasRootPermissions();
|
||||||
if (hasRootPermissions) {
|
if (hasRootPermissions) {
|
||||||
return _rootAPI.installApp(
|
return _rootAPI.installApp(
|
||||||
patchedApp.packageName,
|
patchedApp.packageName,
|
||||||
|
@ -235,7 +247,9 @@ class PatcherAPI {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
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) {
|
} on Exception catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
|
@ -307,7 +321,8 @@ class PatcherAPI {
|
||||||
String getRecommendedVersion(String packageName) {
|
String getRecommendedVersion(String packageName) {
|
||||||
final Map<String, int> versions = {};
|
final Map<String, int> versions = {};
|
||||||
for (final Patch patch in _patches) {
|
for (final Patch patch in _patches) {
|
||||||
final Package? package = patch.compatiblePackages.firstWhereOrNull(
|
final Package? package =
|
||||||
|
patch.compatiblePackages.firstWhereOrNull(
|
||||||
(pack) => pack.name == packageName,
|
(pack) => pack.name == packageName,
|
||||||
);
|
);
|
||||||
if (package != null) {
|
if (package != null) {
|
||||||
|
@ -326,7 +341,8 @@ class PatcherAPI {
|
||||||
versions
|
versions
|
||||||
..clear()
|
..clear()
|
||||||
..addEntries(entries);
|
..addEntries(entries);
|
||||||
versions.removeWhere((key, value) => value != versions.values.last);
|
versions
|
||||||
|
.removeWhere((key, value) => value != versions.values.last);
|
||||||
return (versions.keys.toList()..sort()).last;
|
return (versions.keys.toList()..sort()).last;
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
|
|
@ -142,7 +142,10 @@ class RevancedAPI {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> getLatestReleaseFile(String extension, String repoName) async {
|
Future<File?> getLatestReleaseFile(
|
||||||
|
String extension,
|
||||||
|
String repoName,
|
||||||
|
) async {
|
||||||
try {
|
try {
|
||||||
final Map<String, dynamic>? release = await _getLatestRelease(
|
final Map<String, dynamic>? release = await _getLatestRelease(
|
||||||
extension,
|
extension,
|
||||||
|
|
|
@ -3,7 +3,6 @@ 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:flutter/foundation.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';
|
||||||
|
@ -25,12 +24,14 @@ import 'package:timezone/timezone.dart' as tz;
|
||||||
|
|
||||||
@lazySingleton
|
@lazySingleton
|
||||||
class HomeViewModel extends BaseViewModel {
|
class HomeViewModel extends BaseViewModel {
|
||||||
final NavigationService _navigationService = locator<NavigationService>();
|
final NavigationService _navigationService =
|
||||||
|
locator<NavigationService>();
|
||||||
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
final PatcherAPI _patcherAPI = locator<PatcherAPI>();
|
final PatcherAPI _patcherAPI = locator<PatcherAPI>();
|
||||||
final GithubAPI _githubAPI = locator<GithubAPI>();
|
final GithubAPI _githubAPI = locator<GithubAPI>();
|
||||||
final Toast _toast = locator<Toast>();
|
final Toast _toast = locator<Toast>();
|
||||||
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
|
final flutterLocalNotificationsPlugin =
|
||||||
|
FlutterLocalNotificationsPlugin();
|
||||||
DateTime? _lastUpdate;
|
DateTime? _lastUpdate;
|
||||||
bool showUpdatableApps = false;
|
bool showUpdatableApps = false;
|
||||||
List<PatchedApplication> patchedInstalledApps = [];
|
List<PatchedApplication> patchedInstalledApps = [];
|
||||||
|
@ -41,8 +42,17 @@ class HomeViewModel extends BaseViewModel {
|
||||||
const InitializationSettings(
|
const InitializationSettings(
|
||||||
android: AndroidInitializationSettings('ic_notification'),
|
android: AndroidInitializationSettings('ic_notification'),
|
||||||
),
|
),
|
||||||
onSelectNotification: (p) =>
|
onDidReceiveNotificationResponse: (response) async {
|
||||||
DeviceApps.openApp('app.revanced.manager.flutter'),
|
if (response.id == 0) {
|
||||||
|
_toast.showBottom('homeView.installingMessage');
|
||||||
|
final File? managerApk = await _managerAPI.downloadManager();
|
||||||
|
if (managerApk != null) {
|
||||||
|
await AppInstaller.installApk(managerApk.path);
|
||||||
|
} else {
|
||||||
|
_toast.showBottom('homeView.errorDownloadMessage');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
);
|
);
|
||||||
flutterLocalNotificationsPlugin
|
flutterLocalNotificationsPlugin
|
||||||
.resolvePlatformSpecificImplementation<
|
.resolvePlatformSpecificImplementation<
|
||||||
|
@ -52,6 +62,19 @@ class HomeViewModel extends BaseViewModel {
|
||||||
if (!isConnected) {
|
if (!isConnected) {
|
||||||
_toast.showBottom('homeView.noConnection');
|
_toast.showBottom('homeView.noConnection');
|
||||||
}
|
}
|
||||||
|
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
|
||||||
|
await flutterLocalNotificationsPlugin
|
||||||
|
.getNotificationAppLaunchDetails();
|
||||||
|
if (notificationAppLaunchDetails?.didNotificationLaunchApp ??
|
||||||
|
false) {
|
||||||
|
_toast.showBottom('homeView.installingMessage');
|
||||||
|
final File? managerApk = await _managerAPI.downloadManager();
|
||||||
|
if (managerApk != null) {
|
||||||
|
await AppInstaller.installApk(managerApk.path);
|
||||||
|
} else {
|
||||||
|
_toast.showBottom('homeView.errorDownloadMessage');
|
||||||
|
}
|
||||||
|
}
|
||||||
_getPatchedApps();
|
_getPatchedApps();
|
||||||
_managerAPI.reAssessSavedApps().then((_) => _getPatchedApps());
|
_managerAPI.reAssessSavedApps().then((_) => _getPatchedApps());
|
||||||
}
|
}
|
||||||
|
@ -86,8 +109,10 @@ class HomeViewModel extends BaseViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> hasManagerUpdates() async {
|
Future<bool> hasManagerUpdates() async {
|
||||||
final String? latestVersion = await _managerAPI.getLatestManagerVersion();
|
final String? latestVersion =
|
||||||
final String currentVersion = await _managerAPI.getCurrentManagerVersion();
|
await _managerAPI.getLatestManagerVersion();
|
||||||
|
final String currentVersion =
|
||||||
|
await _managerAPI.getCurrentManagerVersion();
|
||||||
if (latestVersion != null) {
|
if (latestVersion != null) {
|
||||||
try {
|
try {
|
||||||
final int latestVersionInt =
|
final int latestVersionInt =
|
||||||
|
@ -171,7 +196,9 @@ class HomeViewModel extends BaseViewModel {
|
||||||
_toast.showBottom('homeView.updatesDisabled');
|
_toast.showBottom('homeView.updatesDisabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> showUpdateConfirmationDialog(BuildContext parentContext) {
|
Future<void> showUpdateConfirmationDialog(
|
||||||
|
BuildContext parentContext,
|
||||||
|
) {
|
||||||
return showModalBottomSheet(
|
return showModalBottomSheet(
|
||||||
context: parentContext,
|
context: parentContext,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
|
|
|
@ -17,12 +17,14 @@ import 'package:stacked/stacked.dart';
|
||||||
class NavigationViewModel extends IndexTrackingViewModel {
|
class NavigationViewModel extends IndexTrackingViewModel {
|
||||||
Future<void> initialize(BuildContext context) async {
|
Future<void> initialize(BuildContext context) async {
|
||||||
locator<Toast>().initialize(context);
|
locator<Toast>().initialize(context);
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
final SharedPreferences prefs =
|
||||||
|
await SharedPreferences.getInstance();
|
||||||
if (prefs.getBool('permissionsRequested') == null) {
|
if (prefs.getBool('permissionsRequested') == null) {
|
||||||
await prefs.setBool('permissionsRequested', true);
|
await prefs.setBool('permissionsRequested', true);
|
||||||
RootAPI().hasRootPermissions().then(
|
RootAPI().hasRootPermissions().then(
|
||||||
(value) => Permission.requestInstallPackages.request().then(
|
(value) => Permission.requestInstallPackages.request().then(
|
||||||
(value) => Permission.ignoreBatteryOptimizations.request(),
|
(value) =>
|
||||||
|
Permission.ignoreBatteryOptimizations.request(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +39,8 @@ class NavigationViewModel extends IndexTrackingViewModel {
|
||||||
SystemUiOverlayStyle(
|
SystemUiOverlayStyle(
|
||||||
systemNavigationBarColor: Colors.transparent,
|
systemNavigationBarColor: Colors.transparent,
|
||||||
systemNavigationBarIconBrightness:
|
systemNavigationBarIconBrightness:
|
||||||
DynamicTheme.of(context)!.theme.brightness == Brightness.light
|
DynamicTheme.of(context)!.theme.brightness ==
|
||||||
|
Brightness.light
|
||||||
? Brightness.dark
|
? Brightness.dark
|
||||||
: Brightness.light,
|
: Brightness.light,
|
||||||
),
|
),
|
||||||
|
|
|
@ -17,7 +17,8 @@ import 'package:stacked/stacked.dart';
|
||||||
import 'package:stacked_services/stacked_services.dart';
|
import 'package:stacked_services/stacked_services.dart';
|
||||||
|
|
||||||
class SettingsViewModel extends BaseViewModel {
|
class SettingsViewModel extends BaseViewModel {
|
||||||
final NavigationService _navigationService = locator<NavigationService>();
|
final NavigationService _navigationService =
|
||||||
|
locator<NavigationService>();
|
||||||
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
final ManagerAPI _managerAPI = locator<ManagerAPI>();
|
||||||
final Toast _toast = locator<Toast>();
|
final Toast _toast = locator<Toast>();
|
||||||
|
|
||||||
|
@ -62,8 +63,11 @@ class SettingsViewModel extends BaseViewModel {
|
||||||
try {
|
try {
|
||||||
final File outFile = File(_managerAPI.storedPatchesFile);
|
final File outFile = File(_managerAPI.storedPatchesFile);
|
||||||
if (outFile.existsSync()) {
|
if (outFile.existsSync()) {
|
||||||
final String dateTime =
|
final String dateTime = DateTime.now()
|
||||||
DateTime.now().toString().replaceAll(' ', '_').split('.').first;
|
.toString()
|
||||||
|
.replaceAll(' ', '_')
|
||||||
|
.split('.')
|
||||||
|
.first;
|
||||||
await CRFileSaver.saveFileWithDialog(
|
await CRFileSaver.saveFileWithDialog(
|
||||||
SaveFileDialogParams(
|
SaveFileDialogParams(
|
||||||
sourceFilePath: outFile.path,
|
sourceFilePath: outFile.path,
|
||||||
|
@ -83,7 +87,8 @@ class SettingsViewModel extends BaseViewModel {
|
||||||
|
|
||||||
Future<void> importPatches() async {
|
Future<void> importPatches() async {
|
||||||
try {
|
try {
|
||||||
final FilePickerResult? result = await FilePicker.platform.pickFiles(
|
final FilePickerResult? result =
|
||||||
|
await FilePicker.platform.pickFiles(
|
||||||
type: FileType.custom,
|
type: FileType.custom,
|
||||||
allowedExtensions: ['json'],
|
allowedExtensions: ['json'],
|
||||||
);
|
);
|
||||||
|
@ -151,7 +156,7 @@ class SettingsViewModel extends BaseViewModel {
|
||||||
|
|
||||||
Future<int> getSdkVersion() async {
|
Future<int> getSdkVersion() async {
|
||||||
final AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo;
|
final AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo;
|
||||||
return info.version.sdkInt ?? -1;
|
return info.version.sdkInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deleteLogs() async {
|
Future<void> deleteLogs() async {
|
||||||
|
|
|
@ -16,12 +16,12 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
||||||
expand: false,
|
expand: false,
|
||||||
snap: true,
|
snap: true,
|
||||||
snapSizes: const [0.5],
|
snapSizes: const [0.5],
|
||||||
builder: (context, scrollController) => SingleChildScrollView(
|
builder: (_, scrollController) => SingleChildScrollView(
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: FutureBuilder<Map<String, dynamic>?>(
|
child: FutureBuilder<Map<String, dynamic>?>(
|
||||||
future: model.getLatestManagerRelease(),
|
future: model.getLatestManagerRelease(),
|
||||||
builder: (context, snapshot) {
|
builder: (_, snapshot) {
|
||||||
if (!snapshot.hasData) {
|
if (!snapshot.hasData) {
|
||||||
return const SizedBox(
|
return const SizedBox(
|
||||||
height: 300,
|
height: 300,
|
||||||
|
@ -45,7 +45,8 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
I18nText(
|
I18nText(
|
||||||
'homeView.updateDialogTitle',
|
'homeView.updateDialogTitle',
|
||||||
|
@ -62,12 +63,14 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(
|
||||||
Icons.new_releases_outlined,
|
Icons.new_releases_outlined,
|
||||||
color:
|
color: Theme.of(context)
|
||||||
Theme.of(context).colorScheme.secondary,
|
.colorScheme
|
||||||
|
.secondary,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8.0),
|
const SizedBox(width: 8.0),
|
||||||
Text(
|
Text(
|
||||||
snapshot.data!['tag_name'] ?? 'Unknown',
|
snapshot.data!['tag_name'] ??
|
||||||
|
'Unknown',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
|
@ -93,7 +96,8 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 24.0, bottom: 12.0),
|
padding:
|
||||||
|
const EdgeInsets.only(left: 24.0, bottom: 12.0),
|
||||||
child: I18nText(
|
child: I18nText(
|
||||||
'homeView.updateChangelogTitle',
|
'homeView.updateChangelogTitle',
|
||||||
child: Text(
|
child: Text(
|
||||||
|
@ -109,9 +113,12 @@ class UpdateConfirmationDialog extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 24.0),
|
margin:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 24.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.secondaryContainer,
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.secondaryContainer,
|
||||||
borderRadius: BorderRadius.circular(12.0),
|
borderRadius: BorderRadius.circular(12.0),
|
||||||
),
|
),
|
||||||
child: Markdown(
|
child: Markdown(
|
||||||
|
|
56
pubspec.yaml
56
pubspec.yaml
|
@ -10,79 +10,79 @@ environment:
|
||||||
sdk: ">=2.17.5 <3.0.0"
|
sdk: ">=2.17.5 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
animations: ^2.0.4
|
animations: ^2.0.7
|
||||||
app_installer: ^1.1.0
|
app_installer: ^1.1.0
|
||||||
collection: ^1.16.0
|
collection: ^1.17.0
|
||||||
cross_connectivity: ^3.0.5
|
cross_connectivity: ^3.0.5
|
||||||
cr_file_saver: ^0.0.2
|
cr_file_saver: ^0.0.2+1
|
||||||
device_apps:
|
device_apps:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/ponces/flutter_plugin_device_apps
|
url: https://github.com/ponces/flutter_plugin_device_apps
|
||||||
ref: revanced-manager
|
ref: revanced-manager
|
||||||
device_info_plus: ^4.1.2
|
device_info_plus: ^8.1.0
|
||||||
|
dynamic_color: ^1.6.3
|
||||||
dio: ^5.0.0
|
dio: ^5.0.0
|
||||||
dynamic_color: ^1.5.4
|
|
||||||
dynamic_themes: ^1.1.0
|
dynamic_themes: ^1.1.0
|
||||||
expandable: ^5.0.1
|
expandable: ^5.0.1
|
||||||
file_picker:
|
file_picker:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/alexmercerind/flutter_file_picker
|
url: https://github.com/alexmercerind/flutter_file_picker
|
||||||
ref: master
|
ref: master
|
||||||
flex_color_scheme: ^6.0.0
|
flex_color_scheme: ^7.0.1
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_background: ^1.1.0
|
flutter_background: ^1.2.0
|
||||||
flutter_cache_manager: ^3.3.0
|
flutter_cache_manager: ^3.3.0
|
||||||
flutter_i18n: ^0.32.4
|
flutter_i18n: ^0.32.4
|
||||||
flutter_local_notifications: ^9.8.0+1
|
flutter_local_notifications: ^13.0.0
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_svg: ^1.1.1+1
|
flutter_svg: ^2.0.4
|
||||||
fluttertoast: ^8.0.9
|
fluttertoast: ^8.2.1
|
||||||
font_awesome_flutter: ^10.1.0
|
font_awesome_flutter: ^10.4.0
|
||||||
get_it: ^7.2.0
|
get_it: ^7.2.0
|
||||||
google_fonts: ^3.0.1
|
google_fonts: ^4.0.3
|
||||||
http: ^0.13.4
|
http: ^0.13.5
|
||||||
injectable: ^1.5.3
|
injectable: ^2.1.1
|
||||||
intl: ^0.17.0
|
intl: ^0.17.0
|
||||||
json_annotation: ^4.6.0
|
json_annotation: ^4.8.0
|
||||||
logcat:
|
logcat:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/SuaMusica/logcat
|
url: https://github.com/SuaMusica/logcat
|
||||||
ref: feature/nullSafe
|
ref: feature/nullSafe
|
||||||
|
package_info_plus: ^3.0.3
|
||||||
|
path_provider: ^2.0.14
|
||||||
|
permission_handler: ^10.2.0
|
||||||
native_dio_adapter: ^0.1.0
|
native_dio_adapter: ^0.1.0
|
||||||
package_info_plus: ^1.4.3+1
|
|
||||||
path_provider: ^2.0.11
|
|
||||||
permission_handler: ^10.0.0
|
|
||||||
pull_to_refresh: ^2.0.0
|
pull_to_refresh: ^2.0.0
|
||||||
root:
|
root:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/gokul1630/root
|
url: https://github.com/gokul1630/root
|
||||||
ref: main
|
ref: main
|
||||||
share_extend: ^2.0.0
|
share_extend: ^2.0.0
|
||||||
shared_preferences: ^2.0.15
|
shared_preferences: ^2.1.0
|
||||||
skeletons: ^0.0.3
|
skeletons: ^0.0.3
|
||||||
stacked: ^3.2.0
|
stacked: ^3.2.0
|
||||||
stacked_generator: ^1.0.0
|
stacked_generator: ^1.1.0
|
||||||
stacked_services: ^1.0.0
|
stacked_services: ^1.0.0
|
||||||
stacked_themes: ^0.3.9
|
stacked_themes: ^0.3.10
|
||||||
timeago: ^3.2.2
|
timeago: ^3.3.0
|
||||||
timezone: ^0.8.0
|
timezone: ^0.9.0
|
||||||
url_launcher: ^6.1.5
|
url_launcher: ^6.1.10
|
||||||
wakelock: ^0.6.2
|
wakelock: ^0.6.2
|
||||||
flutter_dotenv: ^5.0.2
|
flutter_dotenv: ^5.0.2
|
||||||
|
flutter_markdown: ^0.6.14
|
||||||
pub_release: ^8.0.3
|
pub_release: ^8.0.3
|
||||||
flutter_markdown: ^0.6.13
|
|
||||||
dio_cache_interceptor: ^3.4.0
|
dio_cache_interceptor: ^3.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
json_serializable: ^6.3.1
|
json_serializable: ^6.6.1
|
||||||
build_runner: any
|
build_runner: any
|
||||||
flutter_launcher_icons: ^0.10.0
|
flutter_launcher_icons: ^0.13.0
|
||||||
flutter_lints: ^2.0.1
|
flutter_lints: ^2.0.1
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
injectable_generator: ^1.5.4
|
injectable_generator: ^2.1.5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue