Files
notesnook/apps/mobile/src/components/AttachmentDialog/index.js

285 lines
7.9 KiB
JavaScript
Raw Normal View History

2021-11-09 09:44:48 +05:00
import React, { useEffect, useRef, useState } from 'react';
import { TouchableOpacity, View } from 'react-native';
import { FlatList } from 'react-native-gesture-handler';
import * as Progress from 'react-native-progress';
2021-09-29 12:56:07 +05:00
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
2021-11-09 09:44:48 +05:00
import { useTracked } from '../../provider';
import { useAttachmentStore } from '../../provider/stores';
2022-01-22 12:57:05 +05:00
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
2021-11-09 09:44:48 +05:00
import { db } from '../../utils/database';
2022-01-22 12:57:05 +05:00
import { eCloseAttachmentDialog, eOpenAttachmentsDialog } from '../../utils/Events';
import filesystem from '../../utils/filesystem';
2021-11-09 09:44:48 +05:00
import { SIZE } from '../../utils/SizeUtils';
import { ActionIcon } from '../ActionIcon';
2021-12-26 19:51:24 +05:00
import SheetWrapper from '../Sheet';
2021-09-29 12:56:07 +05:00
import DialogHeader from '../Dialog/dialog-header';
2021-11-09 09:44:48 +05:00
import GeneralSheet from '../GeneralSheet';
2021-09-29 12:56:07 +05:00
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);
2022-01-22 12:57:05 +05:00
let _attachments = db.attachments.ofNote(item.id, 'all');
2021-10-01 12:03:25 +05:00
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-12-25 11:16:33 +05:00
<SheetWrapper
2021-09-29 12:56:07 +05:00
centered={false}
fwdRef={actionSheetRef}
onClose={async () => {
setVisible(false);
2022-01-22 12:57:05 +05:00
}}
>
2021-09-29 12:56:07 +05:00
<View
style={{
width: '100%',
alignSelf: 'center',
2021-10-01 12:03:25 +05:00
paddingHorizontal: 12
2022-01-22 12:57:05 +05:00
}}
>
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'
2022-01-22 12:57:05 +05:00
}}
>
2021-10-01 12:03:25 +05:00
<Icon name="attachment" size={60} color={colors.icon} />
<Paragraph>No attachments on this note</Paragraph>
</View>
}
data={attachments}
2022-01-22 12:57:05 +05:00
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
2022-01-22 12:57:05 +05:00
}}
>
2021-10-01 12:03:25 +05:00
<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>
2021-12-25 11:16:33 +05:00
</SheetWrapper>
2021-09-29 12:56:07 +05:00
);
};
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
}
2022-01-22 12:57:05 +05:00
export const Attachment = ({ attachment, encryption }) => {
2021-09-29 12:56:07 +05:00
const [state] = useTracked();
const colors = state.colors;
2021-10-01 12:03:25 +05:00
const progress = useAttachmentStore(state => state.progress);
2021-10-21 13:20:12 +05:00
const [currentProgress, setCurrentProgress] = useState(
encryption
? {
type: 'encrypt'
}
: null
);
const encryptionProgress = encryption
? useAttachmentStore(state => state.encryptionProgress)
: 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;
}
2022-01-22 12:57:05 +05:00
filesystem.downloadAttachment(attachment.metadata.hash, false);
2021-10-01 12:03:25 +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];
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);
console.log(prog);
2021-10-04 10:23:59 +05:00
setCurrentProgress({
2021-10-01 12:03:25 +05:00
value: prog,
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
}}
2022-01-22 12:57:05 +05:00
type="grayBg"
>
2021-11-09 09:44:48 +05:00
<GeneralSheet context={attachment.metadata.hash} />
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'
2022-01-22 12:57:05 +05:00
}}
>
2021-10-04 10:23:59 +05:00
<View
style={{
justifyContent: 'center',
alignItems: 'center',
marginLeft: -5
2022-01-22 12:57:05 +05:00
}}
>
2021-10-04 10:23:59 +05:00
<Icon name="file" size={SIZE.xxxl} color={colors.icon} />
<Paragraph
adjustsFontSizeToFit
size={6}
color={colors.light}
style={{
position: 'absolute'
2022-01-22 12:57:05 +05:00
}}
>
2021-10-04 10:23:59 +05:00
{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
2022-01-22 12:57:05 +05:00
}}
>
2021-10-01 12:03:25 +05:00
<Paragraph
size={SIZE.sm - 1}
style={{
flexWrap: 'wrap',
marginBottom: 2.5
}}
numberOfLines={1}
lineBreakMode="middle"
2022-01-22 12:57:05 +05:00
color={colors.pri}
>
2021-10-01 12:03:25 +05:00
{attachment.metadata.filename}
</Paragraph>
<Paragraph color={colors.icon} size={SIZE.xs}>
{formatBytes(attachment.length)}{' '}
2022-01-22 12:57:05 +05:00
{currentProgress?.type ? '(' + currentProgress.type + 'ing - tap to cancel)' : ''}
2021-10-01 12:03:25 +05:00
</Paragraph>
</View>
</View>
{currentProgress || encryptionProgress || encryption ? (
<TouchableOpacity
activeOpacity={0.9}
onPress={() => {
if (encryption) return;
db.fs.cancel(attachment.metadata.hash);
setCurrentProgress(null);
}}
2021-10-01 12:03:25 +05:00
style={{
justifyContent: 'center',
marginLeft: 5,
2021-10-21 13:20:12 +05:00
marginTop: 5,
marginRight: -5
2022-01-22 12:57:05 +05:00
}}
>
2021-10-01 12:03:25 +05:00
<Progress.Circle
size={SIZE.xxl}
2021-10-21 13:20:12 +05:00
progress={
encryptionProgress
? encryptionProgress
: currentProgress?.value
? currentProgress?.value / 100
: 0
}
2021-10-01 12:03:25 +05:00
showsText
textStyle={{
fontSize: 10
2021-10-01 12:03:25 +05:00
}}
color={colors.accent}
formatText={progress => (progress * 100).toFixed(0)}
borderWidth={0}
thickness={2}
/>
</TouchableOpacity>
2021-10-01 12:03:25 +05:00
) : (
<ActionIcon
onPress={() => !encryption && onPress(attachment)}
2021-10-01 12:03:25 +05:00
name="download"
size={SIZE.lg}
color={colors.pri}
/>
)}
</View>
2021-09-29 12:56:07 +05:00
);
};