From 362172e832b147cbc8c71ad732823ce9a6bbe8ac Mon Sep 17 00:00:00 2001 From: Vlad0sEnIgma345 Date: Thu, 27 Nov 2025 09:47:08 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=20?= =?UTF-8?q?=D1=8D=D0=BA=D1=80=D0=B0=D0=BD=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=B5=D0=B9=D0=B2=D0=B0?= =?UTF-8?q?=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=B5=20=D1=81=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=BE=D0=B9=20=D1=84=D0=B0=D0=B9?= =?UTF-8?q?=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/frontend/app/add.tsx | 212 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 apps/frontend/app/add.tsx diff --git a/apps/frontend/app/add.tsx b/apps/frontend/app/add.tsx new file mode 100644 index 0000000..2cd8009 --- /dev/null +++ b/apps/frontend/app/add.tsx @@ -0,0 +1,212 @@ +import React, { useState } from 'react'; +import { + TextInput, + TouchableOpacity, + ScrollView, + Alert, + ActivityIndicator, + Platform, +} from 'react-native'; +import { useRouter } from 'expo-router'; +import * as ImagePicker from 'expo-image-picker'; +import { Text, View } from '@/components/Themed'; +import { savesApi } from '@/lib/api'; +import { useColorScheme } from '@/components/useColorScheme'; +import Colors from '@/constants/Colors'; + +export default function AddSaveScreen() { + const [mode, setMode] = useState<'upload' | 'url'>('upload'); + const [url, setUrl] = useState(''); + const [name, setName] = useState(''); + const [description, setDescription] = useState(''); + const [tags, setTags] = useState(''); + const [visibility, setVisibility] = useState<'public' | 'link'>('link'); + const [loading, setLoading] = useState(false); + const router = useRouter(); + const colorScheme = useColorScheme(); + const colors = Colors[colorScheme ?? 'light']; + + const handleUpload = async () => { + if (mode === 'url') { + if (!url) { + Alert.alert('Ошибка', 'Введите URL'); + return; + } + } + + setLoading(true); + try { + if (mode === 'url') { + const tagsArray = tags + ? tags.split(',').map((t) => t.trim()).filter(Boolean) + : undefined; + + await savesApi.createFromUrl({ + url, + name: name || undefined, + description: description || undefined, + tags: tagsArray, + visibility, + }); + } else { + // Загрузка файла + const result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ImagePicker.MediaTypeOptions.All, + allowsEditing: false, + quality: 1, + }); + + if (result.canceled) { + setLoading(false); + return; + } + + const asset = result.assets[0]; + const file = { + uri: asset.uri, + type: asset.mimeType || 'image/jpeg', + name: asset.fileName || `image.${asset.uri.split('.').pop()}`, + }; + + const tagsArray = tags + ? tags.split(',').map((t) => t.trim()).filter(Boolean) + : undefined; + + await savesApi.uploadFile(file, { + name: name || undefined, + description: description || undefined, + tags: tagsArray, + visibility, + }); + } + + Alert.alert('Успех', 'Сейв успешно создан', [ + { text: 'OK', onPress: () => router.back() }, + ]); + } catch (error: any) { + Alert.alert('Ошибка', error.message || 'Не удалось создать сейв'); + } finally { + setLoading(false); + } + }; + + return ( + + + Добавить сейв + + + setMode('upload')} + > + + Загрузить файл + + + setMode('url')} + > + + По URL + + + + + {mode === 'url' && ( + + )} + + + + + + + + + Видимость: + setVisibility('public')} + > + + Публичный + + + setVisibility('link')} + > + + По ссылке + + + + + + {loading ? ( + + ) : ( + + {mode === 'url' ? 'Создать из URL' : 'Выбрать файл'} + + )} + + + + ); +}