@blogmcp/community 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +243 -2
- package/dist/blogmcp-community.global.js +10 -0
- package/dist/chunks/mount-WadUnaTa.js +6436 -0
- package/dist/core/attrs.d.ts +99 -0
- package/dist/core/avatars.d.ts +16 -0
- package/dist/core/badge.d.ts +30 -0
- package/dist/core/centre.d.ts +28 -0
- package/dist/core/client.d.ts +27 -0
- package/dist/core/digest-token.d.ts +2 -0
- package/dist/core/discussion.d.ts +175 -0
- package/dist/core/download.d.ts +4 -0
- package/dist/core/format.d.ts +24 -0
- package/dist/core/i18n.d.ts +28 -0
- package/dist/core/names.d.ts +15 -0
- package/dist/core/notice.d.ts +50 -0
- package/dist/core/onboarding.d.ts +92 -0
- package/dist/core/outcomes.d.ts +29 -0
- package/dist/core/panel.d.ts +96 -0
- package/dist/core/profile.d.ts +40 -0
- package/dist/core/push.d.ts +63 -0
- package/dist/core/realtime.d.ts +35 -0
- package/dist/core/receipt.d.ts +5 -0
- package/dist/core/settings.d.ts +53 -0
- package/dist/core/text.d.ts +35 -0
- package/dist/core/turnstile.d.ts +33 -0
- package/dist/element.d.ts +47 -0
- package/dist/global.d.ts +11 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +45 -0
- package/dist/mount.d.ts +105 -0
- package/dist/react.d.ts +28 -0
- package/dist/react.js +55 -0
- package/dist/ui/AuthorAvatar.vue.d.ts +11 -0
- package/dist/ui/BadgeView.vue.d.ts +13 -0
- package/dist/ui/ConfirmDialog.vue.d.ts +20 -0
- package/dist/ui/DiscussionView.vue.d.ts +44 -0
- package/dist/ui/LinkedText.vue.d.ts +6 -0
- package/dist/ui/MemberSettingsView.vue.d.ts +13 -0
- package/dist/ui/MessageComposer.vue.d.ts +26 -0
- package/dist/ui/MessageItem.vue.d.ts +6 -0
- package/dist/ui/MessageMenu.vue.d.ts +10 -0
- package/dist/ui/MyCommunityView.vue.d.ts +16 -0
- package/dist/ui/NoticeFormView.vue.d.ts +26 -0
- package/dist/ui/NoticeStatusView.vue.d.ts +15 -0
- package/dist/ui/NotificationCentreView.vue.d.ts +12 -0
- package/dist/ui/OnboardingSteps.vue.d.ts +11 -0
- package/dist/ui/ProfileView.vue.d.ts +13 -0
- package/dist/ui/ReactionBar.vue.d.ts +13 -0
- package/dist/ui/ReportDialog.vue.d.ts +15 -0
- package/dist/ui/StatementView.vue.d.ts +15 -0
- package/dist/ui/WelcomeView.vue.d.ts +12 -0
- package/dist/ui/context.d.ts +21 -0
- package/dist/ui/discussion-context.d.ts +19 -0
- package/dist/ui/types.d.ts +7 -0
- package/dist/version.d.ts +1 -0
- package/dist/vue.d.ts +200 -0
- package/dist/vue.js +201 -0
- package/package.json +80 -4
- package/src/core/attrs.ts +186 -0
- package/src/core/avatars.ts +44 -0
- package/src/core/badge.ts +120 -0
- package/src/core/centre.ts +136 -0
- package/src/core/client.ts +54 -0
- package/src/core/digest-token.ts +26 -0
- package/src/core/discussion.ts +876 -0
- package/src/core/download.ts +21 -0
- package/src/core/format.ts +112 -0
- package/src/core/i18n.ts +49 -0
- package/src/core/names.ts +51 -0
- package/src/core/notice.ts +178 -0
- package/src/core/onboarding.ts +492 -0
- package/src/core/outcomes.ts +86 -0
- package/src/core/panel.ts +446 -0
- package/src/core/profile.ts +144 -0
- package/src/core/push.ts +174 -0
- package/src/core/realtime.ts +39 -0
- package/src/core/receipt.ts +28 -0
- package/src/core/settings.ts +363 -0
- package/src/core/text.ts +174 -0
- package/src/core/turnstile.ts +98 -0
- package/src/element.ts +165 -0
- package/src/global.ts +26 -0
- package/src/index.ts +70 -0
- package/src/mount.ts +234 -0
- package/src/react.ts +97 -0
- package/src/shims.d.ts +11 -0
- package/src/ui/AuthorAvatar.vue +26 -0
- package/src/ui/BadgeView.vue +51 -0
- package/src/ui/ConfirmDialog.vue +38 -0
- package/src/ui/DiscussionView.vue +334 -0
- package/src/ui/LinkedText.vue +24 -0
- package/src/ui/MemberSettingsView.vue +175 -0
- package/src/ui/MessageComposer.vue +141 -0
- package/src/ui/MessageItem.vue +223 -0
- package/src/ui/MessageMenu.vue +67 -0
- package/src/ui/MyCommunityView.vue +378 -0
- package/src/ui/NoticeFormView.vue +244 -0
- package/src/ui/NoticeStatusView.vue +82 -0
- package/src/ui/NotificationCentreView.vue +159 -0
- package/src/ui/OnboardingSteps.vue +174 -0
- package/src/ui/ProfileView.vue +91 -0
- package/src/ui/ReactionBar.vue +41 -0
- package/src/ui/ReportDialog.vue +88 -0
- package/src/ui/StatementView.vue +141 -0
- package/src/ui/WelcomeView.vue +72 -0
- package/src/ui/context.ts +75 -0
- package/src/ui/discussion-context.ts +30 -0
- package/src/ui/styles.css +259 -0
- package/src/ui/types.ts +7 -0
- package/src/version.ts +3 -0
- package/src/vue.ts +242 -0
package/src/vue.ts
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<KbDiscussion>`, `<KbNoticeForm>`, `<KbMyCommunity>` and (M2) `<KbNotificationCentre>`, `<KbBadge>`,
|
|
3
|
+
* `<KbMemberSettings>`, `<KbProfile>`, `<KbWelcome>` for Vue / Nuxt: each mounts its element on the
|
|
4
|
+
* client, after hydration, and removes it on unmount. Each renders one empty `<div>` as the mount point —
|
|
5
|
+
* nothing else, on the server or the client — so the element sits where the component does and the page's
|
|
6
|
+
* markup is otherwise the site's alone.
|
|
7
|
+
*
|
|
8
|
+
* <KbDiscussion :article-id="article.id" :sign-in-href="localePath('/login')" />
|
|
9
|
+
*
|
|
10
|
+
* A site served under a path names it: `site-base="/blog"` on a managed blog (its proxy is `/blog/api/community`;
|
|
11
|
+
* the host's own `/api/` there is kb-api, which no element may call).
|
|
12
|
+
*/
|
|
13
|
+
import { defineComponent, h, onBeforeUnmount, onMounted, ref, watch, type PropType } from 'vue'
|
|
14
|
+
import type { CommunityTransport } from '@blogmcp/sdk/community'
|
|
15
|
+
import type { CommunityRoutes } from './core/attrs'
|
|
16
|
+
import type { DiscussionRealtime } from './core/realtime'
|
|
17
|
+
import type {
|
|
18
|
+
MountBadgeOptions,
|
|
19
|
+
MountDiscussionOptions,
|
|
20
|
+
MountMemberSettingsOptions,
|
|
21
|
+
MountMyCommunityOptions,
|
|
22
|
+
MountNoticeFormOptions,
|
|
23
|
+
MountNotificationCentreOptions,
|
|
24
|
+
MountProfileOptions,
|
|
25
|
+
MountWelcomeOptions,
|
|
26
|
+
} from './mount'
|
|
27
|
+
|
|
28
|
+
type Mounter<O> = (o: O & { container: Element }) => () => void
|
|
29
|
+
|
|
30
|
+
/** The shared life of a wrapper: mount after hydration, remount when an option changes, unmount with it. */
|
|
31
|
+
function useMount<O extends object>(kind: string, options: () => O, load: () => Promise<Mounter<O>>) {
|
|
32
|
+
const host = ref<HTMLElement | null>(null)
|
|
33
|
+
let unmount: (() => void) | null = null
|
|
34
|
+
let gone = false
|
|
35
|
+
let ticket = 0
|
|
36
|
+
async function mount(): Promise<void> {
|
|
37
|
+
const mine = ++ticket
|
|
38
|
+
const mountFn = await load()
|
|
39
|
+
if (gone || mine !== ticket || !host.value) return
|
|
40
|
+
unmount?.()
|
|
41
|
+
unmount = mountFn({ ...options(), container: host.value })
|
|
42
|
+
}
|
|
43
|
+
onMounted(() => void mount())
|
|
44
|
+
watch(
|
|
45
|
+
() => JSON.stringify(options(), (_k, v: unknown) => (typeof v === 'function' ? '[fn]' : v)),
|
|
46
|
+
() => void mount(),
|
|
47
|
+
)
|
|
48
|
+
onBeforeUnmount(() => {
|
|
49
|
+
gone = true
|
|
50
|
+
unmount?.()
|
|
51
|
+
unmount = null
|
|
52
|
+
})
|
|
53
|
+
return () => h('div', { ref: host, 'data-blogmcp-community': kind })
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function defined<T extends object>(o: T): T {
|
|
57
|
+
const out = {} as T
|
|
58
|
+
for (const [k, v] of Object.entries(o)) if (v !== undefined && v !== null) (out as Record<string, unknown>)[k] = v
|
|
59
|
+
return out
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const KbDiscussion = defineComponent({
|
|
63
|
+
name: 'KbDiscussion',
|
|
64
|
+
props: {
|
|
65
|
+
articleId: { type: String, required: true },
|
|
66
|
+
apiBase: String,
|
|
67
|
+
siteBase: String,
|
|
68
|
+
lang: String,
|
|
69
|
+
signInHref: String,
|
|
70
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
71
|
+
pollMs: Number,
|
|
72
|
+
nonce: String,
|
|
73
|
+
transport: Function as PropType<CommunityTransport>,
|
|
74
|
+
/** M2: `createRealtimeSession` of `@blogmcp/sdk/community/realtime`. */
|
|
75
|
+
realtime: Function as PropType<DiscussionRealtime>,
|
|
76
|
+
},
|
|
77
|
+
setup(props) {
|
|
78
|
+
return useMount<MountDiscussionOptions>(
|
|
79
|
+
'discussion',
|
|
80
|
+
() => defined({ ...props }) as MountDiscussionOptions,
|
|
81
|
+
async () => (await import('./mount')).mountDiscussion as Mounter<MountDiscussionOptions>,
|
|
82
|
+
)
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
export const KbNoticeForm = defineComponent({
|
|
87
|
+
name: 'KbNoticeForm',
|
|
88
|
+
props: {
|
|
89
|
+
target: Object as PropType<MountNoticeFormOptions['target']>,
|
|
90
|
+
articleId: String,
|
|
91
|
+
apiBase: String,
|
|
92
|
+
siteBase: String,
|
|
93
|
+
lang: String,
|
|
94
|
+
turnstileSiteKey: String,
|
|
95
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
96
|
+
nonce: String,
|
|
97
|
+
transport: Function as PropType<CommunityTransport>,
|
|
98
|
+
},
|
|
99
|
+
setup(props) {
|
|
100
|
+
return useMount<MountNoticeFormOptions>(
|
|
101
|
+
'notice-form',
|
|
102
|
+
() => defined({ ...props }) as MountNoticeFormOptions,
|
|
103
|
+
async () => (await import('./mount')).mountNoticeForm as Mounter<MountNoticeFormOptions>,
|
|
104
|
+
)
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export const KbMyCommunity = defineComponent({
|
|
109
|
+
name: 'KbMyCommunity',
|
|
110
|
+
props: {
|
|
111
|
+
decisionId: String,
|
|
112
|
+
apiBase: String,
|
|
113
|
+
siteBase: String,
|
|
114
|
+
lang: String,
|
|
115
|
+
signInHref: String,
|
|
116
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
117
|
+
nonce: String,
|
|
118
|
+
transport: Function as PropType<CommunityTransport>,
|
|
119
|
+
},
|
|
120
|
+
setup(props) {
|
|
121
|
+
return useMount<MountMyCommunityOptions>(
|
|
122
|
+
'my-community',
|
|
123
|
+
() => defined({ ...props }) as MountMyCommunityOptions,
|
|
124
|
+
async () => (await import('./mount')).mountMyCommunity as Mounter<MountMyCommunityOptions>,
|
|
125
|
+
)
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
export const KbNotificationCentre = defineComponent({
|
|
130
|
+
name: 'KbNotificationCentre',
|
|
131
|
+
props: {
|
|
132
|
+
apiBase: String,
|
|
133
|
+
siteBase: String,
|
|
134
|
+
lang: String,
|
|
135
|
+
signInHref: String,
|
|
136
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
137
|
+
nonce: String,
|
|
138
|
+
transport: Function as PropType<CommunityTransport>,
|
|
139
|
+
},
|
|
140
|
+
setup(props) {
|
|
141
|
+
return useMount<MountNotificationCentreOptions>(
|
|
142
|
+
'notification-centre',
|
|
143
|
+
() => defined({ ...props }) as MountNotificationCentreOptions,
|
|
144
|
+
async () => (await import('./mount')).mountNotificationCentre as Mounter<MountNotificationCentreOptions>,
|
|
145
|
+
)
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
export const KbBadge = defineComponent({
|
|
150
|
+
name: 'KbBadge',
|
|
151
|
+
props: {
|
|
152
|
+
apiBase: String,
|
|
153
|
+
siteBase: String,
|
|
154
|
+
lang: String,
|
|
155
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
156
|
+
pollMs: Number,
|
|
157
|
+
nonce: String,
|
|
158
|
+
transport: Function as PropType<CommunityTransport>,
|
|
159
|
+
},
|
|
160
|
+
setup(props) {
|
|
161
|
+
return useMount<MountBadgeOptions>(
|
|
162
|
+
'badge',
|
|
163
|
+
() => defined({ ...props }) as MountBadgeOptions,
|
|
164
|
+
async () => (await import('./mount')).mountBadge as Mounter<MountBadgeOptions>,
|
|
165
|
+
)
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
export const KbMemberSettings = defineComponent({
|
|
170
|
+
name: 'KbMemberSettings',
|
|
171
|
+
props: {
|
|
172
|
+
apiBase: String,
|
|
173
|
+
siteBase: String,
|
|
174
|
+
lang: String,
|
|
175
|
+
swPath: String,
|
|
176
|
+
signInHref: String,
|
|
177
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
178
|
+
nonce: String,
|
|
179
|
+
transport: Function as PropType<CommunityTransport>,
|
|
180
|
+
},
|
|
181
|
+
setup(props) {
|
|
182
|
+
return useMount<MountMemberSettingsOptions>(
|
|
183
|
+
'member-settings',
|
|
184
|
+
() => defined({ ...props }) as MountMemberSettingsOptions,
|
|
185
|
+
async () => (await import('./mount')).mountMemberSettings as Mounter<MountMemberSettingsOptions>,
|
|
186
|
+
)
|
|
187
|
+
},
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
export const KbProfile = defineComponent({
|
|
191
|
+
name: 'KbProfile',
|
|
192
|
+
props: {
|
|
193
|
+
handle: { type: String, required: true },
|
|
194
|
+
apiBase: String,
|
|
195
|
+
siteBase: String,
|
|
196
|
+
lang: String,
|
|
197
|
+
signInHref: String,
|
|
198
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
199
|
+
nonce: String,
|
|
200
|
+
transport: Function as PropType<CommunityTransport>,
|
|
201
|
+
},
|
|
202
|
+
setup(props) {
|
|
203
|
+
return useMount<MountProfileOptions>(
|
|
204
|
+
'profile',
|
|
205
|
+
() => defined({ ...props }) as MountProfileOptions,
|
|
206
|
+
async () => (await import('./mount')).mountProfile as Mounter<MountProfileOptions>,
|
|
207
|
+
)
|
|
208
|
+
},
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
export const KbWelcome = defineComponent({
|
|
212
|
+
name: 'KbWelcome',
|
|
213
|
+
props: {
|
|
214
|
+
apiBase: String,
|
|
215
|
+
siteBase: String,
|
|
216
|
+
lang: String,
|
|
217
|
+
signInHref: String,
|
|
218
|
+
routes: Object as PropType<CommunityRoutes>,
|
|
219
|
+
nonce: String,
|
|
220
|
+
transport: Function as PropType<CommunityTransport>,
|
|
221
|
+
},
|
|
222
|
+
setup(props) {
|
|
223
|
+
return useMount<MountWelcomeOptions>(
|
|
224
|
+
'welcome',
|
|
225
|
+
() => defined({ ...props }) as MountWelcomeOptions,
|
|
226
|
+
async () => (await import('./mount')).mountWelcome as Mounter<MountWelcomeOptions>,
|
|
227
|
+
)
|
|
228
|
+
},
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
export type {
|
|
232
|
+
MountDiscussionOptions,
|
|
233
|
+
MountNoticeFormOptions,
|
|
234
|
+
MountMyCommunityOptions,
|
|
235
|
+
MountNotificationCentreOptions,
|
|
236
|
+
MountBadgeOptions,
|
|
237
|
+
MountMemberSettingsOptions,
|
|
238
|
+
MountProfileOptions,
|
|
239
|
+
MountWelcomeOptions,
|
|
240
|
+
CommunityRoutes,
|
|
241
|
+
DiscussionRealtime,
|
|
242
|
+
}
|