mirror of
https://github.com/ckaczor/HomeMonitor.git
synced 2026-01-14 01:25:38 -05:00
Add long press button for actions
This commit is contained in:
79
WebDisplay/src/components/LongPressButton.vue
Normal file
79
WebDisplay/src/components/LongPressButton.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
const emit = defineEmits(['longPress']);
|
||||
const props = defineProps(['duration', 'increment', 'progressSize']);
|
||||
|
||||
const current = ref(0 as number);
|
||||
const loading = ref(false);
|
||||
|
||||
let interval: NodeJS.Timeout;
|
||||
|
||||
function mousedown() {
|
||||
loading.value = true;
|
||||
|
||||
increment();
|
||||
|
||||
interval = setInterval(increment, props.increment);
|
||||
}
|
||||
|
||||
function mouseup() {
|
||||
reset();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
clearInterval(interval);
|
||||
|
||||
loading.value = false;
|
||||
current.value = 0;
|
||||
}
|
||||
|
||||
function increment() {
|
||||
current.value = current.value + props.increment;
|
||||
|
||||
if (current.value >= props.duration) {
|
||||
emit('longPress');
|
||||
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
function progress() {
|
||||
if (current.value >= props.duration) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
return (current.value / props.duration) * 100;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:class="{ 'loading-button': loading }"
|
||||
@mousedown="mousedown"
|
||||
@mouseup="mouseup">
|
||||
<span v-show="!loading">
|
||||
<slot name="default"></slot>
|
||||
</span>
|
||||
|
||||
<v-progress-circular
|
||||
v-if="loading"
|
||||
:size="props.progressSize"
|
||||
:model-value="progress()"></v-progress-circular>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.loading-button {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.v-progress-circular__underlay {
|
||||
stroke: #ebebeb !important;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -18,8 +18,4 @@ export default class Environment {
|
||||
public static getAlarmDevice(): string {
|
||||
return '#ALARM_DEVICE#';
|
||||
}
|
||||
|
||||
public static getCalendarEmbedUrl(): string {
|
||||
return '#CALENDAR_EMBED_URL#';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { usePowerStore } from '@/stores/powerStore';
|
||||
import { useHomeAssistantStore } from '@/stores/homeAssistantStore';
|
||||
import CalendarAgenda from '@/components/CalendarAgenda.vue';
|
||||
import LongPressButton from '@/components/LongPressButton.vue';
|
||||
|
||||
const weatherStore = useWeatherStore();
|
||||
weatherStore.start();
|
||||
@@ -104,10 +105,13 @@
|
||||
{{ laundryStore.current.dryer ? 'On' : 'Off' }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
<LongPressButton
|
||||
class="kiosk-garage-door text-center pt-4"
|
||||
v-if="homeAssistantStore?.garageState"
|
||||
v-on:click="homeAssistantStore.toggleGarage()"
|
||||
:duration="2000"
|
||||
:increment="100"
|
||||
:progress-size="38"
|
||||
v-on:longPress="homeAssistantStore.toggleGarage()"
|
||||
:class="homeAssistantStore.garageState === 'closed' ? 'normal' : 'warning'">
|
||||
<v-icon
|
||||
class="kiosk-device-icon"
|
||||
@@ -115,7 +119,7 @@
|
||||
<div class="kiosk-device-text">
|
||||
{{ capitalize(homeAssistantStore.garageState) }}
|
||||
</div>
|
||||
</div>
|
||||
</LongPressButton>
|
||||
<div
|
||||
class="kiosk-house-alarm text-center pt-4"
|
||||
v-if="homeAssistantStore?.houseAlarmState"
|
||||
|
||||
Reference in New Issue
Block a user