Compare commits

..

9 Commits

Author SHA1 Message Date
Oleksandr Kozachuk 3f7a343b17 Improve tooltip. 2025-06-20 13:32:58 +02:00
Oleksandr Kozachuk 217c0b0028 Add Sleep. 2025-06-20 13:22:33 +02:00
Oleksandr Kozachuk a63ed16871 Move night 2 hours later. 2025-06-20 13:22:33 +02:00
Kiyomichi Kosaka 6e45dca49a Merge pull request #75 from ok2/codex/improve-tooltip-for-event-details
Improve event tooltip info
2025-06-20 13:21:47 +02:00
Kiyomichi Kosaka 1ec09e1b76 Improve event tooltip with series info 2025-06-20 13:21:32 +02:00
Kiyomichi Kosaka cf30e830a0 Merge pull request #74 from ok2/codex/update-eonstrips-detail-view-on-timezone-change 2025-06-20 10:31:21 +02:00
Kiyomichi Kosaka 65b85f1575 Update detail view on timezone change 2025-06-20 10:31:06 +02:00
Kiyomichi Kosaka 49b30a69e9 Merge pull request #73 from ok2/codex/rename-sleep-to-night-and-add-timezone-shift-attribute 2025-06-20 10:23:26 +02:00
Kiyomichi Kosaka 6c75140533 Rename Sleep event and add timezone shifting 2025-06-20 10:10:11 +02:00
2 changed files with 49 additions and 17 deletions
+2 -1
View File
@@ -21,5 +21,6 @@ window.SPECIAL_EVENTS = [
{ cobie: '330d.d4ae', label: 'Zusammentag', unit: 'cosmocycle', interval: 1 },
{ cobie: '11de.0c52', label: 'Anna', unit: 'cosmocycle', interval: 1 },
{ cobie: '467f.ae61', label: 'Iris', unit: 'cosmocycle', interval: 1 },
{ cobie: '6854.7a75', label: 'Sleep', unit: 'second', interval: 86400, duration: 28800, showMega: false }
{ cobie: '6854.7a75', label: 'Sleep', unit: 'second', interval: 86400, duration: 28800, showMega: false },
{ cobie: '6854.9695', label: 'Night', unit: 'second', interval: 86400, duration: 28800, showMega: false, shiftWithTimezone: true }
];
+47 -16
View File
@@ -44,6 +44,24 @@ let updateInterval;
let lastRenderedEonstrip = null;
let currentDetailCob = null;
function getTimezoneOffsetSeconds(date) {
if (currentTimezone === 'UTC') return 0;
if (currentTimezone === 'TAI') return getTAIOffsetAt(date);
const dtf = new Intl.DateTimeFormat('en-US', {
timeZone: currentTimezone,
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
});
const parts = dtf.formatToParts(date).reduce((acc, p) => {
if (p.type !== 'literal') acc[p.type] = parseInt(p.value, 10);
return acc;
}, {});
const utcTime = Date.UTC(parts.year, parts.month - 1, parts.day,
parts.hour, parts.minute, parts.second);
return (utcTime - date.getTime()) / 1000;
}
function formatSafeDate(rawDate, cobSeconds, intlOptions) {
if (rawDate instanceof Date && !isNaN(rawDate.getTime())) {
// Date is valid: optionally shift for TAI vs UTC, then format:
@@ -607,9 +625,11 @@ function updateCalendar() {
const cellEnd = cellCob + COBIE_UNITS.eonstrip;
window.SPECIAL_EVENTS.forEach(ev => {
if (ev.showMega === false) return;
const startCob = parseCobiets(ev.start || ev.cobie);
if (startCob === null) return;
const endCob = ev.end ? parseCobiets(ev.end) : Number.POSITIVE_INFINITY;
const baseStart = parseCobiets(ev.start || ev.cobie);
if (baseStart === null) return;
const tzShift = ev.shiftWithTimezone ? getTimezoneOffsetSeconds(fromCobiets(baseStart)) : 0;
const startCob = baseStart - tzShift;
const endCob = ev.end ? parseCobiets(ev.end) - tzShift : Number.POSITIVE_INFINITY;
const unitVal = COBIE_UNITS[ev.unit] || COBIE_UNITS.cosmocycle;
const interval = (ev.interval || 1) * unitVal;
let duration = 0;
@@ -714,9 +734,11 @@ function showEonstripDetail(index, startCob) {
const end = startCob + COBIE_UNITS.eonstrip;
window.SPECIAL_EVENTS.forEach(ev => {
if (ev.showDetail === false) return;
const startCobEv = parseCobiets(ev.start || ev.cobie);
if (startCobEv === null) return;
const endCobEv = ev.end ? parseCobiets(ev.end) : Number.POSITIVE_INFINITY;
const baseStart = parseCobiets(ev.start || ev.cobie);
if (baseStart === null) return;
const tzShift = ev.shiftWithTimezone ? getTimezoneOffsetSeconds(fromCobiets(baseStart)) : 0;
const startCobEv = baseStart - tzShift;
const endCobEv = ev.end ? parseCobiets(ev.end) - tzShift : Number.POSITIVE_INFINITY;
const unitVal = COBIE_UNITS[ev.unit] || COBIE_UNITS.cosmocycle;
const interval = (ev.interval || 1) * unitVal;
let duration = 0;
@@ -742,7 +764,9 @@ function showEonstripDetail(index, startCob) {
start: relStart,
end: relEnd,
cobStart: occ,
cobEnd: occ + duration
cobEnd: occ + duration,
seriesStart: startCobEv,
seriesEnd: endCobEv
});
occ += interval;
}
@@ -791,21 +815,25 @@ function showEonstripDetail(index, startCob) {
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
const opts = {
const optsShort = {
timeZone: currentTimezone === 'TAI' ? 'UTC' : currentTimezone,
year: 'numeric', month: 'short', day: 'numeric',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour: '2-digit', minute: '2-digit',
hour12: false
};
const startStr = formatCobieTimestamp(ev.cobStart);
const endStr = formatCobieTimestamp(ev.cobEnd);
const startDate = fromCobiets(ev.cobStart).toLocaleString('en-US', opts);
const endDate = fromCobiets(ev.cobEnd).toLocaleString('en-US', opts);
const startStr = formatCobieTimestamp(ev.cobStart);
const endStr = formatCobieTimestamp(ev.cobEnd);
const startDate = fromCobiets(ev.cobStart).toLocaleString('en-US', optsShort);
const endDate = fromCobiets(ev.cobEnd).toLocaleString('en-US', optsShort);
const seriesStart = formatCobieTimestamp(ev.seriesStart);
const seriesEnd = isFinite(ev.seriesEnd) ? formatCobieTimestamp(ev.seriesEnd) : '∞';
tooltip.innerHTML =
`<strong>${ev.label}</strong><br>` +
`Start: ${startStr}<br>` +
`End: ${endStr}<br>` +
`${startDate} ${endDate}`;
`Start: ${startStr} (${startDate})<br>` +
(ev.cobEnd > ev.cobStart ? `End: ${endStr} (${endDate})<br>` : '') +
`Series: ${seriesStart} ${seriesEnd}`;
elem.appendChild(tooltip);
timeline.appendChild(elem);
});
@@ -1004,6 +1032,9 @@ document.getElementById('timezone').addEventListener('change', (e) => {
currentTimezone = e.target.value;
updateCurrentTime();
updateCalendar();
if (currentDetailCob !== null) {
showEonstripDetail(currentDetailCob);
}
});
// Set default timezone based on user's locale