feat: display claimed feed list in settings
This commit is contained in:
parent
f1a2ecb7d2
commit
d9ae277cfa
|
|
@ -73,6 +73,12 @@
|
|||
"appearance.title": "Appearance",
|
||||
"appearance.ui_font": "UI Font",
|
||||
"appearance.unread_count": "Unread count",
|
||||
"feeds.claimTips": "To claim your feeds and receive tips, right-click on the feed in your subscription list and select Claim.",
|
||||
"feeds.noFeeds": "No claimed feeds",
|
||||
"feeds.tableHeaders.entryCount": "Entries",
|
||||
"feeds.tableHeaders.name": "Name",
|
||||
"feeds.tableHeaders.subscriptionCount": "Subscriptions",
|
||||
"feeds.tableHeaders.tipAmount": "Received tips",
|
||||
"general.app": "App",
|
||||
"general.data_persist.description": "Persist data locally to enable offline access and local search.",
|
||||
"general.data_persist.label": "Persist data for offline usage",
|
||||
|
|
@ -152,6 +158,7 @@
|
|||
"titles.about": "About",
|
||||
"titles.actions": "Actions",
|
||||
"titles.appearance": "Appearance",
|
||||
"titles.feeds": "Feeds",
|
||||
"titles.general": "General",
|
||||
"titles.integration": "Integration",
|
||||
"titles.invitations": "Invitations",
|
||||
|
|
|
|||
30
src/hono.ts
30
src/hono.ts
|
|
@ -4943,6 +4943,36 @@ declare const _routes: hono_hono_base.HonoBase<
|
|||
status: 200
|
||||
}
|
||||
}
|
||||
"/feeds/claim/list": {
|
||||
$get: {
|
||||
input: {}
|
||||
output: {
|
||||
code: 0
|
||||
data: {
|
||||
feed: {
|
||||
description: string | null
|
||||
title: string | null
|
||||
id: string
|
||||
image: string | null
|
||||
url: string
|
||||
siteUrl: string | null
|
||||
checkedAt: string
|
||||
lastModifiedHeader: string | null
|
||||
etagHeader: string | null
|
||||
ttl: number | null
|
||||
errorMessage: string | null
|
||||
errorAt: string | null
|
||||
ownerUserId: string | null
|
||||
}
|
||||
subscriptionCount: number
|
||||
tipAmount: number
|
||||
entryCount: number
|
||||
}[]
|
||||
}
|
||||
outputFormat: "json" | "text"
|
||||
status: 200
|
||||
}
|
||||
}
|
||||
"/feeds": {
|
||||
$get: {
|
||||
input: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
import { FeedIcon } from "@renderer/components/feed-icon"
|
||||
import { LoadingCircle } from "@renderer/components/ui/loading"
|
||||
import { ScrollArea } from "@renderer/components/ui/scroll-area"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@renderer/components/ui/table"
|
||||
import { useAuthQuery } from "@renderer/hooks/common"
|
||||
import { Balance } from "@renderer/modules/wallet/balance"
|
||||
import { Queries } from "@renderer/queries"
|
||||
import { WEB_URL } from "@shared/constants"
|
||||
import { useTranslation } from "react-i18next"
|
||||
|
||||
export const SettingFeeds = () => {
|
||||
const { t } = useTranslation("settings")
|
||||
const claimedList = useAuthQuery(Queries.feed.claimedList())
|
||||
|
||||
return (
|
||||
<section className="mt-4">
|
||||
<div className="mb-4 space-y-2 text-sm">
|
||||
<p>{t("feeds.claimTips")}</p>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col">
|
||||
<ScrollArea.ScrollArea viewportClassName="max-h-[380px]">
|
||||
{claimedList.data?.length ? (
|
||||
<Table className="mt-4">
|
||||
<TableHeader className="border-b">
|
||||
<TableRow className="[&_*]:!font-semibold">
|
||||
<TableHead className="w-16 text-center" size="sm">
|
||||
{t("feeds.tableHeaders.name")}
|
||||
</TableHead>
|
||||
<TableHead className="text-center" size="sm">
|
||||
{t("feeds.tableHeaders.entryCount")}
|
||||
</TableHead>
|
||||
<TableHead className="text-center" size="sm">
|
||||
{t("feeds.tableHeaders.subscriptionCount")}
|
||||
</TableHead>
|
||||
<TableHead className="text-center" size="sm">
|
||||
{t("feeds.tableHeaders.tipAmount")}
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody className="border-t-[12px] border-transparent">
|
||||
{claimedList.data?.map((row) => (
|
||||
<TableRow key={row.feed.id} className="h-8">
|
||||
<TableCell size="sm">
|
||||
<a
|
||||
target="_blank"
|
||||
href={`${WEB_URL}/feed/${row.feed.id}`}
|
||||
className="flex items-center"
|
||||
>
|
||||
<FeedIcon fallback feed={row.feed} size={16} />
|
||||
<span className="inline-block max-w-[200px] truncate">
|
||||
{row.feed.title}
|
||||
</span>
|
||||
</a>
|
||||
</TableCell>
|
||||
<TableCell align="center" className="tabular-nums" size="sm">
|
||||
{row.entryCount}
|
||||
</TableCell>
|
||||
<TableCell align="center" className="tabular-nums" size="sm">
|
||||
{row.subscriptionCount}
|
||||
</TableCell>
|
||||
<TableCell align="center" size="sm">
|
||||
<Balance>{BigInt(row.tipAmount || 0n)}</Balance>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
) : claimedList.isLoading ? (
|
||||
<LoadingCircle size="large" className="center absolute inset-0" />
|
||||
) : (
|
||||
<div className="mt-36 w-full text-center text-sm text-zinc-400">
|
||||
<p>{t("feeds.noFeeds")}</p>
|
||||
</div>
|
||||
)}
|
||||
</ScrollArea.ScrollArea>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { SettingFeeds } from "@renderer/modules/settings/tabs/feeds"
|
||||
import { SettingsTitle } from "@renderer/modules/settings/title"
|
||||
import { defineSettingPageData } from "@renderer/modules/settings/utils"
|
||||
|
||||
const iconName = "i-mgc-certificate-cute-re"
|
||||
const priority = 1053
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
iconName,
|
||||
name: "titles.feeds",
|
||||
priority,
|
||||
})
|
||||
|
||||
export function Component() {
|
||||
return (
|
||||
<>
|
||||
<SettingsTitle />
|
||||
<SettingFeeds />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -32,6 +32,11 @@ export const feed = {
|
|||
return res
|
||||
}),
|
||||
),
|
||||
claimedList: () =>
|
||||
defineQuery(["feed", "claimedList"], async () => {
|
||||
const res = await apiClient.feeds.claim.list.$get()
|
||||
return res.data
|
||||
}),
|
||||
}
|
||||
|
||||
export const useFeed = ({ id, url }: FeedQueryParams) =>
|
||||
|
|
|
|||
Loading…
Reference in New Issue