@blogmcp/community 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -12
- package/dist/blogmcp-community.global.js +7 -7
- package/dist/chunks/{mount-WadUnaTa.js → mount--2_V2q3M.js} +4724 -1097
- package/dist/core/attrs.d.ts +17 -2
- package/dist/core/discussion.d.ts +92 -18
- package/dist/core/follow.d.ts +26 -0
- package/dist/core/forum-category.d.ts +85 -0
- package/dist/core/forum-search.d.ts +35 -0
- package/dist/core/forum-state.d.ts +30 -0
- package/dist/core/forum-words.d.ts +8 -0
- package/dist/core/forum.d.ts +21 -0
- package/dist/core/moderation.d.ts +80 -0
- package/dist/core/onboarding.d.ts +7 -0
- package/dist/core/profile.d.ts +6 -1
- package/dist/core/realtime.d.ts +13 -2
- package/dist/core/topic.d.ts +47 -0
- package/dist/element.d.ts +26 -1
- package/dist/global.d.ts +7 -6
- package/dist/index.d.ts +13 -4
- package/dist/index.js +54 -27
- package/dist/mount.d.ts +50 -1
- package/dist/react.d.ts +17 -4
- package/dist/react.js +32 -8
- package/dist/ui/FollowButtonView.vue.d.ts +17 -0
- package/dist/ui/FollowToggle.vue.d.ts +6 -0
- package/dist/ui/ForumCategoryView.vue.d.ts +13 -0
- package/dist/ui/ForumModerationView.vue.d.ts +12 -0
- package/dist/ui/ForumNotices.vue.d.ts +7 -0
- package/dist/ui/ForumSearchView.vue.d.ts +11 -0
- package/dist/ui/ForumView.vue.d.ts +12 -0
- package/dist/ui/MembersOnly.vue.d.ts +15 -0
- package/dist/ui/MessageComposer.vue.d.ts +6 -2
- package/dist/ui/MessageMenu.vue.d.ts +2 -0
- package/dist/ui/ModeratorDialog.vue.d.ts +11 -0
- package/dist/ui/TopicRow.vue.d.ts +10 -0
- package/dist/ui/TopicView.vue.d.ts +32 -0
- package/dist/ui/context.d.ts +7 -1
- package/dist/ui/discussion-context.d.ts +11 -3
- package/dist/vue.d.ts +164 -5
- package/dist/vue.js +134 -8
- package/package.json +3 -3
- package/src/core/attrs.ts +22 -2
- package/src/core/discussion.ts +309 -43
- package/src/core/follow.ts +139 -0
- package/src/core/forum-category.ts +323 -0
- package/src/core/forum-search.ts +153 -0
- package/src/core/forum-state.ts +59 -0
- package/src/core/forum-words.ts +38 -0
- package/src/core/forum.ts +83 -0
- package/src/core/moderation.ts +414 -0
- package/src/core/onboarding.ts +16 -4
- package/src/core/outcomes.ts +10 -0
- package/src/core/profile.ts +12 -1
- package/src/core/realtime.ts +15 -2
- package/src/core/topic.ts +234 -0
- package/src/element.ts +63 -1
- package/src/global.ts +27 -5
- package/src/index.ts +49 -2
- package/src/mount.ts +144 -2
- package/src/react.ts +45 -2
- package/src/ui/FollowButtonView.vue +85 -0
- package/src/ui/FollowToggle.vue +39 -0
- package/src/ui/ForumCategoryView.vue +243 -0
- package/src/ui/ForumModerationView.vue +309 -0
- package/src/ui/ForumNotices.vue +23 -0
- package/src/ui/ForumSearchView.vue +171 -0
- package/src/ui/ForumView.vue +128 -0
- package/src/ui/MembersOnly.vue +59 -0
- package/src/ui/MessageComposer.vue +51 -9
- package/src/ui/MessageItem.vue +12 -1
- package/src/ui/MessageMenu.vue +3 -2
- package/src/ui/ModeratorDialog.vue +102 -0
- package/src/ui/MyCommunityView.vue +3 -0
- package/src/ui/NoticeStatusView.vue +15 -2
- package/src/ui/NotificationCentreView.vue +37 -3
- package/src/ui/ProfileView.vue +15 -4
- package/src/ui/TopicRow.vue +70 -0
- package/src/ui/TopicView.vue +395 -0
- package/src/ui/context.ts +8 -3
- package/src/ui/discussion-context.ts +11 -3
- package/src/ui/styles.css +14 -0
- package/src/vue.ts +145 -3
package/README.md
CHANGED
|
@@ -26,10 +26,42 @@ With the community module (M2) there are five more:
|
|
|
26
26
|
the daily e-mail digest, the quiet night 22:00–7:00), each saved on its own; this browser's notifications;
|
|
27
27
|
and the digest e-mail's unsubscribe link (below);
|
|
28
28
|
- `<blogmcp-profile handle="…">`: a member's public profile: name, avatar, since when they are a member, the
|
|
29
|
-
bio as text and the trust level as a label („Nový člen", „Člen", „Stálý člen", „
|
|
29
|
+
bio as text and the trust level as a label („Nový člen", „Člen", „Stálý člen", „Důvěryhodný člen"), never a
|
|
30
|
+
number; with the forum, „Moderátor" and the categories the member moderates now (an appointment, not a trust
|
|
31
|
+
level);
|
|
30
32
|
- `<blogmcp-welcome>`: the page after joining: the rules in summary and three links (the discussions, the
|
|
31
33
|
settings, the member's own profile; a visitor gets your sign-in link instead).
|
|
32
34
|
|
|
35
|
+
With the forum (M3) there are six more. The forum is for members only: a visitor reads one sentence and your
|
|
36
|
+
sign-in link, a member short of the onboarding „Vstoupit do komunity" (the onboarding opens in place; a forum write
|
|
37
|
+
needs the art. 9 consent whatever the tenant asks elsewhere).
|
|
38
|
+
|
|
39
|
+
- `<blogmcp-forum>`: the forum's index. The categories in the team's order, each with its count, its latest
|
|
40
|
+
topics and the link to all of them, and a search box that opens your search page with the query in the
|
|
41
|
+
address's fragment (`#q=…`, never the query string);
|
|
42
|
+
- `<blogmcp-forum-category slug="…">`: a category's topics, by activity or newest, pinned first, more a page at
|
|
43
|
+
a time. Where members open topics, the new-topic composer (a title of at most 200 characters, the opening post,
|
|
44
|
+
the link to the rules); a topic that waits for review says so and lists for its author only. In „Články" the
|
|
45
|
+
rows are the article discussions, each with its follow button;
|
|
46
|
+
- `<blogmcp-topic conversation-id="…">`: a topic's page. The header (title, category, closed, pinned, count),
|
|
47
|
+
the thread in the forum's words („příspěvek", where an article's discussion says „komentář"), the composer,
|
|
48
|
+
reactions, reports, the follow button and, for the opening post's author, the title's edit. A moderator of the
|
|
49
|
+
topic's category gets its menu: close or reopen it, pin it, move it, remove a message (with the rule and the
|
|
50
|
+
facts; the author gets a statement of reasons) or pass a message to the team;
|
|
51
|
+
- `<blogmcp-forum-search>`: the forum's search, as text. It reads the query from `#q=…`; a query shorter than two
|
|
52
|
+
characters is said, never sent;
|
|
53
|
+
- `<blogmcp-follow-button target-kind="…" target-id="…">`: follow a topic or an article discussion
|
|
54
|
+
(`conversation`) or a category (`category`). A follow the member may not have reads „not available"; an unfollow
|
|
55
|
+
never fails;
|
|
56
|
+
- `<blogmcp-forum-moderation>`: a category moderator's queue. The package of each case as text, the decision with
|
|
57
|
+
its statement previewed before it is decided, a matter passed to the team, the messages waiting for review
|
|
58
|
+
published or refused. It renders nothing for a member who moderates nothing.
|
|
59
|
+
|
|
60
|
+
A missing title reads one of three ways: „Smazané téma" only when the opening post was deleted, its own words
|
|
61
|
+
while it is withheld from the viewer, and its title with „Čeká na kontrolu" for the author of a topic waiting for
|
|
62
|
+
review. The forum's own brake pauses the forum's writes only, the article discussions' brake the discussions only
|
|
63
|
+
(the module's brake both); while the team is away the forum says so in one sentence.
|
|
64
|
+
|
|
33
65
|
`<blogmcp-discussion>` also links every `@handle` in a comment to that member's profile page (for a signed-in
|
|
34
66
|
reader; an anonymous one reads the mention as text), and takes live updates through its `realtime` property
|
|
35
67
|
(below).
|
|
@@ -97,23 +129,27 @@ import { KbDiscussion } from '@blogmcp/community/react' // a client component
|
|
|
97
129
|
<KbDiscussion articleId={article.id} apiBase="/api/community" signInHref="/sign-in" />
|
|
98
130
|
```
|
|
99
131
|
|
|
100
|
-
`KbNoticeForm`, `KbMyCommunity`, `KbNotificationCentre`, `KbBadge`, `KbMemberSettings`, `KbProfile
|
|
101
|
-
`KbWelcome`
|
|
132
|
+
`KbNoticeForm`, `KbMyCommunity`, `KbNotificationCentre`, `KbBadge`, `KbMemberSettings`, `KbProfile`,
|
|
133
|
+
`KbWelcome` and the forum's `KbForum`, `KbForumCategory`, `KbTopic`, `KbForumSearch`, `KbFollowButton` and
|
|
134
|
+
`KbForumModeration` work the same way. Each wrapper mounts its element after hydration and
|
|
102
135
|
removes it on unmount. It renders a single empty `<div data-blogmcp-community="…">` as the mount point: the
|
|
103
136
|
discussion is part of the page's flow, so the element goes where the wrapper is.
|
|
104
137
|
|
|
105
138
|
`mountDiscussion(o)`, `mountNoticeForm(o)`, `mountMyCommunity(o)`, `mountNotificationCentre(o)`, `mountBadge(o)`,
|
|
106
|
-
`mountMemberSettings(o)`, `mountProfile(o)
|
|
107
|
-
|
|
139
|
+
`mountMemberSettings(o)`, `mountProfile(o)`, `mountWelcome(o)` and the forum's `mountForum(o)`,
|
|
140
|
+
`mountForumCategory(o)`, `mountTopic(o)`, `mountForumSearch(o)`, `mountFollowButton(o)` and
|
|
141
|
+
`mountForumModeration(o)` do the same from any client-side hook. Each returns the unmount function. The tag names
|
|
142
|
+
are exported too (`DISCUSSION_ELEMENT_TAG` … `FORUM_MODERATION_ELEMENT_TAG`), and `defineForumElement()` and its
|
|
143
|
+
siblings register one element alone.
|
|
108
144
|
|
|
109
145
|
**Plain HTML**
|
|
110
146
|
|
|
111
147
|
```html
|
|
112
148
|
<blogmcp-discussion article-id="…" api-base="/api/community" sign-in-href="/prihlaseni"></blogmcp-discussion>
|
|
113
|
-
<script src="https://cdn.jsdelivr.net/npm/@blogmcp/community@0.
|
|
149
|
+
<script src="https://cdn.jsdelivr.net/npm/@blogmcp/community@0.3.0/dist/blogmcp-community.global.js" nonce="…"></script>
|
|
114
150
|
```
|
|
115
151
|
|
|
116
|
-
The script build (`@blogmcp/community/global`) registers all
|
|
152
|
+
The script build (`@blogmcp/community/global`) registers all fourteen elements. It exposes
|
|
117
153
|
`window.BlogmcpCommunity` and gives the elements its own `nonce`.
|
|
118
154
|
|
|
119
155
|
## Attributes
|
|
@@ -140,10 +176,22 @@ The script build (`@blogmcp/community/global`) registers all eight elements. It
|
|
|
140
176
|
| `<blogmcp-profile>` | `handle` | the member's handle (an `@` in front is fine) |
|
|
141
177
|
| | `sign-in-href` | your sign-in page (profiles are for signed-in readers) |
|
|
142
178
|
| `<blogmcp-welcome>` | `sign-in-href` | your sign-in page (in the profile link's place, for a visitor) |
|
|
179
|
+
| `<blogmcp-forum>` | `sign-in-href` | your sign-in page (a visitor's link) |
|
|
180
|
+
| `<blogmcp-forum-category>` | `slug` | the category's slug |
|
|
181
|
+
| | `sign-in-href` | your sign-in page |
|
|
182
|
+
| `<blogmcp-topic>` | `conversation-id` | the topic (its conversation id) |
|
|
183
|
+
| | `sign-in-href` | your sign-in page |
|
|
184
|
+
| | `poll-ms` | how often to check for new posts while the topic is in view (default 20000; 0 = off) |
|
|
185
|
+
| `<blogmcp-forum-search>` | `sign-in-href` | your sign-in page |
|
|
186
|
+
| `<blogmcp-follow-button>` | `target-kind` | `conversation` (a topic, an article discussion) or `category` |
|
|
187
|
+
| | `target-id` | its id |
|
|
188
|
+
| | `following` | `true` / `false` when your page knows it (left out: the element reads the member's follows) |
|
|
189
|
+
| `<blogmcp-forum-moderation>` | `category-id` | one of the moderator's categories only (left out: all of them) |
|
|
143
190
|
|
|
144
191
|
`routes` names your community pages: `statementPath` (with `{id}`), `myCommunityPath`, `rulesPath`,
|
|
145
192
|
`reportPath`, `noticesPath` and, with the module, `profilePath` (with `{handle}`), `settingsPath`,
|
|
146
|
-
`notificationsPath`, `welcomePath` and `discussionsPath
|
|
193
|
+
`notificationsPath`, `welcomePath` and `discussionsPath`, and with the forum `forumPath`, `categoryPath` (with
|
|
194
|
+
`{slug}`), `topicPath` (with `{id}`, the topic's conversation id) and `searchPath`. Each is a full path on your site, used as it is. A page you leave out
|
|
147
195
|
falls back to the managed blog's pages: `${site-base}/community/…`. `articlePath` (with `{slug}`; no default)
|
|
148
196
|
is your article page — the managed blogs' `/blog/articles/{slug}`, a shop's `/blog/{slug}`: the notification
|
|
149
197
|
centre links a reply or a mention to its message there (`…/<slug>#bcm-msg-<seq>`), and without it those rows stay
|
|
@@ -160,7 +208,9 @@ A `transport` property replaces the HTTP layer, for tests.
|
|
|
160
208
|
## Live updates (`realtime`)
|
|
161
209
|
|
|
162
210
|
The discussion keeps itself fresh by polling. For live updates, import the SDK's realtime entry yourself and pass
|
|
163
|
-
its `createRealtimeSession` as the discussion's `realtime` property (a property, never an attribute)
|
|
211
|
+
its `createRealtimeSession` as the discussion's `realtime` property (a property, never an attribute) — or the
|
|
212
|
+
topic's: `<blogmcp-topic>` takes it the same way (a change of the topic's header, its title or state, reads the
|
|
213
|
+
topic again). Your bundle
|
|
164
214
|
then needs `centrifuge` (≥ 5.7), the entry's peer dependency; the elements never import either, so a site
|
|
165
215
|
without it ships no socket code.
|
|
166
216
|
|
|
@@ -214,7 +264,8 @@ reads it once, clears it from the address bar, and sends it only when the member
|
|
|
214
264
|
(`settingsPath`) where kb-api's e-mails point.
|
|
215
265
|
|
|
216
266
|
Events (bubbling, composed):
|
|
217
|
-
- `bcm-posted`, `{ state: 'visible' | 'held' }`: the reader's comment went out;
|
|
267
|
+
- `bcm-posted`, `{ state: 'visible' | 'held' }`: the reader's comment (or, in a topic, post) went out;
|
|
268
|
+
- `bcm-topic-created`, `{ conversationId, state: 'visible' | 'held' }`: the member opened a topic;
|
|
218
269
|
- `bcm-notice-submitted`, `{ contactKept }`: a notice was received.
|
|
219
270
|
|
|
220
271
|
## Look
|
|
@@ -237,8 +288,9 @@ The properties are `--bcm-bg`, `-fg`, `-muted`, `-line`, `-soft`, `-accent`, `-a
|
|
|
237
288
|
|
|
238
289
|
```bash
|
|
239
290
|
npm run build # ESM + the <script> build (+ size budget, 200 KiB gzip)
|
|
240
|
-
npm test # vitest (happy-dom): controllers, store, onboarding, outcomes, elements, text-only and closed-path scans
|
|
291
|
+
npm test # vitest (happy-dom): controllers, store, onboarding, outcomes, elements, the forum's six, text-only and closed-path scans
|
|
241
292
|
npm run test:e2e # Playwright: desktop + iPhone profile + a plain bundler, mocked community API (ports 8286/8287);
|
|
242
293
|
# m2.e2e.ts drives the centre (its link to a reply's message), the badge, the settings,
|
|
243
|
-
# a profile, the welcome page and the composer's mention limit
|
|
294
|
+
# a profile, the welcome page and the composer's mention limit; plain-bundler.e2e.ts mounts
|
|
295
|
+
# M1's, M2's and the forum's elements from dist/ (a topic opened from a category included)
|
|
244
296
|
```
|