render image asset

This commit is contained in:
balzack 2022-10-05 00:09:57 -07:00
parent a7c97de50e
commit 132816bfe9
11 changed files with 141 additions and 8 deletions

View File

@ -287,6 +287,18 @@ export function useConversationContext() {
}
}
},
getTopicAssetUrl: (topicId, assetId) => {
if (conversationId.current) {
const { cardId, channelId } = conversationId.current;
if (cardId) {
return card.actions.getChannelTopicAssetUrl(cardId, channelId, topicId, assetId);
}
else {
return channel.actions.getTopicAssetUrl(channelId, topicId, assetId);
}
}
return null;
},
}
return { state, actions }

View File

@ -13,7 +13,7 @@ export function ChannelsTitle({ state, actions }) {
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="search1" size={16} color={Colors.disabled} />
<TextInput style={styles.inputfield} value={state.filter} onChangeText={actions.setFilter}
autoCapitalize="none" placeholderTextColor={Colors.disabled} placeholder="Topic" />
autoCapitalize="none" placeholderTextColor={Colors.disabled} placeholder="Topics" />
<View style={styles.space} />
</View>
<TouchableOpacity style={styles.add}>
@ -43,7 +43,7 @@ export function Channels({ openConversation }) {
<View style={styles.inputwrapper}>
<Ionicons style={styles.icon} name="search1" size={16} color={Colors.disabled} />
<TextInput style={styles.inputfield} value={state.topic} onChangeText={actions.setTopic}
autoCapitalize="none" placeholderTextColor={Colors.disabled} placeholder="Topic" />
autoCapitalize="none" placeholderTextColor={Colors.disabled} placeholder="Topics" />
<View style={styles.space} />
</View>
</SafeAreaView>

View File

@ -15,7 +15,7 @@ export function ImageFile({ path, setPosition, remove }) {
return (
<TouchableOpacity activeOpacity={1} onLongPress={remove}>
<Image source={{ uri: path }} style={{ width: 92 * state.ratio, height: 92, marginRight: 16 }} resizeMode={'contain'} />
<Image source={{ uri: path }} style={{ width: 92 * state.ratio, height: 92, marginRight: 16 }} resizeMode={'cover'} />
</TouchableOpacity>
);
}

View File

@ -1,12 +1,29 @@
import { View, Text, TouchableOpacity } from 'react-native';
import { FlatList, ActivityIndicator, View, Text, TouchableOpacity } from 'react-native';
import { useTopicItem } from './useTopicItem.hook';
import { styles } from './TopicItem.styled';
import { Logo } from 'utils/Logo';
import Colors from 'constants/Colors';
import { VideoAsset } from './videoAsset/VideoAsset';
import { AudioAsset } from './audioAsset/AudioAsset';
import { ImageAsset } from './imageAsset/ImageAsset';
export function TopicItem({ item }) {
const { state, actions } = useTopicItem(item);
const renderAsset = (asset) => {
if (asset.item.image) {
return <ImageAsset topicId={item.topicId} asset={asset.item.image} />
}
if (asset.item.video) {
return <VideoAsset topicId={item.topicId} asset={asset.item.video} />
}
if (asset.item.audio) {
return <AudioAsset topicId={item.topicId} asset={asset.item.audio} />
}
return <></>
};
return (
<View style={styles.item}>
<View style={styles.header}>
@ -14,7 +31,27 @@ export function TopicItem({ item }) {
<Text style={styles.name}>{ state.name }</Text>
<Text style={styles.timestamp}>{ state.timestamp }</Text>
</View>
<Text style={styles.message}>{ state.message }</Text>
{ state.status === 'confirmed' && (
<>
{ state.transform === 'complete' && state.assets && (
<FlatList style={styles.carousel}
data={state.assets}
horizontal={true}
renderItem={renderAsset}
/>
)}
{ state.transform === 'incomplete' && (
<ActivityIndicator size="large" color={Colors.background} />
)}
{ state.transform === 'error' && (
<ActivityIndicator size="large" color={Colors.alert} />
)}
<Text style={styles.message}>{ state.message }</Text>
</>
)}
{ state.status !== 'confirmed' && (
<ActivityIndicator size="large" color={Colors.divider} />
)}
</View>
);
}

View File

@ -22,5 +22,10 @@ export const styles = StyleSheet.create({
message: {
paddingLeft: 52,
},
carousel: {
paddingLeft: 52,
marginTop: 4,
marginBottom: 4,
},
})

View File

@ -0,0 +1,6 @@
import { Text } from 'react-native';
export function AudioAsset() {
return <Text>AUDIO</Text>
}

View File

@ -0,0 +1,17 @@
import { Image, TouchableOpacity } from 'react-native';
import { useImageAsset } from './useImageAsset.hook';
import { styles } from './ImageAsset.styled';
import Colors from 'constants/Colors';
export function ImageAsset({ topicId, asset }) {
const { state, actions } = useImageAsset(topicId, asset);
return (
<TouchableOpacity activeOpacity={1}>
<Image source={{ uri: state.url }} style={{ borderRadius: 4, width: 92 * state.ratio, height: 92, marginRight: 16 }} resizeMode={'cover'} />
</TouchableOpacity>
);
}

View File

@ -0,0 +1,17 @@
import { StyleSheet } from 'react-native';
import { Colors } from 'constants/Colors';
export const styles = StyleSheet.create({
overlay: {
marginRight: 16,
position: 'absolute',
bottom: 0,
right: 0,
padding: 2,
borderTopLeftRadius: 4,
backgroundColor: Colors.white,
borderWidth: 1,
borderColor: Colors.divider,
},
})

View File

@ -0,0 +1,32 @@
import { useState, useRef, useEffect, useContext } from 'react';
import { ConversationContext } from 'context/ConversationContext';
import { Image } from 'react-native';
export function useImageAsset(topicId, asset) {
const [state, setState] = useState({
ratio: 1,
url: null,
});
const conversation = useContext(ConversationContext);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
const url = conversation.actions.getTopicAssetUrl(topicId, asset.thumb);
if (url) {
Image.getSize(url, (width, height) => {
updateState({ url, ratio: width / height });
});
}
}, [topicId, conversation, asset]);
const actions = {
};
return { state, actions };
}

View File

@ -67,10 +67,11 @@ export function useTopicItem(item) {
}
}
let message;
let message, assets;
try {
const data = JSON.parse(item.detail.data);
message = data.text;
assets = data.assets;
}
catch (err) {
console.log("empty message");
@ -81,7 +82,7 @@ export function useTopicItem(item) {
const now = new Date();
const offset = now.getTime() - date.getTime();
if(offset < 86400000) {
timestamp = moment(date).format('h:mm');
timestamp = moment(date).format('h:mma');
}
else if (offset < 31449600000) {
timestamp = moment(date).format('M/DD');
@ -90,7 +91,7 @@ export function useTopicItem(item) {
timestamp = moment(date).format('M/DD/YYYY');
}
updateState({ logo, name, known, message, timestamp });
updateState({ logo, name, known, message, timestamp, transform, status, assets });
}, [card, item]);
const actions = {

View File

@ -0,0 +1,6 @@
import { Text } from 'react-native';
export function VideoAsset() {
return <Text>VIDEO</Text>
}