mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 12:39:17 +00:00
passing share intent to selected topic
This commit is contained in:
parent
9dbd64833b
commit
e3bf231b32
@ -39,7 +39,6 @@ export default function App() {
|
||||
|
||||
const clearSharing = () => {
|
||||
setSharing(null);
|
||||
ReceiveSharingIntent.clearReceivedFiles();
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -16,6 +16,7 @@ export const Colors = {
|
||||
disabled: '#aaaaaa',
|
||||
text: '#444444',
|
||||
link: '#0077CC',
|
||||
lightText: '#686868',
|
||||
|
||||
active: '#222222',
|
||||
idle: '#707070',
|
||||
|
@ -39,7 +39,7 @@ const CardDrawer = createDrawerNavigator();
|
||||
const RegistryDrawer = createDrawerNavigator();
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
function ConversationStackScreen({ dmChannel }) {
|
||||
function ConversationStackScreen({ dmChannel, shareChannel, shareIntent, setShareIntent }) {
|
||||
const stackParams = { headerStyle: { backgroundColor: Colors.titleBackground }, headerBackTitleVisible: false };
|
||||
const screenParams = { headerShown: true, headerTintColor: Colors.primary };
|
||||
|
||||
@ -76,11 +76,11 @@ function ConversationStackScreen({ dmChannel }) {
|
||||
<ConversationStack.Navigator initialRouteName="channels" screenOptions={({ route }) => (screenParams)} >
|
||||
|
||||
<ConversationStack.Screen name="channels" options={stackParams}>
|
||||
{(props) => <Channels navigation={props.navigation} dmChannel={dmChannel} openConversation={(cardId, channelId) => openConversation(props.navigation, cardId, channelId)} />}
|
||||
{(props) => <Channels navigation={props.navigation} dmChannel={dmChannel} shareChannel={shareChannel} openConversation={(cardId, channelId) => openConversation(props.navigation, cardId, channelId)} />}
|
||||
</ConversationStack.Screen>
|
||||
|
||||
<ConversationStack.Screen name="conversation" options={stackParams}>
|
||||
{(props) => <Conversation navigation={props.navigation} openDetails={() => openDetails(props.navigation)} closeConversation={(pop) => closeConversation(props.navigation, pop)} /> }
|
||||
{(props) => <Conversation navigation={props.navigation} openDetails={() => openDetails(props.navigation)} closeConversation={(pop) => closeConversation(props.navigation, pop)} shareIntent={shareIntent} setShareIntent={setShareIntent} /> }
|
||||
</ConversationStack.Screen>
|
||||
|
||||
<ConversationStack.Screen name="details" options={{ ...stackParams, headerTitle: (props) => (
|
||||
@ -216,13 +216,13 @@ function HomeScreen({ navParams }) {
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.channels}>
|
||||
<Channels dmChannel={navParams.dmChannel} cardId={cardId} channelId={channelId} openConversation={setConversation} />
|
||||
<Channels dmChannel={navParams.dmChannel} shareChannel={shareChannel} cardId={cardId} channelId={channelId} openConversation={setConversation} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
<View style={styles.conversation}>
|
||||
{ channel && (
|
||||
<SafeAreaView edges={['top', 'bottom', 'right']}>
|
||||
<Conversation closeConversation={closeConversation} openDetails={openDetails} />
|
||||
<Conversation closeConversation={closeConversation} openDetails={openDetails} shareIntent={navParams.shareIntent} setShareIntent={navParams.setShareIntent} />
|
||||
</SafeAreaView>
|
||||
)}
|
||||
{ !channel && (
|
||||
@ -330,17 +330,18 @@ export function Session({ sharing, clearSharing }) {
|
||||
setDmChannel({ id });
|
||||
};
|
||||
|
||||
const setShare = async (cardId, channelId) => {
|
||||
console.log("SET SHARE CHANNEL");
|
||||
const [shareIntent, setShareIntent] = useState(null);
|
||||
const [shareChannel, setShareChannel] = useState(null);
|
||||
const setShare = async ({ cardId, channelId }) => {
|
||||
setShareIntent(sharing);
|
||||
setShareChannel({ cardId, channelId });
|
||||
clearSharing();
|
||||
}
|
||||
const clearShare = async () => {
|
||||
console.log("CLEAR SHARE CHANNEL");
|
||||
clearSharing();
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log("COMPARE", sharing, intent);
|
||||
if (sharing != intent && sharing != null) {
|
||||
navigate('/');
|
||||
}
|
||||
@ -408,7 +409,7 @@ export function Session({ sharing, clearSharing }) {
|
||||
<ScrollView style={styles.drawer}><SafeAreaView edges={['top', 'bottom', 'right']}><Profile /></SafeAreaView></ScrollView>
|
||||
)}>
|
||||
<ProfileDrawer.Screen name="detail">
|
||||
{(props) => <DetailDrawerScreen navParams={{ profileNav: props.navigation, state, actions, addChannel, dmChannel }} />}
|
||||
{(props) => <DetailDrawerScreen navParams={{ profileNav: props.navigation, state, actions, addChannel, dmChannel, shareChannel, shareIntent, setShareIntent }} />}
|
||||
</ProfileDrawer.Screen>
|
||||
</ProfileDrawer.Navigator>
|
||||
)}
|
||||
@ -432,7 +433,7 @@ export function Session({ sharing, clearSharing }) {
|
||||
tabBarActiveTintColor: Colors.white,
|
||||
tabBarInactiveTintColor: Colors.disabled,
|
||||
})}>
|
||||
<Tab.Screen name="Conversation" children={()=><ConversationStackScreen dmChannel={dmChannel} />} />
|
||||
<Tab.Screen name="Conversation" children={()=><ConversationStackScreen dmChannel={dmChannel} shareChannel={shareChannel} shareIntent={shareIntent} setShareIntent={setShareIntent} />} />
|
||||
<Tab.Screen name="Profile" component={ProfileStackScreen} />
|
||||
<Tab.Screen name="Contacts" children={()=><ContactStackScreen addChannel={addChannel} />} />
|
||||
</Tab.Navigator>
|
||||
@ -464,7 +465,7 @@ export function Session({ sharing, clearSharing }) {
|
||||
<Modal
|
||||
animationType="fade"
|
||||
transparent={true}
|
||||
visible={intent != null}
|
||||
visible={sharing != null && intent != null}
|
||||
supportedOrientations={['portrait', 'landscape']}
|
||||
>
|
||||
<Sharing select={setShare} cancel={clearShare} />
|
||||
|
@ -7,7 +7,7 @@ import { Colors } from 'constants/Colors';
|
||||
import { ChannelItem } from './channelItem/ChannelItem';
|
||||
import { AddMember } from './addMember/AddMember';
|
||||
|
||||
export function Channels({ cardId, channelId, navigation, openConversation, dmChannel }) {
|
||||
export function Channels({ cardId, channelId, navigation, openConversation, dmChannel, shareChannel }) {
|
||||
|
||||
const { state, actions } = useChannels();
|
||||
|
||||
@ -32,6 +32,12 @@ export function Channels({ cardId, channelId, navigation, openConversation, dmCh
|
||||
}
|
||||
}, [dmChannel]);
|
||||
|
||||
useEffect(() => {
|
||||
if (shareChannel) {
|
||||
openConversation(shareChannel.cardId, shareChannel.channelId);
|
||||
}
|
||||
}, [shareChannel]);
|
||||
|
||||
useEffect(() => {
|
||||
if (navigation) {
|
||||
navigation.setOptions({
|
||||
|
@ -2,7 +2,6 @@ import { Text, View } from 'react-native';
|
||||
import { TouchableOpacity } from 'react-native-gesture-handler';
|
||||
import { Logo } from 'utils/Logo';
|
||||
import { styles } from './ChannelItem.styled';
|
||||
import { useChannelItem } from './useChannelItem.hook';
|
||||
import Colors from 'constants/Colors';
|
||||
import Ionicons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { Logo } from 'utils/Logo';
|
||||
import { AddTopic } from './addTopic/AddTopic';
|
||||
import { TopicItem } from './topicItem/TopicItem';
|
||||
|
||||
export function Conversation({ navigation, cardId, channelId, closeConversation, openDetails }) {
|
||||
export function Conversation({ navigation, cardId, channelId, closeConversation, openDetails, shareIntent, setShareIntent }) {
|
||||
|
||||
const { state, actions } = useConversation();
|
||||
|
||||
@ -113,7 +113,7 @@ export function Conversation({ navigation, cardId, channelId, closeConversation,
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<AddTopic contentKey={state.contentKey} />
|
||||
<AddTopic contentKey={state.contentKey} shareIntent={shareIntent} setShareIntent={setShareIntent} />
|
||||
</View>
|
||||
<Modal
|
||||
animationType="fade"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ActivityIndicator, Modal, Image, FlatList, TextInput, Alert, View, TouchableOpacity, Text, } from 'react-native';
|
||||
import { useState, useRef } from 'react';
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { useAddTopic } from './useAddTopic.hook';
|
||||
import { styles } from './AddTopic.styled';
|
||||
import AntIcons from 'react-native-vector-icons/AntDesign';
|
||||
@ -13,10 +13,35 @@ import { VideoFile } from './videoFile/VideoFile';
|
||||
import { AudioFile } from './audioFile/AudioFile';
|
||||
import { ImageFile } from './imageFile/ImageFile';
|
||||
|
||||
export function AddTopic({ contentKey }) {
|
||||
export function AddTopic({ contentKey, shareIntent, setShareIntent }) {
|
||||
|
||||
const { state, actions } = useAddTopic(contentKey);
|
||||
|
||||
useEffect(() => {
|
||||
if (shareIntent) {
|
||||
Alert.alert('SHARING', JSON.stringify(shareIntent));
|
||||
shareIntent.forEach(share => {
|
||||
if (share.text) {
|
||||
actions.setMessage(share.text);
|
||||
}
|
||||
if (share.weblink) {
|
||||
actions.setMessage(share.weblink);
|
||||
}
|
||||
const mimeType = share.mimeType?.toLowerCase();
|
||||
if (mimeType === '.jpg' || mimeType === '.png') {
|
||||
actions.addImage(share.filePath)
|
||||
}
|
||||
if (mimeType === '.mp4') {
|
||||
actions.addVideo(share.filePath)
|
||||
}
|
||||
if (mimeType === '.mp3') {
|
||||
actions.addAudio(share.filePath)
|
||||
}
|
||||
});
|
||||
setShareIntent(null);
|
||||
}
|
||||
}, [shareIntent]);
|
||||
|
||||
const addImage = async () => {
|
||||
try {
|
||||
const full = await ImagePicker.openPicker({ mediaType: 'photo' });
|
||||
|
@ -289,9 +289,9 @@ export function useTopicItem(item, hosting, remove, contentKey) {
|
||||
}
|
||||
}
|
||||
|
||||
await Share.open({ urls: files, message: data.text, title: 'Databag', subject: 'Shared from Databag' })
|
||||
await Share.open({ urls: files, message: files.length > 0 ? null : data.text, title: 'Databag', subject: 'Shared from Databag' })
|
||||
while (unlink.length > 0) {
|
||||
const file = fs.unlink.shift();
|
||||
const file = unlink.shift();
|
||||
await fs.unlink(file);
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,42 @@
|
||||
import { Text, View } from 'react-native';
|
||||
import { useState } from 'react';
|
||||
import { TouchableOpacity, Text, View, FlatList } from 'react-native';
|
||||
import { useSharing } from './useSharing.hook';
|
||||
import { styles } from './Sharing.styled';
|
||||
import { SharingItem } from './sharingItem/SharingItem';
|
||||
|
||||
export function Sharing({ setShare, clearShare }) {
|
||||
export function Sharing({ select, cancel }) {
|
||||
|
||||
const [selection, setSelection] = useState(null);
|
||||
const { state, actions } = useSharing();
|
||||
|
||||
return (
|
||||
<View style={styles.sharingBase}>
|
||||
<View style={styles.sharingFrame}>
|
||||
<Text>SHARING</Text>
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.headerText}>Select Topic for Sharing</Text>
|
||||
</View>
|
||||
<FlatList
|
||||
style={styles.content}
|
||||
data={state.channels}
|
||||
initialNumToRender={25}
|
||||
renderItem={({ item }) => <SharingItem select={setSelection} selection={selection} item={item} />}
|
||||
keyExtractor={item => (`${item.cardId}:${item.channelId}`)}
|
||||
/>
|
||||
<View style={styles.controls}>
|
||||
{ !selection && (
|
||||
<View style={styles.disabled}>
|
||||
<Text style={styles.disabledText}>Select</Text>
|
||||
</View>
|
||||
)}
|
||||
{ selection && (
|
||||
<TouchableOpacity style={styles.select} onPress={() => select(selection)}>
|
||||
<Text style={styles.selectText}>Select</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<TouchableOpacity style={styles.cancel} onPress={cancel}>
|
||||
<Text style={styles.cancelText}>Cancel</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
@ -12,10 +12,81 @@ export const styles = StyleSheet.create({
|
||||
},
|
||||
sharingFrame: {
|
||||
backgroundColor: Colors.formBackground,
|
||||
padding: 8,
|
||||
width: '80%',
|
||||
height: '80%',
|
||||
maxWidth: 400,
|
||||
maxHeight: 600,
|
||||
borderRadius: 4,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
header: {
|
||||
padding: 8,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
},
|
||||
headerText: {
|
||||
fontSize: 18,
|
||||
},
|
||||
content: {
|
||||
width: '100%',
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
},
|
||||
controls: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
width: '100%',
|
||||
padding: 4,
|
||||
borderTopWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
select: {
|
||||
borderRadius: 3,
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.primary,
|
||||
backgroundColor: Colors.primary,
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 4,
|
||||
margin: 8,
|
||||
},
|
||||
selectText: {
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
},
|
||||
disabled: {
|
||||
borderRadius: 3,
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.grey,
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 4,
|
||||
margin: 8,
|
||||
},
|
||||
disabledText: {
|
||||
fontSize: 16,
|
||||
color: Colors.grey,
|
||||
},
|
||||
cancel: {
|
||||
borderRadius: 3,
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.text,
|
||||
paddingLeft: 16,
|
||||
paddingRight: 16,
|
||||
paddingTop: 4,
|
||||
paddingBottom: 4,
|
||||
margin: 8,
|
||||
},
|
||||
cancelText: {
|
||||
fontSize: 16,
|
||||
color: Colors.text,
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
|
@ -1,16 +1,125 @@
|
||||
import { useState } from 'react';
|
||||
import { useState, useRef, useEffect, useContext } from 'react';
|
||||
import { ChannelContext } from 'context/ChannelContext';
|
||||
import { CardContext } from 'context/CardContext';
|
||||
import { AccountContext } from 'context/AccountContext';
|
||||
import { ProfileContext } from 'context/ProfileContext';
|
||||
import { getChannelSeals, isUnsealed, getContentKey, encryptChannelSubject, decryptChannelSubject, decryptTopicSubject } from 'context/sealUtil';
|
||||
import { getCardByGuid } from 'context/cardUtil';
|
||||
import { getChannelSubjectLogo } from 'context/channelUtil';
|
||||
|
||||
export function useSharing() {
|
||||
const [state, setState] = useState({
|
||||
channels: [],
|
||||
});
|
||||
|
||||
const channel = useContext(ChannelContext);
|
||||
const card = useContext(CardContext);
|
||||
const account = useContext(AccountContext);
|
||||
const profile = useContext(ProfileContext);
|
||||
|
||||
const resync = useRef(false);
|
||||
const syncing = useRef(false);
|
||||
|
||||
const updateState = (value) => {
|
||||
setState((s) => ({ ...s, ...value }));
|
||||
}
|
||||
|
||||
const setChannelItem = async (cardId, channelId, item) => {
|
||||
const timestamp = item.summary.lastTopic.created;
|
||||
|
||||
// decrypt subject and message
|
||||
let locked = false;
|
||||
let unlocked = false;
|
||||
if (item.detail.dataType === 'sealed') {
|
||||
locked = true;
|
||||
const seals = getChannelSeals(item.detail.data);
|
||||
if (isUnsealed(seals, account.state.sealKey)) {
|
||||
unlocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
let message;
|
||||
if (item?.detail?.dataType === 'sealed') {
|
||||
if (typeof item?.unsealedSummary?.message?.text === 'string') {
|
||||
message = item.unsealedSummary.message.text;
|
||||
}
|
||||
}
|
||||
if (item.detail.dataType === 'superbasic') {
|
||||
if (item.summary.lastTopic.dataType === 'superbasictopic') {
|
||||
try {
|
||||
const data = JSON.parse(item.summary.lastTopic.data);
|
||||
if (typeof data.text === 'string') {
|
||||
message = data.text;
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const profileGuid = profile.state?.identity?.guid;
|
||||
const { logo, subject } = getChannelSubjectLogo(cardId, profileGuid, item, card.state.cards, card.actions.getCardImageUrl);
|
||||
|
||||
return { cardId, channelId, subject, message, logo, timestamp, locked, unlocked };
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
syncChannels();
|
||||
}, [account.state, card.state, channel.state]);
|
||||
|
||||
const syncChannels = async () => {
|
||||
if (syncing.current) {
|
||||
resync.current = true;
|
||||
}
|
||||
else {
|
||||
syncing.current = true;
|
||||
|
||||
const items = [];
|
||||
channel.state.channels.forEach((item, channelId) => {
|
||||
items.push({ channelId, channelItem: item });
|
||||
});
|
||||
card.state.cards.forEach((cardItem, cardId) => {
|
||||
cardItem.channels.forEach((channelItem, channelId) => {
|
||||
items.push({ cardId, channelId, channelItem });
|
||||
});
|
||||
});
|
||||
const channels = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const { cardId, channelId, channelItem } = items[i];
|
||||
channels.push(await setChannelItem(cardId, channelId, channelItem));
|
||||
}
|
||||
const filtered = channels.filter(item => {
|
||||
if (!item.locked || item.unlocked) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const sorted = filtered.sort((a, b) => {
|
||||
const aCreated = a?.timestamp;
|
||||
const bCreated = b?.timestamp;
|
||||
if (aCreated === bCreated) {
|
||||
return 0;
|
||||
}
|
||||
if (!aCreated || aCreated < bCreated) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
updateState({ channels: sorted });
|
||||
|
||||
syncing.current = false;
|
||||
if(resync.current) {
|
||||
resync.current = false;
|
||||
await syncChannels();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const actions = {
|
||||
};
|
||||
|
||||
return { state, actions };
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user