diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index 1a718b4a..77774bda 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -6,6 +6,16 @@ import 'package:timeago/timeago.dart'; class GithubAPI { final GitHub _github = GitHub(); + final Map repoAppPath = { + 'com.google.android.youtube': 'youtube', + 'com.google.android.apps.youtube.music': 'music', + 'com.twitter.android': 'twitter', + 'com.reddit.frontpage': 'reddit', + 'com.zhiliaoapp.musically': 'tiktok', + 'de.dwd.warnapp': 'warnwetter', + 'com.garzotto.pflotsh.ecmwf_a': 'ecmwf', + }; + Future latestReleaseVersion(String org, String repoName) async { try { var latestRelease = await _github.repositories.getLatestRelease( @@ -61,9 +71,19 @@ class GithubAPI { )).toList(); } - Future> getCommits(String org, String repoName) async { - return await (_github.repositories.listCommits( - RepositorySlug(org, repoName), + Future> getCommits( + String packageName, + String org, + String repoName, + ) async { + String path = + 'src/main/kotlin/app/revanced/patches/${repoAppPath[packageName]}'; + return await (PaginationHelper(_github) + .objects, RepositoryCommit>( + 'GET', + '/repos/$org/$repoName/commits', + (i) => RepositoryCommit.fromJson(i), + params: {'path': path}, )).toList(); } } diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index ad6dc7e1..3b7e0ef2 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -15,11 +15,9 @@ class ManagerAPI { final GithubAPI _githubAPI = GithubAPI(); final RootAPI _rootAPI = RootAPI(); late SharedPreferences _prefs; - late List _commits = []; Future initialize() async { _prefs = await SharedPreferences.getInstance(); - _commits = (await _githubAPI.getCommits(ghOrg, patchesRepo)).toList(); } Future downloadPatches(String extension) async { @@ -62,16 +60,16 @@ class ManagerAPI { .toList(); } - void setPatchedApps(List patchedApps) { - _prefs.setStringList('patchedApps', + Future setPatchedApps(List patchedApps) async { + await _prefs.setStringList('patchedApps', patchedApps.map((a) => json.encode(a.toJson())).toList()); } - void savePatchedApp(PatchedApplication app) { + Future savePatchedApp(PatchedApplication app) async { List patchedApps = getPatchedApps(); patchedApps.removeWhere((a) => a.packageName == app.packageName); patchedApps.add(app); - setPatchedApps(patchedApps); + await setPatchedApps(patchedApps); } Future reAssessSavedApps() async { @@ -83,20 +81,12 @@ class ManagerAPI { if (isRemove) { toRemove.add(app); } else { - List newChangelog = getAppChangelog( - app.packageName, - app.patchDate, - ); - if (newChangelog.isNotEmpty) { - app.changelog = newChangelog; - app.hasUpdates = true; - } else { - app.hasUpdates = false; - } + app.hasUpdates = await hasAppUpdates(app.packageName, app.patchDate); + app.changelog = await getAppChangelog(app.packageName, app.patchDate); } } patchedApps.removeWhere((a) => toRemove.contains(a)); - setPatchedApps(patchedApps); + await setPatchedApps(patchedApps); } Future isAppUninstalled(PatchedApplication app, bool isRoot) async { @@ -108,24 +98,38 @@ class ManagerAPI { return !existsRoot && !existsNonRoot; } - List getAppChangelog(String packageName, DateTime patchedDate) { - List newCommits = _commits + Future hasAppUpdates(String packageName, DateTime patchDate) async { + List commits = + await _githubAPI.getCommits(packageName, ghOrg, patchesRepo); + return commits.any((c) => + c.commit != null && + c.commit!.author != null && + c.commit!.author!.date != null && + c.commit!.author!.date!.isAfter(patchDate)); + } + + Future> getAppChangelog( + String packageName, + DateTime patchDate, + ) async { + List commits = + await _githubAPI.getCommits(packageName, ghOrg, patchesRepo); + List newCommits = commits .where((c) => c.commit != null && - c.commit!.message != null && c.commit!.author != null && c.commit!.author!.date != null && - c.commit!.author!.date!.isAfter(patchedDate)) + c.commit!.author!.date!.isAfter(patchDate) && + c.commit!.message != null) .map((c) => c.commit!.message!) .toList(); - if (newCommits.isNotEmpty) { - int firstChore = newCommits.indexWhere((c) => c.startsWith('chore')); - int secondChore = - newCommits.indexWhere((c) => c.startsWith('chore'), firstChore + 1); - if (firstChore >= 0 && secondChore > firstChore) { - return newCommits.sublist(firstChore + 1, secondChore); - } + if (newCommits.isEmpty) { + newCommits = commits + .where((c) => c.commit != null && c.commit!.message != null) + .take(3) + .map((c) => c.commit!.message!) + .toList(); } - return List.empty(); + return newCommits; } } diff --git a/lib/ui/views/home/home_view.dart b/lib/ui/views/home/home_view.dart index e5f4df78..dfc36df6 100644 --- a/lib/ui/views/home/home_view.dart +++ b/lib/ui/views/home/home_view.dart @@ -17,7 +17,6 @@ class HomeView extends StatelessWidget { Widget build(BuildContext context) { return ViewModelBuilder.reactive( disposeViewModel: false, - fireOnModelReadyOnce: true, onModelReady: (model) => model.initialize(), viewModelBuilder: () => locator(), builder: (context, model, child) => Scaffold( @@ -111,8 +110,8 @@ class HomeView extends StatelessWidget { ), const SizedBox(height: 14), model.showUpdatableApps - ? const AvailableUpdatesCard() - : const InstalledAppsCard() + ? AvailableUpdatesCard() + : InstalledAppsCard(), ], ), ), diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 5d4be131..59cca86f 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -26,14 +26,14 @@ class HomeViewModel extends BaseViewModel { List patchedUpdatableApps = []; Future initialize() async { - await _getPatchedApps(); await flutterLocalNotificationsPlugin.initialize( const InitializationSettings( android: AndroidInitializationSettings('ic_notification'), ), onSelectNotification: (p) => DeviceApps.openApp('app.revanced.manager'), ); - _managerAPI.reAssessSavedApps().then((_) => notifyListeners()); + _getPatchedApps(); + _managerAPI.reAssessSavedApps().then((_) => _getPatchedApps()); } void toggleUpdatableApps(bool value) { @@ -49,11 +49,8 @@ class HomeViewModel extends BaseViewModel { locator().setIndex(1); } - Future _getPatchedApps() async { - patchedInstalledApps = _managerAPI - .getPatchedApps() - .where((app) => app.hasUpdates == false) - .toList(); + void _getPatchedApps() { + patchedInstalledApps = _managerAPI.getPatchedApps().toList(); patchedUpdatableApps = _managerAPI .getPatchedApps() .where((app) => app.hasUpdates == true) diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 5752d35b..81ea8068 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -136,7 +136,7 @@ class InstallerViewModel extends BaseViewModel { update(1.0, 'Installed!', 'Installed!'); _app!.patchDate = DateTime.now(); _app!.appliedPatches = _patches.map((p) => p.name).toList(); - _managerAPI.savePatchedApp(_app!); + await _managerAPI.savePatchedApp(_app!); } else { update(1.0, 'Aborting...', 'An error occurred! Aborting'); } diff --git a/lib/ui/views/root_checker/root_checker_viewmodel.dart b/lib/ui/views/root_checker/root_checker_viewmodel.dart index e9fe5083..d2c36c86 100644 --- a/lib/ui/views/root_checker/root_checker_viewmodel.dart +++ b/lib/ui/views/root_checker/root_checker_viewmodel.dart @@ -20,7 +20,7 @@ class RootCheckerViewModel extends BaseViewModel { Future navigateToHome() async { final prefs = await SharedPreferences.getInstance(); - prefs.setBool('isRooted', isRooted); + await prefs.setBool('isRooted', isRooted); _navigationService.navigateTo(Routes.navigation); notifyListeners(); } diff --git a/lib/ui/widgets/homeView/available_updates_card.dart b/lib/ui/widgets/homeView/available_updates_card.dart index 381eb540..cc7642e6 100644 --- a/lib/ui/widgets/homeView/available_updates_card.dart +++ b/lib/ui/widgets/homeView/available_updates_card.dart @@ -1,21 +1,24 @@ import 'package:flutter/material.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/application_item.dart'; class AvailableUpdatesCard extends StatelessWidget { - const AvailableUpdatesCard({ + AvailableUpdatesCard({ Key? key, }) : super(key: key); + final List apps = + locator().patchedUpdatableApps; + @override Widget build(BuildContext context) { return ListView( shrinkWrap: true, padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), - children: locator() - .patchedUpdatableApps + children: apps .map((app) => ApplicationItem( icon: app.icon, name: app.name, diff --git a/lib/ui/widgets/homeView/installed_apps_card.dart b/lib/ui/widgets/homeView/installed_apps_card.dart index 708a7382..8c1716a6 100644 --- a/lib/ui/widgets/homeView/installed_apps_card.dart +++ b/lib/ui/widgets/homeView/installed_apps_card.dart @@ -1,22 +1,25 @@ import 'package:device_apps/device_apps.dart'; import 'package:flutter/material.dart'; import 'package:revanced_manager/app/app.locator.dart'; +import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/application_item.dart'; class InstalledAppsCard extends StatelessWidget { - const InstalledAppsCard({ + InstalledAppsCard({ Key? key, }) : super(key: key); + final List apps = + locator().patchedInstalledApps; + @override Widget build(BuildContext context) { return ListView( shrinkWrap: true, padding: EdgeInsets.zero, physics: const NeverScrollableScrollPhysics(), - children: locator() - .patchedInstalledApps + children: apps .map((app) => ApplicationItem( icon: app.icon, name: app.name, diff --git a/lib/ui/widgets/shared/application_item.dart b/lib/ui/widgets/shared/application_item.dart index 5af52da6..d7959b88 100644 --- a/lib/ui/widgets/shared/application_item.dart +++ b/lib/ui/widgets/shared/application_item.dart @@ -105,7 +105,7 @@ class ApplicationItem extends StatelessWidget { ), const SizedBox(height: 4), Text( - ' - ${changelog.join('\n- ')}', + '\u2022 ${changelog.join('\n\u2022 ')}', style: kRobotoTextStyle, ), ],