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
- 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.
- 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.
- 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.
- Port the specs and confirm skip's suite stays green; verify against a server running
sk-image (secured + read-only role behavior).
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-imagecomponent — 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-setupwidget-config panel — upload (<=10 MB, type-guarded), pick from the boat-wide library, delete-with-confirm, alt text, fit/background, live preview.options/media) — image cache size + purge.ImageAssetService+ akip-plugin-urlresolver that target the plugin's crew-reachable/signalk/v1/api/sk-imagemount (not the admin-gated/plugins/sk-imagealias) and discover variant widths from the plugin'sGET /config.sk-imageadded tosignalk.recommendsso 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 --checkof the PR's shared-file hunks against skip:widgets-interface.tsandwidget.service.tsfail;dashboard.component.tsandplugin-config-client.service.tsapply clean textually (but the latter imports the missingkip-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 anImageentry and a lazy-load map line; the insertion applies against different context (apply fails at :532).widgets-interface.ts— theIWidgetSvcConfigblock the PR extends has diverged (apply fails at :386).src/assets/svg/icons.svg— skip has noimageWidgetsymbol; 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.sk-imageSignal K plugin (Node 22.13+) on the server. That plugin is not part of skip and is a separate deployment/product decision. skip'spackage.json signalk.recommendswould also needsk-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.tssrc/app/core/interfaces/widgets-interface.tssrc/app/core/components/dashboard/dashboard.component.tssrc/app/core/services/plugin-config-client.service.tssrc/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.svgsrc/assets/help-docs/menu.jsonpackage.json(signalk.recommends)Suggested approach
sk-imageplugin (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.widget.service.ts, theimage?config block inwidgets-interface.ts, theimageWidgetsymbol inicons.svg, the Media tab, the image-source-setup wiring, and themenu.json/help entry.dashboard.component.tsauth-aware gating,plugin-config-client.service.tsstripToServerRoot) verbatim, but they depend on the newkip-plugin-url.util, so add that util first.sk-image(secured + read-only role behavior).