fix: update masonry grid sizing logic and notebook list padding

This commit is contained in:
Sepehr Ramezani
2026-02-14 14:20:32 +01:00
parent a0ffc9043b
commit 8f9031f076
580 changed files with 9789 additions and 42619 deletions

View File

@@ -61,6 +61,7 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
const { t } = useLanguage();
const [editingNote, setEditingNote] = useState<{ note: Note; readOnly?: boolean } | null>(null);
const { startDrag, endDrag, draggedNoteId } = useNotebookDrag();
const [muuriReady, setMuuriReady] = useState(false);
// Local state for notes with dynamic size updates
// This allows size changes to propagate immediately without waiting for server
@@ -134,14 +135,20 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
// Calculate columns and item width based on container width
const columns = calculateColumns(containerWidth);
const itemWidth = calculateItemWidth(containerWidth, columns);
const baseItemWidth = calculateItemWidth(containerWidth, columns);
const items = grid.getItems();
items.forEach((item: any) => {
const el = item.getElement();
if (el) {
el.style.width = `${itemWidth}px`;
// Height is auto (determined by content) - Google Keep style
const size = el.getAttribute('data-size') || 'small';
let width = baseItemWidth;
if (columns >= 2 && size === 'medium') {
width = Math.min(baseItemWidth * 1.5, containerWidth);
} else if (columns >= 2 && size === 'large') {
width = Math.min(baseItemWidth * 2, containerWidth);
}
el.style.width = `${width}px`;
}
});
}, []);
@@ -225,13 +232,20 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
if (pinnedGridRef.current && !pinnedMuuri.current) {
pinnedMuuri.current = new MuuriClass(pinnedGridRef.current, layoutOptions)
.on('dragEnd', () => handleDragEnd(pinnedMuuri.current));
applyItemDimensions(pinnedMuuri.current, containerWidth);
pinnedMuuri.current.refreshItems().layout();
}
// Initialize others grid
if (othersGridRef.current && !othersMuuri.current) {
othersMuuri.current = new MuuriClass(othersGridRef.current, layoutOptions)
.on('dragEnd', () => handleDragEnd(othersMuuri.current));
applyItemDimensions(othersMuuri.current, containerWidth);
othersMuuri.current.refreshItems().layout();
}
// Signal that Muuri is ready so sync/resize effects can run
setMuuriReady(true);
};
initMuuri();
@@ -252,6 +266,7 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
// Synchronize items when notes change (e.g. searching, adding)
useEffect(() => {
if (!muuriReady) return;
const syncGridItems = (grid: any, gridRef: React.RefObject<HTMLDivElement | null>, notesArray: Note[]) => {
if (!grid || !gridRef.current) return;
@@ -279,17 +294,31 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
grid.remove(removedItems, { layout: false });
}
// Add new items with correct width
// Add new items with correct width based on size
if (newElements.length > 0) {
newElements.forEach(el => {
el.style.width = `${itemWidth}px`;
const size = el.getAttribute('data-size') || 'small';
let width = itemWidth;
if (columns >= 2 && size === 'medium') {
width = Math.min(itemWidth * 1.5, containerWidth);
} else if (columns >= 2 && size === 'large') {
width = Math.min(itemWidth * 2, containerWidth);
}
el.style.width = `${width}px`;
});
grid.add(newElements, { layout: false });
}
// Update all item widths to ensure consistency
// Update all item widths to ensure consistency (size-aware)
domElements.forEach(el => {
el.style.width = `${itemWidth}px`;
const size = el.getAttribute('data-size') || 'small';
let width = itemWidth;
if (columns >= 2 && size === 'medium') {
width = Math.min(itemWidth * 1.5, containerWidth);
} else if (columns >= 2 && size === 'large') {
width = Math.min(itemWidth * 2, containerWidth);
}
el.style.width = `${width}px`;
});
// Refresh and layout
@@ -308,7 +337,7 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
if (othersMuuri.current) othersMuuri.current.refreshItems().layout();
}, 300);
});
}, [pinnedNotes, othersNotes]); // Re-run when notes change
}, [pinnedNotes, othersNotes, muuriReady]); // Re-run when notes change or Muuri becomes ready
// Handle container resize to update responsive layout
useEffect(() => {
@@ -349,7 +378,7 @@ export function MasonryGrid({ notes, onEdit }: MasonryGridProps) {
clearTimeout(resizeTimeout);
observer.disconnect();
};
}, [applyItemDimensions]);
}, [applyItemDimensions, muuriReady]);
return (
<div ref={containerRef} className="masonry-container">