mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
desktop send/receive + transactions for eth view
This commit is contained in:
parent
b820b113e4
commit
387e2d8403
6 changed files with 277 additions and 254 deletions
|
@ -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) {
|
||||
|
|
|
@ -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> {
|
|||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -309,6 +309,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
|||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: sendReceiveColumnWidth,
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
151
lib/widgets/custom_tab_view.dart
Normal file
151
lib/widgets/custom_tab_view.dart
Normal 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],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue