feat(posts): images open the modal; only text expands in place
Post cards no longer expand the whole card on click (the old two-click path
to the images). The card is compact-only now:
- Hero / rail thumbs / the +N tile are buttons that open the post-scoped image
modal (modal.open(id, { postImageIds })) so you view big + arrow through ALL
the post's images. The feed caps thumbnails at 6, so for posts with more we
lazily getPostFull to get the complete id list; +N opens at the first hidden
image.
- The description is the ONLY in-place expansion: a Show more / Show less toggle
shown only when the text is actually truncated (server description_truncated
flag OR a measured CSS-clamp overflow, ResizeObserver-guarded). Expanding
loads description_full when server-truncated and renders it unclamped.
- Attachments: download chips now render inline in the compact card (the feed
already carries download_url), since the expanded view is gone.
Removes PostImageGrid.vue (the mosaic, now unused). Tests cover show-more
visibility + image-click opening the scoped modal.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,26 +1,61 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { flushPromises } from '@vue/test-utils'
|
||||
|
||||
import PostCard from '../../src/components/posts/PostCard.vue'
|
||||
import { useModalStore } from '../../src/stores/modal.js'
|
||||
import { freshPinia, mountComponent } from '../support/mountComponent.js'
|
||||
|
||||
const now = new Date().toISOString()
|
||||
const BASE = {
|
||||
id: 1, external_post_id: 'P1',
|
||||
post_title: '<strong>Hello World</strong>',
|
||||
post_url: 'https://x/1', post_date: now, downloaded_at: now,
|
||||
artist: { id: 1, name: 'Sabu', slug: 'sabu' },
|
||||
source: { id: 1, platform: 'subscribestar' },
|
||||
thumbnails: [], thumbnails_more: 0, attachments: [],
|
||||
}
|
||||
|
||||
describe('PostCard', () => {
|
||||
it('renders the HTML-stripped title and the artist', () => {
|
||||
const pinia = freshPinia()
|
||||
const now = new Date().toISOString()
|
||||
const post = {
|
||||
id: 1, external_post_id: 'P1',
|
||||
post_title: '<strong>Hello World</strong>',
|
||||
post_url: 'https://x/1', post_date: now, downloaded_at: now,
|
||||
description_plain: 'a description',
|
||||
artist: { id: 1, name: 'Sabu', slug: 'sabu' },
|
||||
source: { id: 1, platform: 'subscribestar' },
|
||||
thumbnails: [], thumbnails_more: 0, attachments: [],
|
||||
}
|
||||
const w = mountComponent(PostCard, { props: { post }, pinia })
|
||||
const post = { ...BASE, description_plain: 'a description' }
|
||||
const w = mountComponent(PostCard, { props: { post }, pinia: freshPinia() })
|
||||
const t = w.text()
|
||||
expect(t).toContain('Hello World') // plain title
|
||||
expect(t).not.toContain('<strong>') // tags stripped
|
||||
expect(t).toContain('Sabu') // artist (RouterLink slot)
|
||||
})
|
||||
|
||||
it('shows a "Show more" toggle only when the description is truncated', () => {
|
||||
const truncated = mountComponent(PostCard, {
|
||||
props: { post: { ...BASE, description_plain: 'lots of text…', description_truncated: true } },
|
||||
pinia: freshPinia(),
|
||||
})
|
||||
expect(truncated.text()).toContain('Show more')
|
||||
|
||||
const full = mountComponent(PostCard, {
|
||||
props: { post: { ...BASE, description_plain: 'short', description_truncated: false } },
|
||||
pinia: freshPinia(),
|
||||
})
|
||||
expect(full.text()).not.toContain('Show more')
|
||||
})
|
||||
|
||||
it('clicking an image opens the post-scoped modal (never expands the card)', async () => {
|
||||
const pinia = freshPinia()
|
||||
const modal = useModalStore()
|
||||
const openSpy = vi.spyOn(modal, 'open').mockResolvedValue()
|
||||
const post = {
|
||||
...BASE,
|
||||
description_plain: 'd',
|
||||
thumbnails: [
|
||||
{ image_id: 10, thumbnail_url: '/a' },
|
||||
{ image_id: 11, thumbnail_url: '/b' },
|
||||
],
|
||||
thumbnails_more: 0,
|
||||
}
|
||||
const w = mountComponent(PostCard, { props: { post }, pinia })
|
||||
await w.find('.fc-post-card__hero').trigger('click')
|
||||
await flushPromises()
|
||||
expect(openSpy).toHaveBeenCalledWith(10, { postImageIds: [10, 11] })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user