Fix date reload on presentation upload

This commit is contained in:
Alex Lion
2026-08-04 14:42:28 +07:00
parent 7225ce29cb
commit 111e1ddf66
4 changed files with 95 additions and 49 deletions

View File

@@ -17,6 +17,7 @@ import QRCodeStyling from "qr-code-styling";
import { Presenter } from "./presenter";
import { Manager } from "./manager";
import { AudioCapture } from "./audio_capture";
import DateTimeLocal from "./date_time_local.mjs";
import Split from "split-grid";
import CustomHooks from "./hooks";
import "./admin-charts.js";
@@ -418,54 +419,7 @@ Hooks.CalendarLocalDate = {
this.el.innerHTML = moment.utc(this.el.dataset.date).local().calendar();
},
};
Hooks.DateTimeLocal = {
mounted() {
this.localTime = this.el.querySelector("input[type=datetime-local]");
this.utcTime = this.el.querySelector("input[type=hidden]");
this.syncLocalTime();
this.handleInput = ({ target }) => {
if (target === this.localTime) this.syncUtcTime();
};
this.el.addEventListener("input", this.handleInput);
},
updated() {
this.localTime = this.el.querySelector("input[type=datetime-local]");
this.utcTime = this.el.querySelector("input[type=hidden]");
this.syncLocalTime();
},
syncLocalTime() {
if (!this.utcTime.value) {
this.localTime.value = "";
return;
}
const value = this.utcTime.value.replace(" ", "T").replace(/Z$/, "");
const date = new Date(`${value}Z`);
if (!Number.isNaN(date.getTime())) {
const pad = (part) => String(part).padStart(2, "0");
this.localTime.value =
`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
`T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}
},
syncUtcTime() {
if (!this.localTime.value) {
this.utcTime.value = "";
return;
}
const date = new Date(this.localTime.value);
if (!Number.isNaN(date.getTime())) {
this.utcTime.value = date.toISOString().slice(0, 19);
}
},
destroyed() {
this.el.removeEventListener("input", this.handleInput);
},
};
Hooks.DateTimeLocal = DateTimeLocal;
Hooks.UpdateAttendees = {
mounted() {
this.handleEvent("update-attendees", ({ count }) => {

View File

@@ -0,0 +1,52 @@
const DateTimeLocal = {
mounted() {
this.localTime = this.el.querySelector("input[type=datetime-local]");
this.utcTime = this.el.querySelector("input[type=hidden]");
this.syncLocalTime();
this.handleInput = ({ target }) => {
if (target === this.localTime) this.syncUtcTime();
};
this.el.addEventListener("input", this.handleInput);
this.el.addEventListener("change", this.handleInput);
},
updated() {
this.localTime = this.el.querySelector("input[type=datetime-local]");
this.utcTime = this.el.querySelector("input[type=hidden]");
this.syncLocalTime();
},
syncLocalTime() {
if (!this.utcTime.value) {
this.localTime.value = "";
return;
}
const value = this.utcTime.value.replace(" ", "T").replace(/Z$/, "");
const date = new Date(`${value}Z`);
if (!Number.isNaN(date.getTime())) {
const pad = (part) => String(part).padStart(2, "0");
this.localTime.value =
`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
`T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}
},
syncUtcTime() {
if (!this.localTime.value) {
this.utcTime.value = "";
return;
}
const date = new Date(this.localTime.value);
if (!Number.isNaN(date.getTime())) {
this.utcTime.value = date.toISOString().slice(0, 19);
}
},
destroyed() {
this.el.removeEventListener("input", this.handleInput);
this.el.removeEventListener("change", this.handleInput);
},
};
export default DateTimeLocal;

View File

@@ -1,6 +1,7 @@
{
"scripts": {
"deploy": "NODE_ENV=production tailwindcss --postcss --minify --input=css/app.css --output=../priv/static/assets/app.css"
"deploy": "NODE_ENV=production tailwindcss --postcss --minify --input=css/app.css --output=../priv/static/assets/app.css",
"test": "node --test test/*.mjs"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.11",

View File

@@ -0,0 +1,39 @@
import assert from "node:assert/strict";
import test from "node:test";
import DateTimeLocal from "../js/date_time_local.mjs";
function mountHook() {
const localTime = { value: "" };
const utcTime = { value: "2026-08-04T12:00:00" };
const listeners = new Map();
const el = {
querySelector(selector) {
return selector === "input[type=datetime-local]" ? localTime : utcTime;
},
addEventListener(type, listener) {
listeners.set(type, listener);
},
removeEventListener(type) {
listeners.delete(type);
},
dispatch(type, target) {
listeners.get(type)?.({ target });
},
};
const hook = { ...DateTimeLocal, el };
hook.mounted();
return { el, hook, localTime, utcTime };
}
test("syncs the hidden UTC value when the datetime control only emits change", () => {
const { el, localTime, utcTime } = mountHook();
localTime.value = "2030-01-02T10:30";
el.dispatch("change", localTime);
assert.equal(utcTime.value, new Date(localTime.value).toISOString().slice(0, 19));
});