mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
Migrate to Telegram Navigator integration
Replace manual BackButton management with official @telegram-apps/react-router-integration to fix navigation issues (back button cycling and double-click). Changes: - Migrate from @tma.js/sdk-react to @telegram-apps/sdk-react - Downgrade react-router-dom to v6 for package compatibility - Add AppWithNavigator component with Telegram navigator integration - Use browser history mode (hashMode: null) to prevent hash URLs - Add multi-level platform detection (user data, platform, version) - Add try-catch error handling for navigator attach/detach - Simplify useBackButton hook to no-op (navigator handles automatically) - Update vite config with new Telegram packages The navigator automatically manages BackButton based on router history, falling back to BrowserRouter in regular browser environment.
This commit is contained in:
243
package-lock.json
generated
243
package-lock.json
generated
@@ -24,7 +24,8 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"@radix-ui/react-visually-hidden": "^1.2.4",
|
"@radix-ui/react-visually-hidden": "^1.2.4",
|
||||||
"@tanstack/react-query": "^5.8.0",
|
"@tanstack/react-query": "^5.8.0",
|
||||||
"@tma.js/sdk-react": "^3.0.15",
|
"@telegram-apps/react-router-integration": "^1.0.1",
|
||||||
|
"@telegram-apps/sdk-react": "^3.3.9",
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^13.5.0",
|
"react-i18next": "^13.5.0",
|
||||||
"react-router-dom": "^7.13.0",
|
"react-router-dom": "^6.30.3",
|
||||||
"tailwind-merge": "^3.4.0",
|
"tailwind-merge": "^3.4.0",
|
||||||
"zustand": "^4.4.0"
|
"zustand": "^4.4.0"
|
||||||
},
|
},
|
||||||
@@ -2266,6 +2267,15 @@
|
|||||||
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
|
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@remix-run/router": {
|
||||||
|
"version": "1.23.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz",
|
||||||
|
"integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rolldown/pluginutils": {
|
"node_modules/@rolldown/pluginutils": {
|
||||||
"version": "1.0.0-beta.53",
|
"version": "1.0.0-beta.53",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
|
||||||
@@ -2607,47 +2617,60 @@
|
|||||||
"react": "^18 || ^19"
|
"react": "^18 || ^19"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/bridge": {
|
"node_modules/@telegram-apps/bridge": {
|
||||||
"version": "2.2.2",
|
"version": "2.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/bridge/-/bridge-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@telegram-apps/bridge/-/bridge-2.11.0.tgz",
|
||||||
"integrity": "sha512-dL7iZzYP/VC4/qJYSXPI1GXLGP3gLTp10L7iGY6PcjB2F4xXS2JnHUoYvD2DgQG1ogjE93zWnVIMN7inx1v+Eg==",
|
"integrity": "sha512-kBZjWRRp/lxKeQ8r8cDWUY9EjxUtyeh/9xTQjsjuGRsCR5XTO1cyVbvcvqzHn53csGx3aBs+fOR3Pk3b6w2JHg==",
|
||||||
|
"deprecated": "This package is not supported anymore. Use @tma.js/bridge instead",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tma.js/signals": "^1.0.1",
|
"@telegram-apps/signals": "^1.1.2",
|
||||||
"@tma.js/toolkit": "^1.0.4",
|
"@telegram-apps/toolkit": "^2.1.3",
|
||||||
"@tma.js/transformers": "^1.1.3",
|
"@telegram-apps/transformers": "^2.2.6",
|
||||||
"@tma.js/types": "^1.0.2",
|
"@telegram-apps/types": "^2.0.3",
|
||||||
"better-promises": "^1.0.0",
|
"better-promises": "^0.4.1",
|
||||||
"error-kid": "^1.0.2",
|
"error-kid": "^0.0.7",
|
||||||
"fp-ts": "^2.16.11",
|
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"valibot": "^1.1.0"
|
"valibot": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/sdk": {
|
"node_modules/@telegram-apps/navigation": {
|
||||||
"version": "3.1.6",
|
"version": "1.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/sdk/-/sdk-3.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@telegram-apps/navigation/-/navigation-1.0.14.tgz",
|
||||||
"integrity": "sha512-NENkQa7G5N9kwbL20ErUMO9Fukxl9eVhcJ439PbCg2WYMk/x9oNbx2DhEzhX4xM718zSjYejmSj1oXCKk0PxYA==",
|
"integrity": "sha512-bqNgF/J8Po7ZtsELm3E1a6aPr7awwxO3sIqD8J6u12urOlGoW5+1KxKKbkPa58mgXuQdsltd8apI+OVy0IYiUA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@telegram-apps/react-router-integration": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@telegram-apps/react-router-integration/-/react-router-integration-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-q5fC0ihXyUDqrSdLQ3u3gypmjI/rMU2mTHeAz9IU1F1bl5X+J17LxWmgLp+OlD0Y97bq2XYmc+UbKrYh+eN3Wg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"peerDependencies": {
|
||||||
"@tma.js/bridge": "^2.2.2",
|
"@telegram-apps/sdk": "^1",
|
||||||
"@tma.js/signals": "^1.0.1",
|
"@types/react": "^17.0.0 || ^18.0.0",
|
||||||
"@tma.js/toolkit": "^1.0.4",
|
"react": "^17.0.0 || ^18.0.0",
|
||||||
"@tma.js/transformers": "^1.1.3",
|
"react-router-dom": "^6.22.3"
|
||||||
"@tma.js/types": "^1.0.2",
|
},
|
||||||
"better-promises": "^1.0.0",
|
"peerDependenciesMeta": {
|
||||||
"error-kid": "^1.0.2",
|
"@types/react": {
|
||||||
"fp-ts": "^2.16.11",
|
"optional": true
|
||||||
"valibot": "^1.1.0"
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/sdk-react": {
|
"node_modules/@telegram-apps/sdk": {
|
||||||
"version": "3.0.15",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/sdk-react/-/sdk-react-3.0.15.tgz",
|
"resolved": "https://registry.npmjs.org/@telegram-apps/sdk/-/sdk-1.1.3.tgz",
|
||||||
"integrity": "sha512-HsgqPINSBK87NIRZ+ZDol07QPhSQ3GOTofyZEH0xoaQjZWb9wVxUXwECa5ozRUdzWZI+Mgx8oD1pzrjyNkDjFA==",
|
"integrity": "sha512-gvcXNttbCouDNTxjDUbO5FS/BdaHYO0ibSddQxiYitShPIDZDxGon0Eh3OSsgUIVPSQSNdXqkXaeqYgA+jeY0A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@telegram-apps/sdk-react": {
|
||||||
|
"version": "3.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@telegram-apps/sdk-react/-/sdk-react-3.3.9.tgz",
|
||||||
|
"integrity": "sha512-85jF1ICT8sYCNzXu19SqJrfrS8XslsvV14KUcToiyL7H5ZMXHt0JQKM+QJgULjnLjEswweQ4/7Bd7mNULf/BIg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tma.js/sdk": "^3.1.6"
|
"@telegram-apps/sdk": "^3.11.8"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||||
@@ -2659,38 +2682,66 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/signals": {
|
"node_modules/@telegram-apps/sdk-react/node_modules/@telegram-apps/sdk": {
|
||||||
"version": "1.0.1",
|
"version": "3.11.8",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/signals/-/signals-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@telegram-apps/sdk/-/sdk-3.11.8.tgz",
|
||||||
"integrity": "sha512-i2HUuwGqL4BmM5KAklAUhMhlEgUOF+F4nMHHS/zxrmD0upHE/0CiXCEdQxVeeOGN6e2RrKlonA40sDtR6OUDCw==",
|
"integrity": "sha512-vlpkYzMJCV9Cadsn9Q+/hbHNR39j5o96N9z4CjZ6AFHkkxOeOqVRrq9zRBw0gmffROkF2bU0WQxhRj8KZ/bPhw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@telegram-apps/bridge": "^2.11.0",
|
||||||
|
"@telegram-apps/navigation": "^1.0.14",
|
||||||
|
"@telegram-apps/signals": "^1.1.2",
|
||||||
|
"@telegram-apps/toolkit": "^2.1.3",
|
||||||
|
"@telegram-apps/transformers": "^2.2.6",
|
||||||
|
"@telegram-apps/types": "^2.0.3",
|
||||||
|
"better-promises": "^0.4.1",
|
||||||
|
"error-kid": "^0.0.7",
|
||||||
|
"valibot": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@telegram-apps/signals": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@telegram-apps/signals/-/signals-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-1P1kdCLX7MfETGPxH7f3UZKIsdE7Tz5S7QmN4Km1sbYQMakD5Bi1NecSMR7/wnHp50gWMI1JzENcMtCEmouhSg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/toolkit": {
|
"node_modules/@telegram-apps/toolkit": {
|
||||||
"version": "1.0.4",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/toolkit/-/toolkit-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@telegram-apps/toolkit/-/toolkit-2.1.3.tgz",
|
||||||
"integrity": "sha512-6CDlkgc+43WD2jy6jog3B50yt9t+/wRwrN25zOa4iSw4IzfqoFjaQcJzTupBYaRxz19C3Rrir7p0/qStS/Z8vw==",
|
"integrity": "sha512-LPUBL7hxQTOr+Dowyk9a1O82nQS4ja4+OYiYWtvqq5nNUHC6Gbbus0zGWCbFcj9CLnIzaeb5HWOg5iSnhoRcyg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@telegram-apps/transformers": {
|
||||||
|
"version": "2.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@telegram-apps/transformers/-/transformers-2.2.6.tgz",
|
||||||
|
"integrity": "sha512-MMBRs3demeBT9Cd614KKZmak7eEyNdEbfu99a0SwEEJe2oIODjJLrUxrhUcAOc5wvTRfrKka27VXVgruauLhdg==",
|
||||||
|
"deprecated": "This package is not supported anymore. Use @tma.js/transfomers instead",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"better-promises": "^1.0.0",
|
"@telegram-apps/toolkit": "^2.1.3",
|
||||||
"fp-ts": "^2.16.11"
|
"@telegram-apps/types": "^2.0.3",
|
||||||
|
"valibot": "1.0.0-beta.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/transformers": {
|
"node_modules/@telegram-apps/transformers/node_modules/valibot": {
|
||||||
"version": "1.1.3",
|
"version": "1.0.0-beta.14",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/transformers/-/transformers-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.14.tgz",
|
||||||
"integrity": "sha512-zRL+fdo/NBpGqCJfl8ItAvcJIFT5Zy6UOYJwQPmUV5/gTHgmSvmGlrP43PeVi9XZ7Ggf4xbO6LUa4ehxozhMTA==",
|
"integrity": "sha512-tLyV2rE5QL6U29MFy3xt4AqMrn+/HErcp2ZThASnQvPMwfSozjV1uBGKIGiegtZIGjinJqn0SlBdannf18wENA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"peerDependencies": {
|
||||||
"@tma.js/toolkit": "^1.0.4",
|
"typescript": ">=5"
|
||||||
"@tma.js/types": "^1.0.2",
|
},
|
||||||
"fp-ts": "^2.16.11",
|
"peerDependenciesMeta": {
|
||||||
"valibot": "^1.1.0"
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tma.js/types": {
|
"node_modules/@telegram-apps/types": {
|
||||||
"version": "1.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@tma.js/types/-/types-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@telegram-apps/types/-/types-2.0.3.tgz",
|
||||||
"integrity": "sha512-qs4mi+U1xZmMQBdMhWAo1X4YqUJ/ae0y28s+GNCpQq58bsJo0h8rvyVOB1RwPvXogIY9+yribbZe6z3AIJmsAQ==",
|
"integrity": "sha512-pXh9BdnLZF3e2BGc4WL+RTRMAUpqKpaSP3Rs8rB4WyRwIoRSGWFKE4gtT/9m42LGixB8YVwdo/pJ+9XO765XEA==",
|
||||||
|
"deprecated": "This package is not supported anymore. Use @tma.js/types instead",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
@@ -3282,12 +3333,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/better-promises": {
|
"node_modules/better-promises": {
|
||||||
"version": "1.0.0",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/better-promises/-/better-promises-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/better-promises/-/better-promises-0.4.1.tgz",
|
||||||
"integrity": "sha512-gPgL2nRgeSbMIe3QpsYdKR3K0S9OZuphVuos60Eqsw8d/6GivOkyJ5D/zmnolJ6hzh7upnnflBUWUlQh4qpU2A==",
|
"integrity": "sha512-cDW7eMvhvCoWzSih5o/OxsAgTUfP05yGMq77xNZUTmcZoNU9vEeFZJ+yJJi4lnocvxFrVFKsG0Yxt7ZnuYJEig==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"error-kid": "^1.0.1"
|
"error-kid": "^0.0.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
@@ -3604,19 +3655,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/cookie": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/express"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
@@ -3757,9 +3795,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/error-kid": {
|
"node_modules/error-kid": {
|
||||||
"version": "1.0.2",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/error-kid/-/error-kid-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/error-kid/-/error-kid-0.0.7.tgz",
|
||||||
"integrity": "sha512-Xvq0ZrY/azCbREWKt9E/3mXDF0MkuEVVvHnOKutUhtq2O8pyneEixQ4nSFkA19Xfn+/OVSg//iVG0dxIDj7DIA==",
|
"integrity": "sha512-8mFs7ZaDWlBFgjOy4lHLMCe2+KZfZXGx5GOgh2VQ/M1CCIvSWzbl2OMl+5fdZgrgoUfhTeF+NPhmqfEvUhN8yw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/es-define-property": {
|
"node_modules/es-define-property": {
|
||||||
@@ -4241,12 +4279,6 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fp-ts": {
|
|
||||||
"version": "2.16.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.16.11.tgz",
|
|
||||||
"integrity": "sha512-LaI+KaX2NFkfn1ZGHoKCmcfv7yrZsC3b8NtWsTVQeHkq4F27vI5igUuO53sxqDEa2gNQMHFPmpojDw/1zmUK7w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/fraction.js": {
|
"node_modules/fraction.js": {
|
||||||
"version": "5.3.4",
|
"version": "5.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
|
||||||
@@ -5679,41 +5711,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router": {
|
||||||
"version": "7.13.0",
|
"version": "6.30.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz",
|
||||||
"integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==",
|
"integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "^1.0.1",
|
"@remix-run/router": "1.23.2"
|
||||||
"set-cookie-parser": "^2.6.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0"
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=18",
|
"react": ">=16.8"
|
||||||
"react-dom": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"react-dom": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom": {
|
"node_modules/react-router-dom": {
|
||||||
"version": "7.13.0",
|
"version": "6.30.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz",
|
||||||
"integrity": "sha512-5CO/l5Yahi2SKC6rGZ+HDEjpjkGaG/ncEP7eWFTvFxbHP8yeeI0PxTDjimtpXYlR3b3i9/WIL4VJttPrESIf2g==",
|
"integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react-router": "7.13.0"
|
"@remix-run/router": "1.23.2",
|
||||||
|
"react-router": "6.30.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20.0.0"
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=18",
|
"react": ">=16.8",
|
||||||
"react-dom": ">=18"
|
"react-dom": ">=16.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-style-singleton": {
|
"node_modules/react-style-singleton": {
|
||||||
@@ -5915,12 +5942,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/set-cookie-parser": {
|
|
||||||
"version": "2.7.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
|
|
||||||
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/shebang-command": {
|
"node_modules/shebang-command": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
@@ -6414,9 +6435,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/valibot": {
|
"node_modules/valibot": {
|
||||||
"version": "1.2.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0.tgz",
|
||||||
"integrity": "sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==",
|
"integrity": "sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": ">=5"
|
"typescript": ">=5"
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.2.8",
|
"@radix-ui/react-tooltip": "^1.2.8",
|
||||||
"@radix-ui/react-visually-hidden": "^1.2.4",
|
"@radix-ui/react-visually-hidden": "^1.2.4",
|
||||||
"@tanstack/react-query": "^5.8.0",
|
"@tanstack/react-query": "^5.8.0",
|
||||||
"@tma.js/sdk-react": "^3.0.15",
|
"@telegram-apps/react-router-integration": "^1.0.1",
|
||||||
|
"@telegram-apps/sdk-react": "^3.3.9",
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
@@ -45,7 +46,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-i18next": "^13.5.0",
|
"react-i18next": "^13.5.0",
|
||||||
"react-router-dom": "^7.13.0",
|
"react-router-dom": "^6.30.3",
|
||||||
"tailwind-merge": "^3.4.0",
|
"tailwind-merge": "^3.4.0",
|
||||||
"zustand": "^4.4.0"
|
"zustand": "^4.4.0"
|
||||||
},
|
},
|
||||||
|
|||||||
102
src/AppWithNavigator.tsx
Normal file
102
src/AppWithNavigator.tsx
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { useEffect, useMemo } from 'react';
|
||||||
|
import { BrowserRouter, Router } from 'react-router-dom';
|
||||||
|
import { useIntegration } from '@telegram-apps/react-router-integration';
|
||||||
|
import { initNavigator } from '@telegram-apps/sdk';
|
||||||
|
import App from './App';
|
||||||
|
import { PlatformProvider } from './platform/PlatformProvider';
|
||||||
|
import { ThemeColorsProvider } from './providers/ThemeColorsProvider';
|
||||||
|
import { WebSocketProvider } from './providers/WebSocketProvider';
|
||||||
|
import { ToastProvider } from './components/Toast';
|
||||||
|
import { TooltipProvider } from './components/primitives/Tooltip';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if running inside Telegram Mini App
|
||||||
|
* Uses multiple checks to reliably detect Telegram environment
|
||||||
|
*/
|
||||||
|
function isTelegramMiniApp(): boolean {
|
||||||
|
if (typeof window === 'undefined') return false;
|
||||||
|
|
||||||
|
const webApp = window.Telegram?.WebApp;
|
||||||
|
if (!webApp) return false;
|
||||||
|
|
||||||
|
// Check 1: initDataUnsafe should have user data in real Telegram
|
||||||
|
const hasUserData = webApp.initDataUnsafe?.user?.id !== undefined;
|
||||||
|
|
||||||
|
// Check 2: Platform should not be 'unknown' (which is default in browser)
|
||||||
|
const validPlatform = webApp.platform !== 'unknown' && webApp.platform !== '';
|
||||||
|
|
||||||
|
// Check 3: Version should be present (SDK loads in Telegram only)
|
||||||
|
const hasVersion = webApp.version !== undefined && webApp.version !== '';
|
||||||
|
|
||||||
|
return hasUserData || (validPlatform && hasVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component wrapper for Telegram navigator setup.
|
||||||
|
* Integrates Telegram Mini Apps navigator with React Router to provide
|
||||||
|
* automatic BackButton management based on navigation history.
|
||||||
|
* Falls back to BrowserRouter when not in Telegram Mini App.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Navigator-based router for Telegram Mini App
|
||||||
|
*/
|
||||||
|
function TelegramRouter({ children }: { children: React.ReactNode }) {
|
||||||
|
const navigator = useMemo(() => initNavigator('app-navigation-state', { hashMode: null }), []);
|
||||||
|
const [location, reactNavigator] = useIntegration(navigator);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
navigator.attach();
|
||||||
|
return () => {
|
||||||
|
try {
|
||||||
|
navigator.detach();
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Failed to detach navigator:', err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Failed to attach navigator:', err);
|
||||||
|
}
|
||||||
|
}, [navigator]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Router location={location} navigator={reactNavigator}>
|
||||||
|
{children}
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AppWithNavigator() {
|
||||||
|
const isTelegram = useMemo(() => {
|
||||||
|
const result = isTelegramMiniApp();
|
||||||
|
console.log('[AppWithNavigator] Platform detection:', {
|
||||||
|
isTelegram: result,
|
||||||
|
platform: window.Telegram?.WebApp?.platform,
|
||||||
|
hasUser: window.Telegram?.WebApp?.initDataUnsafe?.user?.id !== undefined,
|
||||||
|
version: window.Telegram?.WebApp?.version,
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Common app content
|
||||||
|
const appContent = (
|
||||||
|
<PlatformProvider>
|
||||||
|
<ThemeColorsProvider>
|
||||||
|
<TooltipProvider>
|
||||||
|
<ToastProvider>
|
||||||
|
<WebSocketProvider>
|
||||||
|
<App />
|
||||||
|
</WebSocketProvider>
|
||||||
|
</ToastProvider>
|
||||||
|
</TooltipProvider>
|
||||||
|
</ThemeColorsProvider>
|
||||||
|
</PlatformProvider>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use Telegram navigator in Mini App, BrowserRouter elsewhere
|
||||||
|
if (isTelegram) {
|
||||||
|
return <TelegramRouter>{appContent}</TelegramRouter>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <BrowserRouter>{appContent}</BrowserRouter>;
|
||||||
|
}
|
||||||
22
src/main.tsx
22
src/main.tsx
@@ -1,13 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import App from './App';
|
import { AppWithNavigator } from './AppWithNavigator';
|
||||||
import { PlatformProvider } from './platform/PlatformProvider';
|
|
||||||
import { ThemeColorsProvider } from './providers/ThemeColorsProvider';
|
|
||||||
import { WebSocketProvider } from './providers/WebSocketProvider';
|
|
||||||
import { ToastProvider } from './components/Toast';
|
|
||||||
import { TooltipProvider } from './components/primitives/Tooltip';
|
|
||||||
import { initLogoPreload } from './api/branding';
|
import { initLogoPreload } from './api/branding';
|
||||||
import { initTelegramSDK } from './hooks/useTelegramSDK';
|
import { initTelegramSDK } from './hooks/useTelegramSDK';
|
||||||
import './i18n';
|
import './i18n';
|
||||||
@@ -31,19 +25,7 @@ const queryClient = new QueryClient({
|
|||||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<BrowserRouter>
|
<AppWithNavigator />
|
||||||
<PlatformProvider>
|
|
||||||
<ThemeColorsProvider>
|
|
||||||
<TooltipProvider>
|
|
||||||
<ToastProvider>
|
|
||||||
<WebSocketProvider>
|
|
||||||
<App />
|
|
||||||
</WebSocketProvider>
|
|
||||||
</ToastProvider>
|
|
||||||
</TooltipProvider>
|
|
||||||
</ThemeColorsProvider>
|
|
||||||
</PlatformProvider>
|
|
||||||
</BrowserRouter>
|
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import { useEffect, useRef, useCallback } from 'react';
|
|
||||||
import { usePlatform } from '@/platform/hooks/usePlatform';
|
|
||||||
|
|
||||||
interface UseBackButtonOptions {
|
interface UseBackButtonOptions {
|
||||||
/**
|
/**
|
||||||
* Whether the back button should be visible
|
* Whether the back button should be visible
|
||||||
@@ -11,65 +8,46 @@ interface UseBackButtonOptions {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to manage the Telegram BackButton
|
* Hook to manage the Telegram BackButton
|
||||||
* Automatically shows/hides based on component lifecycle
|
|
||||||
*
|
*
|
||||||
* @param onBack - Callback when back button is pressed
|
* NOTE: This hook is now a no-op for backward compatibility.
|
||||||
* @param options - Configuration options
|
* The Telegram Navigator (@telegram-apps/react-router-integration) handles
|
||||||
|
* BackButton visibility and navigation automatically based on router history.
|
||||||
|
*
|
||||||
|
* The navigator:
|
||||||
|
* - Shows BackButton when there's navigation history
|
||||||
|
* - Hides BackButton on root page
|
||||||
|
* - Handles back button clicks automatically
|
||||||
|
*
|
||||||
|
* @param onBack - (Ignored) Callback when back button is pressed
|
||||||
|
* @param options - (Ignored) Configuration options
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```tsx
|
* ```tsx
|
||||||
* function MyPage() {
|
* function MyPage() {
|
||||||
* const navigate = useNavigate();
|
* const navigate = useNavigate();
|
||||||
* useBackButton(() => navigate(-1));
|
* useBackButton(() => navigate('/admin')); // No-op: navigator handles this
|
||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function useBackButton(
|
export function useBackButton(
|
||||||
onBack: (() => void) | null | undefined,
|
_onBack: (() => void) | null | undefined,
|
||||||
options: UseBackButtonOptions = {},
|
_options: UseBackButtonOptions = {},
|
||||||
): void {
|
): void {
|
||||||
const { backButton, capabilities } = usePlatform();
|
// No-op: Navigator handles BackButton automatically
|
||||||
const { visible = true } = options;
|
return;
|
||||||
|
|
||||||
// Use ref to prevent callback recreation issues
|
|
||||||
const callbackRef = useRef(onBack);
|
|
||||||
callbackRef.current = onBack;
|
|
||||||
|
|
||||||
// Stable callback wrapper
|
|
||||||
const handleBack = useCallback(() => {
|
|
||||||
callbackRef.current?.();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// If no native back button support, do nothing
|
|
||||||
if (!capabilities.hasBackButton) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If callback is null/undefined or visible is false, hide button
|
|
||||||
if (!onBack || !visible) {
|
|
||||||
backButton.hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show the back button with our handler
|
|
||||||
backButton.show(handleBack);
|
|
||||||
|
|
||||||
// Cleanup: hide button when component unmounts
|
|
||||||
return () => {
|
|
||||||
backButton.hide();
|
|
||||||
};
|
|
||||||
}, [backButton, capabilities.hasBackButton, handleBack, onBack, visible]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to conditionally show back button based on navigation depth
|
* Hook to conditionally show back button based on navigation depth
|
||||||
* Useful for showing back button only when there's history to go back to
|
|
||||||
*
|
*
|
||||||
* @param canGoBack - Whether navigation back is possible
|
* NOTE: This hook is now a no-op for backward compatibility.
|
||||||
* @param onBack - Callback when back button is pressed
|
* The navigator handles conditional visibility automatically.
|
||||||
|
*
|
||||||
|
* @param canGoBack - (Ignored) Whether navigation back is possible
|
||||||
|
* @param onBack - (Ignored) Callback when back button is pressed
|
||||||
*/
|
*/
|
||||||
export function useConditionalBackButton(canGoBack: boolean, onBack: () => void): void {
|
export function useConditionalBackButton(_canGoBack: boolean, _onBack: () => void): void {
|
||||||
useBackButton(canGoBack ? onBack : null);
|
// No-op: Navigator handles BackButton automatically
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,11 @@ export default defineConfig({
|
|||||||
'@radix-ui/react-visually-hidden',
|
'@radix-ui/react-visually-hidden',
|
||||||
],
|
],
|
||||||
'vendor-dnd': ['@dnd-kit/core', '@dnd-kit/sortable', '@dnd-kit/utilities'],
|
'vendor-dnd': ['@dnd-kit/core', '@dnd-kit/sortable', '@dnd-kit/utilities'],
|
||||||
'vendor-telegram': ['@tma.js/sdk-react'],
|
'vendor-telegram': [
|
||||||
|
'@telegram-apps/sdk',
|
||||||
|
'@telegram-apps/sdk-react',
|
||||||
|
'@telegram-apps/react-router-integration',
|
||||||
|
],
|
||||||
'vendor-utils': [
|
'vendor-utils': [
|
||||||
'axios',
|
'axios',
|
||||||
'zustand',
|
'zustand',
|
||||||
|
|||||||
Reference in New Issue
Block a user