Commit Graph
625 Commits
Author SHA1 Message Date
yonlu d289390396 docs(20-01): complete OGG Vorbis tag writer implementation plan
- SUMMARY.md with implementation details and decisions
- STATE.md updated with position, metrics, and key decisions
- ROADMAP.md updated with Phase 20 progress (1/2 plans)
- REQUIREMENTS.md: OGG-01 through OGG-05 marked complete
2026-03-19 13:55:39 -04:00
yonlu 5e98c03634 feat(20-01): implement OGG Vorbis tag writer with custom page parser and CRC32
- Custom OGG page parser/writer with MSB-first CRC32 lookup table (ogg.go)
- Vorbis Comment packet parse/serialize with raw byte preservation (ogg_vorbis.go)
- METADATA_BLOCK_PICTURE base64 encoding for cover art with legacy field stripping
- Multi-stream and non-Vorbis OGG rejection with clear error messages
- Pipeline integration: FormatOGG constant, .ogg in DetectFormat, writeOggTags dispatch
- Lenient-read/strict-write: warn on CRC mismatch, always write correct CRCs
- Page sequence renumbering and crash-safe writes via AtomicWrite
2026-03-19 13:53:36 -04:00
yonlu 3face33a57 docs(20): create phase plan for OGG Vorbis tag writer 2026-03-19 13:20:16 -04:00
yonlu 676eede51e docs(20): research phase domain 2026-03-19 13:15:12 -04:00
yonlu 707d759ced docs(20): capture phase context 2026-03-19 13:06:07 -04:00
yonlu 1f0fe2cc2e docs(phase-19): complete phase execution 2026-03-19 09:03:54 -04:00
yonlu f7077b15df docs(19-02): complete WAV tag writer tests plan
- SUMMARY.md with 7 test results and 2 deviations documented
- STATE.md: Phase 19 complete, all WAV requirements verified
- ROADMAP.md: Phase 19 marked complete
- REQUIREMENTS.md: WAV-06 marked complete
2026-03-19 09:00:29 -04:00
yonlu f11b523afb style(19-02): fix wsl lint warnings in WAV test and writer
- Add blank lines before cuddled expressions in wav_test.go
- Fix cuddled copy expression in wav.go writeRIFF
- All WAV lint issues resolved (remaining are pre-existing in other files)
2026-03-19 08:57:57 -04:00
yonlu 1b28882af4 test(19-02): add round-trip tests for all WAV tag writer requirements
- TestWriteWavTags_TextFields: 9 field round-trip (WAV-01)
- TestWriteWavTags_CoverArt: JPEG embed/read-back (WAV-04)
- TestWriteWavTags_ClearCoverArt: embed then clear (WAV-04)
- TestWriteWavTags_PartialUpdate: 2-of-9 change, 7 preserved (WAV-01)
- TestWriteWavTags_ChunkPreservation: fmt/data/LIST/bext preserved (WAV-02, WAV-03)
- TestWriteWavTags_AtomicSafety: failed write leaves file untouched (WAV-05)
- TestWriteWavTags_RejectsRF64: RF64 rejected with clear error (WAV-02)
- readWavID3Tags uses bogem/id3v2 ParseReader for reliable read-back
2026-03-19 08:53:36 -04:00
yonlu 21fe17212d test(19-02): add WAV test fixture builder and read-back helper
- createTestWAV: builds minimal valid WAV with optional ID3v2 tag
- readWavID3Tags: extracts ID3v2 from RIFF via parseRIFF + dhowden/tag
- createTestWAVWithExtraChunks: adds LIST INFO and bext chunks for preservation tests
- makePCMFmtData: generates 16-byte PCM format data
2026-03-19 08:50:20 -04:00
yonlu 8794584b97 docs(19-01): complete WAV tag writer implementation plan
- SUMMARY.md with task commits, deviations, decisions
- STATE.md updated with position, metrics, decisions
- ROADMAP.md updated with phase 19 progress (1/2 plans)
- REQUIREMENTS.md: WAV-01 through WAV-05 marked complete
2026-03-19 08:47:04 -04:00
yonlu e6610ff15e feat(19-01): implement WAV RIFF parser/writer and writeWavTags
- Add FormatWAV constant and .wav DetectFormat case
- Add FormatWAV dispatch in pipeline WriteTrackTags switch
- Create wav.go with custom RIFF chunk parser/writer
- parseRIFF: lenient read, RF64 rejection, case-insensitive ID3 chunk detection
- writeRIFF: strict write with correct padding and 4GB size check
- writeWavTags: merge existing ID3v2, reuse applyTextChanges/applyCoverArtChanges
- Atomic write via fileutil.AtomicWrite for crash safety
2026-03-19 08:44:38 -04:00
yonlu 8f4c4a0c2b fix(19-01): add album_artist TPE2 mapping to applyTextChanges
- Map FieldAlbumArtist to TPE2 frame via CommonID
- Follows same pattern as FieldComposer → TCOM
- Fixes latent gap in MP3 writing, enables WAV reuse
2026-03-19 08:42:53 -04:00
yonlu d789c0b68e docs(19): create phase plan for WAV tag writer 2026-03-18 20:37:24 -04:00
yonlu c5184fed79 docs(19): research phase domain 2026-03-18 20:33:37 -04:00
yonlu 75e49a839e docs(19): capture phase context 2026-03-18 19:56:59 -04:00
yonlu 5d37eb3a2a docs: create milestone v1.2.1 roadmap (3 phases) 2026-03-18 16:30:15 -04:00
yonlu 6b4adf8690 docs: define milestone v1.2.1 requirements 2026-03-18 15:01:12 -04:00
yonlu 279501f972 docs: complete project research for v1.2.1 Format Parity 2026-03-18 14:33:42 -04:00
yonlu 664de001ed docs: start milestone v1.2.1 Format Parity 2026-03-18 14:20:55 -04:00
yonlu 2256f8f329 chore: complete v1.2 Tag Editing milestone
Archive v1.2 milestone: ROADMAP + REQUIREMENTS + phases to milestones/.
Evolve PROJECT.md with v1.2 validated requirements and key decisions.
Update RETROSPECTIVE.md with v1.2 lessons and cross-milestone trends.
Clean STATE.md for next milestone.
2026-03-18 14:07:28 -04:00
yonlu e37535b115 docs(phase-18): complete phase execution 2026-03-18 13:57:00 -04:00
yonlu 77dec0bceb docs(18-02): complete batch edit UI plan
- SUMMARY.md with task commits, deviations, and self-check
- STATE.md updated: Phase 18 complete, all BATCH requirements fulfilled
- ROADMAP.md updated: 2/2 plans complete for Phase 18
- REQUIREMENTS.md updated: BATCH-02 and BATCH-04 marked complete
2026-03-18 13:53:53 -04:00
yonlu d430ad884b fix(18-02): add field labels to all track-details states (single/batch, read/edit) 2026-03-18 13:40:11 -04:00
yonlu 9df2d6764a fix(18-02): add field labels above title/artist/album inputs in batch edit mode 2026-03-18 13:32:08 -04:00
yonlu 5f21804b20 docs(18-02): update STATE.md for checkpoint pause at task 3 2026-03-18 13:14:53 -04:00
yonlu 656985add9 feat(18-02): wire batch track-details to all 4 view context menus
- track-list: branch on selection count, resolve tracks from this.tracks
- cover-grid: branch on selection count, resolve from expandedTracks
- queue-panel: branch on indices count, resolve via libraryStore.getCachedTracks
- playlist-details: branch on selection count, resolve via libraryStore
- Each view determines coverArt/coverArtMixed state and calls showBatch()
2026-03-18 13:14:02 -04:00
yonlu 6dab32b36b feat(18-02): add batch edit mode to track-details component
- showBatch() API for multi-track entry with merged field values
- Three-state field model: keep/set/clear via dirty tracking in editValues
- Confirmation dialog showing field changes before batch save
- Progress bar with live counter wired to BatchWriteProgress events
- Cancel button calling CancelBatchWrite during batch write
- Results view with success/failure counts and expandable failure details
- Batch cover art: pick, preview, or clear for all selected tracks
- Post-save data refresh returning to updated summary view
- Single-track show() path unchanged (batchMode = false)
2026-03-18 13:11:36 -04:00
yonlu 92f6353fa6 docs(18-01): complete batch write backend plan
- SUMMARY.md with BatchWriteTrackTags implementation details
- STATE.md updated with Phase 18 position and decisions
- ROADMAP.md progress updated (1/2 plans)
- REQUIREMENTS.md: BATCH-01, BATCH-03 marked complete
2026-03-18 13:04:54 -04:00
yonlu f557ffd652 feat(18-01): add BatchWriteTrackTags with progress, cancellation, and partial failure
- Add BatchFailure and BatchResult types for structured batch outcomes
- Add cancelBatch channel and suppressEvents flag to TagWriter struct
- Add CancelBatchWrite method for mid-batch cancellation from frontend
- Add BatchWriteTrackTags method processing tracks sequentially
- Emit BatchWriteProgress event per-track with current/total/succeeded/failed
- Suppress per-track TrackMetadataChanged; emit single event after batch
- Wails bindings auto-generated for BatchWriteTrackTags and CancelBatchWrite
- tagwriter namespace with BatchResult/BatchFailure in models.ts
2026-03-18 13:02:30 -04:00
yonlu 3dba0e143c feat(18-01): add BatchWriteProgress event constant
- Add BatchWriteProgress to tag writing events const block in events.go
- Regenerate frontend/src/events.ts via genevents codegen tool
2026-03-18 13:00:05 -04:00
yonlu 78f0d89331 docs(18): create phase plan — 2 plans in 2 waves for batch edit 2026-03-18 12:33:27 -04:00
yonlu 33ee843d77 docs(18): create phase plan 2026-03-18 12:30:36 -04:00
yonlu 255b8db375 docs(18): capture phase context 2026-03-18 11:44:31 -04:00
yonlu 4e79e1bb16 docs(phase-17): complete phase execution 2026-03-18 11:25:32 -04:00
yonlu b0976c9217 docs(17-02): complete track details save flow & cover art editing plan
- SUMMARY.md with 5 commits (1 feat + 4 fixes during verification)
- STATE.md updated: Phase 17 complete, decisions added
- ROADMAP.md updated: Phase 17 2/2 Complete
- REQUIREMENTS.md updated: EDIT-02, EDIT-03, EDIT-04 all complete
2026-03-18 11:21:46 -04:00
yonlu 8cd4914842 fix(17-02): refresh cover art URLs after save
After a successful save, re-fetch albums alongside tracks and re-resolve
cover art URLs from the updated album data. Previously the dialog only
refreshed this.track but kept stale this.coverArt URLs pointing to the
old content-hash files, causing the image to revert until reopen.
2026-03-18 10:54:17 -04:00
yonlu d7c2965752 fix(17-02): fix cover art replace and remove
Three issues fixed:

1. asBytes() helper for []interface{} → []byte conversion — same
   float64 deserialization issue as numeric fields. Cover art data
   from the frontend arrives as []interface{} of float64, not []byte.

2. DB sync for cover art — was a placeholder no-op. Now saves image
   to covers cache dir (content-hash dedup + thumbnail generation),
   upserts cover_art row, and updates release_groups.cover_art_id.
   Clear sets cover_art_id to NULL on linked release groups.

3. Frontend ReadFile returns base64 string (Go []byte JSON encoding),
   not number[]. Decode with atob() before creating Uint8Array for
   preview blob URL.
2026-03-18 10:36:17 -04:00
yonlu 900db2e56c fix(17-02): handle float64 numeric values from Wails JSON deserialization
Wails deserializes JSON numbers from JavaScript as float64, not int.
All .(int) type assertions on year, track_number, and disc_number
silently failed. Add asInt() helper, replace all assertions.
2026-03-18 07:46:29 -04:00
yonlu ffcdc41b0d fix(17-02): refresh track-details dialog data after successful save
After saveEdit() succeeds, re-fetch tracks from library store and update
this.track with the fresh data so the dialog shows updated values instead
of the stale snapshot passed via show().
2026-03-18 01:23:34 -04:00
yonlu 265a9ea8ce feat(17-02): implement save flow, cover art editing, and error handling
- Wire saveEdit() to WriteTrackTagsByPath with diff-only TagChanges map
- Add cover art selection via ImageFilePicker with instant blob preview
- Add cover art removal (× button) with clearCoverArt state
- Show saving indicator and disable buttons during save
- Display errors inline in action bar; edit mode stays active on error
- Add ReadFile Go method on FrontendUtil to read cover art bytes
- Add Wails binding for ReadFile
- Clean up all edit state (editValues, pendingCoverArt, errorMessage) on close/cancel
2026-03-17 21:20:01 -04:00
yonlu b776f3acb9 docs(17-01): complete backend bridge & frontend plumbing plan
- Created 17-01-SUMMARY.md
- Updated STATE.md with position, decisions, metrics
- Updated ROADMAP.md with plan progress
- Marked EDIT-01 and EDIT-04 complete in REQUIREMENTS.md
2026-03-17 21:07:19 -04:00
yonlu fc5cf70e4c feat(17-01): add TrackMetadataChanged handler and remove selection gate on Track Details
- LibraryStore now listens for TrackMetadataChanged and invalidates all caches
- Track Details context menu item visible for any right-clicked track in all 4 views
- Removed selectionCount === 1 gate from track-list, queue-panel, cover-grid, playlist-details
2026-03-17 21:04:57 -04:00
yonlu 4235b4a4d5 feat(17-01): add WriteTrackTagsByPath and ImageFilePicker backend methods
- WriteTrackTagsByPath resolves filePath to trackID via GetAudioFileByPath
- ImageFilePicker opens native file dialog filtered to JPEG/PNG
- Added Wails TypeScript bindings for both new methods
2026-03-17 21:03:17 -04:00
yonlu 290f236a1b docs(17): fix files_modified in 17-02-PLAN 2026-03-17 18:37:14 -04:00
yonlu 4f7c800fb6 docs(17): create phase plan for single track edit 2026-03-17 18:35:28 -04:00
yonlu 9951a362ea docs(17): capture phase context 2026-03-17 18:25:13 -04:00
yonlu 4dc8724d03 docs(phase-16): complete phase execution 2026-03-17 11:02:48 -04:00
yonlu bdbcd54e92 docs(16-03): complete WriteTrackTags pipeline plan
- SUMMARY.md with pipeline architecture, 5 tests, 7 files
- STATE.md: Phase 16 complete (3/3), decisions, session
- ROADMAP.md: Phase 16 marked complete
- REQUIREMENTS.md: SYNC-01/02/03/04 and WRITE-06 marked complete
2026-03-17 10:58:13 -04:00
yonlu 64322f9353 feat(16-03): WriteTrackTags pipeline with player safety, scan mutex, events, and app wiring
- TagWriter struct with WriteTrackTags entry point orchestrating full pipeline
- PlayerStopper interface + playerAdapter for import-cycle-free player safety
- PipelineLocker interface + pipelineMu on Library for scan/write mutual exclusion
- TrackMetadataChanged event constant + auto-generated TypeScript events
- TagWriter wired into app.go as Wails binding with SetContext in OnStartup
- 5 pipeline integration tests: player safety, scan mutex, orphan cleanup, genre relink, full DB sync
- Lint fixes: static error, else-if, wsl cuddle, golines
2026-03-17 10:55:10 -04:00