Commit Graph

1056 Commits

Author SHA1 Message Date
Maurice 24bcf6ded8 fix(journey): websocket sync across devices + 404 redirect
- broadcastJourneyEvent now excludes by socket ID instead of user ID,
  so other devices of the same user receive real-time updates (#615)
- Routes pass x-socket-id header through to broadcast functions
- loadJourney handles 404 gracefully — redirects to /journey with
  toast instead of infinite spinner (#616)
2026-04-13 23:03:58 +02:00
Maurice 240b10a192 fix(journey): thumbnails, batch add, optimistic delete, shared albums
- Gallery/timeline load thumbnails instead of originals (50-100KB vs 2-5MB)
- Batch endpoint for adding multiple provider photos in one request
- Optimistic photo deletion — no full page reload on delete
- Immich albums include shared albums
- Select-all button moved outside scroll container (always visible)
- Album tab loads actual album contents via /albums/:id/photos
2026-04-13 22:48:40 +02:00
Maurice 88e1d075e0 fix(build): add ScrollTrigger component, fix JSX syntax, dedup i18n
- Add missing ScrollTrigger component for infinite scroll
- Fix JSX placement inside ternary expression
- Remove 290 duplicate i18n keys across 13 translation files
- Fix it.ts duplicate memories.saveError
2026-04-13 21:55:59 +02:00
Maurice 87de60d8de fix(photos): paginated search with infinite scroll (#613)
Replace bulk-loading all Immich photos (up to 20k) with paginated
search: 50 photos per page, automatic infinite scroll via
IntersectionObserver. Prevents server blocking on large libraries.

- Backend: searchPhotos accepts page/size params, returns hasMore
- Frontend: loads 50 at a time, appends on scroll
- AbortController cancels in-flight requests on tab switch
2026-04-13 21:46:48 +02:00
Maurice e395935f6a fix(photos): cap search to 5000 photos + abort pending requests
Large Immich libraries (7k+ photos) caused timeouts and pending
requests when using "All Photos". Cap pagination at 5 pages (5000
photos) and abort in-flight requests when switching tabs.
2026-04-13 21:31:03 +02:00
Maurice 3a52b80e3a fix(migration): handle old trip_photos schema (immich_asset_id)
Migration 98 assumed trip_photos already had asset_id + provider
columns, but older DBs still have the original immich_asset_id
column. Now detects schema variant and adapts accordingly.
2026-04-13 21:16:16 +02:00
Maurice 7e3cb29c57 fix(journey): album photos, select-all, heading/hr fixes, dark mode
- Load actual album photos instead of date-range search fallback
  (new GET /albums/:id/photos for Immich + Synology)
- Add select all / deselect all toggle in photo picker
- Normalize Markdown headings to plain text in journal stories
- Fix setext headings (---) rendering as hr instead of h2
- Add remark-breaks for proper line break rendering
- Fix pros/cons dark mode gradient backgrounds
- i18n: selectAll/deselectAll in 14 languages
2026-04-13 21:06:15 +02:00
Maurice c60332dcf1 fix(journey): normalize headings and fix setext hr in story text
- Render h1/h2/h3 as plain paragraphs — journal stories are plain
  text, not structured documents
- Preprocess text to insert blank line before --- and === so they
  become horizontal rules instead of setext headings
2026-04-13 20:46:20 +02:00
Maurice 6c253c71c3 fix(weather): handle archive date out of range for future trips (#599)
When a trip is far in the future (e.g. May 2027), the climate fallback
looked up last year's data (May 2026). But if that date hasn't passed
yet, the Open-Meteo archive API returns 400. Now checks if the
reference date is still in the future and goes back one more year.

Fixes the flood of 400 errors that could trigger CrowdSec bans.
2026-04-13 20:33:30 +02:00
Maurice 33c63d34e7 fix(journey): prevent duplicate skeleton entries for multi-day places (#606)
When syncing trip places to journal, places assigned to multiple days
(e.g. multi-night hotels) produced one skeleton entry per day_assignment
row. The existing dedup check only looked at DB state, not at entries
added within the same sync loop. Add the place ID to the tracking set
after insertion so the same place is never inserted twice.
2026-04-13 20:27:48 +02:00
Maurice 149aa4c5e2 fix(collab): preserve line breaks in notes display (#608)
Add remark-breaks plugin so single newlines in note content render
as <br> instead of being collapsed by Markdown. Applies to both
the card preview and the expanded view.
2026-04-13 20:24:13 +02:00
Maurice 1f68ba1ea1 fix(atlas): prevent Nominatim 429 rate limiting (#576)
- Swap resolve order: try local bbox lookup before Nominatim reverse
  geocode — eliminates most external API calls
- Add global throttling (1.1s min between requests) to
  reverseGeocodeCountry so /stats can't flood Nominatim
- Update User-Agent header to include repo URL per Nominatim policy
2026-04-13 20:16:36 +02:00
Maurice c0c59b6d80 feat: unified photo provider abstraction layer (#584)
Introduce trek_photos as central photo registry. Frontend uses
/api/photos/:id/:kind instead of provider-specific URLs. Adding
a new photo provider is now backend-only work.

- New trek_photos table (migration 98) with photo_id FK in
  trip_photos and journey_photos
- Unified /api/photos/:id/thumbnail|original|info endpoint
- photoResolverService for central resolution and streaming
- ProviderPicker: add "All Photos" tab, rename tabs, fix i18n
- Localize all hardcoded strings in JourneyDetailPage (14 langs)
- Fix date formatting to use browser locale instead of hardcoded 'en'
- Journey stats as styled tile cards
2026-04-13 20:08:31 +02:00
Ben Haas 479ab49d67 Merge branch 'dev' into search-auto-complete 2026-04-13 08:47:36 -07:00
Ben Haas 1a51f8e3e1 Add translations for "Loading place details…" and improve place search functionality
- Integrate a loading spinner for "Name" input field during place search.
- Enhance OpenStreetMap place detail retrieval with Nominatim lookup.
- Update `authStore` to track Google Maps API key presence.
2026-04-13 08:28:34 -07:00
Ben Haas 7fca16d866 Switch location bias from a point to a bounding box for improved autocomplete accuracy and validation. 2026-04-13 07:53:40 -07:00
jubnl e629548a42 fix(tests): align tests to actual working code 2026-04-13 14:48:25 +02:00
Julien G. c39182616b Merge pull request #603 from mauriceboe/fix/map-multi-category-filter
fix(map): support multi-category filter on map view
2026-04-13 14:34:16 +02:00
jubnl 1d9a6acc01 fix(map): support multi-category filter on map view
The category filter bridge was collapsing Set<string> to a single
string, emitting '' (no filter) whenever more than one category was
selected. Map now uses the same Set-based membership predicate as the
sidebar list filter.

Closes #602
2026-04-13 14:32:38 +02:00
Marco Sadowski 18da5aed39 Merge branch 'dev' into feature/naver-support 2026-04-13 10:04:28 +02:00
Isaias Tavares 60c5755647 fix(i18n): remove only true duplicate translation keys in 8 language files 2026-04-12 20:10:07 -03:00
Isaias Tavares b84381a8de Revert "fix(i18n): remove duplicate translation keys in 8 language files"
This reverts commit c19e65b46b.
2026-04-12 20:09:35 -03:00
Isaias Tavares c19e65b46b fix(i18n): remove duplicate translation keys in 8 language files 2026-04-12 20:04:32 -03:00
Isaias Tavares 44f5f7d114 chore: retrigger CI 2026-04-12 20:03:57 -03:00
Isaias Tavares f46f484d5f test(i18n): update SUPPORTED_LANGUAGES assertions to use objectContaining
Entries now include a locale field, so exact equality checks were
failing. objectContaining matches on value/label only.
2026-04-12 20:03:57 -03:00
Isaias Tavares bf3649942c refactor(i18n): add locale to SUPPORTED_LANGUAGES and derive LOCALES from it
LOCALES is now built via Object.fromEntries from SUPPORTED_LANGUAGES,
so adding a new language only requires one change in supportedLanguages.ts.
Also types translations as Record<SupportedLanguageCode, ...> so TypeScript
enforces that every supported language has a translation entry.
2026-04-12 20:03:57 -03:00
Isaias Tavares 91f7c3778f refactor(i18n): extract SUPPORTED_LANGUAGES to avoid duplication
Move language list to supportedLanguages.ts so TranslationContext and
settingsStore can import from a single source of truth, eliminating
the hardcoded array in setLanguageTransient.
2026-04-12 20:03:57 -03:00
Isaias Tavares abed22661a fix(login): address PR review feedback
- Use apiClient instead of raw fetch() in configApi.getPublicConfig
- Validate DEFAULT_LANGUAGE against supported codes on server startup
- Log warning instead of silently swallowing fetch errors in LoginPage
- Case-insensitive browser language matching in detectBrowserLanguage
- Guard against undefined navigator in detectBrowserLanguage
- Validate language code in setLanguageTransient before applying
- Import directly from TranslationContext instead of barrel index
2026-04-12 20:03:57 -03:00
Isaias Tavares 57503a6a10 feat(login): add language dropdown, browser auto-detection and configurable default
Replace the language cycling button on the login page with a dropdown
showing all 14 supported languages. Add automatic browser/OS language
detection via navigator.languages, falling back to a configurable
DEFAULT_LANGUAGE env var, then 'en' as last resort.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 20:03:57 -03:00
jubnl 34df665944 fix(workflow): keep more tags at once 2026-04-13 00:39:33 +02:00
Maurice e179769a8f Fix ghost Gallery entries in journal timeline and public share
- deleteEntry now deletes photos with the entry instead of moving them
  to a hidden Gallery entry that becomes an undeletable ghost
- deletePhoto cleans up empty Gallery entries after last photo removed
- getJourneyFull and getPublicJourney filter out empty Gallery entries
  so existing ghosts are hidden in both internal and shared views
2026-04-13 00:18:45 +02:00
Maurice 0d7238300e Fix mobile bottom nav dark mode, always-on widgets, hero stats, atlas scrollbar
- BottomNav respects dark mode via settingsStore (matching Navbar pattern)
- Currency/Timezone widgets always visible on mobile regardless of desktop setting
- Hero trip stats simplified to 3 columns (Days, Places, Buddies) — removed Starts date
- Atlas page uses h-screen overflow-hidden to prevent double scrollbar
2026-04-13 00:11:49 +02:00
Maurice e3dea0a3ea Merge pull request #593 from isaiastavares/fix/i18n-translations
fix(i18n): comprehensive translation audit and fixes across all 14 languages
2026-04-12 23:51:22 +02:00
Maurice 6a19807a72 Fix Nominatim User-Agent and improve error diagnostics
- Update User-Agent from old NOMAD URL to TREK
- Include HTTP status code and response body in Nominatim error messages
2026-04-12 23:31:22 +02:00
Maurice 4680aa254d Fix map tooltips, journey creation, and contributor avatars
- Map tooltips now respect light/dark mode via CSS variables
- Journey creation inherits cover image from first selected trip
- Only day-assigned places are synced to journey (no unplanned places)
- Place count in trip picker reflects assigned places only
- Contributor avatars shown in journey detail page
- Suggestion banner button visible in dark mode (!important override)
- Dashboard list view uses correct trips array and status label
2026-04-12 23:20:13 +02:00
Isaias Tavares 137c6ff9dd fix(i18n): standardize ellipsis to three dots (...) for consistency
Revert common.loading and common.saving from Unicode ellipsis (…) back to
three dots (...) to match the rest of the project (e.g. "Optional caption...").
Update 4 test files that were incorrectly using the Unicode ellipsis character.
2026-04-12 17:41:14 -03:00
Isaias Tavares af789b7f7c fix(i18n): translate hardcoded strings in JourneyDetailPage and fix ellipsis in all languages
- Replace all remaining hardcoded strings in JourneyDetailPage JourneySettingsDialog with t() calls
- Add 14 missing translation keys to all 13 non-English language files
  (trips.member*, common.expand/collapse, inspector.remove, memories.*, journey.*)
- Fix common.loading and common.saving to use Unicode ellipsis (…) instead of three dots (...)
- Update 4 test files that expected three-dot ellipsis to use Unicode ellipsis
- All 2541 tests passing
2026-04-12 17:29:11 -03:00
Isaias Tavares 0fe1c443e9 fix(i18n): translate remaining German hardcoded strings in PhotoUpload
Replace 6 hardcoded German strings in PhotoUpload.tsx with t() calls:
- 'Tag verknüpfen' → t('photos.linkDay')
- 'Kein Tag' / 'Tag N' → t('photos.noDay') / t('photos.dayLabel')
- '{N} Foto(s) ausgewählt' → t('photos.photoSelected/photosSelected')
- 'bis zu 30 Fotos' hint → t('photos.fileTypeHint')
- 'Wird hochgeladen...' → t('common.uploading')

Add all 6 new keys to all 14 language files and update test
assertions from German strings to English equivalents.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:53:50 -03:00
Isaias Tavares ecbb1de8de test: update tests to use English translation strings
Tests were asserting against hardcoded German strings that were replaced
with t() calls. Updated to match the English translation values rendered
by TranslationProvider in the test environment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:46:03 -03:00
Isaias Tavares 9c42a01391 fix(i18n): comprehensive translation audit and fixes across all 14 languages
- Fix critical bug: Photos and Files pages had German text hardcoded in JSX,
  now use t() keys visible correctly in all languages
- Add 16 new translation keys (photos/files UI, login validation, common errors,
  rate limit message) across all 14 language files
- Add missing keys in packing, memories, and budget sections for br, de, it, es,
  fr, nl, pl, cs, hu, ru, zh, zh-TW, ar
- Add 152+ missing keys for zh-TW (entire sections were absent)
- Change Vacay addon name to 'Férias' in pt-BR only
- Add client-side HTTP 429 interceptor that shows translated rate limit message
- Replace hardcoded English fallbacks in TripPlannerPage, DayPlanSidebar,
  DisplaySettingsTab, MapSettingsTab, AccountTab, and TodoListPanel with t()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:36:32 -03:00
Julien G. 7abfb4deba Merge pull request #591 from mauriceboe/feat/prerelease-workflow
Feat/prerelease workflow
2026-04-12 17:24:19 +02:00
jubnl ad27c5f6be fix: restore broken tests after prerelease workflow refactor
- Export __clearVersionCacheForTests() from adminService; call in
  versionNotification beforeEach to reset module-scoped cache between
  tests (VNOTIF-002..006 failed because VNOTIF-001 cached
  update_available:false, short-circuiting all subsequent test fetches)
- Seed appVersion:'2.9.10' in Navbar test authStore; appVersion moved
  from local useEffect state to authStore in last commit so the test
  render no longer fetches it independently (FE-COMP-NAVBAR-016)
- Add data-testid="weekend-days" to VacaySettings weekend-days
  container; use within() in tests to scope button count to that
  section, fixing false positives from the week-start buttons which
  share the same inline styles (FE-COMP-VACAYSETTINGS-003/004)
- Pass isPrerelease={true} in GitHubPanel FE-ADMIN-GH-007; component
  filters out prerelease releases when isPrerelease=false so the badge
  was never rendered (pre-existing, unrelated to last commit)
2026-04-12 17:19:24 +02:00
jubnl 86be4d7997 fix: address prerelease workflow review bugs
- Type checkVersion() with VersionInfo interface; fixes TS errors in
  checkAndNotifyVersion() where object type blocked property access
- Don't cache fallback on !resp.ok or fetch throw; prevents a transient
  GitHub outage from poisoning the 5-min version cache
- Guard parseInt result with Number.isFinite() in compareVersions;
  malformed -pre.abc tags no longer silently compare as equal via NaN
- Pre-compute stripped versions before sort in checkVersion(); avoids
  mutating input array and redundant replace() calls in comparator
- Bump GitHub releases fetch from per_page=20 to per_page=100
- Store appVersion in authStore; populate from App.tsx getAppConfig call
  and remove redundant getAppConfig fetch in Navbar useEffect
- Type GitHubPanel error/expanded state as string|null and Record<number,boolean>
2026-04-12 17:05:17 +02:00
jubnl a2c05f3caa fix: Remove nomad references in stable build workflow 2026-04-12 16:51:33 +02:00
jubnl 62453ebefa fix: harden prerelease workflow against races, orphan tags, and edge cases
- Add concurrency groups to both workflows to prevent parallel version-bump races
- Defer git tag push to merge job so orphan tags can't exist without a live image
- Pin build/merge jobs to the SHA captured in version-bump to prevent TOCTOU
- Guard auto-finalize in docker.yml against cross-major prereleases (requires bump=major + confirm_major=MAJOR)
- Add STABLE fallback to 0.0.0 for fresh repos with no stable tag
- Fix cleanup sort to extract numeric N via awk instead of fragile sort -t. -k4 -n
- Add 5-minute in-memory cache to checkVersion to avoid GitHub API rate limits
- Type GitHubPanel releases state; remove any cast on filter
- Quote all $VERSION/$MAJOR_TAG vars in imagetools create calls
2026-04-12 16:50:54 +02:00
jubnl e198791139 fix: address prerelease workflow review issues
- Remove stale mauriceboe/nomad tags from docker-dev.yml
- Fix APP_VERSION empty string fallback (?? -> ||)
- Fix compareVersions to handle -pre.N suffixes correctly
- Use highest existing N instead of tag count to avoid collision after cleanup
- Add cleanup step to keep only last 5 prerelease tags per base version
2026-04-12 16:39:50 +02:00
jubnl e1a7558647 Merge remote-tracking branch 'origin/feat/prerelease-workflow' into feat/prerelease-workflow 2026-04-12 16:27:17 +02:00
jubnl 981b667fbb feat: prerelease workflow with major version support and version propagation
- Add docker-dev.yml: prerelease CI for dev branch with minor/major bump
  inputs; auto-continues in-flight major line via existing pre tags;
  publishes floating major-pre Docker tag (e.g. 2-pre)
- Rewrite docker.yml version-bump: tag-based versioning, manual bump
  inputs (auto/patch/minor/major), major guarded by confirm_major=MAJOR,
  auto-finalizes in-flight prereleases; publishes floating major tag (e.g. 2)
- Inject APP_VERSION build-arg through Dockerfile so the running container
  knows its real version instead of reading package.json
- Server reads APP_VERSION env in authService/adminService; exposes
  is_prerelease in app config and update-check response; prerelease builds
  compare against GitHub prerelease releases rather than latest stable
- Client stores isPrerelease from config; navbar shows amber version badge
  on prerelease builds (left of dark-mode toggle); GitHubPanel filters out
  prerelease releases unless the running build is itself a prerelease
2026-04-12 16:26:44 +02:00
jubnl 1b45571e63 feat: prerelease workflow with major version support and version propagation
- Add docker-dev.yml: prerelease CI for dev branch with minor/major bump
  inputs; auto-continues in-flight major line via existing pre tags;
  publishes floating major-pre Docker tag (e.g. 2-pre)
- Rewrite docker.yml version-bump: tag-based versioning, manual bump
  inputs (auto/patch/minor/major), major guarded by confirm_major=MAJOR,
  auto-finalizes in-flight prereleases; publishes floating major tag (e.g. 2)
- Inject APP_VERSION build-arg through Dockerfile so the running container
  knows its real version instead of reading package.json
- Server reads APP_VERSION env in authService/adminService; exposes
  is_prerelease in app config and update-check response; prerelease builds
  compare against GitHub prerelease releases rather than latest stable
- Client stores isPrerelease from config; navbar shows amber version badge
  on prerelease builds (left of dark-mode toggle); GitHubPanel filters out
  prerelease releases unless the running build is itself a prerelease

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 16:24:20 +02:00
jubnl 3ad1bef134 fix: enforce target branch workflow 2026-04-12 15:35:40 +02:00