From c64f2f30560159a6fe1e43ae95705cc60274d26c Mon Sep 17 00:00:00 2001 From: Kornilovich Mikhail Date: Sat, 10 Feb 2024 01:08:39 +0300 Subject: [PATCH 1/4] added astronomical clock --- .../main/kotlin/org/icpclive/api/Settings.kt | 7 +++++-- .../main/kotlin/org/icpclive/api/Ticker.kt | 2 -- .../admin/src/components/TickerMessage.js | 2 +- .../admin/src/components/TickerTableRow.js | 20 +++++++++++++++++++ src/frontend/common/api.ts | 3 ++- .../src/components/molecules/Clock.tsx | 10 +++++++++- .../components/organisms/tickers/Clock.tsx | 6 ++++-- 7 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt b/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt index 45f352ef2..5bdb28c5e 100644 --- a/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt +++ b/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt @@ -121,10 +121,13 @@ data class ImageTickerSettings( override fun toMessage() = ImageTickerMessage(this) } - @Serializable @SerialName("clock") -data class ClockTickerSettings(override val part: TickerPart, override val periodMs: Long) : TickerMessageSettings() { +data class ClockTickerSettings( + override val part: TickerPart, + override val periodMs: Long, + val timeZone: String? = null +) : TickerMessageSettings() { override fun toMessage() = ClockTickerMessage(this) } diff --git a/src/backend-api/src/main/kotlin/org/icpclive/api/Ticker.kt b/src/backend-api/src/main/kotlin/org/icpclive/api/Ticker.kt index a771f0e27..6856f30ee 100644 --- a/src/backend-api/src/main/kotlin/org/icpclive/api/Ticker.kt +++ b/src/backend-api/src/main/kotlin/org/icpclive/api/Ticker.kt @@ -31,8 +31,6 @@ class ImageTickerMessage(val settings: ImageTickerSettings) } } - - @Serializable @SerialName("clock") class ClockTickerMessage(val settings: ClockTickerSettings) : diff --git a/src/frontend/admin/src/components/TickerMessage.js b/src/frontend/admin/src/components/TickerMessage.js index f83f29a59..d53a04794 100644 --- a/src/frontend/admin/src/components/TickerMessage.js +++ b/src/frontend/admin/src/components/TickerMessage.js @@ -19,7 +19,7 @@ const addPresetButtons = [ { type: "clock", component: ClockIcon, - settings: { periodMs: 30000 }, + settings: { periodMs: 30000, timeZone: "" }, }, { part: "long", type: "scoreboard", diff --git a/src/frontend/admin/src/components/TickerTableRow.js b/src/frontend/admin/src/components/TickerTableRow.js index 589ed9b76..70dabb81a 100644 --- a/src/frontend/admin/src/components/TickerTableRow.js +++ b/src/frontend/admin/src/components/TickerTableRow.js @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import { DateTime } from "luxon"; import { TableCell, TableRow, TextField } from "@mui/material"; import Box from "@mui/material/Box"; import IconButton from "@mui/material/IconButton"; @@ -16,6 +17,7 @@ import { onChangeFieldEventHandler } from "./PresetsTableRow"; export function TickerTableRow({ data, onShow, onEdit, onDelete }) { const [editData, setEditData] = useState(); + const [errorMessage, setErrorMessage] = useState(""); const onClickEdit = () => { if (editData === undefined) { @@ -41,6 +43,24 @@ export function TickerTableRow({ data, onShow, onEdit, onDelete }) { {data.settings.type === "image" && } + {data.settings.type === "clock" && + (editData === undefined ? data.settings.timeZone : ( + + { + const dateTime = DateTime.now().setZone(event.target.value); + if (dateTime.isValid || event.target.value === "") { + setErrorMessage(""); + onChangeFieldEventHandler(setEditData, "timeZone")(event); + } else { + setErrorMessage(dateTime.invalidReason); + } + }}/> + ) + )} {data.settings.type === "text" && (editData === undefined ? data.settings.text : ( diff --git a/src/frontend/common/api.ts b/src/frontend/common/api.ts index 5322ccc27..fa7c1b37d 100644 --- a/src/frontend/common/api.ts +++ b/src/frontend/common/api.ts @@ -727,6 +727,7 @@ export enum TickerPart { export interface clock { part: TickerPart; periodMs: number; + timeZone?: string | null; } export interface image { @@ -779,4 +780,4 @@ export namespace ProblemSolutionStatistic { export interface IOIProblemEntity { count: number; score: number; -} +} diff --git a/src/frontend/overlay/src/components/molecules/Clock.tsx b/src/frontend/overlay/src/components/molecules/Clock.tsx index 311ac520b..3d0b57394 100644 --- a/src/frontend/overlay/src/components/molecules/Clock.tsx +++ b/src/frontend/overlay/src/components/molecules/Clock.tsx @@ -13,6 +13,7 @@ export const ContestClock = ({ globalTimeMode = false, contestCountdownMode = false, quietMode = false, + timeZone = null }) => { const formatTime = (time, fullFormat = false) => { if (!fullFormat && quietMode && time > 5 * 60 * 1000) { @@ -31,9 +32,16 @@ export const ContestClock = ({ } }, [contestInfo, contestCountdownMode]); + const getDateTimeNowWithCustomTimeZone = (zone) => + DateTime.now().setZone(zone).toFormat(quietMode ? "HH:mm" : "HH:mm:ss"); + const getStatus = useCallback(() => { if (globalTimeMode === true) { - return DateTime.now().setZone(new SystemZone()).toFormat(quietMode ? "HH:mm" : "HH:mm:ss"); + return getDateTimeNowWithCustomTimeZone(timeZone ?? new SystemZone()); + } + + if (timeZone !== null) { + return getDateTimeNowWithCustomTimeZone(timeZone); } if (contestInfo === undefined) { diff --git a/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx b/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx index debc214e8..c4fe08e7e 100644 --- a/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx +++ b/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx @@ -2,9 +2,11 @@ import React from "react"; import { TextWrap } from "./Text"; import ContestClock from "../../molecules/Clock"; -export const Clock = ({ part }) => { +export const Clock = ({ tickerSettings, part }) => { return - + ; }; From affda298ff51c6747f575c78e05856f9ad6a62db Mon Sep 17 00:00:00 2001 From: Mikhail Kornilovich Date: Sat, 10 Feb 2024 01:20:26 +0300 Subject: [PATCH 2/4] fix strange thing in api.ts --- src/frontend/common/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/common/api.ts b/src/frontend/common/api.ts index fa7c1b37d..18f6a86f1 100644 --- a/src/frontend/common/api.ts +++ b/src/frontend/common/api.ts @@ -780,4 +780,4 @@ export namespace ProblemSolutionStatistic { export interface IOIProblemEntity { count: number; score: number; -} +} From d07590a116b665d9f9441bc117e1cfa4ee39d84b Mon Sep 17 00:00:00 2001 From: Mikhail Kornilovich Date: Sun, 11 Feb 2024 16:01:22 +0300 Subject: [PATCH 3/4] backend: fix situation when timeZone is an empty string --- .../src/main/kotlin/org/icpclive/api/Settings.kt | 7 ++++++- .../overlay/src/components/organisms/tickers/Clock.tsx | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt b/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt index 5bdb28c5e..055a589ce 100644 --- a/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt +++ b/src/backend-api/src/main/kotlin/org/icpclive/api/Settings.kt @@ -128,7 +128,12 @@ data class ClockTickerSettings( override val periodMs: Long, val timeZone: String? = null ) : TickerMessageSettings() { - override fun toMessage() = ClockTickerMessage(this) + override fun toMessage(): ClockTickerMessage { + if (timeZone != null && timeZone.isEmpty()) { + return ClockTickerMessage(ClockTickerSettings(part, periodMs, null)) + } + return ClockTickerMessage(this) + } } @Serializable diff --git a/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx b/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx index c4fe08e7e..c6ecb1c7d 100644 --- a/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx +++ b/src/frontend/overlay/src/components/organisms/tickers/Clock.tsx @@ -5,7 +5,7 @@ import ContestClock from "../../molecules/Clock"; export const Clock = ({ tickerSettings, part }) => { return ; }; From ca2223e9918f3abcadb452f2ea666dc3ebf5f314 Mon Sep 17 00:00:00 2001 From: Mikhail Kornilovich Date: Sun, 11 Feb 2024 16:07:06 +0300 Subject: [PATCH 4/4] fixed: ticker settings for preset buttons --- src/frontend/admin/src/components/TickerMessage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/admin/src/components/TickerMessage.js b/src/frontend/admin/src/components/TickerMessage.js index d53a04794..f97401c72 100644 --- a/src/frontend/admin/src/components/TickerMessage.js +++ b/src/frontend/admin/src/components/TickerMessage.js @@ -19,7 +19,7 @@ const addPresetButtons = [ { type: "clock", component: ClockIcon, - settings: { periodMs: 30000, timeZone: "" }, + settings: { periodMs: 30000, timeZone: null }, }, { part: "long", type: "scoreboard",