memi-board 0.52.2 → 0.52.3
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/dist/{ar-BVwpedHS.js → ar-3hd6xh6U.js} +3 -1
- package/dist/ar-3hd6xh6U.js.map +1 -0
- package/dist/{commentImages-D_JJnuoj.js → commentImages-4IOk2u0O.js} +11 -10
- package/dist/commentImages-4IOk2u0O.js.map +1 -0
- package/dist/composables/useMemiBoardComments.d.ts +1 -0
- package/dist/composables/useMemiBoardWritingAssistant.d.ts +1 -1
- package/dist/{de-K2gYwR8U.js → de-DXtmk-4H.js} +3 -1
- package/dist/de-DXtmk-4H.js.map +1 -0
- package/dist/{en-DSCLJyUd.js → en-CyZH4Ct1.js} +2 -1
- package/dist/en-CyZH4Ct1.js.map +1 -0
- package/dist/{es-1P1miLJH.js → es-BtRbHicT.js} +3 -1
- package/dist/es-BtRbHicT.js.map +1 -0
- package/dist/{fr-cDQCmNSc.js → fr-vnizG3rD.js} +3 -1
- package/dist/fr-vnizG3rD.js.map +1 -0
- package/dist/{id-BzDIqeZ4.js → id-Cf8yw8n_.js} +3 -1
- package/dist/id-Cf8yw8n_.js.map +1 -0
- package/dist/index.js +422 -397
- package/dist/index.js.map +1 -1
- package/dist/{ja-B2wxHGCr.js → ja-D-Nrtjk-.js} +3 -1
- package/dist/ja-D-Nrtjk-.js.map +1 -0
- package/dist/{pt-BCY3OODD.js → pt-CSsshr7u.js} +3 -1
- package/dist/pt-CSsshr7u.js.map +1 -0
- package/dist/runtime/components/CommentForm.vue +10 -1
- package/dist/runtime/components/Editor.vue +15 -9
- package/dist/storage.js +1 -1
- package/dist/{zh-Y824rwR6.js → zh-BzrsqVN2.js} +3 -1
- package/dist/zh-BzrsqVN2.js.map +1 -0
- package/docs/firestore.rules.example +3 -3
- package/docs/host-integration.md +13 -0
- package/package.json +1 -1
- package/dist/ar-BVwpedHS.js.map +0 -1
- package/dist/commentImages-D_JJnuoj.js.map +0 -1
- package/dist/de-K2gYwR8U.js.map +0 -1
- package/dist/en-DSCLJyUd.js.map +0 -1
- package/dist/es-1P1miLJH.js.map +0 -1
- package/dist/fr-cDQCmNSc.js.map +0 -1
- package/dist/id-BzDIqeZ4.js.map +0 -1
- package/dist/ja-B2wxHGCr.js.map +0 -1
- package/dist/pt-BCY3OODD.js.map +0 -1
- package/dist/zh-Y824rwR6.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as l, K as u, L as d, M as f, N as p, O as m, P as h, R as g, S as _, T as v, U as y, V as b, W as x, X as S, Y as C, Z as w, _ as T, a as E, b as D, c as
|
|
2
|
-
import { computed as
|
|
3
|
-
import { collection as
|
|
1
|
+
import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as l, K as u, L as d, M as f, N as p, O as m, P as h, R as g, S as _, T as v, U as y, V as b, W as x, X as S, Y as C, Z as w, _ as T, a as E, b as D, c as ee, d as O, f as k, g as A, h as j, j as te, k as ne, l as re, m as M, o as ie, p as ae, q as oe, r as se, s as N, t as ce, u as le, v as ue, w as P, x as de, y as F, z as fe } from "./commentImages-4IOk2u0O.js";
|
|
2
|
+
import { computed as I, onScopeDispose as L, reactive as pe, readonly as me, ref as R, toValue as z, watch as B } from "vue";
|
|
3
|
+
import { collection as he, deleteDoc as ge, deleteField as _e, doc as ve, documentId as V, endAt as ye, endBefore as be, getDoc as xe, getDocFromServer as Se, getDocs as H, getDocsFromServer as Ce, increment as we, limit as U, limitToLast as Te, onSnapshot as W, orderBy as G, query as K, runTransaction as Ee, serverTimestamp as q, setDoc as De, startAfter as J, updateDoc as Y, where as X, writeBatch as Oe } from "firebase/firestore";
|
|
4
4
|
import { useCollection as ke, useCurrentUser as Ae, useDocument as je, useFirebaseApp as Me, useFirebaseAuth as Ne, useFirestore as Z } from "vuefire";
|
|
5
5
|
import { GoogleAuthProvider as Pe, OAuthProvider as Fe, createUserWithEmailAndPassword as Ie, getAuth as Le, signInWithEmailAndPassword as Re, signInWithPopup as ze, signOut as Be, updateProfile as Ve } from "firebase/auth";
|
|
6
6
|
import { deleteObject as He, getMetadata as Ue, getStorage as We, list as Ge, listAll as Ke, ref as qe } from "firebase/storage";
|
|
7
7
|
import { GoogleAIBackend as Je, Schema as Ye, getAI as Xe, getGenerativeModel as Ze } from "firebase/ai";
|
|
8
8
|
//#region src/utils/boardSeo.ts
|
|
9
9
|
function Qe(e, t) {
|
|
10
|
-
return !e || e === "전체" || e ===
|
|
10
|
+
return !e || e === "전체" || e === M(t, "seo.allCategory");
|
|
11
11
|
}
|
|
12
12
|
function $e(e) {
|
|
13
13
|
if (typeof e != "string") return null;
|
|
@@ -37,23 +37,23 @@ function tt(e, t, n = "") {
|
|
|
37
37
|
return i ? /^https?:\/\//i.test(i) ? i : `${r}${i.startsWith("/") ? i : `/${i}`}` : n ? tt(n, t) : r;
|
|
38
38
|
}
|
|
39
39
|
function nt(e, t, n, r, i) {
|
|
40
|
-
let a = r?.trim().slice(0, 40), o = e.trim() || a ||
|
|
40
|
+
let a = r?.trim().slice(0, 40), o = e.trim() || a || M(i, "seo.photo"), s = t?.trim(), c = n.trim() || "Board";
|
|
41
41
|
return s ? `${o} · ${s} | ${c}` : `${o} | ${c}`;
|
|
42
42
|
}
|
|
43
43
|
function rt(e, t) {
|
|
44
44
|
let n = [];
|
|
45
|
-
return e.summary?.trim() ? n.push(e.summary.trim().slice(0, 140)) : n.push(
|
|
45
|
+
return e.summary?.trim() ? n.push(e.summary.trim().slice(0, 140)) : n.push(M(t, "seo.postDescriptionFallback")), e.categoryLabel?.trim() && n.push(e.categoryLabel.trim()), e.authorName?.trim() && n.push(e.authorName.trim()), n.join(" · ").slice(0, 200);
|
|
46
46
|
}
|
|
47
47
|
function it(e, t, n) {
|
|
48
48
|
let r = t.trim() || "Board", i = e?.trim();
|
|
49
|
-
return Qe(i, n) ?
|
|
49
|
+
return Qe(i, n) ? M(n, "seo.listTitleAll", { site: r }) : M(n, "seo.listTitle", {
|
|
50
50
|
name: i,
|
|
51
51
|
site: r
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
function at(e, t) {
|
|
55
55
|
if (e.description?.trim()) return e.description.trim().slice(0, 200);
|
|
56
|
-
let n = e.categoryLabel?.trim(), r = Qe(n, t) ?
|
|
56
|
+
let n = e.categoryLabel?.trim(), r = Qe(n, t) ? M(t, "seo.listDescriptionAll") : M(t, "seo.listDescription", { name: n }), i = (e.recentTitles || []).filter(Boolean).slice(0, 3);
|
|
57
57
|
return i.length ? `${r} ${i.map((e) => `「${e}」`).join(" ")}`.slice(0, 200) : r.slice(0, 200);
|
|
58
58
|
}
|
|
59
59
|
function ot(e) {
|
|
@@ -82,7 +82,7 @@ function Q(e) {
|
|
|
82
82
|
if (!e || typeof e != "object") return;
|
|
83
83
|
let t = {};
|
|
84
84
|
for (let [n, r] of Object.entries(e)) {
|
|
85
|
-
let e =
|
|
85
|
+
let e = F(n);
|
|
86
86
|
if (!e || !r || typeof r != "object") continue;
|
|
87
87
|
let i = {};
|
|
88
88
|
for (let [e, t] of Object.entries(r)) typeof t == "string" && t.trim() && (i[e] = t.trim());
|
|
@@ -92,14 +92,14 @@ function Q(e) {
|
|
|
92
92
|
}
|
|
93
93
|
function ut(e) {
|
|
94
94
|
if (!e || typeof e != "object") return;
|
|
95
|
-
let t = e, n = {}, r =
|
|
95
|
+
let t = e, n = {}, r = F(t.locale);
|
|
96
96
|
r && (n.locale = r);
|
|
97
97
|
for (let e of st) typeof t[e] == "string" && (n[e] = t[e]);
|
|
98
98
|
return Object.keys(n).length ? n : void 0;
|
|
99
99
|
}
|
|
100
100
|
function dt(e) {
|
|
101
101
|
if (!e || typeof e != "object") return;
|
|
102
|
-
let t = e, n = {}, r =
|
|
102
|
+
let t = e, n = {}, r = F(t.locale);
|
|
103
103
|
return r && (n.locale = r), typeof t.hash == "string" && t.hash && (n.hash = t.hash), n.locale || n.hash ? n : void 0;
|
|
104
104
|
}
|
|
105
105
|
function ft(e, t, n) {
|
|
@@ -122,7 +122,7 @@ function ft(e, t, n) {
|
|
|
122
122
|
}), r;
|
|
123
123
|
}
|
|
124
124
|
function pt(e) {
|
|
125
|
-
let t = new Set((e?.translationLocales ?? []).map((e) =>
|
|
125
|
+
let t = new Set((e?.translationLocales ?? []).map((e) => F(e)).filter((e) => !!e)), n = T.map((e) => e.code);
|
|
126
126
|
return t.size ? n.filter((e) => t.has(e)) : n;
|
|
127
127
|
}
|
|
128
128
|
function mt(e) {
|
|
@@ -135,7 +135,7 @@ function ht(e, t, n = T.map((e) => e.code)) {
|
|
|
135
135
|
}
|
|
136
136
|
function gt(e, t, r, i, a) {
|
|
137
137
|
if (!n()) return i;
|
|
138
|
-
let o =
|
|
138
|
+
let o = F(t), s = F(a);
|
|
139
139
|
if (!o || s && o === s) return i;
|
|
140
140
|
let c = lt(e?.[o], r);
|
|
141
141
|
if (c) return c;
|
|
@@ -170,12 +170,12 @@ function St(e, t) {
|
|
|
170
170
|
function Ct() {
|
|
171
171
|
return {
|
|
172
172
|
db: Z(),
|
|
173
|
-
paths:
|
|
173
|
+
paths: P()
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
176
|
async function wt(e, t, n) {
|
|
177
177
|
try {
|
|
178
|
-
let r = await
|
|
178
|
+
let r = await xe(w(e.db, e.paths, t));
|
|
179
179
|
if (!r.exists()) return {
|
|
180
180
|
label: t,
|
|
181
181
|
description: "",
|
|
@@ -208,11 +208,11 @@ async function Et(e, t, n, r) {
|
|
|
208
208
|
let i = e.trim(), a = t.trim();
|
|
209
209
|
if (!i || !a) return null;
|
|
210
210
|
let s = n ?? Ct();
|
|
211
|
-
s.paths = C(s.paths), r && await
|
|
211
|
+
s.paths = C(s.paths), r && await ae(r);
|
|
212
212
|
let c = await wt(s, i, r);
|
|
213
213
|
if (c.hidden) return null;
|
|
214
214
|
try {
|
|
215
|
-
let e = (await
|
|
215
|
+
let e = (await H(K(o(s.db, s.paths), X("boardId", "==", i), X("slug", "==", a), X("listed", "==", !0), X("isPublished", "==", !0), U(1)))).docs[0];
|
|
216
216
|
if (!e) return null;
|
|
217
217
|
let t = e.data() ?? {}, n = typeof t.title == "string" ? t.title : "", l = typeof t.summary == "string" ? t.summary : "", u = Q(t.i18n), d = ut(t.i18nSource), f = vt({
|
|
218
218
|
title: n,
|
|
@@ -239,7 +239,7 @@ async function Et(e, t, n, r) {
|
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
async function Dt(e, t, n) {
|
|
242
|
-
n && await
|
|
242
|
+
n && await ae(n);
|
|
243
243
|
let r = e?.trim() || null, i = t ?? Ct();
|
|
244
244
|
if (i.paths = C(i.paths), r) {
|
|
245
245
|
let e = await wt(i, r, n);
|
|
@@ -256,7 +256,7 @@ async function Dt(e, t, n) {
|
|
|
256
256
|
kind: "category",
|
|
257
257
|
category: r,
|
|
258
258
|
categoryLabel: e.label,
|
|
259
|
-
description: e.description ||
|
|
259
|
+
description: e.description || M(n, "seo.boardDescription", { name: e.label }),
|
|
260
260
|
ogImage: a,
|
|
261
261
|
recentTitles: t
|
|
262
262
|
};
|
|
@@ -264,8 +264,8 @@ async function Dt(e, t, n) {
|
|
|
264
264
|
return {
|
|
265
265
|
kind: "all",
|
|
266
266
|
category: null,
|
|
267
|
-
categoryLabel:
|
|
268
|
-
description:
|
|
267
|
+
categoryLabel: M(n, "seo.allCategory"),
|
|
268
|
+
description: M(n, "seo.allDescription"),
|
|
269
269
|
ogImage: null,
|
|
270
270
|
recentTitles: []
|
|
271
271
|
};
|
|
@@ -273,7 +273,7 @@ async function Dt(e, t, n) {
|
|
|
273
273
|
async function Ot(e, t, n) {
|
|
274
274
|
let r = [], i = null;
|
|
275
275
|
try {
|
|
276
|
-
let a = await
|
|
276
|
+
let a = await H(K(o(e.db, e.paths), X("boardId", "==", t), X("listed", "==", !0), X("isPublished", "==", !0), G("createdAt", "desc"), U(12)));
|
|
277
277
|
for (let e of a.docs) {
|
|
278
278
|
let t = e.data() ?? {}, a = vt({
|
|
279
279
|
title: typeof t.title == "string" ? t.title : "",
|
|
@@ -337,10 +337,10 @@ function zt(e, t, n = Date.now(), r = 10, i = It) {
|
|
|
337
337
|
}
|
|
338
338
|
function Bt(e, t = Date.now(), n) {
|
|
339
339
|
let r = Math.max(0, e - t), i = Math.ceil(r / 36e5);
|
|
340
|
-
if (i <= 0) return
|
|
341
|
-
if (i < 24) return
|
|
340
|
+
if (i <= 0) return M(n, "moderationStrike.liftSoon");
|
|
341
|
+
if (i < 24) return M(n, "moderationStrike.liftInHours", { hours: i });
|
|
342
342
|
let a = Math.floor(i / 24), o = i % 24;
|
|
343
|
-
return o === 0 ?
|
|
343
|
+
return o === 0 ? M(n, "moderationStrike.liftInDays", { days: a }) : M(n, "moderationStrike.liftInDaysHours", {
|
|
344
344
|
days: a,
|
|
345
345
|
hours: o
|
|
346
346
|
});
|
|
@@ -361,15 +361,15 @@ var Ht = "__MEMI_BOARD_AUTH_STATE__";
|
|
|
361
361
|
function Ut() {
|
|
362
362
|
let e = globalThis;
|
|
363
363
|
return e[Ht] || (e[Ht] = {
|
|
364
|
-
role:
|
|
365
|
-
rolePending:
|
|
366
|
-
rawBlockCount:
|
|
367
|
-
blockAtMs:
|
|
364
|
+
role: R("user"),
|
|
365
|
+
rolePending: R(!0),
|
|
366
|
+
rawBlockCount: R(0),
|
|
367
|
+
blockAtMs: R(null),
|
|
368
368
|
watchStarted: !1
|
|
369
369
|
}), e[Ht];
|
|
370
370
|
}
|
|
371
371
|
function Wt() {
|
|
372
|
-
let e = v(), { t, locale: n } =
|
|
372
|
+
let e = v(), { t, locale: n } = N(), r = Ut(), i = Z(), o = Ne(), s = Ae(), { role: c, rolePending: l, rawBlockCount: u, blockAtMs: d } = r;
|
|
373
373
|
function f() {
|
|
374
374
|
let t = e.moderation?.blockBanThreshold;
|
|
375
375
|
return t === 0 ? 0 : typeof t == "number" && t > 0 ? Math.floor(t) : 10;
|
|
@@ -379,7 +379,7 @@ function Wt() {
|
|
|
379
379
|
return typeof t == "number" && t > 0 ? t : It;
|
|
380
380
|
}
|
|
381
381
|
function m(e) {
|
|
382
|
-
return h(i,
|
|
382
|
+
return h(i, P(), e);
|
|
383
383
|
}
|
|
384
384
|
function g(e) {
|
|
385
385
|
if (c.value = [
|
|
@@ -395,22 +395,22 @@ function Wt() {
|
|
|
395
395
|
u.value = Math.max(0, Math.floor(Number(e.moderationBlockCount) || 0)), d.value = Vt(e.moderationBlockAt);
|
|
396
396
|
}
|
|
397
397
|
async function _(e) {
|
|
398
|
-
let t = m(e.uid), n = a(i,
|
|
399
|
-
if (!r.exists()) return await Promise.all([
|
|
398
|
+
let t = m(e.uid), n = a(i, P(), e.uid), r = await xe(t);
|
|
399
|
+
if (!r.exists()) return await Promise.all([De(t, {
|
|
400
400
|
role: "user",
|
|
401
401
|
displayName: e.displayName,
|
|
402
402
|
photoURL: e.photoURL,
|
|
403
|
-
joinedAt:
|
|
404
|
-
lastVisitAt:
|
|
405
|
-
updatedAt:
|
|
406
|
-
}),
|
|
403
|
+
joinedAt: q(),
|
|
404
|
+
lastVisitAt: q(),
|
|
405
|
+
updatedAt: q()
|
|
406
|
+
}), De(n, { email: e.email })]), g({ moderationBlockCount: 0 }), "user";
|
|
407
407
|
let o = r.data();
|
|
408
408
|
g(o);
|
|
409
409
|
let s = typeof o.displayName == "string" && o.displayName.trim(), c = typeof o.photoURL == "string" && o.photoURL.trim(), l = {
|
|
410
|
-
lastVisitAt:
|
|
411
|
-
updatedAt:
|
|
410
|
+
lastVisitAt: q(),
|
|
411
|
+
updatedAt: q()
|
|
412
412
|
};
|
|
413
|
-
return !s && e.displayName && (l.displayName = e.displayName), !c && e.photoURL && (l.photoURL = e.photoURL), await Promise.all([Y(t, l),
|
|
413
|
+
return !s && e.displayName && (l.displayName = e.displayName), !c && e.photoURL && (l.photoURL = e.photoURL), await Promise.all([Y(t, l), De(n, { email: e.email }, { merge: !0 })]), [
|
|
414
414
|
"owner",
|
|
415
415
|
"admin",
|
|
416
416
|
"manager",
|
|
@@ -424,10 +424,10 @@ function Wt() {
|
|
|
424
424
|
g(void 0);
|
|
425
425
|
return;
|
|
426
426
|
}
|
|
427
|
-
let t = await
|
|
427
|
+
let t = await xe(m(e));
|
|
428
428
|
g(t.exists() ? t.data() : void 0);
|
|
429
429
|
}
|
|
430
|
-
r.watchStarted || (r.watchStarted = !0,
|
|
430
|
+
r.watchStarted || (r.watchStarted = !0, B(s, async (e) => {
|
|
431
431
|
if (l.value = !0, !e) {
|
|
432
432
|
c.value = "user", g(void 0), l.value = !1;
|
|
433
433
|
return;
|
|
@@ -440,37 +440,37 @@ function Wt() {
|
|
|
440
440
|
l.value = !1;
|
|
441
441
|
}
|
|
442
442
|
}, { immediate: !0 }));
|
|
443
|
-
let b =
|
|
443
|
+
let b = I(() => !!s.value), x = I(() => c.value === "owner"), S = I(() => c.value === "manager"), C = I(() => x.value || c.value === "admin"), w = I(() => S.value || c.value === "staff"), T = I(() => C.value || w.value), E = I(() => Lt(u.value, d.value, Date.now(), p())), D = I(() => {
|
|
444
444
|
let e = f();
|
|
445
445
|
return e <= 0 ? !1 : zt(u.value, d.value, Date.now(), e, p());
|
|
446
|
-
}),
|
|
446
|
+
}), ee = I(() => {
|
|
447
447
|
let e = f();
|
|
448
448
|
if (e <= 0) return null;
|
|
449
449
|
let t = Rt(u.value, d.value, Date.now(), e, p());
|
|
450
450
|
return t == null ? null : Bt(t, Date.now(), n.value);
|
|
451
|
-
}),
|
|
451
|
+
}), O = I(() => {
|
|
452
452
|
if (!D.value) return null;
|
|
453
|
-
let e =
|
|
453
|
+
let e = ee.value;
|
|
454
454
|
return e ? t("auth.writeRestrictedUntil", { until: e }) : t("auth.writeRestricted");
|
|
455
455
|
});
|
|
456
|
-
async function
|
|
456
|
+
async function k() {
|
|
457
457
|
let e = s.value?.uid, r = f();
|
|
458
458
|
if (!e || r <= 0) return {
|
|
459
459
|
effectiveCount: 0,
|
|
460
460
|
restricted: !1,
|
|
461
461
|
messageSuffix: ""
|
|
462
462
|
};
|
|
463
|
-
let i = m(e), a = await
|
|
463
|
+
let i = m(e), a = await xe(i);
|
|
464
464
|
a.exists() ? await Y(i, {
|
|
465
|
-
moderationBlockCount:
|
|
466
|
-
moderationBlockAt:
|
|
467
|
-
updatedAt:
|
|
468
|
-
}) : await
|
|
465
|
+
moderationBlockCount: we(1),
|
|
466
|
+
moderationBlockAt: q(),
|
|
467
|
+
updatedAt: q()
|
|
468
|
+
}) : await De(i, {
|
|
469
469
|
role: "user",
|
|
470
470
|
displayName: s.value?.displayName ?? null,
|
|
471
471
|
moderationBlockCount: 1,
|
|
472
|
-
moderationBlockAt:
|
|
473
|
-
updatedAt:
|
|
472
|
+
moderationBlockAt: q(),
|
|
473
|
+
updatedAt: q()
|
|
474
474
|
});
|
|
475
475
|
let o = (a.exists() ? Math.max(0, Math.floor(Number(a.data().moderationBlockCount) || 0)) : 0) + 1, c = Date.now();
|
|
476
476
|
u.value = o, d.value = c;
|
|
@@ -495,64 +495,64 @@ function Wt() {
|
|
|
495
495
|
if (!o) throw Error(t("auth.notInitialized"));
|
|
496
496
|
return o;
|
|
497
497
|
}
|
|
498
|
-
async function
|
|
498
|
+
async function j() {
|
|
499
499
|
return ze(A(), new Pe());
|
|
500
500
|
}
|
|
501
|
-
async function
|
|
501
|
+
async function te() {
|
|
502
502
|
let e = new Fe("apple.com");
|
|
503
503
|
return e.addScope("email"), e.addScope("name"), ze(A(), e);
|
|
504
504
|
}
|
|
505
|
-
async function
|
|
505
|
+
async function ne(e, t) {
|
|
506
506
|
return Re(A(), e, t);
|
|
507
507
|
}
|
|
508
|
-
async function
|
|
508
|
+
async function re(e, t, n) {
|
|
509
509
|
let r = await Ie(A(), e, t);
|
|
510
510
|
return n && await Ve(r.user, { displayName: n }), r;
|
|
511
511
|
}
|
|
512
|
-
async function
|
|
512
|
+
async function M() {
|
|
513
513
|
await Be(A());
|
|
514
514
|
}
|
|
515
|
-
function
|
|
515
|
+
function ie(e) {
|
|
516
516
|
return At(s.value?.uid, C.value, w.value, e ? Pt(e) : void 0);
|
|
517
517
|
}
|
|
518
|
-
function
|
|
518
|
+
function ae(e) {
|
|
519
519
|
return s.value ? C.value ? !0 : S.value && !!e && (Pt(e)?.allowedManagerUids ?? []).includes(s.value.uid) : !1;
|
|
520
520
|
}
|
|
521
|
-
function
|
|
522
|
-
return b.value && (s.value?.uid === e.authorUid ||
|
|
521
|
+
function oe(e) {
|
|
522
|
+
return b.value && (s.value?.uid === e.authorUid || ie(e.boardId));
|
|
523
523
|
}
|
|
524
|
-
function
|
|
524
|
+
function se(e) {
|
|
525
525
|
return b.value && s.value?.uid === e.authorUid;
|
|
526
526
|
}
|
|
527
|
-
function
|
|
528
|
-
return b.value && (s.value?.uid === e.authorUid ||
|
|
527
|
+
function ce(e) {
|
|
528
|
+
return b.value && (s.value?.uid === e.authorUid || ie(e.boardId));
|
|
529
529
|
}
|
|
530
530
|
return {
|
|
531
531
|
user: s,
|
|
532
532
|
role: c,
|
|
533
533
|
isOwner: x,
|
|
534
534
|
isManager: S,
|
|
535
|
-
canConfigureBoard:
|
|
535
|
+
canConfigureBoard: ae,
|
|
536
536
|
isSignedIn: b,
|
|
537
537
|
isAdmin: C,
|
|
538
538
|
isStaff: w,
|
|
539
539
|
canManageContent: T,
|
|
540
|
-
canManageBoard:
|
|
540
|
+
canManageBoard: ie,
|
|
541
541
|
rolePending: l,
|
|
542
542
|
moderationBlockCount: E,
|
|
543
543
|
isWriteRestricted: D,
|
|
544
|
-
restrictedUntilLabel:
|
|
545
|
-
restrictedMessage:
|
|
546
|
-
signInWithGoogle:
|
|
547
|
-
signInWithApple:
|
|
548
|
-
signInWithEmail:
|
|
549
|
-
signUpWithEmail:
|
|
550
|
-
signOut:
|
|
551
|
-
canEdit:
|
|
552
|
-
canDelete:
|
|
553
|
-
canEditComment:
|
|
554
|
-
canDeleteComment:
|
|
555
|
-
recordContentModerationBlock:
|
|
544
|
+
restrictedUntilLabel: ee,
|
|
545
|
+
restrictedMessage: O,
|
|
546
|
+
signInWithGoogle: j,
|
|
547
|
+
signInWithApple: te,
|
|
548
|
+
signInWithEmail: ne,
|
|
549
|
+
signUpWithEmail: re,
|
|
550
|
+
signOut: M,
|
|
551
|
+
canEdit: oe,
|
|
552
|
+
canDelete: oe,
|
|
553
|
+
canEditComment: se,
|
|
554
|
+
canDeleteComment: ce,
|
|
555
|
+
recordContentModerationBlock: k,
|
|
556
556
|
refreshBoardUser: y
|
|
557
557
|
};
|
|
558
558
|
}
|
|
@@ -581,7 +581,7 @@ function Jt(e) {
|
|
|
581
581
|
//#region src/utils/findReadablePost.ts
|
|
582
582
|
async function Yt(e, t, n, r, i, a) {
|
|
583
583
|
let s = [X("boardId", "==", n), X("slug", "==", r)];
|
|
584
|
-
return a ? (await
|
|
584
|
+
return a ? (await H(K(o(e, t), ...s, U(1)))).docs[0] : (await Promise.all([H(K(o(e, t), ...s, X("listed", "==", !0), X("isPublished", "==", !0), U(1))), ...i ? [H(K(o(e, t), ...s, X("authorUid", "==", i), U(1)))] : []])).flatMap((e) => e.docs)[0];
|
|
585
585
|
}
|
|
586
586
|
//#endregion
|
|
587
587
|
//#region src/utils/extractEditorImageUrls.ts
|
|
@@ -620,27 +620,27 @@ async function en(e, t) {
|
|
|
620
620
|
}
|
|
621
621
|
var tn = 450;
|
|
622
622
|
async function nn(e, t, n) {
|
|
623
|
-
return (await
|
|
623
|
+
return (await H(K(g(e, t), X("postId", "==", n)))).docs.flatMap((e) => ce(e.data().images, `${x(t, n)}/comment-images/`));
|
|
624
624
|
}
|
|
625
625
|
async function rn(e, t) {
|
|
626
626
|
let n = [...new Set([...t].filter(Boolean))];
|
|
627
627
|
await Promise.all(n.map((t) => He(qe(e, t)).catch(() => {})));
|
|
628
628
|
}
|
|
629
629
|
async function an(e, t) {
|
|
630
|
-
let n = await
|
|
630
|
+
let n = await H(t);
|
|
631
631
|
for (let t = 0; t < n.docs.length; t += tn) {
|
|
632
632
|
let r = Oe(e);
|
|
633
633
|
n.docs.slice(t, t + tn).forEach((e) => r.delete(e.ref)), await r.commit();
|
|
634
634
|
}
|
|
635
635
|
}
|
|
636
636
|
async function on(e, t, n) {
|
|
637
|
-
await an(e,
|
|
637
|
+
await an(e, K(b(e, t), X("postId", "==", n)));
|
|
638
638
|
}
|
|
639
639
|
async function sn(e, t, n) {
|
|
640
|
-
await an(e,
|
|
640
|
+
await an(e, K(b(e, t), X("commentId", "==", n), X("target", "==", "comment")));
|
|
641
641
|
}
|
|
642
642
|
async function cn(e, t, n, r) {
|
|
643
|
-
let i = y(e, n, r), a = s(e, n, r), [o, c] = await Promise.all([
|
|
643
|
+
let i = y(e, n, r), a = s(e, n, r), [o, c] = await Promise.all([xe(i), xe(a)]);
|
|
644
644
|
if (!o.exists()) return;
|
|
645
645
|
let l = o.data(), u = c.exists() ? String(c.data().content ?? "") : "", d = await nn(e, n, r), f = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set();
|
|
646
646
|
for (let e of l.attachments ?? []) {
|
|
@@ -662,7 +662,7 @@ async function cn(e, t, n, r) {
|
|
|
662
662
|
}
|
|
663
663
|
await en(t, x(n, r));
|
|
664
664
|
for (let e of p) await en(t, x(n, e));
|
|
665
|
-
await rn(t, d), await rn(t, f), await an(e,
|
|
665
|
+
await rn(t, d), await rn(t, f), await an(e, K(g(e, n), X("postId", "==", r))), await on(e, n, r), await ge(a), await ge(i);
|
|
666
666
|
}
|
|
667
667
|
//#endregion
|
|
668
668
|
//#region src/utils/postBody.ts
|
|
@@ -719,7 +719,7 @@ function vn(e) {
|
|
|
719
719
|
async function yn(e, t, n, r) {
|
|
720
720
|
let i;
|
|
721
721
|
for (;;) {
|
|
722
|
-
let a = await
|
|
722
|
+
let a = await H(K(t, X("boardId", "==", n), G("__name__"), ...i ? [J(i)] : [], U(400)));
|
|
723
723
|
if (a.empty) break;
|
|
724
724
|
let o = Oe(e), s = 0;
|
|
725
725
|
for (let e of a.docs) e.data().listed !== r && (o.update(e.ref, { listed: r }), s++);
|
|
@@ -731,7 +731,7 @@ async function bn(e, t, n, r) {
|
|
|
731
731
|
}
|
|
732
732
|
async function xn(e, t, n, r) {
|
|
733
733
|
let i = w(e, t, n), a = vn(r.visibility);
|
|
734
|
-
await
|
|
734
|
+
await Ee(e, async (e) => {
|
|
735
735
|
let t = await e.get(i), n = t.data(), o = n?.visibilityTransition || "";
|
|
736
736
|
if (o && o !== a) throw Error("Finish the pending visibility change before changing it again.");
|
|
737
737
|
return !t.exists() || !o && vn(n?.visibility) === a ? (e.set(i, r, { merge: !0 }), !1) : (e.set(i, {
|
|
@@ -739,12 +739,12 @@ async function xn(e, t, n, r) {
|
|
|
739
739
|
visibility: a === "public" ? "public" : vn(n?.visibility),
|
|
740
740
|
visibilityTransition: a
|
|
741
741
|
}, { merge: !0 }), !0);
|
|
742
|
-
}) && (await bn(e, t, n, a !== "hidden"), await
|
|
742
|
+
}) && (await bn(e, t, n, a !== "hidden"), await Ee(e, async (e) => {
|
|
743
743
|
if ((await e.get(i)).data()?.visibilityTransition !== a) throw Error("The visibility transition changed. Reload and retry.");
|
|
744
744
|
e.update(i, {
|
|
745
745
|
visibility: a,
|
|
746
746
|
visibilityTransition: "",
|
|
747
|
-
updatedAt:
|
|
747
|
+
updatedAt: q()
|
|
748
748
|
});
|
|
749
749
|
}));
|
|
750
750
|
}
|
|
@@ -763,7 +763,7 @@ var Sn = "당신은 게시판 콘텐츠를 심사하는 엄격한 모더레이
|
|
|
763
763
|
id: "Indonesian"
|
|
764
764
|
};
|
|
765
765
|
function wn(e) {
|
|
766
|
-
let t = Cn[e] ?? "English", n =
|
|
766
|
+
let t = Cn[e] ?? "English", n = ue(e).name;
|
|
767
767
|
return t === n ? t : `${t} (${n})`;
|
|
768
768
|
}
|
|
769
769
|
function Tn(e) {
|
|
@@ -813,18 +813,18 @@ var kn = {
|
|
|
813
813
|
none: ""
|
|
814
814
|
};
|
|
815
815
|
function An(e, t = "ko") {
|
|
816
|
-
return !e || e === "none" ? "" : e in kn ?
|
|
816
|
+
return !e || e === "none" ? "" : e in kn ? M(t, `moderationPrompt.categories.${e}`) : e;
|
|
817
817
|
}
|
|
818
818
|
function jn(e) {
|
|
819
819
|
let t = e.locale ?? "ko";
|
|
820
820
|
if (e.via === "local" && e.localHit) {
|
|
821
821
|
let n = e.localHit.trim();
|
|
822
|
-
return n.length > 0 && n.length <= 12 ?
|
|
822
|
+
return n.length > 0 && n.length <= 12 ? M(t, "moderationPrompt.localHit", { hit: n }) : M(t, "moderationPrompt.localGeneric");
|
|
823
823
|
}
|
|
824
824
|
let n = (e.reason || "").trim();
|
|
825
825
|
if (n) return n;
|
|
826
826
|
let r = e.category ? An(e.category, t) : "";
|
|
827
|
-
return r ?
|
|
827
|
+
return r ? M(t, "moderationPrompt.categoryBlocked", { category: r }) : M(t, "moderationPrompt.genericBlocked");
|
|
828
828
|
}
|
|
829
829
|
var Mn = [
|
|
830
830
|
"씨발",
|
|
@@ -934,7 +934,7 @@ function Un() {
|
|
|
934
934
|
responseMimeType: "application/json",
|
|
935
935
|
responseSchema: Ye.object({ properties: { locale: Ye.enumString({ enum: T.map((e) => e.code) }) } })
|
|
936
936
|
}
|
|
937
|
-
}).generateContent(JSON.stringify({ text: n.slice(0, Rn) })), In), a =
|
|
937
|
+
}).generateContent(JSON.stringify({ text: n.slice(0, Rn) })), In), a = F(JSON.parse(i.response.text())?.locale);
|
|
938
938
|
if (!a) throw Error("Could not identify the original language. Please try translating again.");
|
|
939
939
|
return a;
|
|
940
940
|
}
|
|
@@ -1080,7 +1080,7 @@ function qn(e, t, n) {
|
|
|
1080
1080
|
commentWriteRole: t.commentWriteRole ?? "user",
|
|
1081
1081
|
allowedStaffUids: Array.isArray(t.allowedStaffUids) ? t.allowedStaffUids : [],
|
|
1082
1082
|
allowedManagerUids: Array.isArray(t.allowedManagerUids) ? t.allowedManagerUids : [],
|
|
1083
|
-
locale:
|
|
1083
|
+
locale: F(t.locale) ?? "",
|
|
1084
1084
|
autoTranslate: t.autoTranslate === !0,
|
|
1085
1085
|
autoTranslatePosts: t.autoTranslatePosts === !0,
|
|
1086
1086
|
translationLocales: mt(t.translationLocales),
|
|
@@ -1089,7 +1089,7 @@ function qn(e, t, n) {
|
|
|
1089
1089
|
};
|
|
1090
1090
|
}
|
|
1091
1091
|
function Jn() {
|
|
1092
|
-
let e = () =>
|
|
1092
|
+
let e = () => P(), t = Z(), r = Me(), { isSignedIn: i, isAdmin: a, isStaff: s, user: c } = Wt(), { t: l, locale: u } = N(), { translateEntries: d } = Un(), f = I(() => K(S(t, e()), G("order", "asc"))), { data: m, pending: h } = ke(f, { ssrKey: p(e(), "boards") }), g = I(() => m.value.map((e, t) => qn(e.id, e, t))), _ = g, v = I(() => g.value.filter((e) => e.visibility !== "hidden")), y = v;
|
|
1093
1093
|
function b(e, t) {
|
|
1094
1094
|
if (!e) return;
|
|
1095
1095
|
let n = g.value.find((t) => t.id === e);
|
|
@@ -1105,20 +1105,20 @@ function Jn() {
|
|
|
1105
1105
|
function D(e) {
|
|
1106
1106
|
return e ? g.value.find((t) => t.id === e)?.visibility ?? "public" : "public";
|
|
1107
1107
|
}
|
|
1108
|
-
let
|
|
1109
|
-
function
|
|
1108
|
+
let ee = D;
|
|
1109
|
+
function O(e) {
|
|
1110
1110
|
return D(e) === "hidden";
|
|
1111
1111
|
}
|
|
1112
|
-
let
|
|
1112
|
+
let k = O;
|
|
1113
1113
|
function A(e) {
|
|
1114
1114
|
if (e) return g.value.find((t) => t.id === e);
|
|
1115
1115
|
}
|
|
1116
1116
|
Nt((e) => A(e));
|
|
1117
|
-
function
|
|
1117
|
+
function j(e) {
|
|
1118
1118
|
return At(c.value?.uid, a.value, s.value, e ? A(e) : void 0);
|
|
1119
1119
|
}
|
|
1120
|
-
let
|
|
1121
|
-
function
|
|
1120
|
+
let te = I(() => g.value.filter((e) => j(e.id)));
|
|
1121
|
+
function ne(e, t) {
|
|
1122
1122
|
return {
|
|
1123
1123
|
label: e.label.trim(),
|
|
1124
1124
|
description: (e.description ?? "").trim(),
|
|
@@ -1129,17 +1129,17 @@ function Jn() {
|
|
|
1129
1129
|
commentWriteRole: e.commentWriteRole ?? "user",
|
|
1130
1130
|
allowedStaffUids: e.allowedStaffUids ?? [],
|
|
1131
1131
|
allowedManagerUids: e.allowedManagerUids ?? [],
|
|
1132
|
-
locale:
|
|
1132
|
+
locale: F(e.locale) ?? "",
|
|
1133
1133
|
autoTranslate: e.autoTranslate === !0,
|
|
1134
1134
|
autoTranslatePosts: e.autoTranslatePosts === !0,
|
|
1135
1135
|
translationLocales: mt(e.translationLocales),
|
|
1136
1136
|
...e.i18n ? { i18n: e.i18n } : {},
|
|
1137
1137
|
...e.i18nSource ? { i18nSource: e.i18nSource } : {},
|
|
1138
1138
|
order: t,
|
|
1139
|
-
updatedAt:
|
|
1139
|
+
updatedAt: q()
|
|
1140
1140
|
};
|
|
1141
1141
|
}
|
|
1142
|
-
async function
|
|
1142
|
+
async function re(e) {
|
|
1143
1143
|
if (!n()) return e;
|
|
1144
1144
|
let t = e.label.trim(), r = (e.description ?? "").trim();
|
|
1145
1145
|
if (!t) return e;
|
|
@@ -1176,40 +1176,40 @@ function Jn() {
|
|
|
1176
1176
|
}
|
|
1177
1177
|
};
|
|
1178
1178
|
}
|
|
1179
|
-
async function
|
|
1179
|
+
async function M(n, r = n.order ?? 0) {
|
|
1180
1180
|
if (!i.value) throw Error(l("boardSettings.signInRequired"));
|
|
1181
1181
|
let a = n.id.trim(), o = n.label.trim();
|
|
1182
1182
|
if (!a || !o) throw Error(l("boardSettings.idAndNameRequired"));
|
|
1183
|
-
let s = Kn(n.visibility), c =
|
|
1183
|
+
let s = Kn(n.visibility), c = ne({
|
|
1184
1184
|
...n,
|
|
1185
1185
|
label: o,
|
|
1186
1186
|
visibility: s
|
|
1187
1187
|
}, r);
|
|
1188
1188
|
await xn(t, e(), a, c);
|
|
1189
1189
|
}
|
|
1190
|
-
let
|
|
1191
|
-
async function
|
|
1190
|
+
let ie = M;
|
|
1191
|
+
async function ae(e) {
|
|
1192
1192
|
if (!i.value) throw Error(l("boardSettings.signInRequired"));
|
|
1193
1193
|
for (let t of e) if (!t.id.trim() || !t.label.trim()) throw Error(l("boardSettings.idAndNameRequired"));
|
|
1194
|
-
for (let [t, n] of e.entries()) await
|
|
1194
|
+
for (let [t, n] of e.entries()) await M(n, t);
|
|
1195
1195
|
}
|
|
1196
|
-
let
|
|
1197
|
-
async function
|
|
1196
|
+
let oe = ae;
|
|
1197
|
+
async function se(n) {
|
|
1198
1198
|
if (!i.value) throw Error(l("boardSettings.signInRequired"));
|
|
1199
1199
|
let a = n.trim();
|
|
1200
1200
|
if (!a) throw Error(l("boardSettings.deleteIdRequired"));
|
|
1201
1201
|
for (;;) {
|
|
1202
|
-
let n = await
|
|
1202
|
+
let n = await H(K(o(t, e()), X("boardId", "==", a), U(25)));
|
|
1203
1203
|
if (n.empty) break;
|
|
1204
1204
|
for (let i of n.docs) await cn(t, We(r), e(), i.id);
|
|
1205
1205
|
}
|
|
1206
|
-
await
|
|
1206
|
+
await ge(w(t, e(), n));
|
|
1207
1207
|
}
|
|
1208
|
-
let
|
|
1209
|
-
async function
|
|
1208
|
+
let ce = se;
|
|
1209
|
+
async function le() {
|
|
1210
1210
|
return Promise.resolve();
|
|
1211
1211
|
}
|
|
1212
|
-
async function
|
|
1212
|
+
async function ue(e) {
|
|
1213
1213
|
let t = e.trim();
|
|
1214
1214
|
if (!t) throw Error(l("boardSettings.nameRequired"));
|
|
1215
1215
|
if (!i.value) throw Error(l("boardSettings.signInRequired"));
|
|
@@ -1217,7 +1217,7 @@ function Jn() {
|
|
|
1217
1217
|
if (n) return n.id;
|
|
1218
1218
|
let r = E(t) || `board-${Date.now()}`, a = r, o = 2, s = new Set(g.value.map((e) => e.id));
|
|
1219
1219
|
for (; s.has(a);) a = `${r}-${o++}`;
|
|
1220
|
-
return await
|
|
1220
|
+
return await M({
|
|
1221
1221
|
id: a,
|
|
1222
1222
|
label: t,
|
|
1223
1223
|
visibility: "public",
|
|
@@ -1234,27 +1234,27 @@ function Jn() {
|
|
|
1234
1234
|
boardLabel: b,
|
|
1235
1235
|
boardDescription: C,
|
|
1236
1236
|
boardVisibility: D,
|
|
1237
|
-
isBoardHidden:
|
|
1237
|
+
isBoardHidden: O,
|
|
1238
1238
|
getBoard: A,
|
|
1239
|
-
canManageBoard:
|
|
1240
|
-
managedBoards:
|
|
1239
|
+
canManageBoard: j,
|
|
1240
|
+
managedBoards: te,
|
|
1241
1241
|
categories: _,
|
|
1242
1242
|
publicCategories: y,
|
|
1243
1243
|
categoryLabel: x,
|
|
1244
1244
|
categoryDescription: T,
|
|
1245
|
-
categoryVisibility:
|
|
1246
|
-
isCategoryHidden:
|
|
1245
|
+
categoryVisibility: ee,
|
|
1246
|
+
isCategoryHidden: k,
|
|
1247
1247
|
settingsPending: h,
|
|
1248
|
-
ensureSettings:
|
|
1249
|
-
addBoard:
|
|
1250
|
-
addCategory:
|
|
1251
|
-
saveBoard:
|
|
1252
|
-
saveCategory:
|
|
1253
|
-
translateBoard:
|
|
1254
|
-
saveBoards:
|
|
1255
|
-
saveCategories:
|
|
1256
|
-
deleteBoard:
|
|
1257
|
-
deleteCategory:
|
|
1248
|
+
ensureSettings: le,
|
|
1249
|
+
addBoard: ue,
|
|
1250
|
+
addCategory: ue,
|
|
1251
|
+
saveBoard: M,
|
|
1252
|
+
saveCategory: ie,
|
|
1253
|
+
translateBoard: re,
|
|
1254
|
+
saveBoards: ae,
|
|
1255
|
+
saveCategories: oe,
|
|
1256
|
+
deleteBoard: se,
|
|
1257
|
+
deleteCategory: ce,
|
|
1258
1258
|
DEFAULT_BOARDS: Wn,
|
|
1259
1259
|
DEFAULT_CATEGORIES: Gn
|
|
1260
1260
|
};
|
|
@@ -1268,12 +1268,12 @@ function Xn(e) {
|
|
|
1268
1268
|
return t === "permission-denied" || t === "firestore/permission-denied";
|
|
1269
1269
|
}
|
|
1270
1270
|
function Zn(e, t) {
|
|
1271
|
-
let n =
|
|
1272
|
-
if (!n) throw Error(
|
|
1271
|
+
let n = z(e)?.trim();
|
|
1272
|
+
if (!n) throw Error(M(t, "posts.boardIdRequired"));
|
|
1273
1273
|
return n;
|
|
1274
1274
|
}
|
|
1275
1275
|
function Qn(e) {
|
|
1276
|
-
let t = Z(), n = Me(), { isBoardHidden: r, getBoard: i } = Jn(), { user: a, canManageBoard: c } = Wt(), { t: l, locale: u } =
|
|
1276
|
+
let t = Z(), n = Me(), { isBoardHidden: r, getBoard: i } = Jn(), { user: a, canManageBoard: c } = Wt(), { t: l, locale: u } = N(), d = () => P(), f = () => Zn(e, u.value), p = () => o(t, d()), m = (e) => y(t, d(), e), h = (e) => s(t, d(), e);
|
|
1277
1277
|
function g(e, t, n) {
|
|
1278
1278
|
return {
|
|
1279
1279
|
id: e,
|
|
@@ -1301,15 +1301,15 @@ function Qn(e) {
|
|
|
1301
1301
|
if (!e.title?.trim()) throw Error(l("posts.titleRequired"));
|
|
1302
1302
|
}
|
|
1303
1303
|
function x() {
|
|
1304
|
-
return
|
|
1304
|
+
return ve(p()).id;
|
|
1305
1305
|
}
|
|
1306
1306
|
function S(e) {
|
|
1307
1307
|
return Yt(t, d(), f(), e, a.value?.uid, c(f()));
|
|
1308
1308
|
}
|
|
1309
1309
|
async function C(e = {}) {
|
|
1310
1310
|
let t = e.pageSize ?? 20, n = [X("boardId", "==", f()), X("isPublished", "==", !0)];
|
|
1311
|
-
e.publicOnly !== !1 && n.push(X("listed", "==", !0)), n.push(
|
|
1312
|
-
let r = await
|
|
1311
|
+
e.publicOnly !== !1 && n.push(X("listed", "==", !0)), n.push(G("createdAt", "desc")), e.cursor && n.push(J(e.cursor)), n.push(U(t + 1));
|
|
1312
|
+
let r = await H(K(p(), ...n)), i = r.docs.slice(0, t);
|
|
1313
1313
|
return {
|
|
1314
1314
|
posts: i.map((e) => ({
|
|
1315
1315
|
id: e.id,
|
|
@@ -1320,7 +1320,7 @@ function Qn(e) {
|
|
|
1320
1320
|
};
|
|
1321
1321
|
}
|
|
1322
1322
|
async function w(e) {
|
|
1323
|
-
let [t, n] = await Promise.all([
|
|
1323
|
+
let [t, n] = await Promise.all([xe(m(e)), xe(h(e))]);
|
|
1324
1324
|
return t.exists() ? g(t.id, t.data(), n.exists() ? n.data() : void 0) : null;
|
|
1325
1325
|
}
|
|
1326
1326
|
async function T(e) {
|
|
@@ -1346,7 +1346,7 @@ function Qn(e) {
|
|
|
1346
1346
|
};
|
|
1347
1347
|
}
|
|
1348
1348
|
}
|
|
1349
|
-
async function
|
|
1349
|
+
async function ee(e) {
|
|
1350
1350
|
let t = e.trim(), n = Yn.get(`${f()}/${t}`);
|
|
1351
1351
|
if (n) return {
|
|
1352
1352
|
status: "ok",
|
|
@@ -1365,10 +1365,10 @@ function Qn(e) {
|
|
|
1365
1365
|
};
|
|
1366
1366
|
}
|
|
1367
1367
|
}
|
|
1368
|
-
async function
|
|
1368
|
+
async function O(e) {
|
|
1369
1369
|
return `${E(e.trim()) || "post"}-${x()}`;
|
|
1370
1370
|
}
|
|
1371
|
-
async function
|
|
1371
|
+
async function k(e) {
|
|
1372
1372
|
if (!e.createdAt) return {
|
|
1373
1373
|
previous: null,
|
|
1374
1374
|
next: null
|
|
@@ -1378,8 +1378,8 @@ function Qn(e) {
|
|
|
1378
1378
|
X("boardId", "==", f()),
|
|
1379
1379
|
X("isPublished", "==", !0),
|
|
1380
1380
|
...e.listed === !1 ? [] : [X("listed", "==", !0)],
|
|
1381
|
-
|
|
1382
|
-
], [n, r] = await Promise.all([
|
|
1381
|
+
G("createdAt", "desc")
|
|
1382
|
+
], [n, r] = await Promise.all([H(K(p(), ...t, J(e.createdAt), U(1))), H(K(p(), ...t, be(e.createdAt), Te(1)))]), i = (e) => {
|
|
1383
1383
|
let t = e.docs[0];
|
|
1384
1384
|
return t ? {
|
|
1385
1385
|
id: t.id,
|
|
@@ -1400,7 +1400,7 @@ function Qn(e) {
|
|
|
1400
1400
|
async function A(e) {
|
|
1401
1401
|
b(e);
|
|
1402
1402
|
let n = e.postId || x(), r = v(), i, a;
|
|
1403
|
-
r ? (i = n, a = un(e.content)) : (a = e.title.trim(), i = e.slug?.trim() || await
|
|
1403
|
+
r ? (i = n, a = un(e.content)) : (a = e.title.trim(), i = e.slug?.trim() || await O(a));
|
|
1404
1404
|
let o = _n(e.content, e.attachments), s = _(), c = Oe(t);
|
|
1405
1405
|
return c.set(m(n), {
|
|
1406
1406
|
boardId: f(),
|
|
@@ -1419,8 +1419,8 @@ function Qn(e) {
|
|
|
1419
1419
|
authorPhoto: e.authorPhoto,
|
|
1420
1420
|
moderationStatus: "approved",
|
|
1421
1421
|
moderationModel: e.moderationModel ?? null,
|
|
1422
|
-
createdAt:
|
|
1423
|
-
updatedAt:
|
|
1422
|
+
createdAt: q(),
|
|
1423
|
+
updatedAt: q(),
|
|
1424
1424
|
...e.translations ? {
|
|
1425
1425
|
i18n: e.translations.i18n,
|
|
1426
1426
|
i18nSource: e.translations.i18nSource
|
|
@@ -1433,63 +1433,63 @@ function Qn(e) {
|
|
|
1433
1433
|
} : {}
|
|
1434
1434
|
}), await c.commit(), Yn.set(`${f()}/${i}`, n), i;
|
|
1435
1435
|
}
|
|
1436
|
-
async function
|
|
1436
|
+
async function j(e, t) {
|
|
1437
1437
|
b(t);
|
|
1438
1438
|
let n = v() ? un(t.content) : t.title.trim(), r = _n(t.content, t.attachments), i = _();
|
|
1439
1439
|
await Promise.all([Y(m(e), {
|
|
1440
1440
|
title: n,
|
|
1441
1441
|
...r,
|
|
1442
|
-
previewImage: r.previewImage ? r.previewImage :
|
|
1443
|
-
videoUrl: r.videoUrl ? r.videoUrl :
|
|
1442
|
+
previewImage: r.previewImage ? r.previewImage : _e(),
|
|
1443
|
+
videoUrl: r.videoUrl ? r.videoUrl : _e(),
|
|
1444
1444
|
tags: t.tags ?? [],
|
|
1445
1445
|
listed: i,
|
|
1446
1446
|
attachments: t.attachments ?? [],
|
|
1447
|
-
updatedAt:
|
|
1447
|
+
updatedAt: q(),
|
|
1448
1448
|
...t.translations ? {
|
|
1449
1449
|
i18n: t.translations.i18n,
|
|
1450
1450
|
i18nSource: t.translations.i18nSource
|
|
1451
1451
|
} : {}
|
|
1452
|
-
}),
|
|
1452
|
+
}), De(h(e), {
|
|
1453
1453
|
content: t.content,
|
|
1454
1454
|
...t.translations ? t.translations.contentI18n ? {
|
|
1455
1455
|
i18n: t.translations.contentI18n,
|
|
1456
1456
|
i18nSource: t.translations.contentI18nSource
|
|
1457
1457
|
} : {
|
|
1458
|
-
i18n:
|
|
1459
|
-
i18nSource:
|
|
1458
|
+
i18n: _e(),
|
|
1459
|
+
i18nSource: _e()
|
|
1460
1460
|
} : {}
|
|
1461
1461
|
}, { merge: !0 })]);
|
|
1462
1462
|
}
|
|
1463
|
-
async function
|
|
1463
|
+
async function te(e, t) {
|
|
1464
1464
|
D(), await Promise.all([Y(m(e), {
|
|
1465
1465
|
i18n: t.i18n,
|
|
1466
1466
|
i18nSource: t.i18nSource,
|
|
1467
|
-
updatedAt:
|
|
1468
|
-
}),
|
|
1467
|
+
updatedAt: q()
|
|
1468
|
+
}), De(h(e), t.contentI18n ? {
|
|
1469
1469
|
i18n: t.contentI18n,
|
|
1470
1470
|
i18nSource: t.contentI18nSource
|
|
1471
1471
|
} : {
|
|
1472
|
-
i18n:
|
|
1473
|
-
i18nSource:
|
|
1472
|
+
i18n: _e(),
|
|
1473
|
+
i18nSource: _e()
|
|
1474
1474
|
}, { merge: !0 })]);
|
|
1475
1475
|
}
|
|
1476
|
-
async function
|
|
1476
|
+
async function ne(e) {
|
|
1477
1477
|
await Y(m(e), {
|
|
1478
1478
|
isPublished: !0,
|
|
1479
|
-
publishedAt:
|
|
1480
|
-
updatedAt:
|
|
1479
|
+
publishedAt: q(),
|
|
1480
|
+
updatedAt: q()
|
|
1481
1481
|
});
|
|
1482
1482
|
}
|
|
1483
|
-
async function
|
|
1483
|
+
async function re(e, t) {
|
|
1484
1484
|
await Y(m(e), t ? {
|
|
1485
1485
|
pinned: !0,
|
|
1486
|
-
pinnedAt:
|
|
1486
|
+
pinnedAt: q()
|
|
1487
1487
|
} : {
|
|
1488
|
-
pinned:
|
|
1489
|
-
pinnedAt:
|
|
1488
|
+
pinned: _e(),
|
|
1489
|
+
pinnedAt: _e()
|
|
1490
1490
|
});
|
|
1491
1491
|
}
|
|
1492
|
-
async function
|
|
1492
|
+
async function M(e) {
|
|
1493
1493
|
await cn(t, We(n), d(), e);
|
|
1494
1494
|
for (let [t, n] of Yn) n === e && Yn.delete(t);
|
|
1495
1495
|
}
|
|
@@ -1498,24 +1498,24 @@ function Qn(e) {
|
|
|
1498
1498
|
getPosts: C,
|
|
1499
1499
|
getPost: w,
|
|
1500
1500
|
getPostBySlug: T,
|
|
1501
|
-
resolvePostIdBySlug:
|
|
1502
|
-
resolveUniqueSlug:
|
|
1503
|
-
getAdjacentPosts:
|
|
1501
|
+
resolvePostIdBySlug: ee,
|
|
1502
|
+
resolveUniqueSlug: O,
|
|
1503
|
+
getAdjacentPosts: k,
|
|
1504
1504
|
createPost: A,
|
|
1505
|
-
updatePost:
|
|
1506
|
-
savePostTranslations:
|
|
1507
|
-
publishPost:
|
|
1508
|
-
setPostPinned:
|
|
1509
|
-
deletePost:
|
|
1505
|
+
updatePost: j,
|
|
1506
|
+
savePostTranslations: te,
|
|
1507
|
+
publishPost: ne,
|
|
1508
|
+
setPostPinned: re,
|
|
1509
|
+
deletePost: M
|
|
1510
1510
|
};
|
|
1511
1511
|
}
|
|
1512
1512
|
var $n = 10, er = 10;
|
|
1513
1513
|
function tr(e, t = {}) {
|
|
1514
|
-
let n = Z(), { isAdmin: r, user: i, canManageBoard: a } = Wt(), s = () =>
|
|
1514
|
+
let n = Z(), { isAdmin: r, user: i, canManageBoard: a } = Wt(), s = () => P(), c = t.pageSize ?? $n, l = I(() => i.value?.uid ?? ""), u = I(() => Zn(e)), d = () => o(n, s()), f = I(() => t.publicOnly === void 0 ? !(r.value || a(u.value)) : typeof t.publicOnly == "boolean" ? t.publicOnly : t.publicOnly.value), p = R([]), m = R([]), h = R([]), g = R([]), _ = R(!0), v = R(!0), y = R(!0), b = R(!1), x = R(""), S = null, C = null, w, T, E;
|
|
1515
1515
|
function D(e) {
|
|
1516
1516
|
return e.createdAt?.toMillis?.() ?? 0;
|
|
1517
1517
|
}
|
|
1518
|
-
let
|
|
1518
|
+
let ee = I(() => {
|
|
1519
1519
|
let e = new Set(g.value.map((e) => e.id)), t = /* @__PURE__ */ new Map();
|
|
1520
1520
|
for (let n of [
|
|
1521
1521
|
...m.value,
|
|
@@ -1524,12 +1524,12 @@ function tr(e, t = {}) {
|
|
|
1524
1524
|
]) n.id && !e.has(n.id) && t.set(n.id, n);
|
|
1525
1525
|
return [...t.values()].sort((e, t) => D(t) - D(e) || String(t.id).localeCompare(String(e.id)));
|
|
1526
1526
|
});
|
|
1527
|
-
function
|
|
1527
|
+
function O() {
|
|
1528
1528
|
let e = [X("boardId", "==", u.value), X("isPublished", "==", !0)];
|
|
1529
1529
|
return f.value && e.push(X("listed", "==", !0)), e;
|
|
1530
1530
|
}
|
|
1531
|
-
function
|
|
1532
|
-
w?.(), w =
|
|
1531
|
+
function k() {
|
|
1532
|
+
w?.(), w = W(K(d(), ...O(), G("createdAt", "desc"), G(V(), "desc"), U(c)), (e) => {
|
|
1533
1533
|
p.value = e.docs.map((e) => ({
|
|
1534
1534
|
id: e.id,
|
|
1535
1535
|
...e.data()
|
|
@@ -1539,7 +1539,7 @@ function tr(e, t = {}) {
|
|
|
1539
1539
|
});
|
|
1540
1540
|
}
|
|
1541
1541
|
function A() {
|
|
1542
|
-
E?.(), E =
|
|
1542
|
+
E?.(), E = W(K(d(), ...O(), X("pinned", "==", !0), G("pinnedAt", "desc"), U(er)), (e) => {
|
|
1543
1543
|
g.value = e.docs.map((e) => ({
|
|
1544
1544
|
id: e.id,
|
|
1545
1545
|
...e.data()
|
|
@@ -1548,14 +1548,14 @@ function tr(e, t = {}) {
|
|
|
1548
1548
|
console.error("[memi-board:postList] notice onSnapshot failed", e), g.value = [], _.value = !1;
|
|
1549
1549
|
});
|
|
1550
1550
|
}
|
|
1551
|
-
function
|
|
1551
|
+
function j() {
|
|
1552
1552
|
T?.();
|
|
1553
1553
|
let e = l.value;
|
|
1554
1554
|
if (!e) {
|
|
1555
1555
|
h.value = [];
|
|
1556
1556
|
return;
|
|
1557
1557
|
}
|
|
1558
|
-
T =
|
|
1558
|
+
T = W(K(d(), X("boardId", "==", u.value), X("authorUid", "==", e), X("isPublished", "==", !1), G("createdAt", "desc"), U(20)), (e) => {
|
|
1559
1559
|
h.value = e.docs.map((e) => ({
|
|
1560
1560
|
id: e.id,
|
|
1561
1561
|
...e.data()
|
|
@@ -1564,17 +1564,17 @@ function tr(e, t = {}) {
|
|
|
1564
1564
|
console.error("[memi-board:postList] own draft onSnapshot failed", e);
|
|
1565
1565
|
});
|
|
1566
1566
|
}
|
|
1567
|
-
async function
|
|
1567
|
+
async function te() {
|
|
1568
1568
|
if (!(b.value || !y.value || v.value)) {
|
|
1569
1569
|
b.value = !0, x.value = "";
|
|
1570
1570
|
try {
|
|
1571
1571
|
let e = C ?? S, t = [
|
|
1572
|
-
...
|
|
1573
|
-
|
|
1574
|
-
|
|
1572
|
+
...O(),
|
|
1573
|
+
G("createdAt", "desc"),
|
|
1574
|
+
G(V(), "desc"),
|
|
1575
1575
|
...e ? [J(e)] : [],
|
|
1576
|
-
|
|
1577
|
-
], n = await
|
|
1576
|
+
U(c + 1)
|
|
1577
|
+
], n = await H(K(d(), ...t)), r = n.docs.slice(0, c), i = r.map((e) => ({
|
|
1578
1578
|
id: e.id,
|
|
1579
1579
|
...e.data()
|
|
1580
1580
|
})), a = new Set([...m.value, ...p.value].map((e) => e.id));
|
|
@@ -1586,29 +1586,29 @@ function tr(e, t = {}) {
|
|
|
1586
1586
|
}
|
|
1587
1587
|
}
|
|
1588
1588
|
}
|
|
1589
|
-
function
|
|
1590
|
-
w?.(), p.value = [], m.value = [], S = null, C = null, y.value = !0, x.value = "", v.value = !0, g.value = [], _.value = !0,
|
|
1589
|
+
function ne() {
|
|
1590
|
+
w?.(), p.value = [], m.value = [], S = null, C = null, y.value = !0, x.value = "", v.value = !0, g.value = [], _.value = !0, k(), A(), j();
|
|
1591
1591
|
}
|
|
1592
|
-
return
|
|
1592
|
+
return B([
|
|
1593
1593
|
u,
|
|
1594
1594
|
f,
|
|
1595
1595
|
l
|
|
1596
|
-
],
|
|
1596
|
+
], ne, { immediate: !0 }), L(() => {
|
|
1597
1597
|
w?.(), E?.(), T?.();
|
|
1598
1598
|
}), {
|
|
1599
|
-
posts:
|
|
1599
|
+
posts: ee,
|
|
1600
1600
|
notices: g,
|
|
1601
|
-
postsPending:
|
|
1601
|
+
postsPending: I(() => v.value || _.value),
|
|
1602
1602
|
hasMore: y,
|
|
1603
1603
|
loadingMore: b,
|
|
1604
1604
|
loadError: x,
|
|
1605
|
-
loadMore:
|
|
1605
|
+
loadMore: te
|
|
1606
1606
|
};
|
|
1607
1607
|
}
|
|
1608
1608
|
function nr(e, t) {
|
|
1609
|
-
let n = Z(), r = () =>
|
|
1609
|
+
let n = Z(), r = () => P(), i = I(() => Zn(e)), a = I(() => typeof t == "string" ? t : t.value), o = I(() => y(n, r(), a.value)), c = I(() => s(n, r(), a.value)), { data: l, pending: u } = je(o), { data: d, pending: f } = je(c);
|
|
1610
1610
|
return {
|
|
1611
|
-
post:
|
|
1611
|
+
post: I(() => {
|
|
1612
1612
|
if (!l.value || l.value.boardId !== i.value) return null;
|
|
1613
1613
|
let e = d.value;
|
|
1614
1614
|
return {
|
|
@@ -1621,14 +1621,14 @@ function nr(e, t) {
|
|
|
1621
1621
|
contentI18nSource: dt(e?.i18nSource)
|
|
1622
1622
|
};
|
|
1623
1623
|
}),
|
|
1624
|
-
pending:
|
|
1624
|
+
pending: I(() => u.value || f.value)
|
|
1625
1625
|
};
|
|
1626
1626
|
}
|
|
1627
1627
|
//#endregion
|
|
1628
1628
|
//#region src/composables/useMemiBoardUserPosts.ts
|
|
1629
1629
|
var rr = 10;
|
|
1630
1630
|
function ir(e, t = {}) {
|
|
1631
|
-
let n = Z(), r = () =>
|
|
1631
|
+
let n = Z(), r = () => P(), i = () => o(n, r()), a = t.pageSize ?? rr, s = I(() => z(e)?.trim() || ""), c = R([]), l = R([]), u = R(!0), d = R(!0), f = R(!1), p = R(""), m = null, h = null, g;
|
|
1632
1632
|
function _(e) {
|
|
1633
1633
|
return {
|
|
1634
1634
|
id: e.id,
|
|
@@ -1638,7 +1638,7 @@ function ir(e, t = {}) {
|
|
|
1638
1638
|
function v(e) {
|
|
1639
1639
|
return e.createdAt?.toMillis?.() ?? 0;
|
|
1640
1640
|
}
|
|
1641
|
-
let y =
|
|
1641
|
+
let y = I(() => {
|
|
1642
1642
|
let e = /* @__PURE__ */ new Map();
|
|
1643
1643
|
for (let t of [...l.value, ...c.value]) t.id && e.set(t.id, t);
|
|
1644
1644
|
return [...e.values()].sort((e, t) => v(t) - v(e) || String(t.id).localeCompare(String(e.id)));
|
|
@@ -1655,7 +1655,7 @@ function ir(e, t = {}) {
|
|
|
1655
1655
|
u.value = !1;
|
|
1656
1656
|
return;
|
|
1657
1657
|
}
|
|
1658
|
-
g =
|
|
1658
|
+
g = W(K(i(), ...b(), G("createdAt", "desc"), G(V(), "desc"), U(a)), (e) => {
|
|
1659
1659
|
c.value = e.docs.map(_), m = e.docs.at(-1) ?? null, h || (d.value = e.docs.length >= a), u.value = !1;
|
|
1660
1660
|
}, (e) => {
|
|
1661
1661
|
console.error("[memi-board:userPosts] onSnapshot failed", e), p.value = e.message || String(e), u.value = !1;
|
|
@@ -1667,11 +1667,11 @@ function ir(e, t = {}) {
|
|
|
1667
1667
|
try {
|
|
1668
1668
|
let e = h ?? m, t = [
|
|
1669
1669
|
...b(),
|
|
1670
|
-
|
|
1671
|
-
|
|
1670
|
+
G("createdAt", "desc"),
|
|
1671
|
+
G(V(), "desc"),
|
|
1672
1672
|
...e ? [J(e)] : [],
|
|
1673
|
-
|
|
1674
|
-
], n = await
|
|
1673
|
+
U(a + 1)
|
|
1674
|
+
], n = await H(K(i(), ...t)), r = n.docs.slice(0, a), o = r.map(_), s = new Set([...l.value, ...c.value].map((e) => e.id));
|
|
1675
1675
|
l.value.push(...o.filter((e) => !s.has(e.id))), h = r.at(-1) ?? h, d.value = n.docs.length > a;
|
|
1676
1676
|
} catch (e) {
|
|
1677
1677
|
p.value = e.message || String(e), console.error("[memi-board:userPosts] loadMore failed", e);
|
|
@@ -1683,7 +1683,7 @@ function ir(e, t = {}) {
|
|
|
1683
1683
|
function C() {
|
|
1684
1684
|
g?.(), c.value = [], l.value = [], m = null, h = null, d.value = !0, p.value = "", u.value = !0, x();
|
|
1685
1685
|
}
|
|
1686
|
-
return
|
|
1686
|
+
return B(s, C, { immediate: !0 }), L(() => g?.()), {
|
|
1687
1687
|
posts: y,
|
|
1688
1688
|
postsPending: u,
|
|
1689
1689
|
hasMore: d,
|
|
@@ -1696,7 +1696,7 @@ function ir(e, t = {}) {
|
|
|
1696
1696
|
//#region src/composables/useMemiBoardUserComments.ts
|
|
1697
1697
|
var ar = 10;
|
|
1698
1698
|
function or(e, t = {}) {
|
|
1699
|
-
let n = Z(), r = () =>
|
|
1699
|
+
let n = Z(), r = () => P(), i = () => g(n, r()), a = t.pageSize ?? ar, o = I(() => z(e)?.trim() || ""), s = R([]), c = R([]), l = R(!0), u = R(!0), d = R(!1), f = R(""), p = null, m = null, h;
|
|
1700
1700
|
function _(e) {
|
|
1701
1701
|
return {
|
|
1702
1702
|
id: e.id,
|
|
@@ -1706,7 +1706,7 @@ function or(e, t = {}) {
|
|
|
1706
1706
|
function v(e) {
|
|
1707
1707
|
return e.createdAt?.toMillis?.() ?? 0;
|
|
1708
1708
|
}
|
|
1709
|
-
let y =
|
|
1709
|
+
let y = I(() => {
|
|
1710
1710
|
let e = /* @__PURE__ */ new Map();
|
|
1711
1711
|
for (let t of [...c.value, ...s.value]) t.id && e.set(t.id, t);
|
|
1712
1712
|
return [...e.values()].sort((e, t) => v(t) - v(e) || String(t.id).localeCompare(String(e.id)));
|
|
@@ -1719,7 +1719,7 @@ function or(e, t = {}) {
|
|
|
1719
1719
|
l.value = !1;
|
|
1720
1720
|
return;
|
|
1721
1721
|
}
|
|
1722
|
-
h =
|
|
1722
|
+
h = W(K(i(), ...b(), G("createdAt", "desc"), G(V(), "desc"), U(a)), (e) => {
|
|
1723
1723
|
s.value = e.docs.map(_), p = e.docs.at(-1) ?? null, m || (u.value = e.docs.length >= a), l.value = !1;
|
|
1724
1724
|
}, (e) => {
|
|
1725
1725
|
console.error("[memi-board:userComments] onSnapshot failed", e), f.value = e.message || String(e), l.value = !1;
|
|
@@ -1731,11 +1731,11 @@ function or(e, t = {}) {
|
|
|
1731
1731
|
try {
|
|
1732
1732
|
let e = m ?? p, t = [
|
|
1733
1733
|
...b(),
|
|
1734
|
-
|
|
1735
|
-
|
|
1734
|
+
G("createdAt", "desc"),
|
|
1735
|
+
G(V(), "desc"),
|
|
1736
1736
|
...e ? [J(e)] : [],
|
|
1737
|
-
|
|
1738
|
-
], n = await
|
|
1737
|
+
U(a + 1)
|
|
1738
|
+
], n = await H(K(i(), ...t)), r = n.docs.slice(0, a), o = r.map(_), l = new Set([...c.value, ...s.value].map((e) => e.id));
|
|
1739
1739
|
c.value.push(...o.filter((e) => !l.has(e.id))), m = r.at(-1) ?? m, u.value = n.docs.length > a;
|
|
1740
1740
|
} catch (e) {
|
|
1741
1741
|
f.value = e.message || String(e), console.error("[memi-board:userComments] loadMore failed", e);
|
|
@@ -1747,7 +1747,7 @@ function or(e, t = {}) {
|
|
|
1747
1747
|
function C() {
|
|
1748
1748
|
h?.(), s.value = [], c.value = [], p = null, m = null, u.value = !0, f.value = "", l.value = !0, x();
|
|
1749
1749
|
}
|
|
1750
|
-
return
|
|
1750
|
+
return B(o, C, { immediate: !0 }), L(() => h?.()), {
|
|
1751
1751
|
comments: y,
|
|
1752
1752
|
commentsPending: l,
|
|
1753
1753
|
hasMore: u,
|
|
@@ -1760,10 +1760,10 @@ function or(e, t = {}) {
|
|
|
1760
1760
|
//#region src/composables/useMemiBoardCommentFeed.ts
|
|
1761
1761
|
var sr = 10;
|
|
1762
1762
|
function cr(e = "latest", t = {}) {
|
|
1763
|
-
let n = Z(), r = () =>
|
|
1764
|
-
let e = Math.floor(Number(
|
|
1763
|
+
let n = Z(), r = () => P(), i = () => g(n, r()), a = I(() => {
|
|
1764
|
+
let e = Math.floor(Number(z(t.pageSize)));
|
|
1765
1765
|
return Number.isFinite(e) && e > 0 ? e : sr;
|
|
1766
|
-
}), o =
|
|
1766
|
+
}), o = I(() => z(e) === "likes" ? "likes" : "latest"), s = R([]), c = R([]), l = R(!0), u = R(!0), d = R(!1), f = R(""), p = null, m = null, h;
|
|
1767
1767
|
function _(e) {
|
|
1768
1768
|
return {
|
|
1769
1769
|
id: e.id,
|
|
@@ -1780,7 +1780,7 @@ function cr(e = "latest", t = {}) {
|
|
|
1780
1780
|
}
|
|
1781
1781
|
return v(t) - v(e) || String(t.id).localeCompare(String(e.id));
|
|
1782
1782
|
}
|
|
1783
|
-
let b =
|
|
1783
|
+
let b = I(() => {
|
|
1784
1784
|
let e = /* @__PURE__ */ new Map();
|
|
1785
1785
|
for (let t of [...c.value, ...s.value]) t.id && e.set(t.id, t);
|
|
1786
1786
|
return [...e.values()].sort(y);
|
|
@@ -1788,17 +1788,17 @@ function cr(e = "latest", t = {}) {
|
|
|
1788
1788
|
function x() {
|
|
1789
1789
|
return o.value === "likes" ? [
|
|
1790
1790
|
X("listed", "==", !0),
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1791
|
+
G("likeCount", "desc"),
|
|
1792
|
+
G("createdAt", "desc"),
|
|
1793
|
+
G(V(), "desc")
|
|
1794
1794
|
] : [
|
|
1795
1795
|
X("listed", "==", !0),
|
|
1796
|
-
|
|
1797
|
-
|
|
1796
|
+
G("createdAt", "desc"),
|
|
1797
|
+
G(V(), "desc")
|
|
1798
1798
|
];
|
|
1799
1799
|
}
|
|
1800
1800
|
function S() {
|
|
1801
|
-
h?.(), h =
|
|
1801
|
+
h?.(), h = W(K(i(), ...x(), U(a.value)), (e) => {
|
|
1802
1802
|
s.value = e.docs.map(_), p = e.docs.at(-1) ?? null, m || (u.value = e.docs.length >= a.value), l.value = !1;
|
|
1803
1803
|
}, (e) => {
|
|
1804
1804
|
console.error("[memi-board:commentFeed] onSnapshot failed", e), f.value = e.message || String(e), l.value = !1;
|
|
@@ -1808,7 +1808,7 @@ function cr(e = "latest", t = {}) {
|
|
|
1808
1808
|
if (!(d.value || !u.value || l.value)) {
|
|
1809
1809
|
d.value = !0, f.value = "";
|
|
1810
1810
|
try {
|
|
1811
|
-
let e = m ?? p, t = await
|
|
1811
|
+
let e = m ?? p, t = await H(K(i(), ...x(), ...e ? [J(e)] : [], U(a.value + 1))), n = t.docs.slice(0, a.value), r = n.map(_), o = new Set([...c.value, ...s.value].map((e) => e.id));
|
|
1812
1812
|
c.value.push(...r.filter((e) => !o.has(e.id))), m = n.at(-1) ?? m, u.value = t.docs.length > a.value;
|
|
1813
1813
|
} catch (e) {
|
|
1814
1814
|
f.value = e.message || String(e), console.error("[memi-board:commentFeed] loadMore failed", e);
|
|
@@ -1820,7 +1820,7 @@ function cr(e = "latest", t = {}) {
|
|
|
1820
1820
|
function w() {
|
|
1821
1821
|
h?.(), s.value = [], c.value = [], p = null, m = null, u.value = !0, f.value = "", l.value = !0, S();
|
|
1822
1822
|
}
|
|
1823
|
-
return
|
|
1823
|
+
return B([o, a], w, { immediate: !0 }), L(() => h?.()), {
|
|
1824
1824
|
comments: b,
|
|
1825
1825
|
commentsPending: l,
|
|
1826
1826
|
hasMore: u,
|
|
@@ -1835,7 +1835,7 @@ function cr(e = "latest", t = {}) {
|
|
|
1835
1835
|
var lr = 100, ur = /* @__PURE__ */ new Map();
|
|
1836
1836
|
function $(e) {
|
|
1837
1837
|
let t = ur.get(e);
|
|
1838
|
-
return t || (t =
|
|
1838
|
+
return t || (t = pe({
|
|
1839
1839
|
text: "",
|
|
1840
1840
|
sentiment: null,
|
|
1841
1841
|
loaded: !1,
|
|
@@ -1845,22 +1845,22 @@ function $(e) {
|
|
|
1845
1845
|
}), ur.set(e, t)), t;
|
|
1846
1846
|
}
|
|
1847
1847
|
function dr(e) {
|
|
1848
|
-
let t = Z(), n = () =>
|
|
1848
|
+
let t = Z(), n = () => P(), { user: r } = Wt(), { t: i, formatNumber: a } = N(), o = I(() => z(e)), s = I(() => `${r.value?.uid ?? ""}:${o.value}`), c = I(() => {
|
|
1849
1849
|
let e = r.value?.uid, i = o.value;
|
|
1850
1850
|
return !e || !i ? null : f(t, n(), e, i);
|
|
1851
|
-
}), l =
|
|
1851
|
+
}), l = I({
|
|
1852
1852
|
get: () => $(s.value).text,
|
|
1853
1853
|
set: (e) => {
|
|
1854
1854
|
$(s.value).text = e;
|
|
1855
1855
|
}
|
|
1856
|
-
}), u =
|
|
1856
|
+
}), u = I(() => $(s.value).sentiment), d = I(() => $(s.value).loaded), p = I(() => $(s.value).pending), m = I(() => $(s.value).saving), h = I(() => $(s.value).error);
|
|
1857
1857
|
async function g() {
|
|
1858
1858
|
let e = c.value;
|
|
1859
1859
|
if (!e) return;
|
|
1860
1860
|
let t = $(s.value);
|
|
1861
1861
|
t.pending = !0, t.error = "";
|
|
1862
1862
|
try {
|
|
1863
|
-
let n = (await
|
|
1863
|
+
let n = (await xe(e)).data();
|
|
1864
1864
|
t.text = n ? n.text ?? "" : "", t.sentiment = n ? n.sentiment ?? null : null, t.loaded = !0;
|
|
1865
1865
|
} catch (e) {
|
|
1866
1866
|
t.error = e.message || String(e), console.error("[memi-board:authorMemo] load failed", e);
|
|
@@ -1876,10 +1876,10 @@ function dr(e) {
|
|
|
1876
1876
|
let o = $(s.value);
|
|
1877
1877
|
o.saving = !0, o.error = "";
|
|
1878
1878
|
try {
|
|
1879
|
-
await
|
|
1879
|
+
await De(n, {
|
|
1880
1880
|
text: r,
|
|
1881
1881
|
sentiment: t,
|
|
1882
|
-
updatedAt:
|
|
1882
|
+
updatedAt: q()
|
|
1883
1883
|
}), o.text = r, o.sentiment = t, o.loaded = !0;
|
|
1884
1884
|
} catch (e) {
|
|
1885
1885
|
throw o.error = e.message || String(e), console.error("[memi-board:authorMemo] save failed", e), e;
|
|
@@ -1893,7 +1893,7 @@ function dr(e) {
|
|
|
1893
1893
|
let t = $(s.value);
|
|
1894
1894
|
t.saving = !0, t.error = "";
|
|
1895
1895
|
try {
|
|
1896
|
-
await
|
|
1896
|
+
await ge(e), t.text = "", t.sentiment = null, t.loaded = !0;
|
|
1897
1897
|
} catch (e) {
|
|
1898
1898
|
throw t.error = e.message || String(e), console.error("[memi-board:authorMemo] remove failed", e), e;
|
|
1899
1899
|
} finally {
|
|
@@ -1914,7 +1914,7 @@ function dr(e) {
|
|
|
1914
1914
|
}
|
|
1915
1915
|
//#endregion
|
|
1916
1916
|
//#region src/composables/useMemiBoardWritingAssistant.ts
|
|
1917
|
-
var fr =
|
|
1917
|
+
var fr = 20, pr = 864e5, mr = 200, hr = {
|
|
1918
1918
|
proofread: "맞춤법, 띄어쓰기, 문법 오류만 고쳐라. 의미와 말투는 바꾸지 마라.",
|
|
1919
1919
|
polish: "뜻과 작성자의 말투를 유지하면서 더 자연스럽고 읽기 좋은 문장으로 다듬어라.",
|
|
1920
1920
|
continue: "앞의 맥락과 말투에 맞는 내용을 과장 없이 한두 문단 이어서 작성하라.",
|
|
@@ -1952,7 +1952,7 @@ function yr(e) {
|
|
|
1952
1952
|
return !e || typeof e != "object" ? null : "toMillis" in e && typeof e.toMillis == "function" ? e.toMillis() : null;
|
|
1953
1953
|
}
|
|
1954
1954
|
function br(e = {}) {
|
|
1955
|
-
let t =
|
|
1955
|
+
let t = N(), n = I(() => F(z(e.locale)) ?? t.locale.value), r = (e, t) => M(n.value, e, t), i = Me(), a = Z(), o = Ae(), s = v(), { translateEntries: c, translateHtml: l, detectSourceLocale: u } = Un();
|
|
1956
1956
|
function d(e, t) {
|
|
1957
1957
|
let n = yr(e.aiWritingWindowAt), r = n != null && t - n < pr, i = Math.max(0, Math.floor(Number(e.aiWritingCount) || 0)), a = Math.max(0, Math.floor(Number(e.aiWritingPending) || 0));
|
|
1958
1958
|
return {
|
|
@@ -1965,35 +1965,35 @@ function br(e = {}) {
|
|
|
1965
1965
|
function f(e, t) {
|
|
1966
1966
|
let n = e + pr, i = Math.max(1, Math.ceil((n - t) / 36e5));
|
|
1967
1967
|
return Error(r("writingAssistant.dailyLimit", {
|
|
1968
|
-
limit:
|
|
1968
|
+
limit: 20,
|
|
1969
1969
|
hours: i
|
|
1970
1970
|
}));
|
|
1971
1971
|
}
|
|
1972
1972
|
async function p(e) {
|
|
1973
1973
|
let t = o.value?.uid;
|
|
1974
1974
|
if (!t) throw Error(r("writingAssistant.loginRequired"));
|
|
1975
|
-
await
|
|
1976
|
-
let i = h(a,
|
|
1975
|
+
await Ee(a, async (n) => {
|
|
1976
|
+
let i = h(a, P(), t), o = await n.get(i);
|
|
1977
1977
|
if (!o.exists()) throw Error(r("writingAssistant.userMissing"));
|
|
1978
1978
|
let s = o.data(), c = e(d(s, Date.now()), s);
|
|
1979
1979
|
c && n.update(i, {
|
|
1980
1980
|
...c,
|
|
1981
|
-
updatedAt:
|
|
1981
|
+
updatedAt: q()
|
|
1982
1982
|
});
|
|
1983
1983
|
});
|
|
1984
1984
|
}
|
|
1985
1985
|
async function m() {
|
|
1986
1986
|
await p((e) => {
|
|
1987
|
-
if (e.active && e.windowAt != null && e.count + e.pending >=
|
|
1987
|
+
if (e.active && e.windowAt != null && e.count + e.pending >= 20) throw f(e.windowAt, Date.now());
|
|
1988
1988
|
return e.active ? { aiWritingPending: e.pending + 1 } : {
|
|
1989
1989
|
aiWritingCount: 0,
|
|
1990
1990
|
aiWritingPending: 1,
|
|
1991
|
-
aiWritingWindowAt:
|
|
1991
|
+
aiWritingWindowAt: q()
|
|
1992
1992
|
};
|
|
1993
1993
|
});
|
|
1994
1994
|
}
|
|
1995
1995
|
async function g() {
|
|
1996
|
-
await p((e) => !e.active || e.pending < 1 || e.count >=
|
|
1996
|
+
await p((e) => !e.active || e.pending < 1 || e.count >= 20 ? null : {
|
|
1997
1997
|
aiWritingCount: e.count + 1,
|
|
1998
1998
|
aiWritingPending: e.pending - 1
|
|
1999
1999
|
});
|
|
@@ -2088,7 +2088,7 @@ function br(e = {}) {
|
|
|
2088
2088
|
if (s) {
|
|
2089
2089
|
let e = {};
|
|
2090
2090
|
for (let [t, n] of Object.entries(m)) {
|
|
2091
|
-
let r =
|
|
2091
|
+
let r = F(t);
|
|
2092
2092
|
r && typeof n == "string" && n.trim() && (e[r] = { content: n.trim() });
|
|
2093
2093
|
}
|
|
2094
2094
|
let t = ft(d, { content: a }, e);
|
|
@@ -2135,7 +2135,7 @@ function br(e = {}) {
|
|
|
2135
2135
|
//#endregion
|
|
2136
2136
|
//#region src/utils/subscribeCommentRange.ts
|
|
2137
2137
|
function xr(e, t, n, r, i, a) {
|
|
2138
|
-
return
|
|
2138
|
+
return W(K(g(e, t), X("postId", "==", n), ...r.rootId ? [X("rootId", "==", r.rootId), X("isReply", "==", !0)] : [X("parentId", "==", null)], G("createdAt", "asc"), G(V(), "asc"), ...r.hasMore && r.cursor ? [ye(r.cursor)] : []), (e) => i(e.docs.map((e) => ({
|
|
2139
2139
|
...e.data(),
|
|
2140
2140
|
id: e.id
|
|
2141
2141
|
}))), a);
|
|
@@ -2150,107 +2150,115 @@ function Tr(e, { t, formatNumber: n }) {
|
|
|
2150
2150
|
return r;
|
|
2151
2151
|
}
|
|
2152
2152
|
function Er(e, t, r = {}) {
|
|
2153
|
-
let i = Z(), a = Me(), o = () =>
|
|
2154
|
-
async function
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2153
|
+
let i = Z(), a = Me(), o = () => P(), { isBoardHidden: s, getBoard: c } = Jn(), { translateComment: l } = br(), u, f = R(!1);
|
|
2154
|
+
async function p(e, t) {
|
|
2155
|
+
if (f.value = !1, !n()) return {};
|
|
2156
|
+
if (t?.i18nSource.body === e) return t;
|
|
2157
|
+
if (c(v.value)?.autoTranslatePosts !== !0) return {};
|
|
2158
|
+
if (u?.i18nSource.body !== e) try {
|
|
2159
|
+
u = await l({
|
|
2160
|
+
body: e,
|
|
2161
|
+
targets: pt(c(v.value))
|
|
2162
|
+
});
|
|
2163
|
+
} catch (e) {
|
|
2164
|
+
return import.meta.dev && console.warn("[memi-board] comment auto-translation skipped", e), f.value = !0, {};
|
|
2165
|
+
}
|
|
2166
|
+
return u;
|
|
2167
|
+
}
|
|
2168
|
+
let m = N(), { t: h } = m, _ = () => g(i, o()), v = I(() => z(e)), b = I(() => z(t)), S = () => !s(v.value), C = R([]), w = R(r.subscribe !== !1), T = R([]), E = R(!1), D = R(r.subscribe !== !1), ee = R(r.subscribe !== !1), O = null, k = 0, A = 0, j;
|
|
2161
2169
|
function te(e) {
|
|
2162
2170
|
return e.createdAt?.toMillis?.() ?? 0;
|
|
2163
2171
|
}
|
|
2164
|
-
let ne =
|
|
2172
|
+
let ne = I(() => {
|
|
2165
2173
|
let e = /* @__PURE__ */ new Map();
|
|
2166
|
-
for (let t of [...
|
|
2174
|
+
for (let t of [...C.value, ...T.value]) t.id && e.set(t.id, t);
|
|
2167
2175
|
return [...e.values()].sort((e, t) => te(e) - te(t) || String(e.id).localeCompare(String(t.id)));
|
|
2168
2176
|
});
|
|
2169
|
-
|
|
2177
|
+
B([b, v], async ([e]) => {
|
|
2170
2178
|
let t = ++k;
|
|
2171
|
-
if (
|
|
2172
|
-
|
|
2179
|
+
if (A++, E.value = !1, T.value = [], C.value = [], O = null, j?.(), j = void 0, D.value = r.subscribe !== !1, r.subscribe !== !1) {
|
|
2180
|
+
w.value = !0, ee.value = !0;
|
|
2173
2181
|
try {
|
|
2174
|
-
let n =
|
|
2182
|
+
let n = H(K(_(), X("postId", "==", e), G("createdAt", "desc"), G(V(), "desc")));
|
|
2175
2183
|
if (await Promise.all([n.then((e) => {
|
|
2176
2184
|
if (t !== k) return;
|
|
2177
2185
|
let n = e.docs.map((e) => ({
|
|
2178
2186
|
id: e.id,
|
|
2179
2187
|
...e.data()
|
|
2180
2188
|
}));
|
|
2181
|
-
|
|
2182
|
-
}),
|
|
2189
|
+
C.value = n.filter((e) => e.parentId === void 0);
|
|
2190
|
+
}), M()]), t !== k) return;
|
|
2183
2191
|
} finally {
|
|
2184
|
-
t === k && (
|
|
2192
|
+
t === k && (w.value = !1, ee.value = !1);
|
|
2185
2193
|
}
|
|
2186
2194
|
}
|
|
2187
2195
|
}, { immediate: !0 });
|
|
2188
2196
|
function re() {
|
|
2189
|
-
|
|
2190
|
-
let e = ++
|
|
2191
|
-
|
|
2197
|
+
j?.();
|
|
2198
|
+
let e = ++A;
|
|
2199
|
+
j = xr(i, o(), b.value, {
|
|
2192
2200
|
cursor: O,
|
|
2193
|
-
hasMore:
|
|
2201
|
+
hasMore: D.value
|
|
2194
2202
|
}, (t) => {
|
|
2195
|
-
e ===
|
|
2203
|
+
e === A && (T.value = t);
|
|
2196
2204
|
}, (e) => {
|
|
2197
2205
|
console.error("[memi-board:comments] onSnapshot failed", e);
|
|
2198
2206
|
});
|
|
2199
2207
|
}
|
|
2200
|
-
async function
|
|
2201
|
-
if (
|
|
2208
|
+
async function M() {
|
|
2209
|
+
if (E.value || !D.value) return;
|
|
2202
2210
|
let e = k;
|
|
2203
|
-
|
|
2211
|
+
E.value = !0;
|
|
2204
2212
|
try {
|
|
2205
2213
|
let t = [
|
|
2206
|
-
X("postId", "==",
|
|
2214
|
+
X("postId", "==", b.value),
|
|
2207
2215
|
X("parentId", "==", null),
|
|
2208
|
-
|
|
2209
|
-
|
|
2216
|
+
G("createdAt", "asc"),
|
|
2217
|
+
G(V(), "asc"),
|
|
2210
2218
|
...O ? [J(O)] : [],
|
|
2211
|
-
|
|
2212
|
-
], n = await
|
|
2219
|
+
U(11)
|
|
2220
|
+
], n = await H(K(_(), ...t));
|
|
2213
2221
|
if (e !== k) return;
|
|
2214
2222
|
let r = n.docs.slice(0, Sr), i = r.map((e) => ({
|
|
2215
2223
|
id: e.id,
|
|
2216
2224
|
...e.data()
|
|
2217
|
-
})), a = new Set(
|
|
2218
|
-
|
|
2225
|
+
})), a = new Set(T.value.map((e) => e.id));
|
|
2226
|
+
T.value.push(...i.filter((e) => !a.has(e.id))), O = r.at(-1) ?? O, D.value = n.size > Sr, re();
|
|
2219
2227
|
} finally {
|
|
2220
|
-
e === k && (
|
|
2228
|
+
e === k && (E.value = !1);
|
|
2221
2229
|
}
|
|
2222
2230
|
}
|
|
2223
|
-
|
|
2224
|
-
k++,
|
|
2231
|
+
L(() => {
|
|
2232
|
+
k++, A++, j?.();
|
|
2225
2233
|
});
|
|
2226
|
-
function
|
|
2227
|
-
return
|
|
2234
|
+
function ie() {
|
|
2235
|
+
return ve(_()).id;
|
|
2228
2236
|
}
|
|
2229
2237
|
function ae(e) {
|
|
2230
|
-
if (!e) return
|
|
2231
|
-
if (!/^[A-Za-z0-9]{10,128}$/.test(e)) throw Error(
|
|
2238
|
+
if (!e) return ve(_());
|
|
2239
|
+
if (!/^[A-Za-z0-9]{10,128}$/.test(e)) throw Error(h("commentForm.uploadFailed"));
|
|
2232
2240
|
return d(i, o(), e);
|
|
2233
2241
|
}
|
|
2234
2242
|
function oe(e, t) {
|
|
2235
|
-
let n = `${x(o(),
|
|
2236
|
-
return
|
|
2243
|
+
let n = `${x(o(), b.value)}/comment-images/${e}/`;
|
|
2244
|
+
return se(t).filter((e) => e.path.startsWith(n));
|
|
2237
2245
|
}
|
|
2238
|
-
async function
|
|
2239
|
-
let n = oe(t, e.images), r = Tr(e.body,
|
|
2246
|
+
async function le(e, t) {
|
|
2247
|
+
let n = oe(t, e.images), r = Tr(e.body, m);
|
|
2240
2248
|
return {
|
|
2241
|
-
postId:
|
|
2242
|
-
boardId:
|
|
2243
|
-
listed:
|
|
2249
|
+
postId: b.value,
|
|
2250
|
+
boardId: v.value,
|
|
2251
|
+
listed: S(),
|
|
2244
2252
|
body: r,
|
|
2245
|
-
...await
|
|
2253
|
+
...await p(r, e.translations),
|
|
2246
2254
|
authorUid: e.authorUid,
|
|
2247
2255
|
authorName: e.authorName,
|
|
2248
2256
|
authorPhoto: e.authorPhoto,
|
|
2249
2257
|
moderationStatus: "approved",
|
|
2250
2258
|
replyCount: 0,
|
|
2251
2259
|
likeCount: 0,
|
|
2252
|
-
createdAt:
|
|
2253
|
-
updatedAt:
|
|
2260
|
+
createdAt: q(),
|
|
2261
|
+
updatedAt: q(),
|
|
2254
2262
|
...n.length ? { images: n } : {}
|
|
2255
2263
|
};
|
|
2256
2264
|
}
|
|
@@ -2262,75 +2270,76 @@ function Er(e, t, r = {}) {
|
|
|
2262
2270
|
async function de(e) {
|
|
2263
2271
|
let t = Oe(i), n = ae(e.id);
|
|
2264
2272
|
t.set(n, {
|
|
2265
|
-
...await
|
|
2273
|
+
...await le(e, n.id),
|
|
2266
2274
|
parentId: null,
|
|
2267
2275
|
rootId: n.id,
|
|
2268
2276
|
depth: 0,
|
|
2269
2277
|
replyToUid: null,
|
|
2270
2278
|
replyToName: null,
|
|
2271
2279
|
isReply: !1
|
|
2272
|
-
}), t.update(y(i, o(),
|
|
2280
|
+
}), t.update(y(i, o(), b.value), { commentCount: we(1) }), await t.commit();
|
|
2273
2281
|
}
|
|
2274
|
-
async function
|
|
2275
|
-
if (!e.parent.id) throw Error(
|
|
2282
|
+
async function F(e) {
|
|
2283
|
+
if (!e.parent.id) throw Error(h("comments.replyTargetNotFound"));
|
|
2276
2284
|
let t = Oe(i), n = ae(e.id), r = e.parent.parentId == null ? e.parent.id : e.parent.rootId;
|
|
2277
|
-
if (!r) throw Error(
|
|
2285
|
+
if (!r) throw Error(h("comments.threadNotFound"));
|
|
2278
2286
|
let a = Math.min((e.parent.depth ?? 0) + 1, 2);
|
|
2279
2287
|
t.set(n, {
|
|
2280
|
-
...await
|
|
2288
|
+
...await le(e, n.id),
|
|
2281
2289
|
parentId: e.parent.id,
|
|
2282
2290
|
rootId: r,
|
|
2283
2291
|
depth: a,
|
|
2284
2292
|
replyToUid: e.parent.authorUid,
|
|
2285
2293
|
replyToName: e.parent.authorName,
|
|
2286
2294
|
isReply: !0
|
|
2287
|
-
}), t.update(d(i, o(), r), { replyCount:
|
|
2295
|
+
}), t.update(d(i, o(), r), { replyCount: we(1) }), t.update(y(i, o(), b.value), { commentCount: we(1) }), await t.commit();
|
|
2288
2296
|
}
|
|
2289
|
-
async function
|
|
2297
|
+
async function fe(e) {
|
|
2290
2298
|
if (!e.id) return;
|
|
2291
|
-
if (e.parentId == null && (e.replyCount ?? 0) > 0) throw Error(
|
|
2292
|
-
let t =
|
|
2299
|
+
if (e.parentId == null && (e.replyCount ?? 0) > 0) throw Error(h("comments.hasRepliesCannotDelete"));
|
|
2300
|
+
let t = ce(e.images, `${x(o(), b.value)}/comment-images/${e.id}/`);
|
|
2293
2301
|
await sn(i, o(), e.id);
|
|
2294
2302
|
let n = Oe(i);
|
|
2295
|
-
n.delete(d(i, o(), e.id)), e.parentId && e.rootId && n.update(d(i, o(), e.rootId), { replyCount:
|
|
2303
|
+
n.delete(d(i, o(), e.id)), e.parentId && e.rootId && n.update(d(i, o(), e.rootId), { replyCount: we(-1) }), n.update(y(i, o(), b.value), { commentCount: we(-1) }), await n.commit(), await ue(t), T.value = T.value.filter((t) => t.id !== e.id), C.value = C.value.filter((t) => t.id !== e.id);
|
|
2296
2304
|
}
|
|
2297
2305
|
async function pe(e, t, n, r) {
|
|
2298
|
-
let a = Tr(t,
|
|
2306
|
+
let a = Tr(t, m), s = {
|
|
2299
2307
|
body: a,
|
|
2300
|
-
updatedAt:
|
|
2308
|
+
updatedAt: q()
|
|
2301
2309
|
};
|
|
2302
2310
|
if (n !== void 0) {
|
|
2303
2311
|
let t = oe(e, n);
|
|
2304
|
-
s.images = t.length ? t :
|
|
2312
|
+
s.images = t.length ? t : _e();
|
|
2305
2313
|
}
|
|
2306
2314
|
await Y(d(i, o(), e), {
|
|
2307
2315
|
...s,
|
|
2308
|
-
...await
|
|
2316
|
+
...await p(a, r)
|
|
2309
2317
|
});
|
|
2310
2318
|
}
|
|
2311
2319
|
async function me(e, t, n) {
|
|
2312
2320
|
await Y(d(i, o(), e), {
|
|
2313
2321
|
isBlinded: t,
|
|
2314
|
-
moderatedAt:
|
|
2322
|
+
moderatedAt: q(),
|
|
2315
2323
|
moderatedBy: n
|
|
2316
2324
|
});
|
|
2317
2325
|
}
|
|
2318
2326
|
return {
|
|
2319
2327
|
comments: ne,
|
|
2320
|
-
commentsPending:
|
|
2321
|
-
hasMore:
|
|
2322
|
-
loadingMore:
|
|
2323
|
-
loadMore:
|
|
2324
|
-
newCommentId:
|
|
2328
|
+
commentsPending: I(() => ee.value || w.value),
|
|
2329
|
+
hasMore: D,
|
|
2330
|
+
loadingMore: E,
|
|
2331
|
+
loadMore: M,
|
|
2332
|
+
newCommentId: ie,
|
|
2333
|
+
translationSkipped: f,
|
|
2325
2334
|
addComment: de,
|
|
2326
|
-
addReply:
|
|
2335
|
+
addReply: F,
|
|
2327
2336
|
updateComment: pe,
|
|
2328
2337
|
setCommentBlinded: me,
|
|
2329
|
-
deleteComment:
|
|
2338
|
+
deleteComment: fe
|
|
2330
2339
|
};
|
|
2331
2340
|
}
|
|
2332
2341
|
function Dr(e, t, n) {
|
|
2333
|
-
let r = Z(), i = () =>
|
|
2342
|
+
let r = Z(), i = () => P(), a = () => g(r, i()), o = t.trim(), s = R([]), c = R(!1), l = R(!1), u = R(!0), d = null, f, p = 0, m = 0;
|
|
2334
2343
|
function h(e) {
|
|
2335
2344
|
return e.sort((e, t) => (e.createdAt?.toMillis?.() ?? 0) - (t.createdAt?.toMillis?.() ?? 0) || String(e.id).localeCompare(String(t.id)));
|
|
2336
2345
|
}
|
|
@@ -2356,11 +2365,11 @@ function Dr(e, t, n) {
|
|
|
2356
2365
|
X("postId", "==", o),
|
|
2357
2366
|
X("rootId", "==", n),
|
|
2358
2367
|
X("isReply", "==", !0),
|
|
2359
|
-
|
|
2360
|
-
|
|
2368
|
+
G("createdAt", "asc"),
|
|
2369
|
+
G(V(), "asc"),
|
|
2361
2370
|
...d ? [J(d)] : [],
|
|
2362
|
-
|
|
2363
|
-
], r = await
|
|
2371
|
+
U(6)
|
|
2372
|
+
], r = await H(K(a(), ...t));
|
|
2364
2373
|
if (e !== p) return;
|
|
2365
2374
|
let i = new Set(s.value.map((e) => e.id)), c = r.docs.slice(0, Cr), f = c.map((e) => ({
|
|
2366
2375
|
id: e.id,
|
|
@@ -2377,7 +2386,7 @@ function Dr(e, t, n) {
|
|
|
2377
2386
|
async function b() {
|
|
2378
2387
|
y(), await v();
|
|
2379
2388
|
}
|
|
2380
|
-
return
|
|
2389
|
+
return L(() => {
|
|
2381
2390
|
p++, m++, f?.();
|
|
2382
2391
|
}), {
|
|
2383
2392
|
replies: s,
|
|
@@ -2391,21 +2400,21 @@ function Dr(e, t, n) {
|
|
|
2391
2400
|
//#endregion
|
|
2392
2401
|
//#region src/composables/useMemiBoardLikes.ts
|
|
2393
2402
|
function Or(e, t) {
|
|
2394
|
-
let n = () =>
|
|
2403
|
+
let n = () => P(), r = Z(), i = Ae(), { t: a } = N(), o = R(!1), s = R(!1), c;
|
|
2395
2404
|
function l(e) {
|
|
2396
|
-
return
|
|
2405
|
+
return fe(r, n(), t, e);
|
|
2397
2406
|
}
|
|
2398
|
-
|
|
2407
|
+
B(i, (e) => {
|
|
2399
2408
|
if (c?.(), c = void 0, !e) {
|
|
2400
2409
|
o.value = !1;
|
|
2401
2410
|
return;
|
|
2402
2411
|
}
|
|
2403
|
-
c =
|
|
2412
|
+
c = W(l(e.uid), (e) => {
|
|
2404
2413
|
o.value = e.exists();
|
|
2405
2414
|
}, (e) => {
|
|
2406
2415
|
console.error("[memi-board:likes] onSnapshot failed", e);
|
|
2407
2416
|
});
|
|
2408
|
-
}, { immediate: !0 }),
|
|
2417
|
+
}, { immediate: !0 }), L(() => c?.());
|
|
2409
2418
|
async function u() {
|
|
2410
2419
|
let c = i.value?.uid;
|
|
2411
2420
|
if (!c) throw Error(a("likes.signInRequired"));
|
|
@@ -2413,12 +2422,12 @@ function Or(e, t) {
|
|
|
2413
2422
|
s.value = !0;
|
|
2414
2423
|
try {
|
|
2415
2424
|
let i = l(c), a = y(r, n(), t);
|
|
2416
|
-
return await
|
|
2425
|
+
return await Ee(r, async (n) => (await n.get(i)).exists() ? (n.delete(i), n.update(a, { likeCount: we(-1) }), !1) : (n.set(i, {
|
|
2417
2426
|
uid: c,
|
|
2418
2427
|
postId: t,
|
|
2419
2428
|
boardId: e,
|
|
2420
|
-
createdAt:
|
|
2421
|
-
}), n.update(a, { likeCount:
|
|
2429
|
+
createdAt: q()
|
|
2430
|
+
}), n.update(a, { likeCount: we(1) }), !0));
|
|
2422
2431
|
} finally {
|
|
2423
2432
|
s.value = !1;
|
|
2424
2433
|
}
|
|
@@ -2431,9 +2440,9 @@ function Or(e, t) {
|
|
|
2431
2440
|
}
|
|
2432
2441
|
var kr = Symbol.for("memi-board:comment-likes");
|
|
2433
2442
|
function Ar(e, t) {
|
|
2434
|
-
let n = () =>
|
|
2435
|
-
|
|
2436
|
-
u?.(), u = void 0, c.value = /* @__PURE__ */ new Set(), e && t && (u =
|
|
2443
|
+
let n = () => P(), r = Z(), i = Ae(), { t: a } = N(), o = I(() => z(e)), s = I(() => z(t)), c = R(/* @__PURE__ */ new Set()), l = R(null), u;
|
|
2444
|
+
B([i, s], ([e, t]) => {
|
|
2445
|
+
u?.(), u = void 0, c.value = /* @__PURE__ */ new Set(), e && t && (u = W(K(b(r, n()), X("uid", "==", e.uid), X("postId", "==", t), X("target", "==", "comment")), (e) => {
|
|
2437
2446
|
let t = /* @__PURE__ */ new Set();
|
|
2438
2447
|
for (let n of e.docs) {
|
|
2439
2448
|
let e = n.data().commentId;
|
|
@@ -2443,7 +2452,7 @@ function Ar(e, t) {
|
|
|
2443
2452
|
}, (e) => {
|
|
2444
2453
|
console.error("[memi-board:comment-likes] onSnapshot failed", e);
|
|
2445
2454
|
}));
|
|
2446
|
-
}, { immediate: !0 }),
|
|
2455
|
+
}, { immediate: !0 }), L(() => u?.());
|
|
2447
2456
|
function f(e) {
|
|
2448
2457
|
return !!e && c.value.has(e);
|
|
2449
2458
|
}
|
|
@@ -2457,7 +2466,7 @@ function Ar(e, t) {
|
|
|
2457
2466
|
if (l.value) return f(e);
|
|
2458
2467
|
l.value = e;
|
|
2459
2468
|
try {
|
|
2460
|
-
let i =
|
|
2469
|
+
let i = fe(r, n(), e, t), l = d(r, n(), e), u = await Ee(r, async (n) => {
|
|
2461
2470
|
let r = await n.get(i), c = await n.get(l);
|
|
2462
2471
|
if (!c.exists()) throw Error(a("likes.commentNotFound"));
|
|
2463
2472
|
let u = Number(c.data()?.likeCount ?? 0);
|
|
@@ -2467,7 +2476,7 @@ function Ar(e, t) {
|
|
|
2467
2476
|
boardId: o.value,
|
|
2468
2477
|
commentId: e,
|
|
2469
2478
|
target: "comment",
|
|
2470
|
-
createdAt:
|
|
2479
|
+
createdAt: q()
|
|
2471
2480
|
}), n.update(l, { likeCount: u + 1 }), !0);
|
|
2472
2481
|
}), f = new Set(c.value);
|
|
2473
2482
|
return u ? f.add(e) : f.delete(e), c.value = f, u;
|
|
@@ -2506,21 +2515,21 @@ var jr = 200, Mr = [
|
|
|
2506
2515
|
}
|
|
2507
2516
|
];
|
|
2508
2517
|
function Nr(e, t) {
|
|
2509
|
-
return Mr.some((t) => t.value === e) ?
|
|
2518
|
+
return Mr.some((t) => t.value === e) ? M(t, `reports.reason.${e}`) : e || M(t, "reports.fallbackLabel");
|
|
2510
2519
|
}
|
|
2511
2520
|
function Pr(e, t) {
|
|
2512
|
-
let n = () =>
|
|
2513
|
-
|
|
2521
|
+
let n = () => P(), r = Z(), i = Ae(), { t: a } = N(), o = R(!1), s = R(!1), c;
|
|
2522
|
+
B(i, (e) => {
|
|
2514
2523
|
if (c?.(), c = void 0, !e) {
|
|
2515
2524
|
o.value = !1;
|
|
2516
2525
|
return;
|
|
2517
2526
|
}
|
|
2518
|
-
c =
|
|
2527
|
+
c = W(u(r, n(), t, e.uid), (e) => {
|
|
2519
2528
|
o.value = e.exists();
|
|
2520
2529
|
}, (e) => {
|
|
2521
2530
|
console.error("[memi-board:reports] onSnapshot failed", e);
|
|
2522
2531
|
});
|
|
2523
|
-
}, { immediate: !0 }),
|
|
2532
|
+
}, { immediate: !0 }), L(() => c?.());
|
|
2524
2533
|
async function l(c) {
|
|
2525
2534
|
let l = i.value?.uid;
|
|
2526
2535
|
if (!l) throw Error(a("reports.signInRequired"));
|
|
@@ -2532,7 +2541,7 @@ function Pr(e, t) {
|
|
|
2532
2541
|
if (f.length > 200) throw Error(a("reports.detailTooLong", { max: 200 }));
|
|
2533
2542
|
s.value = !0;
|
|
2534
2543
|
try {
|
|
2535
|
-
await
|
|
2544
|
+
await De(u(r, n(), t, l), {
|
|
2536
2545
|
uid: l,
|
|
2537
2546
|
target: "post",
|
|
2538
2547
|
postId: t,
|
|
@@ -2543,7 +2552,7 @@ function Pr(e, t) {
|
|
|
2543
2552
|
postTitle: (c.postTitle || "").trim().slice(0, 200),
|
|
2544
2553
|
authorUid: c.authorUid || "",
|
|
2545
2554
|
authorName: c.authorName ?? null,
|
|
2546
|
-
createdAt:
|
|
2555
|
+
createdAt: q()
|
|
2547
2556
|
}), o.value = !0;
|
|
2548
2557
|
} finally {
|
|
2549
2558
|
s.value = !1;
|
|
@@ -2557,7 +2566,7 @@ function Pr(e, t) {
|
|
|
2557
2566
|
}
|
|
2558
2567
|
var Fr = 20;
|
|
2559
2568
|
function Ir(e = {}) {
|
|
2560
|
-
let t = () =>
|
|
2569
|
+
let t = () => P(), n = Z(), { isAdmin: r, canManageContent: i, canManageBoard: a } = Wt(), o = e.pageSize ?? Fr, s = I(() => z(e.boardId)?.trim() || ""), c = R([]), d = R(!0), f = R(!1), p = R(!1), m = R(""), h = null, g;
|
|
2561
2570
|
function _(e) {
|
|
2562
2571
|
return {
|
|
2563
2572
|
id: e.id,
|
|
@@ -2571,18 +2580,18 @@ function Ir(e = {}) {
|
|
|
2571
2580
|
}
|
|
2572
2581
|
d.value = !0;
|
|
2573
2582
|
let e = s.value ? [X("status", "==", "open"), X("boardId", "==", s.value)] : [X("status", "==", "open"), X("target", "==", "post")];
|
|
2574
|
-
g =
|
|
2583
|
+
g = W(K(l(n, t()), ...e, G("createdAt", "desc"), G(V(), "desc"), U(o)), (e) => {
|
|
2575
2584
|
c.value = e.docs.map(_).filter((e) => a(e.boardId)), h = e.docs.at(-1) ?? null, p.value = e.docs.length >= o, d.value = !1;
|
|
2576
2585
|
}, (e) => {
|
|
2577
2586
|
console.error("[memi-board:report-queue] onSnapshot failed", e), m.value = e.message || String(e), d.value = !1;
|
|
2578
2587
|
});
|
|
2579
2588
|
}
|
|
2580
|
-
|
|
2589
|
+
B([i, s], v, { immediate: !0 }), L(() => g?.());
|
|
2581
2590
|
async function y() {
|
|
2582
2591
|
if (!f.value && p.value && h && i.value) {
|
|
2583
2592
|
f.value = !0, m.value = "";
|
|
2584
2593
|
try {
|
|
2585
|
-
let e = s.value ? [X("status", "==", "open"), X("boardId", "==", s.value)] : [X("status", "==", "open"), X("target", "==", "post")], r = await
|
|
2594
|
+
let e = s.value ? [X("status", "==", "open"), X("boardId", "==", s.value)] : [X("status", "==", "open"), X("target", "==", "post")], r = await H(K(l(n, t()), ...e, G("createdAt", "desc"), G(V(), "desc"), J(h), U(o + 1))), i = r.docs.slice(0, o), u = new Set(c.value.map((e) => e.id));
|
|
2586
2595
|
c.value.push(...i.map(_).filter((e) => !u.has(e.id) && a(e.boardId))), h = i.at(-1) ?? h, p.value = r.docs.length > o;
|
|
2587
2596
|
} catch (e) {
|
|
2588
2597
|
m.value = e.message || String(e);
|
|
@@ -2594,7 +2603,7 @@ function Ir(e = {}) {
|
|
|
2594
2603
|
async function b(e, r) {
|
|
2595
2604
|
e.id && a(e.boardId) && await Y(u(n, t(), e.postId, e.uid), {
|
|
2596
2605
|
status: r,
|
|
2597
|
-
reviewedAt:
|
|
2606
|
+
reviewedAt: q(),
|
|
2598
2607
|
reviewedBy: Ae().value?.uid || ""
|
|
2599
2608
|
});
|
|
2600
2609
|
}
|
|
@@ -2612,7 +2621,7 @@ function Ir(e = {}) {
|
|
|
2612
2621
|
//#endregion
|
|
2613
2622
|
//#region src/composables/useMemiBoardViews.ts
|
|
2614
2623
|
function Lr() {
|
|
2615
|
-
let e = () =>
|
|
2624
|
+
let e = () => P(), t = Z();
|
|
2616
2625
|
function n(t, n) {
|
|
2617
2626
|
let { postsCollection: r } = e();
|
|
2618
2627
|
return `memi-board:viewed:${r}:${t}:${n}`;
|
|
@@ -2635,7 +2644,7 @@ function Lr() {
|
|
|
2635
2644
|
if (s && c && !r(s, c)) {
|
|
2636
2645
|
i(s, c);
|
|
2637
2646
|
try {
|
|
2638
|
-
await Y(y(t, e(), c), { viewCount:
|
|
2647
|
+
await Y(y(t, e(), c), { viewCount: we(1) });
|
|
2639
2648
|
} catch (e) {
|
|
2640
2649
|
try {
|
|
2641
2650
|
sessionStorage.removeItem(n(s, c));
|
|
@@ -2658,7 +2667,7 @@ var Rr = {
|
|
|
2658
2667
|
via: "empty"
|
|
2659
2668
|
};
|
|
2660
2669
|
function zr(e = {}) {
|
|
2661
|
-
let t =
|
|
2670
|
+
let t = N(), n = I(() => F(z(e.locale)) ?? t.locale.value), r = v().moderation ?? {}, i = Me(), a = (e) => M(n.value, e), { isWriteRestricted: o, restrictedMessage: s, recordContentModerationBlock: c } = Wt(), l = Nn([...Mn, ...r.localBlocklist ?? []]);
|
|
2662
2671
|
function u(e) {
|
|
2663
2672
|
let t = e.match(l);
|
|
2664
2673
|
return t ? {
|
|
@@ -2817,16 +2826,16 @@ var Br = [
|
|
|
2817
2826
|
"user"
|
|
2818
2827
|
].map((e) => ({
|
|
2819
2828
|
value: e,
|
|
2820
|
-
label:
|
|
2821
|
-
description:
|
|
2829
|
+
label: M("ko", `common.role.${e}`),
|
|
2830
|
+
description: M("ko", `boardUsers.roleDescription.${e}`)
|
|
2822
2831
|
}));
|
|
2823
2832
|
function Vr(e = {}) {
|
|
2824
|
-
let t = () =>
|
|
2833
|
+
let t = () => P(), n = Z(), { t: r } = N(), i = I(() => z(e.enabled) ?? !0 ? c(n, t()) : null), a = ke(i, { ssrKey: p(t(), "users-management") });
|
|
2825
2834
|
async function o(e, i) {
|
|
2826
2835
|
if (!Br.some((e) => e.value === i)) throw Error(r("boardUsers.unsupportedRole"));
|
|
2827
2836
|
await Y(h(n, t(), e), {
|
|
2828
2837
|
role: i,
|
|
2829
|
-
updatedAt:
|
|
2838
|
+
updatedAt: q()
|
|
2830
2839
|
});
|
|
2831
2840
|
}
|
|
2832
2841
|
return {
|
|
@@ -2838,7 +2847,7 @@ function Vr(e = {}) {
|
|
|
2838
2847
|
//#endregion
|
|
2839
2848
|
//#region src/composables/useMemiBoardUserProfile.ts
|
|
2840
2849
|
function Hr(e) {
|
|
2841
|
-
let t = Z(), n = () =>
|
|
2850
|
+
let t = Z(), n = () => P(), r = I(() => z(e)), i = I(() => {
|
|
2842
2851
|
let e = r.value;
|
|
2843
2852
|
return e ? h(t, n(), e) : null;
|
|
2844
2853
|
}), { data: a, pending: o } = je(i);
|
|
@@ -2863,25 +2872,25 @@ function Wr(e) {
|
|
|
2863
2872
|
return [
|
|
2864
2873
|
{
|
|
2865
2874
|
value: "list",
|
|
2866
|
-
label:
|
|
2875
|
+
label: M(e, "sectionUtil.kind.list")
|
|
2867
2876
|
},
|
|
2868
2877
|
{
|
|
2869
2878
|
value: "post",
|
|
2870
|
-
label:
|
|
2879
|
+
label: M(e, "sectionUtil.kind.post")
|
|
2871
2880
|
},
|
|
2872
2881
|
{
|
|
2873
2882
|
value: "comments",
|
|
2874
|
-
label:
|
|
2883
|
+
label: M(e, "sectionUtil.kind.comments")
|
|
2875
2884
|
}
|
|
2876
2885
|
];
|
|
2877
2886
|
}
|
|
2878
2887
|
function Gr(e) {
|
|
2879
2888
|
return [{
|
|
2880
2889
|
value: "latest",
|
|
2881
|
-
label:
|
|
2890
|
+
label: M(e, "sectionUtil.sort.latest")
|
|
2882
2891
|
}, {
|
|
2883
2892
|
value: "likes",
|
|
2884
|
-
label:
|
|
2893
|
+
label: M(e, "sectionUtil.sort.likes")
|
|
2885
2894
|
}];
|
|
2886
2895
|
}
|
|
2887
2896
|
var Kr = Wr("ko"), qr = Gr("ko");
|
|
@@ -2924,13 +2933,13 @@ function ni(e) {
|
|
|
2924
2933
|
return e.previewImage || e.attachments?.find((e) => e.type.startsWith("image/"))?.url;
|
|
2925
2934
|
}
|
|
2926
2935
|
function ri(e, t) {
|
|
2927
|
-
return vt(e, t).trim() || yt(e, t).trim() ||
|
|
2936
|
+
return vt(e, t).trim() || yt(e, t).trim() || M(t, "sectionUtil.untitledPost");
|
|
2928
2937
|
}
|
|
2929
2938
|
function ii(e) {
|
|
2930
2939
|
return e === "image" || e === "video" ? "media" : "list";
|
|
2931
2940
|
}
|
|
2932
2941
|
function ai(e, t) {
|
|
2933
|
-
return
|
|
2942
|
+
return M(t, ii(e) === "media" ? "sectionUtil.view.media" : "sectionUtil.view.list");
|
|
2934
2943
|
}
|
|
2935
2944
|
function oi(e, t) {
|
|
2936
2945
|
return e ? t(e)?.listView ?? "default" : "default";
|
|
@@ -2973,7 +2982,7 @@ function mi(e, t) {
|
|
|
2973
2982
|
return r;
|
|
2974
2983
|
}
|
|
2975
2984
|
function hi(e, t) {
|
|
2976
|
-
return
|
|
2985
|
+
return M(t, "sections.defaultTitle", { n: e + 1 });
|
|
2977
2986
|
}
|
|
2978
2987
|
function gi(e, t, n) {
|
|
2979
2988
|
let r = di(e), i = Yr(r, e.count), a = Q(e.i18n), o = ut(e.i18nSource);
|
|
@@ -2994,7 +3003,7 @@ function gi(e, t, n) {
|
|
|
2994
3003
|
};
|
|
2995
3004
|
}
|
|
2996
3005
|
function _i() {
|
|
2997
|
-
let { locale: e } =
|
|
3006
|
+
let { locale: e } = N(), { translateEntries: t } = Un(), r = Z(), i = ve(r, "settings", "homeLayout"), { data: a, pending: o } = je(i), s = I(() => (Array.isArray(a.value?.blocks) ? a.value.blocks : ci).map((t, n) => gi(t, n, e.value)));
|
|
2998
3007
|
async function c(r) {
|
|
2999
3008
|
if (!n()) return r;
|
|
3000
3009
|
let i = e.value, a = r.filter((e) => {
|
|
@@ -3050,10 +3059,10 @@ function _i() {
|
|
|
3050
3059
|
} catch (e) {
|
|
3051
3060
|
console.warn("[memi-board] section translation skipped", e);
|
|
3052
3061
|
}
|
|
3053
|
-
await
|
|
3062
|
+
await De(i, {
|
|
3054
3063
|
columns: 12,
|
|
3055
3064
|
blocks: t.map((e, t) => l(e, t)),
|
|
3056
|
-
updatedAt:
|
|
3065
|
+
updatedAt: q()
|
|
3057
3066
|
});
|
|
3058
3067
|
}
|
|
3059
3068
|
return {
|
|
@@ -3061,7 +3070,7 @@ function _i() {
|
|
|
3061
3070
|
pending: o,
|
|
3062
3071
|
sections: s,
|
|
3063
3072
|
blocks: s,
|
|
3064
|
-
hasSavedLayout:
|
|
3073
|
+
hasSavedLayout: I(() => Array.isArray(a.value?.blocks)),
|
|
3065
3074
|
saveSections: u,
|
|
3066
3075
|
saveBlocks: u
|
|
3067
3076
|
};
|
|
@@ -3069,20 +3078,20 @@ function _i() {
|
|
|
3069
3078
|
//#endregion
|
|
3070
3079
|
//#region src/composables/useMemiBoardMiniPosts.ts
|
|
3071
3080
|
function vi(e, t) {
|
|
3072
|
-
let n = Z(), r = () =>
|
|
3073
|
-
let i = Math.max(1, Math.floor(Number(
|
|
3074
|
-
return a && s.unshift(X("boardId", "==", a)),
|
|
3081
|
+
let n = Z(), r = () => P(), i = z(e)?.trim() || "all", a = I(() => {
|
|
3082
|
+
let i = Math.max(1, Math.floor(Number(z(t)) || 5)), a = z(e)?.trim() || "", s = [X("isPublished", "==", !0), X("listed", "==", !0)];
|
|
3083
|
+
return a && s.unshift(X("boardId", "==", a)), K(o(n, r()), ...s, G("createdAt", "desc"), U(i));
|
|
3075
3084
|
}), { data: s, pending: c, error: l } = ke(a, { ssrKey: p(r(), `mini-list/${i}`) });
|
|
3076
3085
|
return {
|
|
3077
|
-
posts:
|
|
3086
|
+
posts: I(() => s.value ?? []),
|
|
3078
3087
|
pending: c,
|
|
3079
3088
|
error: l
|
|
3080
3089
|
};
|
|
3081
3090
|
}
|
|
3082
3091
|
function yi(e) {
|
|
3083
|
-
let t = Z(), n = () =>
|
|
3092
|
+
let t = Z(), n = () => P(), r = I(() => [...new Set(z(e).map((e) => e.trim()).filter(Boolean))].slice(0, 10)), i = r.value.join(",") || "none", a = I(() => r.value.length ? K(o(t, n()), X(V(), "in", r.value)) : null), { data: s, pending: c, error: l } = ke(a, { ssrKey: p(n(), `mini-picked/${i}`) });
|
|
3084
3093
|
return {
|
|
3085
|
-
posts:
|
|
3094
|
+
posts: I(() => {
|
|
3086
3095
|
let e = new Map((s.value ?? []).map((e) => [e.id, e])), t = [];
|
|
3087
3096
|
for (let n of r.value) {
|
|
3088
3097
|
let r = e.get(n);
|
|
@@ -3097,6 +3106,22 @@ function yi(e) {
|
|
|
3097
3106
|
//#endregion
|
|
3098
3107
|
//#region src/data/versionHistory.ts
|
|
3099
3108
|
var bi = [
|
|
3109
|
+
{
|
|
3110
|
+
version: "0.52.3",
|
|
3111
|
+
date: "2026-10-30",
|
|
3112
|
+
highlights: [
|
|
3113
|
+
"AI 글쓰기 도우미를 하루 20회까지 쓸 수 있어요",
|
|
3114
|
+
"자동 번역이 실패하거나 한도를 넘어도 글과 댓글은 원문으로 저장돼요",
|
|
3115
|
+
"한도 안내가 10개 언어로 보여요"
|
|
3116
|
+
],
|
|
3117
|
+
highlightsEn: [
|
|
3118
|
+
"The AI writing assistant can now be used up to 20 times a day",
|
|
3119
|
+
"Posts and comments are saved with the original text even when automatic translation fails or the limit is reached",
|
|
3120
|
+
"The daily limit message now appears in all 10 languages"
|
|
3121
|
+
],
|
|
3122
|
+
note: "호스트 Firestore 규칙의 AI 사용 한도도 20으로 바꿔 배포해야 해요.",
|
|
3123
|
+
noteEn: "Update the AI usage limit in the host Firestore rules to 20 and deploy them."
|
|
3124
|
+
},
|
|
3100
3125
|
{
|
|
3101
3126
|
version: "0.52.2",
|
|
3102
3127
|
date: "2026-10-30",
|
|
@@ -3737,11 +3762,11 @@ function Di(e, t, n) {
|
|
|
3737
3762
|
//#endregion
|
|
3738
3763
|
//#region src/composables/useMemiBoardCleanup.ts
|
|
3739
3764
|
function Oi() {
|
|
3740
|
-
let e = Z(), t = Me(), { isAdmin: n, rolePending: r } = Wt(), { t: i } =
|
|
3765
|
+
let e = Z(), t = Me(), { isAdmin: n, rolePending: r } = Wt(), { t: i } = N(), a = R([]), o = R(!1), s = R(!1), c = R(""), l = R(""), u = [], d = "", f = /* @__PURE__ */ new Map();
|
|
3741
3766
|
function p() {
|
|
3742
3767
|
let e = Le(t).currentUser?.uid;
|
|
3743
3768
|
if (!e) throw Error(i("settings.noAccess"));
|
|
3744
|
-
return JSON.stringify([e,
|
|
3769
|
+
return JSON.stringify([e, P()]);
|
|
3745
3770
|
}
|
|
3746
3771
|
function m(e) {
|
|
3747
3772
|
if (h(), p() !== e) throw Error(i("settings.cleanup.contextChanged"));
|
|
@@ -3750,10 +3775,10 @@ function Oi() {
|
|
|
3750
3775
|
if (!n.value || r.value || !Le(t).currentUser) throw Error(i("settings.noAccess"));
|
|
3751
3776
|
}
|
|
3752
3777
|
async function g() {
|
|
3753
|
-
let t =
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3778
|
+
let t = P(), [n, r, i] = await Promise.all([
|
|
3779
|
+
Ce(he(e, t.postsCollection)),
|
|
3780
|
+
Ce(he(e, t.commentsCollection)),
|
|
3781
|
+
Ce(he(e, t.likesCollection))
|
|
3757
3782
|
]), a = /* @__PURE__ */ new Set();
|
|
3758
3783
|
function o(e) {
|
|
3759
3784
|
if (typeof e == "string") {
|
|
@@ -3767,7 +3792,7 @@ function Oi() {
|
|
|
3767
3792
|
} else Array.isArray(e) ? e.forEach(o) : e && typeof e == "object" && Object.getPrototypeOf(e) === Object.prototype && Object.values(e).forEach(o);
|
|
3768
3793
|
}
|
|
3769
3794
|
n.docs.forEach((e) => o(e.data())), r.docs.forEach((e) => o(e.data()));
|
|
3770
|
-
for (let e of n.docs) (await
|
|
3795
|
+
for (let e of n.docs) (await Ce(he(e.ref, "body"))).docs.forEach((e) => o(e.data()));
|
|
3771
3796
|
for (let e of [...a]) {
|
|
3772
3797
|
let t = e.match(/^(.*\/images\/)([^/]+)\.[^/.]+$/);
|
|
3773
3798
|
t && a.add(`${t[1]}thumbnails/${t[2]}.jpg`);
|
|
@@ -3849,20 +3874,20 @@ function Oi() {
|
|
|
3849
3874
|
if (n.kind === "file") {
|
|
3850
3875
|
if (!Ei(n.path, o.cfg.postsCollection)) throw Error("Invalid cleanup path");
|
|
3851
3876
|
let r = We(t), a = qe(r, n.path), [s, c, l] = await Promise.all([
|
|
3852
|
-
|
|
3853
|
-
n.commentId ?
|
|
3877
|
+
Se(ve(e, o.cfg.postsCollection, n.postId)),
|
|
3878
|
+
n.commentId ? Se(ve(e, o.cfg.commentsCollection, n.commentId)) : null,
|
|
3854
3879
|
Ue(a)
|
|
3855
3880
|
]);
|
|
3856
3881
|
m(d), l.generation === f.get(n.path) && !o.referenced.has(n.path) && Ti(l.updated, Date.now()) && (!s.exists() || n.commentId && !c?.exists()) && (await He(a), i = !0);
|
|
3857
3882
|
} else {
|
|
3858
3883
|
let t = n.kind;
|
|
3859
3884
|
if (!Di(n.path, t, o.cfg)) throw Error("Invalid cleanup path");
|
|
3860
|
-
i = await
|
|
3861
|
-
let i = await r.get(
|
|
3885
|
+
i = await Ee(e, async (r) => {
|
|
3886
|
+
let i = await r.get(ve(e, n.path));
|
|
3862
3887
|
if (!i.exists()) return !0;
|
|
3863
3888
|
let a = i.data();
|
|
3864
3889
|
if (typeof a.postId != "string" || !a.postId || a.postId.includes("/")) return !1;
|
|
3865
|
-
let s = await r.get(
|
|
3890
|
+
let s = await r.get(ve(e, o.cfg.postsCollection, a.postId)), c = n.kind === "like" && a.target === "comment" && typeof a.commentId == "string" && a.commentId && !a.commentId.includes("/") ? await r.get(ve(e, o.cfg.commentsCollection, a.commentId)) : null;
|
|
3866
3891
|
return wi(t, a, new Set(s.exists() ? [a.postId] : []), new Set(c?.exists() ? [a.commentId] : [])) ? (m(d), r.delete(i.ref), !0) : !1;
|
|
3867
3892
|
});
|
|
3868
3893
|
}
|
|
@@ -3883,16 +3908,16 @@ function Oi() {
|
|
|
3883
3908
|
}
|
|
3884
3909
|
}
|
|
3885
3910
|
return {
|
|
3886
|
-
items:
|
|
3887
|
-
busy:
|
|
3888
|
-
scanned:
|
|
3889
|
-
error:
|
|
3890
|
-
result:
|
|
3911
|
+
items: me(a),
|
|
3912
|
+
busy: me(o),
|
|
3913
|
+
scanned: me(s),
|
|
3914
|
+
error: me(c),
|
|
3915
|
+
result: me(l),
|
|
3891
3916
|
scan: _,
|
|
3892
3917
|
remove: v
|
|
3893
3918
|
};
|
|
3894
3919
|
}
|
|
3895
3920
|
//#endregion
|
|
3896
|
-
export { lr as AUTHOR_MEMO_MAX_LENGTH, Ur as BOARD_SECTION_COLS, Kr as BOARD_SECTION_KINDS, qr as BOARD_SECTION_SORTS, Br as BOARD_USER_ROLES, wr as COMMENT_BODY_MAX_LENGTH, It as DEFAULT_BLOCK_BAN_DECAY_MS, Ft as DEFAULT_BLOCK_BAN_THRESHOLD, Wn as DEFAULT_BOARDS, Gn as DEFAULT_CATEGORIES, i as DEFAULT_COMMENTS_COLLECTION, r as DEFAULT_LIKES_COLLECTION,
|
|
3921
|
+
export { lr as AUTHOR_MEMO_MAX_LENGTH, Ur as BOARD_SECTION_COLS, Kr as BOARD_SECTION_KINDS, qr as BOARD_SECTION_SORTS, Br as BOARD_USER_ROLES, wr as COMMENT_BODY_MAX_LENGTH, It as DEFAULT_BLOCK_BAN_DECAY_MS, Ft as DEFAULT_BLOCK_BAN_THRESHOLD, Wn as DEFAULT_BOARDS, Gn as DEFAULT_CATEGORIES, i as DEFAULT_COMMENTS_COLLECTION, r as DEFAULT_LIKES_COLLECTION, j as DEFAULT_MEMI_BOARD_LOCALE, m as DEFAULT_POSTS_COLLECTION, ne as DEFAULT_REPORTS_COLLECTION, e as DEFAULT_SETTINGS_COLLECTION, te as DEFAULT_USERS_COLLECTION, A as FALLBACK_MEMI_BOARD_LOCALE, Rn as HTML_MAX_CHARS, T as MEMI_BOARD_LOCALES, jr as REPORT_DETAIL_MAX_LENGTH, Mr as REPORT_REASONS, fr as WRITING_ASSISTANT_DAILY_LIMIT, $e as asHttpUrl, xt as boardCopyIsTranslated, at as boardListOgDescription, it as boardListOgTitle, rt as boardPostOgDescription, nt as boardPostOgTitle, Wr as boardSectionKinds, Gr as boardSectionSorts, p as boardSsrKey, pt as boardTranslationLocales, h as boardUserDoc, c as boardUsersCol, _n as buildPostPreview, At as canManageBoardByRole, jt as canWriteCommentByRole, Yr as clampSectionCount, d as commentDoc, g as commentsCol, de as configureMemiBoard, ht as coversLocales, Jr as defaultSectionCount, St as displayCommentBody, bt as displayPostContent, yt as displayPostSummary, vt as displayPostTitle, _t as displayStoredField, Lt as effectiveModerationBlockCount, Xt as extractEditorImageUrls, Dt as fetchPublicListForSeo, Et as fetchPublicPostForSeo, ee as formatDate, re as formatFullDate, le as formatRelativeDate, Bt as formatRestrictedUntilLabel, O as formatTimestampDetails, fn as hasBodyImage, dn as hasBodyText, ct as hashText, Jt as imeSafeSubmitClick, qt as imeSafeSubmitPointerDown, kt as isAssignedStaff, pn as isContentEmpty, Xn as isFirestorePermissionDenied, _ as isMemiBoardI18nEnabled, k as isMemiBoardLocaleLoaded, n as isMemiBoardTranslationEnabled, zt as isModerationWriteRestricted, fe as likeDoc, t as likeDocId, b as likesCol, ae as loadMemiBoardLocale, gt as localizedText, kr as memiBoardCommentLikesKey, ie as memiBoardHostLocaleKey, ue as memiBoardLocaleInfo, ft as mergeSourceFields, oi as miniBoardView, ti as miniCommentLink, ei as miniMoreLink, ni as miniPostImage, $r as miniPostLink, ri as miniPostTitle, si as miniPostsView, ii as miniViewGroup, ai as miniViewLabel, Rt as moderationWriteRestrictedUntilMs, ot as normalizeBasePath, gi as normalizeBoardSection, F as normalizeMemiBoardLocale, Xr as pairSectionCols, ln as plainTextFromHtml, s as postBodyDoc, y as postDoc, Qt as postNamespaceFromStoragePath, x as postStorageFolder, o as postsCol, ut as readI18nSource, Q as readLocalizedFields, Ci as renderMarkdownToHtml, u as reportDoc, oe as reportDocId, Nr as reportReasonLabel, l as reportsCol, C as resolveBoardPathConfig, Ct as resolvePublicSeoDb, Zr as sectionColClass, Qr as sectionMinHeight, S as settingsCol, w as settingsDoc, E as slugify, Zt as storagePathFromDownloadUrl, un as titleFromBody, tt as toAbsoluteUrl, et as toBoardOgImageUrl, M as translate, P as useBoardPathConfig, Wt as useMemiBoardAuth, dr as useMemiBoardAuthorMemo, Un as useMemiBoardAutoTranslate, Oi as useMemiBoardCleanup, cr as useMemiBoardCommentFeed, Ar as useMemiBoardCommentLikes, Er as useMemiBoardComments, v as useMemiBoardConfig, N as useMemiBoardI18n, Or as useMemiBoardLikes, vi as useMemiBoardMiniLatest, yi as useMemiBoardMiniPicked, zr as useMemiBoardModeration, nr as useMemiBoardPost, tr as useMemiBoardPostList, Qn as useMemiBoardPosts, Dr as useMemiBoardReplies, Ir as useMemiBoardReportQueue, Pr as useMemiBoardReports, _i as useMemiBoardSections, Jn as useMemiBoardSettings, or as useMemiBoardUserComments, ir as useMemiBoardUserPosts, Hr as useMemiBoardUserProfile, Vr as useMemiBoardUsers, Lr as useMemiBoardViews, br as useMemiBoardWritingAssistant, bi as versionHistory, gn as videoListCoverUrl, hn as youtubeId };
|
|
3897
3922
|
|
|
3898
3923
|
//# sourceMappingURL=index.js.map
|