mirror of
https://github.com/oxen-io/oxen-electron-gui-wallet.git
synced 2023-12-14 06:13:02 +01:00
bcf21c3804
Main screen redesign Removed dark mode styling and made it all dark. Fix large button styling on navigation Receive page styling Startup pages redesign Updating field stylings. Fix value display in recieve Updated footer. Added service node page. Added wallet settings. Added disable prop to loki field. Update settings page. Added merging config with default daemon option incase user provides invalid port (empty, null, etc...) Removed theme selection Update wallet-select pages Fixed converting numbers to string Update layout on address page Added loki logo. Made header a bit smaller. Updated wallet init styling. Highlight primary address in receive. updated packages. Updated transaction styling. Simpler tx json handling. Added address validation Fixed up wallet restoration Default node to remote. Added drop down button to the remote node input instead of having it as a seperate field. Removed review page. Center align welcome page. Replaced ryo wallet images with loki image. Updated transaction styling. Fix wallet errors only showing once which causes the next error to just show the loading overlay. Added staking Fix up status display in footer. remove is_ready as lokid doesn't return it. Fixed balance display in receive. Center unlock in wallet details. Updated README other updates.
326 lines
11 KiB
Vue
326 lines
11 KiB
Vue
<template>
|
|
<q-page class="send">
|
|
<template v-if="view_only">
|
|
<div class="q-pa-md">
|
|
|
|
View-only mode. Please load full wallet in order to send coins.
|
|
|
|
</div>
|
|
</template>
|
|
<template v-else>
|
|
|
|
<div class="q-pa-md">
|
|
|
|
<div class="row gutter-md">
|
|
<!-- Amount -->
|
|
<div class="col-6">
|
|
<LokiField label="Amount" :error="$v.newTx.amount.$error">
|
|
<q-input v-model="newTx.amount"
|
|
:dark="theme=='dark'"
|
|
type="number"
|
|
min="0"
|
|
:max="unlocked_balance / 1e9"
|
|
placeholder="0"
|
|
@blur="$v.newTx.amount.$touch"
|
|
hide-underline
|
|
/>
|
|
<q-btn color="secondary" @click="newTx.amount = unlocked_balance / 1e9" :text-color="theme=='dark'?'white':'dark'">All</q-btn>
|
|
</LokiField>
|
|
</div>
|
|
|
|
<!-- Priority -->
|
|
<div class="col-6">
|
|
<LokiField label="Priority">
|
|
<q-select :dark="theme=='dark'"
|
|
v-model="newTx.priority"
|
|
:options="priorityOptions"
|
|
hide-underline
|
|
/>
|
|
</LokiField>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Address -->
|
|
<div class="col q-mt-sm">
|
|
<LokiField label="Address" :error="$v.newTx.address.$error">
|
|
<q-input v-model="newTx.address"
|
|
:dark="theme=='dark'"
|
|
@blur="$v.newTx.address.$touch"
|
|
:placeholder="address_placeholder"
|
|
hide-underline
|
|
/>
|
|
<q-btn color="secondary" :text-color="theme=='dark'?'white':'dark'" to="addressbook">Contacts</q-btn>
|
|
</LokiField>
|
|
</div>
|
|
|
|
<!-- Payment ID -->
|
|
<div class="col q-mt-sm">
|
|
<LokiField label="Payment id" :error="$v.newTx.payment_id.$error" optional>
|
|
<q-input v-model="newTx.payment_id"
|
|
:dark="theme=='dark'"
|
|
@blur="$v.newTx.payment_id.$touch"
|
|
placeholder="16 or 64 hexadecimal characters"
|
|
hide-underline
|
|
/>
|
|
</LokiField>
|
|
</div>
|
|
|
|
<!-- Save to address book -->
|
|
<q-field>
|
|
<q-checkbox v-model="newTx.address_book.save" label="Save to address book" :dark="theme=='dark'" />
|
|
</q-field>
|
|
|
|
<div v-if="newTx.address_book.save">
|
|
<LokiField label="Name" optional>
|
|
<q-input v-model="newTx.address_book.name"
|
|
:dark="theme=='dark'"
|
|
placeholder="Name that belongs to this address"
|
|
hide-underline
|
|
/>
|
|
</LokiField>
|
|
<LokiField class="q-mt-sm" label="Notes" optional>
|
|
<q-input v-model="newTx.address_book.description"
|
|
type="textarea"
|
|
rows="2"
|
|
:dark="theme=='dark'"
|
|
placeholder="Additional notes"
|
|
hide-underline
|
|
/>
|
|
</LokiField>
|
|
</div>
|
|
|
|
<q-field class="q-pt-sm">
|
|
<q-btn
|
|
class="send-btn"
|
|
:disable="!is_able_to_send"
|
|
color="primary" @click="send()" label="Send" />
|
|
</q-field>
|
|
|
|
</div>
|
|
|
|
<q-inner-loading :visible="tx_status.sending" :dark="theme=='dark'">
|
|
<q-spinner color="primary" :size="30" />
|
|
</q-inner-loading>
|
|
|
|
</template>
|
|
|
|
</q-page>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapState } from "vuex"
|
|
import { required, decimal } from "vuelidate/lib/validators"
|
|
import { payment_id, address, greater_than_zero } from "src/validators/common"
|
|
import Identicon from "components/identicon"
|
|
import LokiField from "components/loki_field"
|
|
const objectAssignDeep = require("object-assign-deep");
|
|
export default {
|
|
computed: mapState({
|
|
theme: state => state.gateway.app.config.appearance.theme,
|
|
view_only: state => state.gateway.wallet.info.view_only,
|
|
unlocked_balance: state => state.gateway.wallet.info.unlocked_balance,
|
|
tx_status: state => state.gateway.tx_status,
|
|
is_ready (state) {
|
|
return this.$store.getters["gateway/isReady"]
|
|
},
|
|
is_able_to_send (state) {
|
|
return this.$store.getters["gateway/isAbleToSend"]
|
|
},
|
|
address_placeholder (state) {
|
|
const wallet = state.gateway.wallet.info;
|
|
const prefix = (wallet && wallet.address && wallet.address[0]) || "L";
|
|
return `${prefix}..`;
|
|
}
|
|
}),
|
|
data () {
|
|
return {
|
|
sending: false,
|
|
newTx: {
|
|
amount: 0,
|
|
address: "",
|
|
payment_id: "",
|
|
priority: 0,
|
|
address_book: {
|
|
save: false,
|
|
name: "",
|
|
description: ""
|
|
}
|
|
},
|
|
priorityOptions: [
|
|
{label: "Normal (x1 fee)", value: 0},
|
|
{label: "Slow (x0.25 fee)", value: 1},
|
|
{label: "Fast (x5 fee)", value: 2},
|
|
{label: "Fastest (x41.5 fee)", value: 3},
|
|
],
|
|
}
|
|
},
|
|
validations: {
|
|
newTx: {
|
|
amount: {
|
|
required,
|
|
decimal,
|
|
greater_than_zero
|
|
},
|
|
address: {
|
|
required,
|
|
isAddress(value) {
|
|
if (value === '') return true
|
|
|
|
return new Promise(resolve => {
|
|
address(value, this.$gateway)
|
|
.then(() => resolve(true))
|
|
.catch(e => resolve(false))
|
|
});
|
|
}
|
|
},
|
|
payment_id: { payment_id }
|
|
}
|
|
},
|
|
watch: {
|
|
tx_status: {
|
|
handler(val, old){
|
|
if(val.code == old.code) return
|
|
switch(this.tx_status.code) {
|
|
case 0:
|
|
this.$q.notify({
|
|
type: "positive",
|
|
timeout: 1000,
|
|
message: this.tx_status.message
|
|
})
|
|
this.$v.$reset();
|
|
this.newTx = {
|
|
amount: 0,
|
|
address: "",
|
|
payment_id: "",
|
|
priority: 0,
|
|
address_book: {
|
|
save: false,
|
|
name: "",
|
|
description: ""
|
|
}
|
|
}
|
|
break;
|
|
case -1:
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: this.tx_status.message
|
|
})
|
|
break;
|
|
}
|
|
},
|
|
deep: true
|
|
},
|
|
$route (to) {
|
|
if(to.path == "/wallet/send" && to.query.hasOwnProperty("address")) {
|
|
this.autoFill(to.query)
|
|
}
|
|
}
|
|
},
|
|
mounted () {
|
|
if(this.$route.path == "/wallet/send" && this.$route.query.hasOwnProperty("address")) {
|
|
this.autoFill(this.$route.query)
|
|
}
|
|
},
|
|
methods: {
|
|
|
|
autoFill: function (info) {
|
|
this.newTx.address = info.address
|
|
this.newTx.payment_id = info.payment_id
|
|
},
|
|
|
|
send: function () {
|
|
|
|
this.$v.newTx.$touch()
|
|
|
|
if(this.newTx.amount < 0) {
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: "Amount cannot be negative"
|
|
})
|
|
return
|
|
} else if(this.newTx.amount == 0) {
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: "Amount must be greater than zero"
|
|
})
|
|
return
|
|
} else if(this.newTx.amount > this.unlocked_balance / 1e9) {
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: "Not enough unlocked balance"
|
|
})
|
|
return
|
|
} else if (this.$v.newTx.amount.$error) {
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: "Amount not valid"
|
|
})
|
|
return
|
|
}
|
|
|
|
|
|
if (this.$v.newTx.address.$error) {
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: "Address not valid"
|
|
})
|
|
return
|
|
}
|
|
|
|
if (this.$v.newTx.payment_id.$error) {
|
|
this.$q.notify({
|
|
type: "negative",
|
|
timeout: 1000,
|
|
message: "Payment id not valid"
|
|
})
|
|
return
|
|
}
|
|
|
|
this.$q.dialog({
|
|
title: "Transfer",
|
|
message: "Enter wallet password to continue.",
|
|
prompt: {
|
|
model: "",
|
|
type: "password"
|
|
},
|
|
ok: {
|
|
label: "SEND"
|
|
},
|
|
cancel: {
|
|
flat: true,
|
|
label: "CANCEL",
|
|
color: this.theme=="dark"?"white":"dark"
|
|
}
|
|
}).then(password => {
|
|
this.$store.commit("gateway/set_tx_status", {
|
|
code: 1,
|
|
message: "Sending transaction",
|
|
sending: true
|
|
})
|
|
const newTx = objectAssignDeep.noMutate(this.newTx, {password})
|
|
this.$gateway.send("wallet", "transfer", newTx)
|
|
}).catch(() => {
|
|
})
|
|
}
|
|
},
|
|
components: {
|
|
Identicon,
|
|
LokiField
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.send {
|
|
.send-btn {
|
|
width: 200px;
|
|
}
|
|
}
|
|
</style>
|