Skip to content

Commit

Permalink
feat: custom feed title (#300)
Browse files Browse the repository at this point in the history
* feat: custom feed title

* fix: use type button

* refactor: do not override original feed title
  • Loading branch information
hyoban authored Sep 9, 2024
1 parent 6ce06be commit 501e2f4
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/hono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2790,6 +2790,7 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
json: {
view: number;
url: string;
title?: string | null | undefined;
category?: string | null | undefined;
isPrivate?: boolean | undefined;
};
Expand Down Expand Up @@ -2818,6 +2819,7 @@ declare const _routes: hono_hono_base.HonoBase<Env, {
json: {
view: number;
feedId: string;
title?: string | null | undefined;
category?: string | null | undefined;
isPrivate?: boolean | undefined;
};
Expand Down
23 changes: 23 additions & 0 deletions src/renderer/src/modules/discover/feed-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
FormLabel,
FormMessage,
} from "@renderer/components/ui/form"
import { Input } from "@renderer/components/ui/input"
import { LoadingCircle } from "@renderer/components/ui/loading"
import { useCurrentModal } from "@renderer/components/ui/modal"
import { Switch } from "@renderer/components/ui/switch"
Expand All @@ -38,6 +39,7 @@ const formSchema = z.object({
view: z.string(),
category: z.string().nullable().optional(),
isPrivate: z.boolean().optional(),
title: z.string().optional(),
})

const defaultValue = { view: FeedViewType.Articles.toString() } as z.infer<
Expand Down Expand Up @@ -142,6 +144,7 @@ const FeedInnerForm = ({
form.setValue("view", `${subscription?.view}`)
subscription?.category && form.setValue("category", subscription.category)
form.setValue("isPrivate", subscription?.isPrivate || false)
form.setValue("title", subscription?.title || "")
}
}, [subscription])

Expand All @@ -152,6 +155,7 @@ const FeedInnerForm = ({
view: Number.parseInt(values.view),
category: values.category,
isPrivate: values.isPrivate,
title: values.title,
...(isSubscribed && { feedId: feed.id }),
}
const $method = isSubscribed ?
Expand Down Expand Up @@ -266,6 +270,24 @@ const FeedInnerForm = ({
</FormItem>
)}
/>
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<div>
<FormLabel>Tile</FormLabel>
<FormDescription>
Custom title for this Feed. Leave empty to use the default.
</FormDescription>
</div>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="category"
Expand Down Expand Up @@ -325,6 +347,7 @@ const FeedInnerForm = ({
<div className="flex flex-1 items-end justify-end gap-4">
{isSubscribed && (
<Button
type="button"
ref={buttonRef}
variant="text"
isLoading={deleteSubscription.isPending}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAsRead } from "@renderer/hooks/biz/useAsRead"
import { cn } from "@renderer/lib/utils"
import { EntryTranslation } from "@renderer/modules/entry-column/translation"
import { useEntry } from "@renderer/store/entry/hooks"
import { useFeedById } from "@renderer/store/feed"
import { getPreferredTitle, useFeedById } from "@renderer/store/feed"
import dayjs from "dayjs"

import { StarIcon } from "../star-icon"
Expand Down Expand Up @@ -63,7 +63,7 @@ export function GridItem({
entry={entry.entries}
size={18}
/>
<span className="min-w-0 truncate">{feeds?.title}</span>
<span className="min-w-0 truncate">{getPreferredTitle(feeds)}</span>
<span className="text-zinc-500">·</span>
<span className="text-zinc-500">
{dayjs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { cn, isSafari } from "@renderer/lib/utils"
import { EntryTranslation } from "@renderer/modules/entry-column/translation"
import { Queries } from "@renderer/queries"
import { useEntry } from "@renderer/store/entry/hooks"
import { useFeedById } from "@renderer/store/feed"
import { getPreferredTitle, useFeedById } from "@renderer/store/feed"
import { useDebounceCallback } from "usehooks-ts"

import { ReactVirtuosoItemPlaceholder } from "../../../components/ui/placeholder"
Expand Down Expand Up @@ -82,7 +82,7 @@ export function ListItem({
entry.collections && "text-zinc-600 dark:text-zinc-500",
)}
>
<span className="truncate">{feed.title}</span>
<span className="truncate">{getPreferredTitle(feed)}</span>
<span>·</span>
<span className="shrink-0">
{!!displayTime && <RelativeTime date={displayTime} />}
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/src/modules/entry-content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
} from "@renderer/providers/wrapped-element-provider"
import { Queries } from "@renderer/queries"
import { useEntry, useEntryReadHistory } from "@renderer/store/entry"
import { useFeedById, useFeedHeaderTitle } from "@renderer/store/feed"
import { getPreferredTitle, useFeedById, useFeedHeaderTitle } from "@renderer/store/feed"
import type { FallbackRender } from "@sentry/react"
import { ErrorBoundary } from "@sentry/react"
import type { FC } from "react"
Expand Down Expand Up @@ -190,7 +190,7 @@ export const EntryContentRender: Component<{ entryId: string }> = ({
/>
</div>
<div className="mt-2 text-[13px] font-medium text-zinc-500">
{feed?.title}
{getPreferredTitle(feed)}
</div>
<div className="flex items-center gap-2 text-[13px] text-zinc-500">
{entry.entries.publishedAt &&
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/src/modules/feed-column/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { nextFrame } from "@renderer/lib/dom"
import { getNewIssueUrl } from "@renderer/lib/issues"
import { showNativeMenu } from "@renderer/lib/native-menu"
import { cn } from "@renderer/lib/utils"
import { useFeedById } from "@renderer/store/feed"
import { getPreferredTitle, useFeedById } from "@renderer/store/feed"
import { useSubscriptionByFeedId } from "@renderer/store/subscription"
import { useFeedUnreadStore } from "@renderer/store/unread"
import { WEB_URL } from "@shared/constants"
Expand Down Expand Up @@ -124,7 +124,7 @@ const FeedItemImpl = ({
(feedUnread ? "font-bold" : "font-medium opacity-70"),
)}
>
{feed.title}
{getPreferredTitle(feed)}
</div>
{isOwned && (
<Tooltip delayDuration={300}>
Expand Down
8 changes: 7 additions & 1 deletion src/renderer/src/store/feed/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
} from "@renderer/constants"
import { useRouteParms } from "@renderer/hooks/biz/useRouteParams"
import type { FeedModel } from "@renderer/models"
import { useMemo } from "react"
import { useShallow } from "zustand/react/shallow"

import { getSubscriptionByFeedId } from "../subscription"
import { useFeedStore } from "./store"
import type { FeedQueryParams } from "./types"

Expand Down Expand Up @@ -38,6 +40,10 @@ export const useFeedHeaderTitle = () => {
const { feedId: currentFeedId, view } = useRouteParms()

const feedTitle = useFeedByIdSelector(currentFeedId, (feed) => feed.title)
const subscriptionTitle = useMemo(
() => currentFeedId ? getSubscriptionByFeedId(currentFeedId)?.title ?? "" : "",
[currentFeedId],
)

switch (currentFeedId) {
case ROUTE_FEED_PENDING: {
Expand All @@ -50,7 +56,7 @@ export const useFeedHeaderTitle = () => {
if (currentFeedId?.startsWith(ROUTE_FEED_IN_FOLDER)) {
return currentFeedId.replace(ROUTE_FEED_IN_FOLDER, "")
}
return feedTitle
return subscriptionTitle || feedTitle
}
}
}
10 changes: 10 additions & 0 deletions src/renderer/src/store/feed/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FeedService } from "@renderer/services"
import { produce } from "immer"
import { nanoid } from "nanoid"

import { getSubscriptionByFeedId } from "../subscription"
import { createZustandStore, doMutationAndTransaction } from "../utils/helper"
import type { FeedQueryParams, FeedState } from "./types"

Expand Down Expand Up @@ -100,3 +101,12 @@ export const feedActions = new FeedActions()

export const getFeedById = (feedId: string): Nullable<FeedModel> =>
useFeedStore.getState().feeds[feedId]

export const getPreferredTitle = (feed?: FeedModel | null) => {
if (!feed?.id) {
return feed?.title
}

const subscription = getSubscriptionByFeedId(feed.id)
return subscription?.title || feed.title
}

0 comments on commit 501e2f4

Please sign in to comment.