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: improve ux #752

Merged
merged 11 commits into from
Apr 18, 2023
10 changes: 5 additions & 5 deletions assets/i18n/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"settingsTab": "Settings"
},
"homeView": {
"refreshSuccess": "Refresh successfully",
"widgetTitle": "Dashboard",
"updatesSubtitle": "Updates",
"patchedSubtitle": "Patched applications",
Expand Down Expand Up @@ -72,16 +73,15 @@
"viewTitle": "Select an application",
"searchBarHint": "Search applications",
"storageButton": "Storage",
"errorMessage": "Unable to use selected application"
"errorMessage": "Unable to use selected application",
"downloadToast": "Download function is not available yet"
},
"patchesSelectorView": {
"viewTitle": "Select patches",
"searchBarHint": "Search patches",
"doneButton": "Done",
"recommended": "Recommended",
"recommendedTooltip": "Select all recommended patches",
"all": "All",
"allTooltip": "Select all patches",
"default": "Default",
"defaultTooltip": "Select all default patches",
"none": "None",
"noneTooltip": "Deselect all patches",
"loadPatchesSelection": "Load patches selection",
Expand Down
33 changes: 25 additions & 8 deletions lib/services/github_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@ import 'dart:io';

import 'package:collection/collection.dart';
import 'package:dio/dio.dart';
import 'package:dio_http_cache_lts/dio_http_cache_lts.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:injectable/injectable.dart';
import 'package:native_dio_adapter/native_dio_adapter.dart';
import 'package:revanced_manager/models/patch.dart';

@lazySingleton
class GithubAPI {
late Dio _dio = Dio();
final DioCacheManager _dioCacheManager = DioCacheManager(CacheConfig());
final Options _cacheOptions = buildCacheOptions(
const Duration(hours: 6),

final _cacheOptions = CacheOptions(
store: MemCacheStore(),
maxStale: const Duration(days: 1),
priority: CachePriority.high,
);

final Map<String, String> repoAppPath = {
'com.google.android.youtube': 'youtube',
'com.google.android.apps.youtube.music': 'music',
Expand All @@ -30,13 +33,29 @@ class GithubAPI {

Future<void> initialize(String repoUrl) async {
try {
if (Platform.isIOS || Platform.isMacOS || Platform.isAndroid) {
final CronetEngine androidCronetEngine = await CronetEngine.build(
userAgent: 'ReVanced Manager',
enableBrotli: true,
enableQuic: true,
);
_dio.httpClientAdapter =
NativeAdapter(androidCronetEngine: androidCronetEngine);

_dio = Dio(
BaseOptions(
baseUrl: repoUrl,
),
);
}

_dio = Dio(
BaseOptions(
baseUrl: repoUrl,
),
);

_dio.interceptors.add(_dioCacheManager.interceptor);
_dio.interceptors.add(DioCacheInterceptor(options: _cacheOptions));
} on Exception catch (e) {
if (kDebugMode) {
print(e);
Expand All @@ -46,7 +65,7 @@ class GithubAPI {

Future<void> clearAllCache() async {
try {
await _dioCacheManager.clearAll();
await _cacheOptions.store!.clean();
} on Exception catch (e) {
if (kDebugMode) {
print(e);
Expand All @@ -58,7 +77,6 @@ class GithubAPI {
try {
final response = await _dio.get(
'/repos/$repoName/releases',
options: _cacheOptions,
);
return response.data[0];
} on Exception catch (e) {
Expand All @@ -83,7 +101,6 @@ class GithubAPI {
'path': path,
'since': since.toIso8601String(),
},
options: _cacheOptions,
);
final List<dynamic> commits = response.data;
return commits
Expand Down
17 changes: 17 additions & 0 deletions lib/services/manager_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class ManagerAPI {
String defaultIntegrationsRepo = 'revanced/revanced-integrations';
String defaultCliRepo = 'revanced/revanced-cli';
String defaultManagerRepo = 'revanced/revanced-manager';
String? patchesVersion = '';
bool isDefaultPatchesRepo() {
return getPatchesRepo() == 'revanced/revanced-patches';
}

Future<void> initialize() async {
_prefs = await SharedPreferences.getInstance();
Expand Down Expand Up @@ -267,6 +271,19 @@ class ManagerAPI {
return packageInfo.version;
}

Future<String?> getCurrentPatchesVersion() async {
if (isDefaultPatchesRepo()) {
patchesVersion = await getLatestPatchesVersion();
// print('Patches version: $patchesVersion');
return patchesVersion ?? '0.0.0';
} else {
// fetch from github
patchesVersion =
await _githubAPI.getLastestReleaseVersion(getPatchesRepo());
}
return null;
}

Future<List<PatchedApplication>> getAppsToRemove(
List<PatchedApplication> patchedApps,
) async {
Expand Down
42 changes: 27 additions & 15 deletions lib/services/revanced_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ import 'dart:io';

import 'package:collection/collection.dart';
import 'package:dio/dio.dart';
import 'package:dio_http_cache_lts/dio_http_cache_lts.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:injectable/injectable.dart';
import 'package:native_dio_client/native_dio_client.dart';
import 'package:native_dio_adapter/native_dio_adapter.dart';
import 'package:revanced_manager/models/patch.dart';
import 'package:revanced_manager/utils/check_for_gms.dart';
import 'package:timeago/timeago.dart';

@lazySingleton
class RevancedAPI {
late Dio _dio = Dio();
final DioCacheManager _dioCacheManager = DioCacheManager(CacheConfig());
final Options _cacheOptions = buildCacheOptions(
const Duration(hours: 6),

final _cacheOptions = CacheOptions(
store: MemCacheStore(),
maxStale: const Duration(days: 1),
priority: CachePriority.high,
);

Future<void> initialize(String apiUrl) async {
Expand All @@ -33,14 +34,25 @@ class RevancedAPI {
);
log('ReVanced API: Using default engine + $isGMSInstalled');
} else {
_dio = Dio(
BaseOptions(
baseUrl: apiUrl,
),
)..httpClientAdapter = NativeAdapter();
if (Platform.isIOS || Platform.isMacOS || Platform.isAndroid) {
final CronetEngine androidCronetEngine = await CronetEngine.build(
userAgent: 'ReVanced Manager',
enableBrotli: true,
enableQuic: true,
);
_dio.httpClientAdapter =
NativeAdapter(androidCronetEngine: androidCronetEngine);

_dio = Dio(
BaseOptions(
baseUrl: apiUrl,
),
);
}

log('ReVanced API: Using CronetEngine + $isGMSInstalled');
}
_dio.interceptors.add(_dioCacheManager.interceptor);
_dio.interceptors.add(DioCacheInterceptor(options: _cacheOptions));
} on Exception catch (e) {
if (kDebugMode) {
print(e);
Expand All @@ -50,7 +62,7 @@ class RevancedAPI {

Future<void> clearAllCache() async {
try {
await _dioCacheManager.clearAll();
await _cacheOptions.store!.clean();
} on Exception catch (e) {
if (kDebugMode) {
print(e);
Expand All @@ -61,7 +73,7 @@ class RevancedAPI {
Future<Map<String, List<dynamic>>> getContributors() async {
final Map<String, List<dynamic>> contributors = {};
try {
final response = await _dio.get('/contributors', options: _cacheOptions);
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'];
Expand All @@ -78,7 +90,7 @@ class RevancedAPI {

Future<List<Patch>> getPatches() async {
try {
final response = await _dio.get('/patches', options: _cacheOptions);
final response = await _dio.get('/patches');
final List<dynamic> patches = response.data;
return patches.map((patch) => Patch.fromJson(patch)).toList();
} on Exception catch (e) {
Expand All @@ -94,7 +106,7 @@ class RevancedAPI {
String repoName,
) async {
try {
final response = await _dio.get('/tools', options: _cacheOptions);
final response = await _dio.get('/tools');
final List<dynamic> tools = response.data['tools'];
return tools.firstWhereOrNull(
(t) =>
Expand Down
64 changes: 47 additions & 17 deletions lib/ui/views/app_selector/app_selector_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/ui/views/app_selector/app_selector_viewmodel.dart';
import 'package:revanced_manager/ui/widgets/appSelectorView/app_skeleton_loader.dart';
import 'package:revanced_manager/ui/widgets/appSelectorView/installed_app_item.dart';
import 'package:revanced_manager/ui/widgets/appSelectorView/not_installed_app_item.dart';
import 'package:revanced_manager/ui/widgets/shared/search_bar.dart';
import 'package:stacked/stacked.dart' hide SkeletonLoader;

Expand Down Expand Up @@ -76,30 +77,59 @@ class _AppSelectorViewState extends State<AppSelectorView> {
SliverToBoxAdapter(
child: model.noApps
? Center(
child: I18nText('appSelectorCard.noAppsLabel'),
child: I18nText(
'appSelectorView.noApps',
child: Text(
'',
style: TextStyle(
color:
Theme.of(context).textTheme.titleLarge!.color,
),
),
),
)
: model.apps.isEmpty
? const AppSkeletonLoader()
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0)
.copyWith(bottom: 80),
child: Column(
children: model
.getFilteredApps(_query)
.map(
(app) => InstalledAppItem(
name: app.appName,
pkgName: app.packageName,
icon: app.icon,
patchesCount:
model.patchesCount(app.packageName),
onTap: () {
model.selectApp(app);
Navigator.of(context).pop();
},
),
)
.toList(),
children: [
...model
.getFilteredApps(_query)
.map(
(app) => InstalledAppItem(
name: app.appName,
pkgName: app.packageName,
icon: app.icon,
patchesCount:
model.patchesCount(app.packageName),
recommendedVersion:
model.getRecommendedVersion(
app.packageName,
),
onTap: () {
model.selectApp(app);
Navigator.of(context).pop();
},
),
)
.toList(),
...model
.getFilteredAppsNames(_query)
.map(
(app) => NotInstalledAppItem(
name: app,
patchesCount: model.patchesCount(app),
recommendedVersion:
model.getRecommendedVersion(app),
onTap: () {
model.showDownloadToast();
},
),
)
.toList(),
],
),
),
),
Expand Down
Loading