2021-09-29 12:56:07 +05:00
|
|
|
import React, {useEffect, useRef, useState} from 'react';
|
2021-10-05 10:31:16 +05:00
|
|
|
import {Platform, TouchableOpacity, View} from 'react-native';
|
2021-10-01 12:03:25 +05:00
|
|
|
import {FlatList} from 'react-native-gesture-handler';
|
2021-10-05 10:31:16 +05:00
|
|
|
import * as Progress from 'react-native-progress';
|
|
|
|
|
import * as ScopedStorage from 'react-native-scoped-storage';
|
|
|
|
|
import Sodium from 'react-native-sodium';
|
2021-09-29 12:56:07 +05:00
|
|
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
|
|
|
|
import {useTracked} from '../../provider';
|
2021-10-01 12:03:25 +05:00
|
|
|
import {useAttachmentStore} from '../../provider/stores';
|
|
|
|
|
import {
|
|
|
|
|
eSubscribeEvent,
|
|
|
|
|
eUnSubscribeEvent,
|
|
|
|
|
ToastEvent
|
|
|
|
|
} from '../../services/EventManager';
|
2021-10-02 10:26:29 +05:00
|
|
|
import {db} from '../../utils/database';
|
2021-10-01 12:03:25 +05:00
|
|
|
import {
|
|
|
|
|
eCloseAttachmentDialog,
|
2021-10-05 10:31:16 +05:00
|
|
|
eOpenAttachmentsDialog
|
2021-10-01 12:03:25 +05:00
|
|
|
} from '../../utils/Events';
|
2021-10-05 10:31:16 +05:00
|
|
|
import filesystem from '../../utils/filesystem';
|
2021-09-29 12:56:07 +05:00
|
|
|
import {SIZE} from '../../utils/SizeUtils';
|
2021-10-05 10:31:16 +05:00
|
|
|
import Storage from '../../utils/storage';
|
2021-10-01 12:03:25 +05:00
|
|
|
import {ActionIcon} from '../ActionIcon';
|
2021-09-29 12:56:07 +05:00
|
|
|
import ActionSheetWrapper from '../ActionSheetComponent/ActionSheetWrapper';
|
|
|
|
|
import DialogHeader from '../Dialog/dialog-header';
|
|
|
|
|
import Paragraph from '../Typography/Paragraph';
|
|
|
|
|
|
|
|
|
|
export const AttachmentDialog = () => {
|
|
|
|
|
const [state] = useTracked();
|
|
|
|
|
const colors = state.colors;
|
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
|
const [note, setNote] = useState(null);
|
|
|
|
|
const actionSheetRef = useRef();
|
2021-10-01 12:03:25 +05:00
|
|
|
const [attachments, setAttachments] = useState([]);
|
2021-09-29 12:56:07 +05:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-10-01 12:03:25 +05:00
|
|
|
eSubscribeEvent(eOpenAttachmentsDialog, open);
|
|
|
|
|
eSubscribeEvent(eCloseAttachmentDialog, close);
|
2021-09-29 12:56:07 +05:00
|
|
|
return () => {
|
2021-10-01 12:03:25 +05:00
|
|
|
eUnSubscribeEvent(eOpenAttachmentsDialog, open);
|
|
|
|
|
eUnSubscribeEvent(eCloseAttachmentDialog, close);
|
2021-09-29 12:56:07 +05:00
|
|
|
};
|
2021-10-01 12:03:25 +05:00
|
|
|
}, [visible]);
|
2021-09-29 12:56:07 +05:00
|
|
|
|
|
|
|
|
const open = item => {
|
|
|
|
|
setNote(item);
|
|
|
|
|
setVisible(true);
|
2021-10-01 12:03:25 +05:00
|
|
|
let _attachments = db.attachments.get(item.id);
|
|
|
|
|
setAttachments(_attachments);
|
2021-09-29 12:56:07 +05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (visible) {
|
|
|
|
|
actionSheetRef.current?.show();
|
|
|
|
|
}
|
|
|
|
|
}, [visible]);
|
|
|
|
|
|
|
|
|
|
const close = () => {
|
|
|
|
|
actionSheetRef.current?.hide();
|
2021-10-01 12:03:25 +05:00
|
|
|
setVisible(false);
|
2021-09-29 12:56:07 +05:00
|
|
|
};
|
|
|
|
|
|
2021-10-01 12:03:25 +05:00
|
|
|
return !visible ? null : (
|
2021-09-29 12:56:07 +05:00
|
|
|
<ActionSheetWrapper
|
|
|
|
|
centered={false}
|
|
|
|
|
fwdRef={actionSheetRef}
|
|
|
|
|
onClose={async () => {
|
|
|
|
|
setVisible(false);
|
|
|
|
|
}}>
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
alignSelf: 'center',
|
2021-10-01 12:03:25 +05:00
|
|
|
paddingHorizontal: 12
|
2021-09-29 12:56:07 +05:00
|
|
|
}}>
|
|
|
|
|
<DialogHeader title="Attachments" />
|
2021-10-01 12:03:25 +05:00
|
|
|
<FlatList
|
2021-09-29 12:56:07 +05:00
|
|
|
nestedScrollEnabled
|
|
|
|
|
overScrollMode="never"
|
|
|
|
|
scrollToOverflowEnabled={false}
|
|
|
|
|
keyboardDismissMode="none"
|
|
|
|
|
keyboardShouldPersistTaps="always"
|
|
|
|
|
onMomentumScrollEnd={() => {
|
|
|
|
|
actionSheetRef.current?.handleChildScrollEnd();
|
2021-10-01 12:03:25 +05:00
|
|
|
}}
|
|
|
|
|
ListEmptyComponent={
|
|
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
height: 150,
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
alignItems: 'center'
|
|
|
|
|
}}>
|
|
|
|
|
<Icon name="attachment" size={60} color={colors.icon} />
|
|
|
|
|
<Paragraph>No attachments on this note</Paragraph>
|
|
|
|
|
</View>
|
|
|
|
|
}
|
|
|
|
|
data={attachments}
|
|
|
|
|
renderItem={({item, index}) => (
|
2021-09-29 12:56:07 +05:00
|
|
|
<Attachment attachment={item} note={note} setNote={setNote} />
|
2021-10-01 12:03:25 +05:00
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Paragraph
|
|
|
|
|
color={colors.icon}
|
|
|
|
|
size={SIZE.xs}
|
|
|
|
|
style={{
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
marginTop: 10
|
|
|
|
|
}}>
|
|
|
|
|
<Icon name="shield-key-outline" size={SIZE.xs} color={colors.icon} />
|
|
|
|
|
{' '}All attachments are end-to-end encrypted.
|
|
|
|
|
</Paragraph>
|
2021-09-29 12:56:07 +05:00
|
|
|
</View>
|
|
|
|
|
</ActionSheetWrapper>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function formatBytes(bytes, decimals = 2) {
|
|
|
|
|
if (bytes === 0) return '0 Bytes';
|
|
|
|
|
|
|
|
|
|
const k = 1024;
|
|
|
|
|
const dm = decimals < 0 ? 0 : decimals;
|
|
|
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
|
|
|
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
|
|
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-04 10:23:59 +05:00
|
|
|
function getFileExtension(filename) {
|
|
|
|
|
var ext = /^.+\.([^.]+)$/.exec(filename);
|
|
|
|
|
return ext == null ? '' : ext[1];
|
2021-09-29 12:56:07 +05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Attachment = ({attachment, note, setNote}) => {
|
|
|
|
|
const [state] = useTracked();
|
|
|
|
|
const colors = state.colors;
|
2021-10-01 12:03:25 +05:00
|
|
|
const progress = useAttachmentStore(state => state.progress);
|
2021-10-04 10:23:59 +05:00
|
|
|
const [currentProgress, setCurrentProgress] = useState(null);
|
2021-09-29 12:56:07 +05:00
|
|
|
|
2021-10-04 10:23:59 +05:00
|
|
|
const onPress = async () => {
|
|
|
|
|
if (currentProgress) {
|
2021-10-01 12:03:25 +05:00
|
|
|
db.fs.cancel(attachment.metadata.hash, 'download');
|
2021-10-04 10:23:59 +05:00
|
|
|
useAttachmentStore.getState().remove(attachment.metadata.hash);
|
2021-10-01 12:03:25 +05:00
|
|
|
return;
|
|
|
|
|
}
|
2021-10-05 10:31:16 +05:00
|
|
|
filesystem.downloadAttachment(attachment.metadata.hash);
|
2021-10-01 12:03:25 +05:00
|
|
|
};
|
2021-10-05 10:31:16 +05:00
|
|
|
|
2021-10-04 10:23:59 +05:00
|
|
|
useEffect(() => {
|
2021-10-01 12:03:25 +05:00
|
|
|
let prog = progress[attachment.metadata.hash];
|
2021-10-05 10:31:16 +05:00
|
|
|
if (prog) {
|
|
|
|
|
let type = prog.type;
|
|
|
|
|
let loaded = prog.type === 'download' ? prog.recieved : prog.sent;
|
|
|
|
|
prog = loaded / prog.total;
|
2021-10-01 12:03:25 +05:00
|
|
|
prog = (prog * 100).toFixed(0);
|
2021-10-04 10:23:59 +05:00
|
|
|
console.log('progress: ', prog);
|
2021-10-05 10:31:16 +05:00
|
|
|
console.log(prog);
|
2021-10-04 10:23:59 +05:00
|
|
|
setCurrentProgress({
|
2021-10-01 12:03:25 +05:00
|
|
|
value: prog,
|
2021-10-05 10:31:16 +05:00
|
|
|
percent: prog + '%',
|
|
|
|
|
type: type
|
2021-10-04 10:23:59 +05:00
|
|
|
});
|
2021-10-01 12:03:25 +05:00
|
|
|
} else {
|
2021-10-04 10:23:59 +05:00
|
|
|
setCurrentProgress(null);
|
2021-10-01 12:03:25 +05:00
|
|
|
}
|
2021-10-04 10:23:59 +05:00
|
|
|
}, [progress]);
|
2021-09-29 12:56:07 +05:00
|
|
|
|
|
|
|
|
return (
|
2021-10-01 12:03:25 +05:00
|
|
|
<View
|
|
|
|
|
style={{
|
2021-09-29 12:56:07 +05:00
|
|
|
flexDirection: 'row',
|
|
|
|
|
marginVertical: 5,
|
|
|
|
|
justifyContent: 'space-between',
|
2021-10-01 12:03:25 +05:00
|
|
|
padding: 12,
|
|
|
|
|
paddingVertical: 6,
|
|
|
|
|
borderRadius: 5,
|
|
|
|
|
backgroundColor: colors.nav
|
2021-09-29 12:56:07 +05:00
|
|
|
}}
|
|
|
|
|
type="grayBg">
|
2021-10-01 12:03:25 +05:00
|
|
|
<View
|
2021-09-29 12:56:07 +05:00
|
|
|
style={{
|
2021-10-01 12:03:25 +05:00
|
|
|
flexShrink: 1,
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
alignItems: 'center'
|
2021-09-29 12:56:07 +05:00
|
|
|
}}>
|
2021-10-04 10:23:59 +05:00
|
|
|
<View
|
|
|
|
|
style={{
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
marginLeft: -5
|
|
|
|
|
}}>
|
|
|
|
|
<Icon name="file" size={SIZE.xxxl} color={colors.icon} />
|
|
|
|
|
|
|
|
|
|
<Paragraph
|
|
|
|
|
adjustsFontSizeToFit
|
|
|
|
|
size={6}
|
|
|
|
|
color={colors.light}
|
|
|
|
|
style={{
|
|
|
|
|
position: 'absolute'
|
|
|
|
|
}}>
|
|
|
|
|
{getFileExtension(attachment.metadata.filename).toUpperCase()}
|
|
|
|
|
</Paragraph>
|
|
|
|
|
</View>
|
|
|
|
|
|
2021-10-01 12:03:25 +05:00
|
|
|
<View
|
2021-09-29 12:56:07 +05:00
|
|
|
style={{
|
2021-10-01 12:03:25 +05:00
|
|
|
flexShrink: 1,
|
|
|
|
|
marginLeft: 10
|
|
|
|
|
}}>
|
|
|
|
|
<Paragraph
|
|
|
|
|
size={SIZE.sm - 1}
|
|
|
|
|
style={{
|
|
|
|
|
flexWrap: 'wrap',
|
|
|
|
|
marginBottom: 2.5
|
|
|
|
|
}}
|
|
|
|
|
numberOfLines={1}
|
|
|
|
|
lineBreakMode="middle"
|
|
|
|
|
color={colors.pri}>
|
|
|
|
|
{attachment.metadata.filename}
|
|
|
|
|
</Paragraph>
|
|
|
|
|
|
|
|
|
|
<Paragraph color={colors.icon} size={SIZE.xs}>
|
2021-10-05 10:31:16 +05:00
|
|
|
{formatBytes(attachment.length)}{' '}
|
|
|
|
|
{currentProgress?.type ? '(' + currentProgress.type + 'ing - tap to cancel)' : ''}
|
2021-10-01 12:03:25 +05:00
|
|
|
</Paragraph>
|
|
|
|
|
</View>
|
|
|
|
|
</View>
|
|
|
|
|
|
2021-10-04 10:23:59 +05:00
|
|
|
{currentProgress ? (
|
2021-10-05 10:31:16 +05:00
|
|
|
<TouchableOpacity
|
|
|
|
|
activeOpacity={0.9}
|
|
|
|
|
onPress={() => {
|
|
|
|
|
db.fs.cancel(attachment.metadata.hash);
|
|
|
|
|
setCurrentProgress(null);
|
|
|
|
|
}}
|
2021-10-01 12:03:25 +05:00
|
|
|
style={{
|
|
|
|
|
justifyContent: 'center',
|
2021-10-05 10:31:16 +05:00
|
|
|
marginLeft: 5,
|
|
|
|
|
marginTop:5,
|
|
|
|
|
marginRight:-5
|
2021-10-01 12:03:25 +05:00
|
|
|
}}>
|
|
|
|
|
<Progress.Circle
|
|
|
|
|
size={SIZE.xxl}
|
2021-10-04 10:23:59 +05:00
|
|
|
progress={currentProgress?.value ? currentProgress?.value / 100 : 0}
|
2021-10-01 12:03:25 +05:00
|
|
|
showsText
|
|
|
|
|
textStyle={{
|
2021-10-05 10:31:16 +05:00
|
|
|
fontSize: 10
|
2021-10-01 12:03:25 +05:00
|
|
|
}}
|
|
|
|
|
color={colors.accent}
|
|
|
|
|
formatText={progress => (progress * 100).toFixed(0)}
|
|
|
|
|
borderWidth={0}
|
|
|
|
|
thickness={2}
|
|
|
|
|
/>
|
2021-10-05 10:31:16 +05:00
|
|
|
</TouchableOpacity>
|
2021-10-01 12:03:25 +05:00
|
|
|
) : (
|
|
|
|
|
<ActionIcon
|
|
|
|
|
onPress={() => onPress(attachment)}
|
|
|
|
|
name="download"
|
|
|
|
|
size={SIZE.lg}
|
|
|
|
|
color={colors.pri}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</View>
|
2021-09-29 12:56:07 +05:00
|
|
|
);
|
|
|
|
|
};
|