mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
merging refactored details
This commit is contained in:
parent
1e4f1cf819
commit
dcc075383c
@ -366,7 +366,7 @@ export function useCardContext() {
|
|||||||
return getCardImageUrl(server, token, cardId, profileRevision);
|
return getCardImageUrl(server, token, cardId, profileRevision);
|
||||||
},
|
},
|
||||||
removeChannel: async (cardId, channelId) => {
|
removeChannel: async (cardId, channelId) => {
|
||||||
const { detail, profile } = cards.current.get(cardId) || {};
|
const { detail, profile } = cards.current.get(cardId)?.card || {};
|
||||||
const cardToken = `${profile?.guid}.${detail?.token}`;
|
const cardToken = `${profile?.guid}.${detail?.token}`;
|
||||||
return await removeContactChannel(profile?.node, cardToken, channelId);
|
return await removeContactChannel(profile?.node, cardToken, channelId);
|
||||||
},
|
},
|
||||||
|
@ -157,7 +157,6 @@ export function useConversationContext() {
|
|||||||
clearConversation: async () => {
|
clearConversation: async () => {
|
||||||
conversationId.current = null;
|
conversationId.current = null;
|
||||||
reset.current = true;
|
reset.current = true;
|
||||||
await sync();
|
|
||||||
},
|
},
|
||||||
setChannelSubject: async (type, subject) => {
|
setChannelSubject: async (type, subject) => {
|
||||||
const { cardId, channelId } = conversationId.current || {};
|
const { cardId, channelId } = conversationId.current || {};
|
||||||
|
@ -168,6 +168,8 @@ export function Session() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navParams.detailNav.closeDrawer();
|
navParams.detailNav.closeDrawer();
|
||||||
|
setChannelId(null);
|
||||||
|
setCardId(null);
|
||||||
setChannel(false);
|
setChannel(false);
|
||||||
}, [navParams.closeCount]);
|
}, [navParams.closeCount]);
|
||||||
|
|
||||||
@ -263,20 +265,18 @@ export function Session() {
|
|||||||
|
|
||||||
const DetailDrawerScreen = ({ navParams }) => {
|
const DetailDrawerScreen = ({ navParams }) => {
|
||||||
const [closeCount, setCloseCount] = useState(0);
|
const [closeCount, setCloseCount] = useState(0);
|
||||||
const closeConversation = () => {
|
const clearConversation = (navigation) => {
|
||||||
setCloseCount(closeCount+1);
|
setCloseCount(closeCount+1);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DetailDrawer.Navigator screenOptions={{ ...drawerParams, drawerStyle: { width: '45%' } }} drawerContent={(props) => (
|
<DetailDrawer.Navigator screenOptions={{ ...drawerParams, drawerStyle: { width: '45%' } }} drawerContent={(props) => (
|
||||||
<ScrollView style={styles.drawer}>
|
<SafeAreaView style={styles.drawer} edges={['top', 'bottom', 'right']}>
|
||||||
<SafeAreaView edges={['top', 'bottom', 'right']}>
|
<Details clearConversation={() => clearConversation(props.navigation)} />
|
||||||
<Details closeConversation={closeConversation} />
|
</SafeAreaView>
|
||||||
</SafeAreaView>
|
|
||||||
</ScrollView>
|
|
||||||
)}>
|
)}>
|
||||||
<DetailDrawer.Screen name="contact">
|
<DetailDrawer.Screen name="contact">
|
||||||
{(props) => <ContactDrawerScreen navParams={{...navParams, detailNav: props.navigation}} />}
|
{(props) => <ContactDrawerScreen navParams={{...navParams, closeCount: closeCount, detailNav: props.navigation}} />}
|
||||||
</DetailDrawer.Screen>
|
</DetailDrawer.Screen>
|
||||||
</DetailDrawer.Navigator>
|
</DetailDrawer.Navigator>
|
||||||
);
|
);
|
||||||
|
@ -26,7 +26,8 @@ export function useChannels() {
|
|||||||
const account = useContext(AccountContext);
|
const account = useContext(AccountContext);
|
||||||
const profile = useContext(ProfileContext);
|
const profile = useContext(ProfileContext);
|
||||||
const app = useContext(AppContext);
|
const app = useContext(AppContext);
|
||||||
|
|
||||||
|
const filter = useRef();
|
||||||
const syncing = useRef(false);
|
const syncing = useRef(false);
|
||||||
const resync = useRef(false);
|
const resync = useRef(false);
|
||||||
|
|
||||||
@ -154,6 +155,7 @@ export function useChannels() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
syncChannels();
|
syncChannels();
|
||||||
|
filter.current = state.filter;
|
||||||
}, [app.state, card.state, channel.state, state.filter, state.sealable]);
|
}, [app.state, card.state, channel.state, state.filter, state.sealable]);
|
||||||
|
|
||||||
const syncChannels = async () => {
|
const syncChannels = async () => {
|
||||||
@ -179,10 +181,10 @@ export function useChannels() {
|
|||||||
channels.push(await setChannelItem(loginTimestamp, cardId, channelId, channelItem));
|
channels.push(await setChannelItem(loginTimestamp, cardId, channelId, channelItem));
|
||||||
}
|
}
|
||||||
const filtered = channels.filter(item => {
|
const filtered = channels.filter(item => {
|
||||||
if (!state.filter) {
|
if (!filter.current) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const filterCase = state.filter.toUpperCase();
|
const filterCase = filter.current.toUpperCase();
|
||||||
const subjectCase = item.subject.toUpperCase();
|
const subjectCase = item.subject.toUpperCase();
|
||||||
return subjectCase.includes(filterCase);
|
return subjectCase.includes(filterCase);
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useContext } from 'react';
|
import { useEffect, useState, useContext } from 'react';
|
||||||
import { View, Text, TouchableOpacity } from 'react-native';
|
import { View, Text, TouchableOpacity } from 'react-native';
|
||||||
import { ConversationContext } from 'context/ConversationContext';
|
import { ConversationContext } from 'context/ConversationContext';
|
||||||
import { useConversation } from './useConversation.hook';
|
import { useConversation } from './useConversation.hook';
|
||||||
@ -9,6 +9,7 @@ import { Logo } from 'utils/Logo';
|
|||||||
|
|
||||||
export function Conversation({ navigation, cardId, channelId, closeConversation, openDetails }) {
|
export function Conversation({ navigation, cardId, channelId, closeConversation, openDetails }) {
|
||||||
|
|
||||||
|
const [ready, setReady] = useState(false);
|
||||||
const conversation = useContext(ConversationContext);
|
const conversation = useContext(ConversationContext);
|
||||||
const { state, actions } = useConversation();
|
const { state, actions } = useConversation();
|
||||||
|
|
||||||
@ -30,21 +31,27 @@ export function Conversation({ navigation, cardId, channelId, closeConversation,
|
|||||||
}, [navigation, state.subject]);
|
}, [navigation, state.subject]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
conversation.actions.setConversation(cardId, channelId);
|
(async () => {
|
||||||
return () => { conversation.actions.clearConversation() };
|
setReady(false);
|
||||||
|
await conversation.actions.setConversation(cardId, channelId);
|
||||||
|
setReady(true);
|
||||||
|
})();
|
||||||
|
return () => { conversation.actions.clearConversation(); };
|
||||||
}, [cardId, channelId]);
|
}, [cardId, channelId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
{ !navigation && (
|
{ !navigation && (
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
<TouchableOpacity style={styles.headertitle} onPress={openDetails}>
|
{ ready && (
|
||||||
<Logo src={state.logo} width={32} height={32} radius={2} />
|
<TouchableOpacity style={styles.headertitle} onPress={openDetails}>
|
||||||
<Text style={styles.titletext}>{ state.subject }</Text>
|
<Logo src={state.logo} width={32} height={32} radius={2} />
|
||||||
<Ionicons name={'setting'} size={24} color={Colors.primary} style={styles.titlebutton} />
|
<Text style={styles.titletext} numberOfLines={1} ellipsizeMode={'tail'}>{ state.subject }</Text>
|
||||||
</TouchableOpacity>
|
<Ionicons name={'setting'} size={24} color={Colors.primary} style={styles.titlebutton} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
<TouchableOpacity style={styles.headerclose} onPress={closeConversation}>
|
<TouchableOpacity style={styles.headerclose} onPress={closeConversation}>
|
||||||
<Ionicons name={'close'} size={28} color={Colors.grey} style={styles.titlebutton} />
|
<Ionicons name={'close'} size={22} color={Colors.grey} style={styles.titlebutton} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
@ -16,27 +16,31 @@ export const styles = StyleSheet.create({
|
|||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderColor: Colors.divider,
|
borderColor: Colors.divider,
|
||||||
|
height: 48,
|
||||||
|
marginLeft: 16,
|
||||||
|
marginRight: 16,
|
||||||
},
|
},
|
||||||
headertitle: {
|
headertitle: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
flexShrink: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingLeft: 16,
|
paddingLeft: 8,
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
paddingBottom: 8,
|
paddingBottom: 8,
|
||||||
},
|
},
|
||||||
titletext: {
|
titletext: {
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
|
flexShrink: 1,
|
||||||
paddingLeft: 16,
|
paddingLeft: 16,
|
||||||
paddingRight: 16,
|
paddingRight: 16,
|
||||||
},
|
},
|
||||||
titlebutton: {
|
titlebutton: {
|
||||||
paddingRight: 16,
|
paddingRight: 8,
|
||||||
},
|
},
|
||||||
headerclose: {
|
headerclose: {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
paddingTop: 8,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,11 +5,30 @@ import { Logo } from 'utils/Logo';
|
|||||||
import AntIcons from 'react-native-vector-icons/AntDesign';
|
import AntIcons from 'react-native-vector-icons/AntDesign';
|
||||||
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
import Colors from 'constants/Colors';
|
import Colors from 'constants/Colors';
|
||||||
|
import { MemberItem } from './memberItem/MemberItem';
|
||||||
|
|
||||||
export function Details({ channel, clearConversation }) {
|
export function Details({ channel, clearConversation }) {
|
||||||
|
|
||||||
const { state, actions } = useDetails();
|
const { state, actions } = useDetails();
|
||||||
|
|
||||||
|
const toggle = async (cardId, selected) => {
|
||||||
|
try {
|
||||||
|
if (selected) {
|
||||||
|
await actions.clearCard(cardId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await actions.setCard(cardId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
Alert.alert(
|
||||||
|
'Failed to Update Membership',
|
||||||
|
'Please try again.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const saveSubject = async () => {
|
const saveSubject = async () => {
|
||||||
try {
|
try {
|
||||||
await actions.saveSubject();
|
await actions.saveSubject();
|
||||||
@ -199,8 +218,8 @@ export function Details({ channel, clearConversation }) {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<FlatList style={styles.cards}
|
<FlatList style={styles.cards}
|
||||||
data={state.contacts}
|
data={state.members}
|
||||||
renderItem={({ item }) => <MemberItem hostId={state.hostId} editable={false} members={[]} item={item} />}
|
renderItem={({ item }) => <MemberItem hostId={state.hostId} item={item} />}
|
||||||
keyExtractor={item => item.cardId}
|
keyExtractor={item => item.cardId}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -242,7 +261,7 @@ export function Details({ channel, clearConversation }) {
|
|||||||
<Text style={styles.editHeader}>Channel Members:</Text>
|
<Text style={styles.editHeader}>Channel Members:</Text>
|
||||||
<FlatList style={styles.editMembers}
|
<FlatList style={styles.editMembers}
|
||||||
data={state.connected}
|
data={state.connected}
|
||||||
renderItem={({ item }) => <Text>MEMBER</Text> }
|
renderItem={({ item }) => <MemberItem item={item} toggle={toggle} />}
|
||||||
keyExtractor={item => item.cardId}
|
keyExtractor={item => item.cardId}
|
||||||
/>
|
/>
|
||||||
<View style={styles.editControls}>
|
<View style={styles.editControls}>
|
||||||
|
31
app/mobile/src/session/details/memberItem/MemberItem.jsx
Normal file
31
app/mobile/src/session/details/memberItem/MemberItem.jsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { TouchableOpacity, Switch, Text, View } from 'react-native';
|
||||||
|
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
import { styles } from './MemberItem.styled';
|
||||||
|
import { Logo } from 'utils/Logo';
|
||||||
|
import { Colors } from 'constants/Colors';
|
||||||
|
|
||||||
|
export function MemberItem({ item, hostId, toggle }) {
|
||||||
|
|
||||||
|
const select = () => {
|
||||||
|
if (toggle) {
|
||||||
|
toggle(item.cardId, item.selected);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity style={styles.container} activeOpacity={1} onPress={select}>
|
||||||
|
<Logo src={item.logo} width={32} height={32} radius={6} />
|
||||||
|
<View style={styles.detail}>
|
||||||
|
<Text style={styles.name} numberOfLines={1} ellipsizeMode={'tail'}>{ item.name }</Text>
|
||||||
|
<Text style={styles.handle} numberOfLines={1} ellipsizeMode={'tail'}>{ item.handle }</Text>
|
||||||
|
</View>
|
||||||
|
{ hostId === item.cardId && (
|
||||||
|
<MatIcons name="server" size={20} color={Colors.grey} />
|
||||||
|
)}
|
||||||
|
{ toggle && (
|
||||||
|
<Switch style={styles.switch} trackColor={styles.track} value={item.selected} onValueChange={select} />
|
||||||
|
)}
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import { Colors } from 'constants/Colors';
|
||||||
|
|
||||||
|
export const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
width: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
height: 48,
|
||||||
|
alignItems: 'center',
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderColor: Colors.itemDivider,
|
||||||
|
paddingLeft: 8,
|
||||||
|
paddingRight: 8,
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
paddingLeft: 12,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flexGrow: 1,
|
||||||
|
flexShrink: 1,
|
||||||
|
},
|
||||||
|
space: {
|
||||||
|
height: 64,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
color: Colors.text,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
handle: {
|
||||||
|
color: Colors.text,
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
track: {
|
||||||
|
false: Colors.grey,
|
||||||
|
true: Colors.background,
|
||||||
|
},
|
||||||
|
switch: {
|
||||||
|
transform: [{ scaleX: .7 }, { scaleY: .7 }],
|
||||||
|
},
|
||||||
|
});
|
@ -5,6 +5,7 @@ import { CardContext } from 'context/CardContext';
|
|||||||
import { AccountContext } from 'context/AccountContext';
|
import { AccountContext } from 'context/AccountContext';
|
||||||
import { ProfileContext } from 'context/ProfileContext';
|
import { ProfileContext } from 'context/ProfileContext';
|
||||||
import { getChannelSubjectLogo } from 'context/channelUtil';
|
import { getChannelSubjectLogo } from 'context/channelUtil';
|
||||||
|
import { getCardByGuid } from 'context/cardUtil';
|
||||||
import { getChannelSeals, isUnsealed, getContentKey, updateChannelSubject } from 'context/sealUtil';
|
import { getChannelSeals, isUnsealed, getContentKey, updateChannelSubject } from 'context/sealUtil';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
@ -23,11 +24,11 @@ export function useDetails() {
|
|||||||
pushEnabled: false,
|
pushEnabled: false,
|
||||||
locked: false,
|
locked: false,
|
||||||
unlocked: false,
|
unlocked: false,
|
||||||
count: 0,
|
|
||||||
seals: null,
|
seals: null,
|
||||||
sealKey: null,
|
sealKey: null,
|
||||||
deleteBusy: false,
|
deleteBusy: false,
|
||||||
blockBusy: false,
|
blockBusy: false,
|
||||||
|
unknown: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const card = useContext(CardContext);
|
const card = useContext(CardContext);
|
||||||
@ -64,18 +65,49 @@ export function useDetails() {
|
|||||||
updateState({ locked, unlocked, seals, sealKey, notification });
|
updateState({ locked, unlocked, seals, sealKey, notification });
|
||||||
}, [account.state, conversation.state]);
|
}, [account.state, conversation.state]);
|
||||||
|
|
||||||
useEffect(() => {
|
const setMemberItem = (contact, guids) => {
|
||||||
const connected = [];
|
return {
|
||||||
card.state.cards.forEach(contact => {
|
cardId: contact?.cardId,
|
||||||
if (contact?.card?.detail?.status === 'connected') {
|
name: contact?.profile?.name,
|
||||||
connected.push(contact.card);
|
handle: contact?.profile?.handle,
|
||||||
}
|
node: contact?.profile?.node,
|
||||||
});
|
logo: contact?.profile?.imageSet ? card.actions.getCardImageUrl(contact.cardId) : 'avatar',
|
||||||
updateState({ connected });
|
selected: guids.includes(contact?.profile?.guid),
|
||||||
}, [card.state]);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const hostId = conversation.state.card?.cardId;
|
let unknown = 0;
|
||||||
|
let members = new Map();
|
||||||
|
const host = conversation.state.card;
|
||||||
|
if (host) {
|
||||||
|
members.set(host.card?.cardId, setMemberItem(host.card, []));
|
||||||
|
}
|
||||||
|
const guids = conversation.state.channel?.detail?.members || [];
|
||||||
|
guids.forEach(guid => {
|
||||||
|
if (guid !== profile.state.identity?.guid) {
|
||||||
|
const contact = getCardByGuid(card.state.cards, guid);
|
||||||
|
if (contact) {
|
||||||
|
members.set(contact.card?.cardId, setMemberItem(contact.card, []));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unknown++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const connected = new Map();
|
||||||
|
card.state.cards.forEach(contact => {
|
||||||
|
if (contact?.card?.detail?.status === 'connected') {
|
||||||
|
connected.set(contact.card?.cardId, setMemberItem(contact.card, guids));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
updateState({ connected: Array.from(connected.values()), members: Array.from(members.values()), unknown });
|
||||||
|
}, [card.state, conversation.state]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const hostId = conversation.state.card?.card.cardId;
|
||||||
const profileGuid = profile.state.identity?.guid;
|
const profileGuid = profile.state.identity?.guid;
|
||||||
const channel = conversation.state.channel;
|
const channel = conversation.state.channel;
|
||||||
const cards = card.state.cards;
|
const cards = card.state.cards;
|
||||||
@ -128,6 +160,24 @@ export function useDetails() {
|
|||||||
setSubjectUpdate: (subjectUpdate) => {
|
setSubjectUpdate: (subjectUpdate) => {
|
||||||
updateState({ subjectUpdate });
|
updateState({ subjectUpdate });
|
||||||
},
|
},
|
||||||
|
setCard: async (cardId) => {
|
||||||
|
updateState({ connected: state.connected.map(contact => {
|
||||||
|
if(contact.cardId === cardId) {
|
||||||
|
return { ...contact, selected: true }
|
||||||
|
}
|
||||||
|
return contact;
|
||||||
|
}) });
|
||||||
|
await conversation.actions.setChannelCard(cardId);
|
||||||
|
},
|
||||||
|
clearCard: async (cardId) => {
|
||||||
|
updateState({ connected: state.connected.map(contact => {
|
||||||
|
if(contact.cardId === cardId) {
|
||||||
|
return { ...contact, selected: false }
|
||||||
|
}
|
||||||
|
return contact;
|
||||||
|
}) });
|
||||||
|
await conversation.actions.clearChannelCard(cardId);
|
||||||
|
},
|
||||||
saveSubject: async () => {
|
saveSubject: async () => {
|
||||||
if (state.locked) {
|
if (state.locked) {
|
||||||
const contentKey = await getContentKey(state.seals, state.sealKey);
|
const contentKey = await getContentKey(state.seals, state.sealKey);
|
||||||
|
@ -69,7 +69,7 @@ export function useBlockedTopics() {
|
|||||||
});
|
});
|
||||||
channel.state.channels.forEach((channelItem, channelId, map) => {
|
channel.state.channels.forEach((channelItem, channelId, map) => {
|
||||||
if (channelItem.blocked) {
|
if (channelItem.blocked) {
|
||||||
marged.push({ channel: channelItem });
|
merged.push({ channel: channelItem });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const items = merged.map(setChannelItem);
|
const items = merged.map(setChannelItem);
|
||||||
|
Loading…
Reference in New Issue
Block a user