react update
This commit is contained in:
parent
65a143ef4d
commit
6fbe286ca2
@ -1,8 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDemoMode, getDemoWebApp } from '../utils/demo';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import type { WebApp } from '@twa-dev/types';
|
||||
import { isDemoMode, getDemoWebApp } from '../utils/demo';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@ -12,84 +12,68 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
type SafeWebApp = Partial<Pick<WebApp,
|
||||
| 'initData'
|
||||
| 'initDataUnsafe'
|
||||
| 'platform'
|
||||
| 'colorScheme'
|
||||
| 'themeParams'
|
||||
| 'isExpanded'
|
||||
| 'viewportHeight'
|
||||
| 'viewportStableHeight'
|
||||
| 'headerColor'
|
||||
| 'backgroundColor'
|
||||
| 'isClosingConfirmationEnabled'
|
||||
| 'BackButton'
|
||||
| 'MainButton'
|
||||
| 'ready'
|
||||
| 'expand'
|
||||
| 'close'
|
||||
>>;
|
||||
export interface UseTelegramWebAppResult {
|
||||
webApp: WebApp | null;
|
||||
error: Error | null;
|
||||
isLoading: boolean;
|
||||
isInitialized: boolean;
|
||||
}
|
||||
|
||||
export function useTelegramWebApp() {
|
||||
const [webApp, setWebApp] = useState<SafeWebApp | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
export function useTelegramWebApp(): UseTelegramWebAppResult {
|
||||
const [webApp, setWebApp] = useState<WebApp | null>(null);
|
||||
const [error, setError] = useState<Error | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
const initWebApp = useCallback(async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
|
||||
const initWebApp = async () => {
|
||||
try {
|
||||
if (isDemoMode()) {
|
||||
if (isMounted) {
|
||||
const demoWebApp = getDemoWebApp();
|
||||
setWebApp(demoWebApp);
|
||||
setIsInitialized(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isDemoMode()) {
|
||||
const demoWebApp = getDemoWebApp();
|
||||
setWebApp(demoWebApp);
|
||||
setIsInitialized(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
// Проверяем наличие Telegram WebApp в глобальном объекте
|
||||
if (window.Telegram?.WebApp) {
|
||||
if (isMounted) {
|
||||
setWebApp(window.Telegram.WebApp as SafeWebApp);
|
||||
setIsInitialized(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Если WebApp не найден в глобальном объекте, пробуем импортировать SDK
|
||||
const WebAppModule = await import('@twa-dev/sdk');
|
||||
if (isMounted && WebAppModule.default) {
|
||||
setWebApp(WebAppModule.default as SafeWebApp);
|
||||
setIsInitialized(true);
|
||||
} else {
|
||||
throw new Error('WebApp не найден');
|
||||
}
|
||||
} catch (importError) {
|
||||
console.error('SDK import error:', importError);
|
||||
throw new Error('Ошибка импорта Telegram Web App SDK');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('WebApp initialization error:', err);
|
||||
if (isMounted) {
|
||||
setError('Ошибка инициализации Telegram Web App');
|
||||
if (typeof window !== 'undefined') {
|
||||
if (window.Telegram?.WebApp) {
|
||||
setWebApp(window.Telegram.WebApp);
|
||||
setIsInitialized(true);
|
||||
} else {
|
||||
throw new Error('Telegram WebApp не найден');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Ошибка инициализации WebApp:', err);
|
||||
setError(err instanceof Error ? err : new Error('Неизвестная ошибка'));
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
initWebApp();
|
||||
}, [initWebApp]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!webApp) return;
|
||||
|
||||
const handleThemeChange = () => {
|
||||
// Обновляем состояние при изменении темы
|
||||
setWebApp(prevWebApp => {
|
||||
if (!prevWebApp) return null;
|
||||
return { ...prevWebApp };
|
||||
});
|
||||
};
|
||||
|
||||
if (!isInitialized) {
|
||||
initWebApp();
|
||||
}
|
||||
webApp.onEvent('themeChanged', handleThemeChange);
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
webApp.offEvent('themeChanged', handleThemeChange);
|
||||
};
|
||||
}, [isInitialized]);
|
||||
}, [webApp]);
|
||||
|
||||
return { webApp, error, isInitialized };
|
||||
return { webApp, error, isLoading, isInitialized };
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import type { WebApp, WebAppUser, WebAppInitData, Platforms } from '@twa-dev/types';
|
||||
import type { WebApp, WebAppUser, WebAppInitData, Platforms, HapticFeedback } from '@twa-dev/types';
|
||||
|
||||
// Демо данные для тестирования без Telegram
|
||||
const demoUser: WebAppUser = {
|
||||
@ -28,26 +28,14 @@ export const isDemoMode = () => {
|
||||
// Создаем заглушки для методов WebApp
|
||||
const createNoopFunction = () => () => {};
|
||||
|
||||
type SafeWebApp = Pick<WebApp,
|
||||
| 'initData'
|
||||
| 'initDataUnsafe'
|
||||
| 'platform'
|
||||
| 'colorScheme'
|
||||
| 'themeParams'
|
||||
| 'isExpanded'
|
||||
| 'viewportHeight'
|
||||
| 'viewportStableHeight'
|
||||
| 'headerColor'
|
||||
| 'backgroundColor'
|
||||
| 'isClosingConfirmationEnabled'
|
||||
| 'BackButton'
|
||||
| 'MainButton'
|
||||
| 'ready'
|
||||
| 'expand'
|
||||
| 'close'
|
||||
>;
|
||||
// Создаем заглушку для HapticFeedback
|
||||
const demoHapticFeedback: HapticFeedback = {
|
||||
impactOccurred: (_style: "light" | "medium" | "heavy" | "rigid" | "soft") => demoHapticFeedback,
|
||||
notificationOccurred: (_type: "error" | "success" | "warning") => demoHapticFeedback,
|
||||
selectionChanged: () => demoHapticFeedback
|
||||
};
|
||||
|
||||
export const getDemoWebApp = (): SafeWebApp => ({
|
||||
export const getDemoWebApp = (): WebApp => ({
|
||||
initData: JSON.stringify(demoInitData),
|
||||
initDataUnsafe: demoInitData,
|
||||
platform: 'WEBVIEW' as Platforms,
|
||||
@ -92,6 +80,36 @@ export const getDemoWebApp = (): SafeWebApp => ({
|
||||
hideProgress: createNoopFunction(),
|
||||
setParams: createNoopFunction()
|
||||
},
|
||||
HapticFeedback: demoHapticFeedback,
|
||||
CloudStorage: {
|
||||
setItem: createNoopFunction(),
|
||||
getItem: createNoopFunction(),
|
||||
getItems: createNoopFunction(),
|
||||
removeItem: createNoopFunction(),
|
||||
removeItems: createNoopFunction(),
|
||||
getKeys: createNoopFunction()
|
||||
},
|
||||
version: '7.0',
|
||||
isVersionAtLeast: (version: string) => true,
|
||||
setHeaderColor: createNoopFunction(),
|
||||
setBackgroundColor: createNoopFunction(),
|
||||
enableClosingConfirmation: createNoopFunction(),
|
||||
disableClosingConfirmation: createNoopFunction(),
|
||||
onEvent: createNoopFunction(),
|
||||
offEvent: createNoopFunction(),
|
||||
sendData: createNoopFunction(),
|
||||
switchInlineQuery: createNoopFunction(),
|
||||
openLink: createNoopFunction(),
|
||||
openTelegramLink: createNoopFunction(),
|
||||
openInvoice: createNoopFunction(),
|
||||
showPopup: createNoopFunction(),
|
||||
showAlert: createNoopFunction(),
|
||||
showConfirm: createNoopFunction(),
|
||||
showScanQrPopup: createNoopFunction(),
|
||||
closeScanQrPopup: createNoopFunction(),
|
||||
readTextFromClipboard: createNoopFunction(),
|
||||
requestWriteAccess: createNoopFunction(),
|
||||
requestContact: createNoopFunction(),
|
||||
ready: createNoopFunction(),
|
||||
expand: createNoopFunction(),
|
||||
close: createNoopFunction(),
|
||||
|
20
next.config.js
Normal file
20
next.config.js
Normal file
@ -0,0 +1,20 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
swcMinify: true,
|
||||
output: 'standalone',
|
||||
experimental: {
|
||||
serverActions: {
|
||||
allowedOrigins: ['telegram.org', 't.me'],
|
||||
},
|
||||
},
|
||||
webpack: (config) => {
|
||||
config.externals.push({
|
||||
'utf-8-validate': 'commonjs utf-8-validate',
|
||||
'bufferutil': 'commonjs bufferutil',
|
||||
});
|
||||
return config;
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
31
package.json
31
package.json
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "campfire-id",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Telegram Mini App for user achievements and virtual economy",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@ -9,30 +10,34 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/react": "^2.8.1",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@chakra-ui/next-js": "^2.2.0",
|
||||
"@chakra-ui/react": "^2.8.2",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@twa-dev/sdk": "^6.9.0",
|
||||
"@twa-dev/sdk": "^7.0.0",
|
||||
"@twa-dev/types": "^7.0.0",
|
||||
"@types/cors": "^2.8.17",
|
||||
"axios": "^1.5.1",
|
||||
"axios": "^1.6.7",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"framer-motion": "^10.16.4",
|
||||
"framer-motion": "^11.0.8",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mongoose": "^7.5.3",
|
||||
"next": "^13.5.4",
|
||||
"mongoose": "^8.2.1",
|
||||
"next": "15.2.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.18",
|
||||
"@types/node": "^20.8.3",
|
||||
"@types/react": "^18.2.25",
|
||||
"eslint": "^8.51.0",
|
||||
"eslint-config-next": "13.5.4",
|
||||
"@types/node": "^20.11.24",
|
||||
"@types/react": "^18.2.61",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "15.2.2",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "^5.2.2"
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user