mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-10 12:44:31 +00:00
add manual theme installation
This commit is contained in:
parent
0ec891b439
commit
ee29025364
2 changed files with 192 additions and 2 deletions
|
@ -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(),
|
||||
],
|
||||
|
|
|
@ -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!",
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue