telegix 1.1.1 → 1.1.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/README.md +539 -63
- package/index.cjs +6305 -0
- package/index.d.ts +120 -0
- package/index.js +11 -2
- package/lib/api.js +97 -19
- package/lib/context.js +111 -0
- package/lib/format.js +6 -0
- package/lib/link-preview.js +256 -0
- package/lib/markdownv2.js +3 -0
- package/lib/markup.js +116 -4
- package/lib/rich.js +54 -0
- package/lib/stream.js +251 -0
- package/lib/webapp.js +511 -2
- package/package.json +1 -1
package/lib/webapp.js
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Telegix - Telegram Web App
|
|
2
|
+
* Telegix - Telegram Mini Apps (TMA) & Web App Suite
|
|
3
|
+
* Comprehensive support for Mini Apps 8.0/9.0/10.x:
|
|
4
|
+
* - InitData Validation & Parsing
|
|
5
|
+
* - Full-Screen Mode
|
|
6
|
+
* - Device Motion Tracking (Accelerometer, Orientation, Gyroscope)
|
|
7
|
+
* - Loading Screen Customization (Theme-adaptive splash & skeleton)
|
|
8
|
+
* - Prepared Inline Messages & Launch URLs
|
|
9
|
+
* - Client-side WebApp Bridge Utilities
|
|
10
|
+
* @module telegix/webapp
|
|
3
11
|
*/
|
|
4
12
|
|
|
5
13
|
import crypto from 'crypto';
|
|
@@ -59,7 +67,508 @@ export function validateWebAppInitData(initDataStr, botToken, options = {}) {
|
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
return result;
|
|
62
|
-
} catch
|
|
70
|
+
} catch {
|
|
63
71
|
return null;
|
|
64
72
|
}
|
|
65
73
|
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Parses raw initData string into a structured JavaScript object without cryptographic validation
|
|
77
|
+
* @param {string} initDataStr
|
|
78
|
+
* @returns {object}
|
|
79
|
+
*/
|
|
80
|
+
export function parseWebAppInitData(initDataStr) {
|
|
81
|
+
if (!initDataStr || typeof initDataStr !== 'string') return {};
|
|
82
|
+
|
|
83
|
+
const params = new URLSearchParams(initDataStr);
|
|
84
|
+
const result = {};
|
|
85
|
+
|
|
86
|
+
for (const [key, value] of params.entries()) {
|
|
87
|
+
try {
|
|
88
|
+
result[key] = JSON.parse(value);
|
|
89
|
+
} catch {
|
|
90
|
+
result[key] = value;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Generate a Telegram Mini App direct launch URL
|
|
99
|
+
* @param {string} botUsername - Bot username (without @)
|
|
100
|
+
* @param {string} appShortName - Mini App short name registered in @BotFather
|
|
101
|
+
* @param {string} [startParam] - Optional startapp parameter
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
export function createMiniAppLaunchUrl(botUsername, appShortName, startParam = '') {
|
|
105
|
+
const cleanUsername = String(botUsername).replace(/^@/, '');
|
|
106
|
+
const url = `https://t.me/${cleanUsername}/${appShortName}`;
|
|
107
|
+
return startParam ? `${url}?startapp=${encodeURIComponent(startParam)}` : url;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Builder and Generator for Telegram Mini App Loading Screen (Mini Apps 8.0)
|
|
112
|
+
* Generates lightweight, responsive splash & skeleton screens adapting to dark/light Telegram theme.
|
|
113
|
+
*/
|
|
114
|
+
export class MiniAppLoadingScreen {
|
|
115
|
+
/**
|
|
116
|
+
* @param {object} [options]
|
|
117
|
+
* @param {string} [options.title='Loading Mini App...']
|
|
118
|
+
* @param {string} [options.icon] - Image URL or SVG string for brand icon
|
|
119
|
+
* @param {string} [options.lightColor='#2481cc'] - Primary brand color in light theme
|
|
120
|
+
* @param {string} [options.darkColor='#64b5f6'] - Primary brand color in dark theme
|
|
121
|
+
* @param {string} [options.lightBg='#ffffff'] - Background in light theme
|
|
122
|
+
* @param {string} [options.darkBg='#17212b'] - Background in dark theme
|
|
123
|
+
* @param {boolean} [options.skeleton=true] - Render shimmer skeleton bars below icon
|
|
124
|
+
*/
|
|
125
|
+
constructor(options = {}) {
|
|
126
|
+
this.title = options.title ?? 'Loading...';
|
|
127
|
+
this.icon = options.icon ?? '';
|
|
128
|
+
this.lightColor = options.lightColor ?? '#2481cc';
|
|
129
|
+
this.darkColor = options.darkColor ?? '#64b5f6';
|
|
130
|
+
this.lightBg = options.lightBg ?? '#ffffff';
|
|
131
|
+
this.darkBg = options.darkBg ?? '#17212b';
|
|
132
|
+
this.skeleton = options.skeleton ?? true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Set brand icon (URL or SVG)
|
|
137
|
+
* @param {string} icon
|
|
138
|
+
* @returns {this}
|
|
139
|
+
*/
|
|
140
|
+
setIcon(icon) {
|
|
141
|
+
this.icon = String(icon);
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Set loading title
|
|
147
|
+
* @param {string} title
|
|
148
|
+
* @returns {this}
|
|
149
|
+
*/
|
|
150
|
+
setTitle(title) {
|
|
151
|
+
this.title = String(title);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Set light and dark theme colors
|
|
157
|
+
* @param {string} lightColor
|
|
158
|
+
* @param {string} darkColor
|
|
159
|
+
* @returns {this}
|
|
160
|
+
*/
|
|
161
|
+
setColors(lightColor, darkColor) {
|
|
162
|
+
this.lightColor = lightColor;
|
|
163
|
+
this.darkColor = darkColor;
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Toggle skeleton placeholder display
|
|
169
|
+
* @param {boolean} [enabled=true]
|
|
170
|
+
* @returns {this}
|
|
171
|
+
*/
|
|
172
|
+
setSkeleton(enabled = true) {
|
|
173
|
+
this.skeleton = Boolean(enabled);
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Generate CSS styles for the customized loading screen
|
|
179
|
+
* @returns {string}
|
|
180
|
+
*/
|
|
181
|
+
toCSS() {
|
|
182
|
+
return `
|
|
183
|
+
:root {
|
|
184
|
+
--tg-loading-bg: ${this.lightBg};
|
|
185
|
+
--tg-loading-color: ${this.lightColor};
|
|
186
|
+
--tg-skeleton-base: #e0e0e0;
|
|
187
|
+
--tg-skeleton-shimmer: #f5f5f5;
|
|
188
|
+
}
|
|
189
|
+
@media (prefers-color-scheme: dark) {
|
|
190
|
+
:root {
|
|
191
|
+
--tg-loading-bg: ${this.darkBg};
|
|
192
|
+
--tg-loading-color: ${this.darkColor};
|
|
193
|
+
--tg-skeleton-base: #242f3d;
|
|
194
|
+
--tg-skeleton-shimmer: #313d4f;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
#tg-loading-screen {
|
|
198
|
+
position: fixed;
|
|
199
|
+
inset: 0;
|
|
200
|
+
z-index: 99999;
|
|
201
|
+
display: flex;
|
|
202
|
+
flex-direction: column;
|
|
203
|
+
align-items: center;
|
|
204
|
+
justify-content: center;
|
|
205
|
+
background-color: var(--tg-theme-bg-color, var(--tg-loading-bg));
|
|
206
|
+
color: var(--tg-theme-text-color, #222222);
|
|
207
|
+
transition: opacity 0.35s ease, visibility 0.35s ease;
|
|
208
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
209
|
+
user-select: none;
|
|
210
|
+
}
|
|
211
|
+
#tg-loading-screen.hidden {
|
|
212
|
+
opacity: 0;
|
|
213
|
+
visibility: hidden;
|
|
214
|
+
pointer-events: none;
|
|
215
|
+
}
|
|
216
|
+
.tg-loading-icon {
|
|
217
|
+
width: 72px;
|
|
218
|
+
height: 72px;
|
|
219
|
+
margin-bottom: 16px;
|
|
220
|
+
animation: tg-bounce 1.6s infinite ease-in-out;
|
|
221
|
+
}
|
|
222
|
+
.tg-loading-title {
|
|
223
|
+
font-size: 17px;
|
|
224
|
+
font-weight: 600;
|
|
225
|
+
letter-spacing: -0.2px;
|
|
226
|
+
margin-bottom: 24px;
|
|
227
|
+
color: var(--tg-theme-text-color, #222222);
|
|
228
|
+
}
|
|
229
|
+
.tg-loading-spinner {
|
|
230
|
+
width: 32px;
|
|
231
|
+
height: 32px;
|
|
232
|
+
border: 3px solid rgba(127, 127, 127, 0.2);
|
|
233
|
+
border-top-color: var(--tg-theme-button-color, var(--tg-loading-color));
|
|
234
|
+
border-radius: 50%;
|
|
235
|
+
animation: tg-spin 0.8s linear infinite;
|
|
236
|
+
}
|
|
237
|
+
.tg-skeleton-container {
|
|
238
|
+
width: 80%;
|
|
239
|
+
max-width: 280px;
|
|
240
|
+
display: flex;
|
|
241
|
+
flex-direction: column;
|
|
242
|
+
gap: 10px;
|
|
243
|
+
margin-top: 16px;
|
|
244
|
+
}
|
|
245
|
+
.tg-skeleton-bar {
|
|
246
|
+
height: 14px;
|
|
247
|
+
border-radius: 6px;
|
|
248
|
+
background: linear-gradient(90deg, var(--tg-skeleton-base) 25%, var(--tg-skeleton-shimmer) 50%, var(--tg-skeleton-base) 75%);
|
|
249
|
+
background-size: 200% 100%;
|
|
250
|
+
animation: tg-shimmer 1.5s infinite;
|
|
251
|
+
}
|
|
252
|
+
@keyframes tg-spin { to { transform: rotate(360deg); } }
|
|
253
|
+
@keyframes tg-bounce {
|
|
254
|
+
0%, 100% { transform: scale(1); }
|
|
255
|
+
50% { transform: scale(1.08); }
|
|
256
|
+
}
|
|
257
|
+
@keyframes tg-shimmer {
|
|
258
|
+
0% { background-position: 200% 0; }
|
|
259
|
+
100% { background-position: -200% 0; }
|
|
260
|
+
}
|
|
261
|
+
`.trim();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Generate HTML element string for the customized loading screen
|
|
266
|
+
* @returns {string}
|
|
267
|
+
*/
|
|
268
|
+
toHTML() {
|
|
269
|
+
const iconHtml = this.icon
|
|
270
|
+
? (this.icon.startsWith('<svg')
|
|
271
|
+
? `<div class="tg-loading-icon">${this.icon}</div>`
|
|
272
|
+
: `<img src="${this.icon}" alt="Loading" class="tg-loading-icon" />`)
|
|
273
|
+
: `<div class="tg-loading-spinner"></div>`;
|
|
274
|
+
|
|
275
|
+
const skeletonHtml = this.skeleton
|
|
276
|
+
? `<div class="tg-skeleton-container">
|
|
277
|
+
<div class="tg-skeleton-bar" style="width: 100%;"></div>
|
|
278
|
+
<div class="tg-skeleton-bar" style="width: 75%;"></div>
|
|
279
|
+
<div class="tg-skeleton-bar" style="width: 88%;"></div>
|
|
280
|
+
</div>`
|
|
281
|
+
: '';
|
|
282
|
+
|
|
283
|
+
return `
|
|
284
|
+
<style>${this.toCSS()}</style>
|
|
285
|
+
<div id="tg-loading-screen">
|
|
286
|
+
${iconHtml}
|
|
287
|
+
<div class="tg-loading-title">${this.title}</div>
|
|
288
|
+
${skeletonHtml}
|
|
289
|
+
</div>
|
|
290
|
+
<script>
|
|
291
|
+
window.addEventListener('load', function() {
|
|
292
|
+
if (window.Telegram && window.Telegram.WebApp) {
|
|
293
|
+
window.Telegram.WebApp.ready();
|
|
294
|
+
}
|
|
295
|
+
setTimeout(function() {
|
|
296
|
+
var el = document.getElementById('tg-loading-screen');
|
|
297
|
+
if (el) el.classList.add('hidden');
|
|
298
|
+
}, 200);
|
|
299
|
+
});
|
|
300
|
+
</script>
|
|
301
|
+
`.trim();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Helper to generate loading screen HTML
|
|
307
|
+
* @param {object} options
|
|
308
|
+
* @returns {string}
|
|
309
|
+
*/
|
|
310
|
+
export function generateMiniAppLoadingScreen(options = {}) {
|
|
311
|
+
return new MiniAppLoadingScreen(options).toHTML();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Telegram Mini Apps 8.0/9.0/10.x Full-Screen and Device Motion Controller
|
|
316
|
+
* Lightweight client bridge helper for Telegram WebApp environment.
|
|
317
|
+
*/
|
|
318
|
+
export const MiniApp = {
|
|
319
|
+
/**
|
|
320
|
+
* Check if running inside Telegram Mini App environment
|
|
321
|
+
* @returns {boolean}
|
|
322
|
+
*/
|
|
323
|
+
isInsideTelegram() {
|
|
324
|
+
return typeof window !== 'undefined' && Boolean(window.Telegram?.WebApp);
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Returns window.Telegram.WebApp object safely
|
|
329
|
+
* @returns {object|null}
|
|
330
|
+
*/
|
|
331
|
+
get webApp() {
|
|
332
|
+
return (typeof window !== 'undefined' && window.Telegram?.WebApp) || null;
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Full-Screen Mode Methods (Mini Apps 8.0)
|
|
337
|
+
*/
|
|
338
|
+
fullscreen: {
|
|
339
|
+
/**
|
|
340
|
+
* Request full-screen mode for the Mini App
|
|
341
|
+
*/
|
|
342
|
+
request() {
|
|
343
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.requestFullscreen) {
|
|
344
|
+
window.Telegram.WebApp.requestFullscreen();
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
return false;
|
|
348
|
+
},
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Exit full-screen mode
|
|
352
|
+
*/
|
|
353
|
+
exit() {
|
|
354
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.exitFullscreen) {
|
|
355
|
+
window.Telegram.WebApp.exitFullscreen();
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
return false;
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Check if currently in full-screen mode
|
|
363
|
+
* @returns {boolean}
|
|
364
|
+
*/
|
|
365
|
+
isActive() {
|
|
366
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp) {
|
|
367
|
+
return Boolean(window.Telegram.WebApp.isFullscreen);
|
|
368
|
+
}
|
|
369
|
+
return false;
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Listen for full-screen state changes
|
|
374
|
+
* @param {function(boolean): void} callback
|
|
375
|
+
*/
|
|
376
|
+
onChange(callback) {
|
|
377
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.onEvent) {
|
|
378
|
+
window.Telegram.WebApp.onEvent('fullscreenChanged', () => {
|
|
379
|
+
callback(Boolean(window.Telegram.WebApp.isFullscreen));
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Listen for full-screen request failures
|
|
386
|
+
* @param {function(object): void} callback
|
|
387
|
+
*/
|
|
388
|
+
onFailed(callback) {
|
|
389
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.onEvent) {
|
|
390
|
+
window.Telegram.WebApp.onEvent('fullscreenFailed', callback);
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Device Motion Tracking Methods (Mini Apps 8.0)
|
|
397
|
+
* Tracks Accelerometer, Device Orientation, and Gyroscope
|
|
398
|
+
*/
|
|
399
|
+
motion: {
|
|
400
|
+
/**
|
|
401
|
+
* Start tracking accelerometer
|
|
402
|
+
* @param {object} [options]
|
|
403
|
+
* @param {number} [options.refresh_rate=100] - Refresh rate in ms (min: 20ms, default: 100ms)
|
|
404
|
+
* @returns {boolean}
|
|
405
|
+
*/
|
|
406
|
+
startAccelerometer(options = { refresh_rate: 100 }) {
|
|
407
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.startAccelerometer) {
|
|
408
|
+
window.Telegram.WebApp.startAccelerometer(options);
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
return false;
|
|
412
|
+
},
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Stop tracking accelerometer
|
|
416
|
+
* @returns {boolean}
|
|
417
|
+
*/
|
|
418
|
+
stopAccelerometer() {
|
|
419
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.stopAccelerometer) {
|
|
420
|
+
window.Telegram.WebApp.stopAccelerometer();
|
|
421
|
+
return true;
|
|
422
|
+
}
|
|
423
|
+
return false;
|
|
424
|
+
},
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Listen to accelerometer changes
|
|
428
|
+
* @param {function({ x: number, y: number, z: number }): void} callback
|
|
429
|
+
*/
|
|
430
|
+
onAccelerometer(callback) {
|
|
431
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.onEvent) {
|
|
432
|
+
window.Telegram.WebApp.onEvent('accelerometerChanged', callback);
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Start tracking device orientation
|
|
438
|
+
* @param {object} [options]
|
|
439
|
+
* @param {number} [options.refresh_rate=100]
|
|
440
|
+
* @param {boolean} [options.need_absolute=false]
|
|
441
|
+
* @returns {boolean}
|
|
442
|
+
*/
|
|
443
|
+
startDeviceOrientation(options = { refresh_rate: 100, need_absolute: false }) {
|
|
444
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.startDeviceOrientation) {
|
|
445
|
+
window.Telegram.WebApp.startDeviceOrientation(options);
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
return false;
|
|
449
|
+
},
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Stop tracking device orientation
|
|
453
|
+
* @returns {boolean}
|
|
454
|
+
*/
|
|
455
|
+
stopDeviceOrientation() {
|
|
456
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.stopDeviceOrientation) {
|
|
457
|
+
window.Telegram.WebApp.stopDeviceOrientation();
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
},
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Listen to device orientation changes (alpha, beta, gamma, absolute)
|
|
465
|
+
* @param {function({ alpha: number, beta: number, gamma: number, absolute: boolean }): void} callback
|
|
466
|
+
*/
|
|
467
|
+
onOrientation(callback) {
|
|
468
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.onEvent) {
|
|
469
|
+
window.Telegram.WebApp.onEvent('deviceOrientationChanged', callback);
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Start tracking gyroscope
|
|
475
|
+
* @param {object} [options]
|
|
476
|
+
* @param {number} [options.refresh_rate=100]
|
|
477
|
+
* @returns {boolean}
|
|
478
|
+
*/
|
|
479
|
+
startGyroscope(options = { refresh_rate: 100 }) {
|
|
480
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.startGyroscope) {
|
|
481
|
+
window.Telegram.WebApp.startGyroscope(options);
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
return false;
|
|
485
|
+
},
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Stop tracking gyroscope
|
|
489
|
+
* @returns {boolean}
|
|
490
|
+
*/
|
|
491
|
+
stopGyroscope() {
|
|
492
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.stopGyroscope) {
|
|
493
|
+
window.Telegram.WebApp.stopGyroscope();
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
return false;
|
|
497
|
+
},
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Listen to gyroscope changes
|
|
501
|
+
* @param {function({ x: number, y: number, z: number }): void} callback
|
|
502
|
+
*/
|
|
503
|
+
onGyroscope(callback) {
|
|
504
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.onEvent) {
|
|
505
|
+
window.Telegram.WebApp.onEvent('gyroscopeChanged', callback);
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
},
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Home Screen Shortcut Helpers (Mini Apps 8.0)
|
|
512
|
+
*/
|
|
513
|
+
homeScreen: {
|
|
514
|
+
/**
|
|
515
|
+
* Prompts user to add Mini App shortcut to homescreen
|
|
516
|
+
*/
|
|
517
|
+
addToHomeScreen() {
|
|
518
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.addToHomeScreen) {
|
|
519
|
+
window.Telegram.WebApp.addToHomeScreen();
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
return false;
|
|
523
|
+
},
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Check if shortcut was already added or unsupported
|
|
527
|
+
* @param {function('unsupported'|'unknown'|'added'|'missed'): void} callback
|
|
528
|
+
*/
|
|
529
|
+
checkStatus(callback) {
|
|
530
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.checkHomeScreenStatus) {
|
|
531
|
+
window.Telegram.WebApp.checkHomeScreenStatus(callback);
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Share Prepared Message directly from Mini App (Mini Apps 8.0)
|
|
538
|
+
* @param {string} preparedMessageId - ID obtained via bot.telegram.savePreparedInlineMessage()
|
|
539
|
+
*/
|
|
540
|
+
sharePreparedMessage(preparedMessageId) {
|
|
541
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.shareMessage) {
|
|
542
|
+
window.Telegram.WebApp.shareMessage(preparedMessageId);
|
|
543
|
+
return true;
|
|
544
|
+
}
|
|
545
|
+
return false;
|
|
546
|
+
},
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Prompt user to download a file (Mini Apps 8.0)
|
|
550
|
+
* @param {object} params - { url: string, file_name: string }
|
|
551
|
+
*/
|
|
552
|
+
downloadFile(params) {
|
|
553
|
+
if (typeof window !== 'undefined' && window.Telegram?.WebApp?.downloadFile) {
|
|
554
|
+
window.Telegram.WebApp.downloadFile(params);
|
|
555
|
+
return true;
|
|
556
|
+
}
|
|
557
|
+
return false;
|
|
558
|
+
},
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Haptic Feedback Shortcuts
|
|
562
|
+
*/
|
|
563
|
+
haptics: {
|
|
564
|
+
impact(style = 'medium') {
|
|
565
|
+
window.Telegram?.WebApp?.HapticFeedback?.impactOccurred?.(style);
|
|
566
|
+
},
|
|
567
|
+
notification(type = 'success') {
|
|
568
|
+
window.Telegram?.WebApp?.HapticFeedback?.notificationOccurred?.(type);
|
|
569
|
+
},
|
|
570
|
+
selection() {
|
|
571
|
+
window.Telegram?.WebApp?.HapticFeedback?.selectionChanged?.();
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
};
|