Editor: font-size presets + image insert/export support
Two editor features that were in flight alongside the sound work: - FontSize TipTap extension (rides on textStyle) with Small/Normal/Large/ Title presets in the toolbar; StatusBar + CSS support - Image handling: internal/images handler, upload route + config, client API, EditorCore wiring, and md/html/docx export support for images Claude-Session: https://claude.ai/code/session_016Yr6jELuRc7hyzYLccQKZd
This commit is contained in:
@@ -182,6 +182,21 @@ export const api = {
|
||||
// highlighted snippet. Empty query returns []. Encodes the term for the URL.
|
||||
search: (q: string) => req<SearchResult[]>(`/search?q=${encodeURIComponent(q)}`),
|
||||
|
||||
// Image upload: posts a single image file as multipart form data and returns
|
||||
// its served URL (e.g. /api/images/<hash>.png). Stored on disk by the binary,
|
||||
// so the document JSON keeps a small URL reference instead of inlined base64.
|
||||
// Doesn't go through req() because the body is FormData, not JSON.
|
||||
uploadImage: async (file: File): Promise<{ url: string }> => {
|
||||
const form = new FormData()
|
||||
form.append('image', file)
|
||||
const res = await fetch('/api/images', { method: 'POST', body: form })
|
||||
if (!res.ok) {
|
||||
const detail = await res.text().catch(() => '')
|
||||
throw new Error(`${res.status} ${res.statusText}${detail ? `: ${detail}` : ''}`)
|
||||
}
|
||||
return res.json() as Promise<{ url: string }>
|
||||
},
|
||||
|
||||
// Tags. listTags returns the roster with per-tag document counts; createTag is
|
||||
// idempotent on name (returns the existing tag if it already exists);
|
||||
// updateTag recolors/renames; deleteTag removes it (assignments cascade).
|
||||
|
||||
Reference in New Issue
Block a user