Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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/views/market_maker_bot/buy_coin_select_dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:web_dex/model/forms/coin_trade_amount_input.dart';
import 'package:web_dex/views/market_maker_bot/coin_selection_and_amount_input.dart';
import 'package:web_dex/views/market_maker_bot/coin_trade_amount_form_field.dart';
import 'package:web_dex/views/market_maker_bot/market_maker_form_error_message_extensions.dart';
import 'package:web_dex/shared/utils/utils.dart';

class BuyCoinSelectDropdown extends StatelessWidget {
const BuyCoinSelectDropdown({
Expand All @@ -26,6 +27,29 @@ class BuyCoinSelectDropdown extends StatelessWidget {
Widget build(BuildContext context) {
return CoinSelectionAndAmountInput(
coins: coins,
refine: (list) {
// Order: active with balance (top), active without balance (middle), inactive (bottom)
final sdk = context.sdk;
int rank(Coin c) {
final hasBalance = (c.lastKnownUsdBalance(sdk) ?? 0) > 0;
if (c.isActive && hasBalance) return 0;
if (c.isActive) return 1;
return 2;
}
final sorted = List<Coin>.from(list);
sorted.sort((a, b) {
final ra = rank(a);
final rb = rank(b);
if (ra != rb) return ra - rb;
// Within rank, keep existing priority/balance sorting from upstream by
// comparing their current position heuristically via usd balance desc then abbr
final ba = a.lastKnownUsdBalance(sdk) ?? 0.0;
final bb = b.lastKnownUsdBalance(sdk) ?? 0.0;
if (ba != bb) return bb.compareTo(ba);
return a.abbr.compareTo(b.abbr);
});
return sorted;
},
title: LocaleKeys.buy.tr(),
selectedCoin: buyCoin.value,
onItemSelected: onItemSelected,
Expand Down
45 changes: 45 additions & 0 deletions lib/views/market_maker_bot/coin_search_dropdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:komodo_ui/komodo_ui.dart';
import 'package:web_dex/bloc/coins_bloc/coins_repo.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:web_dex/bloc/coins_manager/coins_manager_bloc.dart';
import 'package:web_dex/router/state/routing_state.dart';
import 'package:web_dex/router/state/wallet_state.dart';
import 'package:web_dex/generated/codegen_loader.g.dart';
import 'package:web_dex/model/main_menu_value.dart';
import 'package:web_dex/generated/codegen_loader.g.dart';
import 'package:web_dex/shared/widgets/coin_item/coin_item_body.dart';

Expand Down Expand Up @@ -133,6 +139,10 @@ class _CoinDropdownState extends State<CoinDropdown> {
_overlayEntry = null;
},
maxHeight: dropdownHeight,
onClose: () {
_overlayEntry?.remove();
_overlayEntry = null;
},
),
),
],
Expand Down Expand Up @@ -168,11 +178,13 @@ class _SearchableDropdown extends StatefulWidget {
final List<DropdownMenuItem<String>> items;
final ValueChanged<String?> onItemSelected;
final double maxHeight;
final VoidCallback? onClose;

const _SearchableDropdown({
required this.items,
required this.onItemSelected,
this.maxHeight = 300,
this.onClose,
});

@override
Expand Down Expand Up @@ -252,6 +264,39 @@ class _SearchableDropdownState extends State<_SearchableDropdown> {
padding: const EdgeInsets.all(16),
child: Text(LocaleKeys.nothingFound.tr()),
),
const Divider(height: 1),
_AddAssetsFooter(onClose: widget.onClose),
],
),
),
);
}
}

class _AddAssetsFooter extends StatelessWidget {
const _AddAssetsFooter({this.onClose});
final VoidCallback? onClose;

@override
Widget build(BuildContext context) {
return InkWell(
key: const Key('add-assets-dropdown-footer'),
onTap: () {
context
.read<CoinsManagerBloc>()
.add(const CoinsManagerCoinsListReset(CoinsManagerAction.add));
routingState.selectedMenu = MainMenuValue.wallet;
routingState.walletState.action = coinsManagerRouteAction.addAssets;
onClose?.call();
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.add_circle_outline),
const SizedBox(width: 8),
Text(LocaleKeys.addAssets.tr()),
],
),
),
Expand Down
55 changes: 31 additions & 24 deletions lib/views/market_maker_bot/coin_selection_and_amount_input.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class CoinSelectionAndAmountInput extends StatefulWidget {
this.trailing,
this.onItemSelected,
this.useFrontPlate = true,
this.refine,
});

final Coin? selectedCoin;
Expand All @@ -32,6 +33,9 @@ class CoinSelectionAndAmountInput extends StatefulWidget {
final Widget? trailing;
final Function(Coin?)? onItemSelected;
final bool useFrontPlate;
/// Optional refiner applied after default filtering/sorting to customize
/// ordering (e.g., activation/balance grouping for buy list).
final List<Coin> Function(List<Coin>)? refine;

@override
State<CoinSelectionAndAmountInput> createState() =>
Expand Down Expand Up @@ -63,31 +67,34 @@ class _CoinSelectionAndAmountInputState

late final _sdk = context.read<KomodoDefiSdk>();
void _prepareItems() {
_items =
prepareCoinsForTable(
context,
widget.coins,
null,
testCoinsEnabled: context
.read<SettingsBloc>()
.state
.testCoinsEnabled,
)
.map(
(coin) => DropdownMenuItem<String>(
value: coin.abbr,
child: CoinSelectItemWidget(
name: coin.displayName,
coinId: coin.abbr,
trailing: AssetBalanceText(
coin.toSdkAsset(_sdk).id,
activateIfNeeded: false,
),
title: CoinItemBody(coin: coin, size: CoinItemSize.large),
),
List<Coin> list = prepareCoinsForTable(
context,
widget.coins,
null,
testCoinsEnabled:
context.read<SettingsBloc>().state.testCoinsEnabled,
);

if (widget.refine != null) {
list = widget.refine!(list);
}

_items = list
.map(
(coin) => DropdownMenuItem<String>(
value: coin.abbr,
child: CoinSelectItemWidget(
name: coin.displayName,
coinId: coin.abbr,
trailing: AssetBalanceText(
coin.toSdkAsset(_sdk).id,
activateIfNeeded: false,
),
)
.toList();
title: CoinItemBody(coin: coin, size: CoinItemSize.large),
),
),
)
.toList();
}

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/views/market_maker_bot/market_maker_bot_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class _MakerFormMobileLayoutState extends State<_MakerFormMobileLayout> {
children: [
BlocBuilder<CoinsBloc, CoinsState>(
builder: (context, state) {
final coins = state.walletCoins.values
final coins = state.coins.values
.where((e) {
final usdPrice = e.usdPrice?.price?.toDouble() ?? 0.0;
return usdPrice > 0;
Expand Down
19 changes: 13 additions & 6 deletions lib/views/market_maker_bot/market_maker_bot_form_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class _MarketMakerBotFormContentState extends State<MarketMakerBotFormContent> {
key: const Key('$keyPrefix-sell-select'),
sellCoin: state.sellCoin,
sellAmount: state.sellAmount,
coins: _coinsWithUsdBalance(widget.coins),
coins: _sellableCoins(widget.coins),
minimumTradeVolume: state.minimumTradeVolume,
maximumTradeVolume: state.maximumTradeVolume,
onItemSelected: _onSelectSellCoin,
Expand Down Expand Up @@ -174,10 +174,13 @@ class _MarketMakerBotFormContentState extends State<MarketMakerBotFormContent> {
);
}

List<Coin> _coinsWithUsdBalance(List<Coin> coins) {
return coins
.where((coin) => (coin.lastKnownUsdBalance(context.sdk) ?? 0) > 0)
.toList();
List<Coin> _sellableCoins(List<Coin> coins) {
// Sell list: must be active, have balance, and have fiat price
return coins.where((coin) {
final hasUsdPrice = (coin.usdPrice?.price?.toDouble() ?? 0.0) > 0.0;
final hasBalance = (coin.lastKnownUsdBalance(context.sdk) ?? 0) > 0.0;
return coin.isActive && hasUsdPrice && hasBalance;
}).toList();
}

void _onMakeOrderPressed() {
Expand Down Expand Up @@ -208,7 +211,11 @@ class _MarketMakerBotFormContentState extends State<MarketMakerBotFormContent> {
}

List<Coin> _filteredCoinsList(Coin? coin) {
return widget.coins.where((e) => e.abbr != coin?.abbr).toList();
// Buy list: include all compatible coins with price data; exclude currently selected sell coin
return widget.coins
.where((e) => e.abbr != coin?.abbr)
.where((e) => (e.usdPrice?.price?.toDouble() ?? 0.0) > 0.0)
.toList();
}

void _onTradeMarginChanged(String value) {
Expand Down
Loading