mirror of
https://github.com/balzack/databag.git
synced 2025-05-05 07:55:15 +00:00
playing audio
This commit is contained in:
parent
4eee3568ce
commit
f5cc6ca9e7
BIN
app/client/mobile/src/images/audio.png
Normal file
BIN
app/client/mobile/src/images/audio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
app/client/mobile/src/images/binary.png
Normal file
BIN
app/client/mobile/src/images/binary.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
@ -2,4 +2,59 @@ import {StyleSheet} from 'react-native';
|
|||||||
import {Colors} from '../constants/Colors';
|
import {Colors} from '../constants/Colors';
|
||||||
|
|
||||||
export const styles = StyleSheet.create({
|
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',
|
||||||
|
},
|
||||||
|
blur: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
audio: {
|
||||||
|
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,62 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { Text } from 'react-native-paper'
|
import { SafeAreaView, Modal, Pressable, View, Image } from 'react-native'
|
||||||
|
import { Icon, ProgressBar, IconButton } from 'react-native-paper'
|
||||||
import { useAudioAsset } from './useAudioAsset.hook';
|
import { useAudioAsset } from './useAudioAsset.hook';
|
||||||
import { MediaAsset } from '../../conversation/Conversation';
|
import { MediaAsset } from '../../conversation/Conversation';
|
||||||
|
import { styles } from './AudioAsset.styled'
|
||||||
|
import {BlurView} from '@react-native-community/blur';
|
||||||
|
import Video from 'react-native-video'
|
||||||
|
import thumb from '../../images/audio.png';
|
||||||
|
|
||||||
export function AudioAsset({ topicId, asset }: { topicId: string, asset: MediaAsset }) {
|
export function AudioAsset({ topicId, asset }: { topicId: string, asset: MediaAsset }) {
|
||||||
const { state, actions } = useAudioAsset(topicId, asset);
|
const { state, actions } = useAudioAsset(topicId, asset);
|
||||||
|
const [modal, setModal] = useState(false);
|
||||||
|
|
||||||
return (<Text>AUDIO</Text>);
|
const showAudio = () => {
|
||||||
|
setModal(true);
|
||||||
|
actions.loadAudio();
|
||||||
|
};
|
||||||
|
|
||||||
|
const hideAudio = () => {
|
||||||
|
setModal(false);
|
||||||
|
actions.cancelLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.audio}>
|
||||||
|
<Pressable style={styles.container} onPress={showAudio}>
|
||||||
|
<Image
|
||||||
|
style={styles.thumb}
|
||||||
|
resizeMode="contain"
|
||||||
|
source={thumb}
|
||||||
|
/>
|
||||||
|
<View style={styles.button}>
|
||||||
|
<Icon size={28} source="play-box-outline" />
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
<Modal animationType="fade" transparent={true} supportedOrientations={['portrait', 'landscape']} visible={modal} onRequestClose={hideAudio}>
|
||||||
|
<View style={styles.modal}>
|
||||||
|
<BlurView style={styles.blur} blurType="dark" blurAmount={16} reducedTransparencyFallbackColor="dark" />
|
||||||
|
<Image
|
||||||
|
style={styles.full}
|
||||||
|
resizeMode="contain"
|
||||||
|
source={thumb}
|
||||||
|
/>
|
||||||
|
{ state.dataUrl && (
|
||||||
|
<Video source={{ uri: state.dataUrl }} style={styles.full}
|
||||||
|
controls={false} resizeMode="contain" />
|
||||||
|
)}
|
||||||
|
{ 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={hideAudio} />
|
||||||
|
</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 { AppContext } from '../../context/AppContext'
|
||||||
import { Focus } from 'databag-client-sdk'
|
import { Focus } from 'databag-client-sdk'
|
||||||
import { ContextType } from '../../context/ContextType'
|
import { ContextType } from '../../context/ContextType'
|
||||||
@ -9,8 +9,10 @@ export function useAudioAsset(topicId: string, asset: MediaAsset) {
|
|||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
dataUrl: null,
|
dataUrl: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
loaded: false,
|
||||||
loadPercent: 0,
|
loadPercent: 0,
|
||||||
})
|
})
|
||||||
|
const cancelled = useRef(false);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const updateState = (value: any) => {
|
const updateState = (value: any) => {
|
||||||
@ -18,21 +20,22 @@ export function useAudioAsset(topicId: string, asset: MediaAsset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
unloadAudio: () => {
|
cancelLoad: () => {
|
||||||
updateState({ dataUrl: null });
|
cancelled.current = true;
|
||||||
},
|
},
|
||||||
loadAudio: async () => {
|
loadAudio: async () => {
|
||||||
const { focus } = app.state;
|
const { focus } = app.state;
|
||||||
const assetId = asset.audio ? asset.audio.full : asset.encrypted ? asset.encrypted.parts : null;
|
const assetId = asset.audio ? asset.audio.full : asset.encrypted ? asset.encrypted.parts : null;
|
||||||
if (focus && assetId != null && !state.loading) {
|
if (focus && assetId != null && !state.loading && !state.dataUrl) {
|
||||||
|
cancelled.current = false;
|
||||||
updateState({ loading: true, loadPercent: 0 });
|
updateState({ loading: true, loadPercent: 0 });
|
||||||
try {
|
try {
|
||||||
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId, (loadPercent: number)=>{ updateState({ loadPercent }) });
|
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId, (loadPercent: number)=>{ updateState({ loadPercent }); return !cancelled.current });
|
||||||
updateState({ dataUrl, loading: false });
|
updateState({ dataUrl });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
updateState({ loading: false });
|
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
updateState({ loading: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user