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