Skip to content
Snippets Groups Projects
Commit c84b8c6d authored by Simon Künzel's avatar Simon Künzel
Browse files

Improve datetime handling and update to new API version

parent b388b30c
Branches
Tags
No related merge requests found
......@@ -11,6 +11,7 @@ import { LectureLiveLabel } from "@/videoag/course/LiveLabel";
import { ErrorComponent, showError, showWarningToast } from "@/videoag/error/ErrorDisplay";
import { FallbackErrorBoundary } from "@/videoag/error/FallbackErrorBoundary";
import { useLanguage } from "@/videoag/localization/LanguageProvider";
import { datetimeToStringOnlyDate, datetimeToStringOnlyTime } from "@/videoag/miscellaneous/Formatting";
import { ReloadBoundary, useReloadBoundary } from "@/videoag/miscellaneous/ReloadBoundary";
import {
ResourceType,
......@@ -170,13 +171,7 @@ function UpcomingUploads({ homepageData }: { homepageData: ResourceType<GetHomep
let dates = []; // group by day/date
for (let lecture of data.upcoming_lectures) {
let date_parsed = new Date(lecture.time);
let date_string = date_parsed.toLocaleDateString([], {
weekday: "short",
year: "numeric",
month: "2-digit",
day: "2-digit",
});
let date_string = datetimeToStringOnlyDate(lecture.time);
let date_index = dates.findIndex((date) => date.date === date_string);
if (date_index === -1) {
......@@ -193,7 +188,6 @@ function UpcomingUploads({ homepageData }: { homepageData: ResourceType<GetHomep
<strong>{date.date}</strong>
<ul className="list-group">
{date.lectures.map((lecture, index) => {
let date_parsed = new Date(lecture.time);
let course_data = data.course_context[lecture.course_id];
return (
<li
......@@ -201,13 +195,7 @@ function UpcomingUploads({ homepageData }: { homepageData: ResourceType<GetHomep
style={{ border: "none" }}
key={index}
>
{
// only time (HH:MM)
date_parsed.toLocaleTimeString([], {
hour: "2-digit",
minute: "2-digit",
})
}{" "}
{datetimeToStringOnlyTime(lecture.time)}{" "}
<a href={`/${course_data.handle}`}>{course_data.full_name}</a>
{": "}
<a href={`/${course_data.handle}#lecture-${lecture.id}`}>
......
......@@ -263,8 +263,6 @@ export function LectureCard({
size?: "small" | "auto";
}) {
const { language } = useLanguage();
let dateStr = datetimeToString(lecture.time);
let sz = size === "small" ? "xxl" : "sm";
return (
......@@ -306,7 +304,7 @@ export function LectureCard({
</span>{" "}
<br />
<br />
<span>{dateStr}</span>
<span>{datetimeToString(lecture.time)}</span>
{lecture.speaker ? (
<div className="small p-children-inline">
{language.get("ui.generic.lecture_given_by")}{" "}
......@@ -345,7 +343,7 @@ export function LectureCard({
<strong>{course.full_name}</strong>
<LectureLiveLabel lecture={lecture} />
</li>
<li>{dateStr}</li>
<li>{datetimeToString(lecture.time)}</li>
{lecture.speaker ? (
<div className="small p-children-inline">
{language.get("ui.generic.lecture_given_by")}{" "}
......
......@@ -16,7 +16,7 @@ import { useLanguage } from "@/videoag/localization/LanguageProvider";
import Title from "@/videoag/miscellaneous/TitleComponent";
import { ResourceType } from "@/videoag/miscellaneous/PromiseHelpers";
import { UpdateOverlay } from "@/videoag/miscellaneous/UpdateOverlay";
import { showInfoToast } from "@/videoag/miscellaneous/Util";
import { showInfoToast, parseApiDatetime } from "@/videoag/miscellaneous/Util";
import { useEditMode } from "@/videoag/object_management/EditModeProvider";
import {
OMDelete,
......@@ -198,12 +198,12 @@ function LectureSuggestions({ course, lecture }: { course: course; lecture: lect
const { language } = useLanguage();
const prevLecture = course.lectures?.findLast(
(l) =>
new Date(l.time) < new Date(lecture.time) &&
parseApiDatetime(l.time) < parseApiDatetime(lecture.time) &&
(l.publish_media ?? []).find((m) => m.include_in_player),
);
const nextLecture = course.lectures?.find(
(l) =>
new Date(l.time) > new Date(lecture.time) &&
parseApiDatetime(l.time) > parseApiDatetime(lecture.time) &&
(l.publish_media ?? []).find((m) => m.include_in_player),
);
......
......@@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
import type { int } from "@/videoag/api/types";
import { useLanguage } from "@/videoag/localization/LanguageProvider";
import { deepEquals } from "@/videoag/miscellaneous/Util";
import { deepEquals, parseApiDatetime, formatApiDatetime } from "@/videoag/miscellaneous/Util";
export type EditorArgs = {
value?: any;
......@@ -232,7 +232,11 @@ export function DatetimeEditor({
}, [knownValue, value, setForceInputUpdate]);
const isValidCheck = (val: string | null | undefined) => {
if (val === null || val === undefined || isNaN(new Date(val).valueOf())) {
let parsedVal = null;
try {
parsedVal = parseApiDatetime(val);
} catch {}
if (val === null || val === undefined || parsedVal === null) {
return mayBeNull === true;
}
return true;
......@@ -246,17 +250,7 @@ export function DatetimeEditor({
isValid = false;
}
} else {
const date = new Date(newValue);
const intToStr = (v: int, length: int) => {
let str = v.toString();
while (str.length < length) {
str = "0" + str;
}
return str;
};
const dateStr = `${intToStr(date.getFullYear(), 4)}-${intToStr(date.getMonth() + 1, 2)}-${intToStr(date.getDate(), 2)}`;
const timeStr = `${intToStr(date.getHours(), 2)}:${intToStr(date.getMinutes(), 2)}:${intToStr(date.getSeconds(), 2)}`;
newValue = `${dateStr}T${timeStr}`;
newValue = formatApiDatetime(new Date(newValue));
}
knownValue.current = newValue;
updateValue(newValue, isValid, false);
......
import { zeropad, parseApiDatetime } from "./Util";
export function semesterToHuman(semester?: string, long_str?: boolean): string {
if (!semester || semester === "zeitlos" || semester === "none" || semester.length !== 6) {
return "Zeitlos";
......@@ -16,10 +18,6 @@ export function semesterToHuman(semester?: string, long_str?: boolean): string {
return `Wintersemester ${year}/${(parseInt(year) + 1).toString().substring(2)}`;
}
}
export function zeropad(num: number, places: number) {
var zero = places - num.toString().length + 1;
return Array(+(zero > 0 && zero)).join("0") + num;
}
export function timestampToString(timestamp: number) {
let h = zeropad(Math.trunc(timestamp / 3600), 2);
let m = zeropad(Math.trunc((timestamp % 3600) / 60), 2);
......@@ -27,10 +25,25 @@ export function timestampToString(timestamp: number) {
let timeasstring = h + ":" + m + ":" + s;
return timeasstring;
}
export function datetimeToString(datetime: string) {
let date_parsed = new Date(datetime);
return `${date_parsed.toLocaleDateString([], { weekday: "short", year: "numeric", month: "2-digit", day: "2-digit" })}, ${date_parsed.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}`;
export function datetimeToStringOnlyDate(datetime: DateTime | string): string {
if (typeof datetime === "string") {
datetime = parseApiDatetime(datetime);
}
return datetime.toLocaleString({ weekday: "short", year: "numeric", month: "2-digit", day: "2-digit" });
}
export function datetimeToStringOnlyTime(datetime: DateTime): string {
if (typeof datetime === "string") {
datetime = parseApiDatetime(datetime);
}
return datetime.toLocaleString({ hour: "2-digit", minute: "2-digit" });
}
export function datetimeToString(datetime: DateTime): string {
return `${datetimeToStringOnlyDate(datetime)}, ${datetimeToStringOnlyTime(datetime)}`;
}
export function filesizeToHuman(size: number) {
if (size < 1024) {
return size + " B";
......
import type React from "react";
import { OverlayTrigger, Tooltip } from "react-bootstrap";
import { toast, Bounce } from "react-toastify";
import { DateTime } from "luxon";
import type { datetime } from "@/videoag/api/types";
export function zeropad(num: number, places: number) {
var zero = places - num.toString().length + 1;
return Array(+(zero > 0 && zero)).join("0") + num;
}
export function formatApiDatetime(datetime: DateTime): string {
return datetime.toUTC().toISO({ format: "extended", suppressSeconds: false, suppressMilliseconds: false, includeOffset: true });
}
export function parseApiDatetime(datetimeString: datetime): DateTime {
return DateTime.fromISO(datetimeString);
}
export function deepEquals(value: any, other: any) {
if (value === null || other === null) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment