mirror of
https://github.com/balzack/databag.git
synced 2025-03-13 00:50:03 +00:00
adding loading indicators for sealed asset
This commit is contained in:
parent
c205cec28c
commit
2e28584ae1
@ -1,4 +1,4 @@
|
||||
import { Image, View, Text, TouchableOpacity } from 'react-native';
|
||||
import { ActivityIndicator, Image, View, Text, TouchableOpacity } from 'react-native';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import Colors from 'constants/Colors';
|
||||
import Video from 'react-native-video';
|
||||
@ -37,6 +37,14 @@ export function AudioAsset({ asset, dismiss }) {
|
||||
<Video ref={player} source={{ uri: state.url }} repeat={true}
|
||||
paused={!state.playing} onLoad={actions.loaded} style={styles.player} />
|
||||
)}
|
||||
{ !state.loaded && (
|
||||
<TouchableOpacity style={styles.loading} onPress={dismiss}>
|
||||
<ActivityIndicator color={Colors.black} size="large" />
|
||||
{ asset.total > 1 && (
|
||||
<Text style={styles.decrypting}>{ asset.block } / { asset.total }</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
@ -37,5 +37,18 @@ export const styles = StyleSheet.create({
|
||||
player: {
|
||||
display: 'none',
|
||||
},
|
||||
loading: {
|
||||
position: 'absolute',
|
||||
display: 'flex',
|
||||
flexAlign: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
decrypting: {
|
||||
fontVariant: ["tabular-nums"],
|
||||
paddingTop: 16,
|
||||
fontSize: 12,
|
||||
color: '#888888',
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { View, Image, ActivityIndicator, TouchableOpacity } from 'react-native';
|
||||
import { Text, View, Image, ActivityIndicator, TouchableOpacity } from 'react-native';
|
||||
import { useImageAsset } from './useImageAsset.hook';
|
||||
import { styles } from './ImageAsset.styled';
|
||||
import Colors from 'constants/Colors';
|
||||
@ -10,9 +10,12 @@ export function ImageAsset({ asset, dismiss }) {
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.container} activeOpacity={1} onPress={actions.showControls}>
|
||||
<FastImage source={{ uri: asset.thumb }} onLoad={actions.setRatio}
|
||||
style={{ ...styles.thumb, width: state.imageWidth, height: state.imageHeight }}
|
||||
resizeMode={FastImage.resizeMode.contain} />
|
||||
{ state.url && (
|
||||
<FastImage source={{ uri: state.url }} onLoad={actions.loaded} onError={actions.failed}
|
||||
style={{ borderRadius: 4, width: state.imageWidth, height: state.imageHeight }}
|
||||
style={{ ...styles.main, width: state.imageWidth, height: state.imageHeight }}
|
||||
resizeMode={FastImage.resizeMode.contain} />
|
||||
)}
|
||||
|
||||
@ -30,6 +33,9 @@ export function ImageAsset({ asset, dismiss }) {
|
||||
{ !state.loaded && !state.failed && (
|
||||
<TouchableOpacity style={styles.loading} onPress={dismiss}>
|
||||
<ActivityIndicator color={Colors.white} size="large" />
|
||||
{ asset.total > 1 && (
|
||||
<Text style={styles.decrypting}>{ asset.block } / { asset.total }</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
@ -9,6 +9,16 @@ export const styles = StyleSheet.create({
|
||||
},
|
||||
loading: {
|
||||
position: 'absolute',
|
||||
display: 'flex',
|
||||
flexAlign: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
decrypting: {
|
||||
fontVariant: ["tabular-nums"],
|
||||
paddingTop: 16,
|
||||
fontSize: 12,
|
||||
color: '#dddddd',
|
||||
},
|
||||
overlay: {
|
||||
marginRight: 16,
|
||||
@ -21,6 +31,16 @@ export const styles = StyleSheet.create({
|
||||
borderWidth: 1,
|
||||
borderColor: Colors.divider,
|
||||
},
|
||||
thumb: {
|
||||
borderRadius: 4,
|
||||
opacity: 0.3,
|
||||
},
|
||||
main: {
|
||||
borderRadius: 4,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
},
|
||||
close: {
|
||||
position: 'absolute',
|
||||
opacity: 0.9,
|
||||
|
@ -63,9 +63,12 @@ export function useImageAsset(asset) {
|
||||
}, [asset]);
|
||||
|
||||
const actions = {
|
||||
loaded: (e) => {
|
||||
setRatio: (e) => {
|
||||
const { width, height } = e.nativeEvent;
|
||||
updateState({ loaded: true, imageRatio: width / height });
|
||||
updateState({ imageRatio: width / height });
|
||||
},
|
||||
loaded: () => {
|
||||
updateState({ loaded: true });
|
||||
},
|
||||
failed: () => {
|
||||
updateState({ failed: true });
|
||||
|
@ -290,6 +290,8 @@ export function useTopicItem(item, hosting, remove, contentKey) {
|
||||
if (exists) {
|
||||
RNFS.unlink(path);
|
||||
}
|
||||
assets[cur] = { ...asset, block: 0, total: asset.parts.length };
|
||||
updateState({ assets: [ ...assets ]});
|
||||
for (let j = 0; j < asset.parts.length; j++) {
|
||||
const part = asset.parts[j];
|
||||
const url = conversation.actions.getTopicAssetUrl(item.topicId, part.partId);
|
||||
@ -300,6 +302,9 @@ export function useTopicItem(item, hosting, remove, contentKey) {
|
||||
throw new Error("unseal assets cancelled");
|
||||
}
|
||||
await RNFS.appendFile(path, decrypted, 'base64');
|
||||
|
||||
assets[cur] = { ...asset, block: j+1, total: asset.parts.length };
|
||||
updateState({ assets: [ ...assets ]});
|
||||
};
|
||||
|
||||
asset.decrypted = path;
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { ActivityIndicator, Image, View, TouchableOpacity } from 'react-native';
|
||||
import { ActivityIndicator, Image, Text, View, TouchableOpacity } from 'react-native';
|
||||
import Colors from 'constants/Colors';
|
||||
import Video from 'react-native-video';
|
||||
import { useVideoAsset } from './useVideoAsset.hook';
|
||||
import { styles } from './VideoAsset.styled';
|
||||
import Icons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { useKeepAwake } from '@sayem314/react-native-keep-awake';
|
||||
import FastImage from 'react-native-fast-image'
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
@ -17,9 +18,12 @@ export function VideoAsset({ asset, dismiss }) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<TouchableOpacity activeOpacity={1} style={styles.container} onPress={actions.showControls}>
|
||||
<FastImage source={{ uri: asset.thumb }} onLoad={actions.setRatio}
|
||||
style={{ ...styles.thumb, width: state.thumbWidth, height: state.thumbHeight }}
|
||||
resizeMode={FastImage.resizeMode.contain} />
|
||||
{ state.url && (
|
||||
<Video source={{ uri: state.url, type: 'video/mp4' }} style={{ width: state.width, height: state.height }} resizeMode={'cover'}
|
||||
onReadyForDisplay={(e) => { console.log(e) }}
|
||||
<Video source={{ uri: state.url, type: 'video/mp4' }} style={{ ...styles.main, width: state.width, height: state.height }}
|
||||
resizeMode={'cover'} onReadyForDisplay={(e) => { console.log(e) }}
|
||||
onLoad={actions.loaded} repeat={true} paused={!state.playing} resizeMode="contain" />
|
||||
)}
|
||||
{ (!state.playing || state.controls) && (
|
||||
@ -44,6 +48,9 @@ export function VideoAsset({ asset, dismiss }) {
|
||||
{ !state.loaded && (
|
||||
<TouchableOpacity style={styles.loading} onPress={dismiss}>
|
||||
<ActivityIndicator color={Colors.white} size="large" />
|
||||
{ asset.total > 0 && (
|
||||
<Text style={styles.decrypting}>{ asset.block } / { asset.total }</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
|
@ -16,6 +16,13 @@ export const styles = StyleSheet.create({
|
||||
paddingRight: 8,
|
||||
paddingTop: 4,
|
||||
},
|
||||
thumb: {
|
||||
borderRadius: 4,
|
||||
opacity: 0.6,
|
||||
},
|
||||
main: {
|
||||
position: 'absolute',
|
||||
},
|
||||
close: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
@ -27,6 +34,16 @@ export const styles = StyleSheet.create({
|
||||
},
|
||||
loading: {
|
||||
position: 'absolute',
|
||||
display: 'flex',
|
||||
flexAlign: 'center',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
decrypting: {
|
||||
fontVariant: ["tabular-nums"],
|
||||
paddingTop: 16,
|
||||
fontSize: 12,
|
||||
color: '#dddddd',
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -9,7 +9,11 @@ export function useVideoAsset(asset) {
|
||||
frameWidth: 1,
|
||||
frameHeight: 1,
|
||||
videoRatio: 1,
|
||||
thumbRatio: 1,
|
||||
width: 1,
|
||||
height: 1,
|
||||
thumbWidth: 64,
|
||||
thumbHeight: 64,
|
||||
url: null,
|
||||
playing: false,
|
||||
loaded: false,
|
||||
@ -27,6 +31,18 @@ export function useVideoAsset(asset) {
|
||||
|
||||
useEffect(() => {
|
||||
const frameRatio = state.frameWidth / state.frameHeight;
|
||||
if (frameRatio > state.thumbRatio) {
|
||||
//thumbHeight constrained
|
||||
const thumbHeight = 0.9 * state.frameHeight;
|
||||
const thumbWidth = thumbHeight * state.thumbRatio;
|
||||
updateState({ thumbWidth, thumbHeight });
|
||||
}
|
||||
else {
|
||||
//thumbWidth constrained
|
||||
const thumbWidth = 0.9 * state.frameWidth;
|
||||
const thumbHeight = thumbWidth / state.thumbRatio;
|
||||
updateState({ thumbWidth, thumbHeight });
|
||||
}
|
||||
if (frameRatio > state.videoRatio) {
|
||||
//height constrained
|
||||
const height = 0.9 * state.frameHeight;
|
||||
@ -39,7 +55,7 @@ export function useVideoAsset(asset) {
|
||||
const height = width / state.videoRatio;
|
||||
updateState({ width, height });
|
||||
}
|
||||
}, [state.frameWidth, state.frameHeight, state.videoRatio]);
|
||||
}, [state.frameWidth, state.frameHeight, state.videoRatio, state.thumbRatio]);
|
||||
|
||||
useEffect(() => {
|
||||
updateState({ frameWidth: dimensions.width, frameHeight: dimensions.height });
|
||||
@ -55,6 +71,10 @@ export function useVideoAsset(asset) {
|
||||
}, [asset]);
|
||||
|
||||
const actions = {
|
||||
setRatio: (e) => {
|
||||
const { width, height } = e.nativeEvent;
|
||||
updateState({ thumbRatio: width / height });
|
||||
},
|
||||
setResolution: (width, height) => {
|
||||
updateState({ display: {}, videoRatio: width / height });
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user