/* This file is part of the Notesnook project (https://notesnook.com/) Copyright (C) 2023 Streetwriters (Private) Limited This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ import React, { useRef, useState } from "react"; import { ActivityIndicator, ScrollView, View } from "react-native"; import Icon from "react-native-vector-icons/MaterialCommunityIcons"; import { db } from "../../common/database"; import filesystem from "../../common/filesystem"; import { presentSheet } from "../../services/event-manager"; import { useThemeColors } from "@notesnook/theme"; import { SIZE } from "../../utils/size"; import SheetProvider from "../sheet-provider"; import { IconButton } from "../ui/icon-button"; import Input from "../ui/input"; import Seperator from "../ui/seperator"; import Heading from "../ui/typography/heading"; import Paragraph from "../ui/typography/paragraph"; import { AttachmentItem } from "./attachment-item"; import DownloadAttachments from "./download-attachments"; import { Button } from "../ui/button"; import { isAudio, isDocument, isImage, isVideo } from "@notesnook/core/dist/utils/filename"; import { useSettingStore } from "../../stores/use-setting-store"; import { FlashList } from "react-native-actions-sheet/dist/src/views/FlashList"; export const AttachmentDialog = ({ note }) => { const { colors } = useThemeColors(); const { height } = useSettingStore((state) => state.dimensions); const [attachments, setAttachments] = useState( note ? db.attachments.ofNote(note.id, "all") : [...(db.attachments.all || [])] ); const attachmentSearchValue = useRef(); const searchTimer = useRef(); const [loading, setLoading] = useState(false); const [currentFilter, setCurrentFilter] = useState("all"); const onChangeText = (text) => { const attachments = note ? db.attachments.ofNote(note.id, "all") : [...(db.attachments.all || [])]; attachmentSearchValue.current = text; if ( !attachmentSearchValue.current || attachmentSearchValue.current === "" ) { setAttachments(filterAttachments(currentFilter)); } clearTimeout(searchTimer.current); searchTimer.current = setTimeout(() => { let results = db.lookup.attachments( attachments, attachmentSearchValue.current ); if (results.length === 0) return; setAttachments(filterAttachments(currentFilter, results)); }, 300); }; const renderItem = ({ item }) => ( { setAttachments(filterAttachments(currentFilter)); }} attachment={item} context="attachments-list" /> ); const onCheck = async () => { setLoading(true); const checkedAttachments = []; for (let attachment of attachments) { let result = await filesystem.checkAttachment(attachment.metadata.hash); if (result.failed) { await db.attachments.markAsFailed( attachment.metadata.hash, result.failed ); } else { await db.attachments.markAsFailed(attachment.id, null); } checkedAttachments.push( db.attachments.attachment(attachment.metadata.hash) ); setAttachments([...checkedAttachments]); } setLoading(false); }; const attachmentTypes = [ { title: "All", filterBy: "all" }, { title: "Images", filterBy: "images" }, { title: "Documents", filterBy: "documents" }, { title: "Video", filterBy: "video" }, { title: "Audio", filterBy: "audio" } ]; const filterAttachments = (type, _attachments) => { const attachments = _attachments || note ? db.attachments.ofNote(note.id, "all") : [...(db.attachments.all || [])]; switch (type) { case "all": return attachments; case "images": return attachments.filter((attachment) => isImage(attachment.metadata.type) ); case "video": return attachments.filter((attachment) => isVideo(attachment.metadata.type) ); case "audio": return attachments.filter((attachment) => isAudio(attachment.metadata.type) ); case "documents": return attachments.filter((attachment) => isDocument(attachment.metadata.type) ); } }; return ( Attachments {loading ? ( ) : ( )} { DownloadAttachments.present( "attachments-list", attachments, !!note ); }} size={SIZE.lg} /> { onChangeText(attachmentSearchValue.current); }} /> {attachmentTypes.map((item) => (