@signalk/app-dock 1.1.0-beta.1 → 1.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,6 +35,18 @@ Tip: double-tapping a clickable element in the underlying webapp will activate t
35
35
 
36
36
  Config changes made in **Plugin Config** apply automatically within ~5 seconds: structural changes (position, icon size, etc.) reload the dock page; changes to the app list hot-update in place.
37
37
 
38
+ ## Install as an app
39
+
40
+ The dock ships a web app manifest, so iOS and Android can install it to the home screen and launch it like a native app -- no Safari/Chrome chrome, no URL bar.
41
+
42
+ - **iPad / iPhone (Safari)**: open the dock URL, tap the Share icon, choose **Add to Home Screen**.
43
+ - **Android (Chrome)**: open the dock URL, tap the ⋮ menu, choose **Install app** (or **Add to Home Screen**).
44
+ - **Desktop (Chrome, Edge)**: an install icon appears in the address bar; click it.
45
+
46
+ HTTPS is **not required** for Add-to-Home-Screen -- the dock installs cleanly over plain `http://your-sk-server:3000/`. It works equally over HTTPS with a self-signed or local-CA cert, provided the device has been configured to trust that CA (the usual iPad profile flow: Settings > General > VPN & Device Management > trust the profile > Settings > General > About > Certificate Trust Settings > enable full trust).
47
+
48
+ If the installed dock ever displays a blank screen after a long idle period (rare; only if the server's caching layer ignores the dock's `no-cache` directives), remove the home-screen icon and re-add it from Safari.
49
+
38
50
  ## Configuration
39
51
 
40
52
  Open **Plugin Config > App Dock** in the admin UI. The embedded configurator provides:
@@ -87,6 +99,16 @@ The repo ships three cooperating surfaces:
87
99
  | `npm run lint` | ESLint check |
88
100
  | `npm run build:config` | Rebuild the admin UI config panel (required after `src/` changes) |
89
101
 
102
+ ### Icon assets
103
+
104
+ If `public/app-icon.svg` changes, regenerate the 180-px apple-touch-icon:
105
+
106
+ ```bash
107
+ rsvg-convert -w 180 -h 180 public/app-icon.svg -o public/app-icon-180.png
108
+ ```
109
+
110
+ `public/app-icon-maskable.svg` is a hand-authored wrapper that places the artwork inside Android's 80% safe zone; if the main icon's layout changes meaningfully, update it by hand to match.
111
+
90
112
  ## License
91
113
 
92
114
  Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalk/app-dock",
3
- "version": "1.1.0-beta.1",
3
+ "version": "1.1.0-beta.2",
4
4
  "description": "macOS-style configurable app dock for switching between SignalK webapps on touch screens",
5
5
  "repository": {
6
6
  "url": "https://github.com/SignalK/app-dock"
Binary file
@@ -0,0 +1,24 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
4
+ <stop offset="0%" stop-color="#60a5fa"/>
5
+ <stop offset="100%" stop-color="#2563eb"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect width="100" height="100" fill="url(#bg)"/>
9
+ <g transform="translate(14 14)">
10
+ <rect x="8" y="48" width="56" height="16" rx="8" fill="#ffffff" fill-opacity="0.25" stroke="#ffffff" stroke-opacity="0.4" stroke-width="0.5"/>
11
+ <rect x="14" y="51" width="10" height="10" rx="2.5" fill="#3b82f6" opacity="0.9"/>
12
+ <rect x="31" y="51" width="10" height="10" rx="2.5" fill="#10b981" opacity="0.9"/>
13
+ <rect x="48" y="51" width="10" height="10" rx="2.5" fill="#f59e0b" opacity="0.9"/>
14
+ <rect x="28" y="34" width="16" height="16" rx="3.5" fill="#10b981" opacity="0.95"/>
15
+ <circle cx="36" cy="66" r="1.5" fill="#ffffff" fill-opacity="0.8"/>
16
+ <circle cx="36" cy="22" r="10" fill="none" stroke="#ffffff" stroke-opacity="0.15" stroke-width="1"/>
17
+ <line x1="36" y1="14" x2="36" y2="18" stroke="#ffffff" stroke-opacity="0.3" stroke-width="1" stroke-linecap="round"/>
18
+ <line x1="36" y1="26" x2="36" y2="30" stroke="#ffffff" stroke-opacity="0.15" stroke-width="1" stroke-linecap="round"/>
19
+ <line x1="28" y1="22" x2="32" y2="22" stroke="#ffffff" stroke-opacity="0.15" stroke-width="1" stroke-linecap="round"/>
20
+ <line x1="40" y1="22" x2="44" y2="22" stroke="#ffffff" stroke-opacity="0.15" stroke-width="1" stroke-linecap="round"/>
21
+ <polygon points="36,15 34,22 36,20 38,22" fill="#ef4444" fill-opacity="0.7"/>
22
+ <polygon points="36,29 34,22 36,24 38,22" fill="#ffffff" fill-opacity="0.25"/>
23
+ </g>
24
+ </svg>
package/public/index.html CHANGED
@@ -4,6 +4,15 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, viewport-fit=cover" />
6
6
  <meta name="mobile-web-app-capable" content="yes" />
7
+ <link rel="manifest" href="manifest.webmanifest" />
8
+ <link rel="icon" type="image/svg+xml" href="app-icon.svg" />
9
+ <link rel="apple-touch-icon" href="app-icon-180.png" />
10
+ <meta name="apple-mobile-web-app-capable" content="yes" />
11
+ <meta name="apple-mobile-web-app-title" content="App Dock" />
12
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
13
+ <meta name="theme-color" content="#000000" />
14
+ <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
15
+ <meta http-equiv="Pragma" content="no-cache" />
7
16
  <title>SK Dock</title>
8
17
  <link rel="stylesheet" href="dock.css" />
9
18
  </head>
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "Signal K App Dock",
3
+ "short_name": "App Dock",
4
+ "description": "macOS-style dock to switch between Signal K webapps",
5
+ "start_url": "/@signalk/app-dock/",
6
+ "scope": "/",
7
+ "display": "standalone",
8
+ "orientation": "any",
9
+ "background_color": "#000000",
10
+ "theme_color": "#000000",
11
+ "icons": [
12
+ {
13
+ "src": "app-icon.svg",
14
+ "sizes": "any",
15
+ "type": "image/svg+xml",
16
+ "purpose": "any"
17
+ },
18
+ {
19
+ "src": "app-icon-180.png",
20
+ "sizes": "180x180",
21
+ "type": "image/png",
22
+ "purpose": "any"
23
+ },
24
+ {
25
+ "src": "app-icon-maskable.svg",
26
+ "sizes": "any",
27
+ "type": "image/svg+xml",
28
+ "purpose": "maskable"
29
+ }
30
+ ]
31
+ }
@@ -521,4 +521,22 @@ describe('public files', () => {
521
521
  it('icon-settings.svg exists', () => {
522
522
  assert.ok(fs.existsSync(path.join(publicDir, 'icon-settings.svg')))
523
523
  })
524
+
525
+ it('manifest.webmanifest exists and is valid JSON with required PWA fields', () => {
526
+ const manifestPath = path.join(publicDir, 'manifest.webmanifest')
527
+ assert.ok(fs.existsSync(manifestPath))
528
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'))
529
+ assert.equal(typeof manifest.name, 'string')
530
+ assert.equal(typeof manifest.start_url, 'string')
531
+ assert.equal(manifest.display, 'standalone')
532
+ assert.ok(Array.isArray(manifest.icons) && manifest.icons.length > 0)
533
+ })
534
+
535
+ it('app-icon-180.png exists (apple-touch-icon)', () => {
536
+ assert.ok(fs.existsSync(path.join(publicDir, 'app-icon-180.png')))
537
+ })
538
+
539
+ it('app-icon-maskable.svg exists', () => {
540
+ assert.ok(fs.existsSync(path.join(publicDir, 'app-icon-maskable.svg')))
541
+ })
524
542
  })