chore(print): basic infrastructure to support reporting progress

This commit is contained in:
Elian Doran 2025-11-21 12:06:32 +02:00
parent 63d430c3d9
commit 6ca941e8e9
No known key found for this signature in database
5 changed files with 22 additions and 5 deletions

View File

@ -7,6 +7,7 @@ import content_renderer, { applyInlineMermaid } from "./services/content_rendere
interface RendererProps { interface RendererProps {
note: FNote; note: FNote;
onReady: () => void; onReady: () => void;
onProgressChanged?: (progress: number) => void;
} }
async function main() { async function main() {
@ -23,13 +24,16 @@ async function main() {
function App({ note, noteId }: { note: FNote | null | undefined, noteId: string }) { function App({ note, noteId }: { note: FNote | null | undefined, noteId: string }) {
const sentReadyEvent = useRef(false); const sentReadyEvent = useRef(false);
const onProgressChanged = useCallback((progress: number) => {
window.dispatchEvent(new CustomEvent("note-load-progress", { detail: { progress } }));
}, []);
const onReady = useCallback(() => { const onReady = useCallback(() => {
if (sentReadyEvent.current) return; if (sentReadyEvent.current) return;
window.dispatchEvent(new Event("note-ready")); window.dispatchEvent(new Event("note-ready"));
window._noteReady = true; window._noteReady = true;
sentReadyEvent.current = true; sentReadyEvent.current = true;
}, []); }, []);
const props: RendererProps | undefined | null = note && { note, onReady }; const props: RendererProps | undefined | null = note && { note, onReady, onProgressChanged };
if (!note || !props) return <Error404 noteId={noteId} /> if (!note || !props) return <Error404 noteId={noteId} />
@ -89,7 +93,7 @@ function SingleNoteRenderer({ note, onReady }: RendererProps) {
</>; </>;
} }
function CollectionRenderer({ note, onReady }: RendererProps) { function CollectionRenderer({ note, onReady, onProgressChanged }: RendererProps) {
const viewType = useNoteViewType(note); const viewType = useNoteViewType(note);
return <CustomNoteList return <CustomNoteList
viewType={viewType} viewType={viewType}
@ -103,6 +107,7 @@ function CollectionRenderer({ note, onReady }: RendererProps) {
await loadCustomCss(note); await loadCustomCss(note);
onReady(); onReady();
}} }}
onProgressChanged={onProgressChanged}
/>; />;
} }

View File

@ -162,6 +162,10 @@ export default function NoteDetail() {
return; return;
} }
iframe.contentWindow.addEventListener("note-load-progress", (e) => {
console.log("Got ", e);
});
iframe.contentWindow.addEventListener("note-ready", () => { iframe.contentWindow.addEventListener("note-ready", () => {
toast.closePersistent("printing"); toast.closePersistent("printing");
iframe.contentWindow?.print(); iframe.contentWindow?.print();

View File

@ -26,9 +26,10 @@ interface NoteListProps {
media: ViewModeMedia; media: ViewModeMedia;
viewType: ViewTypeOptions | undefined; viewType: ViewTypeOptions | undefined;
onReady?: () => void; onReady?: () => void;
onProgressChanged?(progress: number): void;
} }
export default function NoteList(props: Pick<NoteListProps, "displayOnlyCollections" | "media" | "onReady">) { export default function NoteList(props: Pick<NoteListProps, "displayOnlyCollections" | "media" | "onReady" | "onProgressChanged">) {
const { note, noteContext, notePath, ntxId } = useNoteContext(); const { note, noteContext, notePath, ntxId } = useNoteContext();
const viewType = useNoteViewType(note); const viewType = useNoteViewType(note);
const [ enabled, setEnabled ] = useState(noteContext?.hasNoteList()); const [ enabled, setEnabled ] = useState(noteContext?.hasNoteList());
@ -43,7 +44,7 @@ export function SearchNoteList(props: Omit<NoteListProps, "isEnabled" | "viewTyp
return <CustomNoteList {...props} isEnabled={true} viewType={viewType} /> return <CustomNoteList {...props} isEnabled={true} viewType={viewType} />
} }
export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePath, highlightedTokens, displayOnlyCollections, ntxId, onReady, ...restProps }: NoteListProps) { export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePath, highlightedTokens, displayOnlyCollections, ntxId, onReady, onProgressChanged, ...restProps }: NoteListProps) {
const widgetRef = useRef<HTMLDivElement>(null); const widgetRef = useRef<HTMLDivElement>(null);
const noteIds = useNoteIds(shouldEnable ? note : null, viewType, ntxId); const noteIds = useNoteIds(shouldEnable ? note : null, viewType, ntxId);
const isFullHeight = (viewType && viewType !== "list" && viewType !== "grid"); const isFullHeight = (viewType && viewType !== "list" && viewType !== "grid");
@ -86,6 +87,8 @@ export function CustomNoteList({ note, viewType, isEnabled: shouldEnable, notePa
viewConfig: viewModeConfig.config, viewConfig: viewModeConfig.config,
saveConfig: viewModeConfig.storeFn, saveConfig: viewModeConfig.storeFn,
onReady: onReady ?? (() => {}), onReady: onReady ?? (() => {}),
onProgressChanged: onProgressChanged ?? (() => {}),
...restProps ...restProps
} }
} }

View File

@ -17,4 +17,5 @@ export interface ViewModeProps<T extends object> {
saveConfig(newConfig: T): void; saveConfig(newConfig: T): void;
media: ViewModeMedia; media: ViewModeMedia;
onReady(): void; onReady(): void;
onProgressChanged?(progress: number): void;
} }

View File

@ -10,7 +10,7 @@ interface NotesWithContent {
contentEl: HTMLElement; contentEl: HTMLElement;
} }
export function ListPrintView({ note, noteIds: unfilteredNoteIds, onReady }: ViewModeProps<{}>) { export function ListPrintView({ note, noteIds: unfilteredNoteIds, onReady, onProgressChanged }: ViewModeProps<{}>) {
const noteIds = useFilteredNoteIds(note, unfilteredNoteIds); const noteIds = useFilteredNoteIds(note, unfilteredNoteIds);
const [ notesWithContent, setNotesWithContent ] = useState<NotesWithContent[]>(); const [ notesWithContent, setNotesWithContent ] = useState<NotesWithContent[]>();
@ -33,6 +33,10 @@ export function ListPrintView({ note, noteIds: unfilteredNoteIds, onReady }: Vie
noteIdsSet.add(note.noteId); noteIdsSet.add(note.noteId);
notesWithContent.push({ note, contentEl }); notesWithContent.push({ note, contentEl });
if (onProgressChanged) {
onProgressChanged((notesWithContent.length / noteIds.length) * 100);
}
if (note.hasChildren()) { if (note.hasChildren()) {
const filteredChildNotes = await filterChildNotes(note); const filteredChildNotes = await filterChildNotes(note);
for (const childNote of filteredChildNotes) { for (const childNote of filteredChildNotes) {