paynym desktop add new follow popup layout

This commit is contained in:
julian 2023-01-04 12:32:40 -06:00
parent a6cc955090
commit 97d3b35a22
2 changed files with 280 additions and 138 deletions

View file

@ -14,12 +14,16 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
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/paynym_search_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/loading_indicator.dart'; import 'package:stackwallet/widgets/loading_indicator.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart'; import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart'; import 'package:stackwallet/widgets/textfield_icon_button.dart';
@ -49,6 +53,8 @@ class _AddNewPaynymFollowViewState
bool _didSearch = false; bool _didSearch = false;
PaynymAccount? _searchResult; PaynymAccount? _searchResult;
final isDesktop = Util.isDesktop;
Future<void> _search() async { Future<void> _search() async {
_didSearch = true; _didSearch = true;
bool didPopLoading = false; bool didPopLoading = false;
@ -75,6 +81,60 @@ class _AddNewPaynymFollowViewState
} }
} }
Future<void> _clear() async {
_searchString = "";
setState(() {
_searchController.text = "";
});
}
Future<void> _paste() async {
final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
if (data?.text != null && data!.text!.isNotEmpty) {
String content = data.text!.trim();
if (content.contains("\n")) {
content = content.substring(
0,
content.indexOf(
"\n",
),
);
}
_searchString = content;
setState(() {
_searchController.text = content;
_searchController.selection = TextSelection.collapsed(
offset: content.length,
);
});
}
}
Future<void> _scanQr() async {
try {
if (!isDesktop && FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 75));
}
final qrResult = await const BarcodeScannerWrapper().scan();
final pCodeString = qrResult.rawContent;
_searchString = pCodeString;
setState(() {
_searchController.text = pCodeString;
_searchController.selection = TextSelection.collapsed(
offset: pCodeString.length,
);
});
} catch (_) {
// scan failed
}
}
@override @override
void initState() { void initState() {
_searchController = TextEditingController(); _searchController = TextEditingController();
@ -92,9 +152,10 @@ class _AddNewPaynymFollowViewState
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final isDesktop = Util.isDesktop;
return MasterScaffold( return ConditionalParent(
condition: !isDesktop,
builder: (child) => MasterScaffold(
isDesktop: isDesktop, isDesktop: isDesktop,
appBar: AppBar( appBar: AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
@ -109,9 +170,7 @@ class _AddNewPaynymFollowViewState
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
body: ConditionalParent( body: SafeArea(
condition: !isDesktop,
builder: (child) => SafeArea(
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView( builder: (context, constraints) => SingleChildScrollView(
child: ConstrainedBox( child: ConstrainedBox(
@ -119,14 +178,47 @@ class _AddNewPaynymFollowViewState
minHeight: constraints.maxHeight, minHeight: constraints.maxHeight,
), ),
child: IntrinsicHeight( child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(16),
child: child, child: child,
), ),
), ),
), ),
), ),
), ),
child: Padding( ),
padding: const EdgeInsets.all(16), ),
child: ConditionalParent(
condition: isDesktop,
builder: (child) => DesktopDialog(
maxWidth: 580,
maxHeight: double.infinity,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(left: 32),
child: Text(
"Add new",
style: STextStyles.desktopH3(context),
),
),
const DesktopDialogCloseButton(),
],
),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
bottom: 32,
),
child: child,
),
],
),
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -135,7 +227,9 @@ class _AddNewPaynymFollowViewState
), ),
Text( Text(
"Featured PayNyms", "Featured PayNyms",
style: STextStyles.sectionLabelMedium12(context), style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.sectionLabelMedium12(context),
), ),
const SizedBox( const SizedBox(
height: 12, height: 12,
@ -148,11 +242,119 @@ class _AddNewPaynymFollowViewState
), ),
Text( Text(
"Add new", "Add new",
style: STextStyles.sectionLabelMedium12(context), style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.sectionLabelMedium12(context),
), ),
const SizedBox( const SizedBox(
height: 12, height: 12,
), ),
if (isDesktop)
Row(
children: [
Expanded(
child: Stack(
children: [
RoundedContainer(
padding: const EdgeInsets.all(0),
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
height: 56,
child: Center(
child: TextField(
autocorrect: !isDesktop,
enableSuggestions: !isDesktop,
controller: _searchController,
focusNode: searchFieldFocusNode,
onChanged: (value) {
setState(() {
_searchString = value;
});
},
style: STextStyles.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveText,
// height: 1.8,
),
decoration: InputDecoration(
hintText: "Paste payment code",
hoverColor: Colors.transparent,
fillColor: Colors.transparent,
contentPadding: const EdgeInsets.all(16),
hintStyle:
STextStyles.desktopTextFieldLabel(context)
.copyWith(
fontSize: 14,
),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
focusedErrorBorder: InputBorder.none,
suffixIcon: Padding(
padding: const EdgeInsets.only(right: 8),
child: UnconstrainedBox(
child: Row(
children: [
_searchController.text.isNotEmpty
? TextFieldIconButton(
onTap: _clear,
child: RoundedContainer(
padding:
const EdgeInsets.all(8),
color: Theme.of(context)
.extension<StackColors>()!
.buttonBackSecondary,
child: const XIcon(),
),
)
: TextFieldIconButton(
key: const Key(
"paynymPasteAddressFieldButtonKey"),
onTap: _paste,
child: RoundedContainer(
padding:
const EdgeInsets.all(8),
color: Theme.of(context)
.extension<StackColors>()!
.buttonBackSecondary,
child: const ClipboardIcon(),
),
),
TextFieldIconButton(
key: const Key(
"paynymScanQrButtonKey"),
onTap: _scanQr,
child: RoundedContainer(
padding: const EdgeInsets.all(8),
color: Theme.of(context)
.extension<StackColors>()!
.buttonBackSecondary,
child: const QrCodeIcon(),
),
)
],
),
),
),
),
),
),
),
],
),
),
const SizedBox(
width: 10,
),
PaynymSearchButton(onPressed: _search),
],
),
if (!isDesktop)
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
@ -167,14 +369,7 @@ class _AddNewPaynymFollowViewState
_searchString = value; _searchString = value;
}); });
}, },
style: isDesktop style: STextStyles.field(context),
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveText,
height: 1.8,
)
: STextStyles.field(context),
decoration: standardInputDecoration( decoration: standardInputDecoration(
"Paste payment code", "Paste payment code",
searchFieldFocusNode, searchFieldFocusNode,
@ -188,74 +383,18 @@ class _AddNewPaynymFollowViewState
children: [ children: [
_searchController.text.isNotEmpty _searchController.text.isNotEmpty
? TextFieldIconButton( ? TextFieldIconButton(
onTap: _clear,
child: const XIcon(), child: const XIcon(),
onTap: () async {
_searchString = "";
setState(() {
_searchController.text = "";
});
},
) )
: TextFieldIconButton( : TextFieldIconButton(
key: const Key( key: const Key(
"paynymPasteAddressFieldButtonKey"), "paynymPasteAddressFieldButtonKey"),
onTap: () async { onTap: _paste,
final ClipboardData? data =
await Clipboard.getData(
Clipboard.kTextPlain);
if (data?.text != null &&
data!.text!.isNotEmpty) {
String content = data.text!.trim();
if (content.contains("\n")) {
content = content.substring(
0,
content.indexOf(
"\n",
),
);
}
_searchString = content;
setState(() {
_searchController.text = content;
_searchController.selection =
TextSelection.collapsed(
offset: content.length,
);
});
}
},
child: const ClipboardIcon(), child: const ClipboardIcon(),
), ),
TextFieldIconButton( TextFieldIconButton(
key: const Key("paynymScanQrButtonKey"), key: const Key("paynymScanQrButtonKey"),
onTap: () async { onTap: _scanQr,
try {
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(
const Duration(milliseconds: 75));
}
final qrResult =
await const BarcodeScannerWrapper()
.scan();
final pCodeString = qrResult.rawContent;
_searchString = pCodeString;
setState(() {
_searchController.text = pCodeString;
_searchController.selection =
TextSelection.collapsed(
offset: pCodeString.length,
);
});
} catch (_) {
// scan failed
}
},
child: const QrCodeIcon(), child: const QrCodeIcon(),
) )
], ],
@ -265,9 +404,11 @@ class _AddNewPaynymFollowViewState
), ),
), ),
), ),
if (!isDesktop)
const SizedBox( const SizedBox(
height: 12, height: 12,
), ),
if (!isDesktop)
SecondaryButton( SecondaryButton(
label: "Search", label: "Search",
onPressed: _search, onPressed: _search,
@ -300,7 +441,6 @@ class _AddNewPaynymFollowViewState
], ],
), ),
), ),
),
); );
} }
} }

View file

@ -108,9 +108,11 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> {
cursor: SystemMouseCursors.click, cursor: SystemMouseCursors.click,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
Navigator.of(context).pushNamed( showDialog<void>(
AddNewPaynymFollowView.routeName, context: context,
arguments: widget.walletId, builder: (context) => AddNewPaynymFollowView(
walletId: widget.walletId,
),
); );
}, },
child: Container( child: Container(
@ -134,7 +136,7 @@ class _PaynymHomeViewState extends ConsumerState<PaynymHomeView> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
"Follow", "Add new",
style: style:
STextStyles.desktopButtonSecondaryEnabled( STextStyles.desktopButtonSecondaryEnabled(
context) context)