Commit Graph

749 Commits

Author SHA1 Message Date
Claudio Ortolina 39371b26af Show artwork upload preview full-size 2025-07-18 18:43:30 +01:00
Claudio Ortolina 9fe3830e7c Enable gzip in prod 2025-07-17 17:46:29 +01:00
Claudio Ortolina 5e73231767 Move SearchGlobalShortcut to a colocated hook 2025-07-17 17:32:24 +01:00
Claudio Ortolina 7fb8a0d05c Fix font size for online stores collapsible element 2025-07-17 09:12:21 +01:00
Claudio Ortolina 5553c4ffa5 Fix font weight for json_viewer component 2025-07-17 09:11:42 +01:00
Claudio Ortolina acd34424f7 Use LiveToast instead of built-in flash helpers
So that they can stack and get dismissed automatically
2025-07-16 15:26:30 +01:00
Claudio Ortolina 41f040363e Display url_template in monospace font 2025-07-16 13:45:46 +01:00
Claudio Ortolina 91e39124af Simplify online shops UI in wishlist detail view 2025-07-16 11:18:35 +01:00
Claudio Ortolina d24a4386e2 Make top artists rows clickable 2025-07-15 16:22:36 +01:00
Claudio Ortolina 27e9f565e4 Display online stores favicon URLs via Google API 2025-07-15 15:58:46 +01:00
Claudio Ortolina 66651933a5 Group sections in "more" menu 2025-07-15 10:53:44 +01:00
Claudio Ortolina f89d28fae5 Standardize and simplify online store templates list markup 2025-07-15 10:40:39 +01:00
Claudio Ortolina 6386e5e20d Fix live preview for new templates 2025-07-15 10:20:07 +01:00
Claudio Ortolina f329d66fb1 Add format to online store templates 2025-07-15 10:08:40 +01:00
Claudio Ortolina 7d23e7a597 Add live preview of template 2025-07-15 10:05:25 +01:00
Claudio Ortolina 65de5fc833 Add first version of online stores for wishlisted records (claude)
See docs/plans/online_stores.md
2025-07-15 09:42:59 +01:00
Claudio Ortolina af4587fdbf Default record lists to 50 items per page 2025-07-14 12:48:16 +01:00
Claudio Ortolina 405051dcf6 Insert new scrobble rule at the top to match db order 2025-07-13 21:19:28 +01:00
Claudio Ortolina c55fd695e4 Enforce minimum width for record detail action menus 2025-07-13 17:57:36 +01:00
Claudio Ortolina 9bc7f70b50 Fix leading for record details title 2025-07-13 17:57:19 +01:00
Claudio Ortolina 3b08006624 Rename "Collected release" -> "Wishlisted release" 2025-07-13 17:53:31 +01:00
Claudio Ortolina 939c36865f Allow editing a record title 2025-07-13 11:05:29 +01:00
Claudio Ortolina e887addaf2 Simplify form and handling of record dominant colors 2025-07-13 11:05:16 +01:00
Claudio Ortolina fea5e3e862 Use responsive list for scrobble rules list 2025-07-13 10:17:40 +01:00
Claudio Ortolina 24ff180b56 Change button copy from "Apply All Rules" to "Apply All" 2025-07-12 18:05:46 +01:00
Claudio Ortolina 07af0b57d2 Increase size of cover art in editing form
So that colors can be easily picked
2025-07-12 17:40:34 +01:00
Claudio Ortolina b598a179fc Improve markup for color inputs 2025-07-12 17:37:38 +01:00
Claudio Ortolina 06a3e2c54e Use form object colors for form
So that more than one color can be updated at any given time
2025-07-12 17:35:30 +01:00
Claudio Ortolina 2aeae28cd5 First pass at manual editing of dominant colors 2025-07-11 08:54:34 +01:00
Claudio Ortolina 9ecbd470af Add button to copy selected release ID 2025-07-07 13:48:00 +01:00
Claudio Ortolina 35cd81f4a3 Reposition tracklist button 2025-07-07 13:40:26 +01:00
Claudio Ortolina ad74560cf9 Enable Ctrl/Meta+K to trigger universal search 2025-07-07 11:36:41 +01:00
Claudio Ortolina 1492b197ce Make top albums and artists async 2025-07-07 10:19:47 +01:00
Claudio Ortolina a49d8d8f07 Remove unused @record attribute 2025-07-07 10:00:41 +01:00
Claudio Ortolina fbac011e76 Change badge colours for scrobble rule type 2025-07-07 09:22:44 +01:00
Claudio Ortolina f57485e509 Allow manual upload of artist image 2025-07-06 16:57:30 +01:00
Claudio Ortolina 97950e3ad5 Place the universal search modal and the top and make it taller 2025-07-06 14:57:20 +01:00
Claudio Ortolina 4b27699d47 Remove copy about unsupported keyboard shortcuts 2025-07-06 10:19:31 +01:00
Claudio Ortolina c3a4eb56d1 Remove custom debouncing
Search is already debounced via phx-debounce, and doesn't need extra
handling via `handle_info` (which doesn't really help anyway - Claude
added it without thinking it through).
2025-07-06 10:01:29 +01:00
Claudio Ortolina 0d855167ff Consolidate search reset logic 2025-07-06 09:55:41 +01:00
Claudio Ortolina 3787736e39 Remove custom loading state logic 2025-07-06 09:44:42 +01:00
Claudio Ortolina 745bc88061 Remove not working keyboard navigation 2025-07-06 09:39:47 +01:00
Claudio Ortolina 07b51c8c6e Replace custom modal with Fluxon modal 2025-07-06 09:32:07 +01:00
Claudio Ortolina 29986b7041 Remove broken phx-window-keydown directives 2025-07-06 09:18:03 +01:00
Claudio Ortolina b86e8abd52 Remove universal search hooks
- Global shortcuts don't work
- Focus input on open can be achieved just with 'autofocus' attribute
- Maintaining focus when input is active can be achieved just by adding
  an ID to the input
2025-07-06 09:14:57 +01:00
Claudio Ortolina 7056334a06 Import components to remove namespacing 2025-07-05 19:31:05 +01:00
Claudio Ortolina f5092e32c5 Use Fluxon elements for universal search 2025-07-05 19:28:57 +01:00
Claudio Ortolina 543cbe39b7 Misc universal search improvements
- Use zinc instead of gray
- Translate all strings, and remove redundant ones
- Add format, type and release year to record results
- Use existing helpers instead of hand-rolled variants
2025-07-05 19:14:42 +01:00
Claudio Ortolina 069e44e575 Show artworks in universal search 2025-07-05 18:40:46 +01:00
Claudio Ortolina c4d4c91477 First draft: universal search (Claude)
# Universal Search Modal Implementation Plan

## Overview

This plan outlines the implementation of a universal search modal that
provides unified search across Records (Collection), Records (Wishlist),
and Artists. The modal will be accessible via a search icon in the top
navigation bar and a keyboard shortcut.

## Requirements

### Core Features
- Modal accessible via:
  - Search icon in top navigation bar
  - Keyboard shortcut (Ctrl/Cmd + K)
- Search across three entity types:
  1. Records in Collection
  2. Records in Wishlist
  3. Artists
- Real-time search as user types
- Keyboard navigation support
- Mobile-responsive design

### Search Functionality
- Leverage existing FTS5 search infrastructure
- Support existing search syntax (artist:, album:, genre:, etc.)
- Show search results grouped by entity type
- Limit results per category (e.g., 5 per type)
- Click-to-navigate to full results or individual records

## Technical Architecture

### 1. Modal Component Structure

**New Components:**
- `UniversalSearchModal` - Main modal component
- `SearchResultGroup` - Groups results by type (Collection, Wishlist,
Artists)
- `SearchResultItem` - Individual result display
- `SearchInput` - Enhanced search input with keyboard shortcuts

**Component Location:**
```
lib/music_library_web/components/
├── search_components.ex          # New universal search components
└── layouts/app.html.heex         # Add search icon to navigation
```

### 2. LiveView Integration

**New LiveView Module:**
```
lib/music_library_web/live/universal_search_live/
├── index.ex                      # Main search LiveView
└── index.html.heex              # Search modal template
```

**Integration Points:**
- Mount as child LiveView in main layout
- Handle modal open/close state
- Manage search query and results
- Handle keyboard navigation

### 3. Backend Search Implementation

**New Context Functions:**
```elixir
# In lib/music_library/search.ex (new module)
def universal_search(query, opts \\ [])
def search_collection(query, limit \\ 5)
def search_wishlist(query, limit \\ 5)
def search_artists(query, limit \\ 5)
```

**Search Strategy:**
- Reuse existing `Records.search_collection/2` and
`Records.search_wishlist/2`
- Extend `Artists.search/2` or create new artist search function
- Combine results with type metadata
- Implement result limiting and pagination

### 4. Database Considerations

**Leverage Existing Infrastructure:**
- Use existing `records_search_index` FTS5 table
- Utilize existing search parser for tagged queries
- Consider artist search optimization (may need artist search index)

**Artist Search Enhancement:**
- Current artist search may need optimization
- Consider adding FTS5 index for artist_infos table if performance
issues
- Leverage existing artist_records view for artist-record relationships

## Implementation Details

### 1. Modal Behavior

**Desktop:**
- Modal opens centered on screen
- Size: `max-w-2xl` (responsive)
- Overlay with backdrop blur
- Esc key to close, click outside to close

**Mobile:**
- Full-screen modal on mobile (`sm:max-w-2xl max-w-full`)
- Touch-friendly result items
- Swipe down to close (if feasible)
- Virtual keyboard considerations

### 2. Search Interface

**Search Input:**
- Placeholder: "Search records and artists..."
- Auto-focus when modal opens
- Debounced search (300ms delay)
- Clear button when text present
- Loading indicator during search

**Search Results:**
```
┌─────────────────────────────────────┐
│ Search: "radiohead ok computer"     │
├─────────────────────────────────────┤
│ COLLECTION (3 results)              │
│ • OK Computer - Radiohead           │
│ • Kid A - Radiohead                 │
│ • In Rainbows - Radiohead           │
│ View all 12 collection results →    │
├─────────────────────────────────────┤
│ WISHLIST (1 result)                 │
│ • Hail to the Thief - Radiohead     │
│ View all 1 wishlist results →       │
├─────────────────────────────────────┤
│ ARTISTS (1 result)                  │
│ • Radiohead                         │
│ View artist page →                  │
└─────────────────────────────────────┘
```

### 3. Keyboard Navigation

**Keyboard Shortcuts:**
- `Ctrl/Cmd + K` - Open modal
- `Esc` - Close modal
- `↑/↓` - Navigate results
- `Enter` - Select highlighted result
- `Tab` - Move between sections

**Implementation:**
- Use Phoenix LiveView's `phx-window-keydown` for global shortcuts
- Implement focus management with JavaScript hooks
- Maintain accessibility standards (ARIA labels, focus indicators)

### 4. Result Navigation

**Click Actions:**
- Record results → Navigate to record show page
- Artist results → Navigate to artist page
- "View all X results" → Navigate to respective list page with search
applied

**URL Strategy:**
- Don't change URL for modal open/close
- When navigating to results, apply search query to destination page
- Use existing search parameter patterns

## Database Schema Impact

**No Schema Changes Required:**
- Leverage existing tables and search infrastructure
- May add database indexes for performance if needed

**Performance Considerations:**
- Monitor query performance with combined searches
- Consider query result caching for common searches
- Implement search result limits to prevent slow queries

## Testing Strategy

### 1. Unit Tests

**Search Logic Tests:**
```elixir
# test/music_library/search_test.exs
describe "universal_search/2" do
  test "searches across all entity types"
  test "limits results per category"
  test "handles empty queries"
  test "handles special characters"
  test "respects search syntax (artist:, album:, etc.)"
end
```

### 2. Integration Tests

**LiveView Tests:**
```elixir
# test/music_library_web/live/universal_search_live_test.exs
describe "UniversalSearchLive" do
  test "opens modal on keyboard shortcut"
  test "searches as user types"
  test "displays results grouped by type"
  test "navigates to selected results"
  test "handles keyboard navigation"
  test "closes modal on escape"
end
```

### 3. Component Tests

**Search Components:**
```elixir
# test/music_library_web/components/search_components_test.exs
describe "SearchResultGroup" do
  test "renders results with proper grouping"
  test "shows 'view all' link when more results available"
  test "handles empty result sets"
end
```

### 4. JavaScript/Hook Tests

**Browser Tests:**
- Test keyboard shortcuts work globally
- Test focus management
- Test modal open/close behavior
- Test mobile touch interactions

## Mobile Considerations

### 1. Layout Adaptations

**Mobile Modal:**
- Full-screen on small devices
- Reduced padding and margins
- Larger touch targets for results
- Simplified result display (fewer details)

**Touch Interactions:**
- Swipe down to close modal
- Tap to select results
- Pull-to-refresh for search results

### 2. Performance

**Mobile Optimization:**
- Shorter debounce delays on mobile
- Reduced result limits on mobile
- Lazy loading for large result sets
- Optimize image loading for album covers

### 3. Virtual Keyboard

**iOS/Android Considerations:**
- Modal positioning with virtual keyboard
- Proper input focus management
- Prevent zoom on input focus

## Implementation Phases

### Phase 1: Core Modal Infrastructure
1. Create basic modal component
2. Add search icon to navigation
3. Implement modal open/close
4. Add keyboard shortcut support

### Phase 2: Search Backend
1. Create universal search context
2. Implement combined search functions
3. Add result limiting and grouping
4. Optimize query performance

### Phase 3: Search Interface
1. Implement search input with debouncing
2. Add search result display
3. Implement keyboard navigation
4. Add result selection and navigation

### Phase 4: Mobile & Polish
1. Mobile layout optimizations
2. Touch interaction improvements
3. Performance optimizations
4. Accessibility enhancements

### Phase 5: Testing & Documentation
1. Comprehensive test coverage
2. Performance testing
3. Mobile device testing
4. Documentation updates

## Success Metrics

**Functionality:**
- Modal opens/closes reliably
- Search results are accurate and fast
- Keyboard navigation works smoothly
- Mobile experience is touch-friendly

**Performance:**
- Search queries complete in <500ms
- Modal opens in <100ms
- No janky animations or interactions
- Efficient database queries

**Usability:**
- Easy to discover and use
- Intuitive keyboard shortcuts
- Clear result presentation
- Seamless navigation to results

## Risks and Mitigation

**Performance Risks:**
- Complex queries may be slow
- **Mitigation:** Implement query limits, caching, and monitoring

**Mobile Experience:**
- Small screen constraints
- **Mitigation:** Responsive design, touch-friendly interfaces

**Accessibility:**
- Keyboard navigation complexity
- **Mitigation:** Follow ARIA guidelines, comprehensive testing

**Search Accuracy:**
- Users may expect Google-like search
- **Mitigation:** Clear documentation of search syntax, good defaults

## Future Enhancements

**Advanced Features:**
- Search history and suggestions
- Saved searches
- Search filters and facets
- Search result previews

**Integration:**
- Integration with barcode scanning
- Voice search capabilities
- External search (MusicBrainz, Last.fm)

**Analytics:**
- Search usage analytics
- Popular search terms
- Search success rates

## Conclusion

This universal search modal will significantly improve the user
experience by providing quick access to all content types from any page.
The implementation leverages existing infrastructure while adding a
modern, accessible search interface that works well on both desktop and
mobile devices.

The phased approach ensures a solid foundation while allowing for
iterative improvements based on user feedback and usage patterns.
2025-07-05 16:47:06 +01:00