mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat: get changelog from app's specific github path (ugly)
This commit is contained in:
parent
03b45e0db0
commit
5c657fbed5
@ -6,6 +6,16 @@ import 'package:timeago/timeago.dart';
|
|||||||
class GithubAPI {
|
class GithubAPI {
|
||||||
final GitHub _github = GitHub();
|
final GitHub _github = GitHub();
|
||||||
|
|
||||||
|
final Map<String, String> 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<String?> latestReleaseVersion(String org, String repoName) async {
|
Future<String?> latestReleaseVersion(String org, String repoName) async {
|
||||||
try {
|
try {
|
||||||
var latestRelease = await _github.repositories.getLatestRelease(
|
var latestRelease = await _github.repositories.getLatestRelease(
|
||||||
@ -61,9 +71,19 @@ class GithubAPI {
|
|||||||
)).toList();
|
)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<RepositoryCommit>> getCommits(String org, String repoName) async {
|
Future<List<RepositoryCommit>> getCommits(
|
||||||
return await (_github.repositories.listCommits(
|
String packageName,
|
||||||
RepositorySlug(org, repoName),
|
String org,
|
||||||
|
String repoName,
|
||||||
|
) async {
|
||||||
|
String path =
|
||||||
|
'src/main/kotlin/app/revanced/patches/${repoAppPath[packageName]}';
|
||||||
|
return await (PaginationHelper(_github)
|
||||||
|
.objects<Map<String, dynamic>, RepositoryCommit>(
|
||||||
|
'GET',
|
||||||
|
'/repos/$org/$repoName/commits',
|
||||||
|
(i) => RepositoryCommit.fromJson(i),
|
||||||
|
params: <String, dynamic>{'path': path},
|
||||||
)).toList();
|
)).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,9 @@ class ManagerAPI {
|
|||||||
final GithubAPI _githubAPI = GithubAPI();
|
final GithubAPI _githubAPI = GithubAPI();
|
||||||
final RootAPI _rootAPI = RootAPI();
|
final RootAPI _rootAPI = RootAPI();
|
||||||
late SharedPreferences _prefs;
|
late SharedPreferences _prefs;
|
||||||
late List<RepositoryCommit> _commits = [];
|
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
_prefs = await SharedPreferences.getInstance();
|
_prefs = await SharedPreferences.getInstance();
|
||||||
_commits = (await _githubAPI.getCommits(ghOrg, patchesRepo)).toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<File?> downloadPatches(String extension) async {
|
Future<File?> downloadPatches(String extension) async {
|
||||||
@ -62,16 +60,16 @@ class ManagerAPI {
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPatchedApps(List<PatchedApplication> patchedApps) {
|
Future<void> setPatchedApps(List<PatchedApplication> patchedApps) async {
|
||||||
_prefs.setStringList('patchedApps',
|
await _prefs.setStringList('patchedApps',
|
||||||
patchedApps.map((a) => json.encode(a.toJson())).toList());
|
patchedApps.map((a) => json.encode(a.toJson())).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void savePatchedApp(PatchedApplication app) {
|
Future<void> savePatchedApp(PatchedApplication app) async {
|
||||||
List<PatchedApplication> patchedApps = getPatchedApps();
|
List<PatchedApplication> patchedApps = getPatchedApps();
|
||||||
patchedApps.removeWhere((a) => a.packageName == app.packageName);
|
patchedApps.removeWhere((a) => a.packageName == app.packageName);
|
||||||
patchedApps.add(app);
|
patchedApps.add(app);
|
||||||
setPatchedApps(patchedApps);
|
await setPatchedApps(patchedApps);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> reAssessSavedApps() async {
|
Future<void> reAssessSavedApps() async {
|
||||||
@ -83,20 +81,12 @@ class ManagerAPI {
|
|||||||
if (isRemove) {
|
if (isRemove) {
|
||||||
toRemove.add(app);
|
toRemove.add(app);
|
||||||
} else {
|
} else {
|
||||||
List<String> newChangelog = getAppChangelog(
|
app.hasUpdates = await hasAppUpdates(app.packageName, app.patchDate);
|
||||||
app.packageName,
|
app.changelog = await getAppChangelog(app.packageName, app.patchDate);
|
||||||
app.patchDate,
|
|
||||||
);
|
|
||||||
if (newChangelog.isNotEmpty) {
|
|
||||||
app.changelog = newChangelog;
|
|
||||||
app.hasUpdates = true;
|
|
||||||
} else {
|
|
||||||
app.hasUpdates = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
patchedApps.removeWhere((a) => toRemove.contains(a));
|
patchedApps.removeWhere((a) => toRemove.contains(a));
|
||||||
setPatchedApps(patchedApps);
|
await setPatchedApps(patchedApps);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> isAppUninstalled(PatchedApplication app, bool isRoot) async {
|
Future<bool> isAppUninstalled(PatchedApplication app, bool isRoot) async {
|
||||||
@ -108,24 +98,38 @@ class ManagerAPI {
|
|||||||
return !existsRoot && !existsNonRoot;
|
return !existsRoot && !existsNonRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> getAppChangelog(String packageName, DateTime patchedDate) {
|
Future<bool> hasAppUpdates(String packageName, DateTime patchDate) async {
|
||||||
List<String> newCommits = _commits
|
List<RepositoryCommit> 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<List<String>> getAppChangelog(
|
||||||
|
String packageName,
|
||||||
|
DateTime patchDate,
|
||||||
|
) async {
|
||||||
|
List<RepositoryCommit> commits =
|
||||||
|
await _githubAPI.getCommits(packageName, ghOrg, patchesRepo);
|
||||||
|
List<String> newCommits = commits
|
||||||
.where((c) =>
|
.where((c) =>
|
||||||
c.commit != null &&
|
c.commit != null &&
|
||||||
c.commit!.message != null &&
|
|
||||||
c.commit!.author != null &&
|
c.commit!.author != null &&
|
||||||
c.commit!.author!.date != 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!)
|
.map((c) => c.commit!.message!)
|
||||||
.toList();
|
.toList();
|
||||||
if (newCommits.isNotEmpty) {
|
if (newCommits.isEmpty) {
|
||||||
int firstChore = newCommits.indexWhere((c) => c.startsWith('chore'));
|
newCommits = commits
|
||||||
int secondChore =
|
.where((c) => c.commit != null && c.commit!.message != null)
|
||||||
newCommits.indexWhere((c) => c.startsWith('chore'), firstChore + 1);
|
.take(3)
|
||||||
if (firstChore >= 0 && secondChore > firstChore) {
|
.map((c) => c.commit!.message!)
|
||||||
return newCommits.sublist(firstChore + 1, secondChore);
|
.toList();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return List.empty();
|
return newCommits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ class HomeView extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ViewModelBuilder<HomeViewModel>.reactive(
|
return ViewModelBuilder<HomeViewModel>.reactive(
|
||||||
disposeViewModel: false,
|
disposeViewModel: false,
|
||||||
fireOnModelReadyOnce: true,
|
|
||||||
onModelReady: (model) => model.initialize(),
|
onModelReady: (model) => model.initialize(),
|
||||||
viewModelBuilder: () => locator<HomeViewModel>(),
|
viewModelBuilder: () => locator<HomeViewModel>(),
|
||||||
builder: (context, model, child) => Scaffold(
|
builder: (context, model, child) => Scaffold(
|
||||||
@ -111,8 +110,8 @@ class HomeView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 14),
|
const SizedBox(height: 14),
|
||||||
model.showUpdatableApps
|
model.showUpdatableApps
|
||||||
? const AvailableUpdatesCard()
|
? AvailableUpdatesCard()
|
||||||
: const InstalledAppsCard()
|
: InstalledAppsCard(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -26,14 +26,14 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
List<PatchedApplication> patchedUpdatableApps = [];
|
List<PatchedApplication> patchedUpdatableApps = [];
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
await _getPatchedApps();
|
|
||||||
await flutterLocalNotificationsPlugin.initialize(
|
await flutterLocalNotificationsPlugin.initialize(
|
||||||
const InitializationSettings(
|
const InitializationSettings(
|
||||||
android: AndroidInitializationSettings('ic_notification'),
|
android: AndroidInitializationSettings('ic_notification'),
|
||||||
),
|
),
|
||||||
onSelectNotification: (p) => DeviceApps.openApp('app.revanced.manager'),
|
onSelectNotification: (p) => DeviceApps.openApp('app.revanced.manager'),
|
||||||
);
|
);
|
||||||
_managerAPI.reAssessSavedApps().then((_) => notifyListeners());
|
_getPatchedApps();
|
||||||
|
_managerAPI.reAssessSavedApps().then((_) => _getPatchedApps());
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleUpdatableApps(bool value) {
|
void toggleUpdatableApps(bool value) {
|
||||||
@ -49,11 +49,8 @@ class HomeViewModel extends BaseViewModel {
|
|||||||
locator<MainViewModel>().setIndex(1);
|
locator<MainViewModel>().setIndex(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _getPatchedApps() async {
|
void _getPatchedApps() {
|
||||||
patchedInstalledApps = _managerAPI
|
patchedInstalledApps = _managerAPI.getPatchedApps().toList();
|
||||||
.getPatchedApps()
|
|
||||||
.where((app) => app.hasUpdates == false)
|
|
||||||
.toList();
|
|
||||||
patchedUpdatableApps = _managerAPI
|
patchedUpdatableApps = _managerAPI
|
||||||
.getPatchedApps()
|
.getPatchedApps()
|
||||||
.where((app) => app.hasUpdates == true)
|
.where((app) => app.hasUpdates == true)
|
||||||
|
@ -136,7 +136,7 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
update(1.0, 'Installed!', 'Installed!');
|
update(1.0, 'Installed!', 'Installed!');
|
||||||
_app!.patchDate = DateTime.now();
|
_app!.patchDate = DateTime.now();
|
||||||
_app!.appliedPatches = _patches.map((p) => p.name).toList();
|
_app!.appliedPatches = _patches.map((p) => p.name).toList();
|
||||||
_managerAPI.savePatchedApp(_app!);
|
await _managerAPI.savePatchedApp(_app!);
|
||||||
} else {
|
} else {
|
||||||
update(1.0, 'Aborting...', 'An error occurred! Aborting');
|
update(1.0, 'Aborting...', 'An error occurred! Aborting');
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class RootCheckerViewModel extends BaseViewModel {
|
|||||||
|
|
||||||
Future<void> navigateToHome() async {
|
Future<void> navigateToHome() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
prefs.setBool('isRooted', isRooted);
|
await prefs.setBool('isRooted', isRooted);
|
||||||
_navigationService.navigateTo(Routes.navigation);
|
_navigationService.navigateTo(Routes.navigation);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/ui/views/home/home_viewmodel.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/application_item.dart';
|
||||||
|
|
||||||
class AvailableUpdatesCard extends StatelessWidget {
|
class AvailableUpdatesCard extends StatelessWidget {
|
||||||
const AvailableUpdatesCard({
|
AvailableUpdatesCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List<PatchedApplication> apps =
|
||||||
|
locator<HomeViewModel>().patchedUpdatableApps;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListView(
|
return ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
children: locator<HomeViewModel>()
|
children: apps
|
||||||
.patchedUpdatableApps
|
|
||||||
.map((app) => ApplicationItem(
|
.map((app) => ApplicationItem(
|
||||||
icon: app.icon,
|
icon: app.icon,
|
||||||
name: app.name,
|
name: app.name,
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
import 'package:device_apps/device_apps.dart';
|
import 'package:device_apps/device_apps.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:revanced_manager/app/app.locator.dart';
|
import 'package:revanced_manager/app/app.locator.dart';
|
||||||
|
import 'package:revanced_manager/models/patched_application.dart';
|
||||||
import 'package:revanced_manager/ui/views/home/home_viewmodel.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/application_item.dart';
|
||||||
|
|
||||||
class InstalledAppsCard extends StatelessWidget {
|
class InstalledAppsCard extends StatelessWidget {
|
||||||
const InstalledAppsCard({
|
InstalledAppsCard({
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final List<PatchedApplication> apps =
|
||||||
|
locator<HomeViewModel>().patchedInstalledApps;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListView(
|
return ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
children: locator<HomeViewModel>()
|
children: apps
|
||||||
.patchedInstalledApps
|
|
||||||
.map((app) => ApplicationItem(
|
.map((app) => ApplicationItem(
|
||||||
icon: app.icon,
|
icon: app.icon,
|
||||||
name: app.name,
|
name: app.name,
|
||||||
|
@ -105,7 +105,7 @@ class ApplicationItem extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
' - ${changelog.join('\n- ')}',
|
'\u2022 ${changelog.join('\n\u2022 ')}',
|
||||||
style: kRobotoTextStyle,
|
style: kRobotoTextStyle,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user