diff --git a/apps/desktop/layer/renderer/src/modules/subscription-column/SubscriptionTabButton.tsx b/apps/desktop/layer/renderer/src/modules/subscription-column/SubscriptionTabButton.tsx
index 7062b8228..611fc27d3 100644
--- a/apps/desktop/layer/renderer/src/modules/subscription-column/SubscriptionTabButton.tsx
+++ b/apps/desktop/layer/renderer/src/modules/subscription-column/SubscriptionTabButton.tsx
@@ -7,12 +7,16 @@ import type { FC } from "react"
import { startTransition, useCallback } from "react"
import { useTranslation } from "react-i18next"
-import { useUISettingKey } from "~/atoms/settings/ui"
+import { MenuItemText, useShowContextMenu } from "~/atoms/context-menu"
+import { setUISetting, useUISettingKey } from "~/atoms/settings/ui"
import { FocusablePresets } from "~/components/common/Focusable"
import { useNavigateEntry } from "~/hooks/biz/useNavigateEntry"
import { parseView, useRouteParamsSelector } from "~/hooks/biz/useRouteParams"
+import { useTimelineList } from "~/hooks/biz/useTimelineList"
+import { useContextMenu } from "~/hooks/common/useContextMenu"
import { resetSelectedFeedIds } from "./atom"
+import { useShowTimelineTabsSettingsModal } from "./TimelineTabsSettingsModal"
export function SubscriptionTabButton({
timelineId,
@@ -25,35 +29,125 @@ export function SubscriptionTabButton({
const isActive = activeTimelineId === timelineId
const navigate = useNavigateEntry()
+ const navigateToTimeline = useCallback(
+ (nextTimelineId: string) => {
+ navigate({
+ timelineId: nextTimelineId,
+ feedId: null,
+ entryId: null,
+ })
+ resetSelectedFeedIds()
+ },
+ [navigate],
+ )
const setActive = useCallback(() => {
- navigate({
- timelineId,
- feedId: null,
- entryId: null,
- })
- resetSelectedFeedIds()
- }, [navigate, timelineId])
+ navigateToTimeline(timelineId)
+ }, [navigateToTimeline, timelineId])
const view = parseView(timelineId)
if (view === FeedViewType.All) {
- return
+ return (
+
+ )
} else if (typeof view === "number") {
return (
-
+
)
}
}
+const useSubscriptionTabContextMenu = ({
+ timelineId,
+ isActive,
+ navigateToTimeline,
+}: {
+ timelineId: string
+ isActive: boolean
+ navigateToTimeline: (timelineId: string) => void
+}) => {
+ const { t } = useTranslation()
+ const showContextMenu = useShowContextMenu()
+ const showTimelineTabsSettingsModal = useShowTimelineTabsSettingsModal()
+ const visibleTimelineList = useTimelineList({ withAll: true, visible: true })
+ const hiddenTimelineList = useTimelineList({ withAll: true, hidden: true })
+
+ const canHide = visibleTimelineList.filter((id) => id !== timelineId).length > 0
+
+ const handleHide = useCallback(() => {
+ if (!canHide) return
+
+ const nextVisible = visibleTimelineList.filter((id) => id !== timelineId)
+ const nextHidden = hiddenTimelineList.filter((id) => id !== timelineId).concat(timelineId)
+ setUISetting("timelineTabs", {
+ visible: nextVisible,
+ hidden: nextHidden,
+ })
+
+ if (isActive) {
+ const currentIndex = visibleTimelineList.indexOf(timelineId)
+ const fallbackTimelineId =
+ nextVisible[currentIndex] ?? nextVisible[currentIndex - 1] ?? nextVisible[0]
+
+ if (fallbackTimelineId) {
+ navigateToTimeline(fallbackTimelineId)
+ }
+ }
+ }, [canHide, hiddenTimelineList, isActive, navigateToTimeline, timelineId, visibleTimelineList])
+
+ const contextMenuProps = useContextMenu({
+ onContextMenu: async (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ await showContextMenu(
+ [
+ new MenuItemText({
+ label: t("sidebar.timeline_tabs.hide_tab"),
+ click: handleHide,
+ disabled: !canHide,
+ }),
+ new MenuItemText({
+ label: t("sidebar.timeline_tabs.customize"),
+ click: showTimelineTabsSettingsModal,
+ }),
+ ],
+ event,
+ )
+ },
+ })
+
+ return contextMenuProps
+}
+
const ViewAllSwitchButton: FC<{
+ timelineId: string
isActive: boolean
setActive: () => void
shortcut: string
-}> = ({ isActive, setActive, shortcut }) => {
+ navigateToTimeline: (timelineId: string) => void
+}> = ({ timelineId, isActive, setActive, shortcut, navigateToTimeline }) => {
const unreadByView = useUnreadByView(FeedViewType.All)
const { t } = useTranslation()
const showSidebarUnreadCount = useUISettingKey("sidebarShowUnreadCount")
const item = getView(FeedViewType.All)
+ const contextMenuProps = useSubscriptionTabContextMenu({
+ timelineId,
+ isActive,
+ navigateToTimeline,
+ })
return (
{
startTransition(() => {
setActive()
@@ -92,10 +187,12 @@ const ViewAllSwitchButton: FC<{
const ViewSwitchButton: FC<{
view: FeedViewType
+ timelineId: string
isActive: boolean
setActive: () => void
shortcut: string
-}> = ({ view, isActive, setActive, shortcut }) => {
+ navigateToTimeline: (timelineId: string) => void
+}> = ({ view, timelineId, isActive, setActive, shortcut, navigateToTimeline }) => {
const unreadByView = useUnreadByView(view)
const { t } = useTranslation()
const showSidebarUnreadCount = useUISettingKey("sidebarShowUnreadCount")
@@ -107,6 +204,11 @@ const ViewSwitchButton: FC<{
view: item.view,
},
})
+ const contextMenuProps = useSubscriptionTabContextMenu({
+ timelineId,
+ isActive,
+ navigateToTimeline,
+ })
return (
{
startTransition(() => {
setActive()
diff --git a/apps/desktop/layer/renderer/src/modules/subscription-column/TimelineTabsSettingsModal.tsx b/apps/desktop/layer/renderer/src/modules/subscription-column/TimelineTabsSettingsModal.tsx
index 1b562f7a1..6e44b8487 100644
--- a/apps/desktop/layer/renderer/src/modules/subscription-column/TimelineTabsSettingsModal.tsx
+++ b/apps/desktop/layer/renderer/src/modules/subscription-column/TimelineTabsSettingsModal.tsx
@@ -228,7 +228,7 @@ export const useShowTimelineTabsSettingsModal = () => {
return useCallback(() => {
present({
id: "timeline-tabs-settings",
- title: "Customize Timeline Tabs",
+ title: "Customize View Tabs",
content: () => ,
overlay: true,
clickOutsideToDismiss: true,
diff --git a/locales/app/en.json b/locales/app/en.json
index 562a97568..b884c6a01 100644
--- a/locales/app/en.json
+++ b/locales/app/en.json
@@ -392,6 +392,8 @@
"sidebar.feed_column.context_menu.rename_category_success": "Category renamed successfully",
"sidebar.feed_column.context_menu.title": "Move to New Category",
"sidebar.select_sort_method": "Select a sort method",
+ "sidebar.timeline_tabs.customize": "Customize View Tabs...",
+ "sidebar.timeline_tabs.hide_tab": "Hide this view",
"signin.continue_with": "Continue with {{provider}}",
"signin.sign_in_to": "Sign in to",
"signin.sign_up_to": "Sign up to",
diff --git a/locales/app/ja.json b/locales/app/ja.json
index 27ce764c1..e60c93dc0 100644
--- a/locales/app/ja.json
+++ b/locales/app/ja.json
@@ -387,6 +387,8 @@
"sidebar.feed_column.context_menu.rename_category_success": "カテゴリーのリネームに成功しました",
"sidebar.feed_column.context_menu.title": "新規カテゴリーに移動する",
"sidebar.select_sort_method": "並べ替え方法を選択",
+ "sidebar.timeline_tabs.customize": "ビュータブをカスタマイズ...",
+ "sidebar.timeline_tabs.hide_tab": "このビューを非表示にする",
"signin.continue_with": "{{provider}} で続ける",
"signin.sign_in_to": "サインイン",
"signin.sign_up_to": "サインアップ",
diff --git a/locales/app/zh-CN.json b/locales/app/zh-CN.json
index be9c649ac..ae1353754 100644
--- a/locales/app/zh-CN.json
+++ b/locales/app/zh-CN.json
@@ -390,6 +390,8 @@
"sidebar.feed_column.context_menu.rename_category_success": "分类重命名成功",
"sidebar.feed_column.context_menu.title": "移动至新分类",
"sidebar.select_sort_method": "选择排序方法",
+ "sidebar.timeline_tabs.customize": "自定义视图标签...",
+ "sidebar.timeline_tabs.hide_tab": "隐藏此视图",
"signin.continue_with": "使用 {{provider}} 登录",
"signin.sign_in_to": "登录",
"signin.sign_up_to": "注册",
diff --git a/locales/settings/en.json b/locales/settings/en.json
index 577cd811c..2f4c5c75e 100644
--- a/locales/settings/en.json
+++ b/locales/settings/en.json
@@ -129,7 +129,7 @@
"appearance.custom_font": "Custom Font",
"appearance.customization.title": "Customization",
"appearance.customize_sub_tabs.description": "Customize the subscription tabs to your liking.",
- "appearance.customize_sub_tabs.label": "Customize Subscription Tabs",
+ "appearance.customize_sub_tabs.label": "Customize View Tabs",
"appearance.customize_toolbar.description": "Customize the entry content toolbar to your liking.",
"appearance.customize_toolbar.label": "Customize Toolbar",
"appearance.date_format.description": "Adjust the display date format.",