mirror of
https://github.com/revanced/revanced-manager
synced 2024-05-14 13:56:57 +02:00
feat(installer): redesign utility options (#1062)
Co-authored-by: Ushie <ushiekane@gmail.com>
This commit is contained in:
parent
1442916b20
commit
b77d46b2c2
@ -140,6 +140,8 @@
|
|||||||
},
|
},
|
||||||
"installerView": {
|
"installerView": {
|
||||||
"widgetTitle": "Installer",
|
"widgetTitle": "Installer",
|
||||||
|
"installType": "Select install type",
|
||||||
|
"installTypeDescription": "Select the installation type to proceed with.",
|
||||||
"installButton": "Install",
|
"installButton": "Install",
|
||||||
"installRootButton": "Install as Root",
|
"installRootButton": "Install as Root",
|
||||||
"pressBackAgain": "Press back again to cancel",
|
"pressBackAgain": "Press back again to cancel",
|
||||||
@ -149,9 +151,8 @@
|
|||||||
"notificationTitle": "ReVanced Manager is patching",
|
"notificationTitle": "ReVanced Manager is patching",
|
||||||
"notificationText": "Tap to return to the installer",
|
"notificationText": "Tap to return to the installer",
|
||||||
|
|
||||||
"shareApkMenuOption": "Share APK",
|
"exportApkButtonTooltip": "Export patched APK",
|
||||||
"exportApkMenuOption": "Export APK",
|
"exportLogButtonTooltip": "Export log",
|
||||||
"shareLogMenuOption": "Share log",
|
|
||||||
|
|
||||||
"installErrorDialogTitle": "Error",
|
"installErrorDialogTitle": "Error",
|
||||||
"installErrorDialogText1": "Root install is not possible with the current patches selection.\nRepatch your app or choose non-root install.",
|
"installErrorDialogText1": "Root install is not possible with the current patches selection.\nRepatch your app or choose non-root install.",
|
||||||
|
@ -283,7 +283,7 @@ class PatcherAPI {
|
|||||||
return newName;
|
return newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sharePatcherLog(String logs) async {
|
Future<void> exportPatcherLog(String logs) async {
|
||||||
final Directory appCache = await getTemporaryDirectory();
|
final Directory appCache = await getTemporaryDirectory();
|
||||||
final Directory logDir = Directory('${appCache.path}/logs');
|
final Directory logDir = Directory('${appCache.path}/logs');
|
||||||
logDir.createSync();
|
logDir.createSync();
|
||||||
@ -293,10 +293,15 @@ class PatcherAPI {
|
|||||||
.replaceAll(':', '')
|
.replaceAll(':', '')
|
||||||
.replaceAll('T', '')
|
.replaceAll('T', '')
|
||||||
.replaceAll('.', '');
|
.replaceAll('.', '');
|
||||||
final File log =
|
final String fileName = 'revanced-manager_patcher_$dateTime.log';
|
||||||
File('${logDir.path}/revanced-manager_patcher_$dateTime.log');
|
final File log = File('${logDir.path}/$fileName');
|
||||||
log.writeAsStringSync(logs);
|
log.writeAsStringSync(logs);
|
||||||
ShareExtend.share(log.path, 'file');
|
CRFileSaver.saveFileWithDialog(
|
||||||
|
SaveFileDialogParams(
|
||||||
|
sourceFilePath: log.path,
|
||||||
|
destinationFileName: fileName,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getSuggestedVersion(String packageName) {
|
String getSuggestedVersion(String packageName) {
|
||||||
|
@ -4,8 +4,6 @@ import 'package:google_fonts/google_fonts.dart';
|
|||||||
import 'package:revanced_manager/ui/views/installer/installer_viewmodel.dart';
|
import 'package:revanced_manager/ui/views/installer/installer_viewmodel.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/installerView/gradient_progress_indicator.dart';
|
import 'package:revanced_manager/ui/widgets/installerView/gradient_progress_indicator.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_card.dart';
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart';
|
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_popup_menu.dart';
|
|
||||||
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
|
import 'package:revanced_manager/ui/widgets/shared/custom_sliver_app_bar.dart';
|
||||||
import 'package:stacked/stacked.dart';
|
import 'package:stacked/stacked.dart';
|
||||||
|
|
||||||
@ -22,6 +20,40 @@ class InstallerView extends StatelessWidget {
|
|||||||
top: false,
|
top: false,
|
||||||
bottom: false,
|
bottom: false,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
|
floatingActionButton: Visibility(
|
||||||
|
visible: !model.isPatching,
|
||||||
|
child: FloatingActionButton.extended(
|
||||||
|
label: I18nText('installerView.installButton'),
|
||||||
|
icon: const Icon(Icons.file_download_outlined),
|
||||||
|
onPressed: () => model.installTypeDialog(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButtonLocation:
|
||||||
|
FloatingActionButtonLocation.endContained,
|
||||||
|
bottomNavigationBar: Visibility(
|
||||||
|
visible: !model.isPatching,
|
||||||
|
child: BottomAppBar(
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Visibility(
|
||||||
|
visible: !model.hasErrors,
|
||||||
|
child: IconButton.filledTonal(
|
||||||
|
tooltip: FlutterI18n.translate(
|
||||||
|
context, 'installerView.exportApkButtonTooltip'),
|
||||||
|
icon: const Icon(Icons.save),
|
||||||
|
onPressed: () => model.onButtonPressed(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton.filledTonal(
|
||||||
|
tooltip: FlutterI18n.translate(
|
||||||
|
context, 'installerView.exportLogButtonTooltip'),
|
||||||
|
icon: const Icon(Icons.post_add),
|
||||||
|
onPressed: () => model.onButtonPressed(1),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
body: CustomScrollView(
|
body: CustomScrollView(
|
||||||
controller: model.scrollController,
|
controller: model.scrollController,
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
@ -35,44 +67,6 @@ class InstallerView extends StatelessWidget {
|
|||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
onBackButtonPressed: () => model.onWillPop(context),
|
onBackButtonPressed: () => model.onWillPop(context),
|
||||||
actions: <Widget>[
|
|
||||||
Visibility(
|
|
||||||
visible: !model.isPatching,
|
|
||||||
child: CustomPopupMenu(
|
|
||||||
onSelected: (value) => model.onMenuSelection(value),
|
|
||||||
children: {
|
|
||||||
if (!model.hasErrors)
|
|
||||||
0: I18nText(
|
|
||||||
'installerView.shareApkMenuOption',
|
|
||||||
child: const Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
1: I18nText(
|
|
||||||
'installerView.exportApkMenuOption',
|
|
||||||
child: const Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
2: I18nText(
|
|
||||||
'installerView.shareLogMenuOption',
|
|
||||||
child: const Text(
|
|
||||||
'',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
preferredSize: const Size(double.infinity, 1.0),
|
preferredSize: const Size(double.infinity, 1.0),
|
||||||
child: GradientProgressIndicator(progress: model.progress),
|
child: GradientProgressIndicator(progress: model.progress),
|
||||||
@ -96,72 +90,6 @@ class InstallerView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SliverFillRemaining(
|
|
||||||
hasScrollBody: false,
|
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
child: Visibility(
|
|
||||||
visible: !model.isPatching && !model.hasErrors,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0).copyWith(top: 0.0),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
Visibility(
|
|
||||||
visible: model.isInstalled,
|
|
||||||
child: CustomMaterialButton(
|
|
||||||
label: I18nText('installerView.openButton'),
|
|
||||||
isExpanded: true,
|
|
||||||
onPressed: () {
|
|
||||||
model.openApp();
|
|
||||||
model.cleanPatcher();
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: !model.isInstalled && model.isRooted,
|
|
||||||
child: CustomMaterialButton(
|
|
||||||
isFilled: false,
|
|
||||||
label:
|
|
||||||
I18nText('installerView.installRootButton'),
|
|
||||||
isExpanded: true,
|
|
||||||
onPressed: () => model.installResult(
|
|
||||||
context,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: !model.isInstalled,
|
|
||||||
child: const SizedBox(
|
|
||||||
width: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Visibility(
|
|
||||||
visible: !model.isInstalled,
|
|
||||||
child: CustomMaterialButton(
|
|
||||||
label: I18nText('installerView.installButton'),
|
|
||||||
isExpanded: true,
|
|
||||||
onPressed: () => model.installResult(
|
|
||||||
context,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SliverFillRemaining(
|
|
||||||
hasScrollBody: false,
|
|
||||||
child: SizedBox(
|
|
||||||
height: MediaQuery.of(context).viewPadding.bottom,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -169,6 +169,86 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> installTypeDialog(BuildContext context) async {
|
||||||
|
final ValueNotifier<int> installType = ValueNotifier(0);
|
||||||
|
if (isRooted) {
|
||||||
|
await showDialog(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: I18nText(
|
||||||
|
'installerView.installType',
|
||||||
|
),
|
||||||
|
icon: const Icon(Icons.file_download_outlined),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
content: ValueListenableBuilder(
|
||||||
|
valueListenable: installType,
|
||||||
|
builder: (context, value, child) {
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 20, vertical: 10),
|
||||||
|
child: I18nText(
|
||||||
|
'installerView.installTypeDescription',
|
||||||
|
child: Text(
|
||||||
|
'',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
RadioListTile(
|
||||||
|
title: const Text('Non-root'),
|
||||||
|
subtitle: const Text('Recommended'),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
value: 0,
|
||||||
|
groupValue: value,
|
||||||
|
onChanged: (selected) {
|
||||||
|
installType.value = selected!;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
RadioListTile(
|
||||||
|
title: const Text('Root'),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
value: 1,
|
||||||
|
groupValue: value,
|
||||||
|
onChanged: (selected) {
|
||||||
|
installType.value = selected!;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('cancelButton'),
|
||||||
|
isFilled: false,
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
CustomMaterialButton(
|
||||||
|
label: I18nText('installerView.installButton'),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
installResult(context, installType.value == 1);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
installResult(context, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> stopPatcher() async {
|
Future<void> stopPatcher() async {
|
||||||
try {
|
try {
|
||||||
isCanceled = true;
|
isCanceled = true;
|
||||||
@ -253,18 +333,8 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shareResult() {
|
void exportLog() {
|
||||||
try {
|
_patcherAPI.exportPatcherLog(logs);
|
||||||
_patcherAPI.sharePatchedFile(_app.name, _app.version);
|
|
||||||
} on Exception catch (e) {
|
|
||||||
if (kDebugMode) {
|
|
||||||
print(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void shareLog() {
|
|
||||||
_patcherAPI.sharePatcherLog(logs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> cleanPatcher() async {
|
Future<void> cleanPatcher() async {
|
||||||
@ -284,16 +354,13 @@ class InstallerViewModel extends BaseViewModel {
|
|||||||
DeviceApps.openApp(_app.packageName);
|
DeviceApps.openApp(_app.packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onMenuSelection(int value) {
|
void onButtonPressed(int value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 0:
|
case 0:
|
||||||
shareResult();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
exportResult();
|
exportResult();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 1:
|
||||||
shareLog();
|
exportLog();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user