Files
classroomio/apps/dashboard/src/lib/features/ui/text-editor.svelte
T
Rotimi Best d5b07d356e feat: HLS streaming, transcripts, agent course generation & landing-page course previews (#663)
New features:
- HLS video encoding/streaming (hls routes, hls-encoder) and a media
  transcripts pipeline (transcripts route + media-transcript queries)
- AI assistant chat vs. run model: agent-course-generation worker/queue,
  run-monitor pane, chat-changes card, content ask-ai bar
- Per-theme course-page previews across org landing-page themes (bold,
  classic, corporate, editorial, etc.) with a shared course token/component set
- View-as-student mode and login-link / link-invite invite flows

Refactor:
- Extract packages/core consolidating config (env, storage, dashboard-url),
  services and utils previously duplicated under apps/api/src/config
- Remove legacy agent service modules (chat-tools, chat-context,
  context-window, document, fetch-url, lesson-content)
- Relax Cross-Origin-Resource-Policy to allow cross-origin media embedding
- Add format script to tenant-router so turbo run format covers it
2026-06-07 18:43:05 +01:00

66 lines
1.8 KiB
Svelte

<script module lang="ts">
// Module-level singleton: one Promise shared across all mounted instances.
// Dynamic imports are already cached by the JS engine after the first load,
// but reusing the same Promise avoids redundant microtask chains on remounts.
let pending: Promise<typeof import('@cio/ui/custom/editor')> | null = null;
function loadEditor() {
pending ??= import('@cio/ui/custom/editor');
return pending;
}
</script>
<script lang="ts">
// Type-only imports are erased at build time — no static TipTap dependency.
import type { HTMLContent, TiptapEditor } from '@cio/ui/custom/editor';
interface Props {
placeholder?: string | ((node: any) => string);
content?: HTMLContent;
showToolBar?: boolean;
editable?: boolean;
enablePersistence?: boolean;
contentStorageKey?: string;
editableStorageKey?: string;
class?: string;
editorClass?: string;
onChange?: (content: HTMLContent) => void;
onReady?: (editor: TiptapEditor) => void;
onEditorDestroy?: () => void;
}
let {
content = '',
showToolBar = true,
editable = true,
enablePersistence = false,
contentStorageKey = 'edra-content',
editableStorageKey = 'edra-editable',
class: className = '',
editorClass = '',
placeholder = 'Welcome to ClassroomIO',
onChange,
onReady,
onEditorDestroy
}: Props = $props();
</script>
{#await loadEditor()}
<div class="ui:animate-pulse ui:rounded-md ui:bg-muted ui:h-32 ui:w-full" />
{:then { Editor }}
<Editor
{content}
{showToolBar}
{editable}
{enablePersistence}
{contentStorageKey}
{editableStorageKey}
class={className}
{editorClass}
{placeholder}
onContentChange={onChange}
onEditorReady={onReady}
{onEditorDestroy}
/>
{/await}