Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve telegram mini app #1472

Merged
merged 14 commits into from
Jul 29, 2024
Merged
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@cedelabs/widgets-universal": "^1.3.1",
"@metamask/detect-provider": "^2.0.0",
"@soramitsu/soraneo-wallet-web": "1.39.2",
"@tma.js/sdk": "^2.7.0",
"@telegram-apps/sdk": "^1.1.3",
"@walletconnect/ethereum-provider": "^2.13.3",
"@walletconnect/modal": "^2.6.2",
"core-js": "^3.37.1",
Expand Down
13 changes: 2 additions & 11 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import {
initWallet,
waitForCore,
} from '@soramitsu/soraneo-wallet-web';
import { isTMA } from '@tma.js/sdk';
import debounce from 'lodash/debounce';
import { Component, Mixins, Watch } from 'vue-property-decorator';

Expand All @@ -68,7 +67,7 @@ import router, { goTo, lazyComponent } from '@/router';
import { action, getter, mutation, state } from '@/store/decorators';
import { getMobileCssClasses, preloadFontFace, updateDocumentTitle } from '@/utils';
import type { NodesConnection } from '@/utils/connection';
import { TmaSdk } from '@/utils/telegram';
import { tmaSdkService } from '@/utils/telegram';

import type { FeatureFlags } from './store/settings/types';
import type { EthBridgeSettings, SubNetworkApps } from './store/web3/types';
Expand Down Expand Up @@ -155,10 +154,6 @@ export default class App extends Mixins(mixins.TransactionMixin, NodeErrorMixin)

@state.wallet.transactions.isSignTxDialogVisible public isSignTxDialogVisible!: boolean;
@mutation.wallet.transactions.setSignTxDialogVisibility public setSignTxDialogVisibility!: (flag: boolean) => void;
// [DESKTOP] To Enable Desktop
@mutation.wallet.account.setIsDesktop private setIsDesktop!: (v: boolean) => void;
// [TMA] To Enable TMA
@mutation.settings.enableTMA private enableTMA!: FnWithoutArgs;

@Watch('assetsToNotifyQueue')
private handleNotifyOnDeposit(whitelistAssetArray: WhitelistArrayItem[]): void {
Expand Down Expand Up @@ -235,11 +230,7 @@ export default class App extends Mixins(mixins.TransactionMixin, NodeErrorMixin)
}

// To start running as Telegram Web App (desktop capabilities)
if (await isTMA()) {
this.enableTMA();
this.setIsDesktop(true);
await TmaSdk.init(data?.TG_BOT_URL, data.NETWORK_TYPE === WALLET_CONSTS.SoraNetwork.Dev);
}
await tmaSdkService.init(data?.TG_BOT_URL, data.NETWORK_TYPE === WALLET_CONSTS.SoraNetwork.Dev);

await this.setApiKeys(data?.API_KEYS);
await this.setEthBridgeSettings(data.ETH_BRIDGE);
Expand Down
106 changes: 91 additions & 15 deletions src/utils/telegram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,64 @@ import {
isIframe,
retrieveLaunchParams,
initUtils,
initSwipeBehavior,
isTMA,
initHapticFeedback,
type MiniApp,
type LaunchParams,
type Utils,
type Viewport,
} from '@tma.js/sdk';
type SwipeBehavior,
type HapticFeedback,
type ImpactHapticFeedbackStyle,
type NotificationHapticFeedbackType,
} from '@telegram-apps/sdk';

import store from '@/store';

export class TmaSdk {
public static miniApp: MiniApp;
public static launchParams: LaunchParams;
public static viewport: Nullable<Viewport>;
private static utils: Utils;
export type HapticFeedbackBinding = ImpactHapticFeedbackStyle | NotificationHapticFeedbackType;

public static async init(botUrl?: string, isDebug = false): Promise<void> {
const HapticNotificationTypes = ['success', 'warning', 'error'];

function isNotification(value: HapticFeedbackBinding): value is NotificationHapticFeedbackType {
return HapticNotificationTypes.includes(value);
}

class TmaSdk {
public miniApp: Nullable<MiniApp>;
public viewport: Nullable<Viewport>;
public launchParams: Nullable<LaunchParams>;
public swipeBehavior: Nullable<SwipeBehavior>;
private utils: Nullable<Utils>;
private hapticFeedback: Nullable<HapticFeedback>;

public async init(botUrl?: string, isDebug = false): Promise<void> {
try {
// Check if the current platform is Telegram Mini App
const isTma = await isTMA();
if (!isTma) {
console.info('[TMA]: initTMA: Not a Telegram Mini App');
RustemYuzlibaev marked this conversation as resolved.
Show resolved Hide resolved
return;
}
store.commit.settings.enableTMA();
store.commit.wallet.account.setIsDesktop(true);
// Initialize the app in the web version of Telegram
if (isIframe()) {
initWeb();
console.info('[TMA]: initTMA: Web version of Telegram');
}
// Init viewport
// Init viewport and expand it to the full screen
await this.initViewport();
this.viewport?.expand();
// Init mini app
const [miniApp] = initMiniApp();
this.miniApp = miniApp;
console.info('[TMA]: Mini app was initialized');
// Set theme
this.updateTheme();
// Init swipe behavior and disable vertical swipe
this.initSwipeBehavior();
this.swipeBehavior?.disableVerticalSwipe();
// Enable debugging
setDebug(isDebug);
// Retrieve launch params
Expand All @@ -47,6 +76,8 @@ export class TmaSdk {
if (botUrl) {
store.commit.settings.setTelegramBotUrl(botUrl);
}
// Init haptic feedback
this.initHapticFeedback();
// Init utils
this.utils = initUtils();
console.info('[TMA]: Utils were initialized');
Expand All @@ -60,28 +91,49 @@ export class TmaSdk {
*
* Update the theme of the Telegram Mini App using `var(--s-color-utility-body)`
*/
public static updateTheme(): void {
public updateTheme(): void {
try {
const colorUtilityBody =
(getComputedStyle(document.documentElement).getPropertyValue('--s-color-utility-body') as `#${string}`) ||
'#f7f3f4'; // Default color

this.miniApp.setHeaderColor(colorUtilityBody);
this.miniApp.setBgColor(colorUtilityBody);
this.miniApp?.setHeaderColor(colorUtilityBody);
this.miniApp?.setBgColor(colorUtilityBody);
} catch (error) {
console.warn('[TMA]: updateTheme', error);
}
}

public static shareLink(url: string, text?: string): void {
public shareLink(url: string, text?: string): void {
try {
this.utils.shareURL(url, text ? encodeURIComponent(text) : text);
this.utils?.shareURL(url, text ? encodeURIComponent(text) : text);
} catch (error) {
console.warn('[TMA]: shareLink', error);
}
}

private static async initViewport(): Promise<void> {
public useHaptic(type: HapticFeedbackBinding): void {
if (!this.hapticFeedback) {
return;
}
try {
if (isNotification(type)) {
this.hapticFeedback?.notificationOccurred(type);
return;
}
if (this.launchParams?.platform.startsWith('android')) {
// 'android' | 'android_x'
// Android doesn't support different types of haptic feedback except notifications
this.hapticFeedback?.notificationOccurred('success');
} else {
this.hapticFeedback?.impactOccurred(type);
}
} catch (error) {
console.warn('[TMA]: useHapticFeedback', error);
}
}

private async initViewport(): Promise<void> {
try {
const [viewport] = initViewport();
this.viewport = await viewport;
Expand All @@ -91,10 +143,34 @@ export class TmaSdk {
}
}

private static setReferrer(referrerAddress?: string): void {
private initSwipeBehavior(): void {
try {
const [swipeBehavior] = initSwipeBehavior();
this.swipeBehavior = swipeBehavior;
console.info('[TMA]: Swipe behavior was initialized');
} catch (error) {
console.warn('[TMA]: initSwipeBehavior', error);
}
}

private initHapticFeedback(): void {
try {
const hapticFeedback = initHapticFeedback();
this.hapticFeedback = hapticFeedback;
console.info('[TMA]: Haptic feedback was initialized');
} catch (error) {
console.warn('[TMA]: initHapticFeedback', error);
}
}

private setReferrer(referrerAddress?: string): void {
if (referrerAddress && api.validateAddress(referrerAddress)) {
store.commit.referrals.setStorageReferrer(referrerAddress);
console.info('[TMA]: Referrer was set', referrerAddress);
}
}
}

const tmaSdkService = new TmaSdk();

export { tmaSdkService };
34 changes: 28 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1970,8 +1970,7 @@
"@polkadot/util-crypto" "^10.4.2"
rxjs "^7.8.0"

"@polkadot/[email protected]", "polkadotApi@npm:@polkadot/[email protected]":
name polkadotApi
"@polkadot/[email protected]":
version "11.2.1"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-11.2.1.tgz#b19a8e22367703333e71f3613095f76f0dbbca70"
integrity sha512-NwcWadMt+mrJ3T7RuwpnaIYtH4x0eix+GiKRtLMtIO32uAfhwVyMnqvLtxDxa4XDJ/es2rtSMYG+t0b1BTM+xQ==
Expand Down Expand Up @@ -3081,10 +3080,10 @@
dependencies:
defer-to-connect "^2.0.0"

"@tma.js/sdk@^2.7.0":
version "2.7.0"
resolved "https://registry.yarnpkg.com/@tma.js/sdk/-/sdk-2.7.0.tgz#1ae1fa6e5b21f6a5d959328ba84096bf5e6cc910"
integrity sha512-LRuJdoEbAqKmSYccvXx5emSnye2je8oIbBVPtV+BmcNoa/dCZ0gFVkaeuyBqzroGtfGDyGO/WebU54ie5MKmCQ==
"@telegram-apps/sdk@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@telegram-apps/sdk/-/sdk-1.1.3.tgz#e536b59968804ca3c29eacd7c29749221c6a32df"
integrity sha512-gvcXNttbCouDNTxjDUbO5FS/BdaHYO0ibSddQxiYitShPIDZDxGon0Eh3OSsgUIVPSQSNdXqkXaeqYgA+jeY0A==

"@tootallnate/once@1":
version "1.1.2"
Expand Down Expand Up @@ -12133,6 +12132,29 @@ pngjs@^5.0.0:
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==

"polkadotApi@npm:@polkadot/[email protected]":
version "11.2.1"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-11.2.1.tgz#b19a8e22367703333e71f3613095f76f0dbbca70"
integrity sha512-NwcWadMt+mrJ3T7RuwpnaIYtH4x0eix+GiKRtLMtIO32uAfhwVyMnqvLtxDxa4XDJ/es2rtSMYG+t0b1BTM+xQ==
dependencies:
"@polkadot/api-augment" "11.2.1"
"@polkadot/api-base" "11.2.1"
"@polkadot/api-derive" "11.2.1"
"@polkadot/keyring" "^12.6.2"
"@polkadot/rpc-augment" "11.2.1"
"@polkadot/rpc-core" "11.2.1"
"@polkadot/rpc-provider" "11.2.1"
"@polkadot/types" "11.2.1"
"@polkadot/types-augment" "11.2.1"
"@polkadot/types-codec" "11.2.1"
"@polkadot/types-create" "11.2.1"
"@polkadot/types-known" "11.2.1"
"@polkadot/util" "^12.6.2"
"@polkadot/util-crypto" "^12.6.2"
eventemitter3 "^5.0.1"
rxjs "^7.8.1"
tslib "^2.6.2"

portfinder@^1.0.26:
version "1.0.32"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.32.tgz#2fe1b9e58389712429dc2bea5beb2146146c7f81"
Expand Down