mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
adding conversation context
This commit is contained in:
parent
0f60c385ad
commit
0f8a90fb85
@ -14,6 +14,7 @@ import { CardContextProvider } from 'context/CardContext';
|
|||||||
import { ChannelContextProvider } from 'context/ChannelContext';
|
import { ChannelContextProvider } from 'context/ChannelContext';
|
||||||
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
|
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
|
||||||
import { NavigationContainer } from '@react-navigation/native';
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
|
import { ConversationContextProvider } from 'context/ConversationContext';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
|
||||||
@ -23,20 +24,22 @@ export default function App() {
|
|||||||
<ChannelContextProvider>
|
<ChannelContextProvider>
|
||||||
<AccountContextProvider>
|
<AccountContextProvider>
|
||||||
<ProfileContextProvider>
|
<ProfileContextProvider>
|
||||||
<AppContextProvider>
|
<ConversationContextProvider>
|
||||||
<SafeAreaProvider>
|
<AppContextProvider>
|
||||||
<NativeRouter>
|
<SafeAreaProvider>
|
||||||
<Routes>
|
<NativeRouter>
|
||||||
<Route path="/" element={ <Root /> } />
|
<Routes>
|
||||||
<Route path="/admin" element={ <Admin /> } />
|
<Route path="/" element={ <Root /> } />
|
||||||
<Route path="/login" element={ <Access mode="login" /> } />
|
<Route path="/admin" element={ <Admin /> } />
|
||||||
<Route path="/reset" element={ <Access mode="reset" /> } />
|
<Route path="/login" element={ <Access mode="login" /> } />
|
||||||
<Route path="/create" element={ <Access mode="create" /> } />
|
<Route path="/reset" element={ <Access mode="reset" /> } />
|
||||||
<Route path="/session" element={ <NavigationContainer><Session/></NavigationContainer> } />
|
<Route path="/create" element={ <Access mode="create" /> } />
|
||||||
</Routes>
|
<Route path="/session" element={ <NavigationContainer><Session/></NavigationContainer> } />
|
||||||
</NativeRouter>
|
</Routes>
|
||||||
</SafeAreaProvider>
|
</NativeRouter>
|
||||||
</AppContextProvider>
|
</SafeAreaProvider>
|
||||||
|
</AppContextProvider>
|
||||||
|
</ConversationContextProvider>
|
||||||
</ProfileContextProvider>
|
</ProfileContextProvider>
|
||||||
</AccountContextProvider>
|
</AccountContextProvider>
|
||||||
</ChannelContextProvider>
|
</ChannelContextProvider>
|
||||||
|
14
app/mobile/src/context/ConversationContext.js
Normal file
14
app/mobile/src/context/ConversationContext.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { createContext } from 'react';
|
||||||
|
import { useConversationContext } from './useConversationContext.hook';
|
||||||
|
|
||||||
|
export const ConversationContext = createContext({});
|
||||||
|
|
||||||
|
export function ConversationContextProvider({ children }) {
|
||||||
|
const { state, actions } = useConversationContext();
|
||||||
|
return (
|
||||||
|
<ConversationContext.Provider value={{ state, actions }}>
|
||||||
|
{children}
|
||||||
|
</ConversationContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
151
app/mobile/src/context/useConversationContext.hook.js
Normal file
151
app/mobile/src/context/useConversationContext.hook.js
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
import { useState, useEffect, useRef, useContext } from 'react';
|
||||||
|
import { StoreContext } from 'context/StoreContext';
|
||||||
|
import { CardContext } from 'context/CardContext';
|
||||||
|
import { ChannelContext } from 'context/ChannelContext';
|
||||||
|
import { ProfileContext } from 'context/ProfileContext';
|
||||||
|
|
||||||
|
export function useConversationContext() {
|
||||||
|
const [state, setState] = useState({
|
||||||
|
subject: null,
|
||||||
|
logo: null,
|
||||||
|
contacts: [],
|
||||||
|
topics: [],
|
||||||
|
});
|
||||||
|
const store = useContext(StoreContext);
|
||||||
|
const card = useContext(CardContext);
|
||||||
|
const channel = useContext(ChannelContext);
|
||||||
|
const profile = useContext(ProfileContext);
|
||||||
|
const topics = useRef(new Map());
|
||||||
|
const revision = useRef(0);
|
||||||
|
const syncing = useRef(false);
|
||||||
|
const cardId = useRef(null);
|
||||||
|
const channelId = useRef(null);
|
||||||
|
const setView = useRef(0);
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const sync = async () => {
|
||||||
|
const curView = setView.current;
|
||||||
|
const item = getChannel(cardId.current, channelId.current);
|
||||||
|
if (!syncing.current && item?.revision !== revision.current) {
|
||||||
|
syncing.current = true;
|
||||||
|
|
||||||
|
// stuff
|
||||||
|
setChannel(item);
|
||||||
|
|
||||||
|
if (curView === setView.current) {
|
||||||
|
revision.current = item?.revision;
|
||||||
|
}
|
||||||
|
syncing.current = false;
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCard = (guid) => {
|
||||||
|
let contact = null
|
||||||
|
card.state.cards.forEach((card, cardId, map) => {
|
||||||
|
if (card?.profile?.guid === guid) {
|
||||||
|
contact = card;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getChannel = (cardId, channelId) => {
|
||||||
|
if (cardId) {
|
||||||
|
const entry = card.state.cards.get(cardId);
|
||||||
|
return entry?.channels.get(channelId);
|
||||||
|
}
|
||||||
|
return channel.state.channels.get(channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setChannel = (item) => {
|
||||||
|
let contacts = [];
|
||||||
|
let logo = null;
|
||||||
|
let subject = null;
|
||||||
|
|
||||||
|
if (!item) {
|
||||||
|
updateState({ contacts, logo, subject });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.cardId) {
|
||||||
|
contacts.push(card.state.cards.get(item.cardId));
|
||||||
|
}
|
||||||
|
if (item?.detail?.members) {
|
||||||
|
const profileGuid = profile.state.profile.guid;
|
||||||
|
item.detail.members.forEach(guid => {
|
||||||
|
if (profileGuid !== guid) {
|
||||||
|
const contact = getCard(guid);
|
||||||
|
contacts.push(contact);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contacts.length === 0) {
|
||||||
|
logo = 'solution';
|
||||||
|
}
|
||||||
|
else if (contacts.length === 1) {
|
||||||
|
if (contacts[0]?.profile?.imageSet) {
|
||||||
|
logo = card.actions.getCardLogo(contacts[0].cardId, contacts[0].profileRevision);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logo = 'avatar';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logo = 'appstore';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item?.detail?.data) {
|
||||||
|
try {
|
||||||
|
subject = JSON.parse(item?.detail?.data).subject;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!subject) {
|
||||||
|
if (contacts.length) {
|
||||||
|
let names = [];
|
||||||
|
for (let contact of contacts) {
|
||||||
|
if (contact?.profile?.name) {
|
||||||
|
names.push(contact.profile.name);
|
||||||
|
}
|
||||||
|
else if (contact?.profile?.handle) {
|
||||||
|
names.push(contact?.profile?.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subject = names.join(', ');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
subject = "Notes";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateState({ subject, logo, contacts });
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
sync();
|
||||||
|
}, [card, channel]);
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
setChannel: (channel) => {
|
||||||
|
if (channel.cardId !== cardId.current || channel.channelId !== channelId.current) {
|
||||||
|
setView.current++;
|
||||||
|
revision.current = 0;
|
||||||
|
topics.current = new Map();
|
||||||
|
channelId.current = channel.channelId;
|
||||||
|
cardId.current = channel.cardId;
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return { state, actions }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
import { View, TouchableOpacity, Text } from 'react-native';
|
import { View, TouchableOpacity, Text, FlatList } from 'react-native';
|
||||||
import { useLayoutEffect } from 'react';
|
import { useState, useRef } from 'react';
|
||||||
import { useConversation } from './useConversation.hook';
|
import { useConversation } from './useConversation.hook';
|
||||||
import { styles } from './Conversation.styled';
|
import { styles } from './Conversation.styled';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
@ -33,15 +33,12 @@ export function ConversationBody({ channel }) {
|
|||||||
const { state, actions } = useConversation(channel?.cardId, channel?.channelId);
|
const { state, actions } = useConversation(channel?.cardId, channel?.channelId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<FlatList style={styles.topics}
|
||||||
<Text>CHANNEL</Text>
|
data={state.topics}
|
||||||
{ channel && (
|
inverted={true}
|
||||||
<>
|
renderItem={({item}) => <View style={{ height: item.id }}><Text>ITEM { item.id }</Text></View>}
|
||||||
<Text>{ channel?.cardId }</Text>
|
keyExtractor={item => item.id}
|
||||||
<Text>{ channel?.channelId }</Text>
|
/>
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,5 +41,8 @@ export const styles = StyleSheet.create({
|
|||||||
action: {
|
action: {
|
||||||
paddingLeft: 8,
|
paddingLeft: 8,
|
||||||
},
|
},
|
||||||
|
topics: {
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,105 +1,28 @@
|
|||||||
import { useState, useEffect, useContext } from 'react';
|
import { useState, useEffect, useContext } from 'react';
|
||||||
import { CardContext } from 'context/CardContext';
|
import { ConversationContext } from 'context/ConversationContext';
|
||||||
import { ChannelContext } from 'context/ChannelContext';
|
|
||||||
import { ProfileContext } from 'context/ProfileContext';
|
|
||||||
|
|
||||||
export function useConversation(cardId, channelId) {
|
export function useConversation(cardId, channelId) {
|
||||||
|
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
|
topics: [],
|
||||||
subject: null,
|
subject: null,
|
||||||
logo: null,
|
logo: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const card = useContext(CardContext);
|
const conversation = useContext(ConversationContext);
|
||||||
const channel = useContext(ChannelContext);
|
|
||||||
const profile = useContext(ProfileContext);
|
|
||||||
|
|
||||||
const updateState = (value) => {
|
const updateState = (value) => {
|
||||||
setState((s) => ({ ...s, ...value }));
|
setState((s) => ({ ...s, ...value }));
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCard = (guid) => {
|
useEffect(() => {
|
||||||
let contact = null
|
conversation.actions.setChannel({ cardId, channelId });
|
||||||
card.state.cards.forEach((card, cardId, map) => {
|
}, [cardId, channelId]);
|
||||||
if (card?.profile?.guid === guid) {
|
|
||||||
contact = card;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return contact;
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(cardId, channelId);
|
const { topics, subject, logo } = conversation.state;
|
||||||
let item;
|
updateState({ topics, subject, logo });
|
||||||
if (cardId) {
|
}, [conversation]);
|
||||||
const entry = card.state.cards.get(cardId);
|
|
||||||
if (entry) {
|
|
||||||
item = entry.channels.get(channelId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
item = channel.state.channels.get(channelId);
|
|
||||||
}
|
|
||||||
|
|
||||||
let contacts = [];
|
|
||||||
if (item.cardId) {
|
|
||||||
contacts.push(card.state.cards.get(item.cardId));
|
|
||||||
}
|
|
||||||
if (item?.detail?.members) {
|
|
||||||
const profileGuid = profile.state.profile.guid;
|
|
||||||
item.detail.members.forEach(guid => {
|
|
||||||
if (profileGuid !== guid) {
|
|
||||||
const contact = getCard(guid);
|
|
||||||
contacts.push(contact);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let logo = null;
|
|
||||||
if (contacts.length === 0) {
|
|
||||||
logo = 'solution';
|
|
||||||
}
|
|
||||||
else if (contacts.length === 1) {
|
|
||||||
if (contacts[0]?.profile?.imageSet) {
|
|
||||||
logo = card.actions.getCardLogo(contacts[0].cardId, contacts[0].profileRevision);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logo = 'avatar';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logo = 'appstore';
|
|
||||||
}
|
|
||||||
|
|
||||||
let subject = null;
|
|
||||||
if (item?.detail?.data) {
|
|
||||||
try {
|
|
||||||
subject = JSON.parse(item?.detail?.data).subject;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!subject) {
|
|
||||||
if (contacts.length) {
|
|
||||||
let names = [];
|
|
||||||
for (let contact of contacts) {
|
|
||||||
if (contact?.profile?.name) {
|
|
||||||
names.push(contact.profile.name);
|
|
||||||
}
|
|
||||||
else if (contact?.profile?.handle) {
|
|
||||||
names.push(contact?.profile?.handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subject = names.join(', ');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
subject = "Notes";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateState({ subject, logo });
|
|
||||||
}, [cardId, channelId, profile, card, channel]);
|
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
};
|
};
|
||||||
|
@ -23,6 +23,8 @@ export function Profile() {
|
|||||||
|
|
||||||
const { state, actions } = useProfile();
|
const { state, actions } = useProfile();
|
||||||
|
|
||||||
|
console.log(state.imageSource);
|
||||||
|
|
||||||
const setVisible = async (visible) => {
|
const setVisible = async (visible) => {
|
||||||
try {
|
try {
|
||||||
await actions.setVisible(visible);
|
await actions.setVisible(visible);
|
||||||
|
@ -70,6 +70,7 @@ export function useProfile() {
|
|||||||
navigate('/');
|
navigate('/');
|
||||||
},
|
},
|
||||||
setVisible: async (visible) => {
|
setVisible: async (visible) => {
|
||||||
|
updateState({ visible });
|
||||||
await account.actions.setSearchable(visible);
|
await account.actions.setSearchable(visible);
|
||||||
},
|
},
|
||||||
setProfileImage: async (data) => {
|
setProfileImage: async (data) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user