@rimelight/cms 0.0.2 → 0.0.4
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/dist/bylines-Csggkl-g.d.mts +405 -0
- package/dist/index.d.mts +724 -0
- package/dist/index.mjs +2382 -0
- package/dist/integration.d.mts +33 -0
- package/dist/integration.mjs +161 -0
- package/dist/schema/index.d.mts +2063 -0
- package/dist/schema/index.mjs +176 -0
- package/dist/schema/sqlite.d.mts +2132 -0
- package/dist/schema/sqlite.mjs +137 -0
- package/dist/storage/index.d.mts +59 -0
- package/dist/storage/index.mjs +133 -0
- package/package.json +36 -18
- package/src/admin/api/media-file.ts +39 -0
- package/src/admin/api/media.ts +224 -0
- package/src/admin/layouts/CMSDashboardLayout.astro +191 -0
- package/src/admin/layouts/DefaultParentLayout.astro +50 -0
- package/src/admin/pages/assets.astro +424 -0
- package/src/admin/pages/byline-schema.astro +62 -0
- package/src/admin/pages/bylines.astro +16 -0
- package/src/admin/pages/categories.astro +21 -0
- package/src/admin/pages/content-types.astro +55 -0
- package/src/admin/pages/dashboard.astro +61 -0
- package/src/admin/pages/pages-edit.astro +595 -0
- package/src/admin/pages/pages-index.astro +146 -0
- package/src/admin/pages/pages-new.astro +130 -0
- package/src/admin/pages/pages-preview.astro +111 -0
- package/src/admin/pages/pages-review.astro +236 -0
- package/src/admin/pages/settings.astro +203 -0
- package/src/admin/pages/tags.astro +21 -0
- package/src/admin/pages/templates-edit.astro +234 -0
- package/src/admin/pages/templates-index.astro +95 -0
- package/src/admin/pages/templates-new.astro +193 -0
- package/src/admin/pages/users.astro +74 -0
- package/src/admin/pages/versions.astro +74 -0
- package/src/astro/BlockRenderer.astro +44 -102
- package/src/astro/PageRenderer.astro +12 -5
- package/src/astro/blocks/CalloutBlock.astro +7 -7
- package/src/astro/blocks/CardBlock.astro +5 -5
- package/src/astro/blocks/CodeBlock.astro +2 -2
- package/src/astro/blocks/FileTreeBlock.astro +7 -7
- package/src/astro/blocks/ImageBlock.astro +2 -2
- package/src/astro/blocks/OrderedListBlock.astro +2 -2
- package/src/astro/blocks/ParagraphBlock.astro +3 -3
- package/src/astro/blocks/SectionBlock.astro +6 -6
- package/src/astro/blocks/StepItemBlock.astro +3 -3
- package/src/astro/blocks/StepsBlock.astro +1 -1
- package/src/astro/blocks/TableBlock.astro +6 -6
- package/src/astro/blocks/TabsBlock.astro +9 -9
- package/src/astro/blocks/UnorderedListBlock.astro +2 -2
- package/src/astro/blocks/index.ts +35 -0
- package/src/client/components/RimelightBlock.tsx +19 -19
- package/src/client/components/RimelightBlockPicker.tsx +9 -13
- package/src/client/components/RimelightBylinesManager.tsx +438 -0
- package/src/client/components/RimelightEditor.tsx +3 -3
- package/src/client/components/RimelightPreview.tsx +37 -45
- package/src/client/components/RimelightPropertiesPanel.tsx +368 -26
- package/src/client/components/RimelightTaxonomyManager.tsx +369 -0
- package/src/client/components/RimelightTaxonomyMasterDetail.tsx +412 -0
- package/src/client/components/RimelightTemplateEditor.tsx +6 -8
- package/src/client/components/editors/CalloutEditor.tsx +2 -4
- package/src/client/components/editors/CardsEditor.tsx +2 -4
- package/src/client/components/editors/CodeEditor.tsx +1 -3
- package/src/client/components/editors/FileTreeEditor.tsx +2 -4
- package/src/client/components/editors/ImageEditor.tsx +3 -3
- package/src/client/components/editors/ParagraphEditor.tsx +2 -2
- package/src/client/components/editors/SceneEditor.tsx +6 -12
- package/src/client/components/editors/ScriptEditor.tsx +8 -16
- package/src/client/components/editors/SectionEditor.tsx +4 -4
- package/src/client/components/editors/StepItemEditor.tsx +2 -2
- package/src/client/components/editors/StepsEditor.tsx +2 -4
- package/src/client/components/editors/TabItemEditor.tsx +3 -3
- package/src/client/components/editors/TableEditor.tsx +5 -5
- package/src/client/components/editors/TabsEditor.tsx +2 -4
- package/src/client/components/index.ts +3 -0
- package/src/client/loader.ts +3 -0
- package/src/core/diff.ts +145 -0
- package/src/core/excerpt.ts +159 -0
- package/src/core/preview.ts +87 -0
- package/src/core/registry.ts +0 -86
- package/src/core/types/blocks.ts +6 -1
- package/src/core/types/bylines.ts +14 -0
- package/src/core/types/media.ts +13 -0
- package/src/core/types/taxonomies.ts +20 -0
- package/src/cron/scheduled.ts +57 -0
- package/src/docs/agent.ts +116 -0
- package/src/docs/config.ts +25 -0
- package/src/docs/index.ts +5 -0
- package/src/docs/routing.ts +104 -0
- package/src/docs/sidebar.ts +251 -0
- package/src/docs/toc.ts +47 -0
- package/src/env.d.ts +19 -0
- package/src/index.ts +57 -12
- package/src/integration.ts +250 -0
- package/src/loader/live.ts +254 -0
- package/src/markdown/index.ts +0 -1
- package/src/mcp/index.ts +228 -0
- package/src/schema/bylines.ts +23 -0
- package/src/schema/index.ts +3 -4
- package/src/schema/page_versions.ts +2 -0
- package/src/schema/pages.ts +2 -0
- package/src/schema/site_settings.ts +41 -0
- package/src/schema/sqlite.ts +344 -0
- package/src/schema/taxonomies.ts +49 -0
- package/src/services/bylines.ts +74 -0
- package/src/services/search-indexer.ts +61 -0
- package/src/services/site-settings.ts +108 -0
- package/src/services/taxonomies.ts +276 -0
- package/src/storage/index.ts +256 -0
- package/src/astro/blocks/ApiDocumentationBlock.astro +0 -350
- package/src/astro/blocks/DialogueBlock.astro +0 -23
- package/src/astro/blocks/LivePreviewBlock.astro +0 -27
- package/src/astro/blocks/SceneBlock.astro +0 -65
- package/src/astro/blocks/ScriptBlock.astro +0 -59
- package/src/core/template-sync.ts +0 -75
- package/src/markdown/parser.ts +0 -347
- package/src/migration-tools.ts +0 -334
- package/src/migration.ts +0 -155
- package/src/schema/component_dependencies.ts +0 -21
- package/src/schema/component_metadata.ts +0 -31
- package/src/schema/component_metadata_cache.ts +0 -15
- package/src/schema/component_versions.ts +0 -19
- package/src/search/sync.ts +0 -32
- package/src/services/component-metadata.ts +0 -134
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { BaseBlock } from "@rimelight/cms"
|
|
3
|
-
function filterProps(props: any[], options: { hide?: string[]; show?: string[] }): any[] {
|
|
4
|
-
if (options.show?.length) return props.filter((p: any) => options.show!.includes(p.name))
|
|
5
|
-
if (options.hide?.length) return props.filter((p: any) => !options.hide!.includes(p.name))
|
|
6
|
-
return props
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
interface Props {
|
|
10
|
-
block: BaseBlock
|
|
11
|
-
locale?: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const { block } = Astro.props
|
|
15
|
-
const { componentName, sections = {}, hide = [], show = [] } = block.props
|
|
16
|
-
const compMeta = block.props.meta
|
|
17
|
-
const themeCode = block.props.themeCode
|
|
18
|
-
|
|
19
|
-
const filterOpts: { hide?: string[]; show?: string[] } = { hide, show }
|
|
20
|
-
const props = filterProps(compMeta?.props ?? [], filterOpts)
|
|
21
|
-
const slots = compMeta?.slots ?? []
|
|
22
|
-
const emits = compMeta?.emits ?? []
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
{(sections.props !== false) && (
|
|
26
|
-
<div class="api-documentation-section mb-6">
|
|
27
|
-
<h3 class="text-lg font-semibold text-foreground mb-3">Props</h3>
|
|
28
|
-
{props.length > 0 ? (
|
|
29
|
-
<div class="overflow-x-auto">
|
|
30
|
-
<table class="w-full text-sm border-collapse">
|
|
31
|
-
<thead>
|
|
32
|
-
<tr class="border-b border-border">
|
|
33
|
-
<th class="text-left py-2 px-3 font-semibold">Name</th>
|
|
34
|
-
<th class="text-left py-2 px-3 font-semibold">Type</th>
|
|
35
|
-
<th class="text-left py-2 px-3 font-semibold">Required</th>
|
|
36
|
-
<th class="text-left py-2 px-3 font-semibold">Default</th>
|
|
37
|
-
<th class="text-left py-2 px-3 font-semibold">Description</th>
|
|
38
|
-
</tr>
|
|
39
|
-
</thead>
|
|
40
|
-
<tbody>
|
|
41
|
-
{props.map((prop: any) => (
|
|
42
|
-
<tr class="border-b border-border/50">
|
|
43
|
-
<td><span class="font-mono text-sm">{prop.name}</span></td>
|
|
44
|
-
<td><span class="font-mono text-xs text-muted-foreground">{prop.type}</span></td>
|
|
45
|
-
<td>{prop.required ? "Yes" : "No"}</td>
|
|
46
|
-
<td>{prop.default !== undefined ? <span class="font-mono text-xs text-muted-foreground">{prop.default}</span> : "—"}</td>
|
|
47
|
-
<td>{prop.description || "—"}</td>
|
|
48
|
-
</tr>
|
|
49
|
-
))}
|
|
50
|
-
</tbody>
|
|
51
|
-
</table>
|
|
52
|
-
</div>
|
|
53
|
-
) : (
|
|
54
|
-
<p class="text-sm italic text-muted-foreground">No props to display.</p>
|
|
55
|
-
)}
|
|
56
|
-
</div>
|
|
57
|
-
)}
|
|
58
|
-
|
|
59
|
-
{(sections.slots !== false) && (
|
|
60
|
-
<div class="api-documentation-section mb-6">
|
|
61
|
-
<h3 class="text-lg font-semibold text-foreground mb-3">Slots</h3>
|
|
62
|
-
{slots.length === 0 ? (
|
|
63
|
-
<p class="text-sm italic text-muted-foreground">No slots to display.</p>
|
|
64
|
-
) : (
|
|
65
|
-
<div class="overflow-x-auto">
|
|
66
|
-
<table class="w-full text-sm border-collapse">
|
|
67
|
-
<thead>
|
|
68
|
-
<tr class="border-b border-border">
|
|
69
|
-
<th class="text-left py-2 px-3 font-semibold">Slot</th>
|
|
70
|
-
<th class="text-left py-2 px-3 font-semibold">Type</th>
|
|
71
|
-
</tr>
|
|
72
|
-
</thead>
|
|
73
|
-
<tbody>
|
|
74
|
-
{slots.map((slot: any) => (
|
|
75
|
-
<tr class="border-b border-border/50">
|
|
76
|
-
<td class="py-2 px-3">
|
|
77
|
-
<span class="font-mono text-sm">{slot.name}</span>
|
|
78
|
-
</td>
|
|
79
|
-
<td class="py-2 px-3">
|
|
80
|
-
{Object.keys(slot.bindings || {}).length > 0 ? (
|
|
81
|
-
<span class="font-mono text-xs text-muted-foreground">
|
|
82
|
-
{Object.values(slot.bindings)[0]}
|
|
83
|
-
</span>
|
|
84
|
-
) : (
|
|
85
|
-
<span class="text-muted-foreground">-</span>
|
|
86
|
-
)}
|
|
87
|
-
</td>
|
|
88
|
-
</tr>
|
|
89
|
-
))}
|
|
90
|
-
</tbody>
|
|
91
|
-
</table>
|
|
92
|
-
</div>
|
|
93
|
-
)}
|
|
94
|
-
</div>
|
|
95
|
-
)}
|
|
96
|
-
|
|
97
|
-
{(sections.emits !== false) && (
|
|
98
|
-
<div class="api-documentation-section mb-6">
|
|
99
|
-
<h3 class="text-lg font-semibold text-foreground mb-3">Emits</h3>
|
|
100
|
-
{emits.length === 0 ? (
|
|
101
|
-
<p class="text-sm italic text-muted-foreground">No events emitted by this component.</p>
|
|
102
|
-
) : (
|
|
103
|
-
<div class="overflow-x-auto">
|
|
104
|
-
<table class="w-full text-sm border-collapse">
|
|
105
|
-
<thead>
|
|
106
|
-
<tr class="border-b border-border">
|
|
107
|
-
<th class="text-left py-2 px-3 font-semibold">Event</th>
|
|
108
|
-
<th class="text-left py-2 px-3 font-semibold">Payload</th>
|
|
109
|
-
</tr>
|
|
110
|
-
</thead>
|
|
111
|
-
<tbody>
|
|
112
|
-
{emits.map((emit: any) => (
|
|
113
|
-
<tr class="border-b border-border/50">
|
|
114
|
-
<td class="py-2 px-3">
|
|
115
|
-
<span class="font-mono text-sm">{emit.name}</span>
|
|
116
|
-
</td>
|
|
117
|
-
<td class="py-2 px-3">
|
|
118
|
-
<span class="font-mono text-xs text-muted-foreground">{emit.type}</span>
|
|
119
|
-
</td>
|
|
120
|
-
</tr>
|
|
121
|
-
))}
|
|
122
|
-
</tbody>
|
|
123
|
-
</table>
|
|
124
|
-
</div>
|
|
125
|
-
)}
|
|
126
|
-
</div>
|
|
127
|
-
)}
|
|
128
|
-
|
|
129
|
-
{(sections.theme !== false) && (
|
|
130
|
-
<div class="api-documentation-section mb-6">
|
|
131
|
-
<h3 class="text-lg font-semibold text-foreground mb-3">Theme</h3>
|
|
132
|
-
{themeCode ? (
|
|
133
|
-
<div class="api-theme-container relative border border-border rounded-lg overflow-hidden group mb-6" data-component={componentName}>
|
|
134
|
-
<div class="api-theme-collapse overflow-hidden max-h-[240px] relative transition-[max-height] duration-300 ease-in-out">
|
|
135
|
-
<div class="expressive-code m-0 border-0 rounded-none">
|
|
136
|
-
<figure class="frame m-0 border-0">
|
|
137
|
-
<pre class="language-ts overflow-x-auto m-0 border-0 rounded-none bg-muted"><code class="language-ts m-0">{themeCode}</code></pre>
|
|
138
|
-
</figure>
|
|
139
|
-
</div>
|
|
140
|
-
<div class="api-theme-fade absolute bottom-0 left-0 right-0 h-20 bg-gradient-to-t from-background to-transparent pointer-events-none transition-opacity duration-300"></div>
|
|
141
|
-
</div>
|
|
142
|
-
<div class="api-theme-trigger-bar absolute bottom-0 left-0 right-0 flex justify-center pb-3 bg-gradient-to-t from-background/90 via-background/70 to-transparent pt-12">
|
|
143
|
-
<button class="api-theme-btn px-4 py-1.5 text-xs font-semibold text-primary-foreground bg-primary hover:bg-primary/90 border border-border rounded-md shadow-md transition-all duration-200 cursor-pointer">Show theme config</button>
|
|
144
|
-
</div>
|
|
145
|
-
</div>
|
|
146
|
-
) : (
|
|
147
|
-
<p class="text-sm italic text-muted-foreground">No theme data available.</p>
|
|
148
|
-
)}
|
|
149
|
-
</div>
|
|
150
|
-
)}
|
|
151
|
-
|
|
152
|
-
{(sections.changelog) && (
|
|
153
|
-
<div class="api-documentation-section mb-6">
|
|
154
|
-
<h3 class="text-lg font-semibold text-foreground mb-3">Changelog</h3>
|
|
155
|
-
<div class="api-changelog-container group" data-component={componentName}>
|
|
156
|
-
<div class="api-changelog-loading py-6 flex flex-col gap-4">
|
|
157
|
-
<div class="animate-pulse h-4 bg-muted rounded w-1/4"></div>
|
|
158
|
-
<div class="animate-pulse h-3 bg-muted rounded w-full"></div>
|
|
159
|
-
<div class="animate-pulse h-3 bg-muted rounded w-5/6"></div>
|
|
160
|
-
</div>
|
|
161
|
-
<div class="api-changelog-content hidden">
|
|
162
|
-
<div class="api-changelog-timeline-target"></div>
|
|
163
|
-
</div>
|
|
164
|
-
<div class="api-changelog-empty hidden text-sm italic text-muted-foreground py-2">
|
|
165
|
-
No recent changes found.
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
</div>
|
|
169
|
-
)}
|
|
170
|
-
|
|
171
|
-
<script>
|
|
172
|
-
function escapeHtml(str: string): string {
|
|
173
|
-
return str
|
|
174
|
-
.replace(/&/g, "&")
|
|
175
|
-
.replace(/</g, "<")
|
|
176
|
-
.replace(/>/g, ">")
|
|
177
|
-
.replace(/"/g, """)
|
|
178
|
-
.replace(/'/g, "'");
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async function loadChangelog() {
|
|
182
|
-
if (typeof document === "undefined") return;
|
|
183
|
-
const containers = document.querySelectorAll('.api-changelog-container');
|
|
184
|
-
|
|
185
|
-
await Promise.all(
|
|
186
|
-
Array.from(containers).map(async (container) => {
|
|
187
|
-
if (container.getAttribute('data-changelog-ready') === 'true') return;
|
|
188
|
-
container.setAttribute('data-changelog-ready', 'true');
|
|
189
|
-
|
|
190
|
-
const component = container.getAttribute('data-component');
|
|
191
|
-
|
|
192
|
-
const loadingEl = container.querySelector('.api-changelog-loading') as HTMLElement;
|
|
193
|
-
const contentEl = container.querySelector('.api-changelog-content') as HTMLElement;
|
|
194
|
-
const targetEl = container.querySelector('.api-changelog-timeline-target') as HTMLElement;
|
|
195
|
-
const emptyEl = container.querySelector('.api-changelog-empty') as HTMLElement;
|
|
196
|
-
|
|
197
|
-
if (!component || !loadingEl || !contentEl || !targetEl || !emptyEl) return;
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
const res = await fetch(`/api/github/changelog?component=${component}`);
|
|
201
|
-
if (!res.ok) throw new Error();
|
|
202
|
-
const data: any[] = await res.json();
|
|
203
|
-
|
|
204
|
-
loadingEl.classList.add('hidden');
|
|
205
|
-
|
|
206
|
-
if (!data || data.length === 0) {
|
|
207
|
-
emptyEl.classList.remove('hidden');
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const timelineItems: Array<{ type: 'tag' | 'commit'; versionTag?: string; sha?: string; message?: string }> = [];
|
|
212
|
-
|
|
213
|
-
data.forEach((release: any) => {
|
|
214
|
-
if (release.tag) {
|
|
215
|
-
timelineItems.push({
|
|
216
|
-
type: 'tag',
|
|
217
|
-
versionTag: release.tag === 'unreleased' ? 'Soon' : release.tag
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (release.commits && Array.isArray(release.commits)) {
|
|
222
|
-
release.commits.forEach((commit: any) => {
|
|
223
|
-
timelineItems.push({
|
|
224
|
-
type: 'commit',
|
|
225
|
-
sha: commit.sha,
|
|
226
|
-
message: commit.message
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
let rootHtml = `<div data-orientation="vertical" data-slot="root" class="flex flex-col">`;
|
|
233
|
-
|
|
234
|
-
timelineItems.forEach((item, index) => {
|
|
235
|
-
const isLast = index === timelineItems.length - 1;
|
|
236
|
-
|
|
237
|
-
if (item.type === 'tag') {
|
|
238
|
-
rootHtml += `
|
|
239
|
-
<div data-slot="item" class="group relative flex flex-1 gap-3">
|
|
240
|
-
<div data-slot="container" class="relative flex items-center flex-col shrink-0">
|
|
241
|
-
<span data-slot="indicator" class="inline-flex items-center justify-center shrink-0 select-none rounded-full align-middle relative size-6 text-xs text-primary bg-primary/10 border border-primary/20 my-1">
|
|
242
|
-
<span class="i-lucide-tag size-3.5"></span>
|
|
243
|
-
</span>
|
|
244
|
-
${!isLast ? `<div data-slot="separator" class="flex-1 bg-elevated w-0.5 min-h-[16px]"></div>` : ''}
|
|
245
|
-
</div>
|
|
246
|
-
<div data-slot="wrapper" class="w-full py-1">
|
|
247
|
-
<div data-slot="title" class="font-medium text-foreground text-sm flex items-center">
|
|
248
|
-
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-mono font-semibold bg-primary/10 text-primary border border-primary/20">
|
|
249
|
-
${escapeHtml(item.versionTag || '')}
|
|
250
|
-
</span>
|
|
251
|
-
</div>
|
|
252
|
-
</div>
|
|
253
|
-
</div>
|
|
254
|
-
`;
|
|
255
|
-
} else {
|
|
256
|
-
const cleanedMessage = (item.message || '')
|
|
257
|
-
.replace(/#(\d+)/g, '<a href="https://github.com/Rimelight-Entertainment/rimelight/issues/$1" target="_blank" class="text-primary hover:underline">#$1</a>')
|
|
258
|
-
.replace(/`(.*?)`/g, '<code class="text-xs px-1.5 py-0.5 bg-muted border border-border rounded font-mono text-muted-foreground">$1</code>');
|
|
259
|
-
|
|
260
|
-
rootHtml += `
|
|
261
|
-
<div data-slot="item" class="group relative flex flex-1 gap-3">
|
|
262
|
-
<div data-slot="container" class="relative flex items-center flex-col shrink-0">
|
|
263
|
-
<span data-slot="indicator" class="inline-flex items-center justify-center shrink-0 select-none rounded-full align-middle relative size-6 text-xs text-muted bg-transparent">
|
|
264
|
-
<span class="size-1.5 rounded-full bg-border"></span>
|
|
265
|
-
</span>
|
|
266
|
-
${!isLast ? `<div data-slot="separator" class="flex-1 bg-elevated w-0.5 min-h-[16px]"></div>` : ''}
|
|
267
|
-
</div>
|
|
268
|
-
<div data-slot="wrapper" class="w-full py-1 flex items-start gap-2 text-sm">
|
|
269
|
-
<a href="https://github.com/Rimelight-Entertainment/rimelight/commit/${item.sha}" target="_blank" class="font-mono text-xs px-1.5 py-0.5 bg-muted border border-border rounded text-muted-foreground hover:text-foreground hover:border-border shrink-0">
|
|
270
|
-
${item.sha ? item.sha.slice(0, 7) : ''}
|
|
271
|
-
</a>
|
|
272
|
-
<span class="text-muted-foreground text-sm leading-snug pt-0.5">
|
|
273
|
-
${cleanedMessage}
|
|
274
|
-
</span>
|
|
275
|
-
</div>
|
|
276
|
-
</div>
|
|
277
|
-
`;
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
rootHtml += `</div>`;
|
|
282
|
-
|
|
283
|
-
targetEl.innerHTML = rootHtml;
|
|
284
|
-
contentEl.classList.remove('hidden');
|
|
285
|
-
} catch (err) {
|
|
286
|
-
loadingEl.classList.add('hidden');
|
|
287
|
-
emptyEl.textContent = 'Failed to load changelog.';
|
|
288
|
-
emptyEl.classList.remove('hidden');
|
|
289
|
-
}
|
|
290
|
-
})
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
function setupThemeCollapser() {
|
|
295
|
-
if (typeof document === 'undefined') return;
|
|
296
|
-
const containers = document.querySelectorAll('.api-theme-container');
|
|
297
|
-
containers.forEach(container => {
|
|
298
|
-
if (container.getAttribute('data-collapser-ready') === 'true') return;
|
|
299
|
-
container.setAttribute('data-collapser-ready', 'true');
|
|
300
|
-
|
|
301
|
-
const collapseWrapper = container.querySelector('.api-theme-collapse') as HTMLElement;
|
|
302
|
-
const fadeOverlay = container.querySelector('.api-theme-fade') as HTMLElement;
|
|
303
|
-
const btn = container.querySelector('.api-theme-btn') as HTMLButtonElement;
|
|
304
|
-
const triggerBar = container.querySelector('.api-theme-trigger-bar') as HTMLElement;
|
|
305
|
-
|
|
306
|
-
if (!collapseWrapper || !btn || !triggerBar || !fadeOverlay) return;
|
|
307
|
-
|
|
308
|
-
const checkAndSetup = () => {
|
|
309
|
-
const scrollHeight = collapseWrapper.scrollHeight;
|
|
310
|
-
if (scrollHeight <= 240) {
|
|
311
|
-
collapseWrapper.style.maxHeight = 'none';
|
|
312
|
-
fadeOverlay.style.display = 'none';
|
|
313
|
-
triggerBar.style.display = 'none';
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
let isExpanded = false;
|
|
318
|
-
|
|
319
|
-
btn.addEventListener('click', () => {
|
|
320
|
-
isExpanded = !isExpanded;
|
|
321
|
-
if (isExpanded) {
|
|
322
|
-
collapseWrapper.style.maxHeight = `${collapseWrapper.scrollHeight}px`;
|
|
323
|
-
btn.textContent = 'Hide theme config';
|
|
324
|
-
fadeOverlay.style.opacity = '0';
|
|
325
|
-
triggerBar.classList.remove('absolute', 'bottom-0');
|
|
326
|
-
triggerBar.classList.add('relative', 'bg-background', 'py-3', 'border-t', 'border-border');
|
|
327
|
-
triggerBar.style.paddingTop = '12px';
|
|
328
|
-
} else {
|
|
329
|
-
collapseWrapper.style.maxHeight = '240px';
|
|
330
|
-
btn.textContent = 'Show theme config';
|
|
331
|
-
fadeOverlay.style.opacity = '1';
|
|
332
|
-
triggerBar.classList.add('absolute', 'bottom-0');
|
|
333
|
-
triggerBar.classList.remove('relative', 'bg-background', 'py-3', 'border-t', 'border-border');
|
|
334
|
-
triggerBar.style.paddingTop = '48px';
|
|
335
|
-
container.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
setTimeout(checkAndSetup, 150);
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
if (typeof document !== 'undefined') {
|
|
345
|
-
loadChangelog();
|
|
346
|
-
setupThemeCollapser();
|
|
347
|
-
document.addEventListener('astro:page-load', loadChangelog);
|
|
348
|
-
document.addEventListener('astro:after-swap', setupThemeCollapser);
|
|
349
|
-
}
|
|
350
|
-
</script>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { BaseBlock } from "@rimelight/cms"
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
block: BaseBlock
|
|
6
|
-
locale?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const { block } = Astro.props
|
|
10
|
-
const { character, parenthetical, line } = block.props
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
<div class="my-3 mx-8 max-w-md">
|
|
14
|
-
<div class="text-sm font-bold text-center text-pink-800 dark:text-pink-200">
|
|
15
|
-
{character}
|
|
16
|
-
</div>
|
|
17
|
-
{parenthetical && (
|
|
18
|
-
<div class="text-xs italic text-center text-gray-600 dark:text-gray-400 mt-0.5">
|
|
19
|
-
({parenthetical})
|
|
20
|
-
</div>
|
|
21
|
-
)}
|
|
22
|
-
<div class="text-sm text-center text-gray-700 dark:text-gray-300 mt-1">{line}</div>
|
|
23
|
-
</div>
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { BaseBlock } from "@rimelight/cms"
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
block: BaseBlock
|
|
6
|
-
locale?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const { block } = Astro.props
|
|
10
|
-
const { componentCode, framework = "astro", height = "300px", width = "100%", editable = false } = block.props
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
<div class="cms-live-preview border border-border rounded-xl overflow-visible bg-background text-foreground my-6" data-block-id={block.id} data-framework={framework} data-editable={editable}>
|
|
14
|
-
<div class="controls-area p-4 border-b border-border flex items-center justify-between">
|
|
15
|
-
<div class="flex items-center gap-2">
|
|
16
|
-
<span class="text-xs font-medium text-muted-foreground uppercase tracking-wider">Live Preview</span>
|
|
17
|
-
<span class="text-xs font-mono text-muted-foreground bg-muted px-2 py-0.5 rounded">{framework}</span>
|
|
18
|
-
</div>
|
|
19
|
-
{editable && (
|
|
20
|
-
<span class="text-xs text-muted-foreground italic">Editable</span>
|
|
21
|
-
)}
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<div class="preview-area p-4 flex items-center justify-center" style={`height: ${height}; width: ${width};`}>
|
|
25
|
-
<pre class="text-sm font-mono text-muted-foreground bg-muted p-4 rounded-lg overflow-x-auto w-full"><code>{componentCode}</code></pre>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { BaseBlock, TimeOfDay, Setting, Transition } from "@rimelight/cms"
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
block: BaseBlock
|
|
6
|
-
locale?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const { block } = Astro.props
|
|
10
|
-
const { location, timeOfDay, setting, transition, description } = block.props
|
|
11
|
-
|
|
12
|
-
const timeOfDayLabels: Record<TimeOfDay, string> = {
|
|
13
|
-
MORNING: "Morning",
|
|
14
|
-
NOON: "Noon",
|
|
15
|
-
AFTERNOON: "Afternoon",
|
|
16
|
-
EVENING: "Evening",
|
|
17
|
-
NIGHT: "Night",
|
|
18
|
-
OTHER: "Other"
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const settingLabels: Record<Setting, string> = {
|
|
22
|
-
INTERIOR: "INT.",
|
|
23
|
-
EXTERIOR: "EXT.",
|
|
24
|
-
OTHER: "Other"
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const transitionLabels: Record<Transition, string> = {
|
|
28
|
-
CUT_TO: "CUT TO",
|
|
29
|
-
CUT_BACK_TO: "CUT BACK TO",
|
|
30
|
-
FADE_TO: "FADE TO",
|
|
31
|
-
NONE: ""
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const settingLabel = settingLabels[setting as Setting] || "Other"
|
|
35
|
-
const todLabel = timeOfDayLabels[timeOfDay as TimeOfDay] || "Other"
|
|
36
|
-
const transitionLabel = transitionLabels[transition as Transition] || ""
|
|
37
|
-
|
|
38
|
-
const headingParts = []
|
|
39
|
-
if (settingLabel && settingLabel !== "Other") headingParts.push(settingLabel)
|
|
40
|
-
if (location) headingParts.push(location)
|
|
41
|
-
if (todLabel && todLabel !== "Other") headingParts.push(`- ${todLabel}`)
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
<div class="my-4 p-3 border-l-4 border-indigo-400 bg-indigo-50/20 dark:bg-indigo-950/10 rounded-r-lg">
|
|
45
|
-
<div class="flex flex-wrap items-center gap-2 text-sm font-semibold text-indigo-800 dark:text-indigo-200 mb-2">
|
|
46
|
-
{headingParts.map((part) => (
|
|
47
|
-
<span>{part}</span>
|
|
48
|
-
))}
|
|
49
|
-
{transitionLabel && (
|
|
50
|
-
<span class="ml-auto text-[10px] italic text-gray-600 dark:text-gray-400">
|
|
51
|
-
{transitionLabel}
|
|
52
|
-
</span>
|
|
53
|
-
)}
|
|
54
|
-
</div>
|
|
55
|
-
{description && (
|
|
56
|
-
<p class="text-sm text-gray-700 dark:text-gray-300 mb-2">
|
|
57
|
-
{description}
|
|
58
|
-
</p>
|
|
59
|
-
)}
|
|
60
|
-
{((block.children && block.children.length > 0) || (block.props?.children && block.props.children.length > 0)) && (
|
|
61
|
-
<div class="mt-3">
|
|
62
|
-
<slot />
|
|
63
|
-
</div>
|
|
64
|
-
)}
|
|
65
|
-
</div>
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { BaseBlock } from "@rimelight/cms"
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
block: BaseBlock
|
|
6
|
-
locale?: string
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const { block } = Astro.props
|
|
10
|
-
const { title, synopsis, characters, aPlot, bPlot, cPlot, stinger } = block.props
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
<div class="my-6 p-4 border-l-4 border-amber-400 bg-amber-50/20 dark:bg-amber-950/10 rounded-r-lg">
|
|
14
|
-
<div class="mb-4">
|
|
15
|
-
<h3 class="text-xl font-bold text-amber-900 dark:text-amber-100">{title}</h3>
|
|
16
|
-
{synopsis && <p class="text-sm text-gray-600 dark:text-gray-400 mt-1 italic">{synopsis}</p>}
|
|
17
|
-
{characters && characters.length > 0 && (
|
|
18
|
-
<div class="flex flex-wrap gap-3 mt-3 text-xs">
|
|
19
|
-
{characters.map((char: string) => (
|
|
20
|
-
<span class="px-2 py-0.5 rounded-full bg-amber-100 dark:bg-amber-900/30 text-amber-800 dark:text-amber-200">
|
|
21
|
-
{char}
|
|
22
|
-
</span>
|
|
23
|
-
))}
|
|
24
|
-
</div>
|
|
25
|
-
)}
|
|
26
|
-
</div>
|
|
27
|
-
{(aPlot || bPlot || cPlot) && (
|
|
28
|
-
<div class="grid grid-cols-1 md:grid-cols-3 gap-3 my-3">
|
|
29
|
-
{aPlot && (
|
|
30
|
-
<div class="bg-white/50 dark:bg-neutral-900/30 rounded p-2 border border-gray-200 dark:border-gray-700">
|
|
31
|
-
<div class="text-[10px] font-bold uppercase tracking-wider text-gray-600 dark:text-gray-400">A Plot</div>
|
|
32
|
-
<div class="text-sm mt-0.5">{aPlot}</div>
|
|
33
|
-
</div>
|
|
34
|
-
)}
|
|
35
|
-
{bPlot && (
|
|
36
|
-
<div class="bg-white/50 dark:bg-neutral-900/30 rounded p-2 border border-gray-200 dark:border-gray-700">
|
|
37
|
-
<div class="text-[10px] font-bold uppercase tracking-wider text-gray-600 dark:text-gray-400">B Plot</div>
|
|
38
|
-
<div class="text-sm mt-0.5">{bPlot}</div>
|
|
39
|
-
</div>
|
|
40
|
-
)}
|
|
41
|
-
{cPlot && (
|
|
42
|
-
<div class="bg-white/50 dark:bg-neutral-900/30 rounded p-2 border border-gray-200 dark:border-gray-700">
|
|
43
|
-
<div class="text-[10px] font-bold uppercase tracking-wider text-gray-600 dark:text-gray-400">C Plot</div>
|
|
44
|
-
<div class="text-sm mt-0.5">{cPlot}</div>
|
|
45
|
-
</div>
|
|
46
|
-
)}
|
|
47
|
-
</div>
|
|
48
|
-
)}
|
|
49
|
-
{stinger && (
|
|
50
|
-
<p class="text-sm text-gray-600 dark:text-gray-400 italic mt-2 border-t border-gray-200 dark:border-gray-700 pt-2">
|
|
51
|
-
Stinger: {stinger}
|
|
52
|
-
</p>
|
|
53
|
-
)}
|
|
54
|
-
{((block.children && block.children.length > 0) || (block.props?.children && block.props.children.length > 0)) && (
|
|
55
|
-
<div class="mt-4">
|
|
56
|
-
<slot />
|
|
57
|
-
</div>
|
|
58
|
-
)}
|
|
59
|
-
</div>
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { BaseBlock } from "./types/blocks"
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Merges updated template blocks into an existing page block tree. Matches templated blocks by
|
|
5
|
-
* block `type` + `isTemplated: true` tag and structural index. Fits updated template anchors while
|
|
6
|
-
* preserving user-inserted custom blocks around them.
|
|
7
|
-
*/
|
|
8
|
-
export function mergeTemplateBlocks(
|
|
9
|
-
existingPageBlocks: BaseBlock[],
|
|
10
|
-
newTemplateBlocks: BaseBlock[]
|
|
11
|
-
): BaseBlock[] {
|
|
12
|
-
const merged: BaseBlock[] = []
|
|
13
|
-
|
|
14
|
-
const newTemplatedAnchors = newTemplateBlocks.filter((b) => b.isTemplated)
|
|
15
|
-
let existingIndex = 0
|
|
16
|
-
|
|
17
|
-
for (const templateAnchor of newTemplatedAnchors) {
|
|
18
|
-
// Collect user-inserted custom blocks preceding this template anchor
|
|
19
|
-
while (
|
|
20
|
-
existingIndex < existingPageBlocks.length &&
|
|
21
|
-
!existingPageBlocks[existingIndex]?.isTemplated
|
|
22
|
-
) {
|
|
23
|
-
const block = existingPageBlocks[existingIndex]
|
|
24
|
-
if (block) merged.push(block)
|
|
25
|
-
existingIndex++
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Match existing template anchor by block type
|
|
29
|
-
const existingAnchor = existingPageBlocks[existingIndex]
|
|
30
|
-
|
|
31
|
-
if (existingAnchor && existingAnchor.type === templateAnchor.type) {
|
|
32
|
-
merged.push({
|
|
33
|
-
...templateAnchor,
|
|
34
|
-
id: existingAnchor.id,
|
|
35
|
-
props: mergeBlockProps(
|
|
36
|
-
existingAnchor.props,
|
|
37
|
-
templateAnchor.props,
|
|
38
|
-
existingAnchor.templatedProps
|
|
39
|
-
)
|
|
40
|
-
})
|
|
41
|
-
existingIndex++
|
|
42
|
-
} else {
|
|
43
|
-
// New template anchor inserted in template update: add fresh block with new random UUID
|
|
44
|
-
merged.push({
|
|
45
|
-
...templateAnchor,
|
|
46
|
-
id: crypto.randomUUID()
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Append any remaining custom user blocks at the end of the document
|
|
52
|
-
while (existingIndex < existingPageBlocks.length) {
|
|
53
|
-
const block = existingPageBlocks[existingIndex]
|
|
54
|
-
if (block) merged.push(block)
|
|
55
|
-
existingIndex++
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return merged
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function mergeBlockProps(
|
|
62
|
-
existingProps: any,
|
|
63
|
-
templateProps: any,
|
|
64
|
-
templatedProps?: boolean | string[]
|
|
65
|
-
) {
|
|
66
|
-
if (templatedProps === true) return { ...templateProps }
|
|
67
|
-
if (Array.isArray(templatedProps)) {
|
|
68
|
-
const updated = { ...existingProps }
|
|
69
|
-
for (const key of templatedProps) {
|
|
70
|
-
updated[key] = templateProps[key]
|
|
71
|
-
}
|
|
72
|
-
return updated
|
|
73
|
-
}
|
|
74
|
-
return { ...existingProps, ...templateProps }
|
|
75
|
-
}
|