лучшения стабильности и исправления: 1) тключение вертикальных свайпов для стабильности WebApp в Telegram; 2) бновление механизма получения ID пользователя; 3) справление проксирования изображений; 4) бновление типов для Telegram WebApp API

This commit is contained in:
kazachilo 2025-03-14 11:04:27 +03:00
parent 5456532ddd
commit 065229cf00
10 changed files with 59 additions and 35 deletions

View File

@ -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';

View File

@ -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 {

View File

@ -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;
}
// Для локальной разработки используем тестовый ID
CURRENT_USER_ID = window.Telegram.WebApp.initDataUnsafe.user.id;
console.log('Инициализирован ID пользователя Telegram:', CURRENT_USER_ID);
} else {
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',

View File

@ -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 // Передаем заголовок стикерпака

View File

@ -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

View File

@ -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<number>(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);
// Получаем список созданных стикеров

View File

@ -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[] = [];

View File

@ -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<PendingTask[]> {
async getUserPendingTasks(userId = getCurrentUserId()): Promise<PendingTask[]> {
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<GeneratedImage[]> {
async getGeneratedImages(userId = getCurrentUserId()): Promise<GeneratedImage[]> {
try {
const response = await fetch(`${API_BASE_URL}/images_links/${userId}`, {
method: 'GET',
@ -176,9 +176,10 @@ 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 для отладки
// Сохраняем JSON для отладки только при локальной разработке
if (!isTelegramWebAppAvailable()) {
const blob = new Blob([requestBodyJson], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
@ -188,6 +189,7 @@ const apiService = {
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// Отправляем запрос
const response = await fetch(`${API_BASE_URL}/generate_image`, {

View File

@ -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();
}
/**

View File

@ -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
}