2023-09-15 16:55:03 +00:00
|
|
|
<template>
|
|
|
|
|
{{ string_repr }}
|
|
|
|
|
</template>
|
|
|
|
|
|
2025-12-05 02:12:33 +00:00
|
|
|
<script setup lang="ts">
|
2023-09-15 23:20:15 +00:00
|
|
|
import { Duration } from "luxon";
|
2025-12-05 02:12:33 +00:00
|
|
|
import { onBeforeUnmount, onMounted } from "vue";
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
until: number;
|
|
|
|
|
tick_time: number;
|
|
|
|
|
}>(),
|
|
|
|
|
{ tick_time: 200 },
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let interval_id: number | null = null;
|
|
|
|
|
let string_repr = "";
|
|
|
|
|
|
|
|
|
|
function tick(): void {
|
|
|
|
|
const distance_ms = props.until - Date.now();
|
2023-09-15 16:55:03 +00:00
|
|
|
|
2025-12-05 02:12:33 +00:00
|
|
|
if (distance_ms <= 0) {
|
|
|
|
|
string_repr = "Jetzt!";
|
|
|
|
|
return;
|
2023-09-15 16:55:03 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-05 02:12:33 +00:00
|
|
|
const distance = Duration.fromMillis(distance_ms);
|
|
|
|
|
const d_days = distance.shiftTo("day").mapUnits(Math.floor);
|
|
|
|
|
const d_hms = distance.minus(d_days).shiftTo("hour", "minute", "second");
|
|
|
|
|
|
|
|
|
|
if (d_days.days > 0) {
|
|
|
|
|
string_repr = d_days.toHuman() + " ";
|
|
|
|
|
} else {
|
|
|
|
|
string_repr = "";
|
2023-09-15 16:55:03 +00:00
|
|
|
}
|
2025-12-05 02:12:33 +00:00
|
|
|
string_repr += d_hms.toFormat("hh:mm:ss");
|
2023-09-15 16:55:03 +00:00
|
|
|
}
|
2025-12-05 02:12:33 +00:00
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
tick();
|
|
|
|
|
interval_id = window.setInterval(tick, props.tick_time);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
if (interval_id === null) return;
|
|
|
|
|
window.clearInterval(interval_id);
|
|
|
|
|
});
|
2023-09-15 16:55:03 +00:00
|
|
|
</script>
|