parent
6fa74b7ba9
commit
44a8b6df0a
|
@ -0,0 +1,29 @@
|
||||||
|
import controller_interface
|
||||||
|
import io_interface
|
||||||
|
|
||||||
|
import ../../../../../app_service/service/transaction/service as transaction_service
|
||||||
|
import ../../../../../app_service/service/transaction/cryptoRampDto
|
||||||
|
|
||||||
|
export controller_interface
|
||||||
|
|
||||||
|
type
|
||||||
|
Controller* = ref object of controller_interface.AccessInterface
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
transactionService: transaction_service.Service
|
||||||
|
|
||||||
|
proc newController*(
|
||||||
|
delegate: io_interface.AccessInterface,
|
||||||
|
transactionService: transaction_service.Service
|
||||||
|
): Controller =
|
||||||
|
result = Controller()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.transactionService = transactionService
|
||||||
|
|
||||||
|
method delete*(self: Controller) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
method init*(self: Controller) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
method fetchCryptoServices*(self: Controller): seq[CryptoRampDto] =
|
||||||
|
return self.transactionService.fetchCryptoServices()
|
|
@ -0,0 +1,19 @@
|
||||||
|
import ../../../../../app_service/service/transaction/cryptoRampDto
|
||||||
|
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
## Abstract class for any input/interaction with this module.
|
||||||
|
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method init*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method fetchCryptoServices*(self: AccessInterface): seq[CryptoRampDto] {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
type
|
||||||
|
## Abstract class (concept) which must be implemented by object/s used in this
|
||||||
|
## module.
|
||||||
|
DelegateInterface* = concept c
|
|
@ -0,0 +1,18 @@
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
## Abstract class for any input/interaction with this module.
|
||||||
|
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method load*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
# View Delegate Interface
|
||||||
|
# Delegate for the view must be declared here due to use of QtObject and multi
|
||||||
|
# inheritance, which is not well supported in Nim.
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
|
@ -0,0 +1,46 @@
|
||||||
|
import strformat, chronicles
|
||||||
|
|
||||||
|
type Item* = object
|
||||||
|
name: string
|
||||||
|
description: string
|
||||||
|
fees: string
|
||||||
|
logoUrl: string
|
||||||
|
siteUrl: string
|
||||||
|
hostname: string
|
||||||
|
|
||||||
|
proc initItem*(name, description, fees, logoUrl, siteUrl,
|
||||||
|
hostname: string): Item =
|
||||||
|
result.name = name
|
||||||
|
result.description = description
|
||||||
|
result.fees = fees
|
||||||
|
result.logoUrl = logoUrl
|
||||||
|
result.siteUrl = siteUrl
|
||||||
|
result.hostname = hostname
|
||||||
|
|
||||||
|
proc `$`*(self: Item): string =
|
||||||
|
result = "Item("
|
||||||
|
result &= fmt"name:{self.name}, "
|
||||||
|
result &= fmt"description:{self.description}, "
|
||||||
|
result &= fmt"fees:{self.fees}, "
|
||||||
|
result &= fmt"logoUrl:{self.logoUrl}, "
|
||||||
|
result &= fmt"siteUrl:{self.siteUrl}"
|
||||||
|
result &= fmt"hostname:{self.hostname}"
|
||||||
|
result &= ")"
|
||||||
|
|
||||||
|
method getName*(self: Item): string {.base.} =
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
method getDescription*(self: Item): string {.base.} =
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
method getFees*(self: Item): string {.base.} =
|
||||||
|
return self.fees
|
||||||
|
|
||||||
|
method getLogoUrl*(self: Item): string {.base.} =
|
||||||
|
return self.logoUrl
|
||||||
|
|
||||||
|
method getSiteUrl*(self: Item): string {.base.} =
|
||||||
|
return self.siteUrl
|
||||||
|
|
||||||
|
method getHostname*(self: Item): string {.base.} =
|
||||||
|
return self.hostname
|
|
@ -0,0 +1,69 @@
|
||||||
|
import NimQml, Tables
|
||||||
|
|
||||||
|
import item
|
||||||
|
|
||||||
|
type
|
||||||
|
ModelRole {.pure.} = enum
|
||||||
|
Name = UserRole + 1
|
||||||
|
Description
|
||||||
|
Fees
|
||||||
|
LogoUrl
|
||||||
|
SiteUrl
|
||||||
|
Hostname
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
Model* = ref object of QAbstractListModel
|
||||||
|
list: seq[Item]
|
||||||
|
|
||||||
|
proc delete(self: Model) =
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc setup(self: Model) =
|
||||||
|
self.QAbstractListModel.setup
|
||||||
|
|
||||||
|
proc newModel*(): Model =
|
||||||
|
new(result, delete)
|
||||||
|
result.setup()
|
||||||
|
|
||||||
|
method rowCount(self: Model, index: QModelIndex = nil): int =
|
||||||
|
return self.list.len
|
||||||
|
|
||||||
|
method roleNames(self: Model): Table[int, string] =
|
||||||
|
{
|
||||||
|
ModelRole.Name.int:"name",
|
||||||
|
ModelRole.Description.int:"description",
|
||||||
|
ModelRole.Fees.int:"fees",
|
||||||
|
ModelRole.LogoUrl.int:"logoUrl",
|
||||||
|
ModelRole.SiteUrl.int:"siteUrl",
|
||||||
|
ModelRole.Hostname.int:"hostname"
|
||||||
|
}.toTable
|
||||||
|
|
||||||
|
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||||
|
if (not index.isValid):
|
||||||
|
return
|
||||||
|
|
||||||
|
if (index.row < 0 or index.row >= self.list.len):
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = self.list[index.row]
|
||||||
|
let enumRole = role.ModelRole
|
||||||
|
|
||||||
|
case enumRole:
|
||||||
|
of ModelRole.Name:
|
||||||
|
result = newQVariant(item.getName)
|
||||||
|
of ModelRole.Description:
|
||||||
|
result = newQVariant(item.getDescription)
|
||||||
|
of ModelRole.Fees:
|
||||||
|
result = newQVariant(item.getFees)
|
||||||
|
of ModelRole.LogoUrl:
|
||||||
|
result = newQVariant(item.getLogoUrl)
|
||||||
|
of ModelRole.SiteUrl:
|
||||||
|
result = newQVariant(item.getSiteUrl)
|
||||||
|
of ModelRole.Hostname:
|
||||||
|
result = newQVariant(item.getHostname)
|
||||||
|
|
||||||
|
proc setItems*(self: Model, items: seq[Item]) =
|
||||||
|
self.beginResetModel()
|
||||||
|
self.list = items
|
||||||
|
self.endResetModel()
|
|
@ -0,0 +1,61 @@
|
||||||
|
import NimQml, sequtils, sugar
|
||||||
|
|
||||||
|
import ./io_interface, ./view, ./item, ./controller
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
import ../../../../global/global_singleton
|
||||||
|
import ../../../../core/eventemitter
|
||||||
|
import ../../../../../app_service/service/transaction/service as transaction_service
|
||||||
|
import ../../../../../app_service/service/transaction/cryptoRampDto
|
||||||
|
|
||||||
|
export io_interface
|
||||||
|
|
||||||
|
type
|
||||||
|
Module* = ref object of io_interface.AccessInterface
|
||||||
|
delegate: delegate_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
|
view: View
|
||||||
|
controller: controller.AccessInterface
|
||||||
|
moduleLoaded: bool
|
||||||
|
|
||||||
|
proc newModule*(
|
||||||
|
delegate: delegate_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
transactionService: transaction_service.Service,
|
||||||
|
): Module =
|
||||||
|
result = Module()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
|
result.view = newView(result)
|
||||||
|
result.controller = controller.newController(result, transactionService)
|
||||||
|
result.moduleLoaded = false
|
||||||
|
|
||||||
|
method delete*(self: Module) =
|
||||||
|
self.view.delete
|
||||||
|
self.controller.delete
|
||||||
|
|
||||||
|
method fetchCryptoServices*(self: Module) =
|
||||||
|
let cryptoServices = self.controller.fetchCryptoServices()
|
||||||
|
|
||||||
|
let items = cryptoServices.map(proc (w: CryptoRampDto): item.Item =
|
||||||
|
result = initItem(
|
||||||
|
w.name,
|
||||||
|
w.description,
|
||||||
|
w.fees,
|
||||||
|
w.logoUrl,
|
||||||
|
w.siteUrl,
|
||||||
|
w.hostname
|
||||||
|
))
|
||||||
|
self.view.setItems(items)
|
||||||
|
|
||||||
|
method load*(self: Module) =
|
||||||
|
singletonInstance.engine.setRootContextProperty("walletSectionBuySellCrypto", newQVariant(self.view))
|
||||||
|
self.controller.init()
|
||||||
|
self.view.load()
|
||||||
|
|
||||||
|
method isLoaded*(self: Module): bool =
|
||||||
|
return self.moduleLoaded
|
||||||
|
|
||||||
|
method viewDidLoad*(self: Module) =
|
||||||
|
self.fetchCryptoServices()
|
||||||
|
self.moduleLoaded = true
|
||||||
|
self.delegate.buySellCryptoModuleDidLoad()
|
|
@ -0,0 +1,40 @@
|
||||||
|
import NimQml
|
||||||
|
|
||||||
|
import ./model
|
||||||
|
import ./item
|
||||||
|
import ./io_interface
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
View* = ref object of QObject
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
model: Model
|
||||||
|
modelVariant: QVariant
|
||||||
|
|
||||||
|
proc delete*(self: View) =
|
||||||
|
self.model.delete
|
||||||
|
self.modelVariant.delete
|
||||||
|
self.QObject.delete
|
||||||
|
|
||||||
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
|
new(result, delete)
|
||||||
|
result.QObject.setup
|
||||||
|
result.delegate = delegate
|
||||||
|
result.model = newModel()
|
||||||
|
result.modelVariant = newQVariant(result.model)
|
||||||
|
|
||||||
|
proc load*(self: View) =
|
||||||
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
|
proc modelChanged*(self: View) {.signal.}
|
||||||
|
|
||||||
|
proc getModel(self: View): QVariant {.slot.} =
|
||||||
|
return self.modelVariant
|
||||||
|
|
||||||
|
QtProperty[QVariant] model:
|
||||||
|
read = getModel
|
||||||
|
notify = modelChanged
|
||||||
|
|
||||||
|
proc setItems*(self: View, items: seq[Item]) =
|
||||||
|
self.model.setItems(items)
|
||||||
|
self.modelChanged()
|
|
@ -51,6 +51,9 @@ method savedAddressesModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
method isEIP1559Enabled*(self: AccessInterface): bool {.base.} =
|
method isEIP1559Enabled*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method buySellCryptoModuleDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
type
|
type
|
||||||
## Abstract class (concept) which must be implemented by object/s used in this
|
## Abstract class (concept) which must be implemented by object/s used in this
|
||||||
## module.
|
## module.
|
||||||
|
|
|
@ -10,6 +10,7 @@ import ./collectibles/module as collectibles_module
|
||||||
import ./current_account/module as current_account_module
|
import ./current_account/module as current_account_module
|
||||||
import ./transactions/module as transactions_module
|
import ./transactions/module as transactions_module
|
||||||
import ./saved_addresses/module as saved_addresses_module
|
import ./saved_addresses/module as saved_addresses_module
|
||||||
|
import ./buy_sell_crypto/module as buy_sell_crypto_module
|
||||||
|
|
||||||
import ../../../global/global_singleton
|
import ../../../global/global_singleton
|
||||||
import ../../../core/eventemitter
|
import ../../../core/eventemitter
|
||||||
|
@ -39,6 +40,7 @@ type
|
||||||
currentAccountModule: current_account_module.AccessInterface
|
currentAccountModule: current_account_module.AccessInterface
|
||||||
transactionsModule: transactions_module.AccessInterface
|
transactionsModule: transactions_module.AccessInterface
|
||||||
savedAddressesModule: saved_addresses_module.AccessInterface
|
savedAddressesModule: saved_addresses_module.AccessInterface
|
||||||
|
buySellCryptoModule: buy_sell_crypto_module.AccessInterface
|
||||||
|
|
||||||
proc newModule*[T](
|
proc newModule*[T](
|
||||||
delegate: T,
|
delegate: T,
|
||||||
|
@ -65,6 +67,7 @@ proc newModule*[T](
|
||||||
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService)
|
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService)
|
||||||
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService)
|
result.transactionsModule = transactions_module.newModule(result, events, transactionService, walletAccountService)
|
||||||
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
|
result.savedAddressesModule = saved_addresses_module.newModule(result, events, savedAddressService)
|
||||||
|
result.buySellCryptoModule = buy_sell_crypto_module.newModule(result, events, transactionService)
|
||||||
|
|
||||||
method delete*[T](self: Module[T]) =
|
method delete*[T](self: Module[T]) =
|
||||||
self.accountTokensModule.delete
|
self.accountTokensModule.delete
|
||||||
|
@ -74,6 +77,7 @@ method delete*[T](self: Module[T]) =
|
||||||
self.currentAccountModule.delete
|
self.currentAccountModule.delete
|
||||||
self.transactionsModule.delete
|
self.transactionsModule.delete
|
||||||
self.savedAddressesModule.delete
|
self.savedAddressesModule.delete
|
||||||
|
self.buySellCryptoModule.delete
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
self.view.delete
|
self.view.delete
|
||||||
|
|
||||||
|
@ -115,6 +119,7 @@ method load*[T](self: Module[T]) =
|
||||||
self.currentAccountModule.load()
|
self.currentAccountModule.load()
|
||||||
self.transactionsModule.load()
|
self.transactionsModule.load()
|
||||||
self.savedAddressesModule.load()
|
self.savedAddressesModule.load()
|
||||||
|
self.buySellCryptoModule.load()
|
||||||
|
|
||||||
method isLoaded*[T](self: Module[T]): bool =
|
method isLoaded*[T](self: Module[T]): bool =
|
||||||
return self.moduleLoaded
|
return self.moduleLoaded
|
||||||
|
@ -141,6 +146,9 @@ proc checkIfModuleDidLoad[T](self: Module[T]) =
|
||||||
if(not self.savedAddressesModule.isLoaded()):
|
if(not self.savedAddressesModule.isLoaded()):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if(not self.buySellCryptoModule.isLoaded()):
|
||||||
|
return
|
||||||
|
|
||||||
self.switchAccount(0)
|
self.switchAccount(0)
|
||||||
let currency = self.controller.getCurrency()
|
let currency = self.controller.getCurrency()
|
||||||
let signingPhrase = self.controller.getSigningPhrase()
|
let signingPhrase = self.controller.getSigningPhrase()
|
||||||
|
@ -174,3 +182,6 @@ method transactionsModuleDidLoad*[T](self: Module[T]) =
|
||||||
|
|
||||||
method savedAddressesModuleDidLoad*[T](self: Module[T]) =
|
method savedAddressesModuleDidLoad*[T](self: Module[T]) =
|
||||||
self.checkIfModuleDidLoad()
|
self.checkIfModuleDidLoad()
|
||||||
|
|
||||||
|
method buySellCryptoModuleDidLoad*[T](self: Module[T]) =
|
||||||
|
self.checkIfModuleDidLoad()
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import json, strformat
|
||||||
|
|
||||||
|
include ../../common/json_utils
|
||||||
|
|
||||||
|
type
|
||||||
|
CryptoRampDto* = ref object of RootObj
|
||||||
|
name*: string
|
||||||
|
description*: string
|
||||||
|
fees*: string
|
||||||
|
logoUrl*: string
|
||||||
|
siteUrl*: string
|
||||||
|
hostname*: string
|
||||||
|
|
||||||
|
proc newDto*(
|
||||||
|
name: string,
|
||||||
|
description: string,
|
||||||
|
fees: string,
|
||||||
|
logoUrl: string,
|
||||||
|
siteUrl: string,
|
||||||
|
hostname: string
|
||||||
|
): CryptoRampDto =
|
||||||
|
return CryptoRampDto(
|
||||||
|
name: name,
|
||||||
|
description: description,
|
||||||
|
fees: fees,
|
||||||
|
logoUrl: logoUrl,
|
||||||
|
siteUrl: siteUrl,
|
||||||
|
hostname: hostname
|
||||||
|
)
|
||||||
|
|
||||||
|
proc `$`*(self: CryptoRampDto): string =
|
||||||
|
result = "CryptoRampDto("
|
||||||
|
result &= fmt"name:{self.name}, "
|
||||||
|
result &= fmt"description:{self.description}, "
|
||||||
|
result &= fmt"fees:{self.fees}, "
|
||||||
|
result &= fmt"logoUrl:{self.logoUrl}, "
|
||||||
|
result &= fmt"siteUrl:{self.siteUrl}, "
|
||||||
|
result &= fmt"hostname:{self.hostname}"
|
||||||
|
result &= ")"
|
||||||
|
|
||||||
|
proc toCryptoRampDto*(jsonObj: JsonNode): CryptoRampDto =
|
||||||
|
result = CryptoRampDto()
|
||||||
|
discard jsonObj.getProp("name", result.name)
|
||||||
|
discard jsonObj.getProp("description", result.description)
|
||||||
|
discard jsonObj.getProp("fees", result.fees)
|
||||||
|
discard jsonObj.getProp("logoUrl", result.logoUrl)
|
||||||
|
discard jsonObj.getProp("siteUrl", result.siteUrl)
|
||||||
|
discard jsonObj.getProp("hostname", result.hostname)
|
|
@ -17,6 +17,7 @@ import ../settings/service as settings_service
|
||||||
import ../eth/dto/transaction as transaction_data_dto
|
import ../eth/dto/transaction as transaction_data_dto
|
||||||
import ../eth/dto/[contract, method_dto]
|
import ../eth/dto/[contract, method_dto]
|
||||||
import ./dto as transaction_dto
|
import ./dto as transaction_dto
|
||||||
|
import ./cryptoRampDto
|
||||||
import ../eth/utils as eth_utils
|
import ../eth/utils as eth_utils
|
||||||
import ../../common/conversion
|
import ../../common/conversion
|
||||||
|
|
||||||
|
@ -407,3 +408,15 @@ QtObject:
|
||||||
maxFeePerGasM: parseFloat(common_conversion.wei2gwei($(maxFeePerGasM))),
|
maxFeePerGasM: parseFloat(common_conversion.wei2gwei($(maxFeePerGasM))),
|
||||||
maxFeePerGasH: parseFloat(common_conversion.wei2gwei($(baseFee + maxPriorityFeePerGas)))
|
maxFeePerGasH: parseFloat(common_conversion.wei2gwei($(baseFee + maxPriorityFeePerGas)))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proc fetchCryptoServices*(self: Service): seq[CryptoRampDto] =
|
||||||
|
try:
|
||||||
|
let response = transactions.fetchCryptoServices()
|
||||||
|
|
||||||
|
if not response.error.isNil:
|
||||||
|
raise newException(ValueError, "Error fetching crypto services" & response.error.message)
|
||||||
|
|
||||||
|
return response.result.getElems().map(x => x.toCryptoRampDto())
|
||||||
|
except Exception as e:
|
||||||
|
error "Error fetching crypto services", message = e.msg
|
||||||
|
return @[]
|
||||||
|
|
|
@ -39,3 +39,6 @@ proc getPendingOutboundTransactionsByAddress*(address: string): RpcResponse[Json
|
||||||
let payload = %* [address]
|
let payload = %* [address]
|
||||||
result = callPrivateRPC("wallet_getPendingOutboundTransactionsByAddress", payload)
|
result = callPrivateRPC("wallet_getPendingOutboundTransactionsByAddress", payload)
|
||||||
|
|
||||||
|
proc fetchCryptoServices*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
result = core.callPrivateRPC("wallet_getCryptoOnRamps", %* [])
|
||||||
|
|
||||||
|
|
|
@ -123,16 +123,24 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
property int btnOuterMargin: Style.current.bigPadding
|
Component {
|
||||||
|
id: buySellModal
|
||||||
|
CryptoServicesModal {
|
||||||
|
onClosed: destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
id: walletMenu
|
id: walletMenu
|
||||||
width: sendBtn.width + receiveBtn.width + settingsBtn.width
|
|
||||||
+ walletMenu.btnOuterMargin * 2
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 16
|
anchors.rightMargin: 16
|
||||||
|
|
||||||
|
spacing: Style.current.bigPadding
|
||||||
|
|
||||||
HeaderButton {
|
HeaderButton {
|
||||||
id: sendBtn
|
id: sendBtn
|
||||||
imageSource: Style.svg("send")
|
imageSource: Style.svg("send")
|
||||||
|
@ -152,8 +160,17 @@ Item {
|
||||||
onClicked: function () {
|
onClicked: function () {
|
||||||
Global.openPopup(receiveModalComponent);
|
Global.openPopup(receiveModalComponent);
|
||||||
}
|
}
|
||||||
anchors.left: sendBtn.right
|
}
|
||||||
anchors.leftMargin: walletMenu.btnOuterMargin
|
|
||||||
|
HeaderButton {
|
||||||
|
id: buySellBtn
|
||||||
|
imageSource: Style.svg("crypto-icon")
|
||||||
|
flipImage: true
|
||||||
|
//% "Buy / Sell"
|
||||||
|
text: qsTrId("Buy / Sell")
|
||||||
|
onClicked: function () {
|
||||||
|
Global.openPopup(buySellModal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderButton {
|
HeaderButton {
|
||||||
|
@ -169,8 +186,6 @@ Item {
|
||||||
newSettingsMenu.popup(x, settingsBtn.height)
|
newSettingsMenu.popup(x, settingsBtn.height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
anchors.left: receiveBtn.right
|
|
||||||
anchors.leftMargin: walletMenu.btnOuterMargin
|
|
||||||
|
|
||||||
// TODO: replace with StatusPopupMenu
|
// TODO: replace with StatusPopupMenu
|
||||||
PopupMenu {
|
PopupMenu {
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
import shared.panels 1.0
|
||||||
|
|
||||||
|
import StatusQ.Popups 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
|
||||||
|
import "../controls"
|
||||||
|
import "../stores"
|
||||||
|
|
||||||
|
StatusModal {
|
||||||
|
id: cryptoServicesPopupRoot
|
||||||
|
|
||||||
|
height: 400
|
||||||
|
header.title: qsTr("Buy / Sell crypto")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loader
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: servicesComponent
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: servicesComponent
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: Style.current.padding
|
||||||
|
anchors.bottomMargin: Style.current.padding
|
||||||
|
anchors.leftMargin: Style.current.padding
|
||||||
|
anchors.rightMargin: Style.current.padding
|
||||||
|
StyledText {
|
||||||
|
id: note
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: Style.current.secondaryText
|
||||||
|
text: qsTr("Choose a service you'd like to use to buy crypto")
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
anchors.top: note.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.topMargin: Style.current.padding
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 394
|
||||||
|
model: RootStore.cryptoRampServicesModel
|
||||||
|
focus: true
|
||||||
|
spacing: Style.current.padding
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
delegate: StatusListItem {
|
||||||
|
width: parent.width
|
||||||
|
title: name
|
||||||
|
subTitle: description
|
||||||
|
image.source: logoUrl
|
||||||
|
label: fees
|
||||||
|
statusListItemSubTitle.maximumLineCount: 1
|
||||||
|
components: [
|
||||||
|
StatusIcon {
|
||||||
|
icon: "chevron-down"
|
||||||
|
rotation: 270
|
||||||
|
color: Theme.palette.baseColor1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
onClicked: {
|
||||||
|
Global.openLink(siteUrl);
|
||||||
|
cryptoServicesPopupRoot.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,8 @@ QtObject {
|
||||||
property var testNetworks: networksModule.test
|
property var testNetworks: networksModule.test
|
||||||
property var enabledNetworks: networksModule.enabled
|
property var enabledNetworks: networksModule.enabled
|
||||||
|
|
||||||
|
property var cryptoRampServicesModel: walletSectionBuySellCrypto.model
|
||||||
|
|
||||||
// This should be exposed to the UI via "walletModule", WalletModule should use
|
// This should be exposed to the UI via "walletModule", WalletModule should use
|
||||||
// Accounts Service which keeps the info about that (isFirstTimeAccountLogin).
|
// Accounts Service which keeps the info about that (isFirstTimeAccountLogin).
|
||||||
// Then in the View of WalletModule we may have either QtProperty or
|
// Then in the View of WalletModule we may have either QtProperty or
|
||||||
|
|
Loading…
Reference in New Issue