fix: complete logical clock wall-time isolation

This commit is contained in:
2026-08-04 20:37:56 +09:00
committed by Hide_D
parent 5d9512ced7
commit fc6f84ce23
67 changed files with 689 additions and 231 deletions
+5 -1
View File
@@ -27,7 +27,7 @@
<div class="row gx-1 gy-1 py-1">
<div class="col-lg-4 mx-0 mb-0 mt-1 d-grid">
<div class="alert alert-primary mb-0 center" style="padding: 0.5rem 0">
<SimpleClock :serverTime="parseTime(props.date)" />
<SimpleClock :serverTime="parseTime(props.date)" :running="props.clockMode === 'realtime'" />
</div>
</div>
@@ -289,6 +289,10 @@ const props = defineProps({
maxTurn: VueTypes.integer.isRequired,
maxPushTurn: VueTypes.integer.isRequired,
date: VueTypes.string.isRequired,
clockMode: {
type: String as PropType<"realtime" | "manual">,
required: true,
},
year: VueTypes.integer.isRequired,
month: VueTypes.integer.isRequired,
turnTerm: VueTypes.integer.isRequired,
+2 -5
View File
@@ -126,8 +126,6 @@
<script setup lang="ts">
import type { MsgItem, MsgTarget, MsgType } from "@/defs/API/Message";
import { parseTime } from "@/util/parseTime";
import { differenceInMilliseconds, addMinutes } from "date-fns/esm";
import { computed, onMounted, ref, toRef, watch, type ComputedRef, type Ref } from "vue";
import linkifyStr from "linkify-string";
import { SammoAPI } from "@/SammoAPI";
@@ -205,11 +203,10 @@ function testDeletable(msg: MsgItem): boolean {
if (msg.option.invalid) return false;
if (!(msg.option.deletable ?? true)) return false;
const now = new Date();
const last5min = addMinutes(parseTime(msg.time), 5);
const timeDiff = differenceInMilliseconds(last5min, now);
const timeDiff = msg.deleteRemainingMilliseconds;
if (timeDiff <= 0) return false;
if (msg.clockMode === "manual") return true;
deletableTimer.value = window.setTimeout(() => {
deletable.value = testDeletable(msg);
+27 -7
View File
@@ -4,7 +4,7 @@
<script lang="ts" setup>
import { addMilliseconds } from "date-fns";
import { type PropType, ref, onMounted, watch } from "vue";
import { type PropType, ref, onMounted, onUnmounted, watch } from "vue";
import { formatTime } from "@/util/formatTime";
const props = defineProps({
serverTime: {
@@ -17,25 +17,39 @@ const props = defineProps({
required: false,
default: "HH:mm:ss",
},
running: {
type: Boolean,
default: true,
},
});
const timeDiff = ref(0);
const serverNow = ref("");
watch(
() => props.serverTime,
(newValue) => {
() => [props.serverTime, props.running] as const,
([newValue]) => {
const clientNow = new Date();
timeDiff.value = newValue.getTime() - clientNow.getTime();
updateNow();
}
);
let timer: ReturnType<typeof setTimeout> | undefined;
function updateNow() {
const serverNowObj = addMilliseconds(new Date(), timeDiff.value);
if (timer !== undefined) {
clearTimeout(timer);
timer = undefined;
}
const serverNowObj = props.running
? addMilliseconds(new Date(), timeDiff.value)
: props.serverTime;
serverNow.value = formatTime(serverNowObj, props.timeFormat);
setTimeout(() => {
updateNow();
}, 1000 - serverNowObj.getMilliseconds());
if (props.running) {
timer = setTimeout(() => {
updateNow();
}, 1000 - serverNowObj.getMilliseconds());
}
}
onMounted(() => {
@@ -43,4 +57,10 @@ onMounted(() => {
timeDiff.value = props.serverTime.getTime() - clientNow.getTime();
updateNow();
});
onUnmounted(() => {
if (timer !== undefined) {
clearTimeout(timer);
}
});
</script>