mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-10 20:54:33 +00:00
desktop wallet renaming
This commit is contained in:
parent
32eb9bb920
commit
c9220c5c11
3 changed files with 236 additions and 53 deletions
|
@ -43,6 +43,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
|
|||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
|
||||
import 'package:stackwallet/widgets/hover_text_field.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||
import 'package:stackwallet/widgets/stack_text_field.dart';
|
||||
|
@ -66,6 +67,7 @@ class DesktopWalletView extends ConsumerStatefulWidget {
|
|||
}
|
||||
|
||||
class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||
late final TextEditingController controller;
|
||||
late final String walletId;
|
||||
late final EventBus eventBus;
|
||||
|
||||
|
@ -179,10 +181,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
controller = TextEditingController();
|
||||
walletId = widget.walletId;
|
||||
final managerProvider =
|
||||
ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
|
||||
|
||||
controller.text = ref.read(managerProvider).walletName;
|
||||
|
||||
eventBus =
|
||||
widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
|
||||
|
||||
|
@ -211,61 +216,110 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
|||
return DesktopScaffold(
|
||||
appBar: DesktopAppBar(
|
||||
background: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||
leading: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
AppBarIconButton(
|
||||
size: 32,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldDefaultBG,
|
||||
shadows: const [],
|
||||
icon: SvgPicture.asset(
|
||||
Assets.svg.arrowLeft,
|
||||
width: 18,
|
||||
height: 18,
|
||||
leading: Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
AppBarIconButton(
|
||||
size: 32,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.topNavIconPrimary,
|
||||
.textFieldDefaultBG,
|
||||
shadows: const [],
|
||||
icon: SvgPicture.asset(
|
||||
Assets.svg.arrowLeft,
|
||||
width: 18,
|
||||
height: 18,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.topNavIconPrimary,
|
||||
),
|
||||
onPressed: onBackPressed,
|
||||
),
|
||||
onPressed: onBackPressed,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
SvgPicture.asset(
|
||||
Assets.svg.iconFor(coin: coin),
|
||||
width: 32,
|
||||
height: 32,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Text(
|
||||
manager.walletName,
|
||||
style: STextStyles.desktopH3(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: Row(
|
||||
children: [
|
||||
NetworkInfoButton(
|
||||
walletId: walletId,
|
||||
eventBus: eventBus,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
WalletKeysButton(
|
||||
walletId: walletId,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
],
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
SvgPicture.asset(
|
||||
Assets.svg.iconFor(coin: coin),
|
||||
width: 32,
|
||||
height: 32,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 48,
|
||||
),
|
||||
child: IntrinsicWidth(
|
||||
child: HoverTextField(
|
||||
controller: controller,
|
||||
style: STextStyles.desktopH3(context),
|
||||
readOnly: true,
|
||||
onDone: () async {
|
||||
final currentWalletName =
|
||||
ref.read(managerProvider).walletName;
|
||||
final newName = controller.text;
|
||||
if (newName != currentWalletName) {
|
||||
final success = await ref
|
||||
.read(walletsServiceChangeNotifierProvider)
|
||||
.renameWallet(
|
||||
from: currentWalletName,
|
||||
to: newName,
|
||||
shouldNotifyListeners: true,
|
||||
);
|
||||
if (success) {
|
||||
ref
|
||||
.read(walletsChangeNotifierProvider)
|
||||
.getManager(walletId)
|
||||
.walletName = newName;
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.success,
|
||||
message: "Wallet renamed",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.warning,
|
||||
message:
|
||||
"Wallet named \"$newName\" already exists",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
controller.text = currentWalletName;
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
NetworkInfoButton(
|
||||
walletId: walletId,
|
||||
eventBus: eventBus,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
WalletKeysButton(
|
||||
walletId: walletId,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 32,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
useSpacers: false,
|
||||
isCompactHeight: true,
|
||||
),
|
||||
body: Padding(
|
||||
|
|
|
@ -11,6 +11,7 @@ class DesktopAppBar extends StatefulWidget {
|
|||
this.trailing,
|
||||
this.background = Colors.transparent,
|
||||
required this.isCompactHeight,
|
||||
this.useSpacers = true,
|
||||
}) : super(key: key);
|
||||
|
||||
final Widget? leading;
|
||||
|
@ -18,6 +19,7 @@ class DesktopAppBar extends StatefulWidget {
|
|||
final Widget? trailing;
|
||||
final Color background;
|
||||
final bool isCompactHeight;
|
||||
final bool useSpacers;
|
||||
|
||||
@override
|
||||
State<DesktopAppBar> createState() => _DesktopAppBarState();
|
||||
|
@ -33,11 +35,15 @@ class _DesktopAppBarState extends State<DesktopAppBar> {
|
|||
items.add(widget.leading!);
|
||||
}
|
||||
|
||||
items.add(const Spacer());
|
||||
if (widget.useSpacers) {
|
||||
items.add(const Spacer());
|
||||
}
|
||||
|
||||
if (widget.center != null) {
|
||||
items.add(widget.center!);
|
||||
items.add(const Spacer());
|
||||
if (widget.useSpacers) {
|
||||
items.add(const Spacer());
|
||||
}
|
||||
}
|
||||
|
||||
if (widget.trailing != null) {
|
||||
|
|
123
lib/widgets/hover_text_field.dart
Normal file
123
lib/widgets/hover_text_field.dart
Normal file
|
@ -0,0 +1,123 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:stackwallet/utilities/constants.dart';
|
||||
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
|
||||
class HoverTextField extends StatefulWidget {
|
||||
const HoverTextField({
|
||||
Key? key,
|
||||
this.controller,
|
||||
this.focusNode,
|
||||
this.readOnly = false,
|
||||
this.enabled,
|
||||
this.onTap,
|
||||
this.onChanged,
|
||||
this.onEditingComplete,
|
||||
this.style,
|
||||
this.onDone,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextEditingController? controller;
|
||||
final FocusNode? focusNode;
|
||||
final bool readOnly;
|
||||
final bool? enabled;
|
||||
final GestureTapCallback? onTap;
|
||||
final ValueChanged<String>? onChanged;
|
||||
final VoidCallback? onEditingComplete;
|
||||
final TextStyle? style;
|
||||
final VoidCallback? onDone;
|
||||
|
||||
@override
|
||||
State<HoverTextField> createState() => _HoverTextFieldState();
|
||||
}
|
||||
|
||||
class _HoverTextFieldState extends State<HoverTextField> {
|
||||
late final TextEditingController? controller;
|
||||
late final FocusNode? focusNode;
|
||||
late bool readOnly;
|
||||
late bool? enabled;
|
||||
late final GestureTapCallback? onTap;
|
||||
late final ValueChanged<String>? onChanged;
|
||||
late final VoidCallback? onEditingComplete;
|
||||
late final TextStyle? style;
|
||||
late final VoidCallback? onDone;
|
||||
|
||||
final InputBorder inputBorder = OutlineInputBorder(
|
||||
borderSide: const BorderSide(
|
||||
width: 0,
|
||||
color: Colors.transparent,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(Constants.size.circularBorderRadius),
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
controller = widget.controller;
|
||||
focusNode = widget.focusNode ?? FocusNode();
|
||||
readOnly = widget.readOnly;
|
||||
enabled = widget.enabled;
|
||||
onChanged = widget.onChanged;
|
||||
style = widget.style;
|
||||
onTap = widget.onTap;
|
||||
onEditingComplete = widget.onEditingComplete;
|
||||
onDone = widget.onDone;
|
||||
|
||||
focusNode!.addListener(() {
|
||||
if (!focusNode!.hasPrimaryFocus && !readOnly) {
|
||||
setState(() {
|
||||
readOnly = true;
|
||||
});
|
||||
onDone?.call();
|
||||
}
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
controller?.dispose();
|
||||
focusNode?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextField(
|
||||
autocorrect: !Util.isDesktop,
|
||||
enableSuggestions: !Util.isDesktop,
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
readOnly: readOnly,
|
||||
enabled: enabled,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
readOnly = false;
|
||||
});
|
||||
onTap?.call();
|
||||
},
|
||||
onChanged: onChanged,
|
||||
onEditingComplete: () {
|
||||
setState(() {
|
||||
readOnly = true;
|
||||
});
|
||||
onEditingComplete?.call();
|
||||
onDone?.call();
|
||||
},
|
||||
style: style,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 12,
|
||||
),
|
||||
border: inputBorder,
|
||||
focusedBorder: inputBorder,
|
||||
disabledBorder: inputBorder,
|
||||
enabledBorder: inputBorder,
|
||||
errorBorder: inputBorder,
|
||||
fillColor: readOnly
|
||||
? Colors.transparent
|
||||
: Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue