0d817537be
Introduce @workspace/lexical with composable actions, toolbars, embeds, rich-text nodes, media uploads, selection utilities, HTML serialization, and theme styling.\n\nLocalize built-in controls through MessageDescriptor catalogs for English and Simplified Chinese, while providing an English I18nProvider fallback for standalone editor use. Include focused unit coverage for actions, controls, serialization, plugins, public API, and catalogs.
54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import type { NodeKey } from "lexical"
|
|
|
|
export interface LexicalImageUploadState {
|
|
progress?: number
|
|
}
|
|
|
|
const uploadStates = new Map<NodeKey, LexicalImageUploadState>()
|
|
const listeners = new Map<NodeKey, Set<VoidFunction>>()
|
|
|
|
function emit(nodeKey: NodeKey) {
|
|
listeners.get(nodeKey)?.forEach((listener) => listener())
|
|
}
|
|
|
|
export function getImageUploadState(
|
|
nodeKey: NodeKey
|
|
): LexicalImageUploadState | undefined {
|
|
return uploadStates.get(nodeKey)
|
|
}
|
|
|
|
export function setImageUploadState(
|
|
nodeKey: NodeKey,
|
|
state: LexicalImageUploadState
|
|
) {
|
|
uploadStates.set(nodeKey, state)
|
|
emit(nodeKey)
|
|
}
|
|
|
|
export function deleteImageUploadState(nodeKey: NodeKey) {
|
|
if (!uploadStates.delete(nodeKey)) return
|
|
emit(nodeKey)
|
|
}
|
|
|
|
function subscribe(nodeKey: NodeKey, listener: VoidFunction) {
|
|
const nodeListeners = listeners.get(nodeKey) ?? new Set<VoidFunction>()
|
|
nodeListeners.add(listener)
|
|
listeners.set(nodeKey, nodeListeners)
|
|
|
|
return () => {
|
|
nodeListeners.delete(listener)
|
|
if (nodeListeners.size === 0) listeners.delete(nodeKey)
|
|
}
|
|
}
|
|
|
|
export function useImageUploadState(nodeKey: NodeKey) {
|
|
return React.useSyncExternalStore(
|
|
(listener) => subscribe(nodeKey, listener),
|
|
() => getImageUploadState(nodeKey),
|
|
() => undefined
|
|
)
|
|
}
|