diff --git a/app/components/CharacterMenu/CharacterAddTips.tsx b/app/components/CharacterMenu/CharacterAddTips.tsx new file mode 100644 index 0000000..0381881 --- /dev/null +++ b/app/components/CharacterMenu/CharacterAddTips.tsx @@ -0,0 +1,11 @@ +import { View, Text } from 'react-native' + +const CharacterAddTips = () => { + return ( + + CharacterAddTips + + ) +} + +export default CharacterAddTips diff --git a/app/CharacterList.tsx b/app/components/CharacterMenu/CharacterList.tsx similarity index 53% rename from app/CharacterList.tsx rename to app/components/CharacterMenu/CharacterList.tsx index fb5180d..4a2f075 100644 --- a/app/CharacterList.tsx +++ b/app/components/CharacterMenu/CharacterList.tsx @@ -1,23 +1,15 @@ -import AnimatedView from '@components/AnimatedView' import TextBoxModal from '@components/TextBoxModal' -import { AntDesign, FontAwesome, Ionicons } from '@expo/vector-icons' +import { FontAwesome, Ionicons } from '@expo/vector-icons' import { Characters, Chats, Logger, Style } from '@globals' import { useRouter, Stack, usePathname } from 'expo-router' import { useEffect, useState } from 'react' -import { - SafeAreaView, - TouchableOpacity, - ScrollView, - Text, - Image, - StyleSheet, - View, - ActivityIndicator, -} from 'react-native' +import { SafeAreaView, TouchableOpacity, ScrollView, Text, StyleSheet, View } from 'react-native' import { Gesture, GestureDetector } from 'react-native-gesture-handler' import { runOnJS } from 'react-native-reanimated' import { useShallow } from 'zustand/react/shallow' +import CharacterListing from './CharacterListing' + type CharInfo = { name: string id: number @@ -27,7 +19,7 @@ type CharInfo = { const CharacterList = () => { const router = useRouter() - const { setCurrentCard, id } = Characters.useCharacterCard( + const { setCurrentCard } = Characters.useCharacterCard( useShallow((state) => ({ setCurrentCard: state.setCard, id: state.id, @@ -39,7 +31,6 @@ const CharacterList = () => { const [showNewChar, setShowNewChar] = useState(false) const [showDownload, setShowDownload] = useState(false) const [nowLoading, setNowLoading] = useState(false) - const [loadedCharId, setLoadedCharId] = useState(id) const goBack = () => router.back() @@ -48,6 +39,7 @@ const CharacterList = () => { .onEnd(() => { runOnJS(goBack)() }) + const getCharacterList = async () => { try { const list = await Characters.db.query.cardList('character') @@ -58,7 +50,6 @@ const CharacterList = () => { } const setCurrentCharacter = async (charId: number, edit: boolean = false) => { if (nowLoading) return - setLoadedCharId(charId) try { await setCurrentCard(charId) @@ -82,7 +73,6 @@ const CharacterList = () => { Logger.log(`Couldn't load character: ${error}`, true) setNowLoading(false) } - setLoadedCharId(-1) } const handleCreateCharacter = async (text: string) => { @@ -104,6 +94,7 @@ const CharacterList = () => { ( { {characterList.length !== 0 && ( {characterList.map((character, index) => ( - - setCurrentCharacter(character.id)}> - - - {character.name} - - {character.tags.map((item, index) => ( - - {item} - - ))} - - - - - {nowLoading && character.id === loadedCharId ? ( - - ) : ( - { - setCurrentCharacter(character.id, true) - }} - disabled={nowLoading}> - - - )} - - + ))} )} @@ -276,61 +201,6 @@ const styles = StyleSheet.create({ flex: 1, }, - longButton: { - flexDirection: 'row', - flex: 1, - padding: 8, - }, - - longButtonContainer: { - backgroundColor: Style.getColor('primary-surface1'), - borderColor: Style.getColor('primary-surface1'), - borderWidth: 2, - flexDirection: 'row', - marginBottom: 8, - justifyContent: 'space-between', - alignItems: 'center', - borderRadius: 8, - flex: 1, - }, - - longButtonSelectedContainer: { - backgroundColor: Style.getColor('primary-surface1'), - borderColor: Style.getColor('primary-brand'), - borderWidth: 2, - flexDirection: 'row', - marginBottom: 8, - justifyContent: 'space-between', - alignItems: 'center', - borderRadius: 8, - flex: 1, - }, - - secondaryButton: { - paddingHorizontal: 12, - paddingVertical: 20, - }, - - avatar: { - width: 48, - height: 48, - borderRadius: 12, - margin: 4, - backgroundColor: Style.getColor('primary-surface2'), - }, - - nametag: { - fontSize: 16, - marginLeft: 20, - color: Style.getColor('primary-text1'), - }, - - subtag: { - fontSize: 16, - marginLeft: 20, - color: Style.getColor('primary-text2'), - }, - headerButtonRight: { marginLeft: 20, marginRight: 4, diff --git a/app/components/CharacterMenu/CharacterListing.tsx b/app/components/CharacterMenu/CharacterListing.tsx new file mode 100644 index 0000000..9ea03d9 --- /dev/null +++ b/app/components/CharacterMenu/CharacterListing.tsx @@ -0,0 +1,187 @@ +import AnimatedView from '@components/AnimatedView' +import { AntDesign } from '@expo/vector-icons' +import { Characters, Chats, Logger, Style } from '@globals' +import { router } from 'expo-router' +import { View, Text, Image, StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native' + +type CharacterListingProps = { + index: number + character: CharInfo + nowLoading: boolean + setNowLoading: (b: boolean) => void +} + +type CharInfo = { + name: string + id: number + image_id: number + tags: string[] +} + +const CharacterListing: React.FC = ({ + index, + character, + nowLoading, + setNowLoading, +}) => { + const { loadedCharId, setCurrentCard } = Characters.useCharacterCard((state) => ({ + loadedCharId: state.id, + setCurrentCard: state.setCard, + })) + + const loadChat = Chats.useChat((state) => state.load) + + const setCurrentCharacter = async (charId: number, edit: boolean = false) => { + if (nowLoading) return + + try { + await setCurrentCard(charId) + setNowLoading(true) + const returnedChatId = await Chats.db.query.chatNewest(charId) + let chatId = returnedChatId + if (!chatId) { + chatId = await Chats.db.mutate.createChat(charId) + } + if (!chatId) { + Logger.log('Chat creation backup has failed! Please report.', true) + return + } + + await loadChat(chatId) + + setNowLoading(false) + if (edit) router.push('/CharInfo') + else router.back() + } catch (error) { + Logger.log(`Couldn't load character: ${error}`, true) + setNowLoading(false) + } + } + + return ( + + setCurrentCharacter(character.id)}> + + + {character.name} + + {character.tags.map((item, index) => ( + + {item} + + ))} + + + + + {nowLoading && character.id === loadedCharId ? ( + + ) : ( + { + setCurrentCharacter(character.id, true) + }} + disabled={nowLoading}> + + + )} + + + ) +} + +export default CharacterListing + +const styles = StyleSheet.create({ + longButton: { + flexDirection: 'row', + flex: 1, + padding: 8, + }, + + longButtonContainer: { + backgroundColor: Style.getColor('primary-surface1'), + borderColor: Style.getColor('primary-surface1'), + borderWidth: 2, + flexDirection: 'row', + marginBottom: 8, + justifyContent: 'space-between', + alignItems: 'center', + borderRadius: 8, + flex: 1, + }, + + longButtonSelectedContainer: { + backgroundColor: Style.getColor('primary-surface1'), + borderColor: Style.getColor('primary-brand'), + borderWidth: 2, + flexDirection: 'row', + marginBottom: 8, + justifyContent: 'space-between', + alignItems: 'center', + borderRadius: 8, + flex: 1, + }, + + secondaryButton: { + paddingHorizontal: 12, + paddingVertical: 20, + }, + + avatar: { + width: 48, + height: 48, + borderRadius: 12, + margin: 4, + backgroundColor: Style.getColor('primary-surface2'), + }, + + nametag: { + fontSize: 16, + marginLeft: 20, + color: Style.getColor('primary-text1'), + }, + + tag: { + color: Style.getColor('primary-text2'), + fontSize: 12, + backgroundColor: Style.getColor('primary-surface4'), + paddingHorizontal: 4, + paddingVertical: 2, + borderRadius: 4, + rowGap: 2, + columnGap: 4, + }, +}) diff --git a/app/components/CharacterMenu/CharacterNewMenu.tsx b/app/components/CharacterMenu/CharacterNewMenu.tsx new file mode 100644 index 0000000..57b9b24 --- /dev/null +++ b/app/components/CharacterMenu/CharacterNewMenu.tsx @@ -0,0 +1,11 @@ +import { View, Text } from 'react-native' + +const CharacterNewMenu = () => { + return ( + + CharacterNewMenu + + ) +} + +export default CharacterNewMenu diff --git a/app/components/CharacterMenu/CharactersEmpty.tsx b/app/components/CharacterMenu/CharactersEmpty.tsx new file mode 100644 index 0000000..e12429d --- /dev/null +++ b/app/components/CharacterMenu/CharactersEmpty.tsx @@ -0,0 +1,11 @@ +import { View, Text } from 'react-native' + +const CharactersEmpty = () => { + return ( + + NoCharacters + + ) +} + +export default CharactersEmpty