fix(ui): render absolute timestamps in the viewer's local timezone
Download event times showed raw UTC wall-clock (iso.slice). Added formatDateTime()/formatLocalDate() (local tz, robust to naive vs tz-aware ISO) and applied them to the download row + detail modal datetimes and the credential/artist date displays. formatPostDate stays UTC (date-only, locale-stable, unit-tested). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { formatLocalDate } from '../../utils/date.js'
|
||||
|
||||
const props = defineProps({
|
||||
name: { type: String, required: true },
|
||||
@@ -52,7 +53,7 @@ const stats = computed(() => {
|
||||
parts.push(`${props.imageCount} image${props.imageCount === 1 ? '' : 's'}`)
|
||||
}
|
||||
if (props.lastAdded) {
|
||||
parts.push(`last added ${props.lastAdded.slice(0, 10)}`)
|
||||
parts.push(`last added ${formatLocalDate(props.lastAdded)}`)
|
||||
}
|
||||
return parts.join(' · ')
|
||||
})
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { formatLocalDate } from '../../utils/date.js'
|
||||
|
||||
defineProps({
|
||||
platform: { type: Object, required: true },
|
||||
credential: { type: Object, default: null },
|
||||
@@ -39,8 +41,7 @@ defineProps({
|
||||
defineEmits(['replace', 'remove'])
|
||||
|
||||
function fmtDate(iso) {
|
||||
if (!iso) return '—'
|
||||
return iso.slice(0, 10)
|
||||
return iso ? formatLocalDate(iso) : '—'
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<p class="text-caption" style="opacity: 0.75">
|
||||
{{ event.started_at }} → {{ event.finished_at || '(running)' }}
|
||||
{{ formatDateTime(event.started_at) }} → {{ event.finished_at ? formatDateTime(event.finished_at) : '(running)' }}
|
||||
({{ fmtDuration(event.summary?.duration_seconds) }})
|
||||
</p>
|
||||
|
||||
@@ -105,6 +105,7 @@ import { toast } from '../../utils/toast.js'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { copyText } from '../../utils/clipboard.js'
|
||||
import { formatDateTime } from '../../utils/date.js'
|
||||
|
||||
const props = defineProps({ event: { type: Object, default: null } })
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
@@ -93,6 +93,7 @@ import { RouterLink } from 'vue-router'
|
||||
import PlatformChip from '../subscriptions/PlatformChip.vue'
|
||||
import { useSourcesStore } from '../../stores/sources.js'
|
||||
import { downloadStatusColor, downloadStatusIcon, downloadStatusLabel } from '../../utils/downloadStatus.js'
|
||||
import { formatDateTime } from '../../utils/date.js'
|
||||
|
||||
const props = defineProps({ event: { type: Object, required: true } })
|
||||
defineEmits(['open'])
|
||||
@@ -105,9 +106,7 @@ const statusIcon = computed(() => downloadStatusIcon(props.event.status))
|
||||
const statusLabel = computed(() => downloadStatusLabel(props.event.status))
|
||||
|
||||
function fmtTime(iso) {
|
||||
if (!iso) return '—'
|
||||
// 2026-05-27 23:36 — second granularity is in the row's title attr
|
||||
return iso.slice(0, 16).replace('T', ' ')
|
||||
return iso ? formatDateTime(iso) : '—'
|
||||
}
|
||||
function fmtDuration(sec) {
|
||||
if (sec == null) return '—'
|
||||
|
||||
@@ -102,6 +102,7 @@ import { toast } from '../../utils/toast.js'
|
||||
import { computed, ref } from 'vue'
|
||||
import PlatformChip from './PlatformChip.vue'
|
||||
import { useCredentialsStore } from '../../stores/credentials.js'
|
||||
import { formatLocalDate } from '../../utils/date.js'
|
||||
|
||||
const props = defineProps({
|
||||
platform: { type: Object, required: true },
|
||||
@@ -195,8 +196,7 @@ const howToFallback = computed(() => {
|
||||
})
|
||||
|
||||
function fmtDate(iso) {
|
||||
if (!iso) return '—'
|
||||
return iso.slice(0, 10)
|
||||
return iso ? formatLocalDate(iso) : '—'
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user