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:
Aman Sikarwar 2023-04-18 19:45:29 +05:30 committed by GitHub
parent 37b583f560
commit 197770b68b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 199 additions and 92 deletions

View file

@ -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'
} }

View file

@ -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 {

View file

@ -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()));
} }

View file

@ -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 '';

View file

@ -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,

View file

@ -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,

View file

@ -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,
), ),

View file

@ -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 {

View file

@ -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(

View file

@ -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