Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/components/editor/hooks/useEditorEffects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function useEditorEffects({

// Initialize word count when editor is ready
useEffect(() => {
if (!editor || !editor.view) return;
if (!editor || !editor.view || !editor.view.dom) return;

// Calculate initial word count
const text = editor.state.doc.textContent;
Expand All @@ -72,11 +72,11 @@ export function useEditorEffects({

// Track scroll percentage
useEffect(() => {
if (!editor || !editor.view) return;
if (!editor || !editor.view || !editor.view.dom) return;

const updateScrollPercentage = () => {
const editorView = editor.view;
if (!editorView.dom) return;
if (!editorView || !editorView.dom) return;

const { scrollTop, scrollHeight, clientHeight } = editorView.dom;
const maxScroll = scrollHeight - clientHeight;
Expand All @@ -102,7 +102,7 @@ export function useEditorEffects({

// Store the original font size when editor is first created
useEffect(() => {
if (!editor || !editor.view || baseFontSize) return;
if (!editor || !editor.view || !editor.view.dom || baseFontSize) return;

const editorElement = editor.view.dom as HTMLElement;
const computedStyle = window.getComputedStyle(editorElement);
Expand All @@ -112,7 +112,7 @@ export function useEditorEffects({

// Apply zoom level to editor
useEffect(() => {
if (!editor || !editor.view || !baseFontSize) return;
if (!editor || !editor.view || !editor.view.dom || !baseFontSize) return;

const editorElement = editor.view.dom as HTMLElement;

Expand Down
20 changes: 16 additions & 4 deletions src/components/editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ interface NoteEditorProps {
onDeleteNote: (noteId: string) => void;
onArchiveNote: (noteId: string) => void;
onToggleStar: (noteId: string) => void;
starringStar?: boolean;
onHideNote: (noteId: string) => void;
hidingNote?: boolean;
onUnhideNote: (noteId: string) => void;
onRefreshNote?: (noteId: string) => void;
userId?: string;
Expand All @@ -92,7 +94,9 @@ export default function Index({
onDeleteNote,
onArchiveNote,
onToggleStar,
starringStar = false,
onHideNote,
hidingNote = false,
onUnhideNote,
onRefreshNote,
userId = 'current-user',
Expand Down Expand Up @@ -671,10 +675,15 @@ export default function Index({
note.starred ? 'text-yellow-500' : 'text-muted-foreground'
}
title={note.starred ? 'Remove from starred' : 'Add to starred'}
disabled={starringStar}
>
<Star
className={`h-4 w-4 ${note.starred ? 'fill-current' : ''}`}
/>
{starringStar ? (
<div className="h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
) : (
<Star
className={`h-4 w-4 ${note.starred ? 'fill-current' : ''}`}
/>
)}
</Button>

<Button
Expand All @@ -687,8 +696,11 @@ export default function Index({
note.hidden ? 'text-primary' : 'text-muted-foreground'
}
title={note.hidden ? 'Unhide note' : 'Hide note'}
disabled={hidingNote}
>
{note.hidden ? (
{hidingNote ? (
<div className="h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
) : note.hidden ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
Expand Down
39 changes: 36 additions & 3 deletions src/components/layout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,24 @@ export default function MainLayout() {
expandedFolders,
updateFolder,
createNote,
creatingNote,
createFolder,
deleteFolder,
updateNote,
deleteNote,
toggleStar,
starringStar,
archiveNote,
hideNote,
hidingNote,
unhideNote,
toggleFolderExpansion,
reorderFolders,
setSelectedNote,
setSelectedFolder,
setCurrentView,
setSearchQuery,
setNotes,
refetch,
reinitialize,
webSocket,
Expand Down Expand Up @@ -137,17 +141,43 @@ export default function MainLayout() {
const handleRefreshNote = useCallback(async (noteId: string) => {
try {
const apiNote = await api.getNote(noteId);
const note: Note = {
const refreshedNote: Note = {
...apiNote,
createdAt: new Date(apiNote.createdAt),
updatedAt: new Date(apiNote.updatedAt),
hiddenAt: apiNote.hiddenAt ? new Date(apiNote.hiddenAt) : null,
};
setSelectedNote(note);

// Update the note in the notes list
setNotes((prev) =>
prev.map((note) => {
if (note.id === noteId) {
// Preserve attachments and folder from local state
return {
...refreshedNote,
attachments: note.attachments,
folder: note.folder,
};
}
return note;
})
);

// Update selected note
setSelectedNote((prev) => {
if (prev?.id === noteId) {
return {
...refreshedNote,
attachments: prev.attachments,
folder: prev.folder,
};
}
return prev;
});
} catch (error) {
console.error('Failed to refresh note:', error);
}
}, [setSelectedNote]);
}, [setSelectedNote, setNotes]);

const handleMasterPasswordUnlock = useCallback(() => {
handleUnlockSuccess();
Expand Down Expand Up @@ -194,6 +224,7 @@ export default function MainLayout() {
onCreateNote: handleCreateNote,
onToggleFolderPanel: handleToggleFolderPanel,
onEmptyTrash: handleEmptyTrash,
creatingNote,
};

const editorProps: EditorProps = {
Expand All @@ -203,7 +234,9 @@ export default function MainLayout() {
onDeleteNote: deleteNote,
onArchiveNote: archiveNote,
onToggleStar: toggleStar,
starringStar,
onHideNote: hideNote,
hidingNote,
onUnhideNote: unhideNote,
onRefreshNote: handleRefreshNote,
userId,
Expand Down
5 changes: 5 additions & 0 deletions src/components/notes/NotesPanel/NoteCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ function NoteCard({
{note.title || 'Untitled'}
</h3>
<div className="flex items-center gap-1">
{note.isNew && (
<span className="mr-1 rounded-full bg-orange-500 px-1 py-0 text-[9px] font-semibold text-white">
NEW
</span>
)}
{hasExecutableCode && (
<div className="flex items-center text-xs" title="Contains executable code">
<Codesandbox className="h-3.5 w-3.5 text-purple-500" />
Expand Down
31 changes: 16 additions & 15 deletions src/components/notes/NotesPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface FilesPanelProps {
onCreateNote: (templateContent?: { title: string; content: string }) => void;
onToggleFolderPanel: () => void;
onEmptyTrash?: () => Promise<void>;
creatingNote?: boolean;
isMobile?: boolean;
onClose?: () => void;
}
Expand All @@ -62,6 +63,7 @@ export default function FilesPanel({
onCreateNote,
onToggleFolderPanel,
onEmptyTrash,
creatingNote = false,
isMobile = false,
onClose,
}: FilesPanelProps) {
Expand Down Expand Up @@ -110,19 +112,11 @@ export default function FilesPanel({

const filterNotes = (notes: Note[], config: FilterConfig): Note[] => {
return notes.filter((note) => {
if (
config.showAttachmentsOnly &&
(!note.attachments || note.attachments.length === 0)
) {
return false;
}
if (config.showStarredOnly && !note.starred) {
return false;
}
if (config.showHiddenOnly && !note.hidden) {
return false;
}
return true;
return !(
(config.showAttachmentsOnly && (!note.attachments || note.attachments.length === 0)) ||
(config.showStarredOnly && !note.starred) ||
(config.showHiddenOnly && !note.hidden)
);
});
};

Expand Down Expand Up @@ -366,9 +360,16 @@ export default function FilesPanel({
size="sm"
className={`flex items-center justify-center gap-1 ${isMobile ? 'h-9 touch-manipulation px-3' : 'h-6 px-2'}`}
title="Create new note from template"
disabled={creatingNote}
>
<Plus className={isMobile ? 'h-4 w-4' : 'h-3 w-3'} />
{!isMobile && <ChevronDown className="h-2 w-2" />}
{creatingNote ? (
<div className={`${isMobile ? 'h-4 w-4' : 'h-3 w-3'} animate-spin rounded-full border-2 border-current border-t-transparent`} />
) : (
<>
<Plus className={isMobile ? 'h-4 w-4' : 'h-3 w-3'} />
{!isMobile && <ChevronDown className="h-2 w-2" />}
</>
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-64" sideOffset={8}>
Expand Down
Loading