Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add a toggle for alternative sources #1686

Merged
merged 6 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Empty file modified assets/i18n/en_US.json
100755 → 100644
Empty file.
12 changes: 7 additions & 5 deletions assets/i18n/strings.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
"debugSectionTitle": "Debugging",
"advancedSectionTitle": "Advanced",
"exportSectionTitle": "Import & export",
"dataSectionTitle": "Data sources",
"themeModeLabel": "App theme",
"systemThemeLabel": "System",
"lightThemeLabel": "Light",
Expand All @@ -173,17 +174,18 @@
"languageLabel": "Language",
"languageUpdated": "Language updated",
"englishOption": "English",
"sourcesLabel": "Sources",
"sourcesLabelHint": "Configure the source of patches and integrations",
"sourcesLabel": "Alternative sources",
"sourcesLabelHint": "Configure the alternative sources for ReVanced Patches and ReVanced Integrations",
"sourcesIntegrationsLabel": "Integrations source",
"useAlternativeSources": "Use alternative sources",
"useAlternativeSourcesHint": "Use alternative sources for ReVanced Patches and ReVanced Integrations instead of the API",
"sourcesResetDialogTitle": "Reset",
"sourcesResetDialogText": "Are you sure you want to reset your sources to their default values?",
"apiURLResetDialogText": "Are you sure you want to reset your API URL to its default value?",
"sourcesUpdateNote": "Note: Patches will be updated to the latest version automatically.\n\nThis will reveal your IP address to the server.",
"sourcesUpdateNote": "Note: This will automatically download ReVanced Patches and ReVanced Integrations from the alternative sources.\n\nThis will connect you to the alternative source.",
"apiURLLabel": "API URL",
"apiURLHint": "Configure the URL of the API to use",
"apiURLHint": "Configure the API URL of ReVanced Manager",
"selectApiURL": "API URL",
"hostRepositoryLabel": "Repository API",
"orgPatchesLabel": "Patches organization",
"sourcesPatchesLabel": "Patches source",
"orgIntegrationsLabel": "Integrations organization",
Expand Down
49 changes: 26 additions & 23 deletions lib/services/manager_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ class ManagerAPI {
String? patchesVersion = '';
String? integrationsVersion = '';

bool isDefaultPatchesRepo() {
return getPatchesRepo().toLowerCase() == defaultPatchesRepo;
}

bool isDefaultIntegrationsRepo() {
return getIntegrationsRepo().toLowerCase() == defaultIntegrationsRepo;
}

Future<void> initialize() async {
_prefs = await SharedPreferences.getInstance();
isRooted = await _rootAPI.isRooted();
Expand All @@ -73,14 +65,23 @@ class ManagerAPI {
}

// Migrate to new API URL if not done yet as the old one is sunset.
final bool hasMigrated = _prefs.getBool('migratedToNewApiUrl') ?? false;
if (!hasMigrated) {
final bool hasMigratedToNewApi = _prefs.getBool('migratedToNewApiUrl') ?? false;
if (!hasMigratedToNewApi) {
final String apiUrl = getApiUrl().toLowerCase();
if (apiUrl.contains('releases.revanced.app')) {
await setApiUrl(''); // Reset to default.
_prefs.setBool('migratedToNewApiUrl', true);
}
}

final bool hasMigratedToAlternativeSource = _prefs.getBool('migratedToAlternativeSource') ?? false;
if (!hasMigratedToAlternativeSource) {
final String patchesRepo = getPatchesRepo();
final String integrationsRepo = getIntegrationsRepo();
final bool usingAlternativeSources = patchesRepo.toLowerCase() != defaultPatchesRepo || integrationsRepo.toLowerCase() != defaultIntegrationsRepo;
_prefs.setBool('useAlternativeSources', usingAlternativeSources);
_prefs.setBool('migratedToAlternativeSource', true);
}
}

Future<int> getSdkVersion() async {
Expand All @@ -102,14 +103,7 @@ class ManagerAPI {
}

String getRepoUrl() {
return _prefs.getString('repoUrl') ?? defaultRepoUrl;
}

Future<void> setRepoUrl(String url) async {
if (url.isEmpty || url == ' ') {
url = defaultRepoUrl;
}
await _prefs.setString('repoUrl', url);
return defaultRepoUrl;
}

String getPatchesDownloadURL() {
Expand Down Expand Up @@ -219,6 +213,15 @@ class ManagerAPI {
await _prefs.setStringList('usedPatches-$packageName', patchesJson);
}

void useAlternativeSources(bool value) {
_prefs.setBool('useAlternativeSources', value);
_toast.showBottom(t.settingsView.restartAppForChanges);
}

bool isUsingAlternativeSources() {
return _prefs.getBool('useAlternativeSources') ?? false;
}

Option? getPatchOption(String packageName, String patchName, String key) {
final String? optionJson =
_prefs.getString('patchOption-$packageName-$patchName-$key');
Expand Down Expand Up @@ -416,7 +419,7 @@ class ManagerAPI {

Future<File?> downloadPatches() async {
try {
final String repoName = getPatchesRepo();
final String repoName = !isUsingAlternativeSources() ? defaultPatchesRepo : getPatchesRepo();
final String currentVersion = await getCurrentPatchesVersion();
final String url = getPatchesDownloadURL();
return await _githubAPI.getPatchesReleaseFile(
Expand All @@ -435,7 +438,7 @@ class ManagerAPI {

Future<File?> downloadIntegrations() async {
try {
final String repoName = getIntegrationsRepo();
final String repoName = !isUsingAlternativeSources() ? defaultIntegrationsRepo : getIntegrationsRepo();
final String currentVersion = await getCurrentIntegrationsVersion();
final String url = getIntegrationsDownloadURL();
return await _githubAPI.getPatchesReleaseFile(
Expand All @@ -460,7 +463,7 @@ class ManagerAPI {
}

Future<String?> getLatestPatchesReleaseTime() async {
if (isDefaultPatchesRepo()) {
if (!isUsingAlternativeSources()) {
return await _revancedAPI.getLatestReleaseTime(
'.json',
defaultPatchesRepo,
Expand Down Expand Up @@ -493,7 +496,7 @@ class ManagerAPI {
}

Future<String?> getLatestIntegrationsVersion() async {
if (isDefaultIntegrationsRepo()) {
if (!isUsingAlternativeSources()) {
return await _revancedAPI.getLatestReleaseVersion(
'.apk',
defaultIntegrationsRepo,
Expand All @@ -509,7 +512,7 @@ class ManagerAPI {
}

Future<String?> getLatestPatchesVersion() async {
if (isDefaultPatchesRepo()) {
if (!isUsingAlternativeSources()) {
return await _revancedAPI.getLatestReleaseVersion(
'.json',
defaultPatchesRepo,
Expand Down
4 changes: 2 additions & 2 deletions lib/services/revanced_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class RevancedAPI {
final response = await _dio.get('/contributors');
final List<dynamic> repositories = response.data['repositories'];
for (final Map<String, dynamic> repo in repositories) {
final String name = repo['name'].toLowerCase();
final String name = repo['name'];
contributors[name] = repo['contributors'];
}
} on Exception catch (e) {
Expand All @@ -58,7 +58,7 @@ class RevancedAPI {
final List<dynamic> tools = response.data['tools'];
return tools.firstWhereOrNull(
(t) =>
(t['repository'] as String).toLowerCase() == repoName.toLowerCase() &&
(t['repository'] as String) == repoName &&
(t['name'] as String).endsWith(extension),
);
} on Exception catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/views/contributors/contributors_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ class ContributorsViewModel extends BaseViewModel {
final Map<String, List<dynamic>> contributors =
await _managerAPI.getContributors();
patcherContributors = contributors[_managerAPI.defaultPatcherRepo] ?? [];
patchesContributors = contributors[_managerAPI.getPatchesRepo().toLowerCase()] ?? [];
patchesContributors = contributors[_managerAPI.defaultPatchesRepo] ?? [];
integrationsContributors =
contributors[_managerAPI.getIntegrationsRepo().toLowerCase()] ?? [];
contributors[_managerAPI.defaultIntegrationsRepo] ?? [];
cliContributors = contributors[_managerAPI.defaultCliRepo] ?? [];
managerContributors = contributors[_managerAPI.defaultManagerRepo] ?? [];
notifyListeners();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@ class SManageSources extends BaseViewModel {
final ManagerAPI _managerAPI = locator<ManagerAPI>();
final Toast _toast = locator<Toast>();

final TextEditingController _hostSourceController = TextEditingController();
final TextEditingController _orgPatSourceController = TextEditingController();
final TextEditingController _patSourceController = TextEditingController();
final TextEditingController _orgIntSourceController = TextEditingController();
final TextEditingController _intSourceController = TextEditingController();

Future<void> showSourcesDialog(BuildContext context) async {
final String hostRepository = _managerAPI.getRepoUrl();
final String patchesRepo = _managerAPI.getPatchesRepo();
final String integrationsRepo = _managerAPI.getIntegrationsRepo();
_hostSourceController.text = hostRepository;
_orgPatSourceController.text = patchesRepo.split('/')[0];
_patSourceController.text = patchesRepo.split('/')[1];
_orgIntSourceController.text = integrationsRepo.split('/')[0];
Expand All @@ -44,26 +41,6 @@ class SManageSources extends BaseViewModel {
content: SingleChildScrollView(
child: Column(
children: <Widget>[
/*
API for accessing the specified repositories
If default is used, will use the ReVanced API
*/
TextField(
controller: _hostSourceController,
autocorrect: false,
onChanged: (value) => notifyListeners(),
decoration: InputDecoration(
icon: Icon(
Icons.rocket_launch_outlined,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
border: const OutlineInputBorder(),
labelText: t.settingsView.hostRepositoryLabel,
hintText: hostRepository,
),
),
const SizedBox(height: 8),
// Patches owner's name
TextField(
controller: _orgPatSourceController,
autocorrect: false,
Expand Down Expand Up @@ -144,7 +121,6 @@ class SManageSources extends BaseViewModel {
),
FilledButton(
onPressed: () {
_managerAPI.setRepoUrl(_hostSourceController.text.trim());
_managerAPI.setPatchesRepo(
'${_orgPatSourceController.text.trim()}/${_patSourceController.text.trim()}',
);
Expand Down Expand Up @@ -176,7 +152,6 @@ class SManageSources extends BaseViewModel {
),
FilledButton(
onPressed: () {
_managerAPI.setRepoUrl('');
_managerAPI.setPatchesRepo('');
_managerAPI.setIntegrationsRepo('');
_managerAPI.setCurrentPatchesVersion('0.0.0');
Expand Down
3 changes: 3 additions & 0 deletions lib/ui/views/settings/settings_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_upd
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_update_theme.dart';
import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_advanced_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_data_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_debug_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_export_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_team_section.dart';
Expand Down Expand Up @@ -49,6 +50,8 @@ class SettingsView extends StatelessWidget {
_settingsDivider,
SAdvancedSection(),
_settingsDivider,
SDataSection(),
_settingsDivider,
SExportSection(),
_settingsDivider,
STeamSection(),
Expand Down
11 changes: 11 additions & 0 deletions lib/ui/views/settings/settings_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ class SettingsViewModel extends BaseViewModel {
return _managerAPI.isPatchesChangeEnabled();
}

void useAlternativeSources(bool value) {
_managerAPI.useAlternativeSources(value);
_managerAPI.setCurrentPatchesVersion('0.0.0');
_managerAPI.setCurrentIntegrationsVersion('0.0.0');
notifyListeners();
}

bool isUsingAlternativeSources() {
return _managerAPI.isUsingAlternativeSources();
}

Future<void> showPatchesChangeEnableDialog(
bool value,
BuildContext context,
Expand Down
4 changes: 0 additions & 4 deletions lib/ui/widgets/settingsView/settings_advanced_section.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import 'package:flutter/material.dart';
import 'package:revanced_manager/gen/strings.g.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_require_suggested_app_version.dart';
Expand All @@ -26,8 +24,6 @@ class SAdvancedSection extends StatelessWidget {
SRequireSuggestedAppVersion(),
SVersionCompatibilityCheck(),
SUniversalPatches(),
SManageSourcesUI(),
SManageApiUrlUI(),
],
);
}
Expand Down
22 changes: 22 additions & 0 deletions lib/ui/widgets/settingsView/settings_data_section.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ignore_for_file: prefer_const_constructors

import 'package:flutter/material.dart';
import 'package:revanced_manager/gen/strings.g.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart';
import 'package:revanced_manager/ui/widgets/settingsView/settings_use_alternative_sources.dart';

class SDataSection extends StatelessWidget {
const SDataSection({super.key});

@override
Widget build(BuildContext context) {
return SettingsSection(
title: t.settingsView.dataSectionTitle,
children: const <Widget>[
SManageApiUrlUI(),
SUseAlternativeSources(),
],
);
}
}
43 changes: 43 additions & 0 deletions lib/ui/widgets/settingsView/settings_use_alternative_sources.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:revanced_manager/gen/strings.g.dart';
import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.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 SUseAlternativeSources extends StatefulWidget {
const SUseAlternativeSources({super.key});

@override
State<SUseAlternativeSources> createState() => _SUseAlternativeSourcesState();
}

final _settingsViewModel = SettingsViewModel();

class _SUseAlternativeSourcesState extends State<SUseAlternativeSources> {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HapticSwitchListTile(
contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
title: Text(
t.settingsView.useAlternativeSources,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
subtitle: Text(t.settingsView.useAlternativeSourcesHint),
value: _settingsViewModel.isUsingAlternativeSources(),
onChanged: (value) {
_settingsViewModel.useAlternativeSources(value);
setState(() {});
},
),
if (_settingsViewModel.isUsingAlternativeSources())
const SManageSourcesUI(),
],
);
}
}