Compare commits

..

24 Commits

Author SHA1 Message Date
0011222371 chore:fix incorrect version 2023-07-23 14:25:11 +05:30
29db947e25 fix: using non const value in a const variable 2023-07-23 14:04:35 +05:30
fd43ac7581 chore: merge dev branch to main branch (#1032) 2023-07-23 13:53:25 +05:30
e49c19b3cd feat: support older version of android for reddit client patches 2023-07-23 13:51:36 +05:30
Pun
06f0e59967 chore(deps): update libsu to v5.2.0 2023-07-22 13:21:13 +07:00
Pun
c5fc5ee93b build: speed up compilation time
faster build faster build faster build faster build faster build
2023-07-19 18:30:50 +07:00
159c85bd1f fix: close previous dialog when user reset the API URL (#1025) 2023-07-16 21:04:35 +07:00
Pun
2460acf0f4 ci(analyze): don't run when PR is in draft 2023-07-16 17:10:29 +07:00
Pun
6495687841 docs: correct misspelling (EN_US)
This correct spelling to English American, because by default, we use English US.
2023-07-16 16:31:08 +07:00
Pun
d229ccb36c ci(analyze): clarify job name that the job do static analysis & format checking 2023-07-16 16:21:16 +07:00
Pun
4d6a57ddcf ci(analyze): restore run when commit push to dev branch 2023-07-16 16:17:15 +07:00
d161d55aaf fix: patched applications not showing at launch (#1031) 2023-07-16 12:46:01 +07:00
Pun
768ad0c9bc chore: merge dev branch to main branch (#1011)
ReVanced Manager v1.4.1
2023-07-15 20:33:30 +07:00
29323d4e20 build: update app version to v1.4.1 2023-07-15 12:55:59 +07:00
630b22e193 refactor: applies changes from formatter & linter 2023-07-15 12:41:03 +07:00
79116f9e67 fix(patched-applications): non-patched app showing on Installed section (#1022) 2023-07-15 08:11:51 +07:00
eb58475259 fix: showing Installed when it's actually not (#1021) 2023-07-15 08:10:36 +07:00
a879ac30fb fix: prevent unsupported operation exception (#1018) 2023-07-14 17:55:04 +07:00
c5b0621323 fix(navigation-view): back button closing the app from any page (#1019) 2023-07-13 19:25:48 +05:45
0462815014 fix(app-selector): fix text overflow on small screen (#1017) 2023-07-13 00:16:53 +05:45
e64318c947 fix(app-selector): fix text overflow on small screen 2023-07-13 00:14:47 +05:45
b784482788 chore: update libsu to 5.1.0
This should fixes some issues with root
2023-07-11 19:28:59 +07:00
2834e8b348 fix: patchable apps not showing if none of them is installed (#1009) 2023-07-11 17:11:45 +07:00
b23dfd4289 chore: merge dev branch to main branch (#1010) 2023-07-11 01:24:54 +05:30
15 changed files with 198 additions and 127 deletions

View File

@ -1,14 +1,25 @@
name: Analyze Code
on:
push:
branches: [ "dev" ]
paths:
- "**.dart"
- ".github/workflows/analyze.yml"
pull_request:
branches: [ "main", "dev" ]
types:
- opened
- reopened
- synchronize
- ready_for_review
paths:
- "**.dart"
- ".github/workflows/analyze.yml"
jobs:
build:
name: "Static analysis & format check"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

View File

@ -2,23 +2,29 @@
package="app.revanced.manager.flutter">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application
android:label="ReVanced Manager"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:largeHeap="true"
android:requestLegacyExternalStorage="true"
android:extractNativeLibs="true"
android:enableOnBackInvokedCallback="true">
<activity

View File

@ -1,3 +1,6 @@
org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx1536M -XX:+UseParallelGC
org.gradle.parallel=true
org.gradle.daemon=true
org.gradle.caching=true
android.useAndroidX=true
android.enableJetifier=true

View File

@ -1 +1 @@
Patch your favourite apps, right on your device.
Patch your favorite apps, right on your device.

View File

@ -1,12 +1,12 @@
import 'dart:io';
import 'package:app_installer/app_installer.dart';
import 'package:collection/collection.dart';
import 'package:cr_file_saver/file_saver.dart';
import 'package:device_apps/device_apps.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:injectable/injectable.dart';
import 'package:install_plugin/install_plugin.dart';
import 'package:path_provider/path_provider.dart';
import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/models/patch.dart';
@ -232,10 +232,8 @@ class PatcherAPI {
);
}
} else {
await AppInstaller.installApk(_outFile!.path);
return await DeviceApps.isAppInstalled(
patchedApp.packageName,
);
final install = await InstallPlugin.installApk(_outFile!.path);
return install['isSuccess'];
}
} on Exception catch (e) {
if (kDebugMode) {

View File

@ -73,7 +73,7 @@ class RootAPI {
}
Future<List<String>> getInstalledApps() async {
final List<String> apps = List.empty();
final List<String> apps = List.empty(growable: true);
try {
String? res = await Root.exec(
cmd: 'ls "$_revancedDirPath"',

View File

@ -88,7 +88,7 @@ class _AppSelectorViewState extends State<AppSelectorView> {
),
),
)
: model.apps.isEmpty
: model.allApps.isEmpty
? const AppSkeletonLoader()
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0)

View File

@ -45,9 +45,7 @@ class AppSelectorViewModel extends BaseViewModel {
.length
.compareTo(_patcherAPI.getFilteredPatches(a.packageName).length),
);
noApps = apps.isEmpty;
getAllApps();
notifyListeners();
}
@ -57,7 +55,7 @@ class AppSelectorViewModel extends BaseViewModel {
.toSet()
.where((name) => !apps.any((app) => app.packageName == name))
.toList();
noApps = allApps.isEmpty;
return allApps;
}

View File

@ -1,13 +1,13 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:async';
import 'dart:io';
import 'package:app_installer/app_installer.dart';
import 'package:cross_connectivity/cross_connectivity.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:injectable/injectable.dart';
import 'package:install_plugin/install_plugin.dart';
import 'package:path_provider/path_provider.dart';
import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/app/app.router.dart';
@ -51,7 +51,7 @@ class HomeViewModel extends BaseViewModel {
_toast.showBottom('homeView.installingMessage');
final File? managerApk = await _managerAPI.downloadManager();
if (managerApk != null) {
await AppInstaller.installApk(managerApk.path);
await InstallPlugin.installApk(managerApk.path);
} else {
_toast.showBottom('homeView.errorDownloadMessage');
}
@ -72,7 +72,7 @@ class HomeViewModel extends BaseViewModel {
_toast.showBottom('homeView.installingMessage');
final File? managerApk = await _managerAPI.downloadManager();
if (managerApk != null) {
await AppInstaller.installApk(managerApk.path);
await InstallPlugin.installApk(managerApk.path);
} else {
_toast.showBottom('homeView.errorDownloadMessage');
}
@ -272,7 +272,7 @@ class HomeViewModel extends BaseViewModel {
child: CustomMaterialButton(
label: I18nText('updateButton'),
onPressed: () async {
await AppInstaller.installApk(
await InstallPlugin.installApk(
downloadedApk!.path,
);
},
@ -318,7 +318,7 @@ class HomeViewModel extends BaseViewModel {
// UILocalNotificationDateInterpretation.absoluteTime,
// );
_toast.showBottom('homeView.installingMessage');
await AppInstaller.installApk(managerApk.path);
await InstallPlugin.installApk(managerApk.path);
} else {
_toast.showBottom('homeView.errorDownloadMessage');
}

View File

@ -13,58 +13,68 @@ class NavigationView extends StatelessWidget {
return ViewModelBuilder<NavigationViewModel>.reactive(
onViewModelReady: (model) => model.initialize(context),
viewModelBuilder: () => locator<NavigationViewModel>(),
builder: (context, model, child) => Scaffold(
body: PageTransitionSwitcher(
duration: const Duration(milliseconds: 400),
transitionBuilder: (
Widget child,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return FadeThroughTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
fillColor: Theme.of(context).colorScheme.surface,
child: child,
);
},
child: model.getViewForIndex(model.currentIndex),
),
bottomNavigationBar: NavigationBar(
onDestinationSelected: model.setIndex,
selectedIndex: model.currentIndex,
destinations: <Widget>[
NavigationDestination(
icon: model.isIndexSelected(0)
? const Icon(Icons.dashboard)
: const Icon(Icons.dashboard_outlined),
label: FlutterI18n.translate(
context,
'navigationView.dashboardTab',
builder: (context, model, child) => WillPopScope(
onWillPop: () async {
if (model.currentIndex == 0) {
return true;
} else {
model.setIndex(0);
return false;
}
},
child: Scaffold(
body: PageTransitionSwitcher(
duration: const Duration(milliseconds: 400),
transitionBuilder: (
Widget child,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return FadeThroughTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
fillColor: Theme.of(context).colorScheme.surface,
child: child,
);
},
child: model.getViewForIndex(model.currentIndex),
),
bottomNavigationBar: NavigationBar(
onDestinationSelected: model.setIndex,
selectedIndex: model.currentIndex,
destinations: <Widget>[
NavigationDestination(
icon: model.isIndexSelected(0)
? const Icon(Icons.dashboard)
: const Icon(Icons.dashboard_outlined),
label: FlutterI18n.translate(
context,
'navigationView.dashboardTab',
),
tooltip: '',
),
tooltip: '',
),
NavigationDestination(
icon: model.isIndexSelected(1)
? const Icon(Icons.build)
: const Icon(Icons.build_outlined),
label: FlutterI18n.translate(
context,
'navigationView.patcherTab',
NavigationDestination(
icon: model.isIndexSelected(1)
? const Icon(Icons.build)
: const Icon(Icons.build_outlined),
label: FlutterI18n.translate(
context,
'navigationView.patcherTab',
),
tooltip: '',
),
tooltip: '',
),
NavigationDestination(
icon: model.isIndexSelected(2)
? const Icon(Icons.settings)
: const Icon(Icons.settings_outlined),
label: FlutterI18n.translate(
context,
'navigationView.settingsTab',
NavigationDestination(
icon: model.isIndexSelected(2)
? const Icon(Icons.settings)
: const Icon(Icons.settings_outlined),
label: FlutterI18n.translate(
context,
'navigationView.settingsTab',
),
tooltip: '',
),
tooltip: '',
),
],
],
),
),
),
);

View File

@ -93,7 +93,9 @@ class SManageApiUrl extends BaseViewModel {
onPressed: () {
_managerAPI.setApiUrl('');
_toast.showBottom('settingsView.restartAppForChanges');
Navigator.of(context).pop();
Navigator.of(context)
..pop()
..pop();
},
)
],

View File

@ -84,12 +84,16 @@ class _InstalledAppItemState extends State<InstalledAppItem> {
},
),
const SizedBox(width: 4),
Text(
widget.patchesCount == 1
? '${widget.patchesCount} patch'
: '${widget.patchesCount} patches',
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
Flexible(
child: Text(
widget.patchesCount == 1
? '${widget.patchesCount} patch'
: '${widget.patchesCount} patches',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
),
),
),
],

View File

@ -78,12 +78,16 @@ class _NotInstalledAppItem extends State<NotInstalledAppItem> {
},
),
const SizedBox(width: 4),
Text(
widget.patchesCount == 1
? '${widget.patchesCount} patch'
: '${widget.patchesCount} patches',
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
Flexible(
child: Text(
widget.patchesCount == 1
? '${widget.patchesCount} patch'
: '${widget.patchesCount} patches',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
),
),
),
],

View File

@ -1,61 +1,96 @@
import 'package:device_apps/device_apps.dart';
import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/models/patched_application.dart';
import 'package:revanced_manager/services/manager_api.dart';
import 'package:revanced_manager/ui/views/home/home_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/shared/application_item.dart';
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
//ignore: must_be_immutable
class InstalledAppsCard extends StatelessWidget {
InstalledAppsCard({Key? key}) : super(key: key);
final List<PatchedApplication> apps =
locator<HomeViewModel>().patchedInstalledApps;
List<PatchedApplication> apps = locator<HomeViewModel>().patchedInstalledApps;
final ManagerAPI _managerAPI = locator<ManagerAPI>();
List<PatchedApplication> patchedApps = [];
Future _getApps() async {
if (apps.isNotEmpty) {
patchedApps = [...apps];
for (final element in apps) {
await DeviceApps.getApp(element.packageName).then((value) {
if (element.version != value?.versionName) {
patchedApps.remove(element);
}
});
}
if (apps.length != patchedApps.length) {
await _managerAPI.setPatchedApps(patchedApps);
apps.clear();
apps = [...patchedApps];
}
}
}
@override
Widget build(BuildContext context) {
return apps.isEmpty
? CustomCard(
child: Center(
child: Column(
children: <Widget>[
Icon(
size: 40,
Icons.file_download_off,
color: Theme.of(context).colorScheme.secondary,
),
const SizedBox(height: 16),
I18nText(
'homeView.noInstallations',
child: Text(
'',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).colorScheme.secondary,
return FutureBuilder(
future: _getApps(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return apps.isEmpty
? CustomCard(
child: Center(
child: Column(
children: <Widget>[
Icon(
size: 40,
Icons.file_download_off,
color: Theme.of(context).colorScheme.secondary,
),
const SizedBox(height: 16),
I18nText(
'homeView.noInstallations',
child: Text(
'',
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(
color:
Theme.of(context).colorScheme.secondary,
),
),
)
],
),
)
],
),
),
)
: ListView(
shrinkWrap: true,
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
children: apps
.map(
(app) => ApplicationItem(
icon: app.icon,
name: app.name,
patchDate: app.patchDate,
changelog: app.changelog,
isUpdatableApp: false,
onPressed: () =>
locator<HomeViewModel>().navigateToAppInfo(app),
),
)
.toList(),
);
: ListView(
shrinkWrap: true,
padding: EdgeInsets.zero,
physics: const NeverScrollableScrollPhysics(),
children: apps
.map(
(app) => ApplicationItem(
icon: app.icon,
name: app.name,
patchDate: app.patchDate,
changelog: app.changelog,
isUpdatableApp: false,
onPressed: () =>
locator<HomeViewModel>().navigateToAppInfo(app),
),
)
.toList(),
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
);
}
}

View File

@ -4,14 +4,13 @@ homepage: https://github.com/revanced/revanced-manager
publish_to: 'none'
version: 1.4.0+100400000
version: 1.4.3+100400003
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
animations: ^2.0.7
app_installer: ^1.1.0
collection: ^1.17.0
cross_connectivity: ^3.0.5
cr_file_saver:
@ -59,8 +58,8 @@ dependencies:
pull_to_refresh: ^2.0.0
root:
git:
url: https://github.com/gokul1630/root
ref: main
url: https://github.com/EvadeMaster/root
ref: 82803aa40f63cddff81c3e4d27ce8ce3e7c83f60
share_extend: ^2.0.0
shared_preferences: ^2.1.0
skeletons: ^0.0.3
@ -75,6 +74,7 @@ dependencies:
flutter_dotenv: ^5.0.2
flutter_markdown: ^0.6.14
dio_cache_interceptor: ^3.4.0
install_plugin: ^2.1.0
dev_dependencies:
json_serializable: ^6.6.1