diff --git a/app/components/ChatMenu/ChatEditPopup.tsx b/app/components/ChatMenu/ChatEditPopup.tsx index fcadba6..a6c3fc6 100644 --- a/app/components/ChatMenu/ChatEditPopup.tsx +++ b/app/components/ChatMenu/ChatEditPopup.tsx @@ -1,3 +1,4 @@ +import TextBoxModal from '@components/TextBoxModal' import { AntDesign, FontAwesome } from '@expo/vector-icons' import { Characters, Chats, Logger, saveStringToDownload, Style } from '@globals' import { useFocusEffect } from 'expo-router' @@ -32,7 +33,7 @@ type ChatEditPopupProps = { type PopupProps = { onPress: () => void | Promise label: string - iconName: 'copy' | 'download' | 'trash' + iconName: keyof typeof FontAwesome.glyphMap warning?: boolean } @@ -56,6 +57,7 @@ const PopupOption: React.FC = ({ onPress, label, iconName, warning = const ChatEditPopup: React.FC = ({ item, setNowLoading, nowLoading }) => { const [showMenu, setShowMenu] = useState(false) + const [showRename, setShowRename] = useState(false) const menuRef: React.MutableRefObject = useRef(null) const { charName, charId } = Characters.useCharacterCard((state) => ({ @@ -158,6 +160,22 @@ const ChatEditPopup: React.FC = ({ item, setNowLoading, nowL /> + { + await Chats.db.mutate.renameChat(item.id, text) + }} + onClose={() => menuRef.current?.close()} + textCheck={(text) => text.length === 0} + /> + { + setShowRename(true) + }} + label="Rename" + iconName="pencil" + /> + handleExportChat()} label="Export" diff --git a/app/components/TextBoxModal.tsx b/app/components/TextBoxModal.tsx index 62f087b..77e1419 100644 --- a/app/components/TextBoxModal.tsx +++ b/app/components/TextBoxModal.tsx @@ -1,5 +1,5 @@ import { FontAwesome } from '@expo/vector-icons' -import { Style } from '@globals' +import { Logger, Style } from '@globals' import { getStringAsync } from 'expo-clipboard' import { useState, useEffect } from 'react' import { @@ -16,30 +16,39 @@ import { type TextBoxModalProps = { booleans: [boolean, (b: boolean) => void] onConfirm: (text: string) => void + onClose?: () => void title?: string showPaste?: boolean placeholder?: string + textCheck?: (text: string) => boolean + errorMessage?: string } const TextBoxModal: React.FC = ({ booleans: [showModal, setShowModal], onConfirm = (text) => {}, + onClose = () => {}, title = 'Enter Name', showPaste = false, placeholder = '', + textCheck = (text: string) => false, + errorMessage = 'Name cannot be empty', }) => { const [text, setText] = useState('') + const [showError, setShowError] = useState(false) useEffect(() => { setText('') }, [showModal]) const handleOverlayClick = (e: GestureResponderEvent) => { - if (e.target === e.currentTarget) setShowModal(false) + if (e.target === e.currentTarget) handleClose() } const handleClose = () => { setShowModal(false) + setShowError(false) + onClose() } return ( @@ -81,18 +90,20 @@ const TextBoxModal: React.FC = ({ )} - + {showError && {errorMessage}} - setShowModal(false)}> + handleClose()}> Cancel { + if (textCheck(text)) { + setShowError(true) + return + } onConfirm(text) - setShowModal(false) + handleClose() }}> Confirm @@ -173,4 +184,9 @@ const styles = StyleSheet.create({ inputButton: { marginLeft: 12, }, + + errorMessage: { + color: Style.getColor('destructive-brand'), + marginBottom: 8, + }, }) diff --git a/app/constants/Chat.ts b/app/constants/Chat.ts index dfcb975..c2fb9e9 100644 --- a/app/constants/Chat.ts +++ b/app/constants/Chat.ts @@ -546,6 +546,10 @@ export namespace Chats { await database.insert(chatSwipes).values(swipes) } + + export const renameChat = async (chatId: number, name: string) => { + await database.update(chats).set({ name: name }).where(eq(chats.id, chatId)) + } } }