mirror of
				https://github.com/Blah-IM/Weblah.git
				synced 2025-10-31 01:51:37 +00:00 
			
		
		
		
	fix: Add initialDoc prop and BlahRichText conversion utility
Fix typo in schema ("paragragh" -> "paragraph") and implement
bidirectional conversion between BlahRichText and ProseMirror formats.
Update profile page to use new initialDoc prop instead of children.
			
			
This commit is contained in:
		
							parent
							
								
									aaedd69889
								
							
						
					
					
						commit
						b56b47df82
					
				
					 4 changed files with 48 additions and 12 deletions
				
			
		|  | @ -7,10 +7,22 @@ | |||
| 	export interface Props extends Omit<EditorStateConfiguration, 'initialDoc'> { | ||||
| 		onDocChange?: (doc: Node) => void; | ||||
| 		placeholder?: string; | ||||
| 		/** | ||||
| 		 * The initial content in editor. | ||||
| 		 * | ||||
| 		 * This is higher priority than `children`. | ||||
| 		 */ | ||||
| 		initialDoc?: Node | null; | ||||
| 		children?: import('svelte').Snippet; | ||||
| 	} | ||||
| 
 | ||||
| 	const { onDocChange, placeholder = '', children, ...stateConfiguration }: Props = $props(); | ||||
| 	const { | ||||
| 		onDocChange, | ||||
| 		placeholder = '', | ||||
| 		children, | ||||
| 		initialDoc: initialDocProp, | ||||
| 		...stateConfiguration | ||||
| 	}: Props = $props(); | ||||
| 
 | ||||
| 	let domEl: HTMLDivElement; | ||||
| 	let editorView: EditorView; | ||||
|  | @ -18,7 +30,8 @@ | |||
| 	let isEmpty = $state(!children); | ||||
| 
 | ||||
| 	$effect(() => { | ||||
| 		const initialDoc = DOMParser.fromSchema(stateConfiguration.schema).parse(domEl); | ||||
| 		const initialDoc = | ||||
| 			initialDocProp ?? DOMParser.fromSchema(stateConfiguration.schema).parse(domEl); | ||||
| 		domEl.replaceChildren(); | ||||
| 		onDocChange?.(initialDoc); | ||||
| 		isEmpty = initialDoc.textContent.length === 0; | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ import { nodes as basicNodes, marks as basicMarks } from 'prosemirror-schema-bas | |||
| export const messageSchema = new Schema({ | ||||
| 	nodes: { | ||||
| 		doc: { content: 'block+' }, | ||||
| 		paragragh: { | ||||
| 		paragraph: { | ||||
| 			content: 'inline*', | ||||
| 			...basicNodes.paragraph | ||||
| 		}, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import type { BlahRichText, BlahRichTextSpanAttributes } from '@blah-im/core/richText'; | ||||
| import type { Node } from 'prosemirror-model'; | ||||
| import type { Node, Schema } from 'prosemirror-model'; | ||||
| 
 | ||||
| function isObjectEmpty(obj: object) { | ||||
| 	for (const _ in obj) return false; | ||||
|  | @ -58,3 +58,28 @@ export function proseMirrorDocToBlahRichText(doc: Node): BlahRichText { | |||
| 
 | ||||
| 	return spans; | ||||
| } | ||||
| 
 | ||||
| export function blahRichTextToProseMirrorDoc(richText: BlahRichText, schema: Schema): Node { | ||||
| 	console.log(schema); | ||||
| 	const paragraphs = richText.flatMap((span) => { | ||||
| 		if (typeof span === 'string') { | ||||
| 			if (!span.trim().length) return []; | ||||
| 			return [schema.nodes.paragraph.create({}, schema.text(span))]; | ||||
| 		} else { | ||||
| 			const [text, attributes] = span; | ||||
| 			const marks = []; | ||||
| 			if (attributes.b) marks.push(schema.marks.strong.create()); | ||||
| 			if (attributes.i) marks.push(schema.marks.em.create()); | ||||
| 			if (attributes.m) marks.push(schema.marks.code.create()); | ||||
| 			if (attributes.link) marks.push(schema.marks.link.create({ href: attributes.link })); | ||||
| 			if (attributes.u) marks.push(schema.marks.underline.create()); | ||||
| 			if (attributes.s) marks.push(schema.marks.strikethrough.create()); | ||||
| 			if (attributes.tag) marks.push(schema.marks.tag.create()); | ||||
| 			if (attributes.spoiler) marks.push(schema.marks.spoiler.create()); | ||||
| 
 | ||||
| 			return [schema.nodes.paragraph.create({}, schema.text(text, marks))]; | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	return schema.nodes.doc.create({}, paragraphs); | ||||
| } | ||||
|  |  | |||
|  | @ -13,9 +13,12 @@ | |||
| 	import Button from '$lib/components/Button.svelte'; | ||||
| 	import RichTextInput from '$lib/components/RichTextInput.svelte'; | ||||
| 	import { messageSchema } from '$lib/components/RichTextInput/schema'; | ||||
| 	import { blahRichTextToProseMirrorDoc } from '$lib/richText'; | ||||
| 	import type { Node } from 'prosemirror-model'; | ||||
| 
 | ||||
| 	const currentAccount = $derived(accountsManager.currentAccount); | ||||
| 	let profile: BlahProfile | null = $state(null); | ||||
| 	let initialBio: Node | null = $state(null); | ||||
| 
 | ||||
| 	let isBusy: boolean = $state(false); | ||||
| 
 | ||||
|  | @ -23,21 +26,17 @@ | |||
| 		if (currentAccount) { | ||||
| 			const snapshot = $state.snapshot(currentAccount.profile.signee.payload); | ||||
| 			profile = snapshot; | ||||
| 			console.log('Reloaded'); | ||||
| 			initialBio = blahRichTextToProseMirrorDoc([snapshot.bio ?? ''], messageSchema); | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	$inspect(profile); | ||||
| 
 | ||||
| 	async function saveProfile() { | ||||
| 		if (!currentAccount || !profile) return; | ||||
| 
 | ||||
| 		console.log('Saving profile', $state.snapshot(profile)); | ||||
| 		isBusy = true; | ||||
| 		const identity = await accountsManager.identityForAccount(currentAccount); | ||||
| 		await identity.updateProfile(profile); | ||||
| 		await accountsManager.saveIdentity(identity); | ||||
| 		console.log('Profile saved', identity.generateIdentityDescription()); | ||||
| 		isBusy = false; | ||||
| 	} | ||||
| </script> | ||||
|  | @ -67,9 +66,8 @@ | |||
| 				schema={messageSchema} | ||||
| 				onDocChange={(doc) => profile && (profile.bio = doc.textContent)} | ||||
| 				placeholder="a 25 yo. artist from Paris." | ||||
| 			> | ||||
| 				{profile.bio ?? ''} | ||||
| 			</RichTextInput> | ||||
| 				initialDoc={initialBio} | ||||
| 			/> | ||||
| 		</GroupedListSection> | ||||
| 	</GroupedListContainer> | ||||
| {/if} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Shibo Lyu
						Shibo Lyu