import React, {useContext} from "react"; import { Button as SButton, CardContent, CardDescription, CardHeader, CardMeta, Container, Dropdown, Header as SHeader, Image, Modal, PlaceholderLine, TableCell, TableHeaderCell, } from "semantic-ui-react"; import { CardGroupCentered, CardLink, CardPosterLink, cardTitleWrapper, ExternalCardLink, FileIcon, humanFileSize, isoDatetimeToString, mimetypeColor, PageContainer, Paginator, textEllipsis, useTitle } from "./Common"; import {useQuery, useSearchFiles} from "../hooks/customHooks"; import {Route, Routes} from "react-router-dom"; import {CardPlacholder} from "./Placeholder"; import {ArchiveCard, ArchiveRowCells} from "./Archive"; import Grid from "semantic-ui-react/dist/commonjs/collections/Grid"; import {StatusContext, ThemeContext} from "../contexts/contexts"; import {Button, Card, CardIcon, Icon, Placeholder, Segment} from "./Theme"; import {SelectableTable} from "./Tables"; import {VideoCard, VideoRowCells} from "./Videos"; import _ from 'lodash'; import {FileBrowser} from "./FileBrowser"; import {refreshDirectoryFiles, refreshFiles} from "../api"; import {useSubscribeEventName} from "../Events"; export function FilesPage() { useTitle('Files'); return ; } function EbookCard({file}) { const {s} = useContext(ThemeContext); let {ebook, suffix} = file; const downloadUrl = `/download/${encodeURIComponent(file.path)}`; const isEpub = file['mimetype'].startsWith('application/epub'); const viewerUrl = isEpub ? `/epub.html?url=${downloadUrl}` : null; let cover = ; if (ebook && ebook.cover_path) { const coverSrc = `/media/${encodeURIComponent(ebook.cover_path)}`; cover = ; } suffix = suffix ? _.trimStart(suffix, '.').toUpperCase() : null; const downloadButton = ; const detailsButton = setDetailsOpen(true)} />; const [detailsOpen, setDetailsOpen] = React.useState(false); const detailsModal = setDetailsOpen(false)} trigger={detailsButton} > {ebook.title || file.title} Author: {ebook.creator} {humanFileSize(ebook.size)} eBook Path {ebook ? ebook.ebook_path : file.path} Cover Path {ebook && ebook.cover_path ? ebook.cover_path : 'N/A'} {downloadButton} ; const color = mimetypeColor(file.mimetype); return {cover} {ebook ? ebook.title : file.title} {suffix} {detailsModal} } function ImageCard({file}) { const {s} = useContext(ThemeContext); const url = `/media/${encodeURIComponent(file.path)}`; let poster = ; if (file.size && file.size < 50000000) { // Image is less than 5mb, use it. poster = ; } return {poster} {textEllipsis(file.title || file.stem || file.path)} {isoDatetimeToString(file.modified / 1000)} {humanFileSize(file.size)} } function FileCard({file}) { const {s} = useContext(ThemeContext); const isEbookType = file.mimetype && ( file.mimetype.startsWith('application/epub') || file.mimetype.startsWith('application/x-mobipocket-ebook') ); if (file.model === 'video' && file['video']) { return ; } else if (file.model === 'archive' && file['archive']) { return ; } else if (file.mimetype && file.mimetype.startsWith('image/')) { return ; } else if (isEbookType) { return ; } const url = `/download/${encodeURIComponent(file.path)}`; const color = mimetypeColor(file.mimetype); const size = file.size !== null && file.size !== undefined ? humanFileSize(file.size) : null; return {cardTitleWrapper(file.title || file.stem || file.path)} {isoDatetimeToString(file.modified / 1000)} {size} } export function FileCards({files}) { if (!_.isEmpty(files)) { return {files.map(i => )} } else if (files && files.length === 0) { return No results! } else { return } } function ImageRowCells({file}) { const url = `/media/${encodeURIComponent(file.path)}`; let poster = ; if (file.size && file.size < 50000000) { // Image is less than 5mb, use it. poster = ; } // Fragment for SelectableRow return ( {poster} {textEllipsis(file.title || file.stem || file.path)} ) } export function EbookRowCells({file}) { const {ebook} = file; const downloadUrl = `/download/${encodeURIComponent(file.path)}`; const viewerUrl = file['mimetype'].startsWith('application/epub') ? `/epub.html?url=${downloadUrl}` : null; let cover = ; if (ebook && ebook.cover_path) { const coverSrc = `/media/${encodeURIComponent(ebook.cover_path)}`; cover = ; } // Fragment for SelectableRow return ( {cover} {textEllipsis(ebook.title || file.title)} ) } function FileRow({file}) { const isEbookType = file.mimetype && ( file.mimetype.startsWith('application/epub') || file.mimetype.startsWith('application/x-mobipocket-ebook') ); if (file.model === 'video' && 'video' in file) { return ; } else if (file.model === 'archive' && 'archive' in file) { return ; } else if (file.mimetype && file.mimetype.startsWith('image/')) { return ; } else if (isEbookType) { return ; } const onDownloadFile = async () => window.open(`/media/${file.key}`); // Fragment for SelectableRow return onDownloadFile()}> {textEllipsis(file.title)} } export function FileTable({files, selectOn, onSelect, footer, selectedKeys}) { if (!files) { return } else if (files && files.length > 0) { const headerContents = ['Poster', 'Title']; const rows = files.map(i => ); return ; } else { return No results! } } export function FilesView({ files, limit, setLimit, showLimit = false, activePage, totalPages, view, setView, showView = true, showSelect = false, selectElem, selectedKeys, onSelect, setPage, menuColumnsCount, menuColumns, filterOptions, activeFilters, setFilters, multipleFilters, filterPlaceholder, }) { let selectButton; const [selectOn, setSelectOn] = React.useState(false); const toggleSelectOn = () => setSelectOn(!selectOn); const selectButtonDisabled = view !== 'list'; if (showSelect && selectOn) { selectButton = ; } else if (showSelect) { selectButton = ; } let viewButton; if (showView) { if (view === 'list') { viewButton = setView('cards')}/>; } else { viewButton = setView('list')}/>; } } let limitDropdown; const limitOptions = [ {key: 12, value: 12, text: '12'}, {key: 24, value: 24, text: '24'}, {key: 48, value: 48, text: '48'}, {key: 96, value: 96, text: '96'}, ]; if (showLimit) { limitDropdown = setLimit(value)} /> } const paginator = ; let body; if (view === 'list') { const footer = selectOn && selectElem ? <> {selectElem} > : null; body = ; } else { body = ; } const filtersDropdown = setFilters(value)} style={{marginLeft: '0.3em'}} value={activeFilters} />; return <> {selectButton} {viewButton} {limitDropdown} {filterOptions && filtersDropdown} {menuColumns} {body} {paginator} > } export function FilesSearchView({ showView = true, showLimit = false, showSelect = false, emptySearch = false, filterOptions, model, onSelect, setFilters, }) { filterOptions = filterOptions || [ {key: 'video', text: 'Video', value: 'video'}, {key: 'archive', text: 'Archive', value: 'archive'}, {key: 'pdf', text: 'PDF', value: 'pdf'}, {key: 'ebook', text: 'eBook', value: 'ebook'}, {key: 'image', text: 'Image', value: 'image'}, {key: 'zip', text: 'ZIP', value: 'zip'}, ]; const {searchFiles, limit, setLimit, totalPages, activePage, setPage, filter} = useSearchFiles(24, emptySearch, model); const {searchParams, updateQuery} = useQuery(); const setView = (value) => updateQuery({view: value}); const view = searchParams.get('view'); const setFilter = (value) => updateQuery({'filter': value}); return } export function FilesRoute() { return }/> ; } export function FilesRefreshButton() { const {status} = useContext(StatusContext); const refreshing = status && status['flags'] && status['flags'].indexOf('refreshing') >= 0; const refreshingDirectory = status && status['flags'] && status['flags'].indexOf('refreshing_directory') >= 0; const [loading, setLoading] = React.useState(false); const handleClick = async () => { setLoading(true); await refreshFiles(); } // Clear loading when global refresh event completes. useSubscribeEventName('global_refresh_completed', () => setLoading(false)); return Refresh All ; } export function DirectoryRefreshButton({directory}) { const {status} = useContext(StatusContext); const refreshing = status && status['flags'] && status['flags'].indexOf('refreshing') >= 0; const refreshingDirectory = status && status['flags'] && status['flags'].indexOf('refreshing_directory') >= 0; const [loading, setLoading] = React.useState(false); const handleClick = async () => { setLoading(true); await refreshDirectoryFiles(directory); } // Clear loading when global refresh event completes. useSubscribeEventName('global_refresh_completed', () => setLoading(false)); useSubscribeEventName('directory_refresh_completed', () => setLoading(false)); return Refresh Directory }
{humanFileSize(ebook.size)}
{ebook ? ebook.ebook_path : file.path}
{ebook && ebook.cover_path ? ebook.cover_path : 'N/A'}
{suffix}
{textEllipsis(file.title || file.stem || file.path)}
{isoDatetimeToString(file.modified / 1000)}
{humanFileSize(file.size)}
{size}