Fix oh-slider issue Signed-off-by: Hubert Nusser <hubsif@gmx.de>pull/1052/head
parent
f590b28331
commit
d586b77594
|
@ -116,6 +116,16 @@ Display a knob in a card to visualize and control a quantifiable item
|
|||
Size the control using percentages instead of pixels
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
</PropGroup>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -125,6 +125,16 @@ A cell expanding to a knob control
|
|||
Size the control using percentages instead of pixels
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
</PropGroup>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -83,6 +83,16 @@ Knob control, allow to change a number value on a circular track
|
|||
Size the control using percentages instead of pixels
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="variable" label="Variable">
|
||||
<PropDescription>
|
||||
Name of the variable to set on input change
|
||||
|
|
|
@ -110,6 +110,16 @@ Display a slider in a card to control an item
|
|||
Text to append to the label while dragging the cursor
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
</PropGroup>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -120,6 +120,16 @@ A cell expanding to a big vertical slider
|
|||
Text to append to the label while dragging the cursor
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
</PropGroup>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -115,6 +115,16 @@ Display a slider control in a list
|
|||
Text to append to the label while dragging the cursor
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
</PropGroup>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -78,6 +78,16 @@ Slider control, allows to pick a number value on a scale
|
|||
Text to append to the label while dragging the cursor
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="updateInterval" label="Update Interval">
|
||||
<PropDescription>
|
||||
Time to wait between subsequent commands in ms (default 500)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="INTEGER" name="delayStateDisplay" label="Delay State Display">
|
||||
<PropDescription>
|
||||
Time to wait before switching from displaying user input to displaying item state in ms (default 2000)
|
||||
</PropDescription>
|
||||
</PropBlock>
|
||||
<PropBlock type="TEXT" name="variable" label="Variable">
|
||||
<PropDescription>
|
||||
Name of the variable to set on input change
|
||||
|
|
|
@ -11,5 +11,7 @@ export default () => [
|
|||
pt('secondaryColor', 'Secondary Color', 'Color of the rest of the control (HTML value, default #dcdfe6)'),
|
||||
pt('textColor', 'Text Color', 'Color of the value text (HTML value, default #000000)'),
|
||||
pt('strokeWidth', 'Stroke Width', 'Thickness of the arcs, default 17'),
|
||||
pb('responsive', 'Responsive', 'Size the control using percentages instead of pixels')
|
||||
pb('responsive', 'Responsive', 'Size the control using percentages instead of pixels'),
|
||||
pn('updateInterval', 'Update Interval', 'Time to wait between subsequent commands in ms (default 500)').a(),
|
||||
pn('delayStateDisplay', 'Delay State Display', 'Time to wait before switching from displaying user input to displaying item state in ms (default 2000)').a()
|
||||
]
|
||||
|
|
|
@ -10,5 +10,7 @@ export default () => [
|
|||
pb('scale', 'Display Scale', 'Display a scale on the slider'),
|
||||
pn('scaleSteps', 'Scale steps', 'Number of (major) scale markers'),
|
||||
pn('scaleSubSteps', 'Scale sub-steps', 'Number of scale minor markers between each major marker'),
|
||||
pt('unit', 'Unit', 'Text to append to the label while dragging the cursor')
|
||||
pt('unit', 'Unit', 'Text to append to the label while dragging the cursor'),
|
||||
pn('updateInterval', 'Update Interval', 'Time to wait between subsequent commands in ms (default 500)').a(),
|
||||
pn('delayStateDisplay', 'Delay State Display', 'Time to wait before switching from displaying user input to displaying item state in ms (default 2000)').a()
|
||||
]
|
||||
|
|
|
@ -1,69 +1,20 @@
|
|||
<template>
|
||||
<knob-control v-bind="config" :text-color="config.textColor || ($f7.data.themeOptions.dark === 'dark') ? '#ffffff' : undefined" :value="value" @input="onChange" />
|
||||
<knob-control v-bind="config" :text-color="config.textColor || ($f7.data.themeOptions.dark === 'dark') ? '#ffffff' : undefined" :value="value"
|
||||
@input="sendCommandDebounced($event)" @click.native="sendCommandDebounced(value, true)" @touchend.native="sendCommandDebounced(value, true)" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../widget-mixin'
|
||||
import slideMixin from './slide-mixin'
|
||||
import { OhKnobDefinition } from '@/assets/definitions/widgets/system'
|
||||
|
||||
import KnobControl from 'vue-knob-control'
|
||||
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
mixins: [mixin, slideMixin],
|
||||
components: {
|
||||
KnobControl
|
||||
},
|
||||
widget: OhKnobDefinition,
|
||||
data () {
|
||||
return {
|
||||
pendingCommand: null,
|
||||
delayCommand: false,
|
||||
delayUpdate: null
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
delete this.config.value
|
||||
},
|
||||
computed: {
|
||||
value () {
|
||||
if (this.config.variable) return this.context.vars[this.config.variable]
|
||||
if (this.delayUpdate && this.pendingCommand) return this.pendingCommand // to keep the control reactive when operating
|
||||
const value = this.context.store[this.config.item].state
|
||||
// use as a brightness control for HSB values
|
||||
if (value.split && value.split(',').length === 3) return parseFloat(value.split(',')[2])
|
||||
return parseFloat(value)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange (value) {
|
||||
if (value === this.value) return
|
||||
if (this.config.variable) {
|
||||
this.$set(this.context.vars, this.config.variable, value)
|
||||
return
|
||||
}
|
||||
this.pendingCommand = value
|
||||
if (!this.delayCommand) {
|
||||
this.delayCommand = true
|
||||
this.setUpdateDelayTimout()
|
||||
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: value.toString() })
|
||||
setTimeout(() => {
|
||||
this.delayCommand = false
|
||||
if (this.delayUpdate) clearTimeout(this.delayUpdate)
|
||||
if (this.pendingCommand) {
|
||||
this.setUpdateDelayTimout()
|
||||
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: this.pendingCommand.toString() })
|
||||
}
|
||||
}, 200)
|
||||
}
|
||||
},
|
||||
setUpdateDelayTimout () {
|
||||
if (this.delayUpdate) clearTimeout(this.delayUpdate)
|
||||
this.delayUpdate = setTimeout(() => {
|
||||
console.debug('End of update delay')
|
||||
this.delayUpdate = null
|
||||
this.pendingCommand = null
|
||||
}, 2000)
|
||||
}
|
||||
}
|
||||
widget: OhKnobDefinition
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<f7-range ref="rangeslider" class="oh-slider" v-bind="config" :value="value" @range:changed="onChange" :format-label="formatLabel" :format-scale-label="formatScaleLabel" />
|
||||
<f7-range ref="rangeslider" class="oh-slider" v-bind="config" :value="value" :format-label="formatLabel" :format-scale-label="formatScaleLabel"
|
||||
@range:change="sendCommandDebounced($event)" @click.native="sendCommandDebounced(value, true)" @touchend.native="sendCommandDebounced(value, true)" />
|
||||
</template>
|
||||
|
||||
<style lang="stylus">
|
||||
|
@ -10,30 +11,22 @@
|
|||
|
||||
<script>
|
||||
import mixin from '../widget-mixin'
|
||||
import slideMixin from './slide-mixin'
|
||||
import { OhSliderDefinition } from '@/assets/definitions/widgets/system'
|
||||
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
mixins: [mixin, slideMixin],
|
||||
widget: OhSliderDefinition,
|
||||
mounted () {
|
||||
delete this.config.value
|
||||
|
||||
// f7-range inside of masonry can get rendered faulty, as the masonry changes its breakpoint layout after being rendered
|
||||
// re-calculate the range slider after masonry is updated
|
||||
setTimeout(() => {
|
||||
this.$refs.rangeslider.f7Range.calcSize()
|
||||
this.$refs.rangeslider.f7Range.layout()
|
||||
if (this.$refs.rangeslider) {
|
||||
this.$refs.rangeslider.f7Range.calcSize()
|
||||
this.$refs.rangeslider.f7Range.layout()
|
||||
}
|
||||
}, 0)
|
||||
},
|
||||
computed: {
|
||||
value () {
|
||||
if (this.config.variable) return this.context.vars[this.config.variable]
|
||||
const value = this.context.store[this.config.item].state
|
||||
// use as a brightness control for HSB values
|
||||
if (value.split && value.split(',').length === 3) return parseFloat(value.split(',')[2])
|
||||
return parseFloat(value)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatLabel (value) {
|
||||
return this.toStepFixed(value) + (this.config.unit || '')
|
||||
|
@ -45,15 +38,6 @@ export default {
|
|||
// uses the number of decimals in the step config to round the provided number
|
||||
const nbDecimals = this.config.step ? Number(this.config.step).toString().replace(',', '.').split('.')[1] : 0
|
||||
return parseFloat(Number(value).toFixed(nbDecimals))
|
||||
},
|
||||
onChange (value) {
|
||||
const newValue = this.toStepFixed(value)
|
||||
if (newValue === this.toStepFixed(this.value)) return
|
||||
if (this.config.variable) {
|
||||
this.$set(this.context.vars, this.config.variable, value)
|
||||
} else if (this.config.item) {
|
||||
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: newValue.toString() })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
export default {
|
||||
data () {
|
||||
return {
|
||||
pendingCommand: null
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
delete this.config.value
|
||||
|
||||
this.updateInterval = this.config.updateInterval ? this.config.updateInterval : 200
|
||||
this.delayStateDisplay = this.config.delayStateDisplay ? this.config.delayStateDisplay : 2000
|
||||
},
|
||||
computed: {
|
||||
value () {
|
||||
if (this.config.variable) return this.context.vars[this.config.variable]
|
||||
if (this.pendingCommand) return this.pendingCommand // to keep the control reactive when operating
|
||||
const value = this.context.store[this.config.item].state
|
||||
// use as a brightness control for HSB values
|
||||
if (value.split && value.split(',').length === 3) return parseFloat(value.split(',')[2])
|
||||
return parseFloat(value)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendCommandDebounced (value, stop = false) {
|
||||
if ((value === this.value && !stop) || value === this.lastValueSent) return
|
||||
|
||||
if (this.config.variable) {
|
||||
this.$set(this.context.vars, this.config.variable, value)
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.config.item) return
|
||||
|
||||
this.pendingCommand = value
|
||||
let diff = this.lastDateSent ? Date.now() - this.lastDateSent : this.updateInterval
|
||||
let delay = diff < this.updateInterval ? this.updateInterval - diff : stop ? 0 : this.updateInterval
|
||||
|
||||
if (this.sendCommandTimer && stop) {
|
||||
clearTimeout(this.sendCommandTimer)
|
||||
this.sendCommandTimer = null
|
||||
}
|
||||
if (!this.sendCommandTimer) {
|
||||
if (this.displayLockTimer) clearTimeout(this.displayLockTimer)
|
||||
this.sendCommandTimer = setTimeout(() => {
|
||||
this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: this.pendingCommand.toString() })
|
||||
this.lastValueSent = this.pendingCommand
|
||||
this.lastDateSent = Date.now()
|
||||
this.sendCommandTimer = null
|
||||
|
||||
// keep displaying `pendingCommand` as value for `delayStateDisplay` time to give sse state some time to update
|
||||
this.displayLockTimer = setTimeout(() => { this.pendingCommand = null }, this.delayStateDisplay)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue