add download button

This commit is contained in:
NlightN22 2024-12-01 01:33:48 +07:00
parent a9c4d9abb9
commit 910a0fa309
6 changed files with 59 additions and 20 deletions

View File

@ -104,6 +104,8 @@ const en = {
doubleClickToFullHint: 'Double click for fullscreen', doubleClickToFullHint: 'Double click for fullscreen',
rating: 'Rating', rating: 'Rating',
}, },
preparingVideo: 'Preparing video...',
download: 'Download',
maxRetries: 'Error: Unable to fetch data after {{maxRetries}} retries. Please try again later or change period to smaller.', maxRetries: 'Error: Unable to fetch data after {{maxRetries}} retries. Please try again later or change period to smaller.',
config: 'Config', config: 'Config',
create: 'Create', create: 'Create',

View File

@ -101,6 +101,8 @@ const ru = {
doubleClickToFullHint: 'Двойное нажатие мышью для полноэкранного просмотра', doubleClickToFullHint: 'Двойное нажатие мышью для полноэкранного просмотра',
rating: 'Рейтинг', rating: 'Рейтинг',
}, },
preparingVideo: 'Подготовка видео...',
download: 'Скачать',
maxRetries: 'Ошибка: невозможно получить данные после {{maxRetries}} попыток. Пожалуйста попробуйте позже или поменяйте период на меньший.', maxRetries: 'Ошибка: невозможно получить данные после {{maxRetries}} попыток. Пожалуйста попробуйте позже или поменяйте период на меньший.',
config: 'Конфиг.', config: 'Конфиг.',
create: 'Создать', create: 'Создать',

View File

@ -1,10 +1,11 @@
import { Button, Flex, Group, Text } from '@mantine/core'; import { Button, Flex, Group, Text } from '@mantine/core';
import { IconExternalLink } from '@tabler/icons-react'; import { IconDownload } from '@tabler/icons-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { proxyApi } from '../../../services/frigate.proxy/frigate.api'; import { proxyApi } from '../../../services/frigate.proxy/frigate.api';
import { EventFrigate } from '../../../types/event'; import { EventFrigate } from '../../../types/event';
import { getDurationFromTimestamps, unixTimeToDate } from '../../utils/dateUtil'; import { getDurationFromTimestamps, unixTimeToDate } from '../../utils/dateUtil';
import VideoPlayer from '../players/VideoPlayer'; import VideoPlayer from '../players/VideoPlayer';
import DownloadButton from '../buttons/DownloadButton';
interface EventPanelProps { interface EventPanelProps {
event: EventFrigate event: EventFrigate
@ -46,14 +47,9 @@ const EventPanel = ({
<Flex direction='column' align='end' justify='center'> <Flex direction='column' align='end' justify='center'>
{!hostName ? '' : {!hostName ? '' :
<Flex> <Flex>
<Button <DownloadButton
component="a" link={proxyApi.eventDownloadURL(hostName, event.id)}
href={proxyApi.eventDownloadURL(hostName, event.id)} />
download
variant="outline"
leftIcon={<IconExternalLink size="0.9rem" />}>
Download event
</Button>
</Flex> </Flex>
} }
</Flex> </Flex>

View File

@ -1,4 +1,4 @@
import { Accordion, Center, Loader, Text } from '@mantine/core'; import { Accordion, Center, Flex, Loader, Text } from '@mantine/core';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { observer } from 'mobx-react-lite'; import { observer } from 'mobx-react-lite';
import { useContext, useState } from 'react'; import { useContext, useState } from 'react';
@ -9,6 +9,7 @@ import { GetCameraWHostWConfig, GetFrigateHost, getEventsQuerySchema } from '../
import { getUnixTime } from '../../utils/dateUtil'; import { getUnixTime } from '../../utils/dateUtil';
import RetryError from '../RetryError'; import RetryError from '../RetryError';
import EventsAccordionItem from './EventsAccordionItem'; import EventsAccordionItem from './EventsAccordionItem';
import CogwheelLoader from '../loaders/CogwheelLoader';
/** /**
* @param day frigate format, e.g day: 2024-02-23 * @param day frigate format, e.g day: 2024-02-23
@ -97,16 +98,20 @@ const EventsAccordion = ({
} }
}) })
if (isPending) return <Center><Loader /></Center> if (isPending) return <Flex w='100%' h='100%' direction='column' justify='center' align='center'><CogwheelLoader /></Flex>
if (isError && retryCount >= MAX_RETRY_COUNT) { if (isError && retryCount >= MAX_RETRY_COUNT) {
return ( return (
<Center> <Flex w='100%' h='100%' direction='column' justify='center' align='center'>
<Text>{t('maxRetries', { maxRetries: MAX_RETRY_COUNT })}</Text> <Text>{t('maxRetries', { maxRetries: MAX_RETRY_COUNT })}</Text>
</Center> </Flex>
); );
} }
if (isError) return <RetryError onRetry={refetch} /> if (isError) return <RetryError onRetry={refetch} />
if (!data || data.length < 1) return <Center><Text>{t('notHaveEventsAtThatPeriod')}</Text></Center> if (!data || data.length < 1) return (
<Flex w='100%' h='100%' direction='column' justify='center' align='center'>
<Text>{t('notHaveEventsAtThatPeriod')}</Text>
</Flex>
)
const handleOpenPlayer = (value: string | undefined) => { const handleOpenPlayer = (value: string | undefined) => {
if (value !== recStore.playedItem) { if (value !== recStore.playedItem) {

View File

@ -0,0 +1,33 @@
import { Button } from '@mantine/core';
import { IconDownload } from '@tabler/icons-react';
import { t } from 'i18next';
import { FC } from 'react';
interface DownloadButtonProps {
link?: string
onClick?(): void
}
const DownloadButton: FC<DownloadButtonProps> = ({
link,
onClick
}) => {
const handleOnClick = () => {
if (onClick) onClick()
}
return (
<Button
component="a"
href={link}
download
variant="outline"
leftIcon={<IconDownload size="0.9rem" />}
onClick={handleOnClick}
>
{t('download')}
</Button>
);
};
export default DownloadButton;

View File

@ -6,6 +6,8 @@ import { useEffect, useState } from 'react';
import { proxyApi } from '../services/frigate.proxy/frigate.api'; import { proxyApi } from '../services/frigate.proxy/frigate.api';
import RetryError from '../shared/components/RetryError'; import RetryError from '../shared/components/RetryError';
import { formatFileTimestamps } from '../shared/utils/dateUtil'; import { formatFileTimestamps } from '../shared/utils/dateUtil';
import { useTranslation } from 'react-i18next';
import DownloadButton from '../shared/components/buttons/DownloadButton';
interface VideoDownloaderProps { interface VideoDownloaderProps {
cameraName: string cameraName: string
@ -20,6 +22,9 @@ const VideoDownloader = ({
startUnixTime, startUnixTime,
endUnixTime, endUnixTime,
}: VideoDownloaderProps) => { }: VideoDownloaderProps) => {
const { t } = useTranslation()
const maxVideoTime = 70 * 60 const maxVideoTime = 70 * 60
const [createName, setCreateName] = useState<string>() const [createName, setCreateName] = useState<string>()
const [link, setLink] = useState<string>() const [link, setLink] = useState<string>()
@ -138,17 +143,13 @@ const VideoDownloader = ({
const preparingVideo = ( const preparingVideo = (
<> <>
<Text>Preparing video...<Loader /></Text> <Text>{t('preparingVideo')}<Loader /></Text>
</> </>
) )
if (createName) return preparingVideo if (createName) return preparingVideo
return ( return (
<Button <DownloadButton onClick={handleDownload}/>
onClick={handleDownload}
>
Download
</Button>
); );
}; };