@commonpub/layer 0.1.3 → 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.
|
@@ -18,16 +18,23 @@ export function useMirrorContent(fedContent: Ref<Record<string, unknown> | null>
|
|
|
18
18
|
|
|
19
19
|
const title = (fc.title as string) || 'Untitled';
|
|
20
20
|
|
|
21
|
-
// Parse block content:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (typeof content === 'string'
|
|
30
|
-
|
|
21
|
+
// Parse block content: prefer cpub:blocks (full fidelity from CommonPub instances),
|
|
22
|
+
// fall back to HTML content (from non-CommonPub instances or legacy federation)
|
|
23
|
+
let content: unknown;
|
|
24
|
+
if (Array.isArray(fc.cpubBlocks) && fc.cpubBlocks.length > 0) {
|
|
25
|
+
// CommonPub→CommonPub: original block structure preserved
|
|
26
|
+
content = fc.cpubBlocks;
|
|
27
|
+
} else {
|
|
28
|
+
content = fc.content;
|
|
29
|
+
if (typeof content === 'string') {
|
|
30
|
+
const trimmed = content.trim();
|
|
31
|
+
if (trimmed.startsWith('[[') || trimmed.startsWith('[["')) {
|
|
32
|
+
try { content = JSON.parse(trimmed); } catch { /* keep as string */ }
|
|
33
|
+
}
|
|
34
|
+
// If still a string (HTML from federation), wrap as BlockTuple array
|
|
35
|
+
if (typeof content === 'string' && content.trim()) {
|
|
36
|
+
content = [['paragraph', { html: content }]];
|
|
37
|
+
}
|
|
31
38
|
}
|
|
32
39
|
}
|
|
33
40
|
|
|
@@ -76,16 +83,6 @@ export function useMirrorContent(fedContent: Ref<Record<string, unknown> | null>
|
|
|
76
83
|
} satisfies ContentViewData;
|
|
77
84
|
});
|
|
78
85
|
|
|
79
|
-
const viewComponent = computed(() => {
|
|
80
|
-
switch (contentType.value) {
|
|
81
|
-
case 'article': return resolveComponent('ViewsArticleView');
|
|
82
|
-
case 'blog': return resolveComponent('ViewsBlogView');
|
|
83
|
-
case 'explainer': return resolveComponent('ViewsExplainerView');
|
|
84
|
-
case 'project': return resolveComponent('ViewsProjectView');
|
|
85
|
-
default: return null;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
86
|
const originDomain = computed(() => (fedContent.value?.originDomain as string) || 'unknown');
|
|
90
87
|
const originUrl = computed(() => (fedContent.value?.url as string) || null);
|
|
91
88
|
const authorHandle = computed(() => {
|
|
@@ -97,7 +94,6 @@ export function useMirrorContent(fedContent: Ref<Record<string, unknown> | null>
|
|
|
97
94
|
contentType,
|
|
98
95
|
actor,
|
|
99
96
|
transformedContent,
|
|
100
|
-
viewComponent,
|
|
101
97
|
originDomain,
|
|
102
98
|
originUrl,
|
|
103
99
|
authorHandle,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commonpub/layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"files": [
|
|
@@ -45,15 +45,15 @@
|
|
|
45
45
|
"vue": "^3.4.0",
|
|
46
46
|
"vue-router": "^4.3.0",
|
|
47
47
|
"zod": "^4.3.6",
|
|
48
|
+
"@commonpub/auth": "0.5.0",
|
|
48
49
|
"@commonpub/config": "0.7.0",
|
|
49
50
|
"@commonpub/docs": "0.5.0",
|
|
50
|
-
"@commonpub/auth": "0.5.0",
|
|
51
51
|
"@commonpub/editor": "0.5.0",
|
|
52
52
|
"@commonpub/learning": "0.5.0",
|
|
53
|
-
"@commonpub/
|
|
54
|
-
"@commonpub/
|
|
55
|
-
"@commonpub/
|
|
56
|
-
"@commonpub/
|
|
53
|
+
"@commonpub/protocol": "0.9.4",
|
|
54
|
+
"@commonpub/schema": "0.8.8",
|
|
55
|
+
"@commonpub/server": "2.7.0",
|
|
56
|
+
"@commonpub/ui": "0.7.1"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {}
|
|
59
59
|
}
|
|
@@ -57,16 +57,7 @@ const enrichedContent = computed(() => {
|
|
|
57
57
|
return { ...content.value, readTime: readTime.value };
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
//
|
|
61
|
-
const viewComponent = computed(() => {
|
|
62
|
-
switch (contentType.value) {
|
|
63
|
-
case 'article': return resolveComponent('ViewsArticleView');
|
|
64
|
-
case 'blog': return resolveComponent('ViewsBlogView');
|
|
65
|
-
case 'explainer': return resolveComponent('ViewsExplainerView');
|
|
66
|
-
case 'project': return resolveComponent('ViewsProjectView');
|
|
67
|
-
default: return null;
|
|
68
|
-
}
|
|
69
|
-
});
|
|
60
|
+
// Content type used for conditional view component rendering in template
|
|
70
61
|
|
|
71
62
|
// Related content
|
|
72
63
|
const { data: related } = await useFetch<PaginatedResponse<Serialized<ContentListItem>>>('/api/content', {
|
|
@@ -91,12 +82,11 @@ onMounted(() => {
|
|
|
91
82
|
</NuxtLink>
|
|
92
83
|
</div>
|
|
93
84
|
|
|
94
|
-
<!-- Specialized view -->
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/>
|
|
85
|
+
<!-- Specialized view by content type -->
|
|
86
|
+
<ViewsProjectView v-if="contentType === 'project'" :content="(enrichedContent as any)" />
|
|
87
|
+
<ViewsArticleView v-else-if="contentType === 'article'" :content="(enrichedContent as any)" />
|
|
88
|
+
<ViewsBlogView v-else-if="contentType === 'blog'" :content="(enrichedContent as any)" />
|
|
89
|
+
<ViewsExplainerView v-else-if="contentType === 'explainer'" :content="(enrichedContent as any)" />
|
|
100
90
|
|
|
101
91
|
<!-- Fallback: generic view for unknown types -->
|
|
102
92
|
<article v-else class="cpub-view">
|
package/pages/mirror/[id].vue
CHANGED
|
@@ -7,8 +7,8 @@ const id = route.params.id as string;
|
|
|
7
7
|
const { data: fedContent, error, pending } = await useFetch<Record<string, unknown>>(`/api/federation/content/${id}`);
|
|
8
8
|
|
|
9
9
|
const {
|
|
10
|
+
contentType,
|
|
10
11
|
transformedContent,
|
|
11
|
-
viewComponent,
|
|
12
12
|
originDomain,
|
|
13
13
|
originUrl,
|
|
14
14
|
authorHandle,
|
|
@@ -51,15 +51,13 @@ useSeoMeta({
|
|
|
51
51
|
</div>
|
|
52
52
|
</div>
|
|
53
53
|
|
|
54
|
-
<!-- Reuse existing content view
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
:federated-id="id"
|
|
60
|
-
/>
|
|
54
|
+
<!-- Reuse existing content view components by type -->
|
|
55
|
+
<ViewsProjectView v-if="contentType === 'project'" :content="transformedContent" :federated-id="id" />
|
|
56
|
+
<ViewsArticleView v-else-if="contentType === 'article'" :content="transformedContent" :federated-id="id" />
|
|
57
|
+
<ViewsBlogView v-else-if="contentType === 'blog'" :content="transformedContent" :federated-id="id" />
|
|
58
|
+
<ViewsExplainerView v-else-if="contentType === 'explainer'" :content="transformedContent" :federated-id="id" />
|
|
61
59
|
|
|
62
|
-
<!-- Fallback for non-CommonPub content -->
|
|
60
|
+
<!-- Fallback for non-CommonPub content (Mastodon notes, Lemmy posts, etc.) -->
|
|
63
61
|
<article v-else class="cpub-mirror-fallback">
|
|
64
62
|
<div class="cpub-mirror-container">
|
|
65
63
|
<img v-if="transformedContent.coverImageUrl" :src="transformedContent.coverImageUrl" :alt="transformedContent.title" class="cpub-mirror-cover" />
|