mirror of
https://github.com/balzack/databag.git
synced 2025-04-22 09:35:16 +00:00
rendering conversation header
This commit is contained in:
parent
1f70aee040
commit
0f60c385ad
@ -15,7 +15,7 @@ import { useCards } from './cards/useCards.hook';
|
||||
import { RegistryTitle, RegistryBody, Registry } from './registry/Registry';
|
||||
import { useRegistry } from './registry/useRegistry.hook';
|
||||
import { Contact, ContactTitle } from './contact/Contact';
|
||||
import { Details } from './details/Details';
|
||||
import { Details, DetailsHeader, DetailsBody } from './details/Details';
|
||||
import { Conversation, ConversationHeader, ConversationBody } from './conversation/Conversation';
|
||||
import { Welcome } from './welcome/Welcome';
|
||||
import { ChannelsTitle, ChannelsBody, Channels } from './channels/Channels';
|
||||
@ -94,8 +94,12 @@ export function Session() {
|
||||
}}>
|
||||
{(props) => <ConversationBody channel={selected} />}
|
||||
</ConversationStack.Screen>
|
||||
<ConversationStack.Screen name="details">
|
||||
{(props) => <Details channel={selected} clearConversation={() => clearConversation(props.navigation)} />}
|
||||
<ConversationStack.Screen name="details" options={{
|
||||
headerStyle: { backgroundColor: Colors.titleBackground },
|
||||
headerBackTitleVisible: false,
|
||||
headerTitle: (props) => <DetailsHeader channel={selected} />
|
||||
}}>
|
||||
{(props) => <DetailsBody channel={selected} clearConversation={() => clearConversation(props.navigation)} />}
|
||||
</ConversationStack.Screen>
|
||||
</ConversationStack.Navigator>
|
||||
);
|
||||
|
@ -1,11 +1,14 @@
|
||||
import { View, TouchableOpacity, Text } from 'react-native';
|
||||
import { useLayoutEffect } from 'react';
|
||||
import { useConversation } from './useConversation.hook';
|
||||
import { styles } from './Conversation.styled';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import Ionicons from '@expo/vector-icons/AntDesign';
|
||||
import Colors from 'constants/Colors';
|
||||
|
||||
export function ConversationHeader({ channel, closeConversation, openDetails }) {
|
||||
const navigation = useNavigation();
|
||||
const { state, actions } = useConversation();
|
||||
const { state, actions } = useConversation(channel?.cardId, channel?.channelId);
|
||||
|
||||
const setDetails = () => {
|
||||
openDetails(navigation);
|
||||
@ -16,26 +19,26 @@ export function ConversationHeader({ channel, closeConversation, openDetails })
|
||||
|
||||
return (
|
||||
<View style={styles.title}>
|
||||
<TouchableOpacity onPress={clearConversation}>
|
||||
<Text>CLOSE</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={setDetails}>
|
||||
<Text>DETAILS</Text>
|
||||
<View style={styles.subject}>
|
||||
<Text style={styles.subjectText}>{ state.subject }</Text>
|
||||
</View>
|
||||
<TouchableOpacity style={styles.action} onPress={setDetails}>
|
||||
<Ionicons name="setting" size={20} color={Colors.primary} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export function ConversationBody({ channel }) {
|
||||
const { state, actions } = useConversation();
|
||||
const { state, actions } = useConversation(channel?.cardId, channel?.channelId);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text>CHANNEL</Text>
|
||||
{ channel && (
|
||||
<>
|
||||
<Text>{ channel.cardId }</Text>
|
||||
<Text>{ channel.channelId }</Text>
|
||||
<Text>{ channel?.cardId }</Text>
|
||||
<Text>{ channel?.channelId }</Text>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
@ -44,10 +47,14 @@ export function ConversationBody({ channel }) {
|
||||
|
||||
export function Conversation({ channel, closeConversation, openDetails }) {
|
||||
|
||||
const { state, actions } = useConversation(channel?.cardId, channel?.channelId);
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.header}>
|
||||
<ConversationHeader channel={channel} closeConversation={closeConversation} openDetails={openDetails} />
|
||||
<Text style={styles.subjectText}>{ state.subject }</Text>
|
||||
<TouchableOpacity style={styles.action} onPress={openDetails}>
|
||||
<Ionicons name="setting" size={20} color={Colors.primary} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.body}>
|
||||
<ConversationBody channel={channel} />
|
||||
|
@ -7,9 +7,16 @@ export const styles = StyleSheet.create({
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
borderLeftWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
header: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
padding: 8,
|
||||
},
|
||||
body: {
|
||||
width: '100%',
|
||||
@ -17,6 +24,22 @@ export const styles = StyleSheet.create({
|
||||
title: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
subject: {
|
||||
width: '100%',
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
textAlign: 'center',
|
||||
paddingLeft: 16,
|
||||
},
|
||||
subjectText: {
|
||||
fontSize: 18,
|
||||
textAlign: 'center',
|
||||
},
|
||||
action: {
|
||||
paddingLeft: 8,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -1,14 +1,106 @@
|
||||
import { useState, useEffect, useContext } from 'react';
|
||||
import { CardContext } from 'context/CardContext';
|
||||
import { ChannelContext } from 'context/ChannelContext';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
|
||||
export function useConversation() {
|
||||
export function useConversation(cardId, channelId) {
|
||||
|
||||
const [state, setState] = useState({
|
||||
subject: null,
|
||||
logo: null,
|
||||
});
|
||||
|
||||
const card = useContext(CardContext);
|
||||
const channel = useContext(ChannelContext);
|
||||
const profile = useContext(ProfileContext);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
const getCard = (guid) => {
|
||||
let contact = null
|
||||
card.state.cards.forEach((card, cardId, map) => {
|
||||
if (card?.profile?.guid === guid) {
|
||||
contact = card;
|
||||
}
|
||||
});
|
||||
return contact;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(cardId, channelId);
|
||||
let item;
|
||||
if (cardId) {
|
||||
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 = {
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,17 @@
|
||||
import { View, Text, TouchableOpacity } from 'react-native';
|
||||
import { styles } from './Details.styled';
|
||||
|
||||
export function DetailsHeader({ channel }) {
|
||||
return <Text style={styles.title}>Details</Text>
|
||||
}
|
||||
|
||||
export function DetailsBody({ channel, clearConversation }) {
|
||||
return (
|
||||
<TouchableOpacity onPress={clearConversation}>
|
||||
<Text>CLEAR</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
export function Details({ channel, clearConversation }) {
|
||||
return (
|
||||
|
28
app/mobile/src/session/details/Details.styled.js
Normal file
28
app/mobile/src/session/details/Details.styled.js
Normal file
@ -0,0 +1,28 @@
|
||||
import { StyleSheet } from 'react-native';
|
||||
import { Colors } from 'constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
borderLeftWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
header: {
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
padding: 8,
|
||||
},
|
||||
body: {
|
||||
width: '100%',
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
},
|
||||
})
|
||||
|
@ -13,6 +13,7 @@ export const styles = StyleSheet.create({
|
||||
},
|
||||
drawer: {
|
||||
paddingTop: 16,
|
||||
backgroundColor: Colors.formBackground,
|
||||
},
|
||||
titleText: {
|
||||
fontSize: 18,
|
||||
|
Loading…
x
Reference in New Issue
Block a user