advent22/ui/src/components/CountDown.vue

60 lines
1.3 KiB
Vue
Raw Normal View History

2023-09-15 16:55:03 +00:00
<template>
{{ string_repr }}
</template>
<script lang="ts">
2023-09-15 23:20:15 +00:00
import { Duration } from "luxon";
2023-09-15 16:55:03 +00:00
import { Options, Vue } from "vue-class-component";
@Options({
props: {
millis: Number,
tick_time: {
type: Number,
default: 200,
},
},
})
export default class extends Vue {
private millis!: number;
private tick_time!: number;
private interval_id: number | null = null;
public string_repr = "";
2023-09-15 23:20:15 +00:00
private get target_date_ms(): number {
2023-09-16 00:16:57 +00:00
return Date.now() + this.millis;
2023-09-15 16:55:03 +00:00
}
private tick(): void {
2023-09-15 23:20:15 +00:00
const distance_ms = this.target_date_ms - Date.now();
2023-09-15 16:55:03 +00:00
2023-09-15 23:20:15 +00:00
if (distance_ms <= 0) {
2023-09-15 16:55:03 +00:00
this.string_repr = "Jetzt!";
return;
}
2023-09-15 23:20:15 +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");
2023-09-15 16:55:03 +00:00
2023-09-15 23:20:15 +00:00
if (d_days.days > 0) {
this.string_repr = d_days.toHuman() + " ";
} else {
this.string_repr = "";
}
this.string_repr += d_hms.toFormat("hh:mm:ss");
2023-09-15 16:55:03 +00:00
}
public mounted(): void {
this.tick();
this.interval_id = window.setInterval(this.tick, this.tick_time);
}
public beforeUnmount(): void {
if (this.interval_id === null) return;
window.clearInterval(this.interval_id);
}
}
</script>