feat: Add toggle to use pre-releases

This commit is contained in:
aAbed 2025-04-17 22:04:07 +05:45
parent 841d61278b
commit d9258c5838
No known key found for this signature in database
GPG key ID: F26611AB3F996827
7 changed files with 87 additions and 45 deletions

View file

@ -180,6 +180,8 @@
"disablePatchesSelectionWarningText": "You are about to disable changing the selection of patches.\nThe default selection of patches will be restored.\n\nDisable anyways?",
"autoUpdatePatchesLabel": "Auto update patches",
"autoUpdatePatchesHint": "Automatically update patches to the latest version",
"usePrereleasesLabel": "Use pre-releases",
"usePrereleasesHint": "Use pre-releases of ReVanced Manager and ReVanced Patches",
"showUpdateDialogLabel": "Show update dialog",
"showUpdateDialogHint": "Show a dialog when a new update is available",
"universalPatchesLabel": "Show universal patches",

View file

@ -33,12 +33,12 @@ class GithubAPI {
});
}
Future<Map<String, dynamic>?> getLatestRelease(
String repoName,
) async {
Future<Map<String, dynamic>?> getLatestRelease(String repoName) async {
final String prerelease =
_managerAPI.usePrereleases() ? '?per_page=1' : '/latest';
try {
final response = await _dioGetSynchronously(
'/repos/$repoName/releases/latest',
'/repos/$repoName/releases$prerelease',
);
return response.data;
} on Exception catch (e) {
@ -50,17 +50,19 @@ class GithubAPI {
}
Future<String?> getChangelogs(bool isPatches) async {
final String repoName = isPatches
? _managerAPI.getPatchesRepo()
: _managerAPI.defaultManagerRepo;
final String repoName =
isPatches
? _managerAPI.getPatchesRepo()
: _managerAPI.defaultManagerRepo;
try {
final response = await _dioGetSynchronously(
'/repos/$repoName/releases?per_page=50',
);
final buffer = StringBuffer();
final String version = isPatches
? _managerAPI.getLastUsedPatchesVersion()
: await _managerAPI.getCurrentManagerVersion();
final String version =
isPatches
? _managerAPI.getLastUsedPatchesVersion()
: await _managerAPI.getCurrentManagerVersion();
int releases = 0;
for (final release in response.data) {
if (release['tag_name'] == version) {
@ -70,7 +72,7 @@ class GithubAPI {
}
break;
}
if (release['prerelease']) {
if (!_managerAPI.usePrereleases() && release['prerelease']) {
continue;
}
buffer.writeln(release['body']);
@ -96,25 +98,21 @@ class GithubAPI {
) async {
try {
if (url.isNotEmpty) {
return await _downloadManager.getSingleFile(
url,
);
return await _downloadManager.getSingleFile(url);
}
final response = await _dioGetSynchronously(
'/repos/$repoName/releases/tags/$version',
);
final Map<String, dynamic>? release = response.data;
if (release != null) {
final Map<String, dynamic>? asset =
(release['assets'] as List<dynamic>).firstWhereOrNull(
(asset) => (asset['name'] as String).endsWith(extension),
);
final Map<String, dynamic>? asset = (release['assets'] as List<dynamic>)
.firstWhereOrNull(
(asset) => (asset['name'] as String).endsWith(extension),
);
if (asset != null) {
final String downloadUrl = asset['browser_download_url'];
_managerAPI.setPatchesDownloadURL(downloadUrl);
return await _downloadManager.getSingleFile(
downloadUrl,
);
return await _downloadManager.getSingleFile(downloadUrl);
}
}
} on Exception catch (e) {

View file

@ -168,6 +168,14 @@ class ManagerAPI {
return _prefs.getBool('patchesAutoUpdate') ?? false;
}
bool usePrereleases() {
return _prefs.getBool('usePrereleases') ?? false;
}
void setPrereleases(bool value) {
_prefs.setBool('usePrereleases', value);
}
bool isPatchesChangeEnabled() {
return _prefs.getBool('patchesChangeEnabled') ?? false;
}

View file

@ -14,6 +14,7 @@ import 'package:timeago/timeago.dart';
class RevancedAPI {
late final Dio _dio;
late final DownloadManager _downloadManager = locator<DownloadManager>();
late final ManagerAPI _managerAPI = locator<ManagerAPI>();
final Lock getToolsLock = Lock();
@ -43,15 +44,15 @@ class RevancedAPI {
return contributors;
}
Future<Map<String, dynamic>?> _getLatestRelease(
String toolName,
) {
Future<Map<String, dynamic>?> _getLatestRelease(String toolName) {
if (!locator<ManagerAPI>().getDownloadConsent()) {
return Future(() => null);
}
return getToolsLock.synchronized(() async {
try {
final response = await _dio.get('/$toolName');
final response = await _dio.get(
'/$toolName?prerelease=${_managerAPI.usePrereleases()}',
);
return response.data;
} on Exception catch (e) {
if (kDebugMode) {
@ -62,13 +63,9 @@ class RevancedAPI {
});
}
Future<String?> getLatestReleaseVersion(
String toolName,
) async {
Future<String?> getLatestReleaseVersion(String toolName) async {
try {
final Map<String, dynamic>? release = await _getLatestRelease(
toolName,
);
final Map<String, dynamic>? release = await _getLatestRelease(toolName);
if (release != null) {
return release['version'];
}
@ -81,13 +78,9 @@ class RevancedAPI {
return null;
}
Future<File?> getLatestReleaseFile(
String toolName,
) async {
Future<File?> getLatestReleaseFile(String toolName) async {
try {
final Map<String, dynamic>? release = await _getLatestRelease(
toolName,
);
final Map<String, dynamic>? release = await _getLatestRelease(toolName);
if (release != null) {
final String url = release['download_url'];
return await _downloadManager.getSingleFile(url);
@ -136,16 +129,13 @@ class RevancedAPI {
return outputFile;
}
Future<String?> getLatestReleaseTime(
String toolName,
) async {
Future<String?> getLatestReleaseTime(String toolName) async {
try {
final Map<String, dynamic>? release = await _getLatestRelease(
toolName,
);
final Map<String, dynamic>? release = await _getLatestRelease(toolName);
if (release != null) {
final DateTime timestamp =
DateTime.parse(release['created_at'] as String);
final DateTime timestamp = DateTime.parse(
release['created_at'] as String,
);
return format(timestamp, locale: 'en_short');
}
} on Exception catch (e) {

View file

@ -40,6 +40,15 @@ class SettingsViewModel extends BaseViewModel {
notifyListeners();
}
bool usePrereleases() {
return _managerAPI.usePrereleases();
}
void setPrereleases(bool value) {
_managerAPI.setPrereleases(value);
notifyListeners();
}
bool showUpdateDialog() {
return _managerAPI.showUpdateDialog();
}

View file

@ -9,6 +9,7 @@ import 'package:revanced_manager/ui/widgets/settingsView/settings_require_sugges
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_show_update_dialog.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_universal_patches.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_use_prereleases.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_version_compatibility_check.dart';
class SAdvancedSection extends StatelessWidget {
@ -20,6 +21,7 @@ class SAdvancedSection extends StatelessWidget {
title: t.settingsView.advancedSectionTitle,
children: const <Widget>[
SAutoUpdatePatches(),
SUsePrereleases(),
SShowUpdateDialog(),
SEnablePatchesSelection(),
SRequireSuggestedAppVersion(),

View file

@ -0,0 +1,33 @@
import 'package:flutter/material.dart';
import 'package:revanced_manager/gen/strings.g.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/shared/haptics/haptic_switch_list_tile.dart';
class SUsePrereleases extends StatefulWidget {
const SUsePrereleases({super.key});
@override
State<SUsePrereleases> createState() => _SUsePrereleasesState();
}
final _settingsViewModel = SettingsViewModel();
class _SUsePrereleasesState extends State<SUsePrereleases> {
@override
Widget build(BuildContext context) {
return HapticSwitchListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: Text(
t.settingsView.usePrereleasesLabel,
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
),
subtitle: Text(t.settingsView.usePrereleasesHint),
value: _settingsViewModel.usePrereleases(),
onChanged: (value) {
setState(() {
_settingsViewModel.setPrereleases(value);
});
},
);
}
}