Skip to content

feat: per-profile catalog artwork editor with automatic cloud sync#408

Open
test01203 wants to merge 7 commits into
ProdigyV21:mainfrom
test01203:feat/catalog-artwork-cloud-sync
Open

feat: per-profile catalog artwork editor with automatic cloud sync#408
test01203 wants to merge 7 commits into
ProdigyV21:mainfrom
test01203:feat/catalog-artwork-cloud-sync

Conversation

@test01203

Copy link
Copy Markdown
Contributor

What this adds

The catalog edit dialog (pencil icon in Settings → Catalogs) now exposes all four artwork URL fields for every catalog row, editable per-profile and automatically synced to ARVIO Cloud.

Fields added to the edit dialog

Field What it controls
Cover image URL The card face image shown in the catalog row
Hero image URL Full-width background when the row is focused
Animated GIF URL Replaces the cover image on card focus/hover
Clear logo URL Transparent title-logo overlay on the hero

All fields are pre-populated with the current values each time you open the pencil dialog, so you can see and edit what's already set.

How to use

  1. Go to Settings → Catalogs
  2. Navigate to any row (genres like Action/Comedy, or custom catalogs)
  3. Press the pencil (edit) icon
  4. The dialog now shows Title + the four artwork URL fields
  5. Paste any direct image URL (TMDB, TMDB image CDN, or any other host)
  6. Press confirm → image updates immediately and syncs to cloud

Implementation

3 files changed, 89 insertions(+), 1 deletion(−)

CatalogRepository.kt

New updateCatalogArtwork() function that patches collectionCoverImageUrl, collectionHeroImageUrl, collectionFocusGifUrl, and collectionClearLogoUrl on the matching CatalogConfig entry and saves via the existing saveCatalogs() path. No new DataStore key needed.

SettingsViewModel.kt

New updateCatalogArtwork() wrapper that calls the repository and triggers syncLocalStateToCloud(silent = true), exactly matching the renameCatalog() pattern.

SettingsScreen.kt

  • Added four mutableStateOf("") variables for the artwork URLs
  • Widened the rename InputModal to a five-field edit dialog
  • All three places that open the dialog now pre-populate the URL state from catalog.collectionCoverImageUrl etc. before showCatalogRename = true

Why no new cloud sync code

catalogsByProfile already serialises the full CatalogConfig JSON — including all collectionCover/Hero/Gif/ClearLogo fields. An artwork change therefore piggybacks on the existing CATALOGS invalidation scope and is pushed to cloud on the next debounced flush, exactly like a rename or reorder.

🤖 Generated with Claude Code

The-cpu-max and others added 7 commits June 16, 2026 20:21
Vanilla JS + Supabase single-page app served alongside the existing
arvio.tv marketing site. No build step required — just static files.

Features:
- Google OAuth login (via Supabase GoTrue)
- Dashboard with watch stats and recent activity
- Profiles view — shows all ARVIO sub-profiles with active/kids badges
- Addons manager — lists all Stremio + Telegram addons with enabled status
- Watch History — paginated by movie/tv/all, delete individual entries
- Watchlist — view and remove items
- AI Subtitle Translation — toggle on/off, select model (Groq Llama 70B /
  Gemini Flash 2.5), configure auto-select and hearing-impaired removal;
  settings saved directly to cloud sync payload
- Settings — card layout, language, OLED mode, skip profile selection

Data layer: reads/writes the cloud sync payload stored in
profiles.addons.__arvioAccountSyncPayload (same format the TV app uses),
and queries watch_history/watchlist tables directly via Supabase REST.

Co-Authored-By: koby455 <koby455@gmail.com>
Android TV app (CloudSyncRepository.kt):
- Inject PluginDataStore into CloudSyncRepository
- buildCloudPayload: export pluginRepositories, pluginScrapers, pluginsEnabled
  into __arvioAccountSyncPayload so plugins survive device wipes / multi-device
- applyCloudPayload: restore repositories + scrapers from cloud on first launch
  (scraper JS code stays local-only for security; only metadata is synced)

Companion web app (app.js):
- Add IPTV section: shows all M3U playlists per profile with M3U/EPG URLs,
  enabled status, favourite groups and favourite channels
- Add Plugins section: shows all plugin repositories (name, URL, scraper count,
  last updated) and individual scrapers (name, version, supported types,
  content languages, enabled status) with global plugins toggle
- Add both to sidebar navigation

Co-Authored-By: koby455 <koby455@gmail.com>
- All navigation labels, section titles, badges, toasts, and helper
  text translated to English in app.js and index.html
- Auth screen subtitle and Google button label now in English
- timeAgo() helper uses English relative-time strings
- Hebrew remains fully supported as a selectable app language (setting
  stored in cloud sync payload as before)
- Add mock-preview.html: standalone demo page with generic sample data
  for screenshots / PR previews (no Supabase dependency)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cPayload

- Add escapeHtml() helper and apply it to every cloud value injected into innerHTML:
  user display name/email/avatar initial, profile names, addon name/description/logo,
  IPTV playlist name/URL/EPG/profile label/fav groups+channels, plugin repo name/URL,
  scraper name/description/version/logo/types/languages, history title/poster,
  watchlist tmdb_id, settings user ID
- Add safeUrl() helper (https/http only) and use it for all image src attributes
  that come from cloud data (addon logos, scraper logos, user avatar)
- saveSyncPayload now reads the existing wrapper first and only updates
  __arvioAccountSyncPayload and __arvioAccountSyncUpdatedAt, preserving any other
  fields the TV app may have written

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Normalizes the URL via the browser's URL parser before use and
HTML-escapes it, preventing quote/attribute injection from synced
logo or avatar URLs in innerHTML img src attributes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Expands the catalog edit dialog (pencil icon in Settings → Catalogs)
to expose all four artwork URL fields per catalog row, per profile:

- Cover image URL   → collectionCoverImageUrl  (card face)
- Hero image URL    → collectionHeroImageUrl    (background on row focus)
- Animated GIF URL  → collectionFocusGifUrl     (card animation on hover)
- Clear logo URL    → collectionClearLogoUrl    (title logo overlay)

Changes:
• CatalogRepository: add updateCatalogArtwork() that patches the four
  URL fields on a CatalogConfig entry and saves via the existing
  saveCatalogs() path — no new DataStore key needed.
• SettingsViewModel: add updateCatalogArtwork() wrapper that calls the
  repository and triggers syncLocalStateToCloud(silent=true), matching
  the existing renameCatalog() pattern.
• SettingsScreen: widen the rename InputModal into a full edit dialog
  with five fields (title + four artwork URLs), pre-populated from the
  current CatalogConfig values each time the pencil is pressed.
  All three places that open the dialog now also prime the four URL
  state variables before setting showCatalogRename = true.

Cloud sync works automatically — catalogsByProfile already serialises
the full CatalogConfig JSON (including all collectionCover/Hero/Gif/
ClearLogo fields), so a change here is pushed on the next
CATALOGS-scope invalidation, exactly like a rename or reorder.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants