import { Trans } from "@lingui/macro" import { Anchor, Box, Button, Code, Container, Divider, Group, Input, NumberInput, Stack, Text, TextInput, Title } from "@mantine/core" import { useForm } from "@mantine/form" import { openConfirmModal } from "@mantine/modals" import { client, errorToStrings } from "app/client" import { redirectToRootCategory, redirectToSelectedSource } from "app/redirect/thunks" import { useAppDispatch, useAppSelector } from "app/store" import { reloadTree } from "app/tree/thunks" import type { FeedModificationRequest } from "app/types" import { Alert } from "components/Alert" import { Loader } from "components/Loader" import { RelativeDate } from "components/RelativeDate" import { CategorySelect } from "components/content/add/CategorySelect" import { useEffect } from "react" import { useAsync, useAsyncCallback } from "react-async-hook" import { TbDeviceFloppy, TbTrash } from "react-icons/tb" import { useParams } from "react-router-dom" function FilteringExpressionDescription() { const example = url.contains('youtube') or (author eq 'athou' and title.contains('github')) return (
If not empty, an expression evaluating to 'true' or 'false'. If false, new entries for this feed will be marked as read automatically.
Available variables are 'title', 'content', 'url' 'author' and 'categories' and their content is converted to lower case to ease string comparison.
Example: {example}.
Complete syntax is available here .
) } export function FeedDetailsPage() { const { id } = useParams() if (!id) throw Error("id required") const apiKey = useAppSelector(state => state.user.profile?.apiKey) const dispatch = useAppDispatch() const query = useAsync(async () => await client.feed.get(id), [id]) const feed = query.result?.data const form = useForm() const { setValues } = form const modifyFeed = useAsyncCallback(client.feed.modify, { onSuccess: () => { dispatch(reloadTree()) dispatch(redirectToSelectedSource()) }, }) const unsubscribe = useAsyncCallback(client.feed.unsubscribe, { onSuccess: () => { dispatch(reloadTree()) dispatch(redirectToRootCategory()) }, }) const openUnsubscribeModal = () => { const feedName = feed?.name openConfirmModal({ title: Unsubscribe, children: ( Are you sure you want to unsubscribe from {feedName}? ), labels: { confirm: Confirm, cancel: Cancel }, confirmProps: { color: "red" }, onConfirm: async () => await unsubscribe.execute({ id: +id }), }) } useEffect(() => { if (!feed) return setValues(feed) }, [setValues, feed]) if (!feed) return return ( {modifyFeed.error && ( )} {unsubscribe.error && ( )}
{feed.name} Feed URL}> {feed.feedUrl} Website}> {feed.feedLink} Last refresh}> Last refresh message}> {feed.message ?? N/A} Next refresh}> Generated feed url}> {apiKey && ( Link )} {!apiKey && Generate an API key in your profile first.} Name} {...form.getInputProps("name")} required /> Category} {...form.getInputProps("categoryId")} clearable /> Position} {...form.getInputProps("position")} required min={0} /> Filtering expression} description={} {...form.getInputProps("filter")} />
) }