load in optimization and error correction
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m23s

This commit is contained in:
2026-03-20 13:08:15 -05:00
parent da7d2f4d5d
commit 5b2fefbca4
21 changed files with 334 additions and 130 deletions
+26 -23
View File
@@ -1,5 +1,5 @@
import { type Component, createSignal, createMemo, createEffect, onCleanup, For, Show } from "solid-js";
import { store, renameTagDefinition, updateNote, updateTask, removeNote, restoreNote, setActiveNoteId, cleanupNoteAttachments, getFavoriteTag, fetchNoteById, updateStoreWithNote } from "@/store";
import { store, renameTagDefinition, updateNote, updateTask, removeNote, restoreNote, setActiveNoteId, cleanupNoteAttachments, getFavoriteTag, loadNoteContent, requestImmediateNotesMetadataLoad } from "@/store";
import { pb } from "@/lib/pocketbase";
import { type Note } from "@/store";
import { Plus, X, Lock, Unlock, Trash2, ChevronDown, Link as LinkIcon, MoreHorizontal, Type, FileText, Search, Star, ChevronRight } from "lucide-solid";
@@ -57,29 +57,27 @@ export const NotepadView: Component<{
// 3. Trigger cleanup after a tiny delay so the updateNote above processes first
if (currentId) {
setTimeout(() => {
const existingNote = store.notes.find(note => note.id === currentId && !note.deletedAt);
if (!existingNote) return;
cleanupNoteAttachments(currentId).catch(console.error);
}, 100);
}
});
});
// Handle fetching note for unauthenticated users (public shares)
createEffect(async () => {
createEffect(() => {
void requestImmediateNotesMetadataLoad();
});
createEffect(() => {
const id = props.selectedNoteId;
const note = activeNote();
if (!id) return;
// If note is already in store, we are good
const exists = store.notes.find(n => n.id === id);
if (exists) return;
if (!note && pb.authStore.isValid) return;
// If not authenticated or note just missing (e.g. direct link), try to fetch it
console.log("[NotepadView] Note not found in store, attempting public fetch for:", id);
const note = await fetchNoteById(id);
if (note) {
updateStoreWithNote(note);
} else if (!pb.authStore.isValid) {
toast.error("Note not found or you don't have permission to view it.");
}
console.log("[NotepadView] Ensuring note content is loaded for:", id);
void loadNoteContent(id);
});
// Derived states
@@ -361,7 +359,7 @@ export const NotepadView: Component<{
<div class="h-16 w-16 rounded-3xl bg-muted flex items-center justify-center mb-2 animate-pulse">
<Search size={32} class="text-muted-foreground/50" />
</div>
<Show when={props.selectedNoteId && store.notes.length === 0} fallback={
<Show when={props.selectedNoteId && (store.isNotesLoading || store.loadingNoteContentIds.includes(props.selectedNoteId))} fallback={
<div class="space-y-2">
<p class="text-sm font-bold tracking-widest uppercase">No Note Selected</p>
<p class="text-[0.8rem] text-muted-foreground max-w-[200px] leading-relaxed">
@@ -445,7 +443,7 @@ export const NotepadView: Component<{
{/* Editor Area */}
<div class={cn(
"flex-1 md:flex-initial md:shrink flex flex-col min-w-0 md:w-[960px] lg:w-[1120px] md:h-full overflow-visible md:overflow-y-auto relative scroll-smooth bg-background z-20 pt-0",
hasTopViewer() ? "p-0 space-y-0" : "px-4 md:px-6 pb-4 md:pb-6 space-y-4 md:space-y-6"
hasTopViewer() ? "p-0 space-y-0" : "px-4 md:px-6 pb-4 md:pb-6 space-y-2 md:space-y-6"
)}>
<div class={cn(
@@ -617,13 +615,18 @@ export const NotepadView: Component<{
"grow shrink-0 flex flex-col",
hasTopViewer() ? "border-none rounded-none p-0 shadow-none mb-0 min-h-full" : "min-h-[300px] mb-4 px-4 pt-0 pb-4 border border-border/50 rounded-xl bg-background shadow-sm"
)}>
<TaskEditor
content={note().content}
onUpdate={(html) => handleUpdateContent(note().id, html)}
onEditorReady={setEditorInstance}
editable={canEdit()}
class={hasTopViewer() ? "[&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:px-4 md:[&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:px-6 [&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:max-w-3xl [&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:mx-auto [&>.file-viewer-wrapper:first-child]:h-[80vh] [&>.file-viewer-wrapper:first-child]:min-h-0 [&>.file-attachment-wrapper:first-child]:h-[80vh] [&>.file-attachment-wrapper:first-child]:min-h-0 pb-20" : ""}
/>
<Show
when={note().content !== undefined || !store.loadingNoteContentIds.includes(note().id)}
fallback={<div class="h-32 animate-pulse bg-muted/20 rounded-lg" />}
>
<TaskEditor
content={note().content}
onUpdate={(html) => handleUpdateContent(note().id, html)}
onEditorReady={setEditorInstance}
editable={canEdit()}
class={hasTopViewer() ? "[&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:px-4 md:[&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:px-6 [&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:max-w-3xl [&>*:not(.file-viewer-wrapper:first-child,.file-attachment-wrapper:first-child)]:mx-auto [&>.file-viewer-wrapper:first-child]:h-[80vh] [&>.file-viewer-wrapper:first-child]:min-h-0 [&>.file-attachment-wrapper:first-child]:h-[80vh] [&>.file-attachment-wrapper:first-child]:min-h-0 pb-20" : ""}
/>
</Show>
</div>
<Show when={!hasTopViewer()}>
<div class="shrink-0 h-16 md:h-8" />