desktop send/receive + transactions for eth view

This commit is contained in:
julian 2023-04-07 13:38:55 -06:00
parent b820b113e4
commit 387e2d8403
6 changed files with 277 additions and 254 deletions

View file

@ -252,6 +252,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
},
child: Util.isDesktop
? ListView.separated(
shrinkWrap: true,
itemBuilder: (context, index) {
BorderRadius? radius;
if (_transactions2.length == 1) {

View file

@ -39,6 +39,8 @@ class DesktopTokenView extends ConsumerStatefulWidget {
}
class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
static const double sendReceiveColumnWidth = 460;
late final WalletSyncStatus initialSyncStatus;
@override
@ -168,17 +170,16 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
const SizedBox(
height: 24,
),
Expanded(
child: Row(
Row(
children: [
SizedBox(
width: 450,
child: MyWallet(
walletId: widget.walletId,
contractAddress: ref.watch(
tokenServiceProvider.select(
(value) => value!.tokenContract.address,
),
width: sendReceiveColumnWidth,
child: Text(
"My wallet",
style: STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconLeft,
),
),
),
@ -186,15 +187,13 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
width: 16,
),
Expanded(
child: Column(
children: [
Row(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Recent transactions",
style: STextStyles.desktopTextExtraSmall(context)
.copyWith(
style:
STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconLeft,
@ -211,8 +210,29 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
),
],
),
),
],
),
const SizedBox(
height: 16,
height: 14,
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: sendReceiveColumnWidth,
child: MyWallet(
walletId: widget.walletId,
contractAddress: ref.watch(
tokenServiceProvider.select(
(value) => value!.tokenContract.address,
),
),
),
),
const SizedBox(
width: 16,
),
Expanded(
child: TokenTransactionsList(
@ -225,9 +245,6 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> {
],
),
),
],
),
),
);
}
}

View file

@ -309,6 +309,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: sendReceiveColumnWidth,

View file

@ -1,12 +1,15 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/send_receive_tab_menu.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/providers/global/wallets_provider.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/widgets/custom_tab_view.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
class MyWallet extends StatefulWidget {
class MyWallet extends ConsumerStatefulWidget {
const MyWallet({
Key? key,
required this.walletId,
@ -17,67 +20,82 @@ class MyWallet extends StatefulWidget {
final String? contractAddress;
@override
State<MyWallet> createState() => _MyWalletState();
ConsumerState<MyWallet> createState() => _MyWalletState();
}
class _MyWalletState extends State<MyWallet> {
int _selectedIndex = 0;
class _MyWalletState extends ConsumerState<MyWallet> {
final titles = [
"Send",
"Receive",
];
late final bool isEth;
@override
void initState() {
isEth = ref
.read(walletsChangeNotifierProvider)
.getManager(widget.walletId)
.coin ==
Coin.ethereum;
if (isEth && widget.contractAddress == null) {
titles.add("Transactions");
}
super.initState();
}
@override
Widget build(BuildContext context) {
return ListView(
primary: false,
children: [
Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.vertical(
top: Radius.circular(
Constants.size.circularBorderRadius,
),
),
),
child: SendReceiveTabMenu(
onChanged: (index) {
setState(() {
_selectedIndex = index;
});
},
),
),
Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(
Constants.size.circularBorderRadius,
),
),
),
child: AnimatedCrossFade(
firstChild: Padding(
key: const Key("desktopSendViewPortKey"),
RoundedWhiteContainer(
padding: EdgeInsets.zero,
child: CustomTabView(
titles: titles,
children: [
widget.contractAddress == null
? Padding(
padding: const EdgeInsets.all(20),
child: widget.contractAddress == null
? DesktopSend(
child: DesktopSend(
walletId: widget.walletId,
),
)
: DesktopTokenSend(
: Padding(
padding: const EdgeInsets.all(20),
child: DesktopTokenSend(
walletId: widget.walletId,
),
),
secondChild: Padding(
key: const Key("desktopReceiveViewPortKey"),
Padding(
padding: const EdgeInsets.all(20),
child: DesktopReceive(
walletId: widget.walletId,
contractAddress: widget.contractAddress,
),
),
crossFadeState: _selectedIndex == 0
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 250),
if (isEth && widget.contractAddress == null)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height - 362,
),
child: TransactionsList(
walletId: widget.walletId,
managerProvider: ref.watch(
walletsChangeNotifierProvider.select(
(value) => value.getManagerProvider(
widget.walletId,
),
),
),
),
),
),
],
),
),
],

View file

@ -1,165 +0,0 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class SendReceiveTabMenu extends StatefulWidget {
const SendReceiveTabMenu({
Key? key,
this.initialIndex = 0,
this.onChanged,
}) : super(key: key);
final int initialIndex;
final void Function(int)? onChanged;
@override
State<SendReceiveTabMenu> createState() => _SendReceiveTabMenuState();
}
class _SendReceiveTabMenuState extends State<SendReceiveTabMenu> {
late int _selectedIndex;
void _onChanged(int newIndex) {
if (_selectedIndex != newIndex) {
setState(() {
_selectedIndex = newIndex;
});
widget.onChanged?.call(_selectedIndex);
}
}
@override
void initState() {
_selectedIndex = widget.initialIndex;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () => _onChanged(0),
child: Container(
color: Colors.transparent,
child: Column(
children: [
const SizedBox(
height: 16,
),
AnimatedCrossFade(
firstChild: Text(
"Send",
style:
STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorBlue,
),
),
secondChild: Text(
"Send",
style:
STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
crossFadeState: _selectedIndex == 0
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 250),
),
const SizedBox(
height: 19,
),
Container(
height: 2,
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.backgroundAppBar,
),
),
],
),
),
),
),
),
Expanded(
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () => _onChanged(1),
child: Container(
color: Colors.transparent,
child: Column(
children: [
const SizedBox(
height: 16,
),
AnimatedCrossFade(
firstChild: Text(
"Receive",
style:
STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorBlue,
),
),
secondChild: Text(
"Receive",
style:
STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
crossFadeState: _selectedIndex == 1
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 250),
),
const SizedBox(
height: 19,
),
Stack(
children: [
Container(
height: 2,
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.backgroundAppBar,
),
),
AnimatedSlide(
offset: Offset(_selectedIndex == 0 ? -1 : 0, 0),
duration: const Duration(milliseconds: 250),
child: Container(
height: 2,
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorBlue),
),
),
],
),
],
),
),
),
),
),
],
);
}
}

View file

@ -0,0 +1,151 @@
import 'package:flutter/material.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
class CustomTabView extends StatefulWidget {
const CustomTabView({
Key? key,
required this.titles,
required this.children,
this.initialIndex = 0,
this.childPadding,
}) : assert(titles.length == children.length),
super(key: key);
final List<String> titles;
final List<Widget> children;
final int initialIndex;
final EdgeInsets? childPadding;
@override
State<CustomTabView> createState() => _CustomTabViewState();
}
class _CustomTabViewState extends State<CustomTabView> {
final _key = GlobalKey();
late int _selectedIndex;
static const duration = Duration(milliseconds: 250);
@override
void initState() {
_selectedIndex = widget.initialIndex;
super.initState();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) => Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
for (int i = 0; i < widget.titles.length; i++)
Expanded(
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () => setState(() => _selectedIndex = i),
child: Container(
color: Colors.transparent,
child: Column(
children: [
const SizedBox(
height: 16,
),
AnimatedCrossFade(
firstChild: Text(
widget.titles[i],
style:
STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorBlue,
),
),
secondChild: Text(
widget.titles[i],
style:
STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
),
crossFadeState: _selectedIndex == i
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 250),
),
],
),
),
),
),
),
],
),
const SizedBox(
height: 19,
),
Stack(
children: [
Container(
height: 2,
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.backgroundAppBar,
),
),
AnimatedSlide(
offset: Offset(_selectedIndex.toDouble(), 0),
duration: duration,
child: Container(
height: 2,
width: constraints.maxWidth / widget.titles.length,
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorBlue,
),
),
),
],
),
AnimatedSwitcher(
key: _key,
duration: duration,
transitionBuilder: (child, animation) {
return FadeTransition(
opacity: animation,
child: child,
);
},
layoutBuilder: (currentChild, prevChildren) {
return Stack(
alignment: Alignment.topCenter,
children: [
...prevChildren,
if (currentChild != null) currentChild,
],
);
},
child: AnimatedAlign(
key: Key(widget.titles[_selectedIndex]),
alignment: Alignment.topCenter,
duration: duration,
child: Padding(
padding: widget.childPadding ?? EdgeInsets.zero,
child: widget.children[_selectedIndex],
),
),
),
],
),
);
}
}