diff --git a/src/App.tsx b/src/App.tsx index cd50c32..5af3c8e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import React, { lazy, Suspense, useEffect } from 'react'; import { BrowserRouter, Routes, Route, Navigate, Outlet, useNavigate, useLocation } from 'react-router-dom'; import Layout from './components/layout/Layout'; import Home from './screens/Home'; +import { initializeUserId } from './constants/user'; // Ленивая загрузка компонентов const OnboardingWelcome = lazy(() => import('./screens/onboarding/OnboardingWelcome')); @@ -35,6 +36,14 @@ const AppContent: React.FC = () => { const location = useLocation(); useEffect(() => { + // Инициализируем ID пользователя при запуске приложения + initializeUserId(); + + // Отключаем вертикальные свайпы для предотвращения случайного сворачивания WebApp + if (window.Telegram?.WebApp?.isVersionAtLeast('6.9')) { + window.Telegram.WebApp.disableVerticalSwipes(); + } + // Проверяем, видел ли пользователь онбординг и принял ли условия const hasSeenOnboarding = localStorage.getItem('hasSeenOnboarding') === 'true'; const hasAcceptedTerms = localStorage.getItem('hasAcceptedTerms') === 'true'; diff --git a/src/components/blocks/SquareButton.module.css b/src/components/blocks/SquareButton.module.css index 204c4f9..59c7780 100644 --- a/src/components/blocks/SquareButton.module.css +++ b/src/components/blocks/SquareButton.module.css @@ -13,7 +13,7 @@ flex-direction: column; justify-content: flex-end; transition: all 0.2s ease-in-out; - text-align: left; + text-align: center; background-size: 100% 100%; background-position: center; will-change: transform, background-position; @@ -122,6 +122,7 @@ text-align: center; gap: var(--spacing-small); z-index: 1; /* Поверх оверлея */ + width: 100%; } .title { diff --git a/src/constants/user.ts b/src/constants/user.ts index 791b9a6..a4eb555 100644 --- a/src/constants/user.ts +++ b/src/constants/user.ts @@ -3,7 +3,10 @@ */ // Единый ID для всех операций с API -export const DEFAULT_USER_ID = 296487847; +const DEFAULT_USER_ID = 296487847; + +// Переменная для хранения ID текущего пользователя +let CURRENT_USER_ID: number = DEFAULT_USER_ID; /** * Проверяет, доступен ли объект Telegram WebApp и данные пользователя @@ -15,17 +18,22 @@ export const isTelegramWebAppAvailable = (): boolean => { }; /** - * Получает ID пользователя для всех операций с API - * Если доступен Telegram WebApp, возвращает реальный ID пользователя - * В противном случае возвращает тестовый ID + * Инициализация ID пользователя при старте приложения */ -export const getUserId = (): number => { +export const initializeUserId = (): void => { if (isTelegramWebAppAvailable() && window.Telegram?.WebApp?.initDataUnsafe?.user?.id) { - return window.Telegram.WebApp.initDataUnsafe.user.id; + CURRENT_USER_ID = window.Telegram.WebApp.initDataUnsafe.user.id; + console.log('Инициализирован ID пользователя Telegram:', CURRENT_USER_ID); + } else { + console.log('Используется тестовый ID пользователя:', DEFAULT_USER_ID); } - // Для локальной разработки используем тестовый ID - console.log('Используется тестовый ID пользователя:', DEFAULT_USER_ID); - return DEFAULT_USER_ID; +}; + +/** + * Получает текущий ID пользователя + */ +export const getCurrentUserId = (): number => { + return CURRENT_USER_ID; }; /** @@ -33,7 +41,7 @@ export const getUserId = (): number => { * Используется для совместимости с API, требующими строковый ID */ export const getUserIdString = (): string => { - return getUserId().toString(); + return getCurrentUserId().toString(); }; /** @@ -46,7 +54,7 @@ export const getUserInfo = () => { } // Тестовые данные для локальной разработки return { - id: DEFAULT_USER_ID, + id: CURRENT_USER_ID, first_name: 'Test', last_name: 'User', username: 'testuser', diff --git a/src/screens/AddStickerToPackScreen.tsx b/src/screens/AddStickerToPackScreen.tsx index bf6ecaa..c7b9f77 100644 --- a/src/screens/AddStickerToPackScreen.tsx +++ b/src/screens/AddStickerToPackScreen.tsx @@ -4,7 +4,7 @@ import styles from './AddStickerToPackScreen.module.css'; import { stickerService } from '../services/stickerService'; import apiService from '../services/api'; import { GeneratedImage } from '../types/api'; -import { getUserIdString } from '../constants/user'; +import { getCurrentUserId } from '../constants/user'; const AddStickerToPackScreen: React.FC = () => { const navigate = useNavigate(); @@ -81,7 +81,7 @@ const AddStickerToPackScreen: React.FC = () => { // Добавляем стикер в стикерпак, используя file_id изображения await stickerService.addStickerToPack( packName, - getUserIdString(), + getCurrentUserId().toString(), selectedImage.link, emoji, packTitle // Передаем заголовок стикерпака diff --git a/src/screens/CreateStickerPack.tsx b/src/screens/CreateStickerPack.tsx index 1fbba16..e2d5ac5 100644 --- a/src/screens/CreateStickerPack.tsx +++ b/src/screens/CreateStickerPack.tsx @@ -4,7 +4,7 @@ import styles from './CreateStickerPack.module.css'; import { stickerService } from '../services/stickerService'; import apiService from '../services/api'; import { GeneratedImage } from '../types/api'; -import { getUserIdString } from '../constants/user'; +import { getCurrentUserId } from '../constants/user'; /** * Транслитерирует кириллический текст в латиницу. @@ -138,7 +138,7 @@ const CreateStickerPack: React.FC = () => { // Создаем стикерпак await stickerService.createStickerPack( title, - getUserIdString(), + getCurrentUserId().toString(), fileIds, emojis, packName diff --git a/src/screens/Profile.tsx b/src/screens/Profile.tsx index 5c54c64..5565bcc 100644 --- a/src/screens/Profile.tsx +++ b/src/screens/Profile.tsx @@ -3,6 +3,7 @@ import styles from './Profile.module.css'; import { MOCK_USER } from '../constants/mock'; import { stickerService } from '../services/stickerService'; import apiService from '../services/api'; +import { getCurrentUserId } from '../constants/user'; const Profile: React.FC = () => { const [stickersCount, setStickersCount] = useState(0); @@ -15,7 +16,7 @@ const Profile: React.FC = () => { setLoading(true); // Получаем список стикерпаков - const stickerPacks = await stickerService.getUserStickerPacks(stickerService.getUserId()); + const stickerPacks = await stickerService.getUserStickerPacks(getCurrentUserId().toString()); setPacksCount(stickerPacks.length); // Получаем список созданных стикеров diff --git a/src/screens/StickerPacks.tsx b/src/screens/StickerPacks.tsx index b113c55..633256e 100644 --- a/src/screens/StickerPacks.tsx +++ b/src/screens/StickerPacks.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import styles from './StickerPacks.module.css'; import { stickerService } from '../services/stickerService'; -import { getUserIdString } from '../constants/user'; +import { getCurrentUserId } from '../constants/user'; // Функция для удаления дописанной части из названия стикерпака const cleanPackTitle = (title: string): string => { @@ -36,7 +36,7 @@ const StickerPacks: React.FC = () => { const fetchStickerPacks = async () => { try { setLoading(true); - const stickerSets = await stickerService.getUserStickerPacks(getUserIdString()); + const stickerSets = await stickerService.getUserStickerPacks(getCurrentUserId().toString()); // Для каждого стикерпака получаем детальную информацию, обрабатывая ошибки отдельно const packsDetails: StickerPack[] = []; diff --git a/src/services/api.ts b/src/services/api.ts index b3af575..6154bb7 100644 --- a/src/services/api.ts +++ b/src/services/api.ts @@ -2,7 +2,7 @@ import { GenerationResponse, ApiError as ApiErrorType, GeneratedImage, PendingTa import { baseWorkflow } from '../constants/baseWorkflow'; import { prompts } from '../assets/prompts'; import translateService from './translateService'; -import { DEFAULT_USER_ID } from '../constants/user'; +import { getCurrentUserId, isTelegramWebAppAvailable } from '../constants/user'; const API_BASE_URL = 'https://stickerserver.gymnasticstuff.uk'; @@ -50,7 +50,7 @@ class GenerationError extends Error { const apiService = { // Получение списка задач пользователя в статусе PENDING - async getUserPendingTasks(userId = DEFAULT_USER_ID): Promise { + async getUserPendingTasks(userId = getCurrentUserId()): Promise { try { const response = await fetch(`${API_BASE_URL}/user_pending_tasks/${userId}`, { method: 'GET', @@ -98,7 +98,7 @@ const apiService = { return queuePosition * averageGenerationTime; }, - async getGeneratedImages(userId = DEFAULT_USER_ID): Promise { + async getGeneratedImages(userId = getCurrentUserId()): Promise { try { const response = await fetch(`${API_BASE_URL}/images_links/${userId}`, { method: 'GET', @@ -176,18 +176,20 @@ const apiService = { console.log(`Используем тег "${tag}" для стиля "${style || 'chibi'}"`); // Создаем тело запроса как строку JSON вручную - const requestBodyJson = `{"tag":"${tag}","user_id":${DEFAULT_USER_ID},"workflow":${workflowJson}}`; + const requestBodyJson = `{"tag":"${tag}","user_id":${getCurrentUserId()},"workflow":${workflowJson}}`; - // Сохраняем JSON для отладки - const blob = new Blob([requestBodyJson], { type: 'application/json' }); - const url = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = 'generation_request.json'; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - URL.revokeObjectURL(url); + // Сохраняем JSON для отладки только при локальной разработке + if (!isTelegramWebAppAvailable()) { + const blob = new Blob([requestBodyJson], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'generation_request.json'; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + } // Отправляем запрос const response = await fetch(`${API_BASE_URL}/generate_image`, { diff --git a/src/services/stickerService.ts b/src/services/stickerService.ts index ecfc0d8..cebf262 100644 --- a/src/services/stickerService.ts +++ b/src/services/stickerService.ts @@ -1,4 +1,4 @@ -import { getUserIdString } from '../constants/user'; +import { getCurrentUserId } from '../constants/user'; import { StickerPack, StickerSetResponse } from '../types/api'; import { normalizeImageUrl } from './api'; @@ -12,7 +12,7 @@ export class StickerService { * Получает ID пользователя для работы со стикерпаками */ getUserId(): string { - return getUserIdString(); + return getCurrentUserId().toString(); } /** diff --git a/src/types/telegram.d.ts b/src/types/telegram.d.ts index 2479aa8..f2a4463 100644 --- a/src/types/telegram.d.ts +++ b/src/types/telegram.d.ts @@ -22,6 +22,9 @@ interface TelegramWebApp { openTelegramLink: (url: string) => void; openLink: (url: string, options?: any) => void; close: () => void; + disableVerticalSwipes: () => void; + enableVerticalSwipes: () => void; + isVersionAtLeast: (version: string) => boolean; // Другие методы и свойства Telegram Web App API }