one-time hints; builder touchups
This commit is contained in:
@@ -8,6 +8,7 @@ import {tvCustomThemes} from "../../theme.js";
|
||||
export let widget = null
|
||||
export let chart = null
|
||||
export let crosshairPoint = null
|
||||
export let defaultShapeHandler = null // if set, then TV events that dont have a registered shape handler get passed directly to this function
|
||||
let symbolChangedCbs = [] // callbacks for TV's chart.onSymbolChanged()
|
||||
|
||||
|
||||
@@ -268,6 +269,7 @@ export function drawShape(shapeType, ...callbacks) {
|
||||
drawingTool = null
|
||||
previousDrawingTool = widget.selectedLineTool()
|
||||
co.drawing = true
|
||||
co.drew = false
|
||||
widget.selectLineTool(shapeType.code)
|
||||
invokeCallbacks(callbacks, 'onDraw')
|
||||
}
|
||||
@@ -462,9 +464,11 @@ function doHandleDrawingEvent(id, event) {
|
||||
const props = shape.getProperties()
|
||||
if (id in shapeCallbacks)
|
||||
invokeCallbacks(shapeCallbacks[id], 'onProps', id, shape, props)
|
||||
else
|
||||
// otherwise it's an event on a shape we don't "own"
|
||||
else {
|
||||
// otherwise it's an event on a shape we don't "own" that could be being drawn
|
||||
co.drew = true
|
||||
console.log('warning: ignoring setProperties on TV shape', id, props)
|
||||
}
|
||||
} else if (event === 'move') {
|
||||
if (id in shapeCallbacks) {
|
||||
invokeCallbacks(shapeCallbacks[id], 'onMove', id, shape)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-tooltip v-model="show" :close-on-content-click="true"/>
|
||||
<v-tooltip v-model="show" :close-on-content-click="true" :close-on-back="false" :close-delay="null"/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -8,25 +8,26 @@ import {usePrefStore} from "@/store/store.js";
|
||||
|
||||
const prefs = usePrefStore()
|
||||
|
||||
const modelValue = defineModel()
|
||||
const hasBeenShown = ref(false)
|
||||
|
||||
const props = defineProps({
|
||||
key: {type: String, required: true},
|
||||
after: {type: String, default: null},
|
||||
name: {type: String, required: true},
|
||||
when: {type: Boolean, default: true}, // optional conditional for when to show
|
||||
after: {type: String, default: null}, // set to the name of another hint that must happen before this hint, to chain hints into a tutorial.
|
||||
})
|
||||
|
||||
const forceClose = ref(false)
|
||||
|
||||
const show = computed({
|
||||
get() {
|
||||
const result = !prefs.hints[props.key] && modelValue.value && (props.after === null || prefs.hints[props.after])
|
||||
&& !props.finished
|
||||
const shownBefore = prefs.hints[props.name];
|
||||
const whenOk = props.when;
|
||||
const afterOk = props.after === null || prefs.hints[props.after];
|
||||
const result = !forceClose.value && !shownBefore && whenOk && afterOk
|
||||
// console.log(`show ${props.name}? ${result} <=`, !forceClose.value, whenOk, afterOk, prefs.hints)
|
||||
if (result)
|
||||
hasBeenShown.value = true
|
||||
else if (hasBeenShown.value)
|
||||
prefs.hints[props.key] = true
|
||||
prefs.hints[props.name] = true
|
||||
return result
|
||||
},
|
||||
set(v) { if(!v) prefs.hints[props.key] = true}
|
||||
set(v) { if(!v) forceClose.value=true; }
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<template>
|
||||
<div ref="element" class="chart"/>
|
||||
<div id="tv-widget" ref="element" class="chart"/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// import "/public/datafeeds/udf/dist/bundle.js"
|
||||
import {onMounted, ref} from "vue";
|
||||
import {initWidget} from "@/charts/chart.js";
|
||||
|
||||
@@ -12,18 +11,8 @@ const element = ref()
|
||||
onMounted(() => {
|
||||
const el = element.value;
|
||||
initWidget(el)
|
||||
initShapes()
|
||||
})
|
||||
|
||||
function initShapes() {
|
||||
// const c = widget.chart()
|
||||
// for( const s of ss.shapes ) {
|
||||
// const type = s.type.toLowerCase().replace(' ','_')
|
||||
// console.log('create type', type)
|
||||
// c.createMultipointShape(s.points, {shape:type})
|
||||
// }
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -11,28 +11,28 @@
|
||||
<v-tooltip text="Up to 1000 equal parts spread across time" location="top">
|
||||
<template v-slot:activator="{ props }">
|
||||
<span v-bind="props">
|
||||
<v-btn :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-clock-outline" @click="build(order,'DCABuilder')">DCA</v-btn>
|
||||
<v-btn id="DCA-button" :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-clock-outline" @click="build(order,'DCABuilder')">DCA</v-btn>
|
||||
</span>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip text="Trade a price level" location="top">
|
||||
<template v-slot:activator="{ props }">
|
||||
<span v-bind="props">
|
||||
<v-btn :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
|
||||
<v-btn id="LimitBuilder-button" :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
|
||||
</span>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip text="Trade trends and channels" location="top">
|
||||
<template v-slot:activator="{ props }">
|
||||
<span v-bind="props">
|
||||
<v-btn :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-vector-line" @click="build(order,'DiagonalBuilder')">Diagonal</v-btn>
|
||||
<v-btn id="Diagonal-button" :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-vector-line" @click="build(order,'DiagonalBuilder')">Diagonal</v-btn>
|
||||
</span>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<v-tooltip text="Up to 10 weighted parts spaced out in time" location="top">
|
||||
<template v-slot:activator="{ props }">
|
||||
<span v-bind="props">
|
||||
<v-btn :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-reorder-vertical" @click="build(order,'DateBuilder')">Dates</v-btn>
|
||||
<v-btn id="Dates-button" :class="order.buy?'green':'red'" variant="text" prepend-icon="mdi-reorder-vertical" @click="build(order,'DateBuilder')">Dates</v-btn>
|
||||
</span>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
@@ -44,6 +44,13 @@
|
||||
</template>
|
||||
</v-tooltip>
|
||||
<!-- mdi-ray-start-end mdi-vector-polyline -->
|
||||
|
||||
<!-- after="newbie"-->
|
||||
<span>{{builders.length}}</span>
|
||||
<one-time-hint name="choose-builder" :activator="hintData.activator"
|
||||
:text="hintData.text" location="top"
|
||||
:when="!builtAny"/>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +62,7 @@
|
||||
import BuilderFactory from "@/components/chart/BuilderFactory.vue";
|
||||
import {builderFuncs, newBuilder, orderFuncs, useChartOrderStore} from "@/orderbuild.js";
|
||||
import {useStore} from "@/store/store.js";
|
||||
import {computed, onUnmounted, onUpdated, watchEffect} from "vue";
|
||||
import {computed, onUnmounted, onUpdated, ref, watchEffect} from "vue";
|
||||
import {toPrecision} from "@/misc.js";
|
||||
import {useTheme} from "vuetify";
|
||||
import RowBar from "@/components/chart/RowBar.vue";
|
||||
@@ -63,6 +70,7 @@ import Color from "color";
|
||||
import {newOrder} from "@/blockchain/orderlib.js";
|
||||
import OrderAmount from "@/components/chart/OrderAmount.vue";
|
||||
import {track} from "@/track.js";
|
||||
import OneTimeHint from "@/components/OneTimeHint.vue";
|
||||
|
||||
const props = defineProps(['order'])
|
||||
const s = useStore()
|
||||
@@ -75,9 +83,12 @@ const tokenIn = computed(()=>props.order.buy ? co.quoteToken : co.baseToken)
|
||||
const tokenOut = computed(()=>props.order.buy ? co.baseToken : co.quoteToken)
|
||||
|
||||
|
||||
const builtAny = ref(false)
|
||||
|
||||
console.log('order', props.order)
|
||||
function build(order, component, options={}) {
|
||||
track('build', {builder:component})
|
||||
builtAny.value = true
|
||||
order.builders.push(newBuilder(component, options))
|
||||
}
|
||||
|
||||
@@ -187,6 +198,19 @@ const color = computed(()=>theme.value.colors["on-background"])
|
||||
// const lightColorStyle = computed(() => { return {'background-color': lightColor.value} })
|
||||
// const faintColorStyle = computed(() => { return {'background-color': faintColor.value} })
|
||||
|
||||
// Tutorial Hint
|
||||
|
||||
let tutorial = 'limit'
|
||||
|
||||
const _hintData = {
|
||||
'limit': {
|
||||
activator: '#LimitBuilder-button',
|
||||
text: '↓ Try a Limit Ladder ↓'
|
||||
},
|
||||
}
|
||||
|
||||
const hintData = computed(()=>_hintData[tutorial] || _hintData['limit'])
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<one-time-hint name="click-chart" activator="#tv-widget" location="center" :when="builder.lineA===null && !co.drew" text="Click the chart!"/>
|
||||
</rung-builder>
|
||||
</template>
|
||||
|
||||
@@ -102,6 +103,7 @@ import {allocationText, DLine} from "@/charts/shape.js";
|
||||
import {vectorEquals, vectorInterpolate} from "@/vector.js";
|
||||
import AbsoluteTimeEntry from "@/components/AbsoluteTimeEntry.vue";
|
||||
import {useStore} from "@/store/store.js";
|
||||
import OneTimeHint from "@/components/OneTimeHint.vue";
|
||||
|
||||
const s = useStore()
|
||||
const co = useChartOrderStore()
|
||||
|
||||
@@ -33,10 +33,11 @@
|
||||
style="flex: 6em"
|
||||
/>
|
||||
</td>
|
||||
<td class="weight">{{ weights.length ? allocationTexts[lowerIndex] : '' }}</td>
|
||||
<td class="weight">{{ weights.length > 1 ? allocationTexts[lowerIndex] : '' }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<one-time-hint name="click-chart" activator="#tv-widget" location="center" :when="priceA===null" text="Click the chart!"/>
|
||||
</rung-builder>
|
||||
</template>
|
||||
|
||||
@@ -48,6 +49,7 @@ import {MAX_FRACTION, newTranche} from "@/blockchain/orderlib.js";
|
||||
import RungBuilder from "@/components/chart/RungBuilder.vue";
|
||||
import {computed, ref} from "vue";
|
||||
import {allocationText, HLine} from "@/charts/shape.js";
|
||||
import OneTimeHint from "@/components/OneTimeHint.vue";
|
||||
|
||||
const s = useStore()
|
||||
const os = useOrderStore()
|
||||
|
||||
@@ -17,15 +17,27 @@
|
||||
min="1" :max="MAX_RUNGS"
|
||||
:disabled="rungsDisabled"
|
||||
style="width: 6.6em; max-height: 2.5em; height: 2.5em"
|
||||
id="rungs"
|
||||
/>
|
||||
<one-time-hint name="rungs" activator="#rungs" after="choose-builder"
|
||||
text="↓ Try increasing rungs!" location="top"
|
||||
:when="rungs===1&&endpoints[0]!==null"/>
|
||||
<v-tooltip v-if="builder.breakout!==undefined"
|
||||
:text="order.buy?'Breakout orders buy above the breakout line':'Breakdown orders sell below the breakdown line'">
|
||||
<template #activator="{ props }">
|
||||
<div v-bind="props">
|
||||
<v-switch v-model="breakout" :label="order.buy?'Breakout':'Breakdown'"
|
||||
persistent-hint :color="switchColor" :base-color="switchColor" hide-details direction="vertical"
|
||||
density="compact"
|
||||
/>
|
||||
<div class="mx-auto"><span style="font-size: .7em; vertical-align: top"
|
||||
density="compact"/>
|
||||
<div class="mx-auto">
|
||||
<span style="font-size: .7em; vertical-align: top"
|
||||
:style="builder.breakout?{color:new Color(color).lighten(0.5).string()}:null">
|
||||
{{description}}
|
||||
</span></div>
|
||||
{{ description }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</div>
|
||||
|
||||
<slot/>
|
||||
@@ -36,8 +48,13 @@
|
||||
</div>
|
||||
<div v-if="rungs>1" class="mx-2 d-flex justify-start">
|
||||
<div class="d-flex align-center mt-2">
|
||||
<div id="balance-slider">
|
||||
<v-slider v-if="rungs>1" :direction="orientation?'vertical':'horizontal'" min="-100" max="100" v-model="balance100"
|
||||
class="no-slider-bg ml-2 mr-4" hide-details/>
|
||||
</div>
|
||||
<one-time-hint name="balance-slider" activator="#balance-slider" after="rungs"
|
||||
text="↓ Slide the amount balance ↓" location="top"
|
||||
:when="balance100===0"/>
|
||||
<v-text-field type="number" v-model="balance100" min="-100" max="100"
|
||||
density="compact" hide-details variant="outlined" label="Balance" step="5"
|
||||
class="balance">
|
||||
@@ -70,6 +87,7 @@ import {
|
||||
vectorSub
|
||||
} from "@/vector.js";
|
||||
import {logicalXOR} from "@/common.js";
|
||||
import OneTimeHint from "@/components/OneTimeHint.vue";
|
||||
|
||||
const co = useChartOrderStore()
|
||||
const endpoints = defineModel('modelValue') // 2-item list of points/values
|
||||
|
||||
@@ -68,6 +68,7 @@ export const useChartOrderStore = defineStore('chart_orders', () => {
|
||||
const meanRange = ref(1)
|
||||
|
||||
const drawing = ref(false)
|
||||
const drew = ref(true) // true if at least one of the points has been drawn already
|
||||
|
||||
function newOrder() {
|
||||
const order = newDefaultOrder()
|
||||
@@ -97,7 +98,7 @@ export const useChartOrderStore = defineStore('chart_orders', () => {
|
||||
|
||||
return {
|
||||
chartReady, selectedSymbol, intervalSecs, baseToken, quoteToken, price,
|
||||
orders, drawing, newOrder, removeOrder, resetOrders, meanRange,
|
||||
orders, drawing, drew, newOrder, removeOrder, resetOrders, meanRange,
|
||||
showPoolSelection,
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user