Merge pull request #201 from cypherstack/desktop

Desktop
This commit is contained in:
Diego Salazar 2022-11-03 19:40:52 -06:00 committed by GitHub
commit fe44b14453
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1970 additions and 1740 deletions

View file

@ -7,13 +7,17 @@ import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.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/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/rounded_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';
import 'package:stackwallet/utilities/util.dart'; import '../../../widgets/rounded_white_container.dart';
class BaseCurrencySettingsView extends ConsumerStatefulWidget { class BaseCurrencySettingsView extends ConsumerStatefulWidget {
const BaseCurrencySettingsView({Key? key}) : super(key: key); const BaseCurrencySettingsView({Key? key}) : super(key: key);
@ -102,8 +106,14 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
currenciesWithoutSelected.insert(0, current); currenciesWithoutSelected.insert(0, current);
} }
currenciesWithoutSelected = _filtered(); currenciesWithoutSelected = _filtered();
final isDesktop = Util.isDesktop;
return ConditionalParent(
condition: !isDesktop,
builder: (child) {
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background, backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar( appBar: AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
onPressed: () async { onPressed: () async {
@ -127,6 +137,59 @@ class _CurrencyViewState extends ConsumerState<BaseCurrencySettingsView> {
left: 16, left: 16,
right: 16, right: 16,
), ),
child: child,
),
);
},
child: ConditionalParent(
condition: isDesktop,
builder: (child) {
return Padding(
padding: const EdgeInsets.only(
top: 16,
bottom: 32,
left: 32,
right: 32,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: RoundedWhiteContainer(
padding: const EdgeInsets.all(20),
borderColor:
Theme.of(context).extension<StackColors>()!.background,
child: child,
),
),
const SizedBox(
height: 16,
),
Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
desktopMed: true,
onPressed: Navigator.of(context).pop,
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Save changes",
desktopMed: true,
onPressed: Navigator.of(context).pop,
),
),
],
),
],
),
);
},
child: NestedScrollView( child: NestedScrollView(
floatHeaderSlivers: true, floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) { headerSliverBuilder: (context, innerBoxIsScrolled) {

View file

@ -8,7 +8,6 @@ import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart';
import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/providers/global/node_service_provider.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
@ -20,15 +19,18 @@ import 'package:stackwallet/utilities/test_epic_box_connection.dart';
import 'package:stackwallet/utilities/test_monero_node_connection.dart'; import 'package:stackwallet/utilities/test_monero_node_connection.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.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/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.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';
import 'package:stackwallet/widgets/textfield_icon_button.dart'; import 'package:stackwallet/widgets/textfield_icon_button.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
import 'package:stackwallet/utilities/util.dart';
enum AddEditNodeViewType { add, edit } enum AddEditNodeViewType { add, edit }
class AddEditNodeView extends ConsumerStatefulWidget { class AddEditNodeView extends ConsumerStatefulWidget {
@ -59,6 +61,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
late final AddEditNodeViewType viewType; late final AddEditNodeViewType viewType;
late final Coin coin; late final Coin coin;
late final String? nodeId; late final String? nodeId;
late final bool isDesktop;
late bool saveEnabled; late bool saveEnabled;
late bool testConnectionEnabled; late bool testConnectionEnabled;
@ -162,8 +165,198 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
return testPassed; return testPassed;
} }
Future<void> attemptSave() async {
final canConnect = await _testConnection(showFlushBar: false);
bool? shouldSave;
if (!canConnect) {
await showDialog<dynamic>(
context: context,
useSafeArea: true,
barrierDismissible: true,
builder: (_) => isDesktop
? DesktopDialog(
maxWidth: 440,
maxHeight: 300,
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(
top: 32,
),
child: Row(
children: [
const SizedBox(
width: 32,
),
Text(
"Server currently unreachable",
style: STextStyles.desktopH3(context),
),
],
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
top: 16,
bottom: 32,
),
child: Column(
children: [
const Spacer(),
Text(
"Would you like to save this node anyways?",
style: STextStyles.desktopTextMedium(context),
),
const Spacer(
flex: 2,
),
Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
desktopMed: true,
onPressed: () => Navigator.of(
context,
rootNavigator: true,
).pop(false),
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Save",
desktopMed: true,
onPressed: () => Navigator.of(
context,
rootNavigator: true,
).pop(true),
),
),
],
),
],
),
),
),
],
),
)
: StackDialog(
title: "Server currently unreachable",
message: "Would you like to save this node anyways?",
leftButton: TextButton(
onPressed: () async {
Navigator.of(context).pop(false);
},
child: Text(
"Cancel",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
),
),
rightButton: TextButton(
onPressed: () async {
Navigator.of(context).pop(true);
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
child: Text(
"Save",
style: STextStyles.button(context),
),
),
),
).then((value) {
if (value is bool && value) {
shouldSave = true;
} else {
shouldSave = false;
}
});
}
if (!canConnect && !shouldSave!) {
// return without saving
return;
}
final formData = ref.read(nodeFormDataProvider);
// strip unused path
String address = formData.host!;
if (coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash) {
if (address.startsWith("http")) {
final uri = Uri.parse(address);
address = "${uri.scheme}://${uri.host}";
}
}
switch (viewType) {
case AddEditNodeViewType.add:
NodeModel node = NodeModel(
host: address,
port: formData.port!,
name: formData.name!,
id: const Uuid().v1(),
useSSL: formData.useSSL!,
loginName: formData.login,
enabled: true,
coinName: coin.name,
isFailover: formData.isFailover!,
isDown: false,
);
await ref.read(nodeServiceChangeNotifierProvider).add(
node,
formData.password,
true,
);
if (mounted) {
Navigator.of(context)
.popUntil(ModalRoute.withName(widget.routeOnSuccessOrDelete));
}
break;
case AddEditNodeViewType.edit:
NodeModel node = NodeModel(
host: address,
port: formData.port!,
name: formData.name!,
id: nodeId!,
useSSL: formData.useSSL!,
loginName: formData.login,
enabled: true,
coinName: coin.name,
isFailover: formData.isFailover!,
isDown: false,
);
await ref.read(nodeServiceChangeNotifierProvider).add(
node,
formData.password,
true,
);
if (mounted) {
Navigator.of(context)
.popUntil(ModalRoute.withName(widget.routeOnSuccessOrDelete));
}
break;
}
}
@override @override
void initState() { void initState() {
isDesktop = Util.isDesktop;
ref.refresh(nodeFormDataProvider); ref.refresh(nodeFormDataProvider);
viewType = widget.viewType; viewType = widget.viewType;
@ -196,7 +389,9 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
.select((value) => value.getNodeById(id: nodeId!))) .select((value) => value.getNodeById(id: nodeId!)))
: null; : null;
return Scaffold( return ConditionalParent(
condition: !isDesktop,
builder: (child) => Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background, backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar( appBar: AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
@ -228,7 +423,8 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
key: const Key("deleteNodeAppBarButtonKey"), key: const Key("deleteNodeAppBarButtonKey"),
size: 36, size: 36,
shadows: const [], shadows: const [],
color: Theme.of(context).extension<StackColors>()!.background, color:
Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset( icon: SvgPicture.asset(
Assets.svg.trash, Assets.svg.trash,
color: Theme.of(context) color: Theme.of(context)
@ -267,6 +463,49 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
constraints: constraints:
BoxConstraints(minHeight: constraints.maxHeight - 8), BoxConstraints(minHeight: constraints.maxHeight - 8),
child: IntrinsicHeight( child: IntrinsicHeight(
child: child,
),
),
),
);
},
),
),
),
child: ConditionalParent(
condition: isDesktop,
builder: (child) => DesktopDialog(
maxWidth: 580,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
const SizedBox(
width: 8,
),
const AppBarBackButton(
iconSize: 24,
size: 40,
),
Text(
"Add new node",
style: STextStyles.desktopH3(context),
)
],
),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
top: 16,
bottom: 32,
),
child: child,
),
],
),
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
@ -293,30 +532,45 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
} }
}, },
), ),
const Spacer(), if (!isDesktop) const Spacer(),
TextButton( if (isDesktop)
const SizedBox(
height: 78,
),
Row(
children: [
Expanded(
child: SecondaryButton(
label: "Test connection",
enabled: testConnectionEnabled,
desktopMed: true,
onPressed: testConnectionEnabled onPressed: testConnectionEnabled
? () async { ? () async {
await _testConnection(); await _testConnection();
} }
: null, : null,
style: Theme.of(context)
.extension<StackColors>()!
.getSecondaryEnabledButtonColor(context),
child: Text(
"Test connection",
style: STextStyles.button(context).copyWith(
color: testConnectionEnabled
? Theme.of(context)
.extension<StackColors>()!
.textDark
: Theme.of(context)
.extension<StackColors>()!
.textWhite,
), ),
), ),
if (isDesktop)
const SizedBox(
width: 16,
), ),
const SizedBox(height: 16), if (isDesktop)
Expanded(
child: PrimaryButton(
label: "Save",
enabled: saveEnabled,
desktopMed: true,
onPressed: saveEnabled ? attemptSave : null,
),
),
],
),
if (!isDesktop)
const SizedBox(
height: 16,
),
if (!isDesktop)
TextButton( TextButton(
style: saveEnabled style: saveEnabled
? Theme.of(context) ? Theme.of(context)
@ -325,138 +579,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
: Theme.of(context) : Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.getPrimaryDisabledButtonColor(context), .getPrimaryDisabledButtonColor(context),
onPressed: saveEnabled onPressed: saveEnabled ? attemptSave : null,
? () async {
final canConnect = await _testConnection(
showFlushBar: false);
bool? shouldSave;
if (!canConnect) {
await showDialog<dynamic>(
context: context,
useSafeArea: true,
barrierDismissible: true,
builder: (_) => StackDialog(
title: "Server currently unreachable",
message:
"Would you like to save this node anyways?",
leftButton: TextButton(
onPressed: () async {
Navigator.of(context).pop(false);
},
child: Text(
"Cancel",
style: STextStyles.button(context)
.copyWith(
color: Theme.of(context)
.extension<
StackColors>()!
.accentColorDark),
),
),
rightButton: TextButton(
onPressed: () async {
Navigator.of(context).pop(true);
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(
context),
child: Text(
"Save",
style: STextStyles.button(context),
),
),
),
).then((value) {
if (value is bool && value) {
shouldSave = true;
} else {
shouldSave = false;
}
});
}
if (!canConnect && !shouldSave!) {
// return without saving
return;
}
final formData =
ref.read(nodeFormDataProvider);
// strip unused path
String address = formData.host!;
if (coin == Coin.monero ||
coin == Coin.wownero ||
coin == Coin.epicCash) {
if (address.startsWith("http")) {
final uri = Uri.parse(address);
address = "${uri.scheme}://${uri.host}";
}
}
switch (viewType) {
case AddEditNodeViewType.add:
NodeModel node = NodeModel(
host: address,
port: formData.port!,
name: formData.name!,
id: const Uuid().v1(),
useSSL: formData.useSSL!,
loginName: formData.login,
enabled: true,
coinName: coin.name,
isFailover: formData.isFailover!,
isDown: false,
);
await ref
.read(
nodeServiceChangeNotifierProvider)
.add(
node,
formData.password,
true,
);
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(
widget.routeOnSuccessOrDelete));
}
break;
case AddEditNodeViewType.edit:
NodeModel node = NodeModel(
host: address,
port: formData.port!,
name: formData.name!,
id: nodeId!,
useSSL: formData.useSSL!,
loginName: formData.login,
enabled: true,
coinName: coin.name,
isFailover: formData.isFailover!,
isDown: false,
);
await ref
.read(
nodeServiceChangeNotifierProvider)
.add(
node,
formData.password,
true,
);
if (mounted) {
Navigator.of(context).popUntil(
ModalRoute.withName(
widget.routeOnSuccessOrDelete));
}
break;
}
}
: null,
child: Text( child: Text(
"Save", "Save",
style: STextStyles.button(context), style: STextStyles.button(context),
@ -465,12 +588,6 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
], ],
), ),
), ),
),
),
);
},
),
),
); );
} }
} }

View file

@ -9,6 +9,7 @@ import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.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/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.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_dialog_close_button.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -17,11 +18,13 @@ class CoinNodesView extends ConsumerStatefulWidget {
const CoinNodesView({ const CoinNodesView({
Key? key, Key? key,
required this.coin, required this.coin,
this.rootNavigator = false,
}) : super(key: key); }) : super(key: key);
static const String routeName = "/coinNodes"; static const String routeName = "/coinNodes";
final Coin coin; final Coin coin;
final bool rootNavigator;
@override @override
ConsumerState<CoinNodesView> createState() => _CoinNodesViewState(); ConsumerState<CoinNodesView> createState() => _CoinNodesViewState();
@ -63,12 +66,17 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
Expanded( Expanded(
child: const DesktopDialogCloseButton(), child: DesktopDialogCloseButton(
onPressedOverride: Navigator.of(
context,
rootNavigator: widget.rootNavigator,
).pop,
),
), ),
], ],
), ),
Padding( Padding(
padding: EdgeInsets.only( padding: const EdgeInsets.only(
left: 32, left: 32,
right: 32, right: 32,
), ),
@ -83,14 +91,19 @@ class _CoinNodesViewState extends ConsumerState<CoinNodesView> {
), ),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
RichText( BlueTextButton(
text: TextSpan( text: "Add new node",
text: 'Add new nodes', onTap: () {
style: Navigator.of(context).pushNamed(
STextStyles.desktopTextExtraSmall(context).copyWith( AddEditNodeView.routeName,
color: Colors.blueAccent, arguments: Tuple4(
), AddEditNodeViewType.add,
widget.coin,
null,
CoinNodesView.routeName,
), ),
);
},
), ),
], ],
), ),

View file

@ -17,7 +17,13 @@ import 'package:stackwallet/utilities/test_epic_box_connection.dart';
import 'package:stackwallet/utilities/test_monero_node_connection.dart'; import 'package:stackwallet/utilities/test_monero_node_connection.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.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/delete_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class NodeDetailsView extends ConsumerStatefulWidget { class NodeDetailsView extends ConsumerStatefulWidget {
@ -48,6 +54,8 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
late final String nodeId; late final String nodeId;
late final String popRouteName; late final String popRouteName;
bool _desktopReadOnly = true;
@override @override
initState() { initState() {
secureStore = widget.secureStore; secureStore = widget.secureStore;
@ -126,23 +134,34 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
} }
if (testPassed) { if (testPassed) {
unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.success, type: FlushBarType.success,
message: "Server ping success", message: "Server ping success",
context: context, context: context,
),
); );
} else { } else {
unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.warning, type: FlushBarType.warning,
message: "Server unreachable", message: "Server unreachable",
context: context, context: context,
),
); );
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( final isDesktop = Util.isDesktop;
final node = ref.watch(nodeServiceChangeNotifierProvider
.select((value) => value.getNodeById(id: nodeId)));
return ConditionalParent(
condition: !isDesktop,
builder: (child) => Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background, backgroundColor: Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar( appBar: AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
@ -174,7 +193,8 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
key: const Key("nodeDetailsEditNodeAppBarButtonKey"), key: const Key("nodeDetailsEditNodeAppBarButtonKey"),
size: 36, size: 36,
shadows: const [], shadows: const [],
color: Theme.of(context).extension<StackColors>()!.background, color:
Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset( icon: SvgPicture.asset(
Assets.svg.pencil, Assets.svg.pencil,
color: Theme.of(context) color: Theme.of(context)
@ -207,9 +227,6 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
), ),
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
final node = ref.watch(nodeServiceChangeNotifierProvider
.select((value) => value.getNodeById(id: nodeId)));
return SingleChildScrollView( return SingleChildScrollView(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
@ -217,41 +234,141 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
constraints: constraints:
BoxConstraints(minHeight: constraints.maxHeight - 8), BoxConstraints(minHeight: constraints.maxHeight - 8),
child: IntrinsicHeight( child: IntrinsicHeight(
child: child,
),
),
),
);
},
),
),
),
child: ConditionalParent(
condition: isDesktop,
builder: (child) => DesktopDialog(
maxWidth: 580,
maxHeight: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
const SizedBox(
width: 8,
),
const AppBarBackButton(
iconSize: 24,
size: 40,
),
Text(
"Node details",
style: STextStyles.desktopH3(context),
)
],
),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
top: 16,
bottom: 32,
),
child: child,
),
],
),
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
NodeForm( NodeForm(
node: node, node: node,
secureStore: secureStore, secureStore: secureStore,
readOnly: true, readOnly: isDesktop ? _desktopReadOnly : true,
coin: coin, coin: coin,
), ),
const Spacer(), if (!isDesktop) const Spacer(),
TextButton( if (isDesktop)
style: Theme.of(context) const SizedBox(
.extension<StackColors>()! height: 22,
.getSecondaryEnabledButtonColor(context), ),
if (isDesktop)
SizedBox(
height: 56,
child: _desktopReadOnly
? null
: Row(
children: [
Expanded(
child: DeleteButton(
label: "Delete node",
desktopMed: true,
onPressed: () async { onPressed: () async {
await _testConnection(ref, context); Navigator.of(context).pop();
await ref
.read(nodeServiceChangeNotifierProvider)
.delete(
node!.id,
true,
);
}, },
child: Text(
"Test connection",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark),
), ),
), ),
const SizedBox(height: 16), const SizedBox(
width: 16,
),
const Spacer(),
], ],
), ),
), ),
if (isDesktop && !_desktopReadOnly)
const SizedBox(
height: 45,
), ),
), Row(
); children: [
Expanded(
child: SecondaryButton(
label: "Test connection",
desktopMed: true,
onPressed: () async {
await _testConnection(ref, context);
}, },
), ),
), ),
if (isDesktop)
const SizedBox(
width: 16,
),
if (isDesktop)
Expanded(
child: !nodeId.startsWith("default")
? PrimaryButton(
label: _desktopReadOnly ? "Edit" : "Save",
desktopMed: true,
onPressed: () async {
final shouldSave = _desktopReadOnly == false;
setState(() {
_desktopReadOnly = !_desktopReadOnly;
});
if (shouldSave) {
// todo save node
}
},
)
: Container(),
),
],
),
if (!isDesktop)
const SizedBox(
height: 16,
),
],
),
),
); );
} }
} }

View file

@ -6,7 +6,11 @@ import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/sync_type_enum.dart'; import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.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/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
class SyncingOptionsView extends ConsumerWidget { class SyncingOptionsView extends ConsumerWidget {
@ -16,8 +20,13 @@ class SyncingOptionsView extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final isDesktop = Util.isDesktop;
return ConditionalParent(
condition: !isDesktop,
builder: (child) {
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background, backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar( appBar: AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
onPressed: () async { onPressed: () async {
@ -39,6 +48,15 @@ class SyncingOptionsView extends ConsumerWidget {
minHeight: constraints.maxHeight, minHeight: constraints.maxHeight,
), ),
child: IntrinsicHeight( child: IntrinsicHeight(
child: child,
),
),
);
},
),
),
);
},
child: Column( child: Column(
children: [ children: [
RoundedWhiteContainer( RoundedWhiteContainer(
@ -50,21 +68,17 @@ class SyncingOptionsView extends ConsumerWidget {
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
child: RawMaterialButton( child: RawMaterialButton(
// splashColor: Theme.of(context).extension<StackColors>()!.highlight, // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
materialTapTargetSize: materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
), ),
), ),
onPressed: () { onPressed: () {
final state = ref final state =
.read(prefsChangeNotifierProvider) ref.read(prefsChangeNotifierProvider).syncType;
.syncType;
if (state != SyncingType.currentWalletOnly) { if (state != SyncingType.currentWalletOnly) {
ref ref.read(prefsChangeNotifierProvider).syncType =
.read(prefsChangeNotifierProvider)
.syncType =
SyncingType.currentWalletOnly; SyncingType.currentWalletOnly;
// disable auto sync on all wallets that aren't active/current // disable auto sync on all wallets that aren't active/current
@ -83,8 +97,7 @@ class SyncingOptionsView extends ConsumerWidget {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Row( child: Row(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
SizedBox( SizedBox(
width: 20, width: 20,
@ -93,18 +106,15 @@ class SyncingOptionsView extends ConsumerWidget {
activeColor: Theme.of(context) activeColor: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.radioButtonIconEnabled, .radioButtonIconEnabled,
value: value: SyncingType.currentWalletOnly,
SyncingType.currentWalletOnly,
groupValue: ref.watch( groupValue: ref.watch(
prefsChangeNotifierProvider prefsChangeNotifierProvider
.select((value) => .select((value) => value.syncType),
value.syncType),
), ),
onChanged: (value) { onChanged: (value) {
if (value is SyncingType) { if (value is SyncingType) {
ref ref
.read( .read(prefsChangeNotifierProvider)
prefsChangeNotifierProvider)
.syncType = value; .syncType = value;
} }
}, },
@ -115,19 +125,16 @@ class SyncingOptionsView extends ConsumerWidget {
), ),
Flexible( Flexible(
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Sync only currently open wallet", "Sync only currently open wallet",
style: STextStyles.titleBold12( style: STextStyles.titleBold12(context),
context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
Text( Text(
"Sync only the wallet that you are using", "Sync only the wallet that you are using",
style: STextStyles.itemSubtitle( style: STextStyles.itemSubtitle(context),
context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],
@ -143,30 +150,24 @@ class SyncingOptionsView extends ConsumerWidget {
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: RawMaterialButton( child: RawMaterialButton(
// splashColor: Theme.of(context).extension<StackColors>()!.highlight, // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
materialTapTargetSize: materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
), ),
), ),
onPressed: () { onPressed: () {
final state = ref final state =
.read(prefsChangeNotifierProvider) ref.read(prefsChangeNotifierProvider).syncType;
.syncType; if (state != SyncingType.allWalletsOnStartup) {
if (state != ref.read(prefsChangeNotifierProvider).syncType =
SyncingType.allWalletsOnStartup) {
ref
.read(prefsChangeNotifierProvider)
.syncType =
SyncingType.allWalletsOnStartup; SyncingType.allWalletsOnStartup;
// enable auto sync on all wallets // enable auto sync on all wallets
ref ref
.read(walletsChangeNotifierProvider) .read(walletsChangeNotifierProvider)
.managers .managers
.forEach( .forEach((e) => e.shouldAutoSync = true);
(e) => e.shouldAutoSync = true);
} }
}, },
child: Container( child: Container(
@ -174,8 +175,7 @@ class SyncingOptionsView extends ConsumerWidget {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Row( child: Row(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
SizedBox( SizedBox(
width: 20, width: 20,
@ -184,18 +184,15 @@ class SyncingOptionsView extends ConsumerWidget {
activeColor: Theme.of(context) activeColor: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.radioButtonIconEnabled, .radioButtonIconEnabled,
value: value: SyncingType.allWalletsOnStartup,
SyncingType.allWalletsOnStartup,
groupValue: ref.watch( groupValue: ref.watch(
prefsChangeNotifierProvider prefsChangeNotifierProvider
.select((value) => .select((value) => value.syncType),
value.syncType),
), ),
onChanged: (value) { onChanged: (value) {
if (value is SyncingType) { if (value is SyncingType) {
ref ref
.read( .read(prefsChangeNotifierProvider)
prefsChangeNotifierProvider)
.syncType = value; .syncType = value;
} }
}, },
@ -206,19 +203,16 @@ class SyncingOptionsView extends ConsumerWidget {
), ),
Flexible( Flexible(
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Sync all wallets at startup", "Sync all wallets at startup",
style: STextStyles.titleBold12( style: STextStyles.titleBold12(context),
context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
Text( Text(
"All of your wallets will start syncing when you open the app", "All of your wallets will start syncing when you open the app",
style: STextStyles.itemSubtitle( style: STextStyles.itemSubtitle(context),
context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],
@ -234,22 +228,17 @@ class SyncingOptionsView extends ConsumerWidget {
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
child: RawMaterialButton( child: RawMaterialButton(
// splashColor: Theme.of(context).extension<StackColors>()!.highlight, // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
materialTapTargetSize: materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
), ),
), ),
onPressed: () { onPressed: () {
final state = ref final state =
.read(prefsChangeNotifierProvider) ref.read(prefsChangeNotifierProvider).syncType;
.syncType; if (state != SyncingType.selectedWalletsAtStartup) {
if (state != ref.read(prefsChangeNotifierProvider).syncType =
SyncingType.selectedWalletsAtStartup) {
ref
.read(prefsChangeNotifierProvider)
.syncType =
SyncingType.selectedWalletsAtStartup; SyncingType.selectedWalletsAtStartup;
final ids = ref final ids = ref
@ -260,8 +249,8 @@ class SyncingOptionsView extends ConsumerWidget {
ref ref
.read(walletsChangeNotifierProvider) .read(walletsChangeNotifierProvider)
.managers .managers
.forEach((e) => e.shouldAutoSync = .forEach((e) =>
ids.contains(e.walletId)); e.shouldAutoSync = ids.contains(e.walletId));
} }
}, },
child: Container( child: Container(
@ -269,8 +258,7 @@ class SyncingOptionsView extends ConsumerWidget {
child: Padding( child: Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: Row( child: Row(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
SizedBox( SizedBox(
width: 20, width: 20,
@ -279,18 +267,15 @@ class SyncingOptionsView extends ConsumerWidget {
activeColor: Theme.of(context) activeColor: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.radioButtonIconEnabled, .radioButtonIconEnabled,
value: SyncingType value: SyncingType.selectedWalletsAtStartup,
.selectedWalletsAtStartup,
groupValue: ref.watch( groupValue: ref.watch(
prefsChangeNotifierProvider prefsChangeNotifierProvider
.select((value) => .select((value) => value.syncType),
value.syncType),
), ),
onChanged: (value) { onChanged: (value) {
if (value is SyncingType) { if (value is SyncingType) {
ref ref
.read( .read(prefsChangeNotifierProvider)
prefsChangeNotifierProvider)
.syncType = value; .syncType = value;
} }
}, },
@ -301,19 +286,16 @@ class SyncingOptionsView extends ConsumerWidget {
), ),
Flexible( Flexible(
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Sync only selected wallets at startup", "Sync only selected wallets at startup",
style: STextStyles.titleBold12( style: STextStyles.titleBold12(context),
context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
Text( Text(
"Only the wallets you select will start syncing when you open the app", "Only the wallets you select will start syncing when you open the app",
style: STextStyles.itemSubtitle( style: STextStyles.itemSubtitle(context),
context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],
@ -343,8 +325,7 @@ class SyncingOptionsView extends ConsumerWidget {
bottom: 12, bottom: 12,
), ),
child: Row( child: Row(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
const SizedBox( const SizedBox(
width: 12 + 20, width: 12 + 20,
@ -357,23 +338,58 @@ class SyncingOptionsView extends ConsumerWidget {
MaterialTapTargetSize.shrinkWrap, MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants Constants.size.circularBorderRadius,
.size.circularBorderRadius,
), ),
), ),
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed( !isDesktop
WalletSyncingOptionsView ? Navigator.of(context).pushNamed(
.routeName); WalletSyncingOptionsView.routeName)
: showDialog(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return DesktopDialog(
maxWidth: 600,
maxHeight: 800,
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Padding(
padding:
const EdgeInsets.all(
32),
child: Text(
"Select wallets to sync",
style: STextStyles
.desktopH3(context),
textAlign:
TextAlign.center,
),
),
const DesktopDialogCloseButton(),
],
),
const Expanded(
child:
WalletSyncingOptionsView(),
),
],
),
);
});
}, },
child: Column( child: Column(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment.start,
CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Select wallets...", "Select wallets...",
style: style: STextStyles.link2(context),
STextStyles.link2(context),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],
@ -389,12 +405,6 @@ class SyncingOptionsView extends ConsumerWidget {
), ),
], ],
), ),
),
),
);
},
),
),
); );
} }
} }

View file

@ -10,7 +10,9 @@ import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/animated_text.dart'; import 'package:stackwallet/widgets/animated_text.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/custom_buttons/draggable_switch_button.dart'; import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -25,8 +27,13 @@ class WalletSyncingOptionsView extends ConsumerWidget {
final managers = ref final managers = ref
.watch(walletsChangeNotifierProvider.select((value) => value.managers)); .watch(walletsChangeNotifierProvider.select((value) => value.managers));
final isDesktop = Util.isDesktop;
return ConditionalParent(
condition: !isDesktop,
builder: (child) {
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background, backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar( appBar: AppBar(
leading: AppBarBackButton( leading: AppBarBackButton(
onPressed: () async { onPressed: () async {
@ -41,14 +48,26 @@ class WalletSyncingOptionsView extends ConsumerWidget {
), ),
), ),
), ),
body: LayoutBuilder(builder: (context, constraints) { body: Padding(
return Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 12, left: 12,
top: 12, top: 12,
right: 12, right: 12,
), ),
child: SingleChildScrollView( child: child,
),
);
},
child: ConditionalParent(
condition: isDesktop,
builder: (child) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 32),
child: child,
);
},
child: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints( constraints: BoxConstraints(
minHeight: constraints.maxHeight - 24, minHeight: constraints.maxHeight - 24,
@ -71,6 +90,11 @@ class WalletSyncingOptionsView extends ConsumerWidget {
), ),
RoundedWhiteContainer( RoundedWhiteContainer(
padding: const EdgeInsets.all(0), padding: const EdgeInsets.all(0),
borderColor: !isDesktop
? Colors.transparent
: Theme.of(context)
.extension<StackColors>()!
.background,
child: Column( child: Column(
children: [ children: [
...managers.map( ...managers.map(
@ -208,9 +232,9 @@ class WalletSyncingOptionsView extends ConsumerWidget {
), ),
), ),
), ),
),
); );
}), }),
),
); );
} }
} }

View file

@ -14,6 +14,7 @@ import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; 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/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
@ -70,6 +71,20 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
), ),
), ),
body: SafeArea( body: SafeArea(
child: ConditionalParent(
condition: !isDesktop,
builder: (child) => LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraints.maxHeight,
),
child: IntrinsicHeight(
child: child,
),
),
),
),
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB(0, isDesktop ? 0 : 40, 0, 0), padding: EdgeInsets.fromLTRB(0, isDesktop ? 0 : 40, 0, 0),
child: ConstrainedBox( child: ConstrainedBox(
@ -248,6 +263,7 @@ class _StackPrivacyCalls extends ConsumerState<StackPrivacyCalls> {
), ),
), ),
), ),
),
); );
} }
} }
@ -494,158 +510,3 @@ class _PrivacyToggleState extends State<PrivacyToggle> {
); );
} }
} }
// class ContinueButton extends ConsumerWidget {
// const ContinueButton({
// Key? key,
// required this.isDesktop,
// required this.onPressed,
// required this.label,
// }) : super(key: key);
//
// final String label;
// final bool isDesktop;
// final VoidCallback onPressed;
//
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// if (isDesktop) {
// return SizedBox(
// width: 328,
// height: 70,
// child: TextButton(
// style: Theme.of(context)
// .extension<StackColors>()!
// .getPrimaryEnabledButtonColor(context),
// onPressed: onPressed,
// child: Text(
// label,
// style: STextStyles.button(context).copyWith(fontSize: 20),
// ),
// ),
// );
// } else {
// return TextButton(
// style: Theme.of(context)
// .extension<StackColors>()!
// .getPrimaryEnabledButtonColor(context),
// onPressed: onPressed,
// child: Text(
// label,
// style: STextStyles.button(context),
// ),
// );
// }
// }
// }
// class CustomRadio extends StatefulWidget {
// CustomRadio(this.upperCall, {Key? key}) : super(key: key);
//
// Function upperCall;
//
// @override
// createState() {
// return CustomRadioState();
// }
// }
//
// class CustomRadioState extends State<CustomRadio> {
// List<RadioModel> sampleData = <RadioModel>[];
//
// @override
// void initState() {
// super.initState();
// sampleData.add(
// RadioModel(true, Assets.svg.personaEasy, 'Easy Crypto', 'Recommended'));
// sampleData.add(RadioModel(
// false, Assets.svg.personaIncognito, 'Incognito', 'Privacy conscious'));
// }
//
// @override
// Widget build(BuildContext context) {
// return Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// InkWell(
// onTap: () {
// setState(() {
// // if (!sampleData[0].isSelected) {
// widget.upperCall.call(true);
// // }
// for (var element in sampleData) {
// element.isSelected = false;
// }
// sampleData[0].isSelected = true;
// });
// },
// child: RadioItem(sampleData[0]),
// ),
// InkWell(
// onTap: () {
// setState(() {
// // if (!sampleData[1].isSelected) {
// widget.upperCall.call(false);
// // }
// for (var element in sampleData) {
// element.isSelected = false;
// }
// sampleData[1].isSelected = true;
// });
// },
// child: RadioItem(sampleData[1]),
// )
// ],
// );
// }
// }
//
// class RadioItem extends StatelessWidget {
// final RadioModel _item;
// const RadioItem(this._item, {Key? key}) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return Container(
// margin: const EdgeInsets.all(15.0),
// child: RoundedWhiteContainer(
// borderColor: _item.isSelected ? const Color(0xFF0056D2) : null,
// child: Center(
// child: Column(
// children: [
// SvgPicture.asset(
// _item.svg,
// // color: Theme.of(context).extension<StackColors>()!.textWhite,
// width: 140,
// height: 140,
// ),
// RichText(
// textAlign: TextAlign.center,
// text: TextSpan(
// style: STextStyles.label(context).copyWith(fontSize: 12.0),
// children: [
// TextSpan(
// text: _item.topText,
// style: TextStyle(
// color: Theme.of(context)
// .extension<StackColors>()!
// .textDark,
// fontWeight: FontWeight.bold)),
// TextSpan(text: "\n${_item.bottomText}"),
// ],
// ),
// ),
// ],
// )),
// ),
// );
// }
// }
//
// class RadioModel {
// bool isSelected;
// final String svg;
// final String topText;
// final String bottomText;
//
// RadioModel(this.isSelected, this.svg, this.topText, this.bottomText);
// }

View file

@ -21,6 +21,7 @@ import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; 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/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@ -302,8 +303,17 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
child: Row( child: Row(
children: [ children: [
SizedBox( ConditionalParent(
width: isDesktop ? 570 : null, condition: isDesktop,
builder: (child) => SizedBox(
width: 570,
child: child,
),
child: ConditionalParent(
condition: !isDesktop,
builder: (child) => Expanded(
child: child,
),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
@ -368,6 +378,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
), ),
), ),
), ),
),
if (isDesktop) if (isDesktop)
const SizedBox( const SizedBox(
width: 20, width: 20,

View file

@ -10,6 +10,8 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart'; import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'debug_info_dialog.dart';
class AdvancedSettings extends ConsumerStatefulWidget { class AdvancedSettings extends ConsumerStatefulWidget {
const AdvancedSettings({Key? key}) : super(key: key); const AdvancedSettings({Key? key}) : super(key: key);
@ -226,16 +228,16 @@ class ShowLogsButton extends ConsumerWidget {
}) : super(key: key); }) : super(key: key);
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
// Future<void> viewDebugLogs() async { Future<void> viewDebugLogs() async {
// await showDialog<dynamic>( await showDialog<dynamic>(
// context: context, context: context,
// useSafeArea: false, useSafeArea: false,
// barrierDismissible: true, barrierDismissible: true,
// builder: (context) { builder: (context) {
// return const DebugInfoDialog(); return const DebugInfoDialog();
// }, },
// ); );
// } }
return SizedBox( return SizedBox(
width: 101, width: 101,
@ -245,8 +247,7 @@ class ShowLogsButton extends ConsumerWidget {
.extension<StackColors>()! .extension<StackColors>()!
.getPrimaryEnabledButtonColor(context), .getPrimaryEnabledButtonColor(context),
onPressed: () { onPressed: () {
// viewDebugLogs();
// viewDebugLogs();
}, },
child: Text( child: Text(
"Show logs", "Show logs",

View file

@ -1,29 +1,33 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/isar/models/log.dart'; import 'package:stackwallet/models/isar/models/log.dart';
import 'package:stackwallet/providers/global/debug_service_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/log_level_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.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_dialog_close_button.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/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
// import '../../../utilities/assets.dart'; class DebugInfoDialog extends ConsumerStatefulWidget {
// import '../../../utilities/util.dart';
// import '../../../widgets/icon_widgets/x_icon.dart';
// import '../../../widgets/stack_text_field.dart';
// import '../../../widgets/textfield_icon_button.dart';
class DebugInfoDialog extends StatefulWidget {
const DebugInfoDialog({Key? key}) : super(key: key); const DebugInfoDialog({Key? key}) : super(key: key);
@override @override
State<StatefulWidget> createState() => _DebugInfoDialog(); ConsumerState<DebugInfoDialog> createState() => _DebugInfoDialog();
} }
class _DebugInfoDialog extends State<DebugInfoDialog> { class _DebugInfoDialog extends ConsumerState<DebugInfoDialog> {
final _searchController = TextEditingController(); late final TextEditingController searchDebugController;
final _searchFocusNode = FocusNode(); late final FocusNode searchDebugFocusNode;
final scrollController = ScrollController(); final scrollController = ScrollController();
@ -62,15 +66,19 @@ class _DebugInfoDialog extends State<DebugInfoDialog> {
@override @override
void initState() { void initState() {
// ref.read(debugServiceProvider).updateRecentLogs(); searchDebugController = TextEditingController();
searchDebugFocusNode = FocusNode();
ref.read(debugServiceProvider).updateRecentLogs();
super.initState(); super.initState();
} }
@override @override
void dispose() { void dispose() {
_searchController.dispose(); searchDebugFocusNode.dispose();
searchDebugController.dispose();
scrollController.dispose(); scrollController.dispose();
_searchFocusNode.dispose();
super.dispose(); super.dispose();
} }
@ -78,7 +86,7 @@ class _DebugInfoDialog extends State<DebugInfoDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DesktopDialog( return DesktopDialog(
maxHeight: 800, maxHeight: 850,
maxWidth: 600, maxWidth: 600,
child: Column( child: Column(
children: [ children: [
@ -96,68 +104,216 @@ class _DebugInfoDialog extends State<DebugInfoDialog> {
const DesktopDialogCloseButton(), const DesktopDialogCloseButton(),
], ],
), ),
Row( Expanded(
flex: 24,
child: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
sliver: SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 16, horizontal: 32),
child: Column(
children: [ children: [
// ClipRRect( Padding(
// borderRadius: BorderRadius.circular( padding: const EdgeInsets.only(bottom: 16),
// Constants.size.circularBorderRadius, child: ClipRRect(
// ), borderRadius: BorderRadius.circular(
// child: TextField( Constants.size.circularBorderRadius,
// key: const Key("desktopSettingDebugInfo"), ),
// autocorrect: Util.isDesktop ? false : true, child: TextField(
// enableSuggestions: Util.isDesktop ? false : true, autocorrect: Util.isDesktop ? false : true,
// controller: _searchController, enableSuggestions:
// focusNode: _searchFocusNode, Util.isDesktop ? false : true,
// // onChanged: (newString) { controller: searchDebugController,
// // setState(() => _searchTerm = newString); focusNode: searchDebugFocusNode,
// // }, onChanged: (newString) {
// style: STextStyles.field(context), setState(() => _searchTerm = newString);
// decoration: standardInputDecoration( },
// "Search", style: STextStyles.field(context),
// _searchFocusNode, decoration: standardInputDecoration(
// context, "Search",
// ).copyWith( searchDebugFocusNode,
// prefixIcon: Padding( context,
// padding: const EdgeInsets.symmetric( ).copyWith(
// horizontal: 10, prefixIcon: Padding(
// vertical: 16, padding: const EdgeInsets.symmetric(
// ), horizontal: 10,
// child: SvgPicture.asset( vertical: 16,
// Assets.svg.search, ),
// width: 16, child: SvgPicture.asset(
// height: 16, Assets.svg.search,
// ), width: 16,
// ), height: 16,
// suffixIcon: _searchController.text.isNotEmpty ),
// ? Padding( ),
// padding: const EdgeInsets.only(right: 0), suffixIcon: searchDebugController
// child: UnconstrainedBox( .text.isNotEmpty
// child: Row( ? Padding(
// children: [ padding:
// TextFieldIconButton( const EdgeInsets.only(right: 0),
// child: const XIcon(), child: UnconstrainedBox(
// onTap: () async { child: Row(
// setState(() { children: [
// _searchController.text = ""; TextFieldIconButton(
// _searchTerm = ""; child: const XIcon(),
// }); onTap: () async {
// }, setState(() {
// ), searchDebugController
// ], .text = "";
// ), _searchTerm = "";
// ), });
// ) },
// : null, ),
// ),
// ),
// ),
], ],
), ),
// Column( ),
// children: [ )
// : null,
// ], ),
// ), ),
),
),
const SizedBox(
height: 12,
),
],
),
),
),
),
];
},
body: Builder(
builder: (context) {
final logs = filtered(
ref.watch(debugServiceProvider
.select((value) => value.recentLogs)),
_searchTerm)
.reversed
.toList(growable: false);
return CustomScrollView(
reverse: true,
// shrinkWrap: true,
controller: scrollController,
slivers: [
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final log = logs[index];
return Container(
key: Key(
"log_${log.id}_${log.timestampInMillisUTC}"),
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
borderRadius: _borderRadius(index, logs.length),
),
child: Padding(
padding: const EdgeInsets.all(4),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32),
child: RoundedContainer(
padding: const EdgeInsets.all(0),
color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
" [${log.logLevel.name}]",
style: STextStyles.baseXS(context)
.copyWith(
fontSize: 8,
color: (log.logLevel ==
LogLevel.Info
? Theme.of(context)
.extension<
StackColors>()!
.topNavIconGreen
: (log.logLevel ==
LogLevel.Warning
? Theme.of(context)
.extension<
StackColors>()!
.topNavIconYellow
: (log.logLevel ==
LogLevel.Error
? Colors.orange
: Theme.of(context)
.extension<
StackColors>()!
.topNavIconRed))),
),
),
Text(
"[${DateTime.fromMillisecondsSinceEpoch(log.timestampInMillisUTC, isUtc: true)}]: ",
style: STextStyles.baseXS(context)
.copyWith(
fontSize: 12,
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
],
),
Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const SizedBox(
width: 20,
),
Flexible(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
SelectableText(
log.message,
style: STextStyles.baseXS(
context)
.copyWith(
fontSize: 11.5),
),
],
),
),
],
),
],
),
),
),
),
);
},
childCount: logs.length,
),
),
],
);
},
),
),
),
const Spacer(), const Spacer(),
Padding( Padding(
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),

View file

@ -1,371 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/providers/global/base_currencies_provider.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
class CurrencyDialog extends ConsumerStatefulWidget {
const CurrencyDialog({Key? key}) : super(key: key);
@override
ConsumerState<CurrencyDialog> createState() => _CurrencyDialog();
}
class _CurrencyDialog extends ConsumerState<CurrencyDialog> {
late String current;
late List<String> currenciesWithoutSelected;
late final TextEditingController searchCurrencyController;
late final FocusNode searchCurrencyFocusNode;
void onTap(int index) {
if (currenciesWithoutSelected[index] == current || current.isEmpty) {
// ignore if already selected currency
return;
}
current = currenciesWithoutSelected[index];
currenciesWithoutSelected.remove(current);
currenciesWithoutSelected.insert(0, current);
ref.read(prefsChangeNotifierProvider).currency = current;
}
BorderRadius? _borderRadius(int index) {
if (index == 0 && currenciesWithoutSelected.length == 1) {
return BorderRadius.circular(
Constants.size.circularBorderRadius,
);
} else if (index == 0) {
return BorderRadius.vertical(
top: Radius.circular(
Constants.size.circularBorderRadius,
),
);
} else if (index == currenciesWithoutSelected.length - 1) {
return BorderRadius.vertical(
bottom: Radius.circular(
Constants.size.circularBorderRadius,
),
);
}
return null;
}
String filter = "";
List<String> _filtered() {
final currencyMap = ref.read(baseCurrenciesProvider).map;
return currenciesWithoutSelected.where((element) {
return element.toLowerCase().contains(filter.toLowerCase()) ||
(currencyMap[element]?.toLowerCase().contains(filter.toLowerCase()) ??
false);
}).toList();
}
@override
void initState() {
searchCurrencyController = TextEditingController();
searchCurrencyFocusNode = FocusNode();
super.initState();
}
@override
void dispose() {
searchCurrencyController.dispose();
searchCurrencyFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
current = ref
.watch(prefsChangeNotifierProvider.select((value) => value.currency));
currenciesWithoutSelected = ref
.watch(baseCurrenciesProvider.select((value) => value.map))
.keys
.toList();
if (current.isNotEmpty) {
currenciesWithoutSelected.remove(current);
currenciesWithoutSelected.insert(0, current);
}
currenciesWithoutSelected = _filtered();
return DesktopDialog(
maxHeight: 800,
maxWidth: 600,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(32),
child: Text(
"Select currency",
style: STextStyles.desktopH3(context),
textAlign: TextAlign.center,
),
),
const DesktopDialogCloseButton(),
],
),
Expanded(
flex: 24,
child: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context),
sliver: SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 16, horizontal: 32),
child: Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions:
Util.isDesktop ? false : true,
controller: searchCurrencyController,
focusNode: searchCurrencyFocusNode,
onChanged: (newString) {
setState(() => filter = newString);
},
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Search",
searchCurrencyFocusNode,
context,
).copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 16,
),
child: SvgPicture.asset(
Assets.svg.search,
width: 16,
height: 16,
),
),
suffixIcon: searchCurrencyController
.text.isNotEmpty
? Padding(
padding:
const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(),
onTap: () async {
setState(() {
searchCurrencyController
.text = "";
filter = "";
});
},
),
],
),
),
)
: null,
),
),
),
),
],
),
),
),
),
];
},
body: Builder(
builder: (context) {
return CustomScrollView(
slivers: [
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
context,
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
borderRadius: _borderRadius(index),
),
child: Padding(
padding: const EdgeInsets.all(4),
key: Key(
"desktopSettingsCurrencySelect_${currenciesWithoutSelected[index]}"),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32),
child: RoundedContainer(
padding: const EdgeInsets.all(0),
color: currenciesWithoutSelected[index] ==
current
? Theme.of(context)
.extension<StackColors>()!
.currencyListItemBG
: Theme.of(context)
.extension<StackColors>()!
.popupBG,
child: RawMaterialButton(
onPressed: () async {
onTap(index);
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
SizedBox(
width: 20,
height: 20,
child: Radio(
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
materialTapTargetSize:
MaterialTapTargetSize
.shrinkWrap,
value: true,
groupValue:
currenciesWithoutSelected[
index] ==
current,
onChanged: (_) {
onTap(index);
},
),
),
const SizedBox(
width: 12,
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
currenciesWithoutSelected[
index],
key: (currenciesWithoutSelected[
index] ==
current)
? const Key(
"desktopSettingsSelectedCurrencyText")
: null,
style:
STextStyles.largeMedium14(
context),
),
const SizedBox(
height: 2,
),
Text(
ref.watch(baseCurrenciesProvider
.select((value) =>
value.map))[
currenciesWithoutSelected[
index]] ??
"",
key: (currenciesWithoutSelected[
index] ==
current)
? const Key(
"desktopSelectedCurrencyTextDescription")
: null,
style:
STextStyles.itemSubtitle(
context),
),
],
),
],
),
),
),
),
),
),
);
},
childCount: currenciesWithoutSelected.length,
),
),
],
);
},
),
),
),
const Spacer(),
Padding(
padding: const EdgeInsets.all(32),
child: Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed: () {
Navigator.of(context).pop();
},
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Save Changes",
onPressed: () {},
),
)
],
),
),
],
),
);
}
}

View file

@ -1,14 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/currency_view.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'currency_dialog.dart';
class CurrencySettings extends ConsumerStatefulWidget { class CurrencySettings extends ConsumerStatefulWidget {
const CurrencySettings({Key? key}) : super(key: key); const CurrencySettings({Key? key}) : super(key: key);
@ -84,19 +84,51 @@ class NewPasswordButton extends ConsumerWidget {
const NewPasswordButton({ const NewPasswordButton({
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@override Future<void> chooseCurrency(BuildContext context) async {
Widget build(BuildContext context, WidgetRef ref) { // await showDialog<dynamic>(
Future<void> chooseCurrency() async { // context: context,
// useSafeArea: false,
// barrierDismissible: true,
// builder: (context) {
// return CurrencyDialog();
// },
// );
await showDialog<dynamic>( await showDialog<dynamic>(
context: context, context: context,
useSafeArea: false, useSafeArea: false,
barrierDismissible: true, barrierDismissible: true,
builder: (context) { builder: (context) {
return CurrencyDialog(); return DesktopDialog(
maxHeight: 800,
maxWidth: 600,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(32),
child: Text(
"Select currency",
style: STextStyles.desktopH3(context),
textAlign: TextAlign.center,
),
),
const DesktopDialogCloseButton(),
],
),
const Expanded(
child: BaseCurrencySettingsView(),
),
],
),
);
}, },
); );
} }
@override
Widget build(BuildContext context, WidgetRef ref) {
return SizedBox( return SizedBox(
width: 200, width: 200,
height: 48, height: 48,
@ -105,7 +137,7 @@ class NewPasswordButton extends ConsumerWidget {
.extension<StackColors>()! .extension<StackColors>()!
.getPrimaryEnabledButtonColor(context), .getPrimaryEnabledButtonColor(context),
onPressed: () { onPressed: () {
chooseCurrency(); chooseCurrency(context);
}, },
child: Text( child: Text(
"Change currency", "Change currency",

View file

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart'; import 'package:stackwallet/pages_desktop_specific/home/settings_menu/language_settings/language_dialog.dart';
@ -86,19 +85,20 @@ class ChangeLanguageButton extends ConsumerWidget {
const ChangeLanguageButton({ const ChangeLanguageButton({
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) { Future<void> chooseLanguage(BuildContext context) async {
Future<void> chooseLanguage() async {
await showDialog<dynamic>( await showDialog<dynamic>(
context: context, context: context,
useSafeArea: false, useSafeArea: false,
barrierDismissible: true, barrierDismissible: true,
builder: (context) { builder: (context) {
return LanguageDialog(); return const LanguageDialog();
}, },
); );
} }
@override
Widget build(BuildContext context, WidgetRef ref) {
return SizedBox( return SizedBox(
width: 200, width: 200,
height: 48, height: 48,
@ -107,7 +107,7 @@ class ChangeLanguageButton extends ConsumerWidget {
.extension<StackColors>()! .extension<StackColors>()!
.getPrimaryEnabledButtonColor(context), .getPrimaryEnabledButtonColor(context),
onPressed: () { onPressed: () {
chooseLanguage(); chooseLanguage(context);
}, },
child: Text( child: Text(
"Change language", "Change language",

View file

@ -1,15 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
import 'package:stackwallet/providers/global/node_service_provider.dart'; import 'package:stackwallet/providers/global/node_service_provider.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.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';
class NodesSettings extends ConsumerStatefulWidget { class NodesSettings extends ConsumerStatefulWidget {
const NodesSettings({Key? key}) : super(key: key); const NodesSettings({Key? key}) : super(key: key);
@ -23,15 +26,27 @@ class NodesSettings extends ConsumerStatefulWidget {
class _NodesSettings extends ConsumerState<NodesSettings> { class _NodesSettings extends ConsumerState<NodesSettings> {
List<Coin> _coins = [...Coin.values]; List<Coin> _coins = [...Coin.values];
late final TextEditingController searchNodeController;
late final FocusNode searchNodeFocusNode;
String filter = "";
@override @override
void initState() { void initState() {
_coins = _coins.toList(); _coins = _coins.toList();
_coins.remove(Coin.firoTestNet); _coins.remove(Coin.firoTestNet);
searchNodeController = TextEditingController();
searchNodeFocusNode = FocusNode();
super.initState(); super.initState();
} }
@override @override
void dispose() { void dispose() {
searchNodeController.dispose();
searchNodeFocusNode.dispose();
super.dispose(); super.dispose();
} }
@ -47,6 +62,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
return Column( return Column(
mainAxisSize: MainAxisSize.min,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
@ -55,6 +71,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
child: RoundedWhiteContainer( child: RoundedWhiteContainer(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
Assets.svg.circleNode, Assets.svg.circleNode,
@ -63,6 +80,7 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
), ),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.all(10), padding: const EdgeInsets.all(10),
@ -85,13 +103,52 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
), ),
], ],
), ),
//TODO: add search bar Padding(
SingleChildScrollView( padding: const EdgeInsets.all(10.0),
child: Column( child: ClipRRect(
crossAxisAlignment: CrossAxisAlignment.stretch, borderRadius: BorderRadius.circular(
children: [ Constants.size.circularBorderRadius,
...coins.map( ),
(coin) { child: TextField(
autocorrect: Util.isDesktop ? false : true,
enableSuggestions: Util.isDesktop ? false : true,
controller: searchNodeController,
focusNode: searchNodeFocusNode,
onChanged: (newString) {
setState(() => filter = newString);
},
style: STextStyles.field(context),
decoration: standardInputDecoration(
"Search",
searchNodeFocusNode,
context,
).copyWith(
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 16,
),
child: SvgPicture.asset(
Assets.svg.search,
width: 16,
height: 16,
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: RoundedWhiteContainer(
padding: const EdgeInsets.all(0),
borderColor:
Theme.of(context).extension<StackColors>()!.background,
child: ListView.separated(
primary: false,
shrinkWrap: true,
itemBuilder: (context, index) {
final coin = coins[index];
final count = ref final count = ref
.watch(nodeServiceChangeNotifierProvider .watch(nodeServiceChangeNotifierProvider
.select((value) => value.getNodesFor(coin))) .select((value) => value.getNodesFor(coin)))
@ -105,17 +162,29 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
), ),
// side: BorderSide(
// color: Theme.of(context)
// .extension<StackColors>()!
// .shadow),
), ),
materialTapTargetSize: materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap, MaterialTapTargetSize.shrinkWrap,
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed( showDialog<void>(
CoinNodesView.routeName, context: context,
arguments: coin, builder: (context) => Navigator(
initialRoute: CoinNodesView.routeName,
onGenerateRoute: RouteGenerator.generateRoute,
onGenerateInitialRoutes: (_, __) {
return [
FadePageRoute(
CoinNodesView(
coin: coin,
rootNavigator: true,
),
const RouteSettings(
name: CoinNodesView.routeName,
),
),
];
},
),
); );
}, },
child: Padding( child: Padding(
@ -165,8 +234,14 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
), ),
); );
}, },
separatorBuilder: (context, index) => Container(
height: 1,
color: Theme.of(context)
.extension<StackColors>()!
.background,
),
itemCount: coins.length,
), ),
],
), ),
), ),
], ],

View file

@ -7,6 +7,8 @@ import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import '../../../pages/settings_views/global_settings_view/syncing_preferences_views/syncing_options_view.dart';
class SyncingPreferencesSettings extends ConsumerStatefulWidget { class SyncingPreferencesSettings extends ConsumerStatefulWidget {
const SyncingPreferencesSettings({Key? key}) : super(key: key); const SyncingPreferencesSettings({Key? key}) : super(key: key);
@ -62,6 +64,13 @@ class _SyncingPreferencesSettings
), ),
], ],
), ),
///TODO: ONLY SHOW SYNC OPTIONS ON BUTTON PRESS
Column(
children: [
SyncingOptionsView(),
],
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: const [ children: const [

View file

@ -1468,6 +1468,20 @@ class StackColors extends ThemeExtension<StackColors> {
} }
} }
ButtonStyle? getDeleteEnabledButtonColor(BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
textFieldErrorBG,
),
);
ButtonStyle? getDeleteDisabledButtonColor(BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
buttonBackSecondaryDisabled,
),
);
ButtonStyle? getPrimaryEnabledButtonColor(BuildContext context) => ButtonStyle? getPrimaryEnabledButtonColor(BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith( Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>( backgroundColor: MaterialStateProperty.all<Color>(

View file

@ -0,0 +1,98 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/desktop/custom_text_button.dart';
class DeleteButton extends StatelessWidget {
const DeleteButton({
Key? key,
this.width,
this.height,
this.label,
this.onPressed,
this.enabled = true,
this.desktopMed = false,
}) : super(key: key);
final double? width;
final double? height;
final String? label;
final VoidCallback? onPressed;
final bool enabled;
final bool desktopMed;
TextStyle getStyle(bool isDesktop, BuildContext context) {
if (isDesktop) {
if (desktopMed) {
return STextStyles.desktopTextExtraSmall(context).copyWith(
color: enabled
? Theme.of(context).extension<StackColors>()!.accentColorRed
: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondaryDisabled,
);
} else {
return enabled
? STextStyles.desktopButtonSecondaryEnabled(context).copyWith(
color:
Theme.of(context).extension<StackColors>()!.accentColorRed)
: STextStyles.desktopButtonSecondaryDisabled(context);
}
} else {
return STextStyles.button(context).copyWith(
color: enabled
? Theme.of(context).extension<StackColors>()!.accentColorRed
: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondaryDisabled,
);
}
}
@override
Widget build(BuildContext context) {
final isDesktop = Util.isDesktop;
return CustomTextButtonBase(
height: desktopMed ? 56 : height,
width: width,
textButton: TextButton(
onPressed: enabled ? onPressed : null,
style: enabled
? Theme.of(context)
.extension<StackColors>()!
.getDeleteEnabledButtonColor(context)
: Theme.of(context)
.extension<StackColors>()!
.getDeleteDisabledButtonColor(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
Assets.svg.trash,
width: 20,
height: 20,
color: enabled
? Theme.of(context).extension<StackColors>()!.accentColorRed
: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondaryDisabled,
),
if (label != null)
const SizedBox(
width: 10,
),
if (label != null)
Text(
label!,
style: getStyle(isDesktop, context),
),
],
),
),
);
}
}

View file

@ -11,7 +11,7 @@ description: Stack Wallet
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.5.13+85 version: 1.5.14+86
environment: environment:
sdk: ">=2.17.0 <3.0.0" sdk: ">=2.17.0 <3.0.0"