Added clock.
This commit is contained in:
@@ -8,6 +8,17 @@
|
|||||||
@activate="handleSearchActivate"
|
@activate="handleSearchActivate"
|
||||||
@preview="(r) => emit('search-preview', r)"
|
@preview="(r) => emit('search-preview', r)"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
class="current-time"
|
||||||
|
aria-label="Current time (click to go to today)"
|
||||||
|
role="button"
|
||||||
|
tabindex="-1"
|
||||||
|
@click="goToToday"
|
||||||
|
@keydown.enter="goToToday"
|
||||||
|
@keydown.space.prevent="goToToday"
|
||||||
|
>
|
||||||
|
{{ timeString }}
|
||||||
|
</div>
|
||||||
<div class="today-date" @click="goToToday">{{ todayString }}</div>
|
<div class="today-date" @click="goToToday">{{ todayString }}</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -62,11 +73,40 @@ import SettingsDialog from '@/components/SettingsDialog.vue'
|
|||||||
|
|
||||||
const calendarStore = useCalendarStore()
|
const calendarStore = useCalendarStore()
|
||||||
|
|
||||||
|
// Today label: derive from local ticking clock so it flips right at midnight
|
||||||
const todayString = computed(() => {
|
const todayString = computed(() => {
|
||||||
const d = new Date(calendarStore.now)
|
const d = new Date(localNowMs?.value ?? Date.now())
|
||||||
return formatTodayString(d)
|
return formatTodayString(d)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Local ticking clock: update every second without thrashing global store
|
||||||
|
const localNowMs = ref(Date.now())
|
||||||
|
let clockTimer = null
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// Start a 1s ticker for the header clock (independent from store's minute tick)
|
||||||
|
clockTimer = setInterval(() => {
|
||||||
|
localNowMs.value = Date.now()
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (clockTimer) clearInterval(clockTimer)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Current time (24h, NBSP padding for single-digit hours, with day/night emoji)
|
||||||
|
const timeString = computed(() => {
|
||||||
|
const d = new Date(localNowMs.value)
|
||||||
|
const h = d.getHours()
|
||||||
|
const m = d.getMinutes()
|
||||||
|
const hh = h < 10 ? '\u00A0' + h : String(h)
|
||||||
|
const mm = m < 10 ? '0' + m : String(m)
|
||||||
|
// Day at 6-18, otherwise night (TODO: sunrise/sunset)
|
||||||
|
const isDay = h >= 6 && h < 18
|
||||||
|
const emoji = isDay ? '🌞' : '🌙'
|
||||||
|
return `${hh}:${mm}${emoji}`
|
||||||
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['go-to-today', 'search-activate', 'search-preview'])
|
const emit = defineEmits(['go-to-today', 'search-activate', 'search-preview'])
|
||||||
const { referenceDate = null } = defineProps({ referenceDate: { type: String, default: null } })
|
const { referenceDate = null } = defineProps({ referenceDate: { type: String, default: null } })
|
||||||
|
|
||||||
@@ -98,7 +138,9 @@ function openSettings() {
|
|||||||
// Capture baseline before opening settings
|
// Capture baseline before opening settings
|
||||||
try {
|
try {
|
||||||
calendarStore.$history?._baselineIfNeeded?.(true)
|
calendarStore.$history?._baselineIfNeeded?.(true)
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* no-op */
|
||||||
|
}
|
||||||
settingsDialog.value?.open()
|
settingsDialog.value?.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,4 +309,23 @@ onBeforeUnmount(() => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
margin-inline-end: 2rem;
|
margin-inline-end: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.current-time {
|
||||||
|
font-family: ui-monospace, SF Mono, Consolas, Monaco, "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", "Ubuntu Mono", "Source Code Pro", "Fira Mono", "Droid Sans Mono", "Courier New", monospace;
|
||||||
|
font-size: 3.6em;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-time:hover,
|
||||||
|
.current-time:focus-visible {
|
||||||
|
color: var(--strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.current-time {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user