mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-02-04 04:06:38 +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/desktop_scaffold.dart';
|
||||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||||
import 'package:stackwallet/widgets/desktop/secondary_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/rounded_white_container.dart';
|
||||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||||
import 'package:stackwallet/widgets/stack_text_field.dart';
|
import 'package:stackwallet/widgets/stack_text_field.dart';
|
||||||
|
@ -66,6 +67,7 @@ class DesktopWalletView extends ConsumerStatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
|
late final TextEditingController controller;
|
||||||
late final String walletId;
|
late final String walletId;
|
||||||
late final EventBus eventBus;
|
late final EventBus eventBus;
|
||||||
|
|
||||||
|
@ -179,10 +181,13 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
controller = TextEditingController();
|
||||||
walletId = widget.walletId;
|
walletId = widget.walletId;
|
||||||
final managerProvider =
|
final managerProvider =
|
||||||
ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
|
ref.read(walletsChangeNotifierProvider).getManagerProvider(walletId);
|
||||||
|
|
||||||
|
controller.text = ref.read(managerProvider).walletName;
|
||||||
|
|
||||||
eventBus =
|
eventBus =
|
||||||
widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
|
widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance;
|
||||||
|
|
||||||
|
@ -211,7 +216,8 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
return DesktopScaffold(
|
return DesktopScaffold(
|
||||||
appBar: DesktopAppBar(
|
appBar: DesktopAppBar(
|
||||||
background: Theme.of(context).extension<StackColors>()!.popupBG,
|
background: Theme.of(context).extension<StackColors>()!.popupBG,
|
||||||
leading: Row(
|
leading: Expanded(
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 32,
|
width: 32,
|
||||||
|
@ -243,13 +249,57 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
width: 12,
|
width: 12,
|
||||||
),
|
),
|
||||||
Text(
|
ConstrainedBox(
|
||||||
manager.walletName,
|
constraints: const BoxConstraints(
|
||||||
|
minWidth: 48,
|
||||||
|
),
|
||||||
|
child: IntrinsicWidth(
|
||||||
|
child: HoverTextField(
|
||||||
|
controller: controller,
|
||||||
style: STextStyles.desktopH3(context),
|
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,
|
||||||
),
|
),
|
||||||
trailing: Row(
|
);
|
||||||
|
controller.text = currentWalletName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Spacer(),
|
||||||
|
Row(
|
||||||
children: [
|
children: [
|
||||||
NetworkInfoButton(
|
NetworkInfoButton(
|
||||||
walletId: walletId,
|
walletId: walletId,
|
||||||
|
@ -266,6 +316,10 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
useSpacers: false,
|
||||||
isCompactHeight: true,
|
isCompactHeight: true,
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
|
|
|
@ -11,6 +11,7 @@ class DesktopAppBar extends StatefulWidget {
|
||||||
this.trailing,
|
this.trailing,
|
||||||
this.background = Colors.transparent,
|
this.background = Colors.transparent,
|
||||||
required this.isCompactHeight,
|
required this.isCompactHeight,
|
||||||
|
this.useSpacers = true,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final Widget? leading;
|
final Widget? leading;
|
||||||
|
@ -18,6 +19,7 @@ class DesktopAppBar extends StatefulWidget {
|
||||||
final Widget? trailing;
|
final Widget? trailing;
|
||||||
final Color background;
|
final Color background;
|
||||||
final bool isCompactHeight;
|
final bool isCompactHeight;
|
||||||
|
final bool useSpacers;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DesktopAppBar> createState() => _DesktopAppBarState();
|
State<DesktopAppBar> createState() => _DesktopAppBarState();
|
||||||
|
@ -33,12 +35,16 @@ class _DesktopAppBarState extends State<DesktopAppBar> {
|
||||||
items.add(widget.leading!);
|
items.add(widget.leading!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (widget.useSpacers) {
|
||||||
items.add(const Spacer());
|
items.add(const Spacer());
|
||||||
|
}
|
||||||
|
|
||||||
if (widget.center != null) {
|
if (widget.center != null) {
|
||||||
items.add(widget.center!);
|
items.add(widget.center!);
|
||||||
|
if (widget.useSpacers) {
|
||||||
items.add(const Spacer());
|
items.add(const Spacer());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (widget.trailing != null) {
|
if (widget.trailing != null) {
|
||||||
items.add(widget.trailing!);
|
items.add(widget.trailing!);
|
||||||
|
|
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