more UI updates
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// noinspection JSPotentiallyInvalidUsageOfThis
|
// noinspection JSPotentiallyInvalidUsageOfThis
|
||||||
|
|
||||||
import {invokeCallback, mixin} from "@/common.js";
|
import {invokeCallback, mixin} from "@/common.js";
|
||||||
import {chart, createShape, deleteShapeId, dragging, draggingShapeIds, drawShape} from "@/charts/chart.js";
|
import {chart, createShape, deleteShapeId, dragging, draggingShapeIds, drawShape, widget} from "@/charts/chart.js";
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -30,7 +30,7 @@ export const ShapeType = {
|
|||||||
Ray: {name: 'Ray', code: 'ray'},
|
Ray: {name: 'Ray', code: 'ray'},
|
||||||
Line: {name: 'Extended Line', code: 'extended'},
|
Line: {name: 'Extended Line', code: 'extended'},
|
||||||
HRay: {name: 'Horizontal Ray', code: 'horizontal_ray'},
|
HRay: {name: 'Horizontal Ray', code: 'horizontal_ray'},
|
||||||
HLine: {name: 'Horizontal Line', code: 'horizontal_line'},
|
HLine: {name: 'Horizontal Line', code: 'horizontal_line', drawingProp: 'linetoolhorzline'},
|
||||||
VLine: {name: 'Vertical Line', code: 'vertical_line'},
|
VLine: {name: 'Vertical Line', code: 'vertical_line'},
|
||||||
PriceRange: {name: 'Price Range', code: 'price_range'},
|
PriceRange: {name: 'Price Range', code: 'price_range'},
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ class Shape {
|
|||||||
this.model = model // subclass-specific
|
this.model = model // subclass-specific
|
||||||
this.points = null
|
this.points = null
|
||||||
this.points = this.pointsFromModel()
|
this.points = this.pointsFromModel()
|
||||||
console.log('construct points', this.points)
|
// console.log('construct points', this.points)
|
||||||
this.props = props === null ? this.propsFromModel() : mixin(props, this.propsFromModel())
|
this.props = props === null ? this.propsFromModel() : mixin(props, this.propsFromModel())
|
||||||
if (onModel !== null)
|
if (onModel !== null)
|
||||||
this.onModel = onModel
|
this.onModel = onModel
|
||||||
@@ -59,12 +59,26 @@ class Shape {
|
|||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
// have the user draw this shape
|
// have the user draw this shape
|
||||||
console.log(`draw ${this.type.name}`)
|
console.log(`draw ${this.type.name}`, this.model)
|
||||||
if (this.id)
|
if (this.id)
|
||||||
throw Error(`Shape already exists ${this.id}`)
|
throw Error(`Shape already exists ${this.id}`)
|
||||||
|
const or = this.drawingOverrides();
|
||||||
|
// console.log('drawing overrides', or)
|
||||||
|
widget.applyOverrides(or)
|
||||||
drawShape(this.type, new ShapeTVCallbacks(this))
|
drawShape(this.type, new ShapeTVCallbacks(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return an object with property defaults, e.g. { "linetoolhorzline.linecolor": "#7f11e0" }
|
||||||
|
// https://www.tradingview.com/charting-library-docs/latest/api/modules/Charting_Library#drawingoverrides
|
||||||
|
drawingOverrides() {
|
||||||
|
if (this.model.color===null) return null
|
||||||
|
const o = {}
|
||||||
|
const p = this.type.drawingProp
|
||||||
|
o[p+".linecolor"] = this.model.color
|
||||||
|
o[p+".textcolor"] = this.model.color
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
if (this.id !== null) return
|
if (this.id !== null) return
|
||||||
// programatically create the shape using the current this.points
|
// programatically create the shape using the current this.points
|
||||||
@@ -257,6 +271,7 @@ class ShapeTVCallbacks {
|
|||||||
|
|
||||||
constructor(shape) {
|
constructor(shape) {
|
||||||
this.shape = shape
|
this.shape = shape
|
||||||
|
this.creating = false
|
||||||
}
|
}
|
||||||
|
|
||||||
onCreate(shapeId, _tvShape, points, props) {
|
onCreate(shapeId, _tvShape, points, props) {
|
||||||
@@ -264,6 +279,7 @@ class ShapeTVCallbacks {
|
|||||||
throw Error(`Created a shape ${shapeId} where one already existed ${this.shape.id}`)
|
throw Error(`Created a shape ${shapeId} where one already existed ${this.shape.id}`)
|
||||||
this.shape.id = shapeId
|
this.shape.id = shapeId
|
||||||
if( this.shape.lock ) return
|
if( this.shape.lock ) return
|
||||||
|
this.creating = true
|
||||||
invokeCallback(this.shape, 'onCreate', points, props)
|
invokeCallback(this.shape, 'onCreate', points, props)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +290,11 @@ class ShapeTVCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onProps(shapeId, _tvShape, props) {
|
onProps(shapeId, _tvShape, props) {
|
||||||
|
// console.log('onProps', props)
|
||||||
|
if (this.creating) {
|
||||||
|
this.creating = false
|
||||||
|
return
|
||||||
|
}
|
||||||
this.shape.props = props
|
this.shape.props = props
|
||||||
this.shape.onProps(props)
|
this.shape.onProps(props)
|
||||||
this.shape.onDirtyModel(this.shape.propsToModel)
|
this.shape.onDirtyModel(this.shape.propsToModel)
|
||||||
@@ -353,7 +374,6 @@ export class HLine extends Shape {
|
|||||||
|
|
||||||
propsToModel() {this.model.color=this.props.linecolor}
|
propsToModel() {this.model.color=this.props.linecolor}
|
||||||
|
|
||||||
|
|
||||||
onDrag(points) {
|
onDrag(points) {
|
||||||
const s = this.tvShape();
|
const s = this.tvShape();
|
||||||
console.log('shape', s)
|
console.log('shape', s)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
:label="order.amountIsTokenA ? 'Amount':('Value in '+co.selectedSymbol.quote.s)"
|
:label="order.amountIsTokenA ? 'Amount':('Value in '+co.selectedSymbol.quote.s)"
|
||||||
>
|
>
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<v-btn variant="tonal" :color="color" class="ml-3"
|
<v-btn variant="outlined" :color="color" class="ml-3"
|
||||||
:text="(order.buy ? 'Buy ' : 'Sell ') + co.selectedSymbol.base.s"
|
:text="(order.buy ? 'Buy ' : 'Sell ') + co.selectedSymbol.base.s"
|
||||||
@click="order.buy=!order.buy"/>
|
@click="order.buy=!order.buy"/>
|
||||||
</template>
|
</template>
|
||||||
@@ -50,6 +50,7 @@ import {lightenColor, lightenColor2} from "@/misc.js";
|
|||||||
import {useTheme} from "vuetify";
|
import {useTheme} from "vuetify";
|
||||||
import RowBar from "@/components/chart/RowBar.vue";
|
import RowBar from "@/components/chart/RowBar.vue";
|
||||||
import ColorBand from "@/components/chart/ColorBand.vue";
|
import ColorBand from "@/components/chart/ColorBand.vue";
|
||||||
|
import Color from "color";
|
||||||
|
|
||||||
const props = defineProps(['order'])
|
const props = defineProps(['order'])
|
||||||
const co = useChartOrderStore()
|
const co = useChartOrderStore()
|
||||||
@@ -66,7 +67,7 @@ function builders(order) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const theme = useTheme().current
|
const theme = useTheme().current
|
||||||
const color = computed(()=>props.order.buy?theme.value.colors.success:theme.value.colors.error)
|
const color = computed(()=>new Color(props.order.buy?theme.value.colors.success:theme.value.colors.error).darken(0.2).string())
|
||||||
const lightColor = computed(() => lightenColor(color.value))
|
const lightColor = computed(() => lightenColor(color.value))
|
||||||
const faintColor = computed(() => lightenColor2(color.value))
|
const faintColor = computed(() => lightenColor2(color.value))
|
||||||
const colorStyle = computed(() => { return {'color': color.value} })
|
const colorStyle = computed(() => { return {'color': color.value} })
|
||||||
|
|||||||
@@ -1,18 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="d-flex flex-column h-100">
|
<div class="d-flex flex-column h-100">
|
||||||
<div class="d-flex mb-1">
|
<toolbar>
|
||||||
<span class="arrow align-self-start"><v-icon icon="mdi-arrow-up-bold" color="green"/></span>
|
<v-btn variant="flat" prepend-icon="mdi-plus" @click="co.newOrder" v-if="co.orders.length===0">New Order</v-btn>
|
||||||
<span class="logo">dexorder</span>
|
<v-btn variant="text" prepend-icon="mdi-send" :color="orderColor" v-if="co.orders.length>0">Place Order</v-btn>
|
||||||
<v-chip text="ALPHA" size='x-small' color="red" class="align-self-start pr-6" variant="text"/>
|
<v-btn variant="flat" prepend-icon="mdi-cancel" v-if="co.orders.length>0" @click="cancelOrder">Cancel</v-btn>
|
||||||
<v-btn variant="flat" prepend-icon="mdi-plus" @click="co.newOrder" v-if="co.orders.length===0">New Order</v-btn>
|
</toolbar>
|
||||||
<!-- <v-btn variant="flat" prepend-icon="mdi-question" @click="build('Test')">Test</v-btn>-->
|
|
||||||
<v-btn variant="tonal" prepend-icon="mdi-send" :color="orderColor" v-if="co.orders.length>0">Place Order</v-btn>
|
|
||||||
<v-btn variant="text" prepend-icon="mdi-cancel" v-if="co.orders.length>0" @click="cancelOrder">Cancel</v-btn>
|
|
||||||
|
|
||||||
<div class="w-100 d-flex justify-end">
|
|
||||||
<v-btn variant="text" icon="mdi-safe-square" color="grey-darken-2" text="Vault" @click="$router.push('/vault')"></v-btn>
|
|
||||||
<v-btn variant="text" icon="mdi-information-outline" text="Order Status" @click="$router.push('/orders')"></v-btn>
|
|
||||||
</div>
|
|
||||||
<v-dialog v-model="showCancel" max-width="300">
|
<v-dialog v-model="showCancel" max-width="300">
|
||||||
<v-card title="Cancel Order?" text="Do you want to cancel this order and create a new one?">
|
<v-card title="Cancel Order?" text="Do you want to cancel this order and create a new one?">
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
@@ -22,7 +14,6 @@
|
|||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
</div>
|
|
||||||
<!-- <div v-for="b in co.builderList">{{JSON.stringify(b)}}</div>-->
|
<!-- <div v-for="b in co.builderList">{{JSON.stringify(b)}}</div>-->
|
||||||
<div class="overflow-y-auto">
|
<div class="overflow-y-auto">
|
||||||
<template v-for="o in co.orders">
|
<template v-for="o in co.orders">
|
||||||
@@ -41,6 +32,7 @@ import {useOrderStore, useStore} from "@/store/store.js";
|
|||||||
import {routeFinder} from "@/blockchain/route.js";
|
import {routeFinder} from "@/blockchain/route.js";
|
||||||
import ChartOrder from "@/components/chart/ChartOrder.vue";
|
import ChartOrder from "@/components/chart/ChartOrder.vue";
|
||||||
import {useTheme} from "vuetify";
|
import {useTheme} from "vuetify";
|
||||||
|
import Toolbar from "@/components/chart/Toolbar.vue";
|
||||||
|
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
const co = useChartOrderStore()
|
const co = useChartOrderStore()
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {computed} from "vue";
|
|||||||
|
|
||||||
const props = defineProps(['color'])
|
const props = defineProps(['color'])
|
||||||
const computedStyle = computed(() => {
|
const computedStyle = computed(() => {
|
||||||
console.log('computing bar color')
|
|
||||||
return {
|
return {
|
||||||
'background-color': props.color,
|
'background-color': props.color,
|
||||||
'border-color': props.color,
|
'border-color': props.color,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ import {chart} from "@/charts/chart.js";
|
|||||||
import {useChartOrderStore} from "@/orderbuild.js";
|
import {useChartOrderStore} from "@/orderbuild.js";
|
||||||
import Color from "color";
|
import Color from "color";
|
||||||
import {HLine} from "@/charts/shape.js";
|
import {HLine} from "@/charts/shape.js";
|
||||||
import {builderDefaults, lightenColor2} from "@/misc.js";
|
import {builderDefaults, lightenColor2, lineColor} from "@/misc.js";
|
||||||
import {useTheme} from "vuetify";
|
import {useTheme} from "vuetify";
|
||||||
import {useOrderStore} from "@/store/store.js";
|
import {useOrderStore} from "@/store/store.js";
|
||||||
import RowBar from "@/components/chart/RowBar.vue";
|
import RowBar from "@/components/chart/RowBar.vue";
|
||||||
@@ -77,6 +77,12 @@ const theme = useTheme().current
|
|||||||
const props = defineProps(['order', 'builder'])
|
const props = defineProps(['order', 'builder'])
|
||||||
const emit = defineEmits(['update:builder'])
|
const emit = defineEmits(['update:builder'])
|
||||||
|
|
||||||
|
function computeDefaultColor() {
|
||||||
|
const index = props.order.builders.indexOf(props.builder)
|
||||||
|
return lineColor(props.order.buy, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultColor = computeDefaultColor()
|
||||||
|
|
||||||
// Fields must be defined in order to be reactive
|
// Fields must be defined in order to be reactive
|
||||||
builderDefaults(props, emit, {
|
builderDefaults(props, emit, {
|
||||||
@@ -87,7 +93,7 @@ builderDefaults(props, emit, {
|
|||||||
priceB: null,
|
priceB: null,
|
||||||
rungs: 1,
|
rungs: 1,
|
||||||
skew: 0,
|
skew: 0,
|
||||||
color: null,
|
color: defaultColor,
|
||||||
})
|
})
|
||||||
|
|
||||||
const skew100 = computed( {
|
const skew100 = computed( {
|
||||||
@@ -106,7 +112,7 @@ const lineAPrice = computed({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const lineA = new HLine(
|
const lineA = new HLine(
|
||||||
{price:null,color:null},
|
{price:null,color:defaultColor},
|
||||||
function (line) {props.builder.priceA = line.price; props.builder.color = line.color; adjustShapes()},
|
function (line) {props.builder.priceA = line.price; props.builder.color = line.color; adjustShapes()},
|
||||||
deleteBuilder
|
deleteBuilder
|
||||||
)
|
)
|
||||||
@@ -120,7 +126,7 @@ const lineBPrice = computed({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const lineB = new HLine(
|
const lineB = new HLine(
|
||||||
{price:null,color:null},
|
{price:null,color:props.builder.color.value},
|
||||||
(line)=>{props.builder.priceB = line.price; props.builder.color = line.color; adjustShapes()},
|
(line)=>{props.builder.priceB = line.price; props.builder.color = line.color; adjustShapes()},
|
||||||
deleteBuilder
|
deleteBuilder
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-sheet dense class="d-flex align-content-stretch" style="overflow-y: hidden; background-color: inherit !important;">
|
<row-bar :color="builder.color">
|
||||||
<div class="bg-grey-lighten-1" style="width:1em"> </div>
|
<div class="bg-grey-lighten-1" style="width:1em"> </div>
|
||||||
<div style="min-width: 3em; font-size: larger" class="align-self-start ma-3">Market Order</div>
|
<div style="min-width: 3em; font-size: larger" class="align-self-start ma-3">Market Order</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<template v-slot:append-inner>%</template>
|
<template v-slot:append-inner>%</template>
|
||||||
</v-text-field>
|
</v-text-field>
|
||||||
</div>
|
</div>
|
||||||
</v-sheet>
|
</row-bar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -20,6 +20,7 @@ import {useChartOrderStore} from "@/orderbuild.js";
|
|||||||
import {builderDefaults} from "@/misc.js";
|
import {builderDefaults} from "@/misc.js";
|
||||||
import {useOrderStore} from "@/store/store.js";
|
import {useOrderStore} from "@/store/store.js";
|
||||||
import {computed} from "vue";
|
import {computed} from "vue";
|
||||||
|
import RowBar from "@/components/chart/RowBar.vue";
|
||||||
|
|
||||||
const co = useChartOrderStore()
|
const co = useChartOrderStore()
|
||||||
const props = defineProps(['order', 'builder'])
|
const props = defineProps(['order', 'builder'])
|
||||||
|
|||||||
@@ -12,9 +12,8 @@ import {computed} from "vue";
|
|||||||
import {lightenColor2} from "@/misc.js";
|
import {lightenColor2} from "@/misc.js";
|
||||||
|
|
||||||
const props = defineProps(['color'])
|
const props = defineProps(['color'])
|
||||||
const faintColor = computed(() => lightenColor2(props.color))
|
const faintColor = computed(() => lightenColor2(props.color,.70))
|
||||||
const computedStyle = computed(() => {
|
const computedStyle = computed(() => {
|
||||||
console.log('computing bar color')
|
|
||||||
return {
|
return {
|
||||||
'background-color': props.color,
|
'background-color': props.color,
|
||||||
'border-color': props.color,
|
'border-color': props.color,
|
||||||
|
|||||||
@@ -1,28 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="d-flex mb-1">
|
<div class="d-flex mb-1">
|
||||||
<span class="arrow align-self-start"><v-icon icon="mdi-arrow-up-bold" color="green"/></span>
|
<span class="arrow align-self-start"><v-icon icon="mdi-arrow-up-bold" :color="theme.colors.success"/></span>
|
||||||
<span class="logo">dexorder</span>
|
<span class="logo">dexorder</span>
|
||||||
<v-chip text="ALPHA" size='x-small' color="red" class="align-self-start pr-6" variant="text"/>
|
<v-chip text="ALPHA" size='x-small' color="red" class="align-self-start pr-6" variant="text"/>
|
||||||
<v-btn variant="flat" prepend-icon="mdi-plus" @click="co.newOrder" v-if="co.orders.length===0">New Order</v-btn>
|
<slot/>
|
||||||
<!-- <v-btn variant="flat" prepend-icon="mdi-question" @click="build('Test')">Test</v-btn>-->
|
|
||||||
<v-btn variant="tonal" prepend-icon="mdi-send" :color="orderColor" v-if="co.orders.length>0">Place Order</v-btn>
|
|
||||||
<v-btn variant="text" prepend-icon="mdi-cancel" v-if="co.orders.length>0" @click="cancelOrder">Cancel</v-btn>
|
|
||||||
|
|
||||||
<div class="w-100 d-flex justify-end">
|
<div class="w-100 d-flex justify-end">
|
||||||
<v-btn variant="text" icon="mdi-safe-square" color="grey-darken-2" text="Vault" @click="$router.push('/vault')"></v-btn>
|
<v-btn variant="text" icon="mdi-safe-square" color="grey-darken-2" text="Vault" @click="$router.push('/vault')"></v-btn>
|
||||||
<v-btn variant="text" icon="mdi-information-outline" text="Order Status" @click="$router.push('/orders')"></v-btn>
|
<v-btn variant="text" icon="mdi-information-outline" text="Order Status" @click="$router.push('/orders')"></v-btn>
|
||||||
</div>
|
</div>
|
||||||
<v-dialog v-model="showCancel" max-width="300">
|
|
||||||
<v-card title="Cancel Order?" text="Do you want to cancel this order and create a new one?">
|
|
||||||
<v-card-actions>
|
|
||||||
<v-spacer/>
|
|
||||||
<v-btn @click="()=>showCancel=false">Keep Existing</v-btn>
|
|
||||||
<v-btn @click="()=>{co.orders.shift(); showCancel=false}" color="red">Cancel Order</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -40,7 +26,6 @@ const co = useChartOrderStore()
|
|||||||
const showCancel = ref(false)
|
const showCancel = ref(false)
|
||||||
|
|
||||||
const theme = useTheme().current
|
const theme = useTheme().current
|
||||||
const orderColor = computed(()=>co.orders.length===0?null : co.orders[0].buy ? theme.value.colors.success:theme.value.colors.error)
|
|
||||||
|
|
||||||
function cancelOrder() {
|
function cancelOrder() {
|
||||||
showCancel.value = true
|
showCancel.value = true
|
||||||
|
|||||||
93
src/misc.js
93
src/misc.js
@@ -4,7 +4,7 @@ import {token} from "@/blockchain/token.js";
|
|||||||
import Color from "color";
|
import Color from "color";
|
||||||
|
|
||||||
export class SingletonCoroutine {
|
export class SingletonCoroutine {
|
||||||
constructor(f, delay=10, retry=true) {
|
constructor(f, delay = 10) {
|
||||||
this.f = f
|
this.f = f
|
||||||
this.delay = delay
|
this.delay = delay
|
||||||
this.timeout = null
|
this.timeout = null
|
||||||
@@ -18,24 +18,22 @@ export class SingletonCoroutine {
|
|||||||
invoke(/*arguments*/) {
|
invoke(/*arguments*/) {
|
||||||
this.args = arguments
|
this.args = arguments
|
||||||
// console.log('invoke', arguments)
|
// console.log('invoke', arguments)
|
||||||
if( this.timeout === null )
|
if (this.timeout === null)
|
||||||
|
// noinspection JSCheckFunctionSignatures
|
||||||
this.timeout = setTimeout(this.onTimeout, this.delay, this)
|
this.timeout = setTimeout(this.onTimeout, this.delay, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
async onTimeout(self) {
|
async onTimeout(self) {
|
||||||
try {
|
try {
|
||||||
await self.f(...self.args)
|
await self.f(...self.args)
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
if (self.retry) {
|
||||||
if( self.retry ) {
|
|
||||||
console.log('retrying', this.f, 'due to error', e)
|
console.log('retrying', this.f, 'due to error', e)
|
||||||
self.timeout = null
|
self.timeout = null
|
||||||
self.invoke(self.args)
|
self.invoke(self.args)
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
self.timeout = null
|
self.timeout = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,11 +50,11 @@ export const uint32max = 4294967295n
|
|||||||
export const uint64max = 18446744073709551615n
|
export const uint64max = 18446744073709551615n
|
||||||
|
|
||||||
export function tokenNumber(token, balance) {
|
export function tokenNumber(token, balance) {
|
||||||
return FixedNumber.fromValue(balance, token.decimals, {decimals:token.decimals, width: 256})
|
return FixedNumber.fromValue(balance, token.decimals, {decimals: token.decimals, width: 256})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tokenFloat(token, balance) {
|
export function tokenFloat(token, balance) {
|
||||||
return tokenNumber(token,balance).toUnsafeFloat()
|
return tokenNumber(token, balance).toUnsafeFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function routeInverted(route) {
|
export function routeInverted(route) {
|
||||||
@@ -65,27 +63,28 @@ export function routeInverted(route) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function intervalString(seconds) {
|
export function intervalString(seconds) {
|
||||||
if( seconds < 1 )
|
if (seconds < 1)
|
||||||
return 'now'
|
return 'now'
|
||||||
else if( seconds < 60 )
|
else if (seconds < 60)
|
||||||
return `${seconds} seconds`
|
return `${seconds} seconds`
|
||||||
else if( seconds < 3600 )
|
else if (seconds < 3600)
|
||||||
return `${(seconds/60).toFixed(1)} minutes`
|
return `${(seconds / 60).toFixed(1)} minutes`
|
||||||
else if( seconds < 86400 )
|
else if (seconds < 86400)
|
||||||
return `${(seconds/3600).toFixed(1)} hours`
|
return `${(seconds / 3600).toFixed(1)} hours`
|
||||||
else
|
else
|
||||||
return `${(seconds/86400).toFixed(1)} days`
|
return `${(seconds / 86400).toFixed(1)} days`
|
||||||
}
|
}
|
||||||
|
|
||||||
const _dateFormat = new Intl.DateTimeFormat( undefined, {dateStyle: 'medium', timeStyle: 'short'})
|
const _dateFormat = new Intl.DateTimeFormat(undefined, {dateStyle: 'medium', timeStyle: 'short'})
|
||||||
|
|
||||||
export function dateString(seconds) {
|
export function dateString(seconds) {
|
||||||
const date = new Date(seconds*1000)
|
const date = new Date(seconds * 1000)
|
||||||
return _dateFormat.format(date)
|
return _dateFormat.format(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function timestamp(date=null) {
|
export function timestamp(date = null) {
|
||||||
if(date===null)
|
if (date === null)
|
||||||
date = new Date()
|
date = new Date()
|
||||||
return Math.round(date.getTime() / 1000)
|
return Math.round(date.getTime() / 1000)
|
||||||
}
|
}
|
||||||
@@ -101,30 +100,30 @@ export function pairKey(tokenA, tokenB) {
|
|||||||
export function pairPriceAddr(baseTokenAddr, quoteTokenAddr, price) {
|
export function pairPriceAddr(baseTokenAddr, quoteTokenAddr, price) {
|
||||||
const baseToken = token(baseTokenAddr)
|
const baseToken = token(baseTokenAddr)
|
||||||
const quoteToken = token(quoteTokenAddr)
|
const quoteToken = token(quoteTokenAddr)
|
||||||
if( !baseToken || !quoteToken )
|
if (!baseToken || !quoteToken)
|
||||||
return null
|
return null
|
||||||
return pairPrice(baseToken, quoteToken, price)
|
return pairPrice(baseToken, quoteToken, price)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function pairPrice(baseToken, quoteToken, price, decimals=null) {
|
export function pairPrice(baseToken, quoteToken, price, decimals = null) {
|
||||||
if( price === null || price === undefined )
|
if (price === null || price === undefined)
|
||||||
return price
|
return price
|
||||||
if( decimals === null )
|
if (decimals === null)
|
||||||
decimals = baseToken.decimals-quoteToken.decimals
|
decimals = baseToken.decimals - quoteToken.decimals
|
||||||
console.log('pairPrice', baseToken, quoteToken, price, decimals)
|
console.log('pairPrice', baseToken, quoteToken, price, decimals)
|
||||||
if( decimals >= 0 )
|
if (decimals >= 0)
|
||||||
price /= 10 ** decimals
|
price /= 10 ** decimals
|
||||||
else
|
else
|
||||||
price *= 10 ** -decimals
|
price *= 10 ** -decimals
|
||||||
const invertedKey = pairKey(baseToken, quoteToken);
|
const invertedKey = pairKey(baseToken, quoteToken);
|
||||||
const prefs = usePrefStore()
|
const prefs = usePrefStore()
|
||||||
if( !(invertedKey in prefs.inverted) ) {
|
if (!(invertedKey in prefs.inverted)) {
|
||||||
// todo prefer stablecoins as the quote asset
|
// todo prefer stablecoins as the quote asset
|
||||||
prefs.inverted[invertedKey] = false
|
prefs.inverted[invertedKey] = false
|
||||||
}
|
}
|
||||||
if( prefs.inverted[invertedKey] )
|
if (prefs.inverted[invertedKey])
|
||||||
price = 1/price
|
price = 1 / price
|
||||||
return price
|
return price
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,10 +144,34 @@ export function uuid() {
|
|||||||
return crypto.randomUUID();
|
return crypto.randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function lightenColor(color, lightness=85) {
|
export function lightenColor(color, lightness = 85, alpha = null) {
|
||||||
return new Color(color).hsl().lightness(lightness).string()
|
let c = new Color(color).hsl().lightness(lightness)
|
||||||
|
if (alpha !== null)
|
||||||
|
c = c.rgb().alpha(alpha)
|
||||||
|
return c.string()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function lightenColor2(color) {
|
export function lightenColor2(color, alpha = null) {
|
||||||
return lightenColor(color,98)
|
return lightenColor(color, 98, alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const colorRanges = {
|
||||||
|
buy: ['#00CC33', '#3300CC'],
|
||||||
|
sell: ['#CC0033', '#CCCC33'],
|
||||||
|
}
|
||||||
|
|
||||||
|
export function lineColor(buy, index) {
|
||||||
|
const range = buy ? colorRanges.buy : colorRanges.sell
|
||||||
|
const a = new Color(range[0]).rgb()
|
||||||
|
const b = new Color(range[1]).rgb()
|
||||||
|
// const z2 = Math.PI * Math.PI / 6 - 1 // ζ(2) modulo 1
|
||||||
|
const z2 = 1 - 1/Math.E // ζ(2) modulo 1
|
||||||
|
const kk = index * z2;
|
||||||
|
const k = kk - Math.trunc(kk)
|
||||||
|
const mix = (x, y) => (1 - k) * x + k * y
|
||||||
|
const c = new Color([mix(a.red(), b.red()), mix(a.green(), b.green()), mix(a.blue(), b.blue())])
|
||||||
|
// console.log('default color', c.string())
|
||||||
|
return c.string()
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user