@capgo/capacitor-pretty-toast 8.1.0

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.
Files changed (85) hide show
  1. package/CapgoCapacitorPrettyToast.podspec +17 -0
  2. package/LICENSE +373 -0
  3. package/Package.swift +28 -0
  4. package/README.md +341 -0
  5. package/android/build.gradle +71 -0
  6. package/android/src/main/AndroidManifest.xml +6 -0
  7. package/android/src/main/java/com/toast/PrettyToastPlugin.kt +197 -0
  8. package/android/src/main/java/com/toast/ToastOverlay.kt +495 -0
  9. package/android/src/main/java/com/toast/anim/CutoutMorphAnimator.kt +235 -0
  10. package/android/src/main/java/com/toast/anim/SlideAnimator.kt +64 -0
  11. package/android/src/main/java/com/toast/anim/ToastAnimator.kt +23 -0
  12. package/android/src/main/java/com/toast/backdrop/BackdropSampler.kt +142 -0
  13. package/android/src/main/java/com/toast/backdrop/OutlineController.kt +100 -0
  14. package/android/src/main/java/com/toast/cutout/CutoutDetector.kt +88 -0
  15. package/android/src/main/java/com/toast/cutout/CutoutInfo.kt +28 -0
  16. package/android/src/main/java/com/toast/gesture/ToastGestureHandler.kt +68 -0
  17. package/android/src/main/java/com/toast/ui/IconMapper.kt +26 -0
  18. package/android/src/main/java/com/toast/ui/PassThroughFrameLayout.kt +53 -0
  19. package/android/src/main/java/com/toast/ui/ToastViewFactory.kt +224 -0
  20. package/android/src/main/java/com/toast/util/Density.kt +17 -0
  21. package/android/src/main/java/com/toast/util/StatusBarController.kt +24 -0
  22. package/android/src/main/java/com/toast/util/ToastConstants.kt +36 -0
  23. package/android/src/main/res/.gitkeep +0 -0
  24. package/android/src/main/res/drawable/ic_arrow_downward.xml +9 -0
  25. package/android/src/main/res/drawable/ic_arrow_upward.xml +9 -0
  26. package/android/src/main/res/drawable/ic_cancel.xml +9 -0
  27. package/android/src/main/res/drawable/ic_check_circle.xml +9 -0
  28. package/android/src/main/res/drawable/ic_favorite.xml +9 -0
  29. package/android/src/main/res/drawable/ic_info.xml +9 -0
  30. package/android/src/main/res/drawable/ic_mail.xml +9 -0
  31. package/android/src/main/res/drawable/ic_notifications.xml +9 -0
  32. package/android/src/main/res/drawable/ic_touch_app.xml +9 -0
  33. package/android/src/main/res/drawable/ic_warning.xml +9 -0
  34. package/android/src/main/res/drawable/ic_wifi.xml +9 -0
  35. package/android/src/main/res/values/colors.xml +3 -0
  36. package/android/src/main/res/values/strings.xml +3 -0
  37. package/android/src/main/res/values/styles.xml +3 -0
  38. package/android/src/test/java/com/toast/PrettyToastPluginTest.kt +26 -0
  39. package/dist/docs.json +459 -0
  40. package/dist/esm/controller.d.ts +30 -0
  41. package/dist/esm/controller.js +271 -0
  42. package/dist/esm/controller.js.map +1 -0
  43. package/dist/esm/definitions.d.ts +144 -0
  44. package/dist/esm/definitions.js +2 -0
  45. package/dist/esm/definitions.js.map +1 -0
  46. package/dist/esm/driver.d.ts +19 -0
  47. package/dist/esm/driver.js +24 -0
  48. package/dist/esm/driver.js.map +1 -0
  49. package/dist/esm/icons.d.ts +14 -0
  50. package/dist/esm/icons.js +138 -0
  51. package/dist/esm/icons.js.map +1 -0
  52. package/dist/esm/index.d.ts +2 -0
  53. package/dist/esm/index.js +2 -0
  54. package/dist/esm/index.js.map +1 -0
  55. package/dist/esm/internal-plugin.d.ts +2 -0
  56. package/dist/esm/internal-plugin.js +5 -0
  57. package/dist/esm/internal-plugin.js.map +1 -0
  58. package/dist/esm/internal-types.d.ts +31 -0
  59. package/dist/esm/internal-types.js +2 -0
  60. package/dist/esm/internal-types.js.map +1 -0
  61. package/dist/esm/toast.d.ts +1 -0
  62. package/dist/esm/toast.js +5 -0
  63. package/dist/esm/toast.js.map +1 -0
  64. package/dist/esm/web-renderer.d.ts +36 -0
  65. package/dist/esm/web-renderer.js +296 -0
  66. package/dist/esm/web-renderer.js.map +1 -0
  67. package/dist/esm/web.d.ts +10 -0
  68. package/dist/esm/web.js +28 -0
  69. package/dist/esm/web.js.map +1 -0
  70. package/dist/plugin.cjs.js +770 -0
  71. package/dist/plugin.cjs.js.map +1 -0
  72. package/dist/plugin.js +773 -0
  73. package/dist/plugin.js.map +1 -0
  74. package/ios/Sources/PrettyToastPlugin/CustomHostingView.swift +13 -0
  75. package/ios/Sources/PrettyToastPlugin/PassThroughWindow.swift +143 -0
  76. package/ios/Sources/PrettyToastPlugin/PrettyToastColorParser.swift +94 -0
  77. package/ios/Sources/PrettyToastPlugin/PrettyToastPlugin.swift +138 -0
  78. package/ios/Sources/PrettyToastPlugin/PrettyToastView.swift +267 -0
  79. package/ios/Sources/PrettyToastPlugin/Toast.swift +29 -0
  80. package/ios/Sources/PrettyToastPlugin/ToastManager.swift +392 -0
  81. package/ios/Tests/PrettyToastPluginTests/PrettyToastPluginTests.swift +21 -0
  82. package/package.json +98 -0
  83. package/scripts/check-capacitor-plugin-wiring.mjs +254 -0
  84. package/scripts/deploy-example-capgo.mjs +86 -0
  85. package/scripts/test-ios.sh +14 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,773 @@
1
+ var capacitorPrettyToast = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const ICON_MAP = [
5
+ ['checkmark', { glyph: '✓', color: '#30D158' }],
6
+ ['xmark', { glyph: '✕', color: '#FF453A' }],
7
+ ['info', { glyph: 'ℹ', color: '#0A84FF' }],
8
+ ['exclamation', { glyph: '!', color: '#FF9F0A' }],
9
+ ['heart', { glyph: '♥', color: '#FF375F' }],
10
+ ['arrow.up', { glyph: '↑', color: '#0A84FF' }],
11
+ ['arrow.down', { glyph: '↓', color: '#0A84FF' }],
12
+ ['arrow', { glyph: '↑', color: '#0A84FF' }],
13
+ ['envelope', { glyph: '✉', color: '#FFFFFF' }],
14
+ ['mail', { glyph: '✉', color: '#FFFFFF' }],
15
+ ['wifi', { glyph: '◉', color: '#FFFFFF' }],
16
+ ];
17
+ const DEFAULT_ICON_SYMBOL = 'bell.badge.fill';
18
+ const svgRasterCache = new Map();
19
+ function isSvgIcon(value) {
20
+ return typeof value === 'string' && value.trimStart().startsWith('<svg');
21
+ }
22
+ function normalizeIconSource(source) {
23
+ if (!source)
24
+ return undefined;
25
+ if (typeof source === 'string') {
26
+ return source.trim() || undefined;
27
+ }
28
+ if (typeof source.uri === 'string') {
29
+ return source.uri.trim() || undefined;
30
+ }
31
+ return undefined;
32
+ }
33
+ function getSymbolIcon(symbol) {
34
+ const normalized = symbol !== null && symbol !== void 0 ? symbol : '';
35
+ for (const [key, info] of ICON_MAP) {
36
+ if (normalized.includes(key))
37
+ return info;
38
+ }
39
+ return { glyph: null, color: '#FFFFFF' };
40
+ }
41
+ function getAccessibilityAnnouncement(config) {
42
+ if (config.accessibilityAnnouncement !== undefined) {
43
+ return config.accessibilityAnnouncement;
44
+ }
45
+ return [config.title, config.message].filter(Boolean).join('. ');
46
+ }
47
+ function isNativeSafeIconUri(uri) {
48
+ if (!uri)
49
+ return false;
50
+ return (uri.startsWith('https://') ||
51
+ uri.startsWith('http://') ||
52
+ uri.startsWith('file://') ||
53
+ uri.startsWith('data:') ||
54
+ uri.startsWith('/'));
55
+ }
56
+ async function rasterizeSvgToPngDataUrl(svg) {
57
+ let pending = svgRasterCache.get(svg);
58
+ if (!pending) {
59
+ pending = rasterizeSvgToPngDataUrlInternal(svg);
60
+ svgRasterCache.set(svg, pending);
61
+ }
62
+ return pending;
63
+ }
64
+ async function blobUrlToDataUrl(uri) {
65
+ if (typeof window === 'undefined' || typeof fetch === 'undefined' || typeof FileReader === 'undefined') {
66
+ return null;
67
+ }
68
+ try {
69
+ const response = await fetch(uri);
70
+ const blob = await response.blob();
71
+ return await new Promise((resolve) => {
72
+ const reader = new FileReader();
73
+ reader.onload = () => {
74
+ resolve(typeof reader.result === 'string' ? reader.result : null);
75
+ };
76
+ reader.onerror = () => resolve(null);
77
+ reader.readAsDataURL(blob);
78
+ });
79
+ }
80
+ catch (_a) {
81
+ return null;
82
+ }
83
+ }
84
+ function rasterizeSvgToPngDataUrlInternal(svg) {
85
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
86
+ return Promise.resolve(null);
87
+ }
88
+ const encodedSvg = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
89
+ return new Promise((resolve) => {
90
+ const image = new Image();
91
+ image.onload = () => {
92
+ try {
93
+ const sourceWidth = image.naturalWidth || 96;
94
+ const sourceHeight = image.naturalHeight || 96;
95
+ const maxSide = Math.max(sourceWidth, sourceHeight, 1);
96
+ const scale = 128 / maxSide;
97
+ const width = Math.max(1, Math.round(sourceWidth * scale));
98
+ const height = Math.max(1, Math.round(sourceHeight * scale));
99
+ const canvas = document.createElement('canvas');
100
+ canvas.width = width;
101
+ canvas.height = height;
102
+ const context = canvas.getContext('2d');
103
+ if (!context) {
104
+ resolve(null);
105
+ return;
106
+ }
107
+ context.clearRect(0, 0, width, height);
108
+ context.drawImage(image, 0, 0, width, height);
109
+ resolve(canvas.toDataURL('image/png'));
110
+ }
111
+ catch (_a) {
112
+ resolve(null);
113
+ }
114
+ };
115
+ image.onerror = () => resolve(null);
116
+ image.src = encodedSvg;
117
+ });
118
+ }
119
+ function parseSvgElement(svgMarkup) {
120
+ if (typeof DOMParser === 'undefined')
121
+ return null;
122
+ try {
123
+ const documentNode = new DOMParser().parseFromString(svgMarkup, 'image/svg+xml');
124
+ if (documentNode.querySelector('parsererror') || documentNode.querySelector('script')) {
125
+ return null;
126
+ }
127
+ const root = documentNode.documentElement;
128
+ if (!root || root.tagName.toLowerCase() !== 'svg')
129
+ return null;
130
+ const svg = root.cloneNode(true);
131
+ svg.setAttribute('width', '40');
132
+ svg.setAttribute('height', '40');
133
+ svg.setAttribute('aria-hidden', 'true');
134
+ svg.style.display = 'block';
135
+ return svg;
136
+ }
137
+ catch (_a) {
138
+ return null;
139
+ }
140
+ }
141
+
142
+ const VARIANT_ICONS = {
143
+ success: 'checkmark.circle.fill',
144
+ error: 'xmark.circle.fill',
145
+ info: 'info.circle.fill',
146
+ warning: 'exclamationmark.triangle.fill',
147
+ loading: 'arrow.triangle.2.circlepath',
148
+ };
149
+ class ToastController {
150
+ constructor(driver) {
151
+ this.driver = driver;
152
+ this.queue = [];
153
+ this.current = null;
154
+ this.isShowing = false;
155
+ this.idCounter = 0;
156
+ this.autoDismissTimer = null;
157
+ this.autoDismissed = false;
158
+ this.driver.subscribe({
159
+ onDismiss: (event) => this.handleDismiss(event.id),
160
+ onPress: (event) => this.handlePress(event.id),
161
+ onActionPress: (event) => this.handleActionPress(event.id),
162
+ });
163
+ this.ref = {
164
+ show: (config, options) => this.show(config, options),
165
+ success: (title, config, options) => this.showVariant('success', title, config, options),
166
+ error: (title, config, options) => this.showVariant('error', title, config, options),
167
+ info: (title, config, options) => this.showVariant('info', title, config, options),
168
+ warning: (title, config, options) => this.showVariant('warning', title, config, options),
169
+ loading: (title, config, options) => this.showVariant('loading', title, config, options),
170
+ update: (id, partial) => this.update(id, partial),
171
+ promise: (promise, messages) => this.promise(promise, messages),
172
+ dismiss: (id) => this.dismiss(id),
173
+ dismissAll: () => this.dismissAll(),
174
+ };
175
+ }
176
+ show(config, options) {
177
+ var _a, _b;
178
+ const id = (_a = config.id) !== null && _a !== void 0 ? _a : this.generateId();
179
+ const entry = this.hydrateEntry(Object.assign(Object.assign({}, config), { id }));
180
+ if ((options === null || options === void 0 ? void 0 : options.force) && this.isShowing) {
181
+ this.queue.unshift(entry);
182
+ this.clearAutoDismissTimer();
183
+ this.autoDismissed = false;
184
+ void this.driver.dismiss((_b = this.current) === null || _b === void 0 ? void 0 : _b.id);
185
+ return id;
186
+ }
187
+ if (!this.isShowing) {
188
+ this.presentToast(entry);
189
+ return id;
190
+ }
191
+ this.queue.push(entry);
192
+ this.prepareSvgIcon(entry);
193
+ return id;
194
+ }
195
+ update(id, partial) {
196
+ var _a;
197
+ if (((_a = this.current) === null || _a === void 0 ? void 0 : _a.id) === id) {
198
+ this.current = this.hydrateEntry(Object.assign(Object.assign(Object.assign({}, this.current), partial), { id }), this.current);
199
+ this.armAutoDismissTimer(this.current);
200
+ void this.driver.update(this.buildPayload(this.current));
201
+ this.prepareSvgIcon(this.current);
202
+ return;
203
+ }
204
+ const index = this.queue.findIndex((entry) => entry.id === id);
205
+ if (index === -1)
206
+ return;
207
+ const existing = this.queue[index];
208
+ const updated = this.hydrateEntry(Object.assign(Object.assign(Object.assign({}, existing), partial), { id }), existing);
209
+ this.queue[index] = updated;
210
+ this.prepareSvgIcon(updated);
211
+ }
212
+ dismiss(id) {
213
+ var _a;
214
+ if (id && ((_a = this.current) === null || _a === void 0 ? void 0 : _a.id) !== id) {
215
+ this.queue = this.queue.filter((entry) => entry.id !== id);
216
+ return;
217
+ }
218
+ if (!this.current)
219
+ return;
220
+ this.clearAutoDismissTimer();
221
+ this.autoDismissed = false;
222
+ void this.driver.dismiss(this.current.id);
223
+ }
224
+ dismissAll() {
225
+ this.queue = [];
226
+ if (!this.current)
227
+ return;
228
+ this.clearAutoDismissTimer();
229
+ this.autoDismissed = false;
230
+ void this.driver.dismiss(this.current.id);
231
+ }
232
+ promise(promise, messages) {
233
+ const loadingConfig = typeof messages.loading === 'string'
234
+ ? { title: messages.loading }
235
+ : Object.assign({}, messages.loading);
236
+ if (loadingConfig.autoDismiss === undefined) {
237
+ loadingConfig.autoDismiss = false;
238
+ }
239
+ if (!loadingConfig.icon) {
240
+ loadingConfig.icon = VARIANT_ICONS.loading;
241
+ }
242
+ const id = this.show(loadingConfig);
243
+ promise.then((value) => {
244
+ const next = typeof messages.success === 'function' ? messages.success(value) : messages.success;
245
+ const config = typeof next === 'string' ? { title: next } : Object.assign({}, next);
246
+ if (!config.icon)
247
+ config.icon = VARIANT_ICONS.success;
248
+ if (config.autoDismiss === undefined)
249
+ config.autoDismiss = true;
250
+ if (config.duration === undefined)
251
+ config.duration = 3000;
252
+ this.update(id, config);
253
+ }, (error) => {
254
+ const next = typeof messages.error === 'function' ? messages.error(error) : messages.error;
255
+ const config = typeof next === 'string' ? { title: next } : Object.assign({}, next);
256
+ if (!config.icon)
257
+ config.icon = VARIANT_ICONS.error;
258
+ if (config.autoDismiss === undefined)
259
+ config.autoDismiss = true;
260
+ if (config.duration === undefined)
261
+ config.duration = 3000;
262
+ this.update(id, config);
263
+ });
264
+ return promise;
265
+ }
266
+ showVariant(variant, title, config, options) {
267
+ var _a;
268
+ const toastConfig = Object.assign(Object.assign({}, config), { title, icon: (_a = config === null || config === void 0 ? void 0 : config.icon) !== null && _a !== void 0 ? _a : VARIANT_ICONS[variant], _fallbackIcon: VARIANT_ICONS[variant] });
269
+ if (variant === 'loading' && toastConfig.autoDismiss === undefined) {
270
+ toastConfig.autoDismiss = false;
271
+ }
272
+ return this.show(toastConfig, options);
273
+ }
274
+ presentToast(entry) {
275
+ var _a;
276
+ this.isShowing = true;
277
+ this.current = entry;
278
+ this.armAutoDismissTimer(entry);
279
+ (_a = entry.onShow) === null || _a === void 0 ? void 0 : _a.call(entry);
280
+ void this.driver.show(this.buildPayload(entry));
281
+ this.prepareSvgIcon(entry);
282
+ }
283
+ showNext() {
284
+ const next = this.queue.shift();
285
+ if (!next) {
286
+ this.isShowing = false;
287
+ this.current = null;
288
+ return;
289
+ }
290
+ this.presentToast(next);
291
+ }
292
+ handleDismiss(id) {
293
+ var _a, _b;
294
+ if (!this.current || this.current.id !== id)
295
+ return;
296
+ const entry = this.current;
297
+ this.clearAutoDismissTimer();
298
+ if (this.autoDismissed) {
299
+ (_a = entry.onAutoDismiss) === null || _a === void 0 ? void 0 : _a.call(entry);
300
+ }
301
+ (_b = entry.onHide) === null || _b === void 0 ? void 0 : _b.call(entry);
302
+ this.autoDismissed = false;
303
+ this.showNext();
304
+ }
305
+ handlePress(id) {
306
+ if (!this.current || this.current.id !== id || !this.current.onPress)
307
+ return;
308
+ this.current.onPress();
309
+ this.clearAutoDismissTimer();
310
+ this.autoDismissed = false;
311
+ void this.driver.dismiss(id);
312
+ }
313
+ handleActionPress(id) {
314
+ if (!this.current || this.current.id !== id || !this.current.action)
315
+ return;
316
+ this.current.action.onPress();
317
+ this.clearAutoDismissTimer();
318
+ this.autoDismissed = false;
319
+ void this.driver.dismiss(id);
320
+ }
321
+ armAutoDismissTimer(entry) {
322
+ var _a, _b;
323
+ this.clearAutoDismissTimer();
324
+ this.autoDismissed = false;
325
+ const autoDismiss = (_a = entry.autoDismiss) !== null && _a !== void 0 ? _a : true;
326
+ const duration = (_b = entry.duration) !== null && _b !== void 0 ? _b : 3000;
327
+ if (!autoDismiss || duration <= 0)
328
+ return;
329
+ this.autoDismissTimer = setTimeout(() => {
330
+ this.autoDismissTimer = null;
331
+ this.autoDismissed = true;
332
+ }, duration);
333
+ }
334
+ clearAutoDismissTimer() {
335
+ if (!this.autoDismissTimer)
336
+ return;
337
+ clearTimeout(this.autoDismissTimer);
338
+ this.autoDismissTimer = null;
339
+ }
340
+ hydrateEntry(config, previous) {
341
+ var _a, _b, _c;
342
+ const iconSourceUri = normalizeIconSource(config.iconSource);
343
+ const rawIcon = typeof config.icon === 'string' ? config.icon : '';
344
+ const rawSvg = !iconSourceUri && isSvgIcon(rawIcon) ? rawIcon.trim() : undefined;
345
+ const fallbackIcon = (_b = (_a = config._fallbackIcon) !== null && _a !== void 0 ? _a : previous === null || previous === void 0 ? void 0 : previous._fallbackIcon) !== null && _b !== void 0 ? _b : DEFAULT_ICON_SYMBOL;
346
+ const iconSymbol = rawSvg ? fallbackIcon : rawIcon || fallbackIcon;
347
+ const resolvedIconUri = iconSourceUri && isNativeSafeIconUri(iconSourceUri)
348
+ ? iconSourceUri
349
+ : rawSvg && (previous === null || previous === void 0 ? void 0 : previous.rawSvg) === rawSvg
350
+ ? previous.resolvedIconUri
351
+ : iconSourceUri && (previous === null || previous === void 0 ? void 0 : previous.iconSourceUri) === iconSourceUri
352
+ ? previous.resolvedIconUri
353
+ : undefined;
354
+ return Object.assign(Object.assign({}, config), { id: config.id, iconSymbol,
355
+ iconSourceUri,
356
+ rawSvg,
357
+ resolvedIconUri, isPreparingSvg: rawSvg ? ((_c = previous === null || previous === void 0 ? void 0 : previous.isPreparingSvg) !== null && _c !== void 0 ? _c : false) : false });
358
+ }
359
+ buildPayload(entry) {
360
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
361
+ const iconUri = (_b = (_a = entry.iconSourceUri) !== null && _a !== void 0 ? _a : entry.resolvedIconUri) !== null && _b !== void 0 ? _b : '';
362
+ return {
363
+ id: entry.id,
364
+ icon: entry.iconSymbol,
365
+ iconUri,
366
+ webIconUri: (_c = entry.iconSourceUri) !== null && _c !== void 0 ? _c : iconUri,
367
+ iconSvg: entry.iconSourceUri ? '' : ((_d = entry.rawSvg) !== null && _d !== void 0 ? _d : ''),
368
+ title: (_e = entry.title) !== null && _e !== void 0 ? _e : '',
369
+ message: (_f = entry.message) !== null && _f !== void 0 ? _f : '',
370
+ duration: (_g = entry.duration) !== null && _g !== void 0 ? _g : 3000,
371
+ autoDismiss: (_h = entry.autoDismiss) !== null && _h !== void 0 ? _h : true,
372
+ enableSwipeDismiss: (_j = entry.enableSwipeDismiss) !== null && _j !== void 0 ? _j : true,
373
+ useDynamicIsland: true,
374
+ accentColor: entry.accentColor,
375
+ strokeColor: entry.strokeColor,
376
+ disableBackdropSampling: (_k = entry.disableBackdropSampling) !== null && _k !== void 0 ? _k : false,
377
+ actionLabel: (_m = (_l = entry.action) === null || _l === void 0 ? void 0 : _l.label) !== null && _m !== void 0 ? _m : '',
378
+ accessibilityAnnouncement: getAccessibilityAnnouncement(entry),
379
+ };
380
+ }
381
+ prepareSvgIcon(entry) {
382
+ var _a, _b;
383
+ if (entry.isPreparingSvg || entry.resolvedIconUri) {
384
+ return;
385
+ }
386
+ const needsSvgRaster = Boolean(entry.rawSvg);
387
+ const needsBlobConversion = Boolean((_a = entry.iconSourceUri) === null || _a === void 0 ? void 0 : _a.startsWith('blob:'));
388
+ if (!needsSvgRaster && !needsBlobConversion) {
389
+ return;
390
+ }
391
+ entry.isPreparingSvg = true;
392
+ const resolveAsset = needsSvgRaster && entry.rawSvg
393
+ ? rasterizeSvgToPngDataUrl(entry.rawSvg)
394
+ : blobUrlToDataUrl((_b = entry.iconSourceUri) !== null && _b !== void 0 ? _b : '');
395
+ void resolveAsset.then((dataUrl) => {
396
+ var _a;
397
+ entry.isPreparingSvg = false;
398
+ if (!dataUrl)
399
+ return;
400
+ entry.resolvedIconUri = dataUrl;
401
+ if (((_a = this.current) === null || _a === void 0 ? void 0 : _a.id) === entry.id) {
402
+ void this.driver.update(this.buildPayload(entry));
403
+ }
404
+ });
405
+ }
406
+ generateId() {
407
+ this.idCounter += 1;
408
+ return `toast-${this.idCounter}-${Date.now()}`;
409
+ }
410
+ }
411
+
412
+ const PrettyToastBridge = core.registerPlugin('PrettyToast', {
413
+ web: () => Promise.resolve().then(function () { return web; }).then((module) => new module.PrettyToastWeb()),
414
+ });
415
+
416
+ class CapacitorToastDriver {
417
+ constructor() {
418
+ this.subscribed = false;
419
+ }
420
+ subscribe(events) {
421
+ if (this.subscribed)
422
+ return;
423
+ this.subscribed = true;
424
+ void PrettyToastBridge.addListener('toastDismiss', events.onDismiss);
425
+ void PrettyToastBridge.addListener('toastPress', events.onPress);
426
+ void PrettyToastBridge.addListener('toastActionPress', events.onActionPress);
427
+ }
428
+ show(payload) {
429
+ return PrettyToastBridge.showCurrentToast(payload);
430
+ }
431
+ update(payload) {
432
+ return PrettyToastBridge.updateCurrentToast(payload);
433
+ }
434
+ dismiss(id) {
435
+ return PrettyToastBridge.dismissCurrentToast(id ? { id } : {});
436
+ }
437
+ }
438
+
439
+ const controller = new ToastController(new CapacitorToastDriver());
440
+ const toast = controller.ref;
441
+
442
+ const ENTER_MS = 450;
443
+ const EXIT_MS = 350;
444
+ const ENTER_EASING = 'cubic-bezier(0.22, 1.2, 0.36, 1)';
445
+ const EXIT_EASING = 'cubic-bezier(0.4, 0, 0.2, 1)';
446
+ const SWIPE_THRESHOLD = -40;
447
+ class WebToastRenderer {
448
+ constructor(events) {
449
+ this.events = events;
450
+ this.current = null;
451
+ this.root = null;
452
+ this.iconSlot = null;
453
+ this.titleNode = null;
454
+ this.messageNode = null;
455
+ this.actionButton = null;
456
+ this.autoDismissTimer = null;
457
+ this.exitTimer = null;
458
+ this.prefersDark = false;
459
+ this.dragStartY = null;
460
+ this.dragY = 0;
461
+ this.isDragging = false;
462
+ if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {
463
+ this.prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
464
+ }
465
+ }
466
+ show(payload) {
467
+ this.current = payload;
468
+ this.clearExitTimer();
469
+ this.clearAutoDismissTimer();
470
+ this.dragStartY = null;
471
+ this.dragY = 0;
472
+ this.isDragging = false;
473
+ this.ensureElements();
474
+ this.render(payload);
475
+ this.applyEnteringState();
476
+ requestAnimationFrame(() => {
477
+ var _a;
478
+ if (!this.root || ((_a = this.current) === null || _a === void 0 ? void 0 : _a.id) !== payload.id)
479
+ return;
480
+ this.root.style.transform = 'translate(-50%, 0) scale(1)';
481
+ this.root.style.opacity = '1';
482
+ });
483
+ this.armAutoDismiss(payload);
484
+ }
485
+ update(payload) {
486
+ if (!this.root || !this.current || this.current.id !== payload.id)
487
+ return;
488
+ this.current = payload;
489
+ this.render(payload);
490
+ this.armAutoDismiss(payload);
491
+ }
492
+ dismiss(id) {
493
+ if (!this.current || (id && this.current.id !== id) || !this.root)
494
+ return;
495
+ this.clearAutoDismissTimer();
496
+ this.startExit();
497
+ }
498
+ ensureElements() {
499
+ if (typeof document === 'undefined')
500
+ return;
501
+ if (this.root) {
502
+ if (!this.root.isConnected) {
503
+ document.body.appendChild(this.root);
504
+ }
505
+ return;
506
+ }
507
+ const root = document.createElement('div');
508
+ root.setAttribute('role', 'status');
509
+ root.setAttribute('aria-live', 'polite');
510
+ root.style.position = 'fixed';
511
+ root.style.top = 'calc(var(--safe-area-inset-top, env(safe-area-inset-top, 0px)) + 10px)';
512
+ root.style.left = '50%';
513
+ root.style.zIndex = '2147483647';
514
+ root.style.width = 'min(360px, calc(100vw - 20px))';
515
+ root.style.boxSizing = 'border-box';
516
+ root.style.background = '#000';
517
+ root.style.borderRadius = '30px';
518
+ root.style.padding = '14px 20px';
519
+ root.style.display = 'flex';
520
+ root.style.alignItems = 'center';
521
+ root.style.gap = '10px';
522
+ root.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
523
+ root.style.userSelect = 'none';
524
+ root.style.touchAction = 'none';
525
+ root.style.boxShadow = '0 10px 30px rgba(0, 0, 0, 0.35)';
526
+ root.style.transform = 'translate(-50%, -40px) scale(0.8)';
527
+ root.style.opacity = '0';
528
+ root.style.transition = `transform ${ENTER_MS}ms ${ENTER_EASING}, opacity ${ENTER_MS}ms ${ENTER_EASING}`;
529
+ root.addEventListener('pointerdown', (event) => this.handlePointerDown(event));
530
+ root.addEventListener('pointermove', (event) => this.handlePointerMove(event));
531
+ root.addEventListener('pointerup', (event) => this.handlePointerUp(event));
532
+ root.addEventListener('pointercancel', (event) => this.handlePointerUp(event));
533
+ root.addEventListener('click', () => {
534
+ if (!this.current || this.dragY < -4)
535
+ return;
536
+ this.events.onPress(this.current.id);
537
+ });
538
+ const iconSlot = document.createElement('div');
539
+ iconSlot.style.width = '50px';
540
+ iconSlot.style.flexShrink = '0';
541
+ iconSlot.style.display = 'flex';
542
+ iconSlot.style.alignItems = 'center';
543
+ iconSlot.style.justifyContent = 'center';
544
+ iconSlot.style.fontSize = '35px';
545
+ iconSlot.style.lineHeight = '1';
546
+ const textWrap = document.createElement('div');
547
+ textWrap.style.flex = '1';
548
+ textWrap.style.minWidth = '0';
549
+ const titleNode = document.createElement('div');
550
+ titleNode.style.color = '#fff';
551
+ titleNode.style.fontWeight = '600';
552
+ titleNode.style.fontSize = '15px';
553
+ titleNode.style.lineHeight = '20px';
554
+ titleNode.style.wordBreak = 'break-word';
555
+ const messageNode = document.createElement('div');
556
+ messageNode.style.color = 'rgba(255, 255, 255, 0.6)';
557
+ messageNode.style.fontSize = '12px';
558
+ messageNode.style.lineHeight = '16px';
559
+ messageNode.style.wordBreak = 'break-word';
560
+ textWrap.appendChild(titleNode);
561
+ textWrap.appendChild(messageNode);
562
+ const actionButton = document.createElement('button');
563
+ actionButton.type = 'button';
564
+ actionButton.style.flexShrink = '0';
565
+ actionButton.style.marginLeft = '4px';
566
+ actionButton.style.padding = '6px 12px';
567
+ actionButton.style.background = 'rgba(255,255,255,0.12)';
568
+ actionButton.style.border = 'none';
569
+ actionButton.style.borderRadius = '999px';
570
+ actionButton.style.fontSize = '13px';
571
+ actionButton.style.fontWeight = '600';
572
+ actionButton.style.cursor = 'pointer';
573
+ actionButton.style.display = 'none';
574
+ actionButton.addEventListener('click', (event) => {
575
+ event.stopPropagation();
576
+ if (!this.current)
577
+ return;
578
+ this.events.onActionPress(this.current.id);
579
+ });
580
+ actionButton.addEventListener('pointerdown', (event) => event.stopPropagation());
581
+ root.appendChild(iconSlot);
582
+ root.appendChild(textWrap);
583
+ root.appendChild(actionButton);
584
+ document.body.appendChild(root);
585
+ this.root = root;
586
+ this.iconSlot = iconSlot;
587
+ this.titleNode = titleNode;
588
+ this.messageNode = messageNode;
589
+ this.actionButton = actionButton;
590
+ }
591
+ render(payload) {
592
+ var _a, _b, _c;
593
+ if (!this.root || !this.iconSlot || !this.titleNode || !this.messageNode || !this.actionButton) {
594
+ return;
595
+ }
596
+ const symbolInfo = getSymbolIcon(payload.icon);
597
+ const accentColor = (_a = payload.accentColor) !== null && _a !== void 0 ? _a : symbolInfo.color;
598
+ const outline = payload.strokeColor
599
+ ? payload.strokeColor
600
+ : payload.disableBackdropSampling
601
+ ? 'rgba(255,255,255,0.06)'
602
+ : this.prefersDark
603
+ ? `color-mix(in srgb, ${accentColor} 20%, transparent)`
604
+ : '';
605
+ this.root.style.border = outline ? `2px solid ${outline}` : 'none';
606
+ this.root.style.cursor = payload.actionLabel || payload.icon ? 'pointer' : 'default';
607
+ this.root.setAttribute('aria-label', payload.accessibilityAnnouncement || '');
608
+ this.iconSlot.style.color = accentColor;
609
+ this.iconSlot.replaceChildren();
610
+ const renderableUri = payload.webIconUri || payload.iconUri;
611
+ if (renderableUri) {
612
+ const image = document.createElement('img');
613
+ image.src = renderableUri;
614
+ image.alt = '';
615
+ image.style.width = '40px';
616
+ image.style.height = '40px';
617
+ image.style.objectFit = 'contain';
618
+ this.iconSlot.appendChild(image);
619
+ }
620
+ else if (payload.iconSvg) {
621
+ const svg = parseSvgElement(payload.iconSvg);
622
+ if (svg) {
623
+ this.iconSlot.appendChild(svg);
624
+ }
625
+ else {
626
+ this.iconSlot.textContent = (_b = getSymbolIcon(payload.icon || DEFAULT_ICON_SYMBOL).glyph) !== null && _b !== void 0 ? _b : '';
627
+ }
628
+ }
629
+ else {
630
+ const glyph = (_c = symbolInfo.glyph) !== null && _c !== void 0 ? _c : getSymbolIcon(DEFAULT_ICON_SYMBOL).glyph;
631
+ if (glyph) {
632
+ this.iconSlot.textContent = glyph;
633
+ }
634
+ else {
635
+ this.iconSlot.innerHTML =
636
+ '<svg width="28" height="28" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2.25a1 1 0 0 1 1 1v.6a7 7 0 0 1 6 6.93v3.36l1.38 2.07A1.25 1.25 0 0 1 19.34 18H4.66a1.25 1.25 0 0 1-1.04-1.94L5 14v-3.22a7 7 0 0 1 6-6.93v-.6a1 1 0 0 1 1-1Zm-2.5 17.25a2.5 2.5 0 0 0 5 0h-5Z" /></svg>';
637
+ }
638
+ }
639
+ this.titleNode.textContent = payload.title;
640
+ this.titleNode.style.display = payload.title ? 'block' : 'none';
641
+ this.messageNode.textContent = payload.message;
642
+ this.messageNode.style.display = payload.message ? 'block' : 'none';
643
+ this.messageNode.style.marginTop = payload.title && payload.message ? '4px' : '0';
644
+ this.actionButton.textContent = payload.actionLabel;
645
+ this.actionButton.style.color = accentColor;
646
+ this.actionButton.style.display = payload.actionLabel ? 'inline-flex' : 'none';
647
+ }
648
+ armAutoDismiss(payload) {
649
+ this.clearAutoDismissTimer();
650
+ if (!payload.autoDismiss || payload.duration <= 0)
651
+ return;
652
+ this.autoDismissTimer = setTimeout(() => {
653
+ this.startExit();
654
+ }, payload.duration);
655
+ }
656
+ startExit() {
657
+ if (!this.root || !this.current || this.exitTimer)
658
+ return;
659
+ const currentId = this.current.id;
660
+ this.root.style.transition = `transform ${EXIT_MS}ms ${EXIT_EASING}, opacity ${EXIT_MS}ms ${EXIT_EASING}`;
661
+ this.root.style.transform = `translate(-50%, ${this.dragY - 40}px) scale(1)`;
662
+ this.root.style.opacity = '0';
663
+ this.exitTimer = setTimeout(() => {
664
+ var _a;
665
+ this.exitTimer = null;
666
+ this.clearAutoDismissTimer();
667
+ this.dragY = 0;
668
+ this.isDragging = false;
669
+ this.dragStartY = null;
670
+ if ((_a = this.root) === null || _a === void 0 ? void 0 : _a.isConnected) {
671
+ this.root.remove();
672
+ }
673
+ this.root = null;
674
+ this.iconSlot = null;
675
+ this.titleNode = null;
676
+ this.messageNode = null;
677
+ this.actionButton = null;
678
+ this.current = null;
679
+ this.events.onDismiss(currentId);
680
+ }, EXIT_MS);
681
+ }
682
+ applyEnteringState() {
683
+ if (!this.root)
684
+ return;
685
+ this.root.style.transition = `transform ${ENTER_MS}ms ${ENTER_EASING}, opacity ${ENTER_MS}ms ${ENTER_EASING}`;
686
+ this.root.style.transform = 'translate(-50%, -40px) scale(0.8)';
687
+ this.root.style.opacity = '0';
688
+ }
689
+ handlePointerDown(event) {
690
+ var _a, _b;
691
+ if (event.button !== 0)
692
+ return;
693
+ this.dragStartY = event.clientY;
694
+ this.dragY = 0;
695
+ (_b = (_a = this.root) === null || _a === void 0 ? void 0 : _a.setPointerCapture) === null || _b === void 0 ? void 0 : _b.call(_a, event.pointerId);
696
+ }
697
+ handlePointerMove(event) {
698
+ if (!this.root || this.dragStartY === null)
699
+ return;
700
+ const nextDragY = Math.min(0, event.clientY - this.dragStartY);
701
+ this.dragY = nextDragY;
702
+ this.isDragging = nextDragY < -2;
703
+ if (!this.isDragging)
704
+ return;
705
+ this.root.style.transition = 'none';
706
+ this.root.style.transform = `translate(-50%, ${nextDragY}px) scale(1)`;
707
+ }
708
+ handlePointerUp(event) {
709
+ var _a, _b;
710
+ if (!this.root || this.dragStartY === null)
711
+ return;
712
+ this.dragStartY = null;
713
+ (_b = (_a = this.root).releasePointerCapture) === null || _b === void 0 ? void 0 : _b.call(_a, event.pointerId);
714
+ if (this.dragY < SWIPE_THRESHOLD) {
715
+ this.startExit();
716
+ return;
717
+ }
718
+ this.isDragging = false;
719
+ this.dragY = 0;
720
+ this.root.style.transition = `transform ${EXIT_MS}ms ${EXIT_EASING}, opacity ${EXIT_MS}ms ${EXIT_EASING}`;
721
+ this.root.style.transform = 'translate(-50%, 0) scale(1)';
722
+ }
723
+ clearAutoDismissTimer() {
724
+ if (!this.autoDismissTimer)
725
+ return;
726
+ clearTimeout(this.autoDismissTimer);
727
+ this.autoDismissTimer = null;
728
+ }
729
+ clearExitTimer() {
730
+ if (!this.exitTimer)
731
+ return;
732
+ clearTimeout(this.exitTimer);
733
+ this.exitTimer = null;
734
+ }
735
+ }
736
+
737
+ class PrettyToastWeb extends core.WebPlugin {
738
+ constructor() {
739
+ super(...arguments);
740
+ this.renderer = new WebToastRenderer({
741
+ onDismiss: (id) => {
742
+ this.notifyListeners('toastDismiss', { id });
743
+ },
744
+ onPress: (id) => {
745
+ this.notifyListeners('toastPress', { id });
746
+ },
747
+ onActionPress: (id) => {
748
+ this.notifyListeners('toastActionPress', { id });
749
+ },
750
+ });
751
+ }
752
+ async showCurrentToast(options) {
753
+ this.renderer.show(options);
754
+ }
755
+ async updateCurrentToast(options) {
756
+ this.renderer.update(options);
757
+ }
758
+ async dismissCurrentToast(options) {
759
+ this.renderer.dismiss(options === null || options === void 0 ? void 0 : options.id);
760
+ }
761
+ }
762
+
763
+ var web = /*#__PURE__*/Object.freeze({
764
+ __proto__: null,
765
+ PrettyToastWeb: PrettyToastWeb
766
+ });
767
+
768
+ exports.toast = toast;
769
+
770
+ return exports;
771
+
772
+ })({}, capacitorExports);
773
+ //# sourceMappingURL=plugin.js.map