mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
dynamic max fee rate value (#1395)
This commit is contained in:
parent
190c8e06b9
commit
9ff6da3d5d
12 changed files with 54 additions and 9 deletions
|
@ -291,4 +291,10 @@ class CWBitcoin extends Bitcoin {
|
|||
outputsCount,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
int getMaxCustomFeeRate(Object wallet) {
|
||||
final bitcoinWallet = wallet as ElectrumWallet;
|
||||
return (bitcoinWallet.feeRate(BitcoinTransactionPriority.fast) * 1.1).round();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -675,6 +675,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
|
|||
final selectedItem = items.indexOf(sendViewModel.transactionPriority);
|
||||
final customItemIndex = sendViewModel.getCustomPriorityIndex(items);
|
||||
final isBitcoinWallet = sendViewModel.walletType == WalletType.bitcoin;
|
||||
final maxCustomFeeRate = sendViewModel.maxCustomFeeRate?.toDouble();
|
||||
double? customFeeRate = isBitcoinWallet ? sendViewModel.customBitcoinFeeRate.toDouble() : null;
|
||||
|
||||
await showPopUp<void>(
|
||||
|
@ -689,6 +690,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
|
|||
sendViewModel.displayFeeRate(priority, customFeeRate?.round()),
|
||||
selectedAtIndex: selectedIdx,
|
||||
customItemIndex: customItemIndex,
|
||||
maxValue: maxCustomFeeRate,
|
||||
title: S.of(context).please_select,
|
||||
headerEnabled: !isBitcoinWallet,
|
||||
closeOnItemSelected: !isBitcoinWallet,
|
||||
|
|
|
@ -37,6 +37,7 @@ class OtherSettingsPage extends BasePage {
|
|||
customItemIndex: _otherSettingsViewModel.customPriorityItemIndex,
|
||||
onItemSelected: _otherSettingsViewModel.onDisplayBitcoinPrioritySelected,
|
||||
customValue: _otherSettingsViewModel.customBitcoinFeeRate,
|
||||
maxValue: _otherSettingsViewModel.maxCustomFeeRate?.toDouble(),
|
||||
) :
|
||||
SettingsPickerCell(
|
||||
title: S.current.settings_fee_priority,
|
||||
|
|
|
@ -15,6 +15,7 @@ class SettingsPriorityPickerCell<ItemType> extends StandardListRow {
|
|||
this.isGridView = false,
|
||||
this.matchingCriteria,
|
||||
this.customValue,
|
||||
this.maxValue,
|
||||
this.customItemIndex,
|
||||
this.onItemSelected})
|
||||
: super(
|
||||
|
@ -34,6 +35,7 @@ class SettingsPriorityPickerCell<ItemType> extends StandardListRow {
|
|||
displayItem: (ItemType item) => displayItem!(item, sliderValue.round()),
|
||||
selectedAtIndex: selectedAtIndex,
|
||||
customItemIndex: customItemIndex,
|
||||
maxValue: maxValue,
|
||||
headerEnabled: false,
|
||||
closeOnItemSelected: false,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
@ -61,6 +63,7 @@ class SettingsPriorityPickerCell<ItemType> extends StandardListRow {
|
|||
final bool isGridView;
|
||||
final bool Function(ItemType, String)? matchingCriteria;
|
||||
double? customValue;
|
||||
double? maxValue;
|
||||
int? customItemIndex;
|
||||
|
||||
@override
|
||||
|
|
|
@ -10,6 +10,7 @@ class StandardPickerListItem<T> extends TransactionDetailsListItem {
|
|||
required this.onItemSelected,
|
||||
required this.selectedIdx,
|
||||
required this.customItemIndex,
|
||||
this.maxValue,
|
||||
required this.customValue})
|
||||
: super(title: title, value: value);
|
||||
|
||||
|
@ -18,6 +19,7 @@ class StandardPickerListItem<T> extends TransactionDetailsListItem {
|
|||
final Function(double) onSliderChanged;
|
||||
final Function(T) onItemSelected;
|
||||
final int selectedIdx;
|
||||
final double? maxValue;
|
||||
final int customItemIndex;
|
||||
double customValue;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ class RBFDetailsPage extends BasePage {
|
|||
selectedIdx: item.selectedIdx,
|
||||
customItemIndex: item.customItemIndex,
|
||||
customValue: item.customValue,
|
||||
maxValue: item.maxValue,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,21 @@ class Picker<Item> extends StatefulWidget {
|
|||
this.headerEnabled = true,
|
||||
this.closeOnItemSelected = true,
|
||||
this.sliderValue,
|
||||
this.minValue,
|
||||
this.maxValue,
|
||||
this.customItemIndex,
|
||||
this.isWrapped = true,
|
||||
this.borderColor,
|
||||
this.onSliderChanged,
|
||||
this.matchingCriteria,
|
||||
}) : assert(hintText == null ||
|
||||
matchingCriteria !=
|
||||
null); // make sure that if the search field is enabled then there is a searching criteria provided
|
||||
}) : assert(hintText == null || matchingCriteria != null) {
|
||||
// make sure that if the search field is enabled then there is a searching criteria provided
|
||||
if (sliderValue != null && maxValue != null) {
|
||||
if (sliderValue! > maxValue!) {
|
||||
sliderValue = maxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int selectedAtIndex;
|
||||
final List<Item> items;
|
||||
|
@ -49,12 +56,14 @@ class Picker<Item> extends StatefulWidget {
|
|||
final String? hintText;
|
||||
final bool headerEnabled;
|
||||
final bool closeOnItemSelected;
|
||||
final double? sliderValue;
|
||||
double? sliderValue;
|
||||
final double? minValue;
|
||||
final int? customItemIndex;
|
||||
final bool isWrapped;
|
||||
final Color? borderColor;
|
||||
final Function(double)? onSliderChanged;
|
||||
final bool Function(Item, String)? matchingCriteria;
|
||||
final double? maxValue;
|
||||
|
||||
@override
|
||||
_PickerState<Item> createState() => _PickerState<Item>(items, images, onItemSelected);
|
||||
|
@ -138,7 +147,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
|
|||
containerHeight = height * 0.75;
|
||||
}
|
||||
|
||||
final content = Column (
|
||||
final content = Column(
|
||||
children: [
|
||||
if (widget.title?.isNotEmpty ?? false)
|
||||
Container(
|
||||
|
@ -211,8 +220,9 @@ class _PickerState<Item> extends State<Picker<Item>> {
|
|||
fontWeight: FontWeight.w500,
|
||||
fontFamily: 'Lato',
|
||||
decoration: TextDecoration.none,
|
||||
color:
|
||||
Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
color: Theme.of(context)
|
||||
.extension<CakeTextTheme>()!
|
||||
.titleColor,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -491,8 +501,8 @@ class _PickerState<Item> extends State<Picker<Item>> {
|
|||
child: Slider(
|
||||
value: widget.sliderValue ?? 1,
|
||||
onChanged: isActivated ? widget.onSliderChanged : null,
|
||||
min: 1,
|
||||
max: 100,
|
||||
min: widget.minValue ?? 1,
|
||||
max: widget.maxValue ?? 100,
|
||||
divisions: 100,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -15,6 +15,7 @@ class StandardPickerList<T> extends StatefulWidget {
|
|||
required this.selectedIdx,
|
||||
required this.customItemIndex,
|
||||
required this.customValue,
|
||||
this.maxValue,
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
@ -26,6 +27,7 @@ class StandardPickerList<T> extends StatefulWidget {
|
|||
final String value;
|
||||
final int selectedIdx;
|
||||
final double customValue;
|
||||
final double? maxValue;
|
||||
|
||||
@override
|
||||
_StandardPickerListState<T> createState() => _StandardPickerListState<T>();
|
||||
|
@ -59,6 +61,7 @@ class _StandardPickerListState<T> extends State<StandardPickerList<T>> {
|
|||
displayItem: adaptedDisplayItem,
|
||||
selectedAtIndex: selectedIdx,
|
||||
customItemIndex: widget.customItemIndex,
|
||||
maxValue: widget.maxValue,
|
||||
headerEnabled: false,
|
||||
closeOnItemSelected: false,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
|
|
@ -166,6 +166,13 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
|||
return null;
|
||||
}
|
||||
|
||||
int? get maxCustomFeeRate {
|
||||
if (wallet.type == WalletType.bitcoin) {
|
||||
return bitcoin!.getMaxCustomFeeRate(wallet);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@computed
|
||||
int get customBitcoinFeeRate => _settingsStore.customBitcoinFeeRate;
|
||||
|
||||
|
|
|
@ -140,6 +140,13 @@ abstract class OtherSettingsViewModelBase with Store {
|
|||
return customItem != null ? priorities.indexOf(customItem) : null;
|
||||
}
|
||||
|
||||
int? get maxCustomFeeRate {
|
||||
if (_wallet.type == WalletType.bitcoin) {
|
||||
return bitcoin!.getMaxCustomFeeRate(_wallet);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@action
|
||||
ProviderType onBuyProviderTypeSelected(ProviderType buyProviderType) =>
|
||||
_settingsStore.defaultBuyProviders[walletType] = buyProviderType;
|
||||
|
|
|
@ -348,12 +348,14 @@ abstract class TransactionDetailsViewModelBase with Store {
|
|||
final customItem = priorities.firstWhereOrNull(
|
||||
(element) => element == sendViewModel.bitcoinTransactionPriorityCustom);
|
||||
final customItemIndex = customItem != null ? priorities.indexOf(customItem) : null;
|
||||
final maxCustomFeeRate = sendViewModel.maxCustomFeeRate?.toDouble();
|
||||
|
||||
RBFListItems.add(StandardPickerListItem(
|
||||
title: S.current.estimated_new_fee,
|
||||
value: bitcoin!.formatterBitcoinAmountToString(amount: newFee) + ' ${walletTypeToCryptoCurrency(wallet.type)}',
|
||||
items: priorityForWalletType(wallet.type),
|
||||
customValue: settingsStore.customBitcoinFeeRate.toDouble(),
|
||||
maxValue: maxCustomFeeRate,
|
||||
selectedIdx: selectedItem,
|
||||
customItemIndex: customItemIndex ?? 0,
|
||||
displayItem: (dynamic priority, double sliderValue) =>
|
||||
|
|
|
@ -159,6 +159,7 @@ abstract class Bitcoin {
|
|||
Future<bool> isChangeSufficientForFee(Object wallet, String txId, String newFee);
|
||||
int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
|
||||
int getFeeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size});
|
||||
int getMaxCustomFeeRate(Object wallet);
|
||||
}
|
||||
""";
|
||||
|
||||
|
|
Loading…
Reference in a new issue