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.
@@ -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: string, callback: EventCallback): void;
55
- off(event: string, callback: EventCallback): void;
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 };
@@ -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: "No update info available"
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: this.state.newVersion
132
+ version
114
133
  };
115
134
  this.setState({ status: "ready" });
116
- this.emit("updateReady");
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("updateReady");
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: "No downloaded bundle"
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 || "#10b981"};
191
- --ota-gradient-from: ${theme?.gradientFrom || "#10b981"};
192
- --ota-gradient-to: ${theme?.gradientTo || "#059669"};
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.7);
195
- --ota-overlay-bg: linear-gradient(to bottom, var(--ota-gradient-from), var(--ota-gradient-to));
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
- animation: fadeIn 0.3s ease;
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.hidden {
220
- display: none;
265
+ .overlay.visible {
266
+ opacity: 1;
267
+ visibility: visible;
221
268
  }
222
269
 
223
- @keyframes fadeIn {
224
- from { opacity: 0; }
225
- to { opacity: 1; }
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: 96px;
247
- height: 96px;
248
- background: white;
249
- border-radius: 22px;
250
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
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.5rem;
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
- margin-bottom: 2rem;
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: 128px;
282
- height: 128px;
283
- margin: 0 auto 1.5rem;
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.2);
295
- stroke-width: 8;
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: 8;
378
+ stroke-width: 6;
302
379
  stroke-linecap: round;
303
- transition: stroke-dashoffset 0.3s ease;
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
- font-size: 1.875rem;
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
- .check-icon {
322
- width: 64px;
323
- height: 64px;
324
- background: rgba(255, 255, 255, 0.2);
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.5rem;
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
- .check-icon svg {
333
- width: 32px;
334
- height: 32px;
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: 1rem;
446
+ font-size: 1.0625rem;
343
447
  font-weight: 600;
344
448
  border: none;
345
- border-radius: 1rem;
449
+ border-radius: 14px;
346
450
  cursor: pointer;
347
- box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
348
- transition: transform 0.15s ease;
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.95);
466
+ transform: scale(0.97);
353
467
  }
354
468
 
355
469
  /* Applying State */
356
- .spinner {
357
- width: 32px;
358
- height: 32px;
359
- border: 3px solid rgba(255, 255, 255, 0.3);
360
- border-top-color: white;
361
- border-radius: 50%;
362
- margin: 0 auto 1rem;
363
- animation: spin 0.8s linear infinite;
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: 64px;
373
- height: 64px;
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.5rem;
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: 32px;
384
- height: 32px;
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.5rem;
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.2);
542
+ padding: 1rem 1.5rem;
543
+ background: rgba(255, 255, 255, 0.15);
402
544
  color: white;
403
- font-size: 1rem;
545
+ font-size: 1.0625rem;
404
546
  font-weight: 600;
405
- border: none;
406
- border-radius: 1rem;
547
+ border: 1px solid rgba(255, 255, 255, 0.2);
548
+ border-radius: 14px;
407
549
  cursor: pointer;
408
- transition: transform 0.15s ease;
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.95);
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 tamamlandı!",
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 = false;
455
- this.render();
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 ? "" : "hidden"}">
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 d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/>
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
- <p class="version">v${state.currentVersion} → v${state.newVersion || "..."}</p>
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">${state.progress}%</div>
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="check-icon">
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.5rem;">${this.texts.downloadComplete}</p>
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="spinner"></div>
531
- <p class="status-text">${this.texts.applying}</p>
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">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-ota",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.mjs",
6
6
  "types": "dist/src/index.d.mts",