add manual theme installation

This commit is contained in:
julian 2023-05-11 10:33:10 -06:00
parent 0ec891b439
commit ee29025364
2 changed files with 192 additions and 2 deletions

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/install_theme_from_file_dialog.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/appearance_settings/sub_widgets/stack_theme_card.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/themes/stack_colors.dart';
@ -28,6 +29,13 @@ class _ManageThemesViewState extends ConsumerState<ManageThemesView> {
Future<List<StackThemeMetaData>> future = Future(() => []);
void _onInstallPressed() {
showDialog<void>(
context: context,
builder: (context) => const InstallThemeFromFileDialog(),
);
}
@override
void initState() {
_showThemes = ref.read(prefsChangeNotifierProvider).externalCalls;
@ -72,7 +80,7 @@ class _ManageThemesViewState extends ConsumerState<ManageThemesView> {
padding: const EdgeInsets.all(16),
child: SecondaryButton(
label: "Install theme file",
onPressed: () {},
onPressed: _onInstallPressed,
),
),
],
@ -106,7 +114,7 @@ class _ManageThemesViewState extends ConsumerState<ManageThemesView> {
),
SecondaryButton(
label: "Install theme file",
onPressed: () {},
onPressed: _onInstallPressed,
),
const Spacer(),
],

View file

@ -0,0 +1,182 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/themes/theme_service.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/show_loading.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
class InstallThemeFromFileDialog extends ConsumerStatefulWidget {
const InstallThemeFromFileDialog({Key? key}) : super(key: key);
@override
ConsumerState<InstallThemeFromFileDialog> createState() =>
_InstallThemeFromFileDialogState();
}
class _InstallThemeFromFileDialogState
extends ConsumerState<InstallThemeFromFileDialog> {
late final TextEditingController controller;
Future<bool> _install() async {
try {
final fileBytes = await File(controller.text).readAsBytes();
await ref.read(pThemeService).install(
themeArchive: ByteData.view(
fileBytes.buffer,
),
);
return true;
} catch (e, s) {
Logging.instance.log(
"Failed to install theme: $e\n$s",
level: LogLevel.Warning,
);
return false;
}
}
Future<void> _pickFile() async {
try {
final result = await FilePicker.platform.pickFiles(
dialogTitle: "Choose theme file",
type: FileType.custom,
allowedExtensions: ["zip"],
lockParentWindow: true, // windows only
);
if (result != null && mounted) {
setState(() {
controller.text = result.paths.first ?? "";
});
}
} catch (e, s) {
Logging.instance.log("$e\n$s", level: LogLevel.Error);
}
}
@override
void initState() {
controller = TextEditingController();
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return StackDialogBase(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Install theme file",
style: STextStyles.pageTitleH2(context),
),
const SizedBox(
height: 12,
),
TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
onTap: _pickFile,
controller: controller,
style: STextStyles.field(context),
decoration: InputDecoration(
hintText: "Choose file...",
hintStyle: STextStyles.fieldLabel(context),
suffixIcon: UnconstrainedBox(
child: Row(
children: [
const SizedBox(
width: 16,
),
SvgPicture.asset(
Assets.svg.folder,
color:
Theme.of(context).extension<StackColors>()!.textDark3,
width: 16,
height: 16,
),
const SizedBox(
width: 12,
),
],
),
),
),
readOnly: true,
),
const SizedBox(
height: 20,
),
Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed: Navigator.of(context).pop,
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Install",
enabled: controller.text.isNotEmpty,
onPressed: () async {
final result = await showLoading(
whileFuture: _install(),
context: context,
message: "Installing ${controller.text}...",
);
if (mounted) {
Navigator.of(context).pop();
if (!result) {
unawaited(
showDialog(
context: context,
builder: (_) => StackOkDialog(
title: "Failed to install theme:",
message: controller.text,
),
),
);
} else {
unawaited(
showDialog(
context: context,
builder: (_) => const StackOkDialog(
title: "Theme install succeeded!",
),
),
);
}
}
},
),
),
],
)
],
),
);
}
}