desktop reusable widgets and create/restore flow ui

This commit is contained in:
julian 2022-09-18 10:14:27 -06:00
parent 1f509c53db
commit c28e188c8f
11 changed files with 440 additions and 226 deletions

View file

@ -5,7 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart';
import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/next_button.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_app_bar.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
@ -13,6 +13,8 @@ import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.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_scaffold.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
@ -55,135 +57,123 @@ class _AddWalletViewState extends State<AddWalletView> {
debugPrint("BUILD: $runtimeType");
if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
return Material(
color: CFColors.background,
child: Column(
return DesktopScaffold(
appBar: const DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
),
body: Column(
children: [
DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
const AddWalletText(
isDesktop: true,
),
const SizedBox(
height: 16,
),
Expanded(
child: Column(
children: [
const AddWalletText(
isDesktop: true,
child: SizedBox(
width: 480,
child: RoundedWhiteContainer(
radiusMultiplier: 2,
padding: const EdgeInsets.only(
left: 16,
top: 16,
right: 16,
bottom: 0,
),
const SizedBox(
height: 16,
),
Expanded(
child: SizedBox(
width: 480,
child: RoundedWhiteContainer(
radiusMultiplier: 2,
padding: const EdgeInsets.only(
left: 16,
top: 16,
right: 16,
bottom: 0,
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
controller: _searchFieldController,
focusNode: _searchFocusNode,
onChanged: (value) {
setState(() {
_searchTerm = value;
});
},
style: STextStyles.desktopTextMedium.copyWith(
height: 2,
),
decoration: standardInputDecoration(
"Search",
_searchFocusNode,
).copyWith(
contentPadding: const EdgeInsets.symmetric(
vertical: 10,
),
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
// vertical: 20,
),
child: TextField(
controller: _searchFieldController,
focusNode: _searchFocusNode,
onChanged: (value) {
setState(() {
_searchTerm = value;
});
},
style: STextStyles.desktopTextMedium.copyWith(
height: 2,
),
decoration: standardInputDecoration(
"Search",
_searchFocusNode,
).copyWith(
contentPadding: const EdgeInsets.symmetric(
vertical: 10,
),
prefixIcon: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
// vertical: 20,
),
child: SvgPicture.asset(
Assets.svg.search,
width: 24,
height: 24,
color: CFColors
.textFieldDefaultSearchIconLeft,
),
),
suffixIcon:
_searchFieldController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(
right: 10),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(
width: 24,
height: 24,
),
onTap: () async {
setState(() {
_searchFieldController
.text = "";
_searchTerm = "";
});
},
),
],
),
),
)
: null,
),
child: SvgPicture.asset(
Assets.svg.search,
width: 24,
height: 24,
color:
CFColors.textFieldDefaultSearchIconLeft,
),
),
suffixIcon: _searchFieldController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 10),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(
width: 24,
height: 24,
),
onTap: () async {
setState(() {
_searchFieldController.text =
"";
_searchTerm = "";
});
},
),
],
),
),
)
: null,
),
Expanded(
child: SearchableCoinList(
coins: coins,
isDesktop: true,
searchTerm: _searchTerm,
),
),
],
),
),
),
),
Expanded(
child: SearchableCoinList(
coins: coins,
isDesktop: true,
searchTerm: _searchTerm,
),
),
],
),
const SizedBox(
height: 16,
),
const SizedBox(
height: 70,
width: 480,
child: AddWalletNextButton(
isDesktop: true,
),
),
const SizedBox(
height: 32,
),
],
),
),
),
const SizedBox(
height: 16,
),
const SizedBox(
height: 70,
width: 480,
child: AddWalletNextButton(
isDesktop: true,
),
),
const SizedBox(
height: 32,
),
],
),
);

View file

@ -1,11 +1,16 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:stackwallet/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.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_scaffold.dart';
import 'package:tuple/tuple.dart';
class CreateOrRestoreWalletView extends StatelessWidget {
@ -22,97 +27,234 @@ class CreateOrRestoreWalletView extends StatelessWidget {
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
final isDesktop =
Platform.isLinux || Platform.isWindows || Platform.isMacOS;
if (isDesktop) {
return DesktopScaffold(
appBar: const DesktopAppBar(
isCompactHeight: false,
leading: AppBarBackButton(),
trailing: ExitToMyStackButton(),
),
),
body: Container(
color: CFColors.almostWhite,
child: Padding(
padding: const EdgeInsets.all(16),
body: SizedBox(
width: 480,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(31),
child: Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
width: MediaQuery.of(context).size.width / 3,
),
),
const Spacer(
flex: 2,
),
Text(
"Add ${coin.prettyName} wallet",
textAlign: TextAlign.center,
style: STextStyles.pageTitleH1,
const Spacer(),
CreateRestoreWalletTitle(
coin: coin,
isDesktop: isDesktop,
),
const SizedBox(
height: 8,
height: 16,
),
Text(
"Create a new wallet or restore an existing wallet from seed.",
textAlign: TextAlign.center,
style: STextStyles.subtitle),
const Spacer(
flex: 5,
),
TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent,
),
),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.New,
coin,
),
);
},
child: Text(
"Create new wallet",
style: STextStyles.button,
),
CreateRestoreWalletSubTitle(
isDesktop: isDesktop,
),
const SizedBox(
height: 12,
height: 32,
),
TextButton(
style: Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.stackAccent.withOpacity(0.25),
),
),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.Restore,
coin,
),
);
},
child: Text(
"Restore wallet",
style: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
),
CoinImage(
coin: coin,
isDesktop: isDesktop,
),
const SizedBox(
height: 32,
),
CreateWalletButtonGroup(
coin: coin,
isDesktop: isDesktop,
),
const Spacer(),
const SizedBox(
height: kDesktopAppBarHeight,
),
],
),
),
),
);
} else {
return Scaffold(
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
Navigator.of(context).pop();
},
),
),
body: Container(
color: CFColors.background,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.all(31),
child: CoinImage(
coin: coin,
isDesktop: isDesktop,
),
),
const Spacer(
flex: 2,
),
CreateRestoreWalletTitle(
coin: coin,
isDesktop: isDesktop,
),
const SizedBox(
height: 8,
),
CreateRestoreWalletSubTitle(
isDesktop: isDesktop,
),
const Spacer(
flex: 5,
),
CreateWalletButtonGroup(
coin: coin,
isDesktop: isDesktop,
),
],
),
),
),
);
}
}
}
class CreateRestoreWalletTitle extends StatelessWidget {
const CreateRestoreWalletTitle({
Key? key,
required this.coin,
required this.isDesktop,
}) : super(key: key);
final Coin coin;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Text(
"Add ${coin.prettyName} wallet",
textAlign: TextAlign.center,
style: isDesktop ? STextStyles.desktopH2 : STextStyles.pageTitleH1,
);
}
}
class CreateRestoreWalletSubTitle extends StatelessWidget {
const CreateRestoreWalletSubTitle({
Key? key,
required this.isDesktop,
}) : super(key: key);
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Text(
"Create a new wallet or restore an existing wallet from seed.",
textAlign: TextAlign.center,
style: isDesktop ? STextStyles.desktopSubtitleH2 : STextStyles.subtitle,
);
}
}
class CoinImage extends StatelessWidget {
const CoinImage({
Key? key,
required this.coin,
required this.isDesktop,
}) : super(key: key);
final Coin coin;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Image(
image: AssetImage(
Assets.png.imageFor(coin: coin),
),
width: isDesktop ? 324 : MediaQuery.of(context).size.width / 3,
);
}
}
class CreateWalletButtonGroup extends StatelessWidget {
const CreateWalletButtonGroup({
Key? key,
required this.coin,
required this.isDesktop,
}) : super(key: key);
final Coin coin;
final bool isDesktop;
@override
Widget build(BuildContext context) {
return Column(
children: [
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
minWidth: isDesktop ? 480 : 0,
),
child: TextButton(
style: CFColors.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.New,
coin,
),
);
},
child: Text(
"Create new wallet",
style: isDesktop
? STextStyles.desktopButtonEnabled
: STextStyles.button,
),
),
),
SizedBox(
height: isDesktop ? 16 : 12,
),
ConstrainedBox(
constraints: BoxConstraints(
minHeight: isDesktop ? 70 : 0,
minWidth: isDesktop ? 480 : 0,
),
child: TextButton(
style: CFColors.getSecondaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(
NameYourWalletView.routeName,
arguments: Tuple2(
AddWalletType.Restore,
coin,
),
);
},
child: Text(
"Restore wallet",
style: isDesktop
? STextStyles.desktopButtonSecondaryEnabled
: STextStyles.button.copyWith(
color: CFColors.stackAccent,
),
),
),
),
],
);
}
}

View file

@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_app_bar.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
@ -13,6 +12,8 @@ import 'package:stackwallet/utilities/enums/flush_bar_type.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/text_styles.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_scaffold.dart';
import 'package:stackwallet/widgets/progress_bar.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:zxcvbn/zxcvbn.dart';
@ -116,19 +117,19 @@ class _CreatePasswordViewState extends State<CreatePasswordView> {
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType ");
return Material(
child: Column(
return DesktopScaffold(
appBar: DesktopAppBar(
leading: AppBarBackButton(
onPressed: () async {
if (mounted) {
Navigator.of(context).pop();
}
},
),
isCompactHeight: false,
),
body: Column(
children: [
DesktopAppBar(
leading: AppBarBackButton(
onPressed: () async {
if (mounted) {
Navigator.of(context).pop();
}
},
),
isCompactHeight: false,
),
Expanded(
child: Center(
child: SizedBox(
@ -381,10 +382,7 @@ class _CreatePasswordViewState extends State<CreatePasswordView> {
),
),
const SizedBox(
// balance out height of "appbar"
// 56 = height of app bar buttons
// 20 = top and bottom padding
height: 56 + 20 + 20,
height: kDesktopAppBarHeight,
),
],
),

View file

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_menu.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
class DesktopHomeView extends ConsumerStatefulWidget {
@ -17,13 +16,13 @@ class DesktopHomeView extends ConsumerStatefulWidget {
class _DesktopHomeViewState extends ConsumerState<DesktopHomeView> {
int currentViewIndex = 0;
final List<Widget> contentViews = [
const Navigator(
onGenerateRoute: RouteGenerator.generateRoute,
initialRoute: MyStackView.routeName,
),
// const MyStackView(
// key: Key("myStackViewKey"),
// const Navigator(
// onGenerateRoute: RouteGenerator.generateRoute,
// initialRoute: MyStackView.routeName,
// ),
const MyStackView(
key: Key("myStackViewKey"),
),
Container(
color: Colors.green,
),

View file

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
import 'package:stackwallet/utilities/text_styles.dart';
class ExitToMyStackButton extends StatelessWidget {
const ExitToMyStackButton({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
right: 24,
),
child: SizedBox(
height: 56,
child: TextButton(
style: CFColors.getSmallSecondaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).popUntil(
ModalRoute.withName(DesktopHomeView.routeName),
);
},
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30,
),
child: Text(
"Exit to My Stack",
style: STextStyles.desktopButtonSmallSecondaryEnabled,
),
),
),
),
);
}
}

View file

@ -2,16 +2,15 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/pages/wallets_view/sub_widgets/empty_wallets.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_app_bar.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
class MyStackView extends ConsumerStatefulWidget {
const MyStackView({Key? key}) : super(key: key);
static const String routeName = "/myStackDesktop";
@override

View file

@ -165,6 +165,7 @@ abstract class CFColors {
static const Color textFieldDefaultBackground = Color(0xFFEEEFF1);
static const Color buttonBackgroundPrimary = Color(0xFF232323);
static const Color buttonBackSecondary = Color(0xFFE0E3E3);
static const Color buttonBackPrimaryDisabled = Color(0xFFD7D7D7);
@ -185,7 +186,16 @@ abstract class CFColors {
),
);
static ButtonStyle? getSecondaryEnabledButtonColor(BuildContext context) =>
static ButtonStyle? getSecondaryEnabledButtonColor(
BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.buttonBackSecondary,
),
);
static ButtonStyle? getSmallSecondaryEnabledButtonColor(
BuildContext context) =>
Theme.of(context).textButtonTheme.style?.copyWith(
backgroundColor: MaterialStateProperty.all<Color>(
CFColors.textFieldDefaultBackground,

View file

@ -187,6 +187,13 @@ class STextStyles {
height: 26 / 20,
);
static final TextStyle desktopButtonSecondaryEnabled = GoogleFonts.inter(
color: CFColors.buttonTextSecondary,
fontWeight: FontWeight.w500,
fontSize: 20,
height: 26 / 20,
);
static final TextStyle desktopTextExtraSmall = GoogleFonts.inter(
color: CFColors.buttonTextPrimaryDisabled,
fontWeight: FontWeight.w500,
@ -194,7 +201,7 @@ class STextStyles {
height: 24 / 16,
);
static final TextStyle desktopButtonSecondaryEnabled = GoogleFonts.inter(
static final TextStyle desktopButtonSmallSecondaryEnabled = GoogleFonts.inter(
color: CFColors.buttonTextSecondary,
fontWeight: FontWeight.w500,
fontSize: 16,

View file

@ -48,9 +48,9 @@ class AppBarIconButton extends StatelessWidget {
}
class AppBarBackButton extends StatelessWidget {
const AppBarBackButton({Key? key, required this.onPressed}) : super(key: key);
const AppBarBackButton({Key? key, this.onPressed}) : super(key: key);
final VoidCallback onPressed;
final VoidCallback? onPressed;
@override
Widget build(BuildContext context) {
@ -74,7 +74,7 @@ class AppBarBackButton extends StatelessWidget {
width: 24,
height: 24,
),
onPressed: onPressed,
onPressed: onPressed ?? Navigator.of(context).pop,
),
);
}

View file

@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/cfcolors.dart';
class DesktopScaffold extends StatelessWidget {
const DesktopScaffold({
Key? key,
this.background = CFColors.background,
this.appBar,
this.body,
}) : super(key: key);
final Color background;
final Widget? appBar;
final Widget? body;
@override
Widget build(BuildContext context) {
return Material(
color: background,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (appBar != null) appBar!,
if (body != null)
Expanded(
child: body!,
),
],
),
);
}
}