mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 01:55:17 +00:00
supporting binary download
This commit is contained in:
parent
ee8169f168
commit
39b4a98c39
@ -1259,6 +1259,8 @@ PODS:
|
||||
- React-logger (= 0.74.3)
|
||||
- React-perflogger (= 0.74.3)
|
||||
- React-utils (= 0.74.3)
|
||||
- rn-fetch-blob (0.12.0):
|
||||
- React-Core
|
||||
- RNCClipboard (1.15.0):
|
||||
- React-Core
|
||||
- RNFS (2.20.0):
|
||||
@ -1493,6 +1495,7 @@ DEPENDENCIES:
|
||||
- React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
|
||||
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- rn-fetch-blob (from `../node_modules/rn-fetch-blob`)
|
||||
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
|
||||
- RNFS (from `../node_modules/react-native-fs`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
@ -1632,6 +1635,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/react/utils"
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
rn-fetch-blob:
|
||||
:path: "../node_modules/rn-fetch-blob"
|
||||
RNCClipboard:
|
||||
:path: "../node_modules/@react-native-clipboard/clipboard"
|
||||
RNFS:
|
||||
@ -1713,6 +1718,7 @@ SPEC CHECKSUMS:
|
||||
React-runtimescheduler: 0c80752bceb80924cb8a4babc2a8e3ed70d41e87
|
||||
React-utils: a06061b3887c702235d2dac92dacbd93e1ea079e
|
||||
ReactCommon: f00e436b3925a7ae44dfa294b43ef360fbd8ccc4
|
||||
rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba
|
||||
RNCClipboard: 69ab8e51324d5b351f6ba72bbdb72478087a2c64
|
||||
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
|
||||
RNGestureHandler: 6fee3422fd8c81c5ee756fa72e3d1780e9943d9d
|
||||
|
@ -43,7 +43,8 @@
|
||||
"react-native-video": "^6.8.2",
|
||||
"react-native-wheel-color-picker": "^1.3.1",
|
||||
"react-router-dom": "^6.26.0",
|
||||
"react-router-native": "^6.26.0"
|
||||
"react-router-native": "^6.26.0",
|
||||
"rn-fetch-blob": "^0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.0",
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {StyleSheet} from 'react-native';
|
||||
import {Colors} from '../constants/Colors';
|
||||
import {Colors} from '../../constants/Colors';
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
modal: {
|
||||
@ -14,6 +14,9 @@ export const styles = StyleSheet.create({
|
||||
borderRadius: 4,
|
||||
backgroundColor: '#444444',
|
||||
},
|
||||
control: {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
container: {
|
||||
position: 'relative',
|
||||
width: 92,
|
||||
@ -30,6 +33,11 @@ export const styles = StyleSheet.create({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
info: {
|
||||
fontSize: 12,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
},
|
||||
blur: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
@ -52,10 +60,29 @@ export const styles = StyleSheet.create({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
label: {
|
||||
flexGrow: 1,
|
||||
fontSize: 32,
|
||||
paddingLeft: 16,
|
||||
minWidth: 0,
|
||||
textOverflow: 'ellipsis',
|
||||
flexShrink: 1,
|
||||
},
|
||||
close: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
position: 'absolute',
|
||||
alignItems: 'center',
|
||||
top: 0,
|
||||
right: 0,
|
||||
minWidth: 0,
|
||||
width: '100%',
|
||||
},
|
||||
alert: {
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
},
|
||||
alertLabel: {
|
||||
color: Colors.offsync,
|
||||
},
|
||||
closeIcon: {
|
||||
backgroundColor: 'transparent',
|
||||
|
@ -1,17 +1,19 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { SafeAreaView, Modal, Pressable, View, Image, Animated, useAnimatedValue } from 'react-native'
|
||||
import { Icon, ProgressBar, IconButton } from 'react-native-paper'
|
||||
import { SafeAreaView, Modal, Share, Pressable, View, Image, Animated, useAnimatedValue } from 'react-native'
|
||||
import { Text, 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';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
|
||||
export function BinaryAsset({ topicId, asset, loaded, show }: { topicId: string, asset: MediaAsset, loaded: ()=>void, show: boolean }) {
|
||||
const { state, actions } = useBinaryAsset(topicId, asset);
|
||||
const [modal, setModal] = useState(false);
|
||||
const opacity = useAnimatedValue(0);
|
||||
const [alert, setAlert] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
@ -23,7 +25,21 @@ export function BinaryAsset({ topicId, asset, loaded, show }: { topicId: string,
|
||||
}
|
||||
}, [show]);
|
||||
|
||||
const share = async () => {
|
||||
try {
|
||||
setAlert('');
|
||||
const extension = asset.binary?.extension || asset.encrypted?.extension;
|
||||
const options = { fileCache: true, appendExt: extension.toLowerCase() };
|
||||
const download = await RNFetchBlob.config(options).fetch("GET", state.dataUrl);
|
||||
await Share.share({ url: download.path() });
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
setAlert(state.strings.operationFailed)
|
||||
}
|
||||
}
|
||||
|
||||
const showBinary = () => {
|
||||
setAlert('');
|
||||
setModal(true);
|
||||
actions.loadBinary();
|
||||
};
|
||||
@ -48,6 +64,7 @@ export function BinaryAsset({ topicId, asset, loaded, show }: { topicId: string,
|
||||
<View style={styles.button}>
|
||||
<Icon size={28} source="download-outline" />
|
||||
</View>
|
||||
<Text style={styles.info} numberOfLines={1}>{ asset.binary?.label || asset.encrypted?.label }</Text>
|
||||
</Animated.View>
|
||||
</Pressable>
|
||||
<Modal animationType="fade" transparent={true} supportedOrientations={['portrait', 'landscape']} visible={modal} onRequestClose={hideBinary}>
|
||||
@ -59,16 +76,22 @@ export function BinaryAsset({ topicId, asset, loaded, show }: { topicId: string,
|
||||
resizeMode="contain"
|
||||
source={thumb}
|
||||
/>
|
||||
<View style={styles.button}>
|
||||
<Icon size={64} source="download-outline" />
|
||||
</View>
|
||||
{ state.dataUrl && (
|
||||
<View style={styles.button}>
|
||||
<IconButton style={styles.control} size={64} icon="download-outline" onPress={share} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
{ state.loading && (
|
||||
<View style={styles.progress}>
|
||||
<ProgressBar progress={state.loadPercent / 100} />
|
||||
</View>
|
||||
)}
|
||||
<SafeAreaView style={styles.alert}>
|
||||
<Text style={styles.alertLabel}>{ alert }</Text>
|
||||
</SafeAreaView>
|
||||
<SafeAreaView style={styles.close}>
|
||||
<Text style={styles.label} adjustsFontSizeToFit={true} numberOfLines={1}>{ asset.binary?.label || asset.encrypted?.label }</Text>
|
||||
<IconButton style={styles.closeIcon} icon="close" compact="true" mode="contained" size={28} onPress={hideBinary} />
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { useState, useContext, useEffect, useRef } from 'react'
|
||||
import { AppContext } from '../../context/AppContext'
|
||||
import { DisplayContext } from '../../context/DisplayContext';
|
||||
import { Focus } from 'databag-client-sdk'
|
||||
import { ContextType } from '../../context/ContextType'
|
||||
import { MediaAsset } from '../../conversation/Conversation';
|
||||
|
||||
export function useBinaryAsset(topicId: string, asset: MediaAsset) {
|
||||
const app = useContext(AppContext) as ContextType
|
||||
const display = useContext(DisplayContext) as ContextType
|
||||
const [state, setState] = useState({
|
||||
strings: display.state.strings,
|
||||
dataUrl: null,
|
||||
loading: false,
|
||||
loaded: false,
|
||||
@ -25,7 +28,7 @@ export function useBinaryAsset(topicId: string, asset: MediaAsset) {
|
||||
},
|
||||
loadBinary: async () => {
|
||||
const { focus } = app.state;
|
||||
const assetId = asset.audio ? asset.audio.full : asset.encrypted ? asset.encrypted.parts : null;
|
||||
const assetId = asset.binary ? asset.binary.data : asset.encrypted ? asset.encrypted.parts : null;
|
||||
if (focus && assetId != null && !state.loading && !state.dataUrl) {
|
||||
cancelled.current = false;
|
||||
updateState({ loading: true, loadPercent: 0 });
|
||||
|
@ -3471,6 +3471,7 @@ __metadata:
|
||||
react-router-dom: ^6.26.0
|
||||
react-router-native: ^6.26.0
|
||||
react-test-renderer: 18.2.0
|
||||
rn-fetch-blob: ^0.12.0
|
||||
typescript: 5.0.4
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
@ -3946,7 +3947,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"base-64@npm:^0.1.0":
|
||||
"base-64@npm:0.1.0, base-64@npm:^0.1.0":
|
||||
version: 0.1.0
|
||||
resolution: "base-64@npm:0.1.0"
|
||||
checksum: 5a42938f82372ab5392cbacc85a5a78115cbbd9dbef9f7540fa47d78763a3a8bd7d598475f0d92341f66285afd377509851a9bb5c67bbecb89686e9255d5b3eb
|
||||
@ -5734,6 +5735,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:7.0.6":
|
||||
version: 7.0.6
|
||||
resolution: "glob@npm:7.0.6"
|
||||
dependencies:
|
||||
fs.realpath: ^1.0.0
|
||||
inflight: ^1.0.4
|
||||
inherits: 2
|
||||
minimatch: ^3.0.2
|
||||
once: ^1.3.0
|
||||
path-is-absolute: ^1.0.0
|
||||
checksum: 6ad065f51982f9a76f7052984121c95bca376ea02060b21200ad62b400422b05f0dc331f72da89a73c21a2451cbe9bec16bb17dcf37a516dc51bbbb6efe462a1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7":
|
||||
version: 10.4.5
|
||||
resolution: "glob@npm:10.4.5"
|
||||
@ -9598,6 +9613,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rn-fetch-blob@npm:^0.12.0":
|
||||
version: 0.12.0
|
||||
resolution: "rn-fetch-blob@npm:0.12.0"
|
||||
dependencies:
|
||||
base-64: 0.1.0
|
||||
glob: 7.0.6
|
||||
checksum: 56e5832be583e97d58f955c0c4f6dcb0eb62c97dde331182c6effb726253731cb555d4a5f6c81079ed2fcb957f81633cbe95b37d326d063405f912506de20ff4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"run-parallel@npm:^1.1.9":
|
||||
version: 1.2.0
|
||||
resolution: "run-parallel@npm:1.2.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user