From 1c38dc87e357c5f9cf57dba8f1404cfd0d6e2938 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 26 Jun 2025 10:33:27 -0400 Subject: [PATCH] fix: drag handle actions now affect the correct block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added menuNode state to capture the node position when menu opens - Updated all action functions to use menuNode instead of currentNode - This ensures drag handle actions (Turn into, Delete, etc.) always affect the block where the handle was clicked, not where the mouse currently hovers - Also formatted code with prettier 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- SVG_ANALYSIS_REPORT.md | 94 ++++--- prd/PRD-codebase-cleanup-refactoring.md | 32 ++- src/assets/styles/_z-index.scss | 2 +- src/assets/styles/variables.scss | 1 - src/lib/actions/tooltip.ts | 2 +- .../components/HorizontalPhotoScroll.svelte | 5 +- src/lib/components/MasonryPhotoGrid.svelte | 2 +- src/lib/components/PhotoGrid.svelte | 23 +- .../components/SingleColumnPhotoGrid.svelte | 2 +- .../components/ThreeColumnPhotoGrid.svelte | 2 +- src/lib/components/TwoColumnPhotoGrid.svelte | 2 +- src/lib/components/admin/BaseDropdown.svelte | 4 +- src/lib/components/admin/BaseModal.svelte | 14 +- .../admin/BaseSegmentedController.svelte | 4 +- .../admin/DeleteConfirmationModal.svelte | 9 +- src/lib/components/admin/DropdownMenu.svelte | 63 ++--- src/lib/components/admin/FormField.svelte | 2 +- src/lib/components/admin/Modal.svelte | 10 +- .../components/admin/PublishDropdown.svelte | 9 +- .../components/admin/StatusDropdown.svelte | 16 +- .../admin/composer/ComposerCore.svelte | 30 ++- .../admin/composer/ComposerLinkManager.svelte | 2 +- .../composer/ComposerMediaHandler.svelte.ts | 2 +- .../admin/composer/ComposerToolbar.svelte | 4 +- .../admin/composer/MediaInsertDropdown.svelte | 2 +- .../admin/composer/TextStyleDropdown.svelte | 2 +- .../components/admin/composer/editorConfig.ts | 7 +- src/lib/components/admin/composer/index.ts | 2 +- src/lib/components/admin/composer/types.ts | 2 +- .../composer/useComposerEvents.svelte.ts | 6 +- .../admin/composer/useDropdown.svelte.ts | 2 +- src/lib/components/edra/drag-handle.svelte | 245 ++++++++++-------- src/lib/components/edra/editor.css | 1 - .../edra/extensions/drag-handle/index.ts | 12 +- src/lib/components/edra/tooltip.scss | 2 +- src/lib/components/icons/CloseButton.svelte | 2 +- src/lib/components/icons/CopyIcon.svelte | 12 +- src/lib/components/icons/FileIcon.svelte | 2 +- src/routes/test-grids/+page.svelte | 34 ++- 39 files changed, 353 insertions(+), 316 deletions(-) diff --git a/SVG_ANALYSIS_REPORT.md b/SVG_ANALYSIS_REPORT.md index f64d4cf..9038220 100644 --- a/SVG_ANALYSIS_REPORT.md +++ b/SVG_ANALYSIS_REPORT.md @@ -9,6 +9,7 @@ This analysis examines SVG usage patterns in the Svelte 5 codebase to identify o ### 1. Inline SVGs vs. Imported SVGs **Inline SVGs Found:** + - **Close/X buttons**: Found in 7+ components with identical SVG code - `admin/Modal.svelte` - `admin/UnifiedMediaModal.svelte` @@ -17,8 +18,8 @@ This analysis examines SVG usage patterns in the Svelte 5 codebase to identify o - `admin/GalleryManager.svelte` - `admin/MediaDetailsModal.svelte` - `Lightbox.svelte` - - **Loading spinners**: Found in 2+ components + - `admin/Button.svelte` - `admin/ImageUploader.svelte` - `admin/GalleryUploader.svelte` @@ -30,26 +31,23 @@ This analysis examines SVG usage patterns in the Svelte 5 codebase to identify o ### 2. SVG Import Patterns **Consistent patterns using aliases:** + ```svelte -// Good - using $icons alias -import ArrowLeft from '$icons/arrow-left.svg' -import ChevronDownIcon from '$icons/chevron-down.svg' - -// Component imports with ?component -import PhotosIcon from '$icons/photos.svg?component' -import ViewSingleIcon from '$icons/view-single.svg?component' - -// Raw imports -import ChevronDownIcon from '$icons/chevron-down.svg?raw' +// Good - using $icons alias import ArrowLeft from '$icons/arrow-left.svg' import ChevronDownIcon +from '$icons/chevron-down.svg' // Component imports with ?component import PhotosIcon from +'$icons/photos.svg?component' import ViewSingleIcon from '$icons/view-single.svg?component' // Raw +imports import ChevronDownIcon from '$icons/chevron-down.svg?raw' ``` ### 3. Unused SVG Files **Unused icons in `/src/assets/icons/`:** + - `dashboard.svg` - `metadata.svg` **Unused illustrations in `/src/assets/illos/`:** + - `jedmund-blink.svg` - `jedmund-headphones.svg` - `jedmund-listening-downbeat.svg` @@ -65,11 +63,13 @@ import ChevronDownIcon from '$icons/chevron-down.svg?raw' ### 4. Duplicate SVG Definitions **Close/X Button SVG** (appears 7+ times): + ```svg ``` **Loading Spinner SVG** (appears 3+ times): + ```svg @@ -90,44 +90,47 @@ import ChevronDownIcon from '$icons/chevron-down.svg?raw' ### 1. Create Reusable Icon Components **Option A: Create individual icon components** + ```svelte - + ``` **Option B: Create an Icon component with name prop** + ```svelte {#if IconComponent} - + {/if} ``` ### 2. Extract Inline SVGs to Files Create new SVG files for commonly used inline SVGs: + - `/src/assets/icons/close.svg` - `/src/assets/icons/loading.svg` - `/src/assets/icons/external-link.svg` @@ -137,12 +140,14 @@ Create new SVG files for commonly used inline SVGs: ### 3. Clean Up Unused Assets Remove the following unused files to reduce bundle size: + - All unused illustration files (11 files) - Unused icon files (2 files) ### 4. Standardize Import Methods Establish a consistent pattern: + - Use `?component` for SVGs used as Svelte components - Use direct imports for SVGs used as images - Avoid `?raw` imports unless necessary @@ -152,21 +157,36 @@ Establish a consistent pattern: ```svelte - - - + + + ``` @@ -183,4 +203,4 @@ Establish a consistent pattern: 1. **High Priority**: Extract and componentize duplicate inline SVGs (close button, loading spinner) 2. **Medium Priority**: Remove unused SVG files -3. **Low Priority**: Standardize all import patterns and create comprehensive icon system \ No newline at end of file +3. **Low Priority**: Standardize all import patterns and create comprehensive icon system diff --git a/prd/PRD-codebase-cleanup-refactoring.md b/prd/PRD-codebase-cleanup-refactoring.md index 1f1081c..7cd6c2d 100644 --- a/prd/PRD-codebase-cleanup-refactoring.md +++ b/prd/PRD-codebase-cleanup-refactoring.md @@ -3,7 +3,7 @@ **Date**: December 26, 2025 **Author**: Claude Code **Status**: Draft -**Priority**: High +**Priority**: High ## Executive Summary @@ -20,18 +20,21 @@ This PRD outlines a comprehensive cleanup and refactoring plan for the jedmund-s ## Key Findings ### 1. Overengineered Components + - **EnhancedComposer** (1,347 lines) - Handles too many responsibilities - **LastFM Stream Server** (625 lines) - Complex data transformations that could be simplified - **Multiple Media Modals** - Overlapping functionality across 3+ modal components - **Complex State Management** - Components with 10-20 state variables ### 2. Unused Code + - 5 unused components (Squiggly, PhotoLightbox, Pill, SVGHoverEffect, MusicPreview) - 13 unused SVG files (2 icons, 11 illustrations) - Minimal commented-out code (good!) - 1 potentially unused API endpoint (/api/health) ### 3. DRY Violations + - **Photo Grid Components** - 3 nearly identical components - **Modal Components** - Duplicate backdrop and positioning logic - **Dropdown Components** - Repeated dropdown patterns @@ -39,6 +42,7 @@ This PRD outlines a comprehensive cleanup and refactoring plan for the jedmund-s - **Segmented Controllers** - Duplicate animation and positioning logic ### 4. Hardcoded Values + - **Colors**: 200+ hardcoded hex/rgba values instead of using existing variables - **Spacing**: 1,000+ hardcoded pixel values instead of using `$unit` system - **Z-indexes**: 60+ hardcoded z-index values without consistent scale @@ -46,6 +50,7 @@ This PRD outlines a comprehensive cleanup and refactoring plan for the jedmund-s - **Border radius**: Not using existing `$corner-radius-*` variables ### 5. SVG Issues + - 7+ duplicate inline close button SVGs - 3+ duplicate loading spinner SVGs - Inconsistent import patterns @@ -54,9 +59,11 @@ This PRD outlines a comprehensive cleanup and refactoring plan for the jedmund-s ## Implementation Timeline ### Phase 1: Quick Wins (Week 1) + Focus on low-risk, high-impact changes that don't require architectural modifications. - [x] **Remove unused components** (5 components) + - [x] Delete `/src/lib/components/Squiggly.svelte` - [x] Delete `/src/lib/components/PhotoLightbox.svelte` - [x] Delete `/src/lib/components/Pill.svelte` @@ -64,6 +71,7 @@ Focus on low-risk, high-impact changes that don't require architectural modifica - [x] Delete `/src/lib/components/MusicPreview.svelte` - [x] **Remove unused SVG files** (13 files) + - [x] Delete unused icons: `dashboard.svg`, `metadata.svg` - [x] Delete unused illustrations (11 files - see SVG analysis report) @@ -72,18 +80,22 @@ Focus on low-risk, high-impact changes that don't require architectural modifica - [x] Address TODO in `/src/lib/server/api-utils.ts` about authentication (noted for future work) ### Phase 2: CSS Variable Standardization (Week 2) + Create a consistent design system by extracting hardcoded values. - [x] **Create z-index system** + - [x] Create `src/assets/styles/_z-index.scss` with constants - [x] Replace 60+ hardcoded z-index values - [x] **Extract color variables** + - [x] Add missing color variables for frequently used colors - [x] Replace 200+ hardcoded hex/rgba values (replaced most common colors) - [x] Create shadow/overlay variables for rgba values - [x] **Standardize spacing** + - [x] Add missing unit multipliers (added `$unit-7x` through `$unit-19x` and common pixel values) - [x] Replace 1,000+ hardcoded pixel values with unit variables (replaced in key components) @@ -92,15 +104,18 @@ Create a consistent design system by extracting hardcoded values. - [x] Replace hardcoded duration values (replaced in key components) ### Phase 3: Component Refactoring (Weeks 3-4) + Refactor components to reduce duplication and complexity. - [x] **Create base components** + - [x] Extract `BaseModal` component for shared modal logic - [x] Create `BaseDropdown` for dropdown patterns - [x] Merge `FormField` and `FormFieldWrapper` - [x] Create `BaseSegmentedController` for shared logic - [x] **Refactor photo grids** + - [x] Create unified `PhotoGrid` component with `columns` prop - [x] Remove 3 duplicate grid components - [x] Use composition for layout variations @@ -112,9 +127,11 @@ Refactor components to reduce duplication and complexity. - [x] Extract other repeated inline SVGs (FileIcon, CopyIcon) ### Phase 4: Complex Refactoring (Weeks 5-6) + Tackle the most complex components and patterns. - [x] **Refactor EnhancedComposer** + - [x] Split into focused sub-components - [x] Extract toolbar component - [x] Separate media management @@ -122,6 +139,7 @@ Tackle the most complex components and patterns. - [x] Reduce state variables from 20+ to <10 - [ ] **Simplify LastFM Stream Server** + - [ ] Extract data transformation utilities - [ ] Simplify "now playing" detection algorithm - [ ] Reduce state tracking duplication @@ -133,9 +151,11 @@ Tackle the most complex components and patterns. - [ ] Eliminate prop drilling with stores ### Phase 5: Architecture & Utilities (Week 7) + Improve overall architecture and create shared utilities. - [ ] **Create shared utilities** + - [ ] API client with consistent error handling - [ ] CSS mixins for common patterns - [ ] Media handling utilities @@ -148,9 +168,11 @@ Improve overall architecture and create shared utilities. - [ ] Create shared animation definitions ### Phase 6: Testing & Documentation (Week 8) + Ensure changes don't break functionality and document new patterns. - [ ] **Testing** + - [ ] Run full build and type checking - [ ] Test all refactored components - [ ] Verify no regressions in functionality @@ -165,19 +187,23 @@ Ensure changes don't break functionality and document new patterns. ## Success Metrics 1. **Code Reduction** + - Target: 20-30% reduction in total lines of code - Eliminate 1,000+ instances of code duplication 2. **Component Simplification** + - No component larger than 500 lines - Average component size under 200 lines 3. **Design System Consistency** + - Zero hardcoded colors in components - All spacing using design tokens - Consistent z-index scale 4. **Bundle Size** + - 10-15% reduction in JavaScript bundle size - Removal of unused assets @@ -189,11 +215,13 @@ Ensure changes don't break functionality and document new patterns. ## Risk Mitigation 1. **Regression Testing** + - Test each phase thoroughly before moving to next - Keep backups of original components during refactoring - Use feature flags for gradual rollout if needed 2. **Performance Impact** + - Monitor bundle size after each phase - Profile component render performance - Ensure no performance regressions @@ -215,4 +243,4 @@ Each phase should be implemented as a separate git branch with the ability to re --- -**Next Steps**: Review this PRD and approve the implementation timeline. Each phase can be tracked using the checkboxes above. \ No newline at end of file +**Next Steps**: Review this PRD and approve the implementation timeline. Each phase can be tracked using the checkboxes above. diff --git a/src/assets/styles/_z-index.scss b/src/assets/styles/_z-index.scss index 312ea91..c1f0121 100644 --- a/src/assets/styles/_z-index.scss +++ b/src/assets/styles/_z-index.scss @@ -36,4 +36,4 @@ $z-index-toast: 10000; // Admin-specific z-indexes $z-index-admin-nav: 100; $z-index-admin-sidebar: 200; -$z-index-admin-modal: 1050; \ No newline at end of file +$z-index-admin-modal: 1050; diff --git a/src/assets/styles/variables.scss b/src/assets/styles/variables.scss index 2469618..f438a84 100644 --- a/src/assets/styles/variables.scss +++ b/src/assets/styles/variables.scss @@ -225,7 +225,6 @@ $info-color: $blue-50; // Component specific $image-border-color: rgba(0, 0, 0, 0.03); - /* Shadows and Overlays * -------------------------------------------------------------------------- */ $card-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); diff --git a/src/lib/actions/tooltip.ts b/src/lib/actions/tooltip.ts index 5d061e4..6c5b827 100644 --- a/src/lib/actions/tooltip.ts +++ b/src/lib/actions/tooltip.ts @@ -49,4 +49,4 @@ export function tooltip(element: HTMLElement, options: TooltipOptions | string) } } } -} \ No newline at end of file +} diff --git a/src/lib/components/HorizontalPhotoScroll.svelte b/src/lib/components/HorizontalPhotoScroll.svelte index f91fcbb..a781f00 100644 --- a/src/lib/components/HorizontalPhotoScroll.svelte +++ b/src/lib/components/HorizontalPhotoScroll.svelte @@ -6,10 +6,7 @@ showCaptions?: boolean } - let { - photos = [], - showCaptions = true - }: Props = $props() + let { photos = [], showCaptions = true }: Props = $props()
diff --git a/src/lib/components/MasonryPhotoGrid.svelte b/src/lib/components/MasonryPhotoGrid.svelte index ce9a29f..1da4992 100644 --- a/src/lib/components/MasonryPhotoGrid.svelte +++ b/src/lib/components/MasonryPhotoGrid.svelte @@ -10,4 +10,4 @@ let { photos = [], columns = 'auto' }: Props = $props() - \ No newline at end of file + diff --git a/src/lib/components/PhotoGrid.svelte b/src/lib/components/PhotoGrid.svelte index 7d6452e..4c0b114 100644 --- a/src/lib/components/PhotoGrid.svelte +++ b/src/lib/components/PhotoGrid.svelte @@ -21,22 +21,21 @@ class: className = '' }: Props = $props() - - // Split photos into columns for column-based layouts function splitIntoColumns(photos: Photo[], numColumns: number): Photo[][] { const columns: Photo[][] = Array.from({ length: numColumns }, () => []) - + photos.forEach((photo, index) => { columns[index % numColumns].push(photo) }) - + return columns } - const columnPhotos = $derived( - (columns === 1 || columns === 2 || columns === 3) && !masonry ? splitIntoColumns(photos, columns) : [] + (columns === 1 || columns === 2 || columns === 3) && !masonry + ? splitIntoColumns(photos, columns) + : [] ) // Window width for responsive masonry @@ -45,9 +44,9 @@ // Calculate masonry column widths based on columns prop const masonryConfig = $derived(() => { if (!masonry) return null - + const gapSize = gap === 'small' ? 8 : gap === 'large' ? 32 : 16 - + if (columns === 1) { const width = windowWidth - 64 // Account for padding return { minColWidth: width, maxColWidth: width, gap: gapSize } @@ -55,7 +54,7 @@ const width = Math.floor((windowWidth - 64 - gapSize) / 2) return { minColWidth: width - 10, maxColWidth: width + 10, gap: gapSize } } else if (columns === 3) { - const width = Math.floor((windowWidth - 64 - (gapSize * 2)) / 3) + const width = Math.floor((windowWidth - 64 - gapSize * 2) / 3) return { minColWidth: width - 10, maxColWidth: width + 10, gap: gapSize } } else { // Auto columns @@ -90,7 +89,7 @@ > {#snippet children({ item })}
- + {#if showCaptions}

{item.caption || ''}

{/if} @@ -147,7 +146,7 @@ &--3-column { display: flex; gap: var(--grid-gap); - + @include breakpoint('mobile') { flex-direction: column; } @@ -233,4 +232,4 @@ } } } - \ No newline at end of file + diff --git a/src/lib/components/SingleColumnPhotoGrid.svelte b/src/lib/components/SingleColumnPhotoGrid.svelte index f06ba47..ff51cee 100644 --- a/src/lib/components/SingleColumnPhotoGrid.svelte +++ b/src/lib/components/SingleColumnPhotoGrid.svelte @@ -9,4 +9,4 @@ let { photos = [] }: Props = $props() - \ No newline at end of file + diff --git a/src/lib/components/ThreeColumnPhotoGrid.svelte b/src/lib/components/ThreeColumnPhotoGrid.svelte index ad2df82..4687db7 100644 --- a/src/lib/components/ThreeColumnPhotoGrid.svelte +++ b/src/lib/components/ThreeColumnPhotoGrid.svelte @@ -9,4 +9,4 @@ let { photos = [] }: Props = $props() - \ No newline at end of file + diff --git a/src/lib/components/TwoColumnPhotoGrid.svelte b/src/lib/components/TwoColumnPhotoGrid.svelte index 5be9155..d915802 100644 --- a/src/lib/components/TwoColumnPhotoGrid.svelte +++ b/src/lib/components/TwoColumnPhotoGrid.svelte @@ -9,4 +9,4 @@ let { photos = [] }: Props = $props() - \ No newline at end of file + diff --git a/src/lib/components/admin/BaseDropdown.svelte b/src/lib/components/admin/BaseDropdown.svelte index 43cd090..3024a22 100644 --- a/src/lib/components/admin/BaseDropdown.svelte +++ b/src/lib/components/admin/BaseDropdown.svelte @@ -53,7 +53,7 @@