Skip to content

Port Kip #1120: Image widget (sk-image plugin) #242

Description

@mairas

Upstream

Port the Image widget from Kip PR mxtommy/Kip#1120 (OPEN, unmerged as of this writing).

What the upstream change does

Adds an Image display widget to Kip. Storage/processing lives in a separate Signal K plugin (sk-image, published, Node.js 22.13+); Kip ships only the client side:

  • widget-image component — renders a server-stored image scaled to fit/fill over a solid or transparent background, lazy-loaded, requests the smallest variant on first paint then upgrades.
  • image-source-setup widget-config panel — upload (<=10 MB, type-guarded), pick from the boat-wide library, delete-with-confirm, alt text, fit/background, live preview.
  • Settings -> Media card (options/media) — image cache size + purge.
  • ImageAssetService + a kip-plugin-url resolver that target the plugin's crew-reachable /signalk/v1/api/sk-image mount (not the admin-gated /plugins/sk-image alias) and discover variant widths from the plugin's GET /config.
  • Auth-aware plugin-gating tweak: on a secured server the plugin-state API is admin-only, so an unreadable state is treated as "can't verify" rather than "not installed", and read-only accounts get a clear 403 message.
  • sk-image added to signalk.recommends so the App Store offers to install it.

Why this needs a manual port (not a cherry-pick)

The bulk is brand-new files, but the wiring lands in files skip has diverged. git apply --check of the PR's shared-file hunks against skip: widgets-interface.ts and widget.service.ts fail; dashboard.component.ts and plugin-config-client.service.ts apply clean textually (but the latter imports the missing kip-plugin-url.util, so it will not compile until that new util is added).

  • widget.service.ts — skip's widget registry has diverged heavily (35 widgets incl. skip-only Freeboard-SK, Racesteer, Racer Start Line/Timer, Wind Trends, Countdown Timer, Video). The PR inserts an Image entry and a lazy-load map line; the insertion applies against different context (apply fails at :532).
  • widgets-interface.ts — the IWidgetSvcConfig block the PR extends has diverged (apply fails at :386).
  • src/assets/svg/icons.svg — skip has no imageWidget symbol; this large, rebranded symbol file must get the icon added by hand.
  • options/tabs, root-modal-widget-config, menu.json — need the Media tab / image-source-setup wiring / help entry threaded in manually.
  • External dependency: requires the standalone sk-image Signal K plugin (Node 22.13+) on the server. That plugin is not part of skip and is a separate deployment/product decision. skip's package.json signalk.recommends would also need sk-image.

Affected skip files

New:

  • src/app/widgets/widget-image/{widget-image.component.ts,.html,.scss,.spec.ts}
  • src/app/widget-config/image-source-setup/{image-source-setup.component.ts,.html,.scss,.spec.ts}
  • src/app/core/components/options/media/{media.component.ts,.html,.scss,.spec.ts}
  • src/app/core/services/image-asset.service.ts (+ spec)
  • src/app/core/utils/kip-plugin-url.util.ts (+ spec)
  • src/assets/help-docs/image-widget.md (+ img assets)

Modified (diverged wiring):

  • src/app/core/services/widget.service.ts
  • src/app/core/interfaces/widgets-interface.ts
  • src/app/core/components/dashboard/dashboard.component.ts
  • src/app/core/services/plugin-config-client.service.ts
  • src/app/core/components/options/tabs/tabs.component.{ts,html}
  • src/app/widget-config/root-modal-widget-config/root-modal-widget-config.component.{ts,html}
  • src/assets/svg/icons.svg
  • src/assets/help-docs/menu.json
  • package.json (signalk.recommends)

Suggested approach

  1. Decide first whether skip wants this at all — it hard-depends on the external sk-image plugin (Node.js 22.13+) being installed on the SK server, and the upstream PR is still OPEN. Wait for it to merge before porting so the API surface is stable.
  2. If adopting: copy the new component/service/util files as-is (they are self-contained), then hand-wire the diverged shared files — add the registry entry + lazy-load import in widget.service.ts, the image? config block in widgets-interface.ts, the imageWidget symbol in icons.svg, the Media tab, the image-source-setup wiring, and the menu.json/help entry.
  3. Take the two clean hunks (dashboard.component.ts auth-aware gating, plugin-config-client.service.ts stripToServerRoot) verbatim, but they depend on the new kip-plugin-url.util, so add that util first.
  4. Port the specs and confirm skip's suite stays green; verify against a server running sk-image (secured + read-only role behavior).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions