mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-12-23 11:59:30 +00:00
stub pages for mobile and desktop
lots of extra code, lots of commented sections, the models are wrong, the pages just load on desktop and mobile. need to complete the form and ... well, there's a lot, really
This commit is contained in:
parent
30ea0cc24f
commit
290adfec21
12 changed files with 1318 additions and 60 deletions
428
lib/models/buy/buy_form_state.dart
Normal file
428
lib/models/buy/buy_form_state.dart
Normal file
|
@ -0,0 +1,428 @@
|
||||||
|
import 'package:decimal/decimal.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:stackwallet/services/buy/buy.dart';
|
||||||
|
|
||||||
|
class BuyFormState extends ChangeNotifier {
|
||||||
|
Buy? _buy;
|
||||||
|
Buy? get buy => _buy;
|
||||||
|
set buy(Buy? value) {
|
||||||
|
_buy = value;
|
||||||
|
_onBuyTypeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuyRateType _buyType = BuyRateType.estimated;
|
||||||
|
// BuyRateType get buyType => _buyType;
|
||||||
|
// set buyType(BuyRateType value) {
|
||||||
|
// _buyType = value;
|
||||||
|
// _onBuyRateTypeChanged();
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool reversed = false;
|
||||||
|
|
||||||
|
Decimal? fromAmount;
|
||||||
|
Decimal? toAmount;
|
||||||
|
|
||||||
|
Decimal? minAmount;
|
||||||
|
Decimal? maxAmount;
|
||||||
|
|
||||||
|
Decimal? rate;
|
||||||
|
// Estimate? estimate;
|
||||||
|
//
|
||||||
|
// dynamic? _market;
|
||||||
|
// dynamic? get market => _market;
|
||||||
|
//
|
||||||
|
// dynamic? _from;
|
||||||
|
// dynamic? _to;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'BuyFormState: {test: "test"}';
|
||||||
|
// return 'BuyFormState: {_buy: $_buy, _buyType: $_buyType, reversed: $reversed, fromAmount: $fromAmount, toAmount: $toAmount, minAmount: $minAmount, maxAmount: $maxAmount, rate: $rate, estimate: $estimate, _market: $_market, _from: $_from, _to: $_to, _onError: $_onError}';
|
||||||
|
}
|
||||||
|
|
||||||
|
String? get fromTicker {
|
||||||
|
// switch (buyType) {
|
||||||
|
// case BuyRateType.estimated:
|
||||||
|
// return _from?.ticker;
|
||||||
|
// case BuyRateType.fixed:
|
||||||
|
// switch (buy?.name) {
|
||||||
|
// // case SimpleSwapBuy.buyName:
|
||||||
|
// // return _from?.ticker;
|
||||||
|
// case ChangeNowBuy.buyName:
|
||||||
|
// return market?.from;
|
||||||
|
// default:
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
String? get toTicker {
|
||||||
|
// switch (buyType) {
|
||||||
|
// case BuyRateType.estimated:
|
||||||
|
// return _to?.ticker;
|
||||||
|
// case BuyRateType.fixed:
|
||||||
|
// switch (buy?.name) {
|
||||||
|
// // case SimpleSwapBuy.buyName:
|
||||||
|
// // return _to?.ticker;
|
||||||
|
// case ChangeNowBuy.buyName:
|
||||||
|
// return market?.to;
|
||||||
|
// default:
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void Function(String)? _onError;
|
||||||
|
|
||||||
|
// dynamic? get from => _from;
|
||||||
|
// dynamic? get to => _to;
|
||||||
|
//
|
||||||
|
// void setCurrencies(dynamic from, dynamic to) {
|
||||||
|
// _from = from;
|
||||||
|
// _to = to;
|
||||||
|
// }
|
||||||
|
|
||||||
|
String get warning {
|
||||||
|
// if (reversed) {
|
||||||
|
// if (toTicker != null && toAmount != null) {
|
||||||
|
// if (minAmount != null &&
|
||||||
|
// toAmount! < minAmount! &&
|
||||||
|
// toAmount! > Decimal.zero) {
|
||||||
|
// return "Minimum amount ${minAmount!.toString()} ${toTicker!.toUpperCase()}";
|
||||||
|
// } else if (maxAmount != null && toAmount! > maxAmount!) {
|
||||||
|
// return "Maximum amount ${maxAmount!.toString()} ${toTicker!.toUpperCase()}";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if (fromTicker != null && fromAmount != null) {
|
||||||
|
// if (minAmount != null &&
|
||||||
|
// fromAmount! < minAmount! &&
|
||||||
|
// fromAmount! > Decimal.zero) {
|
||||||
|
// return "Minimum amount ${minAmount!.toString()} ${fromTicker!.toUpperCase()}";
|
||||||
|
// } else if (maxAmount != null && fromAmount! > maxAmount!) {
|
||||||
|
// return "Maximum amount ${maxAmount!.toString()} ${fromTicker!.toUpperCase()}";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String get fromAmountString => fromAmount?.toStringAsFixed(8) ?? "";
|
||||||
|
String get toAmountString => toAmount?.toStringAsFixed(8) ?? "";
|
||||||
|
|
||||||
|
bool get canBuy {
|
||||||
|
// if (buy?.name == ChangeNowBuy.buyName && buyType == BuyRateType.fixed) {
|
||||||
|
// return _market != null &&
|
||||||
|
// fromAmount != null &&
|
||||||
|
// toAmount != null &&
|
||||||
|
// warning.isEmpty;
|
||||||
|
// } else {
|
||||||
|
// return fromAmount != null &&
|
||||||
|
// fromAmount != Decimal.zero &&
|
||||||
|
// toAmount != null &&
|
||||||
|
// rate != null &&
|
||||||
|
// warning.isEmpty;
|
||||||
|
// }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearAmounts(bool shouldNotifyListeners) {
|
||||||
|
// fromAmount = null;
|
||||||
|
// toAmount = null;
|
||||||
|
// minAmount = null;
|
||||||
|
// maxAmount = null;
|
||||||
|
// rate = null;
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setFromAmountAndCalculateToAmount(
|
||||||
|
Decimal newFromAmount,
|
||||||
|
bool shouldNotifyListeners,
|
||||||
|
) async {
|
||||||
|
// if (newFromAmount == Decimal.zero) {
|
||||||
|
// toAmount = Decimal.zero;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fromAmount = newFromAmount;
|
||||||
|
// reversed = false;
|
||||||
|
//
|
||||||
|
// await updateRanges(shouldNotifyListeners: false);
|
||||||
|
//
|
||||||
|
// await updateEstimate(
|
||||||
|
// shouldNotifyListeners: false,
|
||||||
|
// reversed: reversed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> setToAmountAndCalculateFromAmount(
|
||||||
|
Decimal newToAmount,
|
||||||
|
bool shouldNotifyListeners,
|
||||||
|
) async {
|
||||||
|
// if (newToAmount == Decimal.zero) {
|
||||||
|
// fromAmount = Decimal.zero;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// toAmount = newToAmount;
|
||||||
|
// reversed = true;
|
||||||
|
//
|
||||||
|
// await updateRanges(shouldNotifyListeners: false);
|
||||||
|
//
|
||||||
|
// await updateEstimate(
|
||||||
|
// shouldNotifyListeners: false,
|
||||||
|
// reversed: reversed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<void> updateTo(dynamic to, bool shouldNotifyListeners) async {
|
||||||
|
Future<void> updateTo(dynamic to, bool shouldNotifyListeners) async {
|
||||||
|
// try {
|
||||||
|
// _to = to;
|
||||||
|
// if (_from == null) {
|
||||||
|
// rate = null;
|
||||||
|
// notifyListeners();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await updateRanges(shouldNotifyListeners: false);
|
||||||
|
//
|
||||||
|
// await updateEstimate(
|
||||||
|
// shouldNotifyListeners: false,
|
||||||
|
// reversed: reversed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// //todo: check if print needed
|
||||||
|
// // debugPrint(
|
||||||
|
// // "_updated TO: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$fromAmount _toAmount=$toAmount rate:$rate for: $buy");
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
// } catch (e, s) {
|
||||||
|
// Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<void> updateFrom(dynamic from, bool shouldNotifyListeners) async {
|
||||||
|
Future<void> updateFrom(dynamic from, bool shouldNotifyListeners) async {
|
||||||
|
// try {
|
||||||
|
// _from = from;
|
||||||
|
//
|
||||||
|
// if (_to == null) {
|
||||||
|
// rate = null;
|
||||||
|
// notifyListeners();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await updateRanges(shouldNotifyListeners: false);
|
||||||
|
//
|
||||||
|
// await updateEstimate(
|
||||||
|
// shouldNotifyListeners: false,
|
||||||
|
// reversed: reversed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// //todo: check if print needed
|
||||||
|
// // debugPrint(
|
||||||
|
// // "_updated FROM: _from=${_from!.ticker} _to=${_to!.ticker} _fromAmount=$fromAmount _toAmount=$toAmount rate:$rate for: $buy");
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
// } catch (e, s) {
|
||||||
|
// Logging.instance.log("$e\n$s", level: LogLevel.Error);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateMarket(
|
||||||
|
// dynamic? market,
|
||||||
|
dynamic? market,
|
||||||
|
bool shouldNotifyListeners,
|
||||||
|
) async {
|
||||||
|
// _market = market;
|
||||||
|
//
|
||||||
|
// if (_market == null) {
|
||||||
|
// fromAmount = null;
|
||||||
|
// toAmount = null;
|
||||||
|
// } else {
|
||||||
|
// if (fromAmount != null) {
|
||||||
|
// if (fromAmount! <= Decimal.zero) {
|
||||||
|
// toAmount = Decimal.zero;
|
||||||
|
// } else {
|
||||||
|
// await updateRanges(shouldNotifyListeners: false);
|
||||||
|
// await updateEstimate(
|
||||||
|
// shouldNotifyListeners: false,
|
||||||
|
// reversed: reversed,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onBuyRateTypeChanged() {
|
||||||
|
// print("_onBuyRateTypeChanged");
|
||||||
|
// updateRanges(shouldNotifyListeners: true).then(
|
||||||
|
// (_) => updateEstimate(
|
||||||
|
// shouldNotifyListeners: true,
|
||||||
|
// reversed: reversed,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onBuyTypeChanged() {
|
||||||
|
// updateRanges(shouldNotifyListeners: true).then(
|
||||||
|
// (_) => updateEstimate(
|
||||||
|
// shouldNotifyListeners: true,
|
||||||
|
// reversed: reversed,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateRanges({required bool shouldNotifyListeners}) async {
|
||||||
|
// // if (buy?.name == SimpleSwapBuy.buyName) {
|
||||||
|
// // reversed = false;
|
||||||
|
// // }
|
||||||
|
// final _fromTicker = reversed ? toTicker : fromTicker;
|
||||||
|
// final _toTicker = reversed ? fromTicker : toTicker;
|
||||||
|
// if (_fromTicker == null || _toTicker == null) {
|
||||||
|
// Logging.instance.log(
|
||||||
|
// "Tried to $runtimeType.updateRanges where (from: $_fromTicker || to: $_toTicker) for: $buy",
|
||||||
|
// level: LogLevel.Info,
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// final response = await buy?.getRange(
|
||||||
|
// _fromTicker,
|
||||||
|
// _toTicker,
|
||||||
|
// buyType == BuyRateType.fixed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if (response?.value == null) {
|
||||||
|
// Logging.instance.log(
|
||||||
|
// "Tried to $runtimeType.updateRanges for: $buy where response: $response",
|
||||||
|
// level: LogLevel.Info,
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final range = response!.value!;
|
||||||
|
//
|
||||||
|
// minAmount = range.min;
|
||||||
|
// maxAmount = range.max;
|
||||||
|
//
|
||||||
|
// //todo: check if print needed
|
||||||
|
// // debugPrint(
|
||||||
|
// // "updated range for: $buy for $_fromTicker-$_toTicker: $range");
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> updateEstimate({
|
||||||
|
required bool shouldNotifyListeners,
|
||||||
|
required bool reversed,
|
||||||
|
}) async {
|
||||||
|
// // if (buy?.name == SimpleSwapBuy.buyName) {
|
||||||
|
// // reversed = false;
|
||||||
|
// // }
|
||||||
|
// final amount = reversed ? toAmount : fromAmount;
|
||||||
|
// if (fromTicker == null ||
|
||||||
|
// toTicker == null ||
|
||||||
|
// amount == null ||
|
||||||
|
// amount <= Decimal.zero) {
|
||||||
|
// Logging.instance.log(
|
||||||
|
// "Tried to $runtimeType.updateEstimate for: $buy where (from: $fromTicker || to: $toTicker || amount: $amount)",
|
||||||
|
// level: LogLevel.Info,
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// final response = await buy?.getEstimate(
|
||||||
|
// fromTicker!,
|
||||||
|
// toTicker!,
|
||||||
|
// amount,
|
||||||
|
// buyType == BuyRateType.fixed,
|
||||||
|
// reversed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if (response?.value == null) {
|
||||||
|
// Logging.instance.log(
|
||||||
|
// "Tried to $runtimeType.updateEstimate for: $buy where response: $response",
|
||||||
|
// level: LogLevel.Info,
|
||||||
|
// );
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// estimate = response!.value!;
|
||||||
|
//
|
||||||
|
// if (reversed) {
|
||||||
|
// fromAmount = estimate!.estimatedAmount;
|
||||||
|
// } else {
|
||||||
|
// toAmount = estimate!.estimatedAmount;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// rate = (toAmount! / fromAmount!).toDecimal(scaleOnInfinitePrecision: 12);
|
||||||
|
//
|
||||||
|
// //todo: check if print needed
|
||||||
|
// // debugPrint(
|
||||||
|
// // "updated estimate for: $buy for $fromTicker-$toTicker: $estimate");
|
||||||
|
//
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOnError({
|
||||||
|
required void Function(String)? onError,
|
||||||
|
bool shouldNotifyListeners = false,
|
||||||
|
}) {
|
||||||
|
// _onError = onError;
|
||||||
|
// if (shouldNotifyListeners) {
|
||||||
|
// notifyListeners();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> swap({dynamic? market}) async {
|
||||||
|
// final Decimal? newToAmount = fromAmount;
|
||||||
|
// final Decimal? newFromAmount = toAmount;
|
||||||
|
//
|
||||||
|
// fromAmount = newFromAmount;
|
||||||
|
// toAmount = newToAmount;
|
||||||
|
//
|
||||||
|
// minAmount = null;
|
||||||
|
// maxAmount = null;
|
||||||
|
//
|
||||||
|
// if (buyType == BuyRateType.fixed && buy?.name == ChangeNowBuy.buyName) {
|
||||||
|
// await updateMarket(market, false);
|
||||||
|
// } else {
|
||||||
|
// final dynamic? newTo = from;
|
||||||
|
// final dynamic? newFrom = to;
|
||||||
|
//
|
||||||
|
// _to = newTo;
|
||||||
|
// _from = newFrom;
|
||||||
|
//
|
||||||
|
// await updateRanges(shouldNotifyListeners: false);
|
||||||
|
//
|
||||||
|
// await updateEstimate(
|
||||||
|
// shouldNotifyListeners: false,
|
||||||
|
// reversed: reversed,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
237
lib/models/buy/response_objects/buy.dart
Normal file
237
lib/models/buy/response_objects/buy.dart
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
|
part 'buy.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: Buy.typeId)
|
||||||
|
class Buy {
|
||||||
|
static const typeId = 22;
|
||||||
|
|
||||||
|
@HiveField(0)
|
||||||
|
final String uuid;
|
||||||
|
|
||||||
|
@HiveField(1)
|
||||||
|
final String tradeId;
|
||||||
|
|
||||||
|
@HiveField(2)
|
||||||
|
final String rateType;
|
||||||
|
|
||||||
|
@HiveField(3)
|
||||||
|
final String direction;
|
||||||
|
|
||||||
|
@HiveField(4)
|
||||||
|
final DateTime timestamp;
|
||||||
|
|
||||||
|
@HiveField(5)
|
||||||
|
final DateTime updatedAt;
|
||||||
|
|
||||||
|
@HiveField(6)
|
||||||
|
final String payInCurrency;
|
||||||
|
|
||||||
|
@HiveField(7)
|
||||||
|
final String payInAmount;
|
||||||
|
|
||||||
|
@HiveField(8)
|
||||||
|
final String payInAddress;
|
||||||
|
|
||||||
|
@HiveField(9)
|
||||||
|
final String payInNetwork;
|
||||||
|
|
||||||
|
@HiveField(10)
|
||||||
|
final String payInExtraId;
|
||||||
|
|
||||||
|
@HiveField(11)
|
||||||
|
final String payInTxid;
|
||||||
|
|
||||||
|
@HiveField(12)
|
||||||
|
final String payOutCurrency;
|
||||||
|
|
||||||
|
@HiveField(13)
|
||||||
|
final String payOutAmount;
|
||||||
|
|
||||||
|
@HiveField(14)
|
||||||
|
final String payOutAddress;
|
||||||
|
|
||||||
|
@HiveField(15)
|
||||||
|
final String payOutNetwork;
|
||||||
|
|
||||||
|
@HiveField(16)
|
||||||
|
final String payOutExtraId;
|
||||||
|
|
||||||
|
@HiveField(17)
|
||||||
|
final String payOutTxid;
|
||||||
|
|
||||||
|
@HiveField(18)
|
||||||
|
final String refundAddress;
|
||||||
|
|
||||||
|
@HiveField(19)
|
||||||
|
final String refundExtraId;
|
||||||
|
|
||||||
|
@HiveField(20)
|
||||||
|
final String status;
|
||||||
|
|
||||||
|
@HiveField(21)
|
||||||
|
final String exchangeName;
|
||||||
|
|
||||||
|
const Buy({
|
||||||
|
required this.uuid,
|
||||||
|
required this.tradeId,
|
||||||
|
required this.rateType,
|
||||||
|
required this.direction,
|
||||||
|
required this.timestamp,
|
||||||
|
required this.updatedAt,
|
||||||
|
required this.payInCurrency,
|
||||||
|
required this.payInAmount,
|
||||||
|
required this.payInAddress,
|
||||||
|
required this.payInNetwork,
|
||||||
|
required this.payInExtraId,
|
||||||
|
required this.payInTxid,
|
||||||
|
required this.payOutCurrency,
|
||||||
|
required this.payOutAmount,
|
||||||
|
required this.payOutAddress,
|
||||||
|
required this.payOutNetwork,
|
||||||
|
required this.payOutExtraId,
|
||||||
|
required this.payOutTxid,
|
||||||
|
required this.refundAddress,
|
||||||
|
required this.refundExtraId,
|
||||||
|
required this.status,
|
||||||
|
required this.exchangeName,
|
||||||
|
});
|
||||||
|
|
||||||
|
Trade copyWith({
|
||||||
|
String? tradeId,
|
||||||
|
String? rateType,
|
||||||
|
String? direction,
|
||||||
|
DateTime? timestamp,
|
||||||
|
DateTime? updatedAt,
|
||||||
|
String? payInCurrency,
|
||||||
|
String? payInAmount,
|
||||||
|
String? payInAddress,
|
||||||
|
String? payInNetwork,
|
||||||
|
String? payInExtraId,
|
||||||
|
String? payInTxid,
|
||||||
|
String? payOutCurrency,
|
||||||
|
String? payOutAmount,
|
||||||
|
String? payOutAddress,
|
||||||
|
String? payOutNetwork,
|
||||||
|
String? payOutExtraId,
|
||||||
|
String? payOutTxid,
|
||||||
|
String? refundAddress,
|
||||||
|
String? refundExtraId,
|
||||||
|
String? status,
|
||||||
|
String? exchangeName,
|
||||||
|
}) {
|
||||||
|
return Buy(
|
||||||
|
uuid: uuid,
|
||||||
|
tradeId: tradeId ?? this.tradeId,
|
||||||
|
rateType: rateType ?? this.rateType,
|
||||||
|
direction: direction ?? this.direction,
|
||||||
|
timestamp: timestamp ?? this.timestamp,
|
||||||
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
|
payInCurrency: payInCurrency ?? this.payInCurrency,
|
||||||
|
payInAmount: payInAmount ?? this.payInAmount,
|
||||||
|
payInAddress: payInAddress ?? this.payInAddress,
|
||||||
|
payInNetwork: payInNetwork ?? this.payInNetwork,
|
||||||
|
payInExtraId: payInExtraId ?? this.payInExtraId,
|
||||||
|
payInTxid: payInTxid ?? this.payInTxid,
|
||||||
|
payOutCurrency: payOutCurrency ?? this.payOutCurrency,
|
||||||
|
payOutAmount: payOutAmount ?? this.payOutAmount,
|
||||||
|
payOutAddress: payOutAddress ?? this.payOutAddress,
|
||||||
|
payOutNetwork: payOutNetwork ?? this.payOutNetwork,
|
||||||
|
payOutExtraId: payOutExtraId ?? this.payOutExtraId,
|
||||||
|
payOutTxid: payOutTxid ?? this.payOutTxid,
|
||||||
|
refundAddress: refundAddress ?? this.refundAddress,
|
||||||
|
refundExtraId: refundExtraId ?? this.refundExtraId,
|
||||||
|
status: status ?? this.status,
|
||||||
|
exchangeName: exchangeName ?? this.exchangeName,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> toMap() {
|
||||||
|
return {
|
||||||
|
"uuid": uuid,
|
||||||
|
"tradeId": tradeId,
|
||||||
|
"rateType": rateType,
|
||||||
|
"direction": direction,
|
||||||
|
"timestamp": timestamp.toIso8601String(),
|
||||||
|
"updatedAt": updatedAt.toIso8601String(),
|
||||||
|
"payInCurrency": payInCurrency,
|
||||||
|
"payInAmount": payInAmount,
|
||||||
|
"payInAddress": payInAddress,
|
||||||
|
"payInNetwork": payInNetwork,
|
||||||
|
"payInExtraId": payInExtraId,
|
||||||
|
"payInTxid": payInTxid,
|
||||||
|
"payOutCurrency": payOutCurrency,
|
||||||
|
"payOutAmount": payOutAmount,
|
||||||
|
"payOutAddress": payOutAddress,
|
||||||
|
"payOutNetwork": payOutNetwork,
|
||||||
|
"payOutExtraId": payOutExtraId,
|
||||||
|
"payOutTxid": payOutTxid,
|
||||||
|
"refundAddress": refundAddress,
|
||||||
|
"refundExtraId": refundExtraId,
|
||||||
|
"status": status,
|
||||||
|
"exchangeName": exchangeName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
factory Buy.fromMap(Map<String, dynamic> map) {
|
||||||
|
return Buy(
|
||||||
|
uuid: map["uuid"] as String,
|
||||||
|
tradeId: map["tradeId"] as String,
|
||||||
|
rateType: map["rateType"] as String,
|
||||||
|
direction: map["direction"] as String,
|
||||||
|
timestamp: DateTime.parse(map["timestamp"] as String),
|
||||||
|
updatedAt: DateTime.parse(map["updatedAt"] as String),
|
||||||
|
payInCurrency: map["payInCurrency"] as String,
|
||||||
|
payInAmount: map["payInAmount"] as String,
|
||||||
|
payInAddress: map["payInAddress"] as String,
|
||||||
|
payInNetwork: map["payInNetwork"] as String,
|
||||||
|
payInExtraId: map["payInExtraId"] as String,
|
||||||
|
payInTxid: map["payInTxid"] as String,
|
||||||
|
payOutCurrency: map["payOutCurrency"] as String,
|
||||||
|
payOutAmount: map["payOutAmount"] as String,
|
||||||
|
payOutAddress: map["payOutAddress"] as String,
|
||||||
|
payOutNetwork: map["payOutNetwork"] as String,
|
||||||
|
payOutExtraId: map["payOutExtraId"] as String,
|
||||||
|
payOutTxid: map["payOutTxid"] as String,
|
||||||
|
refundAddress: map["refundAddress"] as String,
|
||||||
|
refundExtraId: map["refundExtraId"] as String,
|
||||||
|
status: map["status"] as String,
|
||||||
|
exchangeName: map["exchangeName"] as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// factory Trade.fromExchangeTransaction(
|
||||||
|
// ExchangeTransaction exTx, bool reversed) {
|
||||||
|
// return Buy(
|
||||||
|
// uuid: exTx.uuid,
|
||||||
|
// tradeId: exTx.id,
|
||||||
|
// rateType: "",
|
||||||
|
// direction: reversed ? "reverse" : "direct",
|
||||||
|
// timestamp: exTx.date,
|
||||||
|
// updatedAt: DateTime.tryParse(exTx.statusObject!.updatedAt) ?? exTx.date,
|
||||||
|
// payInCurrency: exTx.fromCurrency,
|
||||||
|
// payInAmount: exTx.statusObject!.amountSendDecimal.isEmpty
|
||||||
|
// ? exTx.statusObject!.expectedSendAmountDecimal
|
||||||
|
// : exTx.statusObject!.amountSendDecimal,
|
||||||
|
// payInAddress: exTx.payinAddress,
|
||||||
|
// payInNetwork: "",
|
||||||
|
// payInExtraId: exTx.payinExtraId,
|
||||||
|
// payInTxid: exTx.statusObject!.payinHash,
|
||||||
|
// payOutCurrency: exTx.toCurrency,
|
||||||
|
// payOutAmount: exTx.amount,
|
||||||
|
// payOutAddress: exTx.payoutAddress,
|
||||||
|
// payOutNetwork: "",
|
||||||
|
// payOutExtraId: exTx.payoutExtraId,
|
||||||
|
// payOutTxid: exTx.statusObject!.payoutHash,
|
||||||
|
// refundAddress: exTx.refundAddress,
|
||||||
|
// refundExtraId: exTx.refundExtraId,
|
||||||
|
// status: exTx.statusObject!.status.name,
|
||||||
|
// exchangeName: ChangeNowExchange.exchangeName,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
}
|
123
lib/models/buy/response_objects/currency.dart
Normal file
123
lib/models/buy/response_objects/currency.dart
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
class Currency {
|
||||||
|
/// Currency ticker
|
||||||
|
final String ticker;
|
||||||
|
|
||||||
|
/// Currency name
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// Currency network
|
||||||
|
final String network;
|
||||||
|
|
||||||
|
/// Currency logo url
|
||||||
|
final String image;
|
||||||
|
|
||||||
|
/// Indicates if a currency has an Extra ID
|
||||||
|
final bool hasExternalId;
|
||||||
|
|
||||||
|
/// external id if it exists
|
||||||
|
final String? externalId;
|
||||||
|
|
||||||
|
/// Indicates if a currency is a fiat currency (EUR, USD)
|
||||||
|
final bool isFiat;
|
||||||
|
|
||||||
|
/// Indicates if a currency is popular
|
||||||
|
final bool featured;
|
||||||
|
|
||||||
|
/// Indicates if a currency is stable
|
||||||
|
final bool isStable;
|
||||||
|
|
||||||
|
/// Indicates if a currency is available on a fixed-rate flow
|
||||||
|
final bool supportsFixedRate;
|
||||||
|
|
||||||
|
/// (Optional - based on api call) Indicates whether the pair is
|
||||||
|
/// currently supported by change now
|
||||||
|
final bool? isAvailable;
|
||||||
|
|
||||||
|
Currency({
|
||||||
|
required this.ticker,
|
||||||
|
required this.name,
|
||||||
|
required this.network,
|
||||||
|
required this.image,
|
||||||
|
required this.hasExternalId,
|
||||||
|
this.externalId,
|
||||||
|
required this.isFiat,
|
||||||
|
required this.featured,
|
||||||
|
required this.isStable,
|
||||||
|
required this.supportsFixedRate,
|
||||||
|
this.isAvailable,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Currency.fromJson(Map<String, dynamic> json) {
|
||||||
|
try {
|
||||||
|
return Currency(
|
||||||
|
ticker: json["ticker"] as String,
|
||||||
|
name: json["name"] as String,
|
||||||
|
network: json["network"] as String? ?? "",
|
||||||
|
image: json["image"] as String,
|
||||||
|
hasExternalId: json["hasExternalId"] as bool,
|
||||||
|
externalId: json["externalId"] as String?,
|
||||||
|
isFiat: json["isFiat"] as bool,
|
||||||
|
featured: json["featured"] as bool,
|
||||||
|
isStable: json["isStable"] as bool,
|
||||||
|
supportsFixedRate: json["supportsFixedRate"] as bool,
|
||||||
|
isAvailable: json["isAvailable"] as bool?,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final map = {
|
||||||
|
"ticker": ticker,
|
||||||
|
"name": name,
|
||||||
|
"network": network,
|
||||||
|
"image": image,
|
||||||
|
"hasExternalId": hasExternalId,
|
||||||
|
"externalId": externalId,
|
||||||
|
"isFiat": isFiat,
|
||||||
|
"featured": featured,
|
||||||
|
"isStable": isStable,
|
||||||
|
"supportsFixedRate": supportsFixedRate,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isAvailable != null) {
|
||||||
|
map["isAvailable"] = isAvailable!;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
Currency copyWith({
|
||||||
|
String? ticker,
|
||||||
|
String? name,
|
||||||
|
String? network,
|
||||||
|
String? image,
|
||||||
|
bool? hasExternalId,
|
||||||
|
String? externalId,
|
||||||
|
bool? isFiat,
|
||||||
|
bool? featured,
|
||||||
|
bool? isStable,
|
||||||
|
bool? supportsFixedRate,
|
||||||
|
bool? isAvailable,
|
||||||
|
}) {
|
||||||
|
return Currency(
|
||||||
|
ticker: ticker ?? this.ticker,
|
||||||
|
name: name ?? this.name,
|
||||||
|
network: network ?? this.network,
|
||||||
|
image: image ?? this.image,
|
||||||
|
hasExternalId: hasExternalId ?? this.hasExternalId,
|
||||||
|
externalId: externalId ?? this.externalId,
|
||||||
|
isFiat: isFiat ?? this.isFiat,
|
||||||
|
featured: featured ?? this.featured,
|
||||||
|
isStable: isStable ?? this.isStable,
|
||||||
|
supportsFixedRate: supportsFixedRate ?? this.supportsFixedRate,
|
||||||
|
isAvailable: isAvailable ?? this.isAvailable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return "Currency: ${toJson()}";
|
||||||
|
}
|
||||||
|
}
|
227
lib/pages/buy_view/buy_form.dart
Normal file
227
lib/pages/buy_view/buy_form.dart
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
import 'package:decimal/decimal.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:stackwallet/providers/buy/buy_form_state_provider.dart';
|
||||||
|
import 'package:stackwallet/utilities/assets.dart';
|
||||||
|
import 'package:stackwallet/utilities/enums/coin_enum.dart';
|
||||||
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
import 'package:stackwallet/utilities/util.dart';
|
||||||
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
|
import 'package:stackwallet/widgets/rounded_container.dart';
|
||||||
|
|
||||||
|
class BuyForm extends ConsumerStatefulWidget {
|
||||||
|
const BuyForm({
|
||||||
|
Key? key,
|
||||||
|
this.walletId,
|
||||||
|
this.coin,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String? walletId;
|
||||||
|
final Coin? coin;
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<BuyForm> createState() => _BuyFormState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BuyFormState extends ConsumerState<BuyForm> {
|
||||||
|
late final String? walletId;
|
||||||
|
late final Coin? coin;
|
||||||
|
|
||||||
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
debugPrint("BUILD: $runtimeType");
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"You will send",
|
||||||
|
style: STextStyles.itemSubtitle(context).copyWith(
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.textDark3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 10 : 4,
|
||||||
|
),
|
||||||
|
// ExchangeTextField(
|
||||||
|
// controller: _sendController,
|
||||||
|
// focusNode: _sendFocusNode,
|
||||||
|
// textStyle: STextStyles.smallMed14(context).copyWith(
|
||||||
|
// color: Theme.of(context).extension<StackColors>()!.textDark,
|
||||||
|
// ),
|
||||||
|
// buttonColor:
|
||||||
|
// Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
|
||||||
|
// borderRadius: Constants.size.circularBorderRadius,
|
||||||
|
// background:
|
||||||
|
// Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
|
||||||
|
// onTap: () {
|
||||||
|
// if (_sendController.text == "-") {
|
||||||
|
// _sendController.text = "";
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// onChanged: sendFieldOnChanged,
|
||||||
|
// onButtonTap: selectSendCurrency,
|
||||||
|
// isWalletCoin: isWalletCoin(coin, true),
|
||||||
|
// image: _fetchIconUrlFromTicker(ref.watch(
|
||||||
|
// buyFormStateProvider.select((value) => value.fromTicker))),
|
||||||
|
// ticker: ref.watch(
|
||||||
|
// buyFormStateProvider.select((value) => value.fromTicker)),
|
||||||
|
// ),
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 10 : 4,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 10 : 4,
|
||||||
|
),
|
||||||
|
// if (ref
|
||||||
|
// .watch(buyFormStateProvider.select((value) => value.warning))
|
||||||
|
// .isNotEmpty &&
|
||||||
|
// !ref.watch(buyFormStateProvider.select((value) => value.reversed)))
|
||||||
|
// Text(
|
||||||
|
// ref.watch(buyFormStateProvider.select((value) => value.warning)),
|
||||||
|
// style: STextStyles.errorSmall(context),
|
||||||
|
// ),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"You will receive",
|
||||||
|
style: STextStyles.itemSubtitle(context).copyWith(
|
||||||
|
color: Theme.of(context).extension<StackColors>()!.textDark3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ConditionalParent(
|
||||||
|
condition: isDesktop,
|
||||||
|
builder: (child) => MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
|
child: RoundedContainer(
|
||||||
|
padding: isDesktop
|
||||||
|
? const EdgeInsets.all(6)
|
||||||
|
: const EdgeInsets.all(2),
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.buttonBackSecondary,
|
||||||
|
radiusMultiplier: 0.75,
|
||||||
|
child: GestureDetector(
|
||||||
|
// onTap: () async {
|
||||||
|
// await _swap();
|
||||||
|
// },
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(4),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.svg.swap,
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.accentColorDark,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 10 : 7,
|
||||||
|
),
|
||||||
|
// ExchangeTextField(
|
||||||
|
// focusNode: _receiveFocusNode,
|
||||||
|
// controller: _receiveController,
|
||||||
|
// textStyle: STextStyles.smallMed14(context).copyWith(
|
||||||
|
// color: Theme.of(context).extension<StackColors>()!.textDark,
|
||||||
|
// ),
|
||||||
|
// buttonColor:
|
||||||
|
// Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
|
||||||
|
// borderRadius: Constants.size.circularBorderRadius,
|
||||||
|
// background:
|
||||||
|
// Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
|
||||||
|
// onTap: () {
|
||||||
|
// if (!(ref.read(prefsChangeNotifierProvider).exchangeRateType ==
|
||||||
|
// ExchangeRateType.estimated) &&
|
||||||
|
// _receiveController.text == "-") {
|
||||||
|
// _receiveController.text = "";
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// onChanged: receiveFieldOnChanged,
|
||||||
|
// onButtonTap: selectReceiveCurrency,
|
||||||
|
// isWalletCoin: isWalletCoin(coin, true),
|
||||||
|
// image: _fetchIconUrlFromTicker(ref.watch(
|
||||||
|
// buyFormStateProvider.select((value) => value.toTicker))),
|
||||||
|
// ticker: ref.watch(
|
||||||
|
// buyFormStateProvider.select((value) => value.toTicker)),
|
||||||
|
// readOnly: ref.watch(prefsChangeNotifierProvider
|
||||||
|
// .select((value) => value.exchangeRateType)) ==
|
||||||
|
// ExchangeRateType.estimated,
|
||||||
|
// // ||
|
||||||
|
// // ref.watch(exchangeProvider).name ==
|
||||||
|
// // SimpleSwapExchange.exchangeName,
|
||||||
|
// ),
|
||||||
|
// if (ref
|
||||||
|
// .watch(buyFormStateProvider.select((value) => value.warning))
|
||||||
|
// .isNotEmpty &&
|
||||||
|
// ref.watch(buyFormStateProvider.select((value) => value.reversed)))
|
||||||
|
// Text(
|
||||||
|
// ref.watch(buyFormStateProvider.select((value) => value.warning)),
|
||||||
|
// style: STextStyles.errorSmall(context),
|
||||||
|
// ),
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 20 : 12,
|
||||||
|
),
|
||||||
|
// SizedBox(
|
||||||
|
// height: 60,
|
||||||
|
// child: RateTypeToggle(
|
||||||
|
// onChanged: onRateTypeChanged,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// these reads should be watch
|
||||||
|
if (ref.watch(buyFormStateProvider).fromAmount != null &&
|
||||||
|
ref.watch(buyFormStateProvider).fromAmount != Decimal.zero)
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 20 : 12,
|
||||||
|
),
|
||||||
|
// these reads should be watch
|
||||||
|
// if (ref.watch(buyFormStateProvider).fromAmount != null &&
|
||||||
|
// ref.watch(buyFormStateProvider).fromAmount != Decimal.zero)
|
||||||
|
// ExchangeProviderOptions(
|
||||||
|
// from: ref.watch(buyFormStateProvider).fromTicker,
|
||||||
|
// to: ref.watch(buyFormStateProvider).toTicker,
|
||||||
|
// fromAmount: ref.watch(buyFormStateProvider).fromAmount,
|
||||||
|
// toAmount: ref.watch(buyFormStateProvider).toAmount,
|
||||||
|
// fixedRate: ref.watch(prefsChangeNotifierProvider
|
||||||
|
// .select((value) => value.exchangeRateType)) ==
|
||||||
|
// ExchangeRateType.fixed,
|
||||||
|
// reversed: ref
|
||||||
|
// .watch(buyFormStateProvider.select((value) => value.reversed)),
|
||||||
|
// ),
|
||||||
|
SizedBox(
|
||||||
|
height: isDesktop ? 20 : 12,
|
||||||
|
),
|
||||||
|
// PrimaryButton(
|
||||||
|
// buttonHeight: isDesktop ? ButtonHeight.l : null,
|
||||||
|
// enabled: ref
|
||||||
|
// .watch(buyFormStateProvider.select((value) => value.canExchange)),
|
||||||
|
// // onPressed: ref.watch(buyFormStateProvider
|
||||||
|
// // .select((value) => value.canExchange))
|
||||||
|
// // ? onExchangePressed
|
||||||
|
// // : null,
|
||||||
|
// label: "Exchange",
|
||||||
|
// )
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:stackwallet/pages/buy_view/buy_form.dart';
|
||||||
|
import 'package:stackwallet/utilities/constants.dart';
|
||||||
import 'package:stackwallet/utilities/text_styles.dart';
|
import 'package:stackwallet/utilities/text_styles.dart';
|
||||||
|
import 'package:stackwallet/utilities/theme/stack_colors.dart';
|
||||||
|
|
||||||
class BuyView extends StatefulWidget {
|
class BuyView extends StatefulWidget {
|
||||||
const BuyView({Key? key}) : super(key: key);
|
const BuyView({Key? key}) : super(key: key);
|
||||||
|
@ -13,37 +16,156 @@ class _BuyViewState extends State<BuyView> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//todo: check if print needed
|
//todo: check if print needed
|
||||||
// debugPrint("BUILD: BuyView");
|
// debugPrint("BUILD: BuyView");
|
||||||
|
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Center(
|
child: NestedScrollView(
|
||||||
child: SingleChildScrollView(
|
floatHeaderSlivers: true,
|
||||||
child: Column(
|
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||||
children: [
|
return [
|
||||||
Center(
|
SliverOverlapAbsorber(
|
||||||
child: Text(
|
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||||
"Coming soon",
|
sliver: const SliverToBoxAdapter(
|
||||||
style: STextStyles.pageTitleH1(context),
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
top: 16,
|
||||||
),
|
),
|
||||||
|
child: BuyForm(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
},
|
||||||
|
body: Builder(
|
||||||
|
builder: (buildContext) {
|
||||||
|
// final buys =
|
||||||
|
// ref.watch(buysServiceProvider.select((value) => value.buys));
|
||||||
|
// final buyCount = buys.length;
|
||||||
|
// final hasHistory = buyCount > 0;
|
||||||
|
const hasHistory = false;
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
|
child: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverOverlapInjector(
|
||||||
|
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
|
||||||
|
buildContext,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"Trades",
|
||||||
|
style: STextStyles.itemSubtitle(context).copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textDark3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 12,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// child: Column(
|
),
|
||||||
// children: [
|
// if (hasHistory)
|
||||||
// Container(
|
// SliverList(
|
||||||
// color: Colors.green,
|
// delegate: SliverChildBuilderDelegate((context, index) {
|
||||||
// child: Text("BuyView"),
|
// return Padding(
|
||||||
|
// padding: const EdgeInsets.all(4),
|
||||||
|
// child: TradeCard(
|
||||||
|
// key: Key("tradeCard_${trades[index].uuid}"),
|
||||||
|
// trade: trades[index],
|
||||||
|
// onTap: () async {
|
||||||
|
// final String tradeId = trades[index].tradeId;
|
||||||
|
//
|
||||||
|
// final lookup = ref
|
||||||
|
// .read(tradeSentFromStackLookupProvider)
|
||||||
|
// .all;
|
||||||
|
//
|
||||||
|
// //todo: check if print needed
|
||||||
|
// // debugPrint("ALL: $lookup");
|
||||||
|
//
|
||||||
|
// final String? txid = ref
|
||||||
|
// .read(tradeSentFromStackLookupProvider)
|
||||||
|
// .getTxidForTradeId(tradeId);
|
||||||
|
// final List<String>? walletIds = ref
|
||||||
|
// .read(tradeSentFromStackLookupProvider)
|
||||||
|
// .getWalletIdsForTradeId(tradeId);
|
||||||
|
//
|
||||||
|
// if (txid != null &&
|
||||||
|
// walletIds != null &&
|
||||||
|
// walletIds.isNotEmpty) {
|
||||||
|
// final manager = ref
|
||||||
|
// .read(walletsChangeNotifierProvider)
|
||||||
|
// .getManager(walletIds.first);
|
||||||
|
//
|
||||||
|
// //todo: check if print needed
|
||||||
|
// // debugPrint("name: ${manager.walletName}");
|
||||||
|
//
|
||||||
|
// // TODO store tx data completely locally in isar so we don't lock up ui here when querying txData
|
||||||
|
// final txData = await manager.transactionData;
|
||||||
|
//
|
||||||
|
// final tx = txData.getAllTransactions()[txid];
|
||||||
|
//
|
||||||
|
// if (mounted) {
|
||||||
|
// unawaited(Navigator.of(context).pushNamed(
|
||||||
|
// TradeDetailsView.routeName,
|
||||||
|
// arguments: Tuple4(tradeId, tx,
|
||||||
|
// walletIds.first, manager.walletName),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// unawaited(Navigator.of(context).pushNamed(
|
||||||
|
// TradeDetailsView.routeName,
|
||||||
|
// arguments: Tuple4(
|
||||||
|
// tradeId, null, walletIds?.first, null),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
// },
|
||||||
// ),
|
// ),
|
||||||
// Container(
|
// );
|
||||||
// color: Colors.green,
|
// }, childCount: tradeCount),
|
||||||
// child: Text("BuyView"),
|
|
||||||
// ),
|
|
||||||
// Spacer(),
|
|
||||||
// Container(
|
|
||||||
// color: Colors.green,
|
|
||||||
// child: Text("BuyView"),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
// ),
|
||||||
|
if (!hasHistory)
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.popupBG,
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
Constants.size.circularBorderRadius,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Text(
|
||||||
|
"Trades will appear here",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: STextStyles.itemSubtitle(context),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,7 +308,7 @@ class _HomeViewState extends ConsumerState<HomeView> {
|
||||||
if (next == 1) {
|
if (next == 1) {
|
||||||
_exchangeDataLoadingService.loadAll(ref);
|
_exchangeDataLoadingService.loadAll(ref);
|
||||||
}
|
}
|
||||||
if (next >= 0 && next <= 1) {
|
if (next >= 0 && next <= 2) {
|
||||||
_pageController.animateToPage(
|
_pageController.animateToPage(
|
||||||
next,
|
next,
|
||||||
duration: const Duration(milliseconds: 300),
|
duration: const Duration(milliseconds: 300),
|
||||||
|
|
|
@ -153,7 +153,7 @@ class _HomeViewButtonBarState extends ConsumerState<HomeViewButtonBar> {
|
||||||
"Buy",
|
"Buy",
|
||||||
style: STextStyles.button(context).copyWith(
|
style: STextStyles.button(context).copyWith(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: selectedIndex == 1
|
color: selectedIndex == 2
|
||||||
? Theme.of(context)
|
? Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.buttonTextPrimary
|
.buttonTextPrimary
|
||||||
|
|
|
@ -200,37 +200,37 @@ class WalletNavigationBar extends StatelessWidget {
|
||||||
),
|
),
|
||||||
// TODO: Do not delete this code.
|
// TODO: Do not delete this code.
|
||||||
// only temporarily disabled
|
// only temporarily disabled
|
||||||
// Spacer(
|
Spacer(
|
||||||
// flex: 2,
|
flex: 2,
|
||||||
// ),
|
),
|
||||||
// GestureDetector(
|
GestureDetector(
|
||||||
// onTap: onBuyPressed,
|
onTap: onBuyPressed,
|
||||||
// child: Container(
|
child: Container(
|
||||||
// color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
// child: Padding(
|
child: Padding(
|
||||||
// padding: const EdgeInsets.symmetric(vertical: 2.0),
|
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
||||||
// child: Column(
|
child: Column(
|
||||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
// children: [
|
children: [
|
||||||
// Spacer(),
|
Spacer(),
|
||||||
// SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
// Assets.svg.buy,
|
Assets.svg.buyDesktop,
|
||||||
// width: 24,
|
width: 24,
|
||||||
// height: 24,
|
height: 24,
|
||||||
// ),
|
),
|
||||||
// SizedBox(
|
SizedBox(
|
||||||
// height: 4,
|
height: 4,
|
||||||
// ),
|
),
|
||||||
// Text(
|
Text(
|
||||||
// "Buy",
|
"Buy2",
|
||||||
// style: STextStyles.buttonSmall(context),
|
style: STextStyles.buttonSmall(context),
|
||||||
// ),
|
),
|
||||||
// Spacer(),
|
Spacer(),
|
||||||
// ],
|
],
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
6
lib/providers/buy/buy_form_state_provider.dart
Normal file
6
lib/providers/buy/buy_form_state_provider.dart
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/models/buy/buy_form_state.dart';
|
||||||
|
|
||||||
|
final buyFormStateProvider = ChangeNotifierProvider<BuyFormState>(
|
||||||
|
(ref) => BuyFormState(),
|
||||||
|
);
|
5
lib/providers/global/buys_service_provider.dart
Normal file
5
lib/providers/global/buys_service_provider.dart
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:stackwallet/services/buys_service.dart';
|
||||||
|
|
||||||
|
final buysServiceProvider =
|
||||||
|
ChangeNotifierProvider<BuysService>((ref) => BuysService());
|
44
lib/services/buy/buy.dart
Normal file
44
lib/services/buy/buy.dart
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
abstract class Buy {
|
||||||
|
String get name;
|
||||||
|
|
||||||
|
// Future<BuyResponse<List<Currency>>> getAllCurrencies(bool fixedRate);
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<List<Pair>>> getPairsFor(
|
||||||
|
// String currency,
|
||||||
|
// bool fixedRate,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<List<Pair>>> getAllPairs(bool fixedRate);
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<Trade>> getTrade(String tradeId);
|
||||||
|
// Future<BuyResponse<Trade>> updateTrade(Trade trade);
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<List<Trade>>> getTrades();
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<Range>> getRange(
|
||||||
|
// String from,
|
||||||
|
// String to,
|
||||||
|
// bool fixedRate,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<Estimate>> getEstimate(
|
||||||
|
// String from,
|
||||||
|
// String to,
|
||||||
|
// Decimal amount,
|
||||||
|
// bool fixedRate,
|
||||||
|
// bool reversed,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// Future<BuyResponse<Trade>> createTrade({
|
||||||
|
// required String from,
|
||||||
|
// required String to,
|
||||||
|
// required bool fixedRate,
|
||||||
|
// required Decimal amount,
|
||||||
|
// required String addressTo,
|
||||||
|
// String? extraId,
|
||||||
|
// required String addressRefund,
|
||||||
|
// required String refundExtraId,
|
||||||
|
// String? rateId,
|
||||||
|
// required bool reversed,
|
||||||
|
// });
|
||||||
|
}
|
66
lib/services/buys_service.dart
Normal file
66
lib/services/buys_service.dart
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:stackwallet/hive/db.dart';
|
||||||
|
import 'package:stackwallet/models/buy/response_objects/buy.dart';
|
||||||
|
|
||||||
|
class BuysService extends ChangeNotifier {
|
||||||
|
List<Buy> get Buys {
|
||||||
|
final list = DB.instance.values<Buy>(boxName: DB.boxNameBuys);
|
||||||
|
list.sort((a, b) =>
|
||||||
|
b.timestamp.millisecondsSinceEpoch -
|
||||||
|
a.timestamp.millisecondsSinceEpoch);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buy? get(String BuyId) {
|
||||||
|
try {
|
||||||
|
return DB.instance
|
||||||
|
.values<Buy>(boxName: DB.boxNameBuys)
|
||||||
|
.firstWhere((e) => e.BuyId == BuyId);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> add({
|
||||||
|
required Buy Buy,
|
||||||
|
required bool shouldNotifyListeners,
|
||||||
|
}) async {
|
||||||
|
await DB.instance
|
||||||
|
.put<Buy>(boxName: DB.boxNameBuys, key: Buy.uuid, value: Buy);
|
||||||
|
|
||||||
|
if (shouldNotifyListeners) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> edit({
|
||||||
|
required Buy Buy,
|
||||||
|
required bool shouldNotifyListeners,
|
||||||
|
}) async {
|
||||||
|
if (DB.instance.get<Buy>(boxName: DB.boxNameBuys, key: Buy.uuid) == null) {
|
||||||
|
throw Exception("Attempted to edit a Buy that does not exist in Hive!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// add overwrites so this edit function is just a wrapper with an extra check
|
||||||
|
await add(Buy: Buy, shouldNotifyListeners: shouldNotifyListeners);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> delete({
|
||||||
|
required Buy Buy,
|
||||||
|
required bool shouldNotifyListeners,
|
||||||
|
}) async {
|
||||||
|
await deleteByUuid(
|
||||||
|
uuid: Buy.uuid, shouldNotifyListeners: shouldNotifyListeners);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteByUuid({
|
||||||
|
required String uuid,
|
||||||
|
required bool shouldNotifyListeners,
|
||||||
|
}) async {
|
||||||
|
await DB.instance.delete<Buy>(boxName: DB.boxNameBuys, key: uuid);
|
||||||
|
|
||||||
|
if (shouldNotifyListeners) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue