Skip to content

Commit

Permalink
flutter: redesign transaction list
Browse files Browse the repository at this point in the history
I'm done now! Not touching this screen for a long while
  • Loading branch information
octobocto committed Nov 2, 2023
1 parent 03d1def commit 5bf9adb
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 43 deletions.
189 changes: 149 additions & 40 deletions lib/pages/tabs/dashboard_tab_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import 'dart:convert';

import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get_it/get_it.dart';
import 'package:intl/intl.dart';
import 'package:logger/logger.dart';
import 'package:sail_ui/sail_ui.dart';
import 'package:sail_ui/theme/theme.dart';
import 'package:sail_ui/widgets/core/sail_snackbar.dart';
import 'package:sail_ui/widgets/core/sail_text.dart';
import 'package:sidesail/providers/balance_provider.dart';
import 'package:sidesail/providers/transactions_provider.dart';
Expand Down Expand Up @@ -78,45 +79,17 @@ class DashboardTabPage extends StatelessWidget {
titleTrailing: viewModel.transactions.length.toString(),
endWidget: SailToggle(label: 'Show raw', value: viewModel.showRaw, onChanged: viewModel.toggleRaw),
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
dataRowMaxHeight: viewModel.showRaw ? 350 : null,
columns: [
if (viewModel.showRaw) DataColumn(label: SailText.primary12('Raw')),
DataColumn(label: SailText.primary12('Category')),
DataColumn(label: SailText.primary12('Amount')),
DataColumn(label: SailText.primary12('Fee')),
DataColumn(label: SailText.primary12('TXID')),
DataColumn(label: SailText.primary12('Time')),
DataColumn(label: SailText.primary12('Address')),
DataColumn(label: SailText.primary12('Label')),
DataColumn(label: SailText.primary12('Account')),
],
rows: viewModel.transactions.map((tx) {
return DataRow(
cells: [
if (viewModel.showRaw)
DataCell(
SizedBox(
width: 600,
child: SailText.primary12(
const JsonEncoder.withIndent(' ').convert(jsonDecode(tx.raw)),
),
),
),
DataCell(SailText.primary12(tx.category)),
DataCell(SailText.primary12(tx.amount.toString())),
DataCell(SailText.primary12(tx.fee.toString())),
DataCell(SailText.primary12(tx.txid)),
DataCell(SailText.primary12(DateFormat('HH:mm MMM d').format(tx.time))),
DataCell(SailText.primary12(tx.address)),
DataCell(SailText.primary12(tx.label)),
DataCell(SailText.primary12(tx.account)),
],
);
}).toList(),
),
SailColumn(
spacing: 0,
withDivider: true,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (final tx in viewModel.transactions)
TxView(
showRAW: viewModel.showRaw,
tx: tx,
),
],
),
],
),
Expand All @@ -128,6 +101,142 @@ class DashboardTabPage extends StatelessWidget {
}
}

class TxView extends StatefulWidget {
final bool showRAW;
final Transaction tx;

const TxView({super.key, required this.showRAW, required this.tx});

@override
State<TxView> createState() => _TxViewState();
}

class _TxViewState extends State<TxView> {
bool expanded = false;
late Map<String, dynamic> decodedTx;
@override
void initState() {
super.initState();
decodedTx = jsonDecode(widget.tx.raw);
}

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: SailStyleValues.padding15,
horizontal: SailStyleValues.padding10,
),
child: SailColumn(
spacing: SailStyleValues.padding8,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SailScaleButton(
onPressed: () {
setState(() {
expanded = !expanded;
});
},
child: SingleValueView(
icon: widget.tx.confirmations >= 1
? Tooltip(
message: '${widget.tx.confirmations} confirmations',
child: SailSVG.icon(SailSVGAsset.iconConfirmed, width: 13),
)
: Tooltip(
message: 'Unconfirmed',
child: SailSVG.icon(SailSVGAsset.iconPending, width: 13),
),
copyable: false,
label: 'label',
value: extractTXTitle(widget.tx),
),
),
if (expanded) ExpandedTXView(decodedTX: decodedTx),
],
),
);
}

String extractTXTitle(Transaction tx) {
String title = '${tx.category} ${tx.amount.toStringAsFixed(8)} SBTC';

if (tx.address.isEmpty) {
return '$title in ${tx.txid}';
}

if (tx.amount.isNegative || tx.amount == 0) {
return '$title to ${tx.address}';
}

return '$title from ${tx.address}';
}
}

class ExpandedTXView extends StatelessWidget {
final Map<String, dynamic> decodedTX;

const ExpandedTXView({super.key, required this.decodedTX});

@override
Widget build(BuildContext context) {
return SailColumn(
spacing: SailStyleValues.padding8,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: decodedTX.keys.map((key) {
return SingleValueView(label: key, value: decodedTX[key]);
}).toList(),
);
}
}

class SingleValueView extends StatelessWidget {
final String label;
final dynamic value;
final Widget? icon;
final bool copyable;

const SingleValueView({
super.key,
required this.label,
required this.value,
this.icon,
this.copyable = true,
});

@override
Widget build(BuildContext context) {
final theme = SailTheme.of(context);
final messenger = ScaffoldMessenger.of(context);

return SailRow(
spacing: SailStyleValues.padding8,
children: [
if (icon != null)
icon!
else
const SizedBox(
width: 13,
),
SizedBox(
width: 110,
child: SailText.secondary12(label),
),
SailScaleButton(
onPressed: copyable
? () {
Clipboard.setData(ClipboardData(text: value.toString()));
showSnackBar(theme, messenger, 'Copied $label');
}
: null,
child: SailText.primary12(value.toString()),
),
],
);
}
}

class HomePageViewModel extends BaseViewModel {
final log = Logger(level: Level.debug);
BalanceProvider get _balanceProvider => GetIt.I.get<BalanceProvider>();
Expand Down
3 changes: 3 additions & 0 deletions packages/sail_ui/assets/svgs/icon_pending.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/sail_ui/assets/svgs/icon_pending_half.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/sail_ui/assets/svgs/icon_success.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/sail_ui/lib/style/color.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class SailColor {
shadow: SailColorScheme.greyLight.withOpacity(0.18),
text: SailColorScheme.whiteLight,
textSecondary: SailColorScheme.darkTextSecondary,
textTertiary: SailColorScheme.greyMiddle,
textTertiary: SailColorScheme.darkTextTertiary,
textHint: SailColorScheme.darkTextHint,
orange: SailColorScheme.orange,
disabledPrimaryButton: SailColorScheme.orange.withOpacity(0.4),
Expand Down
1 change: 1 addition & 0 deletions packages/sail_ui/lib/style/color_scheme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ abstract class SailColorScheme {
static const darkDivider = Color(0xff212234);
static const darkChip = Color.fromRGBO(124, 124, 164, 0.1); // #7C7CA4
static const darkTextSecondary = Color(0xffD2D3E0);
static const darkTextTertiary = Color(0xff858699);
// modal colors
static const darkActionModalBackground = Color.fromRGBO(29, 30, 43, 1);
static const darkTextHint = Color(0xff4D4F69);
Expand Down
1 change: 1 addition & 0 deletions packages/sail_ui/lib/widgets/core/sail_snackbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void showSnackBar(

messenger.showSnackBar(
SnackBar(
duration: const Duration(seconds: 1),
behavior: SnackBarBehavior.fixed,
backgroundColor: theme.colors.background,
content: SailPadding(
Expand Down
11 changes: 10 additions & 1 deletion packages/sail_ui/lib/widgets/core/sail_svg.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ enum SailSVGAsset {
iconSidechain,

iconCopy,
iconDropdown
iconDropdown,
iconConfirmed,
iconPending
}

/// If you don't want to overwrite the color of the svg, put it in here!
Expand All @@ -22,6 +24,8 @@ enum SailSVGAsset {
const coloredAssets = [
SailSVGAsset.iconMainchain,
SailSVGAsset.iconSidechain,
SailSVGAsset.iconConfirmed,
SailSVGAsset.iconPending,
];

class SailSVG {
Expand Down Expand Up @@ -78,6 +82,11 @@ extension AsAssetPath on SailSVGAsset {
return 'assets/svgs/icon_copy.svg';
case SailSVGAsset.iconDropdown:
return 'assets/svgs/icon_dropdown.svg';

case SailSVGAsset.iconConfirmed:
return 'assets/svgs/icon_success.svg';
case SailSVGAsset.iconPending:
return 'assets/svgs/icon_pending.svg';
}
}
}
2 changes: 1 addition & 1 deletion packages/sail_ui/lib/widgets/core/sail_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class SailText {
final theme = SailTheme.of(context);
return _Text(
label: label,
style: SailStyleValues.regular12.copyWith(color: theme.colors.text),
style: SailStyleValues.regular12.copyWith(color: theme.colors.textTertiary),
textAlign: textAlign,
);
},
Expand Down

0 comments on commit 5bf9adb

Please sign in to comment.