4d2c464045
PostCard and PostModal competed for the same data and rendered redundant chrome (header twice, image grid twice, attachment list twice). The wider PostCard layout we shipped 2026-05-27 has enough real estate to be the canonical post surface, so collapse the two into one. Compact (default) state is unchanged: hero + 3-cell rail + truncated title + 3/5-line description + attachment count badge. Whole-card click expands in place. Expanded state shows: full title, mosaic of ALL post images via PostImageGrid (uncapped, lazy-loaded via getPostFull), full sanitized-HTML description with paragraph wrapping, attachments as downloadable pill links. Click the chevron in the header to collapse; mosaic image clicks open ImageViewer scoped to the post (modalStore's postImageIds path is preserved — only the comment changed). Per-card local state — no global modal store. Each PostCard owns its own expanded ref and lazy-loaded detail; collapsing a card discards neither (so re-expand is instant after the first fetch). Deleted: PostModal.vue, postModal.js store. Removed the App.vue mount.
26 lines
688 B
Vue
26 lines
688 B
Vue
<template>
|
|
<v-app>
|
|
<AppShell>
|
|
<RouterView />
|
|
</AppShell>
|
|
<ImageViewer v-if="modal.isOpen" @close="modal.close()" />
|
|
<AppSnackbar ref="snackbar" />
|
|
</v-app>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, ref } from 'vue'
|
|
import AppShell from './components/AppShell.vue'
|
|
import AppSnackbar from './components/AppSnackbar.vue'
|
|
import ImageViewer from './components/modal/ImageViewer.vue'
|
|
import { useModalStore } from './stores/modal.js'
|
|
|
|
const modal = useModalStore()
|
|
const snackbar = ref(null)
|
|
|
|
onMounted(() => {
|
|
// Expose snackbar via a simple global so stores can call it without props.
|
|
window.__fcToast = (opts) => snackbar.value?.open(opts)
|
|
})
|
|
</script>
|