Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions lib/models/exchange/response_objects/trade.dart
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,30 @@ class Trade {
);
}

/// Statuses that indicate a trade has reached an end state and is no longer
/// expected to change. Trades in one of these states can be safely deleted.
static const Set<String> terminalStatuses = {
"Finished",
"finished",
"completed",
"Completed",
"Failed",
"failed",
"Refunded",
"refunded",
"Expired",
"expired",
"Closed",
"closed",
};

/// Whether this trade has reached a terminal (finished/expired/etc) state.
bool get isTerminalStatus => terminalStatuses.contains(status);

/// Whether this trade is still in progress (waiting, new, processing, etc).
/// These trades can still be deleted but only behind a stronger warning.
bool get isInProgress => !isTerminalStatus;

@override
String toString() {
return toMap().toString();
Expand Down
154 changes: 154 additions & 0 deletions lib/pages/exchange_view/trade_details_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import '../../widgets/conditional_parent.dart';
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
import '../../widgets/custom_buttons/blue_text_button.dart';
import '../../widgets/desktop/desktop_dialog.dart';
import '../../widgets/desktop/primary_button.dart';
import '../../widgets/desktop/secondary_button.dart';
import '../../widgets/qr.dart';
import '../../widgets/rounded_container.dart';
Expand Down Expand Up @@ -212,6 +213,128 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
trade.status == "wait" ||
trade.status == "Waiting");

final isTerminalStatus = trade.isTerminalStatus;

void deleteTrade() {
if (isDesktop) {
showDialog<void>(
context: context,
builder: (_) => DesktopDialog(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use SDIalog with dynamic height sizing to fit content (NO HARDCODED HEIGHT)

maxWidth: 450,
maxHeight: 300,
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
children: [
Text(
isTerminalStatus
? "Delete this trade?"
: "Delete an active trade?",
style: STextStyles.desktopH3(context),
),
const SizedBox(height: 16),
Text(
isTerminalStatus
? "Trade will be deleted permanently!"
: "This trade is still active and has not finished. "
"Deleting it will permanently remove it from your "
"device and you will no longer be able to track "
"its status. Proceed only if you know what you "
"are doing.",
style: STextStyles.desktopTextSmall(context),
),
const Spacer(),
Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
buttonHeight: ButtonHeight.l,
onPressed: Navigator.of(context).pop,
),
),
const SizedBox(width: 16),
Expanded(
child: PrimaryButton(
label: "Delete",
buttonHeight: ButtonHeight.l,
onPressed: () async {
await ref
.read(tradesServiceProvider)
.delete(
trade: trade,
shouldNotifyListeners: true,
);
if (context.mounted) {
Navigator.of(
context,
).pop(); // close confirm dialog
Navigator.of(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

confirm dialog should only pop itself. Let the details dialog decide to pop itself based on the response from the confirm dialog

context,
rootNavigator: true,
).pop(); // close trade details dialog
}
},
),
),
],
),
],
),
),
),
);
return;
}
showDialog<dynamic>(
context: context,
useSafeArea: true,
barrierDismissible: true,
builder: (_) => StackDialog(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might as well use SDialog here as well and then a single dialog can be shown so there is less code to write and less code to maintain and less code to trouble shoot and l;ess code to test

title: isTerminalStatus
? "Delete this trade?"
: "Delete an active trade?",
message: isTerminalStatus
? "Trade will be deleted permanently!"
: "This trade is still active and has not finished. "
"Deleting it will permanently remove it from your "
"device and you will no longer be able to track its "
"status. Proceed only if you know what you are doing.",
leftButton: TextButton(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use SecondaryButton

style: Theme.of(
context,
).extension<StackColors>()!.getSecondaryEnabledButtonStyle(context),
child: Text("Cancel", style: STextStyles.itemSubtitle12(context)),
onPressed: () {
Navigator.of(context).pop();
},
),
rightButton: TextButton(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use PrimaryButton

style: Theme.of(
context,
).extension<StackColors>()!.getPrimaryEnabledButtonStyle(context),
child: Text("Delete", style: STextStyles.button(context)),
onPressed: () async {
await ref
.read(tradesServiceProvider)
.delete(trade: trade, shouldNotifyListeners: true);
if (context.mounted) {
Navigator.of(context).pop();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again see above comment re pops

Navigator.of(context).pop();
unawaited(
showFloatingFlushBar(
type: FlushBarType.success,
message: "Trade deleted",
context: context,
),
);
}
},
),
),
);
}

return ConditionalParent(
condition: !isDesktop,
builder: (child) => Background(
Expand All @@ -232,6 +355,31 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
"Trade details",
style: STextStyles.navBarTitle(context),
),
actions: [
Padding(
padding: const EdgeInsets.only(top: 10, bottom: 10, right: 10),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("tradeDetailsViewDeleteTradeButtonKey"),
size: 36,
shadows: const [],
color: Theme.of(
context,
).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.trash,
color: Theme.of(
context,
).extension<StackColors>()!.accentColorDark,
width: 20,
height: 20,
),
onPressed: deleteTrade,
),
),
),
],
),
body: SafeArea(
child: Padding(
Expand Down Expand Up @@ -295,6 +443,12 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
);
},
),
const SizedBox(height: 16),
SecondaryButton(
label: "Delete trade",
buttonHeight: ButtonHeight.l,
onPressed: deleteTrade,
),
const SizedBox(height: 32),
],
),
Expand Down
Loading