mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 01:55:17 +00:00
preparing to add messages
This commit is contained in:
parent
f5cc6ca9e7
commit
096e8f7548
@ -3,10 +3,7 @@ import {Colors} from '../constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
conversation: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '100%',
|
||||
minHeight: 0,
|
||||
flex: 1
|
||||
},
|
||||
messageList: {
|
||||
width: '100%',
|
||||
@ -70,5 +67,47 @@ export const styles = StyleSheet.create({
|
||||
},
|
||||
label: {
|
||||
fontSize: 24,
|
||||
},
|
||||
add: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
message: {
|
||||
width: '100%',
|
||||
fontSize: 14,
|
||||
padding: 0,
|
||||
},
|
||||
controls: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
gap: 8,
|
||||
},
|
||||
control: {
|
||||
borderRadius: 4,
|
||||
},
|
||||
surface: {
|
||||
borderRadius: 4,
|
||||
width: 36,
|
||||
height: 36,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
button: {
|
||||
color: Colors.primary,
|
||||
},
|
||||
end: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexGrow: 1,
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
separator: {
|
||||
width: 1,
|
||||
height: '100%',
|
||||
}
|
||||
});
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import {SafeAreaView, View, FlatList, TouchableOpacity} from 'react-native';
|
||||
import {KeyboardAvoidingView, Platform, SafeAreaView, Pressable, View, FlatList, TouchableOpacity} from 'react-native';
|
||||
import {styles} from './Conversation.styled';
|
||||
import {useConversation} from './useConversation.hook';
|
||||
import {Message} from '../message/Message';
|
||||
import {Icon, Text, IconButton, Divider} from 'react-native-paper';
|
||||
import {Surface, Icon, Text, TextInput, IconButton, Divider} from 'react-native-paper';
|
||||
import { ActivityIndicator } from 'react-native-paper';
|
||||
import { Colors } from '../constants/Colors';
|
||||
|
||||
const SCROLL_THRESHOLD = 16;
|
||||
|
||||
@ -69,9 +70,9 @@ export function Conversation({close}: {close: ()=>void}) {
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.conversation}>
|
||||
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} keyboardVerticalOffset={Platform.OS === 'ios' ? 64 : 50} style={styles.conversation}>
|
||||
<SafeAreaView style={styles.header}>
|
||||
<IconButton style={styles.icon} compact="true" mode="contained" icon="arrow-left" size={28} onPress={onClose} />
|
||||
<IconButton style={styles.icon} mode="contained" icon="arrow-left" size={28} onPress={onClose} />
|
||||
<View style={styles.title}>
|
||||
{ state.detailSet && state.subject && (
|
||||
<Text adjustsFontSizeToFit={true} numberOfLines={1} style={styles.label}>{ state.subject }</Text>
|
||||
@ -86,7 +87,7 @@ export function Conversation({close}: {close: ()=>void}) {
|
||||
<Text adjustsFontSizeToFit={true} numberOfLines={1} style={styles.unknown}>{ `, ${state.strings.unknownContact} (${state.unknownContacts})` }</Text>
|
||||
)}
|
||||
</View>
|
||||
<IconButton style={styles.icon} compact="true" mode="contained" icon="cog-outline" size={28} onPress={()=>{}} />
|
||||
<IconButton style={styles.icon} mode="contained" icon="cog-outline" size={28} onPress={()=>{}} />
|
||||
</SafeAreaView>
|
||||
<Divider style={styles.border} bold={true} />
|
||||
<View style={styles.thread}>
|
||||
@ -134,9 +135,21 @@ export function Conversation({close}: {close: ()=>void}) {
|
||||
)}
|
||||
</View>
|
||||
<Divider style={styles.border} bold={true} />
|
||||
<TouchableOpacity style={styles.add} onPress={() => thread.current.scrollToEnd()}>
|
||||
<Text>ADD</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.add}>
|
||||
<TextInput multiline={true} mode="outlined" style={styles.message} spellcheck={false} autoComplete="off" autoCapitalize="none" autoCorrect={false} placeholder={state.strings.newMessage} />
|
||||
<View style={styles.controls}>
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="camera" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="video-outline" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="volume-high" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="file-outline" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
<Divider style={styles.separator} />
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="format-color-text" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="format-size" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
<View style={styles.end}>
|
||||
<Pressable style={styles.control}><Surface style={styles.surface} elevation={2}><Icon style={styles.button} source="send" size={24} color={Colors.primary} /></Surface></Pressable>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
|
@ -2,4 +2,67 @@ import {StyleSheet} from 'react-native';
|
||||
import {Colors} from '../constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
modal: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
button: {
|
||||
position: 'absolute',
|
||||
borderRadius: 4,
|
||||
backgroundColor: '#444444',
|
||||
},
|
||||
container: {
|
||||
position: 'relative',
|
||||
width: 92,
|
||||
height: 92,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
cover: {
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
aspectRatio: 1,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
blur: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
binary: {
|
||||
position: 'relative',
|
||||
},
|
||||
thumb: {
|
||||
borderRadius: 4,
|
||||
width: 92,
|
||||
height: 92,
|
||||
},
|
||||
full: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
close: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
},
|
||||
closeIcon: {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
progress: {
|
||||
position: 'absolute',
|
||||
bottom: '10%',
|
||||
width: '50%',
|
||||
},
|
||||
});
|
||||
|
@ -1,11 +1,63 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text } from 'react-native-paper'
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { SafeAreaView, Modal, Pressable, View, Image } from 'react-native'
|
||||
import { Icon, ProgressBar, IconButton } from 'react-native-paper'
|
||||
import { useBinaryAsset } from './useBinaryAsset.hook';
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
import { styles } from './BinaryAsset.styled'
|
||||
import {BlurView} from '@react-native-community/blur';
|
||||
import Video from 'react-native-video'
|
||||
import thumb from '../../images/binary.png';
|
||||
|
||||
export function BinaryAsset({ topicId, asset }: { topicId: string, asset: MediaAsset }) {
|
||||
const { state, actions } = useBinaryAsset(topicId, asset);
|
||||
const [modal, setModal] = useState(false);
|
||||
|
||||
return (<Text>BINARY</Text>);
|
||||
const showBinary = () => {
|
||||
setModal(true);
|
||||
actions.loadBinary();
|
||||
};
|
||||
|
||||
const hideBinary = () => {
|
||||
setModal(false);
|
||||
actions.cancelLoad();
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.audio}>
|
||||
<Pressable style={styles.container} onPress={showBinary}>
|
||||
<Image
|
||||
style={styles.thumb}
|
||||
resizeMode="contain"
|
||||
source={thumb}
|
||||
/>
|
||||
<View style={styles.button}>
|
||||
<Icon size={28} source="download-outline" />
|
||||
</View>
|
||||
</Pressable>
|
||||
<Modal animationType="fade" transparent={true} supportedOrientations={['portrait', 'landscape']} visible={modal} onRequestClose={hideBinary}>
|
||||
<View style={styles.modal}>
|
||||
<BlurView style={styles.blur} blurType="dark" blurAmount={16} reducedTransparencyFallbackColor="dark" />
|
||||
<View style={styles.cover}>
|
||||
<Image
|
||||
style={styles.full}
|
||||
resizeMode="contain"
|
||||
source={thumb}
|
||||
/>
|
||||
<View style={styles.button}>
|
||||
<Icon size={64} source="download-outline" />
|
||||
</View>
|
||||
</View>
|
||||
{ state.loading && (
|
||||
<View style={styles.progress}>
|
||||
<ProgressBar progress={state.loadPercent / 100} />
|
||||
</View>
|
||||
)}
|
||||
<SafeAreaView style={styles.close}>
|
||||
<IconButton style={styles.closeIcon} icon="close" compact="true" mode="contained" size={28} onPress={hideBinary} />
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
</Modal>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useState, useContext, useEffect } from 'react'
|
||||
import { useState, useContext, useEffect, useRef } from 'react'
|
||||
import { AppContext } from '../../context/AppContext'
|
||||
import { Focus } from 'databag-client-sdk'
|
||||
import { ContextType } from '../../context/ContextType'
|
||||
@ -7,10 +7,12 @@ import { MediaAsset } from '../../conversation/Conversation';
|
||||
export function useBinaryAsset(topicId: string, asset: MediaAsset) {
|
||||
const app = useContext(AppContext) as ContextType
|
||||
const [state, setState] = useState({
|
||||
dataUrl: '',
|
||||
dataUrl: null,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
loadPercent: 0,
|
||||
})
|
||||
const cancelled = useRef(false);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updateState = (value: any) => {
|
||||
@ -18,21 +20,22 @@ export function useBinaryAsset(topicId: string, asset: MediaAsset) {
|
||||
}
|
||||
|
||||
const actions = {
|
||||
unloadBinary: () => {
|
||||
updateState({ dataUrl: null });
|
||||
cancelLoad: () => {
|
||||
cancelled.current = true;
|
||||
},
|
||||
loadBinary: async () => {
|
||||
const { focus } = app.state;
|
||||
const assetId = asset.binary ? asset.binary.data : asset.encrypted ? asset.encrypted.parts : null;
|
||||
if (focus && assetId != null && !state.loading) {
|
||||
const assetId = asset.audio ? asset.audio.full : asset.encrypted ? asset.encrypted.parts : null;
|
||||
if (focus && assetId != null && !state.loading && !state.dataUrl) {
|
||||
cancelled.current = false;
|
||||
updateState({ loading: true, loadPercent: 0 });
|
||||
try {
|
||||
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId, (loadPercent: number)=>{ updateState({ loadPercent }) });
|
||||
updateState({ dataUrl, loading: false });
|
||||
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId, (loadPercent: number)=>{ updateState({ loadPercent }); return !cancelled.current });
|
||||
updateState({ dataUrl });
|
||||
} catch (err) {
|
||||
updateState({ loading: false });
|
||||
console.log(err);
|
||||
}
|
||||
updateState({ loading: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ export function getLegacyData(data: any): { data: any, assets: AssetItem[] } {
|
||||
}
|
||||
assetItems.add(dataAsset);
|
||||
index += 1;
|
||||
return { audio: { label, extension, data: `${index-1}` }};
|
||||
return { binary: { label, extension, data: `${index-1}` }};
|
||||
}
|
||||
}
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user