capacitor-ota 1.0.5 → 1.0.6
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/dist/src/index.d.mts +36 -4
- package/dist/src/index.mjs +261 -83
- package/package.json +1 -1
package/dist/src/index.d.mts
CHANGED
|
@@ -42,17 +42,49 @@ interface DownloadedBundle {
|
|
|
42
42
|
id: string;
|
|
43
43
|
version: string;
|
|
44
44
|
}
|
|
45
|
+
type OtaEventType = 'stateChange' | 'updateAvailable' | 'downloadStart' | 'downloadProgress' | 'downloadComplete' | 'updateReady' | 'updateApplied' | 'error' | 'noUpdate';
|
|
46
|
+
interface OtaEventMap {
|
|
47
|
+
stateChange: OtaState;
|
|
48
|
+
updateAvailable: {
|
|
49
|
+
currentVersion: string;
|
|
50
|
+
newVersion: string;
|
|
51
|
+
};
|
|
52
|
+
downloadStart: {
|
|
53
|
+
version: string;
|
|
54
|
+
};
|
|
55
|
+
downloadProgress: {
|
|
56
|
+
progress: number;
|
|
57
|
+
version: string;
|
|
58
|
+
};
|
|
59
|
+
downloadComplete: {
|
|
60
|
+
version: string;
|
|
61
|
+
};
|
|
62
|
+
updateReady: {
|
|
63
|
+
version: string;
|
|
64
|
+
bundleId: string;
|
|
65
|
+
};
|
|
66
|
+
updateApplied: {
|
|
67
|
+
version: string;
|
|
68
|
+
};
|
|
69
|
+
error: {
|
|
70
|
+
message: string;
|
|
71
|
+
phase: 'check' | 'download' | 'apply';
|
|
72
|
+
};
|
|
73
|
+
noUpdate: {
|
|
74
|
+
currentVersion: string;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
type OtaEventCallback<T extends OtaEventType> = (data: OtaEventMap[T]) => void;
|
|
45
78
|
//#endregion
|
|
46
79
|
//#region src/OtaUpdater.d.ts
|
|
47
|
-
type EventCallback = (data?: any) => void;
|
|
48
80
|
declare class OtaUpdater {
|
|
49
81
|
private config;
|
|
50
82
|
private listeners;
|
|
51
83
|
private downloadedBundle;
|
|
52
84
|
state: OtaState;
|
|
53
85
|
constructor(config: OtaConfig);
|
|
54
|
-
on(event:
|
|
55
|
-
off(event:
|
|
86
|
+
on<T extends OtaEventType>(event: T, callback: OtaEventCallback<T>): () => void;
|
|
87
|
+
off<T extends OtaEventType>(event: T, callback: OtaEventCallback<T>): void;
|
|
56
88
|
private emit;
|
|
57
89
|
private setState;
|
|
58
90
|
notifyAppReady(): Promise<void>;
|
|
@@ -83,4 +115,4 @@ declare class OtaUpdateElement extends HTMLElement {
|
|
|
83
115
|
//#region src/index.d.ts
|
|
84
116
|
declare function initOtaUpdate(config: OtaConfig): Promise<OtaUpdater>;
|
|
85
117
|
//#endregion
|
|
86
|
-
export { DownloadedBundle, OtaConfig, OtaState, OtaStatus, OtaTexts, OtaTheme, OtaUpdateElement, OtaUpdater, RemoteVersion, getOtaUpdater, initOtaUpdate };
|
|
118
|
+
export { DownloadedBundle, OtaConfig, OtaEventCallback, OtaEventMap, OtaEventType, OtaState, OtaStatus, OtaTexts, OtaTheme, OtaUpdateElement, OtaUpdater, RemoteVersion, getOtaUpdater, initOtaUpdate };
|
package/dist/src/index.mjs
CHANGED
|
@@ -38,6 +38,7 @@ var OtaUpdater = class {
|
|
|
38
38
|
on(event, callback) {
|
|
39
39
|
if (!this.listeners.has(event)) this.listeners.set(event, /* @__PURE__ */ new Set());
|
|
40
40
|
this.listeners.get(event).add(callback);
|
|
41
|
+
return () => this.off(event, callback);
|
|
41
42
|
}
|
|
42
43
|
off(event, callback) {
|
|
43
44
|
this.listeners.get(event)?.delete(callback);
|
|
@@ -48,8 +49,6 @@ var OtaUpdater = class {
|
|
|
48
49
|
setState(partial) {
|
|
49
50
|
Object.assign(this.state, partial);
|
|
50
51
|
this.emit("stateChange", { ...this.state });
|
|
51
|
-
if (partial.progress !== void 0) this.emit("progress", partial.progress);
|
|
52
|
-
if (partial.error) this.emit("error", partial.error);
|
|
53
52
|
}
|
|
54
53
|
async notifyAppReady() {
|
|
55
54
|
if (!isNativePlatform()) return;
|
|
@@ -77,9 +76,14 @@ var OtaUpdater = class {
|
|
|
77
76
|
const data = await response.json();
|
|
78
77
|
if (compareVersions(data.version, this.state.currentVersion) > 0) {
|
|
79
78
|
this.setState({ newVersion: data.version });
|
|
79
|
+
this.emit("updateAvailable", {
|
|
80
|
+
currentVersion: this.state.currentVersion,
|
|
81
|
+
newVersion: data.version
|
|
82
|
+
});
|
|
80
83
|
return true;
|
|
81
84
|
}
|
|
82
85
|
this.setState({ status: "idle" });
|
|
86
|
+
this.emit("noUpdate", { currentVersion: this.state.currentVersion });
|
|
83
87
|
return false;
|
|
84
88
|
} catch (e) {
|
|
85
89
|
const error = e instanceof Error ? e.message : "Update check failed";
|
|
@@ -87,33 +91,52 @@ var OtaUpdater = class {
|
|
|
87
91
|
status: "error",
|
|
88
92
|
error
|
|
89
93
|
});
|
|
94
|
+
this.emit("error", {
|
|
95
|
+
message: error,
|
|
96
|
+
phase: "check"
|
|
97
|
+
});
|
|
90
98
|
return false;
|
|
91
99
|
}
|
|
92
100
|
}
|
|
93
101
|
async download() {
|
|
94
102
|
if (!this.state.newVersion) {
|
|
103
|
+
const error = "No update info available";
|
|
95
104
|
this.setState({
|
|
96
105
|
status: "error",
|
|
97
|
-
error
|
|
106
|
+
error
|
|
107
|
+
});
|
|
108
|
+
this.emit("error", {
|
|
109
|
+
message: error,
|
|
110
|
+
phase: "download"
|
|
98
111
|
});
|
|
99
112
|
return false;
|
|
100
113
|
}
|
|
114
|
+
const version = this.state.newVersion;
|
|
101
115
|
this.setState({
|
|
102
116
|
status: "downloading",
|
|
103
117
|
progress: 0,
|
|
104
118
|
error: null
|
|
105
119
|
});
|
|
120
|
+
this.emit("downloadStart", { version });
|
|
106
121
|
if (!isNativePlatform()) {
|
|
107
122
|
for (let i = 0; i <= 100; i += 5) {
|
|
108
123
|
this.setState({ progress: i });
|
|
124
|
+
this.emit("downloadProgress", {
|
|
125
|
+
progress: i,
|
|
126
|
+
version
|
|
127
|
+
});
|
|
109
128
|
await new Promise((r) => setTimeout(r, 50));
|
|
110
129
|
}
|
|
111
130
|
this.downloadedBundle = {
|
|
112
131
|
id: "web-sim",
|
|
113
|
-
version
|
|
132
|
+
version
|
|
114
133
|
};
|
|
115
134
|
this.setState({ status: "ready" });
|
|
116
|
-
this.emit("
|
|
135
|
+
this.emit("downloadComplete", { version });
|
|
136
|
+
this.emit("updateReady", {
|
|
137
|
+
version,
|
|
138
|
+
bundleId: "web-sim"
|
|
139
|
+
});
|
|
117
140
|
return true;
|
|
118
141
|
}
|
|
119
142
|
try {
|
|
@@ -122,6 +145,10 @@ var OtaUpdater = class {
|
|
|
122
145
|
const { CapacitorUpdater } = await import("@capgo/capacitor-updater");
|
|
123
146
|
const listener = await CapacitorUpdater.addListener("download", (event) => {
|
|
124
147
|
this.setState({ progress: event.percent });
|
|
148
|
+
this.emit("downloadProgress", {
|
|
149
|
+
progress: event.percent,
|
|
150
|
+
version
|
|
151
|
+
});
|
|
125
152
|
});
|
|
126
153
|
const bundle = await CapacitorUpdater.download({
|
|
127
154
|
url: data.url,
|
|
@@ -134,7 +161,11 @@ var OtaUpdater = class {
|
|
|
134
161
|
version: bundle.version
|
|
135
162
|
};
|
|
136
163
|
this.setState({ status: "ready" });
|
|
137
|
-
this.emit("
|
|
164
|
+
this.emit("downloadComplete", { version: bundle.version });
|
|
165
|
+
this.emit("updateReady", {
|
|
166
|
+
version: bundle.version,
|
|
167
|
+
bundleId: bundle.id
|
|
168
|
+
});
|
|
138
169
|
return true;
|
|
139
170
|
} catch (e) {
|
|
140
171
|
const error = e instanceof Error ? e.message : "Download failed";
|
|
@@ -142,6 +173,10 @@ var OtaUpdater = class {
|
|
|
142
173
|
status: "error",
|
|
143
174
|
error
|
|
144
175
|
});
|
|
176
|
+
this.emit("error", {
|
|
177
|
+
message: error,
|
|
178
|
+
phase: "download"
|
|
179
|
+
});
|
|
145
180
|
return false;
|
|
146
181
|
}
|
|
147
182
|
}
|
|
@@ -149,27 +184,36 @@ var OtaUpdater = class {
|
|
|
149
184
|
this.setState({ status: "applying" });
|
|
150
185
|
if (!isNativePlatform()) {
|
|
151
186
|
await new Promise((r) => setTimeout(r, 500));
|
|
152
|
-
this.emit("updateApplied");
|
|
187
|
+
this.emit("updateApplied", { version: this.state.newVersion || "" });
|
|
153
188
|
window.location.reload();
|
|
154
189
|
return;
|
|
155
190
|
}
|
|
156
191
|
if (!this.downloadedBundle) {
|
|
192
|
+
const error = "No downloaded bundle";
|
|
157
193
|
this.setState({
|
|
158
194
|
status: "error",
|
|
159
|
-
error
|
|
195
|
+
error
|
|
196
|
+
});
|
|
197
|
+
this.emit("error", {
|
|
198
|
+
message: error,
|
|
199
|
+
phase: "apply"
|
|
160
200
|
});
|
|
161
201
|
return;
|
|
162
202
|
}
|
|
163
203
|
try {
|
|
164
204
|
const { CapacitorUpdater } = await import("@capgo/capacitor-updater");
|
|
165
205
|
await CapacitorUpdater.set({ id: this.downloadedBundle.id });
|
|
166
|
-
this.emit("updateApplied");
|
|
206
|
+
this.emit("updateApplied", { version: this.downloadedBundle.version });
|
|
167
207
|
} catch (e) {
|
|
168
208
|
const error = e instanceof Error ? e.message : "Apply failed";
|
|
169
209
|
this.setState({
|
|
170
210
|
status: "error",
|
|
171
211
|
error
|
|
172
212
|
});
|
|
213
|
+
this.emit("error", {
|
|
214
|
+
message: error,
|
|
215
|
+
phase: "apply"
|
|
216
|
+
});
|
|
173
217
|
}
|
|
174
218
|
}
|
|
175
219
|
};
|
|
@@ -187,12 +231,12 @@ function createOtaUpdater(config) {
|
|
|
187
231
|
function getStyles(theme) {
|
|
188
232
|
return `
|
|
189
233
|
:host {
|
|
190
|
-
--ota-primary: ${theme?.primaryColor || "#
|
|
191
|
-
--ota-gradient-from: ${theme?.gradientFrom || "#
|
|
192
|
-
--ota-gradient-to: ${theme?.gradientTo || "#
|
|
234
|
+
--ota-primary: ${theme?.primaryColor || "#6366f1"};
|
|
235
|
+
--ota-gradient-from: ${theme?.gradientFrom || "#4f46e5"};
|
|
236
|
+
--ota-gradient-to: ${theme?.gradientTo || "#7c3aed"};
|
|
193
237
|
--ota-text: ${theme?.textColor || "#ffffff"};
|
|
194
|
-
--ota-text-muted: rgba(255, 255, 255, 0.
|
|
195
|
-
--ota-overlay-bg: linear-gradient(
|
|
238
|
+
--ota-text-muted: rgba(255, 255, 255, 0.75);
|
|
239
|
+
--ota-overlay-bg: linear-gradient(135deg, var(--ota-gradient-from), var(--ota-gradient-to));
|
|
196
240
|
}
|
|
197
241
|
|
|
198
242
|
* {
|
|
@@ -212,17 +256,20 @@ function getStyles(theme) {
|
|
|
212
256
|
justify-content: center;
|
|
213
257
|
padding: 2rem;
|
|
214
258
|
color: var(--ota-text);
|
|
215
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
216
|
-
|
|
259
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
260
|
+
opacity: 0;
|
|
261
|
+
visibility: hidden;
|
|
262
|
+
transition: opacity 0.4s ease, visibility 0.4s ease;
|
|
217
263
|
}
|
|
218
264
|
|
|
219
|
-
.overlay.
|
|
220
|
-
|
|
265
|
+
.overlay.visible {
|
|
266
|
+
opacity: 1;
|
|
267
|
+
visibility: visible;
|
|
221
268
|
}
|
|
222
269
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
270
|
+
.overlay.hidden {
|
|
271
|
+
opacity: 0;
|
|
272
|
+
visibility: hidden;
|
|
226
273
|
}
|
|
227
274
|
|
|
228
275
|
.safe-area-top {
|
|
@@ -240,18 +287,36 @@ function getStyles(theme) {
|
|
|
240
287
|
text-align: center;
|
|
241
288
|
width: 100%;
|
|
242
289
|
max-width: 320px;
|
|
290
|
+
transform: translateY(20px);
|
|
291
|
+
opacity: 0;
|
|
292
|
+
animation: slideUp 0.5s ease 0.1s forwards;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
@keyframes slideUp {
|
|
296
|
+
to {
|
|
297
|
+
transform: translateY(0);
|
|
298
|
+
opacity: 1;
|
|
299
|
+
}
|
|
243
300
|
}
|
|
244
301
|
|
|
245
302
|
.icon {
|
|
246
|
-
width:
|
|
247
|
-
height:
|
|
248
|
-
background:
|
|
249
|
-
border-radius:
|
|
250
|
-
box-shadow:
|
|
303
|
+
width: 100px;
|
|
304
|
+
height: 100px;
|
|
305
|
+
background: rgba(255, 255, 255, 0.95);
|
|
306
|
+
border-radius: 24px;
|
|
307
|
+
box-shadow:
|
|
308
|
+
0 20px 40px -10px rgba(0, 0, 0, 0.3),
|
|
309
|
+
0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
251
310
|
display: flex;
|
|
252
311
|
align-items: center;
|
|
253
312
|
justify-content: center;
|
|
254
313
|
margin-bottom: 2rem;
|
|
314
|
+
animation: iconPulse 2s ease-in-out infinite;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
@keyframes iconPulse {
|
|
318
|
+
0%, 100% { transform: scale(1); }
|
|
319
|
+
50% { transform: scale(1.02); }
|
|
255
320
|
}
|
|
256
321
|
|
|
257
322
|
.icon svg {
|
|
@@ -261,14 +326,25 @@ function getStyles(theme) {
|
|
|
261
326
|
}
|
|
262
327
|
|
|
263
328
|
h1 {
|
|
264
|
-
font-size: 1.
|
|
329
|
+
font-size: 1.625rem;
|
|
265
330
|
font-weight: 700;
|
|
266
331
|
margin-bottom: 0.5rem;
|
|
332
|
+
letter-spacing: -0.02em;
|
|
267
333
|
}
|
|
268
334
|
|
|
269
335
|
.version {
|
|
270
336
|
color: var(--ota-text-muted);
|
|
271
|
-
|
|
337
|
+
font-size: 0.9375rem;
|
|
338
|
+
margin-bottom: 2.5rem;
|
|
339
|
+
display: flex;
|
|
340
|
+
align-items: center;
|
|
341
|
+
gap: 0.5rem;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.version-arrow {
|
|
345
|
+
width: 20px;
|
|
346
|
+
height: 20px;
|
|
347
|
+
opacity: 0.7;
|
|
272
348
|
}
|
|
273
349
|
|
|
274
350
|
.content {
|
|
@@ -278,89 +354,144 @@ function getStyles(theme) {
|
|
|
278
354
|
/* Progress Circle */
|
|
279
355
|
.progress-container {
|
|
280
356
|
position: relative;
|
|
281
|
-
width:
|
|
282
|
-
height:
|
|
283
|
-
margin: 0 auto 1.
|
|
357
|
+
width: 140px;
|
|
358
|
+
height: 140px;
|
|
359
|
+
margin: 0 auto 1.75rem;
|
|
284
360
|
}
|
|
285
361
|
|
|
286
362
|
.progress-svg {
|
|
287
363
|
width: 100%;
|
|
288
364
|
height: 100%;
|
|
289
365
|
transform: rotate(-90deg);
|
|
366
|
+
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15));
|
|
290
367
|
}
|
|
291
368
|
|
|
292
369
|
.progress-bg {
|
|
293
370
|
fill: none;
|
|
294
|
-
stroke: rgba(255, 255, 255, 0.
|
|
295
|
-
stroke-width:
|
|
371
|
+
stroke: rgba(255, 255, 255, 0.15);
|
|
372
|
+
stroke-width: 6;
|
|
296
373
|
}
|
|
297
374
|
|
|
298
375
|
.progress-bar {
|
|
299
376
|
fill: none;
|
|
300
377
|
stroke: white;
|
|
301
|
-
stroke-width:
|
|
378
|
+
stroke-width: 6;
|
|
302
379
|
stroke-linecap: round;
|
|
303
|
-
transition: stroke-dashoffset 0.
|
|
380
|
+
transition: stroke-dashoffset 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
|
304
381
|
}
|
|
305
382
|
|
|
306
383
|
.progress-text {
|
|
307
384
|
position: absolute;
|
|
308
385
|
inset: 0;
|
|
309
386
|
display: flex;
|
|
387
|
+
flex-direction: column;
|
|
310
388
|
align-items: center;
|
|
311
389
|
justify-content: center;
|
|
312
|
-
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.progress-percent {
|
|
393
|
+
font-size: 2.25rem;
|
|
313
394
|
font-weight: 700;
|
|
395
|
+
letter-spacing: -0.02em;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.progress-label {
|
|
399
|
+
font-size: 0.75rem;
|
|
400
|
+
color: var(--ota-text-muted);
|
|
401
|
+
text-transform: uppercase;
|
|
402
|
+
letter-spacing: 0.05em;
|
|
403
|
+
margin-top: 0.25rem;
|
|
314
404
|
}
|
|
315
405
|
|
|
316
406
|
.status-text {
|
|
317
407
|
color: var(--ota-text-muted);
|
|
408
|
+
font-size: 0.9375rem;
|
|
318
409
|
}
|
|
319
410
|
|
|
320
411
|
/* Ready State */
|
|
321
|
-
.
|
|
322
|
-
width:
|
|
323
|
-
height:
|
|
324
|
-
background: rgba(255, 255, 255, 0.
|
|
412
|
+
.success-icon {
|
|
413
|
+
width: 80px;
|
|
414
|
+
height: 80px;
|
|
415
|
+
background: rgba(255, 255, 255, 0.15);
|
|
325
416
|
border-radius: 50%;
|
|
326
417
|
display: flex;
|
|
327
418
|
align-items: center;
|
|
328
419
|
justify-content: center;
|
|
329
|
-
margin: 0 auto 1.
|
|
420
|
+
margin: 0 auto 1.75rem;
|
|
421
|
+
animation: successPop 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
@keyframes successPop {
|
|
425
|
+
0% { transform: scale(0); opacity: 0; }
|
|
426
|
+
100% { transform: scale(1); opacity: 1; }
|
|
330
427
|
}
|
|
331
428
|
|
|
332
|
-
.
|
|
333
|
-
width:
|
|
334
|
-
height:
|
|
429
|
+
.success-icon svg {
|
|
430
|
+
width: 40px;
|
|
431
|
+
height: 40px;
|
|
432
|
+
stroke-dasharray: 50;
|
|
433
|
+
stroke-dashoffset: 50;
|
|
434
|
+
animation: checkDraw 0.6s ease 0.2s forwards;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
@keyframes checkDraw {
|
|
438
|
+
to { stroke-dashoffset: 0; }
|
|
335
439
|
}
|
|
336
440
|
|
|
337
441
|
.apply-btn {
|
|
338
442
|
width: 100%;
|
|
339
|
-
padding: 1rem;
|
|
443
|
+
padding: 1rem 1.5rem;
|
|
340
444
|
background: white;
|
|
341
445
|
color: var(--ota-primary);
|
|
342
|
-
font-size:
|
|
446
|
+
font-size: 1.0625rem;
|
|
343
447
|
font-weight: 600;
|
|
344
448
|
border: none;
|
|
345
|
-
border-radius:
|
|
449
|
+
border-radius: 14px;
|
|
346
450
|
cursor: pointer;
|
|
347
|
-
box-shadow:
|
|
348
|
-
|
|
451
|
+
box-shadow:
|
|
452
|
+
0 10px 25px -5px rgba(0, 0, 0, 0.2),
|
|
453
|
+
0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
454
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
455
|
+
-webkit-tap-highlight-color: transparent;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.apply-btn:hover {
|
|
459
|
+
transform: translateY(-1px);
|
|
460
|
+
box-shadow:
|
|
461
|
+
0 14px 30px -5px rgba(0, 0, 0, 0.25),
|
|
462
|
+
0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
349
463
|
}
|
|
350
464
|
|
|
351
465
|
.apply-btn:active {
|
|
352
|
-
transform: scale(0.
|
|
466
|
+
transform: scale(0.97);
|
|
353
467
|
}
|
|
354
468
|
|
|
355
469
|
/* Applying State */
|
|
356
|
-
.
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
470
|
+
.applying-container {
|
|
471
|
+
display: flex;
|
|
472
|
+
flex-direction: column;
|
|
473
|
+
align-items: center;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.spinner-ring {
|
|
477
|
+
width: 48px;
|
|
478
|
+
height: 48px;
|
|
479
|
+
margin-bottom: 1.5rem;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
.spinner-ring svg {
|
|
483
|
+
width: 100%;
|
|
484
|
+
height: 100%;
|
|
485
|
+
animation: spin 1.2s linear infinite;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.spinner-ring circle {
|
|
489
|
+
fill: none;
|
|
490
|
+
stroke: white;
|
|
491
|
+
stroke-width: 3;
|
|
492
|
+
stroke-linecap: round;
|
|
493
|
+
stroke-dasharray: 90;
|
|
494
|
+
stroke-dashoffset: 60;
|
|
364
495
|
}
|
|
365
496
|
|
|
366
497
|
@keyframes spin {
|
|
@@ -369,22 +500,32 @@ function getStyles(theme) {
|
|
|
369
500
|
|
|
370
501
|
/* Error State */
|
|
371
502
|
.error-icon {
|
|
372
|
-
width:
|
|
373
|
-
height:
|
|
503
|
+
width: 80px;
|
|
504
|
+
height: 80px;
|
|
374
505
|
background: rgba(239, 68, 68, 0.2);
|
|
375
506
|
border-radius: 50%;
|
|
376
507
|
display: flex;
|
|
377
508
|
align-items: center;
|
|
378
509
|
justify-content: center;
|
|
379
|
-
margin: 0 auto 1.
|
|
510
|
+
margin: 0 auto 1.75rem;
|
|
511
|
+
animation: shake 0.5s ease;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
@keyframes shake {
|
|
515
|
+
0%, 100% { transform: translateX(0); }
|
|
516
|
+
20%, 60% { transform: translateX(-5px); }
|
|
517
|
+
40%, 80% { transform: translateX(5px); }
|
|
380
518
|
}
|
|
381
519
|
|
|
382
520
|
.error-icon svg {
|
|
383
|
-
width:
|
|
384
|
-
height:
|
|
521
|
+
width: 40px;
|
|
522
|
+
height: 40px;
|
|
523
|
+
color: #fca5a5;
|
|
385
524
|
}
|
|
386
525
|
|
|
387
526
|
.error-title {
|
|
527
|
+
font-size: 1.125rem;
|
|
528
|
+
font-weight: 600;
|
|
388
529
|
color: #fecaca;
|
|
389
530
|
margin-bottom: 0.5rem;
|
|
390
531
|
}
|
|
@@ -392,24 +533,40 @@ function getStyles(theme) {
|
|
|
392
533
|
.error-message {
|
|
393
534
|
color: var(--ota-text-muted);
|
|
394
535
|
font-size: 0.875rem;
|
|
395
|
-
margin-bottom: 1.
|
|
536
|
+
margin-bottom: 1.75rem;
|
|
537
|
+
line-height: 1.5;
|
|
396
538
|
}
|
|
397
539
|
|
|
398
540
|
.retry-btn {
|
|
399
541
|
width: 100%;
|
|
400
|
-
padding: 1rem;
|
|
401
|
-
background: rgba(255, 255, 255, 0.
|
|
542
|
+
padding: 1rem 1.5rem;
|
|
543
|
+
background: rgba(255, 255, 255, 0.15);
|
|
402
544
|
color: white;
|
|
403
|
-
font-size:
|
|
545
|
+
font-size: 1.0625rem;
|
|
404
546
|
font-weight: 600;
|
|
405
|
-
border:
|
|
406
|
-
border-radius:
|
|
547
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
548
|
+
border-radius: 14px;
|
|
407
549
|
cursor: pointer;
|
|
408
|
-
transition: transform 0.
|
|
550
|
+
transition: transform 0.2s ease, background 0.2s ease;
|
|
551
|
+
-webkit-tap-highlight-color: transparent;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.retry-btn:hover {
|
|
555
|
+
background: rgba(255, 255, 255, 0.2);
|
|
409
556
|
}
|
|
410
557
|
|
|
411
558
|
.retry-btn:active {
|
|
412
|
-
transform: scale(0.
|
|
559
|
+
transform: scale(0.97);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/* Subtle background animation */
|
|
563
|
+
.overlay::before {
|
|
564
|
+
content: '';
|
|
565
|
+
position: absolute;
|
|
566
|
+
inset: 0;
|
|
567
|
+
background: radial-gradient(circle at 30% 20%, rgba(255,255,255,0.1) 0%, transparent 50%),
|
|
568
|
+
radial-gradient(circle at 70% 80%, rgba(255,255,255,0.08) 0%, transparent 50%);
|
|
569
|
+
pointer-events: none;
|
|
413
570
|
}
|
|
414
571
|
`;
|
|
415
572
|
}
|
|
@@ -419,7 +576,7 @@ function getStyles(theme) {
|
|
|
419
576
|
const DEFAULT_TEXTS = {
|
|
420
577
|
title: "Güncelleme Mevcut",
|
|
421
578
|
downloading: "İndiriliyor...",
|
|
422
|
-
downloadComplete: "İndirme
|
|
579
|
+
downloadComplete: "İndirme tamamlandı",
|
|
423
580
|
applyButton: "Şimdi Güncelle",
|
|
424
581
|
applying: "Güncelleme uygulanıyor...",
|
|
425
582
|
errorTitle: "Güncelleme başarısız",
|
|
@@ -449,10 +606,16 @@ var OtaUpdateElement = class extends HTMLElement {
|
|
|
449
606
|
show() {
|
|
450
607
|
this.visible = true;
|
|
451
608
|
this.render();
|
|
609
|
+
requestAnimationFrame(() => {
|
|
610
|
+
this.shadow.querySelector(".overlay")?.classList.add("visible");
|
|
611
|
+
});
|
|
452
612
|
}
|
|
453
613
|
hide() {
|
|
454
|
-
this.visible
|
|
455
|
-
|
|
614
|
+
this.shadow.querySelector(".overlay")?.classList.remove("visible");
|
|
615
|
+
setTimeout(() => {
|
|
616
|
+
this.visible = false;
|
|
617
|
+
this.render();
|
|
618
|
+
}, 400);
|
|
456
619
|
}
|
|
457
620
|
connectedCallback() {
|
|
458
621
|
const ota = getOtaUpdater();
|
|
@@ -474,13 +637,13 @@ var OtaUpdateElement = class extends HTMLElement {
|
|
|
474
637
|
const circumference = 2 * Math.PI * 45;
|
|
475
638
|
this.shadow.innerHTML = `
|
|
476
639
|
<style>${getStyles(this.theme)}</style>
|
|
477
|
-
<div class="overlay ${this.visible ? "" : "
|
|
640
|
+
<div class="overlay ${this.visible ? "visible" : ""}">
|
|
478
641
|
<div class="safe-area-top"></div>
|
|
479
642
|
<div class="container">
|
|
480
643
|
<!-- App Icon -->
|
|
481
644
|
<div class="icon">
|
|
482
|
-
<svg viewBox="0 0 24 24" fill="currentColor">
|
|
483
|
-
<path
|
|
645
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
646
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
|
|
484
647
|
</svg>
|
|
485
648
|
</div>
|
|
486
649
|
|
|
@@ -488,7 +651,13 @@ var OtaUpdateElement = class extends HTMLElement {
|
|
|
488
651
|
<h1>${this.texts.title}</h1>
|
|
489
652
|
|
|
490
653
|
<!-- Version -->
|
|
491
|
-
<
|
|
654
|
+
<div class="version">
|
|
655
|
+
<span>v${state.currentVersion}</span>
|
|
656
|
+
<svg class="version-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
657
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6" />
|
|
658
|
+
</svg>
|
|
659
|
+
<span>v${state.newVersion || "..."}</span>
|
|
660
|
+
</div>
|
|
492
661
|
|
|
493
662
|
<!-- Content -->
|
|
494
663
|
<div class="content">
|
|
@@ -513,22 +682,31 @@ var OtaUpdateElement = class extends HTMLElement {
|
|
|
513
682
|
stroke-dashoffset="${this.getProgressOffset(state.progress)}"
|
|
514
683
|
/>
|
|
515
684
|
</svg>
|
|
516
|
-
<div class="progress-text"
|
|
685
|
+
<div class="progress-text">
|
|
686
|
+
<span class="progress-percent">${state.progress}</span>
|
|
687
|
+
<span class="progress-label">yükleniyor</span>
|
|
688
|
+
</div>
|
|
517
689
|
</div>
|
|
518
690
|
<p class="status-text">${this.texts.downloading}</p>
|
|
519
691
|
`;
|
|
520
692
|
case "ready": return `
|
|
521
|
-
<div class="
|
|
693
|
+
<div class="success-icon">
|
|
522
694
|
<svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24">
|
|
523
695
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
|
524
696
|
</svg>
|
|
525
697
|
</div>
|
|
526
|
-
<p class="status-text" style="margin-bottom: 1.
|
|
698
|
+
<p class="status-text" style="margin-bottom: 1.75rem;">${this.texts.downloadComplete}</p>
|
|
527
699
|
<button class="apply-btn" data-action="apply">${this.texts.applyButton}</button>
|
|
528
700
|
`;
|
|
529
701
|
case "applying": return `
|
|
530
|
-
<div class="
|
|
531
|
-
|
|
702
|
+
<div class="applying-container">
|
|
703
|
+
<div class="spinner-ring">
|
|
704
|
+
<svg viewBox="0 0 50 50">
|
|
705
|
+
<circle cx="25" cy="25" r="20" />
|
|
706
|
+
</svg>
|
|
707
|
+
</div>
|
|
708
|
+
<p class="status-text">${this.texts.applying}</p>
|
|
709
|
+
</div>
|
|
532
710
|
`;
|
|
533
711
|
case "error": return `
|
|
534
712
|
<div class="error-icon">
|