From f5b5443c94d198b7afdc8233756602231daf496e Mon Sep 17 00:00:00 2001 From: balzack Date: Sun, 5 Jan 2025 21:53:42 -0800 Subject: [PATCH] support direct text link --- app/client/mobile/src/contacts/Contacts.tsx | 10 +++---- app/client/mobile/src/content/Content.tsx | 23 ++++++++++++++-- .../mobile/src/content/useContent.hook.ts | 20 ++++++++++++++ app/client/mobile/src/session/Session.tsx | 26 ++++++++++++++----- 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/app/client/mobile/src/contacts/Contacts.tsx b/app/client/mobile/src/contacts/Contacts.tsx index c055b0ee..88c31e34 100644 --- a/app/client/mobile/src/contacts/Contacts.tsx +++ b/app/client/mobile/src/contacts/Contacts.tsx @@ -18,7 +18,7 @@ function Action({icon, color, select}: {icon: string; color: string; select: () return ; } -export function Contacts({openRegistry, openContact}: {openRegistry: () => void; openContact: (params: ContactParams) => void}) { +export function Contacts({openRegistry, openContact, callContact, textContact}: {openRegistry: () => void; openContact: (params: ContactParams) => void, callContact: (cardId: null|string)=>void, textContact: (cardId: null|string)=>void}) { const theme = useTheme(); const {state, actions} = useContacts(); const [alert, setAlert] = useState(false); @@ -74,17 +74,13 @@ export function Contacts({openRegistry, openContact}: {openRegistry: () => void; key="call" icon="phone-outline" color={Colors.connected} - select={async () => { - await new Promise(r => setTimeout(r, 2000)); //call contact - }} + select={()=>callContact(item.cardId)} />, { - await new Promise(r => setTimeout(r, 2000)); //text contact - }} + select={()=>textContact(item.cardId)} />, ]; } else if (syncStatus === 'offsync') { diff --git a/app/client/mobile/src/content/Content.tsx b/app/client/mobile/src/content/Content.tsx index ced2111f..dc1ba565 100644 --- a/app/client/mobile/src/content/Content.tsx +++ b/app/client/mobile/src/content/Content.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; import {Divider, Switch, Surface, IconButton, Button, Text, TextInput, useTheme} from 'react-native-paper'; import {SafeAreaView, Modal, FlatList, View} from 'react-native'; import {styles} from './Content.styled'; @@ -9,7 +9,7 @@ import {BlurView} from '@react-native-community/blur'; import {Card} from '../card/Card'; import {Confirm} from '../confirm/Confirm'; -export function Content({openConversation}: {openConversation: ()=>void}) { +export function Content({openConversation, textCard}: {openConversation: ()=>void, textCard: {cardId: null|string}}) { const [add, setAdd] = useState(false); const [adding, setAdding] = useState(false); const [sealedTopic, setSealedTopic] = useState(false); @@ -28,6 +28,25 @@ export function Content({openConversation}: {openConversation: ()=>void}) { }); const cards = state.sealSet && sealedTopic ? state.sealable : state.connected; + useEffect(() => { + if (textCard.cardId) { + openTopic(textCard.cardId); + } + }, [textCard]); + + const openTopic = async (cardId: string) => { + setAdding(true); + try { + const id = await actions.openTopic(cardId); + actions.setFocus(null, id); + openConversation(); + } catch (err) { + console.log(err); + setAlert(true); + } + setAdding(false); + } + const addTopic = async () => { setAdding(true); try { diff --git a/app/client/mobile/src/content/useContent.hook.ts b/app/client/mobile/src/content/useContent.hook.ts index 8a4501d0..f02aa9bb 100644 --- a/app/client/mobile/src/content/useContent.hook.ts +++ b/app/client/mobile/src/content/useContent.hook.ts @@ -229,6 +229,26 @@ export function useContent() { setFocus: async (cardId: string | null, channelId: string) => { await app.actions.setFocus(cardId, channelId); }, + openTopic: async (cardId: string) => { + const content = app.state.session.getContent() + const card = state.cards.find(card => card.cardId === cardId) + if (card) { + const sealable = card.sealable && state.sealSet; + const thread = state.sorted.find(channel => { + const { sealed, cardId, members} = channel; + if (sealed === sealable && cardId == null && members.length === 1 && members[0].guid === card.guid) { + return true; + } + return false; + }); + if (thread) { + return thread.channelId; + } else { + const topic = await content.addChannel(sealable, sealable ? 'sealed' : 'superbasic', {}, [cardId]); + return topic.id; + } + } + }, addTopic: async (sealed: boolean, subject: string, contacts: string[]) => { const content = app.state.session.getContent() if (sealed) { diff --git a/app/client/mobile/src/session/Session.tsx b/app/client/mobile/src/session/Session.tsx index a23efb55..1211b630 100644 --- a/app/client/mobile/src/session/Session.tsx +++ b/app/client/mobile/src/session/Session.tsx @@ -31,12 +31,18 @@ export function Session() { const {state} = useSession(); const scheme = useColorScheme(); const [tab, setTab] = useState('content'); + const [textCard, setTextCard] = useState({ cardId: null} as {cardId: null|string}); const sessionNav = {strings: state.strings}; const showContent = {display: tab === 'content' ? 'flex' : 'none'}; const showContact = {display: tab === 'contacts' ? 'flex' : 'none'}; const showSettings = {display: tab === 'settings' ? 'flex' : 'none'}; + const textContact = (cardId: null|string) => { + setTextCard({ cardId }); + setTab('content') + } + return ( {state.layout !== 'large' && ( @@ -48,14 +54,14 @@ export function Session() { ...styles.body, ...showContent, }}> - + - + {props => ( - props.navigation.navigate('conversation')} /> + props.navigation.navigate('conversation')} /> )} void}) { const [contactParams, setContactParams] = useState({ guid: '', } as ContactParams); @@ -198,6 +204,8 @@ function ContactTab({scheme}: {scheme: string}) { setContactParams(params); props.navigation.navigate('profile'); }} + callContact={(cardId: string)=>console.log("CALL: ", cardId)} + textContact={textContact} /> )} @@ -301,6 +309,7 @@ function RegistryScreen({nav}) { } function ContactsScreen({nav}) { + const [textCard, setTextCard] = useState({ cardId: null} as {cardId: null|string}); const ContactsComponent = useCallback( () => ( @@ -309,6 +318,8 @@ function ContactsScreen({nav}) { openContact={(params: ContactParams) => { nav.openContact(params, nav.profile.openDrawer); }} + callContact={(cardId: string)=>console.log('CALL: ', cardId)} + textContact={(cardId: null|string)=>setTextCard({ cardId })} /> ), @@ -325,7 +336,7 @@ function ContactsScreen({nav}) { drawerType: 'front', headerShown: false, }}> - {({navigation}) => } + {({navigation}) => } ); } @@ -357,6 +368,7 @@ function SettingsScreen({nav}) { function HomeScreen({nav}) { const [focus, setFocus] = useState(false); + const [textCard, setTextCard] = useState({ cardId: null} as {cardId: null|string}); return ( @@ -365,7 +377,7 @@ function HomeScreen({nav}) { - setFocus(true)} /> + setFocus(true)} />