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