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'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import { useTracked } from '../../provider'; import { useAttachmentStore } from '../../provider/stores'; import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager'; import { db } from '../../utils/database'; import { eCloseAttachmentDialog, eOpenAttachmentsDialog } from '../../utils/Events'; import filesystem from '../../utils/filesystem'; import { SIZE } from '../../utils/SizeUtils'; import { ActionIcon } from '../ActionIcon'; 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(); const [attachments, setAttachments] = useState([]); useEffect(() => { eSubscribeEvent(eOpenAttachmentsDialog, open); eSubscribeEvent(eCloseAttachmentDialog, close); return () => { eUnSubscribeEvent(eOpenAttachmentsDialog, open); eUnSubscribeEvent(eCloseAttachmentDialog, close); }; }, [visible]); const open = item => { setNote(item); setVisible(true); let _attachments = db.attachments.ofNote(item.id,"files"); setAttachments(_attachments); }; useEffect(() => { if (visible) { actionSheetRef.current?.show(); } }, [visible]); const close = () => { actionSheetRef.current?.hide(); setVisible(false); }; return !visible ? null : ( { setVisible(false); }}> { actionSheetRef.current?.handleChildScrollEnd(); }} ListEmptyComponent={ No attachments on this note } data={attachments} renderItem={({item, index}) => ( )} /> {' '}All attachments are end-to-end encrypted. ); }; 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]; } function getFileExtension(filename) { var ext = /^.+\.([^.]+)$/.exec(filename); return ext == null ? '' : ext[1]; } export const Attachment = ({attachment,encryption}) => { const [state] = useTracked(); const colors = state.colors; const progress = useAttachmentStore(state => state.progress); const [currentProgress, setCurrentProgress] = useState(encryption ? { type:"encrypt" }: null); const encryptionProgress = encryption ? useAttachmentStore(state => state.encryptionProgress) : null const onPress = async () => { if (currentProgress) { db.fs.cancel(attachment.metadata.hash, 'download'); useAttachmentStore.getState().remove(attachment.metadata.hash); return; } filesystem.downloadAttachment(attachment.metadata.hash); }; useEffect(() => { 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; prog = (prog * 100).toFixed(0); console.log('progress: ', prog); console.log(prog); setCurrentProgress({ value: prog, percent: prog + '%', type: type }); } else { setCurrentProgress(null); } }, [progress]); return ( {getFileExtension(attachment.metadata.filename).toUpperCase()} {attachment.metadata.filename} {formatBytes(attachment.length)}{' '} {currentProgress?.type ? '(' + currentProgress.type + 'ing - tap to cancel)' : ''} {currentProgress || encryptionProgress ? ( { if (encryption) return; db.fs.cancel(attachment.metadata.hash); setCurrentProgress(null); }} style={{ justifyContent: 'center', marginLeft: 5, marginTop:5, marginRight:-5 }}> (progress * 100).toFixed(0)} borderWidth={0} thickness={2} /> ) : ( !encryption && onPress(attachment)} name="download" size={SIZE.lg} color={colors.pri} /> )} ); };