@wowlabtech/mini-app-adapter 0.2.0 → 0.2.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/dist/index.cjs +263 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.js +268 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -56,6 +56,10 @@ interface MiniAppViewportInsets {
|
|
|
56
56
|
safeArea: MiniAppSafeAreaInsets;
|
|
57
57
|
contentSafeArea: MiniAppSafeAreaInsets;
|
|
58
58
|
}
|
|
59
|
+
interface MiniAppViewportState {
|
|
60
|
+
height: number;
|
|
61
|
+
stableHeight: number;
|
|
62
|
+
}
|
|
59
63
|
interface MiniAppInitOptions {
|
|
60
64
|
/**
|
|
61
65
|
* Enables verbose logs for platforms that support it.
|
|
@@ -170,6 +174,10 @@ interface MiniAppAdapter {
|
|
|
170
174
|
* Requests fullscreen mode if supported by the platform.
|
|
171
175
|
*/
|
|
172
176
|
requestFullscreen?(): void;
|
|
177
|
+
/**
|
|
178
|
+
* Subscribes to viewport size changes. Returns disposer.
|
|
179
|
+
*/
|
|
180
|
+
onViewportChange?(callback: (state: MiniAppViewportState) => void): () => void;
|
|
173
181
|
/**
|
|
174
182
|
* Returns viewport safe area insets if supported by the platform.
|
|
175
183
|
*/
|
|
@@ -216,6 +224,21 @@ interface MiniAppAdapter {
|
|
|
216
224
|
* Resolves with true if permission was granted.
|
|
217
225
|
*/
|
|
218
226
|
requestNotificationsPermission?(): Promise<boolean>;
|
|
227
|
+
/**
|
|
228
|
+
* Prompts user to add the mini app to the home screen if supported.
|
|
229
|
+
* Resolves with true when the prompt succeeded.
|
|
230
|
+
*/
|
|
231
|
+
addToHomeScreen?(): Promise<boolean>;
|
|
232
|
+
/**
|
|
233
|
+
* Checks whether the mini app is already added to the home screen, if supported.
|
|
234
|
+
* Returns platform-specific status or 'unknown' when not available.
|
|
235
|
+
*/
|
|
236
|
+
checkHomeScreenStatus?(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
237
|
+
/**
|
|
238
|
+
* Revokes/denies push notifications if supported by the platform.
|
|
239
|
+
* Resolves with true if notifications were disabled.
|
|
240
|
+
*/
|
|
241
|
+
denyNotifications?(): Promise<boolean>;
|
|
219
242
|
/**
|
|
220
243
|
* Subscribes to push token updates delivered by native shells.
|
|
221
244
|
*/
|
|
@@ -292,6 +315,10 @@ declare abstract class BaseMiniAppAdapter implements MiniAppAdapter {
|
|
|
292
315
|
getLaunchParams(): unknown;
|
|
293
316
|
decodeStartParam(_param: string): unknown;
|
|
294
317
|
requestFullscreen(): void;
|
|
318
|
+
onViewportChange(callback: (state: {
|
|
319
|
+
height: number;
|
|
320
|
+
stableHeight: number;
|
|
321
|
+
}) => void): () => void;
|
|
295
322
|
getViewportInsets(): MiniAppViewportInsets | undefined;
|
|
296
323
|
shareMessage(_message: string): Promise<void>;
|
|
297
324
|
shareUrl(_url: string, _text: string): void;
|
|
@@ -311,6 +338,9 @@ declare abstract class BaseMiniAppAdapter implements MiniAppAdapter {
|
|
|
311
338
|
scanQRCode(_options?: MiniAppQrScanOptions): Promise<string | null>;
|
|
312
339
|
requestPhone(): Promise<string | null>;
|
|
313
340
|
requestNotificationsPermission(): Promise<boolean>;
|
|
341
|
+
addToHomeScreen(): Promise<boolean>;
|
|
342
|
+
checkHomeScreenStatus(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
343
|
+
denyNotifications(): Promise<boolean>;
|
|
314
344
|
enableVerticalSwipes(): void;
|
|
315
345
|
disableVerticalSwipes(): void;
|
|
316
346
|
protected notifyEnvironmentChanged(): void;
|
|
@@ -384,6 +414,10 @@ declare class TelegramMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
384
414
|
decodeStartParam(param: string): unknown;
|
|
385
415
|
requestFullscreen(): void;
|
|
386
416
|
getViewportInsets(): MiniAppViewportInsets | undefined;
|
|
417
|
+
onViewportChange(callback: (state: {
|
|
418
|
+
height: number;
|
|
419
|
+
stableHeight: number;
|
|
420
|
+
}) => void): () => void;
|
|
387
421
|
onAppearanceChange(callback: (appearance: 'dark' | 'light' | undefined) => void): () => void;
|
|
388
422
|
setBackButtonVisibility(visible: boolean): void;
|
|
389
423
|
enableVerticalSwipes(): void;
|
|
@@ -393,6 +427,8 @@ declare class TelegramMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
393
427
|
shareUrl(url: string, text?: string): void;
|
|
394
428
|
downloadFile(url: string, filename: string): Promise<void>;
|
|
395
429
|
shareStory(mediaUrl: string, options?: MiniAppShareStoryOptions): Promise<void>;
|
|
430
|
+
addToHomeScreen(): Promise<boolean>;
|
|
431
|
+
checkHomeScreenStatus(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
396
432
|
requestPhone(): Promise<string | null>;
|
|
397
433
|
private setupAppearanceWatcher;
|
|
398
434
|
private notifyAppearance;
|
|
@@ -400,6 +436,8 @@ declare class TelegramMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
400
436
|
private prepareViewport;
|
|
401
437
|
private requestFullscreenInternal;
|
|
402
438
|
private getViewportMountOptions;
|
|
439
|
+
private safeHeightFromSdk;
|
|
440
|
+
private stableHeightFromSdk;
|
|
403
441
|
private notifyViewHide;
|
|
404
442
|
private notifyViewRestore;
|
|
405
443
|
protected onDestroy(): void;
|
|
@@ -430,10 +468,14 @@ declare class VKMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
430
468
|
supports(capability: MiniAppCapability): Promise<boolean>;
|
|
431
469
|
requestPhone(): Promise<string | null>;
|
|
432
470
|
requestNotificationsPermission(): Promise<boolean>;
|
|
471
|
+
addToHomeScreen(): Promise<boolean>;
|
|
472
|
+
denyNotifications(): Promise<boolean>;
|
|
433
473
|
scanQRCode(options?: MiniAppQrScanOptions): Promise<string | null>;
|
|
434
474
|
onViewHide(callback: () => void): () => void;
|
|
435
475
|
onViewRestore(callback: () => void): () => void;
|
|
436
476
|
shareStory(mediaUrl: string, _options?: MiniAppShareStoryOptions): Promise<void>;
|
|
477
|
+
shareUrl(url: string, text?: string): void;
|
|
478
|
+
private shareUrlInternal;
|
|
437
479
|
downloadFile(url: string, filename: string): Promise<void>;
|
|
438
480
|
trackConversionEvent(event: string, payload?: Record<string, unknown>): void;
|
|
439
481
|
trackPixelEvent(event: string, payload?: Record<string, unknown>): void;
|
|
@@ -461,9 +503,13 @@ declare class VKMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
461
503
|
}
|
|
462
504
|
|
|
463
505
|
declare class WebMiniAppAdapter extends BaseMiniAppAdapter {
|
|
506
|
+
private deferredPrompt;
|
|
464
507
|
constructor();
|
|
465
508
|
downloadFile(url: string, filename: string): Promise<void>;
|
|
466
509
|
scanQRCode(_options?: MiniAppQrScanOptions): Promise<string | null>;
|
|
510
|
+
shareUrl(url: string, text: string): void;
|
|
511
|
+
addToHomeScreen(): Promise<boolean>;
|
|
512
|
+
checkHomeScreenStatus(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
467
513
|
}
|
|
468
514
|
|
|
469
515
|
interface CreateAdapterOptions {
|
|
@@ -508,4 +554,4 @@ declare function trackPixelEvent(event: string, payload?: Record<string, unknown
|
|
|
508
554
|
|
|
509
555
|
declare function getPlatform(): MiniAppPlatform;
|
|
510
556
|
|
|
511
|
-
export { AdapterProvider, BaseMiniAppAdapter, type CreateAdapterOptions, MaxMiniAppAdapter, type MiniAppAdapter, type MiniAppCapability, type MiniAppEnvironmentInfo, type MiniAppInitOptions, type MiniAppPlatform, type MiniAppPopupOptions, type MiniAppQrScanOptions, ShellMiniAppAdapter, TelegramMiniAppAdapter, VKMiniAppAdapter, WebMiniAppAdapter, configureVkPixel, createAdapter, createShellAPI, detectPlatform, getActiveAdapter, getPlatform, isShell, isShellAndroid, isShellIOS, readShellPlatform, requestShellPushPermission, shell, storeShellToken, trackConversionEvent, trackPixelEvent, useAdapterTheme, useMiniAppAdapter, useSafeArea };
|
|
557
|
+
export { AdapterProvider, BaseMiniAppAdapter, type CreateAdapterOptions, MaxMiniAppAdapter, type MiniAppAdapter, type MiniAppCapability, type MiniAppEnvironmentInfo, type MiniAppInitOptions, type MiniAppPlatform, type MiniAppPopupOptions, type MiniAppQrScanOptions, type MiniAppViewportState, ShellMiniAppAdapter, TelegramMiniAppAdapter, VKMiniAppAdapter, WebMiniAppAdapter, configureVkPixel, createAdapter, createShellAPI, detectPlatform, getActiveAdapter, getPlatform, isShell, isShellAndroid, isShellIOS, readShellPlatform, requestShellPushPermission, shell, storeShellToken, trackConversionEvent, trackPixelEvent, useAdapterTheme, useMiniAppAdapter, useSafeArea };
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,10 @@ interface MiniAppViewportInsets {
|
|
|
56
56
|
safeArea: MiniAppSafeAreaInsets;
|
|
57
57
|
contentSafeArea: MiniAppSafeAreaInsets;
|
|
58
58
|
}
|
|
59
|
+
interface MiniAppViewportState {
|
|
60
|
+
height: number;
|
|
61
|
+
stableHeight: number;
|
|
62
|
+
}
|
|
59
63
|
interface MiniAppInitOptions {
|
|
60
64
|
/**
|
|
61
65
|
* Enables verbose logs for platforms that support it.
|
|
@@ -170,6 +174,10 @@ interface MiniAppAdapter {
|
|
|
170
174
|
* Requests fullscreen mode if supported by the platform.
|
|
171
175
|
*/
|
|
172
176
|
requestFullscreen?(): void;
|
|
177
|
+
/**
|
|
178
|
+
* Subscribes to viewport size changes. Returns disposer.
|
|
179
|
+
*/
|
|
180
|
+
onViewportChange?(callback: (state: MiniAppViewportState) => void): () => void;
|
|
173
181
|
/**
|
|
174
182
|
* Returns viewport safe area insets if supported by the platform.
|
|
175
183
|
*/
|
|
@@ -216,6 +224,21 @@ interface MiniAppAdapter {
|
|
|
216
224
|
* Resolves with true if permission was granted.
|
|
217
225
|
*/
|
|
218
226
|
requestNotificationsPermission?(): Promise<boolean>;
|
|
227
|
+
/**
|
|
228
|
+
* Prompts user to add the mini app to the home screen if supported.
|
|
229
|
+
* Resolves with true when the prompt succeeded.
|
|
230
|
+
*/
|
|
231
|
+
addToHomeScreen?(): Promise<boolean>;
|
|
232
|
+
/**
|
|
233
|
+
* Checks whether the mini app is already added to the home screen, if supported.
|
|
234
|
+
* Returns platform-specific status or 'unknown' when not available.
|
|
235
|
+
*/
|
|
236
|
+
checkHomeScreenStatus?(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
237
|
+
/**
|
|
238
|
+
* Revokes/denies push notifications if supported by the platform.
|
|
239
|
+
* Resolves with true if notifications were disabled.
|
|
240
|
+
*/
|
|
241
|
+
denyNotifications?(): Promise<boolean>;
|
|
219
242
|
/**
|
|
220
243
|
* Subscribes to push token updates delivered by native shells.
|
|
221
244
|
*/
|
|
@@ -292,6 +315,10 @@ declare abstract class BaseMiniAppAdapter implements MiniAppAdapter {
|
|
|
292
315
|
getLaunchParams(): unknown;
|
|
293
316
|
decodeStartParam(_param: string): unknown;
|
|
294
317
|
requestFullscreen(): void;
|
|
318
|
+
onViewportChange(callback: (state: {
|
|
319
|
+
height: number;
|
|
320
|
+
stableHeight: number;
|
|
321
|
+
}) => void): () => void;
|
|
295
322
|
getViewportInsets(): MiniAppViewportInsets | undefined;
|
|
296
323
|
shareMessage(_message: string): Promise<void>;
|
|
297
324
|
shareUrl(_url: string, _text: string): void;
|
|
@@ -311,6 +338,9 @@ declare abstract class BaseMiniAppAdapter implements MiniAppAdapter {
|
|
|
311
338
|
scanQRCode(_options?: MiniAppQrScanOptions): Promise<string | null>;
|
|
312
339
|
requestPhone(): Promise<string | null>;
|
|
313
340
|
requestNotificationsPermission(): Promise<boolean>;
|
|
341
|
+
addToHomeScreen(): Promise<boolean>;
|
|
342
|
+
checkHomeScreenStatus(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
343
|
+
denyNotifications(): Promise<boolean>;
|
|
314
344
|
enableVerticalSwipes(): void;
|
|
315
345
|
disableVerticalSwipes(): void;
|
|
316
346
|
protected notifyEnvironmentChanged(): void;
|
|
@@ -384,6 +414,10 @@ declare class TelegramMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
384
414
|
decodeStartParam(param: string): unknown;
|
|
385
415
|
requestFullscreen(): void;
|
|
386
416
|
getViewportInsets(): MiniAppViewportInsets | undefined;
|
|
417
|
+
onViewportChange(callback: (state: {
|
|
418
|
+
height: number;
|
|
419
|
+
stableHeight: number;
|
|
420
|
+
}) => void): () => void;
|
|
387
421
|
onAppearanceChange(callback: (appearance: 'dark' | 'light' | undefined) => void): () => void;
|
|
388
422
|
setBackButtonVisibility(visible: boolean): void;
|
|
389
423
|
enableVerticalSwipes(): void;
|
|
@@ -393,6 +427,8 @@ declare class TelegramMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
393
427
|
shareUrl(url: string, text?: string): void;
|
|
394
428
|
downloadFile(url: string, filename: string): Promise<void>;
|
|
395
429
|
shareStory(mediaUrl: string, options?: MiniAppShareStoryOptions): Promise<void>;
|
|
430
|
+
addToHomeScreen(): Promise<boolean>;
|
|
431
|
+
checkHomeScreenStatus(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
396
432
|
requestPhone(): Promise<string | null>;
|
|
397
433
|
private setupAppearanceWatcher;
|
|
398
434
|
private notifyAppearance;
|
|
@@ -400,6 +436,8 @@ declare class TelegramMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
400
436
|
private prepareViewport;
|
|
401
437
|
private requestFullscreenInternal;
|
|
402
438
|
private getViewportMountOptions;
|
|
439
|
+
private safeHeightFromSdk;
|
|
440
|
+
private stableHeightFromSdk;
|
|
403
441
|
private notifyViewHide;
|
|
404
442
|
private notifyViewRestore;
|
|
405
443
|
protected onDestroy(): void;
|
|
@@ -430,10 +468,14 @@ declare class VKMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
430
468
|
supports(capability: MiniAppCapability): Promise<boolean>;
|
|
431
469
|
requestPhone(): Promise<string | null>;
|
|
432
470
|
requestNotificationsPermission(): Promise<boolean>;
|
|
471
|
+
addToHomeScreen(): Promise<boolean>;
|
|
472
|
+
denyNotifications(): Promise<boolean>;
|
|
433
473
|
scanQRCode(options?: MiniAppQrScanOptions): Promise<string | null>;
|
|
434
474
|
onViewHide(callback: () => void): () => void;
|
|
435
475
|
onViewRestore(callback: () => void): () => void;
|
|
436
476
|
shareStory(mediaUrl: string, _options?: MiniAppShareStoryOptions): Promise<void>;
|
|
477
|
+
shareUrl(url: string, text?: string): void;
|
|
478
|
+
private shareUrlInternal;
|
|
437
479
|
downloadFile(url: string, filename: string): Promise<void>;
|
|
438
480
|
trackConversionEvent(event: string, payload?: Record<string, unknown>): void;
|
|
439
481
|
trackPixelEvent(event: string, payload?: Record<string, unknown>): void;
|
|
@@ -461,9 +503,13 @@ declare class VKMiniAppAdapter extends BaseMiniAppAdapter {
|
|
|
461
503
|
}
|
|
462
504
|
|
|
463
505
|
declare class WebMiniAppAdapter extends BaseMiniAppAdapter {
|
|
506
|
+
private deferredPrompt;
|
|
464
507
|
constructor();
|
|
465
508
|
downloadFile(url: string, filename: string): Promise<void>;
|
|
466
509
|
scanQRCode(_options?: MiniAppQrScanOptions): Promise<string | null>;
|
|
510
|
+
shareUrl(url: string, text: string): void;
|
|
511
|
+
addToHomeScreen(): Promise<boolean>;
|
|
512
|
+
checkHomeScreenStatus(): Promise<'added' | 'not_added' | 'unknown' | string>;
|
|
467
513
|
}
|
|
468
514
|
|
|
469
515
|
interface CreateAdapterOptions {
|
|
@@ -508,4 +554,4 @@ declare function trackPixelEvent(event: string, payload?: Record<string, unknown
|
|
|
508
554
|
|
|
509
555
|
declare function getPlatform(): MiniAppPlatform;
|
|
510
556
|
|
|
511
|
-
export { AdapterProvider, BaseMiniAppAdapter, type CreateAdapterOptions, MaxMiniAppAdapter, type MiniAppAdapter, type MiniAppCapability, type MiniAppEnvironmentInfo, type MiniAppInitOptions, type MiniAppPlatform, type MiniAppPopupOptions, type MiniAppQrScanOptions, ShellMiniAppAdapter, TelegramMiniAppAdapter, VKMiniAppAdapter, WebMiniAppAdapter, configureVkPixel, createAdapter, createShellAPI, detectPlatform, getActiveAdapter, getPlatform, isShell, isShellAndroid, isShellIOS, readShellPlatform, requestShellPushPermission, shell, storeShellToken, trackConversionEvent, trackPixelEvent, useAdapterTheme, useMiniAppAdapter, useSafeArea };
|
|
557
|
+
export { AdapterProvider, BaseMiniAppAdapter, type CreateAdapterOptions, MaxMiniAppAdapter, type MiniAppAdapter, type MiniAppCapability, type MiniAppEnvironmentInfo, type MiniAppInitOptions, type MiniAppPlatform, type MiniAppPopupOptions, type MiniAppQrScanOptions, type MiniAppViewportState, ShellMiniAppAdapter, TelegramMiniAppAdapter, VKMiniAppAdapter, WebMiniAppAdapter, configureVkPixel, createAdapter, createShellAPI, detectPlatform, getActiveAdapter, getPlatform, isShell, isShellAndroid, isShellIOS, readShellPlatform, requestShellPushPermission, shell, storeShellToken, trackConversionEvent, trackPixelEvent, useAdapterTheme, useMiniAppAdapter, useSafeArea };
|
package/dist/index.js
CHANGED
|
@@ -607,6 +607,27 @@ var BaseMiniAppAdapter = class {
|
|
|
607
607
|
}
|
|
608
608
|
requestFullscreen() {
|
|
609
609
|
}
|
|
610
|
+
onViewportChange(callback) {
|
|
611
|
+
if (typeof window === "undefined") {
|
|
612
|
+
return () => {
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
const fallbackHeight = () => window.visualViewport?.height ?? window.innerHeight;
|
|
616
|
+
const notify = () => {
|
|
617
|
+
const height = fallbackHeight();
|
|
618
|
+
callback({ height, stableHeight: height });
|
|
619
|
+
};
|
|
620
|
+
notify();
|
|
621
|
+
const onResize = () => notify();
|
|
622
|
+
window.visualViewport?.addEventListener("resize", onResize);
|
|
623
|
+
window.visualViewport?.addEventListener("scroll", onResize);
|
|
624
|
+
window.addEventListener("resize", onResize);
|
|
625
|
+
return () => {
|
|
626
|
+
window.visualViewport?.removeEventListener("resize", onResize);
|
|
627
|
+
window.visualViewport?.removeEventListener("scroll", onResize);
|
|
628
|
+
window.removeEventListener("resize", onResize);
|
|
629
|
+
};
|
|
630
|
+
}
|
|
610
631
|
getViewportInsets() {
|
|
611
632
|
return void 0;
|
|
612
633
|
}
|
|
@@ -681,6 +702,25 @@ var BaseMiniAppAdapter = class {
|
|
|
681
702
|
return null;
|
|
682
703
|
}
|
|
683
704
|
async requestNotificationsPermission() {
|
|
705
|
+
if (typeof Notification === "undefined" || typeof Notification.requestPermission !== "function") {
|
|
706
|
+
return false;
|
|
707
|
+
}
|
|
708
|
+
try {
|
|
709
|
+
const permission = await Notification.requestPermission();
|
|
710
|
+
return permission === "granted";
|
|
711
|
+
} catch (error) {
|
|
712
|
+
console.warn("[tvm-app-adapter] requestNotificationsPermission fallback failed:", error);
|
|
713
|
+
return false;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
async addToHomeScreen() {
|
|
717
|
+
return false;
|
|
718
|
+
}
|
|
719
|
+
async checkHomeScreenStatus() {
|
|
720
|
+
return "unknown";
|
|
721
|
+
}
|
|
722
|
+
async denyNotifications() {
|
|
723
|
+
console.warn("[tvm-app-adapter] denyNotifications fallback is not supported in this environment.");
|
|
684
724
|
return false;
|
|
685
725
|
}
|
|
686
726
|
enableVerticalSwipes() {
|
|
@@ -1010,7 +1050,11 @@ import {
|
|
|
1010
1050
|
shareURL as shareURLSdk,
|
|
1011
1051
|
copyTextToClipboard as copyTextToClipboardSdk,
|
|
1012
1052
|
downloadFile as downloadFileSdk,
|
|
1013
|
-
shareStory as shareStorySdk
|
|
1053
|
+
shareStory as shareStorySdk,
|
|
1054
|
+
addToHomeScreen as addToHomeScreenSdk,
|
|
1055
|
+
checkHomeScreenStatus as checkHomeScreenStatusSdk,
|
|
1056
|
+
on,
|
|
1057
|
+
off
|
|
1014
1058
|
} from "@tma.js/sdk";
|
|
1015
1059
|
|
|
1016
1060
|
// src/lib/features.ts
|
|
@@ -1356,6 +1400,63 @@ var TelegramMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
1356
1400
|
return void 0;
|
|
1357
1401
|
}
|
|
1358
1402
|
}
|
|
1403
|
+
onViewportChange(callback) {
|
|
1404
|
+
const disposers = [];
|
|
1405
|
+
const fallbackHeight = () => typeof window !== "undefined" ? window.visualViewport?.height ?? window.innerHeight : 0;
|
|
1406
|
+
const notify = (state) => {
|
|
1407
|
+
const heightCandidate = state?.height ?? this.safeHeightFromSdk();
|
|
1408
|
+
const stableCandidate = state?.stableHeight ?? this.stableHeightFromSdk();
|
|
1409
|
+
const height = Number.isFinite(heightCandidate) ? heightCandidate : fallbackHeight();
|
|
1410
|
+
const stableHeight = Number.isFinite(stableCandidate) && stableCandidate > 0 ? stableCandidate : height;
|
|
1411
|
+
callback({ height, stableHeight });
|
|
1412
|
+
};
|
|
1413
|
+
const ensureMounted = async () => {
|
|
1414
|
+
try {
|
|
1415
|
+
await ensureViewportMounted(this.getViewportMountOptions());
|
|
1416
|
+
} catch (error) {
|
|
1417
|
+
console.warn("[tvm-app-adapter] ensureViewportMounted failed:", error);
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
void ensureMounted().finally(() => notify());
|
|
1421
|
+
const { sdkViewport } = this.getViewportMountOptions();
|
|
1422
|
+
if (typeof sdkViewport.on === "function") {
|
|
1423
|
+
try {
|
|
1424
|
+
const off2 = sdkViewport.on("change", (next) => notify(next));
|
|
1425
|
+
if (typeof off2 === "function") {
|
|
1426
|
+
disposers.push(off2);
|
|
1427
|
+
}
|
|
1428
|
+
} catch (error) {
|
|
1429
|
+
console.warn("[tvm-app-adapter] viewport.on(change) subscription failed:", error);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
try {
|
|
1433
|
+
if (typeof sdkViewport.height?.sub === "function") {
|
|
1434
|
+
disposers.push(sdkViewport.height.sub(() => notify()));
|
|
1435
|
+
}
|
|
1436
|
+
if (typeof sdkViewport.stableHeight?.sub === "function") {
|
|
1437
|
+
disposers.push(sdkViewport.stableHeight.sub(() => notify()));
|
|
1438
|
+
}
|
|
1439
|
+
} catch (error) {
|
|
1440
|
+
console.warn("[tvm-app-adapter] viewport signal subscriptions failed:", error);
|
|
1441
|
+
}
|
|
1442
|
+
if (typeof window !== "undefined") {
|
|
1443
|
+
const onResize = () => notify();
|
|
1444
|
+
window.visualViewport?.addEventListener("resize", onResize);
|
|
1445
|
+
window.addEventListener("resize", onResize);
|
|
1446
|
+
disposers.push(() => {
|
|
1447
|
+
window.visualViewport?.removeEventListener("resize", onResize);
|
|
1448
|
+
window.removeEventListener("resize", onResize);
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
return () => {
|
|
1452
|
+
disposers.forEach((dispose) => {
|
|
1453
|
+
try {
|
|
1454
|
+
dispose();
|
|
1455
|
+
} catch {
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1359
1460
|
onAppearanceChange(callback) {
|
|
1360
1461
|
this.appearanceListeners.add(callback);
|
|
1361
1462
|
callback(this.environment.appearance);
|
|
@@ -1433,6 +1534,50 @@ var TelegramMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
1433
1534
|
async shareStory(mediaUrl, options) {
|
|
1434
1535
|
shareStorySdk(mediaUrl, options);
|
|
1435
1536
|
}
|
|
1537
|
+
async addToHomeScreen() {
|
|
1538
|
+
const isAvailable = typeof addToHomeScreenSdk?.isAvailable === "function" ? addToHomeScreenSdk.isAvailable() : true;
|
|
1539
|
+
if (!isAvailable) {
|
|
1540
|
+
return super.addToHomeScreen();
|
|
1541
|
+
}
|
|
1542
|
+
return new Promise((resolve) => {
|
|
1543
|
+
const cleanup = () => {
|
|
1544
|
+
off("home_screen_added", handleSuccess);
|
|
1545
|
+
off("home_screen_failed", handleFail);
|
|
1546
|
+
};
|
|
1547
|
+
const handleSuccess = () => {
|
|
1548
|
+
cleanup();
|
|
1549
|
+
resolve(true);
|
|
1550
|
+
};
|
|
1551
|
+
const handleFail = () => {
|
|
1552
|
+
cleanup();
|
|
1553
|
+
resolve(false);
|
|
1554
|
+
};
|
|
1555
|
+
on("home_screen_added", handleSuccess);
|
|
1556
|
+
on("home_screen_failed", handleFail);
|
|
1557
|
+
try {
|
|
1558
|
+
addToHomeScreenSdk();
|
|
1559
|
+
} catch (error) {
|
|
1560
|
+
cleanup();
|
|
1561
|
+
console.warn("[tvm-app-adapter] Telegram addToHomeScreen failed:", error);
|
|
1562
|
+
resolve(false);
|
|
1563
|
+
}
|
|
1564
|
+
});
|
|
1565
|
+
}
|
|
1566
|
+
async checkHomeScreenStatus() {
|
|
1567
|
+
try {
|
|
1568
|
+
const status = await checkHomeScreenStatusSdk();
|
|
1569
|
+
if (typeof status === "string") {
|
|
1570
|
+
return status;
|
|
1571
|
+
}
|
|
1572
|
+
if (typeof status === "boolean") {
|
|
1573
|
+
return status ? "added" : "not_added";
|
|
1574
|
+
}
|
|
1575
|
+
return "unknown";
|
|
1576
|
+
} catch (error) {
|
|
1577
|
+
console.warn("[tvm-app-adapter] Telegram checkHomeScreenStatus failed:", error);
|
|
1578
|
+
return "unknown";
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1436
1581
|
async requestPhone() {
|
|
1437
1582
|
const contactFeature = ensureFeature(requestContact);
|
|
1438
1583
|
if (!contactFeature.ok) {
|
|
@@ -1542,6 +1687,26 @@ var TelegramMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
1542
1687
|
}
|
|
1543
1688
|
};
|
|
1544
1689
|
}
|
|
1690
|
+
safeHeightFromSdk() {
|
|
1691
|
+
try {
|
|
1692
|
+
if (typeof rawViewport.height === "function") {
|
|
1693
|
+
return rawViewport.height();
|
|
1694
|
+
}
|
|
1695
|
+
} catch {
|
|
1696
|
+
return void 0;
|
|
1697
|
+
}
|
|
1698
|
+
return void 0;
|
|
1699
|
+
}
|
|
1700
|
+
stableHeightFromSdk() {
|
|
1701
|
+
try {
|
|
1702
|
+
if (typeof rawViewport.stableHeight === "function") {
|
|
1703
|
+
return rawViewport.stableHeight();
|
|
1704
|
+
}
|
|
1705
|
+
} catch {
|
|
1706
|
+
return void 0;
|
|
1707
|
+
}
|
|
1708
|
+
return void 0;
|
|
1709
|
+
}
|
|
1545
1710
|
notifyViewHide() {
|
|
1546
1711
|
for (const listener of this.viewHideListeners) {
|
|
1547
1712
|
try {
|
|
@@ -1774,6 +1939,39 @@ var VKMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
1774
1939
|
return false;
|
|
1775
1940
|
}
|
|
1776
1941
|
}
|
|
1942
|
+
async addToHomeScreen() {
|
|
1943
|
+
const supported = await this.supportsBridgeMethod("VKWebAppAddToHomeScreen");
|
|
1944
|
+
if (!supported) {
|
|
1945
|
+
console.warn("[tvm-app-adapter] VK addToHomeScreen not supported");
|
|
1946
|
+
return super.addToHomeScreen();
|
|
1947
|
+
}
|
|
1948
|
+
try {
|
|
1949
|
+
const response = await bridge.send("VKWebAppAddToHomeScreen");
|
|
1950
|
+
if (response && typeof response === "object" && "result" in response) {
|
|
1951
|
+
return Boolean(response.result);
|
|
1952
|
+
}
|
|
1953
|
+
return true;
|
|
1954
|
+
} catch (error) {
|
|
1955
|
+
console.warn("[tvm-app-adapter] VK addToHomeScreen failed:", error);
|
|
1956
|
+
return false;
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
async denyNotifications() {
|
|
1960
|
+
const supported = await this.supportsBridgeMethod("VKWebAppDenyNotifications");
|
|
1961
|
+
if (!supported) {
|
|
1962
|
+
return super.denyNotifications();
|
|
1963
|
+
}
|
|
1964
|
+
try {
|
|
1965
|
+
const response = await bridge.send("VKWebAppDenyNotifications");
|
|
1966
|
+
if (response && typeof response === "object" && "result" in response) {
|
|
1967
|
+
return Boolean(response.result);
|
|
1968
|
+
}
|
|
1969
|
+
return true;
|
|
1970
|
+
} catch (error) {
|
|
1971
|
+
console.warn("[tvm-app-adapter] VK deny notifications failed:", error);
|
|
1972
|
+
return false;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1777
1975
|
async scanQRCode(options) {
|
|
1778
1976
|
const supportsQrScanner = await this.supportsBridgeMethod("VKWebAppOpenCodeReader");
|
|
1779
1977
|
if (!supportsQrScanner) {
|
|
@@ -1809,6 +2007,25 @@ var VKMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
1809
2007
|
};
|
|
1810
2008
|
await bridge.send("VKWebAppShowStoryBox", bridgeOptions);
|
|
1811
2009
|
}
|
|
2010
|
+
shareUrl(url, text) {
|
|
2011
|
+
void this.shareUrlInternal(url, text);
|
|
2012
|
+
}
|
|
2013
|
+
async shareUrlInternal(url, text) {
|
|
2014
|
+
const supported = await this.supportsBridgeMethod("VKWebAppShare");
|
|
2015
|
+
if (!supported) {
|
|
2016
|
+
super.shareUrl(url, text ?? "");
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
try {
|
|
2020
|
+
await bridge.send("VKWebAppShare", {
|
|
2021
|
+
link: url,
|
|
2022
|
+
...text ? { text } : {}
|
|
2023
|
+
});
|
|
2024
|
+
} catch (error) {
|
|
2025
|
+
console.warn("[tvm-app-adapter] VK shareUrl failed:", error);
|
|
2026
|
+
super.shareUrl(url, text ?? "");
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
1812
2029
|
async downloadFile(url, filename) {
|
|
1813
2030
|
const supported = await this.supportsBridgeMethod("VKWebAppDownloadFile");
|
|
1814
2031
|
if (!supported) {
|
|
@@ -2167,6 +2384,13 @@ var WebMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
2167
2384
|
languageCode: navigator.language,
|
|
2168
2385
|
isWebView: false
|
|
2169
2386
|
});
|
|
2387
|
+
__publicField(this, "deferredPrompt", null);
|
|
2388
|
+
if (typeof window !== "undefined") {
|
|
2389
|
+
window.addEventListener("beforeinstallprompt", (event) => {
|
|
2390
|
+
event.preventDefault();
|
|
2391
|
+
this.deferredPrompt = event;
|
|
2392
|
+
});
|
|
2393
|
+
}
|
|
2170
2394
|
}
|
|
2171
2395
|
async downloadFile(url, filename) {
|
|
2172
2396
|
try {
|
|
@@ -2315,6 +2539,49 @@ var WebMiniAppAdapter = class extends BaseMiniAppAdapter {
|
|
|
2315
2539
|
}
|
|
2316
2540
|
});
|
|
2317
2541
|
}
|
|
2542
|
+
shareUrl(url, text) {
|
|
2543
|
+
if (navigator.share) {
|
|
2544
|
+
try {
|
|
2545
|
+
navigator.share({ title: text, text, url });
|
|
2546
|
+
return;
|
|
2547
|
+
} catch (err) {
|
|
2548
|
+
console.warn("Share cancelled or failed:", err);
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
const payload = text ? `${text}
|
|
2552
|
+
${url}` : url;
|
|
2553
|
+
this.copyTextToClipboard(payload).catch((err) => {
|
|
2554
|
+
console.warn("Share fallback (clipboard) failed:", err);
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2557
|
+
async addToHomeScreen() {
|
|
2558
|
+
const isAndroid = /android/i.test(navigator.userAgent);
|
|
2559
|
+
if (!isAndroid || !this.deferredPrompt) {
|
|
2560
|
+
return super.addToHomeScreen();
|
|
2561
|
+
}
|
|
2562
|
+
try {
|
|
2563
|
+
this.deferredPrompt.prompt();
|
|
2564
|
+
const choice = await this.deferredPrompt.userChoice;
|
|
2565
|
+
this.deferredPrompt = null;
|
|
2566
|
+
return choice?.outcome === "accepted";
|
|
2567
|
+
} catch (error) {
|
|
2568
|
+
console.warn("[tvm-app-adapter] Web addToHomeScreen failed:", error);
|
|
2569
|
+
this.deferredPrompt = null;
|
|
2570
|
+
return false;
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
async checkHomeScreenStatus() {
|
|
2574
|
+
try {
|
|
2575
|
+
const isStandalone = typeof window !== "undefined" && window.matchMedia?.("(display-mode: standalone)").matches || // iOS Safari specific flag
|
|
2576
|
+
typeof navigator !== "undefined" && navigator.standalone === true;
|
|
2577
|
+
if (isStandalone) {
|
|
2578
|
+
return "added";
|
|
2579
|
+
}
|
|
2580
|
+
return "unknown";
|
|
2581
|
+
} catch {
|
|
2582
|
+
return "unknown";
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2318
2585
|
};
|
|
2319
2586
|
|
|
2320
2587
|
// src/adapters/index.ts
|