memi-board 0.36.0 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -2
- package/dist/runtime/components/ListDefault.vue +2 -2
- package/dist/runtime/components/ListDense.vue +2 -2
- package/dist/runtime/components/ListVideo.vue +2 -2
- package/dist/runtime/components/MiniCard.vue +2 -2
- package/dist/runtime/components/MiniPosts.vue +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -221,6 +221,7 @@ const { post: postSeo } = await useMemiBoardPostSeo({
|
|
|
221
221
|
- [ ] 목록·상세 페이지에 `await useMemiBoard*Seo(…)` 한 줄
|
|
222
222
|
- [ ] 호스트 SEO API **만들지 않음**
|
|
223
223
|
- [ ] CSS `@source` (아래)
|
|
224
|
+
- [ ] (선택) 읽은 글 표시 CSS (아래)
|
|
224
225
|
- [ ] Rules·indexes **deploy**
|
|
225
226
|
- [ ] 최초 admin + 첫 카테고리
|
|
226
227
|
|
|
@@ -235,7 +236,26 @@ const { post: postSeo } = await useMemiBoardPostSeo({
|
|
|
235
236
|
@source "../../../node_modules/memi-board/dist/runtime/components";
|
|
236
237
|
```
|
|
237
238
|
|
|
238
|
-
### 5.
|
|
239
|
+
### 5. 읽은 글 표시 (선택)
|
|
240
|
+
|
|
241
|
+
목록·미니 컴포넌트의 글 링크는 `.memi-board-post-link` 클래스가 붙어 있고, 제목 텍스트는 `text-inherit`로 링크 색을 따른다. 패키지는 색을 강제하지 않으므로, 방문한 글을 흐리게 보이고 싶으면 호스트 CSS에 `:visited` 스타일만 추가하면 된다.
|
|
242
|
+
|
|
243
|
+
```css
|
|
244
|
+
/* app/assets/css/main.css */
|
|
245
|
+
a.memi-board-post-link:visited {
|
|
246
|
+
color: #737373;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.dark a.memi-board-post-link:visited {
|
|
250
|
+
color: #a3a3a3;
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**`:visited`는 `color`만 허용하고, 그마저도 `var()`·알파값은 브라우저가 무시한다** (히스토리 스니핑 방지). 그래서 Nuxt UI 토큰(`var(--ui-text-muted)`)을 그대로 못 쓰고 라이트/다크용 리터럴 색상을 각각 지정해야 한다(위 값은 Tailwind `neutral-500`/`neutral-400`).
|
|
255
|
+
|
|
256
|
+
브라우저 네이티브 `:visited` 라서 서버·DB 저장이 필요 없다. 단, SPA 클라이언트 라우팅(`NuxtLink`)으로만 이동한 경우 브라우저에 "실제 방문"으로 기록되지 않을 수 있어 완전히 신뢰할 수는 없다 — 정확한 읽음 추적이 필요하면 별도로 방문 글 ID를 저장하는 방식을 구현해야 한다.
|
|
257
|
+
|
|
258
|
+
### 6. Security Rules + 인덱스 배포
|
|
239
259
|
|
|
240
260
|
1. [docs/firestore.rules.example](docs/firestore.rules.example) → 호스트 `firestore.rules`에 병합
|
|
241
261
|
(`memiBoardPosts`/`memiBoardComments`/`memiBoardLikes`/`memiBoardSettings`/`memiBoardUsers` — 전부 최상위 flat 컬렉션)
|
|
@@ -257,7 +277,7 @@ const { post: postSeo } = await useMemiBoardPostSeo({
|
|
|
257
277
|
|
|
258
278
|
> ⚠️ npm 패키지 tarball에도 `docs/` 가 포함된다(0.4.7+). 구버전이면 GitHub의 `docs/`를 보면 된다.
|
|
259
279
|
|
|
260
|
-
###
|
|
280
|
+
### 7. 최초 관리자와 카테고리 만들기
|
|
261
281
|
|
|
262
282
|
Rules는 일반 사용자가 스스로 관리자가 되는 것을 막는다. 따라서 최초 한 번은 다음 순서가 필요하다.
|
|
263
283
|
|
|
@@ -493,6 +513,7 @@ export default defineNuxtPlugin(() => {
|
|
|
493
513
|
- [ ] 목록·상세 페이지에 `await useMemiBoardListSeo` / `useMemiBoardPostSeo`
|
|
494
514
|
- [ ] 호스트 SEO API 없음
|
|
495
515
|
- [ ] CSS `@source` …/memi-board/dist/runtime/components
|
|
516
|
+
- [ ] (선택) `.memi-board-post-link:visited` 읽은 글 표시 CSS
|
|
496
517
|
- [ ] Rules 예시 병합 + **deploy**
|
|
497
518
|
- [ ] 카테고리·listed 쿼리 사용 시 indexes deploy
|
|
498
519
|
- [ ] 페이지·미들웨어 직접 작성 (또는 playground 복사)
|
|
@@ -35,7 +35,7 @@ function image(post: PostModel): string | undefined {
|
|
|
35
35
|
<component
|
|
36
36
|
:is="postTo(post) ? NuxtLink : 'button'"
|
|
37
37
|
:to="postTo(post)"
|
|
38
|
-
class="flex min-w-0 flex-1 text-left transition-colors hover:bg-elevated/50"
|
|
38
|
+
class="memi-board-post-link flex min-w-0 flex-1 text-left text-highlighted transition-colors hover:bg-elevated/50"
|
|
39
39
|
@click="!postTo(post) && emit('select', post)"
|
|
40
40
|
>
|
|
41
41
|
<div class="min-w-0 flex-1 flex flex-col justify-center gap-1 overflow-hidden py-2 pl-3 pr-2">
|
|
@@ -56,7 +56,7 @@ function image(post: PostModel): string | undefined {
|
|
|
56
56
|
size="sm"
|
|
57
57
|
class="mt-0.5 shrink-0"
|
|
58
58
|
/>
|
|
59
|
-
<h3 class="min-w-0 line-clamp-2 break-words text-sm font-medium leading-snug sm:text-base">
|
|
59
|
+
<h3 class="min-w-0 line-clamp-2 break-words text-sm font-medium leading-snug text-inherit sm:text-base">
|
|
60
60
|
{{ post.title?.trim() || post.summary || '사진' }}
|
|
61
61
|
</h3>
|
|
62
62
|
<span
|
|
@@ -31,7 +31,7 @@ function thumb(post: PostModel): string | undefined {
|
|
|
31
31
|
<component
|
|
32
32
|
:is="postTo(post) ? NuxtLink : 'button'"
|
|
33
33
|
:to="postTo(post)"
|
|
34
|
-
class="group flex min-w-0 w-full items-baseline gap-1.5 rounded-lg text-left transition-colors hover:bg-elevated/60"
|
|
34
|
+
class="memi-board-post-link group flex min-w-0 w-full items-baseline gap-1.5 rounded-lg text-left text-highlighted transition-colors hover:bg-elevated/60"
|
|
35
35
|
@click="!postTo(post) && emit('select', post)"
|
|
36
36
|
>
|
|
37
37
|
<UBadge
|
|
@@ -42,7 +42,7 @@ function thumb(post: PostModel): string | undefined {
|
|
|
42
42
|
size="sm"
|
|
43
43
|
class="shrink-0"
|
|
44
44
|
/>
|
|
45
|
-
<h3 class="min-w-0 truncate text-sm font-medium leading-snug text-
|
|
45
|
+
<h3 class="min-w-0 truncate text-sm font-medium leading-snug text-inherit transition-colors group-hover:text-primary">
|
|
46
46
|
{{ post.title?.trim() || post.summary || '사진' }}
|
|
47
47
|
</h3>
|
|
48
48
|
<span
|
|
@@ -32,7 +32,7 @@ function cover(post: PostModel): string | undefined {
|
|
|
32
32
|
<component
|
|
33
33
|
:is="postTo(post) ? NuxtLink : 'button'"
|
|
34
34
|
:to="postTo(post)"
|
|
35
|
-
class="block w-full text-left transition hover:bg-elevated/50"
|
|
35
|
+
class="memi-board-post-link block w-full text-left text-highlighted transition hover:bg-elevated/50"
|
|
36
36
|
@click="!postTo(post) && emit('select', post)"
|
|
37
37
|
>
|
|
38
38
|
<div class="relative aspect-video overflow-hidden bg-elevated">
|
|
@@ -52,7 +52,7 @@ function cover(post: PostModel): string | undefined {
|
|
|
52
52
|
size="sm"
|
|
53
53
|
class="mt-0.5 shrink-0"
|
|
54
54
|
/>
|
|
55
|
-
<h3 class="min-w-0 line-clamp-2 font-medium">{{ post.title }}</h3>
|
|
55
|
+
<h3 class="min-w-0 line-clamp-2 font-medium text-inherit">{{ post.title }}</h3>
|
|
56
56
|
<span
|
|
57
57
|
v-if="(post.commentCount ?? 0) > 0"
|
|
58
58
|
class="mt-0.5 inline-flex shrink-0 items-center rounded-full bg-primary/10 px-1.5 py-px text-[11px] font-semibold tabular-nums text-primary"
|
|
@@ -19,7 +19,7 @@ const to = computed(() => props.getPostLink?.(props.post) ?? miniPostLink(props.
|
|
|
19
19
|
<component
|
|
20
20
|
:is="to ? NuxtLink : 'div'"
|
|
21
21
|
:to="to"
|
|
22
|
-
class="group flex h-full min-w-0 flex-col overflow-hidden rounded-lg bg-elevated/40 text-left"
|
|
22
|
+
class="memi-board-post-link group flex h-full min-w-0 flex-col overflow-hidden rounded-lg bg-elevated/40 text-left text-highlighted"
|
|
23
23
|
>
|
|
24
24
|
<div
|
|
25
25
|
class="overflow-hidden bg-muted"
|
|
@@ -39,7 +39,7 @@ const to = computed(() => props.getPostLink?.(props.post) ?? miniPostLink(props.
|
|
|
39
39
|
</div>
|
|
40
40
|
</div>
|
|
41
41
|
<div class="flex flex-1 flex-col gap-0.5 p-2.5">
|
|
42
|
-
<p class="line-clamp-2 text-sm font-medium leading-snug text-
|
|
42
|
+
<p class="line-clamp-2 text-sm font-medium leading-snug text-inherit group-hover:text-primary">
|
|
43
43
|
{{ title }}
|
|
44
44
|
</p>
|
|
45
45
|
<span class="mt-1 inline-flex items-center gap-0.5 text-[11px] tabular-nums text-muted">
|
|
@@ -80,11 +80,11 @@ function postTo(post: PostModel) {
|
|
|
80
80
|
<component
|
|
81
81
|
:is="postTo(post) ? NuxtLink : 'div'"
|
|
82
82
|
:to="postTo(post)"
|
|
83
|
-
class="flex items-center gap-2 px-3 py-2 transition-colors hover:bg-elevated/60"
|
|
83
|
+
class="memi-board-post-link flex items-center gap-2 px-3 py-2 text-highlighted transition-colors hover:bg-elevated/60"
|
|
84
84
|
>
|
|
85
85
|
<div class="min-w-0 flex-1">
|
|
86
86
|
<div class="flex min-w-0 items-start gap-1.5">
|
|
87
|
-
<p class="min-w-0 flex-1 truncate text-sm font-medium text-
|
|
87
|
+
<p class="min-w-0 flex-1 truncate text-sm font-medium text-inherit">
|
|
88
88
|
{{ miniPostTitle(post) }}
|
|
89
89
|
</p>
|
|
90
90
|
<span class="mt-0.5 inline-flex shrink-0 items-center gap-0.5 text-[11px] tabular-nums text-muted">
|