mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 01:55:17 +00:00
rendering image asset
This commit is contained in:
parent
ce2ffabe9b
commit
219c04e213
@ -44,7 +44,7 @@ export const styles = StyleSheet.create({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
back: {
|
||||
icon: {
|
||||
flexShrink: 0,
|
||||
marginRight: 0,
|
||||
marginLeft: 0,
|
||||
@ -59,15 +59,14 @@ export const styles = StyleSheet.create({
|
||||
header: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
},
|
||||
iconSpace: {
|
||||
width: '10%',
|
||||
width: '100%',
|
||||
minWidth: 0,
|
||||
},
|
||||
title: {
|
||||
width: '80%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
flexGrow: 1,
|
||||
},
|
||||
label: {
|
||||
fontSize: 24,
|
||||
|
@ -19,7 +19,7 @@ export type MediaAsset = {
|
||||
export function Conversation({close}: {close: ()=>void}) {
|
||||
const { state, actions } = useConversation();
|
||||
const [ more, setMore ] = useState(false);
|
||||
const [ selected, setSelected ] = useState(null);
|
||||
const [ selected, setSelected ] = useState(null as null | string);
|
||||
const thread = useRef();
|
||||
|
||||
const scrolled = useRef(false);
|
||||
@ -71,11 +71,7 @@ export function Conversation({close}: {close: ()=>void}) {
|
||||
return (
|
||||
<View style={styles.conversation}>
|
||||
<SafeAreaView style={styles.header}>
|
||||
{close && (
|
||||
<View style={styles.iconSpace}>
|
||||
<IconButton style={styles.back} compact="true" mode="contained" icon="arrow-left" size={28} onPress={onClose} />
|
||||
</View>
|
||||
)}
|
||||
<IconButton style={styles.icon} compact="true" 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>
|
||||
@ -90,7 +86,7 @@ export function Conversation({close}: {close: ()=>void}) {
|
||||
<Text adjustsFontSizeToFit={true} numberOfLines={1} style={styles.unknown}>{ `, ${state.strings.unknownContact} (${state.unknownContacts})` }</Text>
|
||||
)}
|
||||
</View>
|
||||
{close && <View style={styles.iconSpace} />}
|
||||
<IconButton style={styles.icon} compact="true" mode="contained" icon="cog-outline" size={28} onPress={()=>{}} />
|
||||
</SafeAreaView>
|
||||
<Divider style={styles.border} bold={true} />
|
||||
<View style={styles.thread}>
|
||||
@ -116,7 +112,7 @@ export function Conversation({close}: {close: ()=>void}) {
|
||||
card={card}
|
||||
profile={profile}
|
||||
host={host}
|
||||
select={(id: string)=>setSelected(id)}
|
||||
select={(id)=>setSelected(id)}
|
||||
selected={selected}
|
||||
/>
|
||||
)
|
||||
|
@ -79,4 +79,18 @@ export const styles = StyleSheet.create({
|
||||
paddingRight: 12,
|
||||
paddingTop: 4,
|
||||
},
|
||||
carousel: {
|
||||
paddingLeft: 8,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
assets: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: 16,
|
||||
},
|
||||
item: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
backgroundColor: 'yellow',
|
||||
}
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useRef, useEffect, useState, useCallback } from 'react';
|
||||
import { avatar } from '../constants/Icons'
|
||||
import { Pressable, View, Image } from 'react-native';
|
||||
import { Pressable, ScrollView, View, Image } from 'react-native';
|
||||
import {Icon, Text, IconButton, Surface, Divider} from 'react-native-paper';
|
||||
import { Topic, Card, Profile } from 'databag-client-sdk';
|
||||
import { ImageAsset } from './imageAsset/ImageAsset';
|
||||
@ -9,8 +9,9 @@ import { VideoAsset } from './videoAsset/VideoAsset';
|
||||
import { BinaryAsset } from './binaryAsset/BinaryAsset';
|
||||
import { useMessage } from './useMessage.hook';
|
||||
import {styles} from './Message.styled';
|
||||
import { MediaAsset } from '../conversation/Conversatin';
|
||||
|
||||
export function Message({ topic, card, profile, host, select, selected }: { topic: Topic, card: Card | null, profile: Profile | null, host: boolean, select: (id: string)=>void, selected: string }) {
|
||||
export function Message({ topic, card, profile, host, select, selected }: { topic: Topic, card: Card | null, profile: Profile | null, host: boolean, select: (id: null | string)=>void, selected: string }) {
|
||||
const { state, actions } = useMessage();
|
||||
const { locked, data, created, topicId, status, transform } = topic;
|
||||
const { name, handle, node } = profile || card || { name: null, handle: null, node: null }
|
||||
@ -23,13 +24,27 @@ export function Message({ topic, card, profile, host, select, selected }: { topi
|
||||
const [editText, setEditText] = useState('');
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
const media = !assets ? [] : assets.map((asset: MediaAsset, index: number) => {
|
||||
if (asset.image || asset.encrypted?.type === 'image') {
|
||||
return <ImageAsset key={index} topicId={topicId} asset={asset as MediaAsset} />
|
||||
} else if (asset.audio || asset.encrypted?.type === 'audio') {
|
||||
return <AudioAsset key={index} topicId={topicId} asset={asset as MediaAsset} />
|
||||
} else if (asset.video || asset.encrypted?.type === 'video') {
|
||||
return <VideoAsset key={index} topicId={topicId} asset={asset as MediaAsset} />
|
||||
} else if (asset.binary || asset.encrypted?.type === 'binary') {
|
||||
return <BinaryAsset key={index} topicId={topicId} asset={asset as MediaAsset} />
|
||||
} else {
|
||||
return <View key={index}></View>
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={styles.message}>
|
||||
<View style={styles.topic}>
|
||||
<View style={styles.content}>
|
||||
<Image style={styles.logo} resizeMode={'contain'} source={{uri: logoUrl}} />
|
||||
<View style={styles.body}>
|
||||
<Pressable style={styles.header} onPress={()=>select(topicId)}>
|
||||
<Pressable style={styles.header} onPress={()=>select(topicId == selected ? null : topicId)}>
|
||||
<View style={styles.name}>
|
||||
{ name && (
|
||||
<Text style={styles.handle}>{ name }</Text>
|
||||
@ -62,6 +77,11 @@ export function Message({ topic, card, profile, host, select, selected }: { topi
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
{ assets?.length > 0 && (
|
||||
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} style={styles.carousel} contentContainerStyle={styles.assets}>
|
||||
{ media }
|
||||
</ScrollView>
|
||||
)}
|
||||
{ topicId === selected && (
|
||||
<Surface style={styles.options}>
|
||||
<IconButton style={styles.option} loading={false} compact="true" mode="contained" icon="share-variant-outline" size={24} onPress={() => {}} />
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text } from 'react-native'
|
||||
import { Text } from 'react-native-paper'
|
||||
import { useAudioAsset } from './useAudioAsset.hook';
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text } from 'react-native'
|
||||
import { Text } from 'react-native-paper'
|
||||
import { useBinaryAsset } from './useBinaryAsset.hook';
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
|
||||
|
@ -2,4 +2,9 @@ import {StyleSheet} from 'react-native';
|
||||
import {Colors} from '../constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
image: {
|
||||
},
|
||||
thumb: {
|
||||
borderRadius: 4,
|
||||
},
|
||||
});
|
||||
|
@ -1,11 +1,37 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text } from 'react-native'
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Animated, View, Image, useAnimatedValue } from 'react-native'
|
||||
import { Text } from 'react-native-paper'
|
||||
import { useImageAsset } from './useImageAsset.hook';
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
import { styles } from './ImageAsset.styled'
|
||||
|
||||
export function ImageAsset({ topicId, asset }: { topicId: string, asset: MediaAsset }) {
|
||||
const { state, actions } = useImageAsset(topicId, asset);
|
||||
const fadeAnim = useAnimatedValue(0);
|
||||
|
||||
return (<Text>IMAGE</Text>);
|
||||
useEffect(() => {
|
||||
if (state.loaded) {
|
||||
Animated.timing(fadeAnim, {
|
||||
toValue: 1,
|
||||
duration: 100,
|
||||
useNativeDriver: true,
|
||||
}).start();
|
||||
}
|
||||
}, [state.loaded]);
|
||||
|
||||
return (
|
||||
<View style={styles.image}>
|
||||
{ state.thumbUrl && (
|
||||
<Animated.Image
|
||||
style={[styles.thumb,{opacity: fadeAnim,},]}
|
||||
resizeMode="contain"
|
||||
height={92}
|
||||
width={92 * state.ratio}
|
||||
source={{ uri: state.thumbUrl }}
|
||||
onLoad={actions.loaded}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,9 @@ export function useImageAsset(topicId: string, asset: MediaAsset) {
|
||||
const [state, setState] = useState({
|
||||
thumbUrl: null,
|
||||
dataUrl: null,
|
||||
ratio: 1,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
loadPercent: 0,
|
||||
})
|
||||
|
||||
@ -36,6 +38,10 @@ export function useImageAsset(topicId: string, asset: MediaAsset) {
|
||||
}, [asset]);
|
||||
|
||||
const actions = {
|
||||
loaded: (e) => {
|
||||
const { width, height } = e.nativeEvent.source;
|
||||
updateState({ loaded: true, ratio: width / height });
|
||||
},
|
||||
unloadImage: () => {
|
||||
updateState({ dataUrl: null });
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Text } from 'react-native'
|
||||
import { Text } from 'react-native-paper'
|
||||
import { useVideoAsset } from './useVideoAsset.hook';
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user