import { ActionIcon, Badge, Card, Center, createStyles, Flex, Group, Image, Loader, LoadingOverlay, MediaQuery, ScrollArea, Stack, Text, Title, UnstyledButton, } from '@mantine/core'; import { useElementSize } from '@mantine/hooks'; import { IconBulldozer, IconCalendarTime, IconClock, IconCopyright, IconRefresh, IconRss, IconSpeakerphone, } from '@tabler/icons'; import { useTranslation } from 'next-i18next'; import Link from 'next/link'; import { useState } from 'react'; import { useGetRssFeed } from '../../hooks/widgets/rss/useGetRssFeed'; import { sleep } from '../../tools/client/time'; import { defineWidget } from '../helper'; import { IWidget } from '../widgets'; const definition = defineWidget({ id: 'rss', icon: IconRss, options: { rssFeedUrl: { type: 'text', defaultValue: '', }, }, gridstack: { minWidth: 2, minHeight: 2, maxWidth: 12, maxHeight: 12, }, component: RssTile, }); export type IRssWidget = IWidget<(typeof definition)['id'], typeof definition>; interface RssTileProps { widget: IRssWidget; } function RssTile({ widget }: RssTileProps) { const { t } = useTranslation('modules/rss'); const { data, isLoading, isFetching, isError, refetch } = useGetRssFeed( widget.properties.rssFeedUrl ); const { classes } = useStyles(); const [loadingOverlayVisible, setLoadingOverlayVisible] = useState(false); const { ref, height } = useElementSize(); if (!data || isLoading) { return (
); } if (!data.success || isError) { return (
{t('card.errors.general.title')} {t('card.errors.general.text')}
); } return ( {data.feed.image ? ( {data.feed.image.title} ) : ( {data.feed.title} )} { setLoadingOverlayVisible(true); await Promise.all([sleep(1500), refetch()]); setLoadingOverlayVisible(false); }} disabled={isFetching || isLoading} > {data.feed.items.map((item: any, index: number) => ( {item.enclosure && ( // eslint-disable-next-line @next/next/no-img-element backdrop )} {item.categories && ( {item.categories.map((category: any, categoryIndex: number) => ( {category._} ))} )} {item.title} {item.content} {item.pubDate && } ))} {data.feed.copyright} {data.feed.pubDate} {data.feed.lastBuildDate} {data.feed.feedUrl && ( Feed URL )} ); } const TimeDisplay = ({ date }: { date: string }) => ( {date} ); const useStyles = createStyles(({ colorScheme }) => ({ backgroundImage: { position: 'absolute', width: '100%', height: '100%', filter: colorScheme === 'dark' ? 'blur(30px)' : 'blur(15px)', transform: 'scaleX(-1)', opacity: colorScheme === 'dark' ? 0.3 : 0.2, transition: 'ease-in-out 0.2s', '&:hover': { opacity: colorScheme === 'dark' ? 0.4 : 0.3, filter: 'blur(40px) brightness(0.7)', }, }, })); export default definition;