tensorgrid-ui 1.0.3 → 1.0.5
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/lib/client.js +1 -1
- package/lib/index.js +86 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -689,7 +689,7 @@ window.__ModuleLoader__.load({
|
|
|
689
689
|
"count.idle.other": "Фоновых задач: {count}",
|
|
690
690
|
"list.aria": "Фоновые задачи",
|
|
691
691
|
"status.running": "выполняется",
|
|
692
|
-
"status.stopping": "
|
|
692
|
+
"status.stopping": "остановка",
|
|
693
693
|
"status.completed": "завершена",
|
|
694
694
|
"status.killed": "отменена",
|
|
695
695
|
"status.failed": "ошибка",
|
package/lib/index.js
CHANGED
|
@@ -39,6 +39,64 @@ const FAVICON =
|
|
|
39
39
|
BRAND_PATHS.map((d) => `<path d="${d}"/>`).join('') +
|
|
40
40
|
'</svg>'
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Иконка установленного приложения: знак на тёмной плашке.
|
|
44
|
+
*
|
|
45
|
+
* Отличается от фавиконки не прихотью. Фавиконка живёт на вкладке рядом с
|
|
46
|
+
* чужими и подстраивается под схему ОС; иконка приложения стоит в панели
|
|
47
|
+
* задач и меню «Пуск», где голый знак без фона выглядит потерянным.
|
|
48
|
+
*
|
|
49
|
+
* Здесь скругление рисуется прямо в SVG — в отличие от файла .ico, который
|
|
50
|
+
* проходит через конвертер и теряет прозрачность. Браузер получает SVG как
|
|
51
|
+
* есть, портить нечему.
|
|
52
|
+
*/
|
|
53
|
+
const APP_ICON = (() => {
|
|
54
|
+
const size = 1024
|
|
55
|
+
const [vx, vy, vw, vh] = BRAND_VIEWBOX.split(' ').map(Number)
|
|
56
|
+
const padding = size * 0.16
|
|
57
|
+
const scale = (size - padding * 2) / vw
|
|
58
|
+
const shiftX = padding - vx * scale
|
|
59
|
+
const shiftY = (size - vh * scale) / 2 - vy * scale
|
|
60
|
+
return (
|
|
61
|
+
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${size} ${size}" width="${size}" height="${size}" role="img" aria-label="TENSOR GRID">` +
|
|
62
|
+
`<rect width="${size}" height="${size}" rx="${Math.round(size * 0.22)}" fill="#0B0D12"/>` +
|
|
63
|
+
`<g transform="translate(${shiftX.toFixed(2)} ${shiftY.toFixed(2)}) scale(${scale.toFixed(5)})">` +
|
|
64
|
+
BRAND_PATHS.map((d) => `<path d="${d}" fill="#FFFFFF"/>`).join('') +
|
|
65
|
+
'</g></svg>'
|
|
66
|
+
)
|
|
67
|
+
})()
|
|
68
|
+
|
|
69
|
+
const APP_ICON_PATH = '/tensorgrid-icon.svg'
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Веб-манифест. Он задаёт не только иконку, но и ИМЯ установленного
|
|
73
|
+
* приложения — то, что видно в панели задач, меню «Пуск» и заголовке окна.
|
|
74
|
+
* Поставочный называет продукт чужим именем, поэтому манифест свой.
|
|
75
|
+
*
|
|
76
|
+
* Поля id, start_url, scope и display повторяют поставочные: они определяют
|
|
77
|
+
* поведение установленного приложения, и менять их значило бы чинить не то.
|
|
78
|
+
*/
|
|
79
|
+
const MANIFEST = JSON.stringify(
|
|
80
|
+
{
|
|
81
|
+
id: '/',
|
|
82
|
+
name: 'TENSOR GRID',
|
|
83
|
+
short_name: 'TENSOR GRID',
|
|
84
|
+
start_url: '/',
|
|
85
|
+
scope: '/',
|
|
86
|
+
display: 'fullscreen',
|
|
87
|
+
background_color: '#0B0D12',
|
|
88
|
+
theme_color: '#0B0D12',
|
|
89
|
+
icons: [
|
|
90
|
+
{ src: APP_ICON_PATH, sizes: 'any', type: 'image/svg+xml', purpose: 'any' },
|
|
91
|
+
// maskable разрешает системе обрезать иконку под свою форму. Знак
|
|
92
|
+
// отступает от краёв на 16%, поэтому обрезка его не заденет.
|
|
93
|
+
{ src: APP_ICON_PATH, sizes: 'any', type: 'image/svg+xml', purpose: 'maskable' },
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
null,
|
|
97
|
+
2,
|
|
98
|
+
)
|
|
99
|
+
|
|
42
100
|
export const name = 'tensorgrid-ui'
|
|
43
101
|
|
|
44
102
|
/**
|
|
@@ -63,6 +121,34 @@ export function apply(ctx) {
|
|
|
63
121
|
}),
|
|
64
122
|
)
|
|
65
123
|
|
|
124
|
+
web.effect(() =>
|
|
125
|
+
web.webServer.register({
|
|
126
|
+
kind: 'exact',
|
|
127
|
+
path: APP_ICON_PATH,
|
|
128
|
+
handler(_req, res) {
|
|
129
|
+
res.writeHead(200, {
|
|
130
|
+
'content-type': 'image/svg+xml; charset=utf-8',
|
|
131
|
+
'cache-control': 'no-cache',
|
|
132
|
+
})
|
|
133
|
+
res.end(APP_ICON)
|
|
134
|
+
},
|
|
135
|
+
}),
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
web.effect(() =>
|
|
139
|
+
web.webServer.register({
|
|
140
|
+
kind: 'exact',
|
|
141
|
+
path: '/manifest.webmanifest',
|
|
142
|
+
handler(_req, res) {
|
|
143
|
+
res.writeHead(200, {
|
|
144
|
+
'content-type': 'application/manifest+json; charset=utf-8',
|
|
145
|
+
'cache-control': 'no-cache',
|
|
146
|
+
})
|
|
147
|
+
res.end(MANIFEST)
|
|
148
|
+
},
|
|
149
|
+
}),
|
|
150
|
+
)
|
|
151
|
+
|
|
66
152
|
// Состояние обновлений держим в памяти: проверка ходит в сеть и в git,
|
|
67
153
|
// и дёргать её на каждый рендер настроек незачем.
|
|
68
154
|
let cached = null
|
package/package.json
CHANGED