Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rodrigogs/whats-reader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.29.4
Choose a base ref
...
head repository: rodrigogs/whats-reader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.30.0
Choose a head ref
  • 12 commits
  • 46 files changed
  • 5 contributors

Commits on Jan 11, 2026

  1. Merge pull request #64 from rodrigogs/main

    chore: sync main to dev after v1.29.1
    github-actions[bot] authored Jan 11, 2026
    Configuration menu
    Copy the full SHA
    68bc785 View commit details
    Browse the repository at this point in the history

Commits on Mar 3, 2026

  1. feat: improve date format detection and resilience

    - Add support for DD/MM/YY with AM/PM (12-hour European/Brazilian format)
    - Add support for dot-time format (HH.MM.SS) and Finnish 'klo' marker
    - Add support for bracketed year-first formats [YYYY/MM/DD]
    - Implement smart line normalization:
      - Remove bidirectional marks (LTR/RTL)
      - Normalize AM/PM variants (a.m., p.m., p. m. → AM/PM)
      - Convert dot-separated time to colon format
      - Trim Unicode whitespace
    - Improve date pattern detection:
      - Score patterns across file sample (first 200 lines)
      - Detect day-first vs month-first ambiguity
      - Prioritize patterns by frequency and context
      - Graceful fallback to all patterns if no clear match
    - Ensure proper localization of timestamps in MediaGallery lightbox
    
    Resolves #69
    rodrigogs committed Mar 3, 2026
    Configuration menu
    Copy the full SHA
    d8f9ddc View commit details
    Browse the repository at this point in the history
  2. fix: preserve original line content in parseLine for sender/content

    Co-authored-by: rodrigogs <2362425+rodrigogs@users.noreply.github.com>
    Copilot and rodrigogs committed Mar 3, 2026
    Configuration menu
    Copy the full SHA
    ec7c3da View commit details
    Browse the repository at this point in the history
  3. Merge pull request #72 from rodrigogs/main

    chore: sync main to dev after v1.29.2
    github-actions[bot] authored Mar 3, 2026
    Configuration menu
    Copy the full SHA
    eaa4f78 View commit details
    Browse the repository at this point in the history

Commits on Mar 31, 2026

  1. Configuration menu
    Copy the full SHA
    3fb9633 View commit details
    Browse the repository at this point in the history
  2. ci: upgrade all GitHub Actions to Node.js 24-compatible versions

    - actions/checkout v4 → v6
    - actions/setup-node v4 → v6
    - actions/cache v4 → v5
    - actions/upload-artifact v4 → v7
    - actions/download-artifact v4 → v8
    - actions/upload-pages-artifact v3 → v4
    - actions/deploy-pages v4 → v5
    - actions/github-script v7 → v8
    - cycjimmy/semantic-release-action v4 → v6
    rodrigogs committed Mar 31, 2026
    Configuration menu
    Copy the full SHA
    906912b View commit details
    Browse the repository at this point in the history
  3. chore: sync main to dev

    rodrigogs committed Mar 31, 2026
    Configuration menu
    Copy the full SHA
    fe63aa7 View commit details
    Browse the repository at this point in the history

Commits on Apr 1, 2026

  1. feat: add persistent conversation feature with cross-platform file re…

    …storation (#66)
    
    * feat: add persistent conversation feature with cross-platform file restoration
    
    Implement "Remember Conversation" toggle that persists chat sessions
    across app restarts using IndexedDB (idb-keyval). Three platform
    strategies: Electron file paths, Chromium FileSystemFileHandle, and
    fallback reselect for Firefox/Safari.
    
    New components: RestoreSessionModal, ReselectFileModal, Toast, Modal.
    Stores metadata, bookmarks, transcriptions, settings (~1MB).
    Never stores the ZIP file itself.
    
    * fix: resolve all 15 type errors in persistent conversations feature
    
    - Add File System Access API type declarations (FileSystemHandlePermissionDescriptor,
      OpenFilePickerOptions, FileSystemFileHandle augmentation, Window.showOpenFilePicker)
      to the global scope in src/app.d.ts
    - Register 7 missing icon names (alert-circle, folder, clock, check-all, x,
      check-circle, message-circle) in the Icon component with SVG path definitions
    - Add missing isElectronPathReference import in +page.svelte, which also resolves
      the union type narrowing error for filePath access
    
    * fix(electron): harden file:readFromPath IPC handler
    
    - Restrict to .zip files only to prevent path traversal attacks
    - Use async fs.promises.readFile() instead of blocking readFileSync()
    - Properly slice Buffer to ArrayBuffer using byteOffset/byteLength
    
    * fix(i18n): replace hardcoded English strings with Paraglide messages
    
    Replace hardcoded strings in RestoreSessionModal ("Select All",
    "Deselect All") and ReselectFileModal ("Drop WhatsApp ZIP file here",
    "or click below to browse", "Browse Files") with proper Paraglide i18n
    message calls. Added translations for all 10 supported languages.
    
    * fix(persistence): clean up IndexedDB entries when removing a remembered chat
    
    When a user removed a chat via handleRemoveChat(), persisted data in
    IndexedDB was not cleaned up, leaving orphaned entries that caused the
    restore modal to show stale chats. Now handleRemoveChat checks if the
    chat is in rememberedChats and, if so, finds and removes the persisted
    entry from IndexedDB before removing it from UI state.
    
    * fix(persistence): add error logging to silent catch blocks
    
    Add console.error/warn logging to five catch blocks in
    persistence.svelte.ts that were silently swallowing errors, making
    IndexedDB issues impossible to debug.
    
    * fix(ReselectFileModal): eliminate drag-drop flicker with counter pattern
    
    Replace boolean isDragging state with dragCounter pattern to fix visual
    flicker that occurred when dragging files over nested elements. The counter
    increments on dragenter and decrements on dragleave, preventing the rapid
    toggling that caused the flicker.
    
    * chore: remove AI handoff document
    
    * fix: clean up dead code, timer leaks, and unused imports
    
    * fix: resolve critical bugs and extract duplicated parse/index logic
    
    - Fix C2: restore loop now awaits user reselect via Promise pattern
      instead of continuing to next chat immediately
    - Fix C1: add one-time guard to $effect for persistence check
    - Fix C3: harden Electron file read with path normalization and
      symlink protection (lstat check)
    - DRY: extract startIndexWorker() and makeProgressCallback() from
      ~150 lines of duplicated code between handleFilesSelected and
      loadChatFromBuffer
    
    * fix: address final review items
    
    - Replace remaining hardcoded English strings with i18n messages
    - Filter transcriptions to only include current chat's message IDs
      when persisting (prevents cross-chat data leakage)
    - Add translations for new keys to all 9 non-English locales
    - Document chatFileReferences intentional non-reactive mutation
    
    * fix: translate all persistence keys and remove dead isRestoring state
    
    * refactor: deduplicate getBookmarksForChatAsExport
    
    * fix(electron): use file descriptor to prevent TOCTOU race in file read
    
    * refactor(Toast): replace inline SVGs with Icon component
    
    Replace inline SVG elements with the reusable Icon component for better code maintainability and consistency. The status icon now uses check-circle for success and alert-circle for error/info types, while the close button uses the x icon.
    
    * fix(a11y): add aria-label to drop zone and i18n Modal close label
    
    - Add aria-label to drop zone in ReselectFileModal for screen reader accessibility
    - Replace hardcoded 'Close modal' string with i18n key close_modal in Modal component
    - Add close_modal translations to all 10 locale files (en, pt, es, fr, de, it, nl, ja, zh, ru)
    
    * refactor: address all 13 review items
    
    Correctness:
    - #1: handleRemoveChat now removes from UI first (sync), cleans up
      IndexedDB in background to avoid stale index issues
    - #2: Remove redundant double-store of FileSystemFileHandle
      (savePersistedChat already handles it)
    - #3: Restored chats now populate chatFileReferences with persistedId
      to prevent orphaned duplicates on toggle
    
    Security:
    - #4: Use file descriptor with O_NOFOLLOW to prevent TOCTOU race
      in Electron file read IPC
    
    DRY:
    - #5: Extract LoadingChat interface to shared state.svelte.ts
    - #6: getBookmarksForChatAsExport delegates to getBookmarksForChat
    - #7: Extract sanitizeFilename helper to format.ts
    - #8: formatDate kept local (locale-aware, not extractable)
    - #9: Add addRemembered/removeRemembered helpers (5 call sites)
    
    i18n/Accessibility:
    - #10: Add aria-label to ReselectFileModal drop zone
    - #11: i18n Modal close label across 10 locales
    
    Clean Code:
    - #12: Split handleToggleRemember into rememberChat/forgetChat
    - #13: Toast uses Icon component instead of inline SVGs
    
    * fix: address all 9 Copilot review comments
    
    1. Capture Electron file.path from drag-drop for persistence
    2. Block metadata restoration when file validation fails
    3. Deduplicate savePersistedChat (removes existing entry first)
    4. Filter transcriptions by chat message IDs (prevents cross-chat leak)
    5. Case-insensitive .zip check in ReselectFileModal
    6. Clamp dragCounter to 0 minimum
    7. Use isAbsolute + reject .. segments for Electron path validation
    8. Guard error.message with instanceof Error check
    9. Add keyboard/click handlers to drop zone for accessibility
    
    * fix: address 3 new Copilot review comments
    
    - Seed rememberedChats from IndexedDB on load so toggle state is
      correct even when user skips restore modal or clicks Start Fresh
    - Fix verifyHandlePermission docstring to reflect shouldRequest param
    - Use chatId+messageId composite key for bookmark import dedup to
      prevent cross-chat bookmark collisions
    
    * fix: capture FileSystemFileHandle during drag-drop for seamless persistence
    
    - Use DataTransferItem.getAsFileSystemHandle() during drop event to
      capture handles without showing a second file picker (Chrome 86+)
    - Remove promptForFileHandle() call from rememberChat — handles are
      now captured at drag-drop time, eliminating the confusing double-
      file-picker UX
    - Update reselect flow to capture Electron file.path and update the
      persisted entry so future restores work automatically
    - Add DataTransferItem.getAsFileSystemHandle type declaration
    
    * fix: capture file handles synchronously during drop and fix closure bug
    
    - Start all getAsFileSystemHandle() Promises synchronously via
      Promise.all before any await, preventing DataTransferItem
      invalidation after first async tick
    - Capture handleIndex and file path BEFORE the async IIFE to avoid
      closure-over-loop-variable bug where stale index was read after
      multiple awaits
    
    * fix: pass Electron file path from dialog to persistence layer
    
    The Electron file picker (openFile dialog) returns the absolute path
    but it was discarded when creating the File object from the buffer.
    This caused all Electron-picked files to be stored as
    'reselect-required' instead of 'electron-path', forcing manual
    reselection on every restore.
    
    Now FileDropZone passes the path from Electron's dialog result via
    a new 'paths' callback parameter. handleFilesSelected prefers this
    explicit path over file.path (drag-drop fallback).
    
    * debug: add persistence flow logging to trace Electron path issue
    
    * fix: address 4 Copilot review comments
    
    - Toast: reset visibility and restart timer when message prop changes
    - FileDropZone: use showOpenFilePicker() on Chrome for file input to
      capture FileSystemFileHandle (drag-drop already captures handles;
      this fixes the regular "click to browse" flow)
    - Remove unused isFileSystemAccessSupported import from +page.svelte
    - Electron dialog path already fixed (result.path passed via paths
      callback parameter)
    
    * fix: address 3 Copilot review comments
    
    - Electron IPC: add lstat pre-check for cross-platform symlink
      rejection (O_NOFOLLOW not supported on Windows), with graceful
      fallback to O_RDONLY when O_NOFOLLOW unavailable
    - FileDropZone: enable multi-select in showOpenFilePicker to match
      the existing <input multiple> behavior
    - CSS: use :where(button) for low-specificity cursor rule so Tailwind
      utilities can override it
    
    * fix: ReselectFileModal uses Electron dialog to capture file path
    
    The reselect modal was using the web file input which doesn't
    capture the absolute file path in Electron. Now uses the Electron
    native dialog (electronAPI.openFile) which returns the path, and
    passes it through to updatePersistedChat so the entry is upgraded
    from 'reselect-required' to 'electron-path'. After one reselect,
    future restores work automatically.
    
    * fix: move Remember Conversation above Transcription Language in context menu
    
    * fix: ReselectFileModal captures FileSystemFileHandle on Chrome and upgrades persisted entries
    
    The reselect modal was using plain <input type=file> on Chrome,
    which doesn't capture a FileSystemFileHandle. This meant even after
    reselecting, the entry stayed as 'reselect-required' and the user
    would be prompted again on every restart.
    
    Now:
    - Chrome/Edge: uses showOpenFilePicker() to capture a handle, then
      upgrades the persisted entry from 'reselect-required' to
      'file-handle' via storeFileHandle + updatePersistedChat
    - Electron: uses native dialog to capture path, upgrades to
      'electron-path'
    - Drag-drop in reselect modal also captures handle via
      getAsFileSystemHandle()
    
    After one reselect, future restores work automatically on all
    platforms.
    
    * fix: removing chat from list no longer deletes persisted data
    
    Removing a chat only clears it from the current session. Persisted
    data in IndexedDB is preserved so the chat reappears in the restore
    modal on next launch. To permanently forget a chat, user must toggle
    Remember Conversation off.
    
    * chore: remove debug logging from persistence flow
    
    * fix: sidebar import uses Electron dialog and captures file path
    
    The sidebar "Import chat" button was using a plain <input type=file>
    which doesn't reliably provide file.path in Electron. Now uses the
    same platform-aware import as the main drop zone:
    - Electron: native dialog via electronAPI.openFile() with path capture
    - Chrome/Edge: showOpenFilePicker() with handle capture
    - Fallback: regular file input
    
    Also fixes Node.js Buffer pool issue in dialog:openFile handler
    (was sending entire shared ArrayBuffer instead of just the file's
    portion).
    
    * refactor: address all review items - dead code, DRY, a11y, error feedback
    
    - Replace dynamic import of storeFileHandle with static import
    - Remove 6 unused i18n keys from all 10 locale files
    - Remove dead exports: promptForFileHandle, getPersistedChat, getBookmarksForChatAsExport
    - Add error toast on restore failure in handleRestoreChats
    - Extract shared file-picker helpers (openZipFilePicker, openElectronFile, getElectronFilePath)
    - Add aria-label to FileDropZone drop zone
    - Rename persistence_close_notification to close_notification in Toast
    
    * refactor: centralize modals, fix cross-chat ID collisions, address review feedback
    
    - Extract ChatAvatar component replacing 3 inline avatar implementations
    - Add shared formatRelativeDate helper (label/compact modes)
    - Add Button size="lg" variant with disabled styles
    - Vertically center Modal on all breakpoints, not just desktop
    - RestoreSessionModal: remove description banner, only chat list scrolls,
      fixed footer with action buttons
    - Fix message ID collisions across chats by including filename in hash
    - Fix Toast timer not restarting when message changes while visible
    - Gate reselect flow: only upgrade persisted entry when validation passes
    - Add persistence_restore_failed i18n key across all 10 locales
    - Remove unused isFileSystemAccessSupported import and function
    
    ---------
    
    Co-authored-by: Rodrigo Gomes da Silva <rodrigo.smscom@gmail.com>
    Copilot and rodrigogs authored Apr 1, 2026
    Configuration menu
    Copy the full SHA
    432bdb4 View commit details
    Browse the repository at this point in the history
  2. Merge pull request #81 from rodrigogs/dev

    release: persistent conversations
    rodrigogs authored Apr 1, 2026
    Configuration menu
    Copy the full SHA
    9a56ab9 View commit details
    Browse the repository at this point in the history
  3. chore: update non-breaking dependencies

    Update 18 packages to latest minor/patch versions:
    - svelte 5.45→5.55, @sveltejs/kit 2.49→2.55, vite 7.2→7.3
    - tailwindcss 4.1→4.2, @tailwindcss/vite 4.1→4.2
    - @biomejs/biome 2.3→2.4 (migrate config schema)
    - electron 39.2→39.8, electron-builder 26.0→26.8
    - @inlang/paraglide-js 2.6→2.15, @inlang/cli 3.0→3.1
    - semantic-release 25.0.2→25.0.3, svelte-check 4.3→4.4
    rodrigogs committed Apr 1, 2026
    Configuration menu
    Copy the full SHA
    0339368 View commit details
    Browse the repository at this point in the history
  4. chore: update deps and CI to Node 24

    - Update 18 non-breaking dependencies to latest minor/patch
    - Migrate Biome config schema to 2.4.10
    - Bump all CI workflows from Node 22 to Node 24
      (fixes npm ci lockfile incompatibility with npm 11)
    rodrigogs committed Apr 1, 2026
    Configuration menu
    Copy the full SHA
    00cfe23 View commit details
    Browse the repository at this point in the history
  5. chore(release): 1.30.0 [skip ci]

    # [1.30.0](v1.29.4...v1.30.0) (2026-04-01)
    
    ### Bug Fixes
    
    * preserve original line content in parseLine for sender/content ([ec7c3da](ec7c3da))
    
    ### Features
    
    * add persistent conversation feature with cross-platform file restoration ([#66](#66)) ([432bdb4](432bdb4))
    * improve date format detection and resilience ([d8f9ddc](d8f9ddc)), closes [#69](#69)
    semantic-release-bot committed Apr 1, 2026
    Configuration menu
    Copy the full SHA
    ad7bf68 View commit details
    Browse the repository at this point in the history
Loading