diff --git a/apps/desktop/layer/renderer/src/atoms/context-menu.ts b/apps/desktop/layer/renderer/src/atoms/context-menu.ts
index f8344fa65..bc943d0d5 100644
--- a/apps/desktop/layer/renderer/src/atoms/context-menu.ts
+++ b/apps/desktop/layer/renderer/src/atoms/context-menu.ts
@@ -56,7 +56,6 @@ export type FollowMenuItem = MenuItemText | MenuItemSeparator
export type MenuItemInput = MenuItemText | MenuItemSeparator | NilValue
function sortShortcutsString(shortcut: string) {
- shortcut = shortcut.replace("$mod", "Meta")
const order = ["Shift", "Ctrl", "Meta", "Alt"]
const nextShortcut = transformShortcut(shortcut)
diff --git a/apps/desktop/layer/renderer/src/constants/shortcuts.ts b/apps/desktop/layer/renderer/src/constants/shortcuts.ts
index c35e160ec..cbeee4397 100644
--- a/apps/desktop/layer/renderer/src/constants/shortcuts.ts
+++ b/apps/desktop/layer/renderer/src/constants/shortcuts.ts
@@ -41,6 +41,10 @@ const shortcutConfigs = {
name: tShortcuts("keys.subscriptions.openInBrowser"),
key: "O",
},
+ openSiteInBrowser: {
+ name: tShortcuts("keys.subscriptions.openSiteInBrowser"),
+ key: "$mod+O",
+ },
markAllAsRead: {
name: tShortcuts("keys.entries.markAllAsRead"),
key: "Shift+$mod+A",
diff --git a/apps/desktop/layer/renderer/src/hooks/biz/useFeedActions.tsx b/apps/desktop/layer/renderer/src/hooks/biz/useFeedActions.tsx
index dbff5df33..1865ab042 100644
--- a/apps/desktop/layer/renderer/src/hooks/biz/useFeedActions.tsx
+++ b/apps/desktop/layer/renderer/src/hooks/biz/useFeedActions.tsx
@@ -13,11 +13,12 @@ import { MenuItemSeparator, MenuItemText } from "~/atoms/context-menu"
import { useIsInMASReview } from "~/atoms/server-configs"
import { whoami } from "~/atoms/user"
import { useModalStack } from "~/components/ui/modal/stacked/hooks"
-import { shortcuts } from "~/constants/shortcuts"
import { apiClient } from "~/lib/api-fetch"
import { UrlBuilder } from "~/lib/url-builder"
import { useBoostModal } from "~/modules/boost/hooks"
import { useFeedClaimModal } from "~/modules/claim"
+import { COMMAND_ID } from "~/modules/command/commands/id"
+import { useCommandShortcuts } from "~/modules/command/hooks/use-command-binding"
import { FeedForm } from "~/modules/discover/FeedForm"
import { InboxForm } from "~/modules/discover/InboxForm"
import { ListForm } from "~/modules/discover/ListForm"
@@ -46,11 +47,11 @@ const ConfirmDestroyModalContent = ({ onConfirm }: { onConfirm: () => void }) =>
return (
-
+
{t("sidebar.feed_actions.unfollow_feed_many_warning")}
-
@@ -107,6 +108,8 @@ export const useFeedActions = ({
const isInMASReview = useIsInMASReview()
+ const shortcuts = useCommandShortcuts()
+
const items = useMemo(() => {
const related = feed || inbox
if (!related) return []
@@ -116,7 +119,7 @@ export const useFeedActions = ({
const items: MenuItemInput[] = [
new MenuItemText({
label: t("sidebar.feed_actions.mark_all_as_read"),
- shortcut: "$mod+Shift+A",
+ shortcut: shortcuts[COMMAND_ID.subscription.markAllAsRead],
disabled: isEntryList,
click: () =>
subscriptionActions.markReadByFeedIds({
@@ -138,8 +141,10 @@ export const useFeedActions = ({
}),
...(isFeedOwner
? [
+ MenuItemSeparator.default,
new MenuItemText({
label: t("sidebar.feed_actions.feed_owned_by_you"),
+ disabled: true,
}),
new MenuItemText({
label: t("sidebar.feed_actions.reset_feed"),
@@ -147,6 +152,7 @@ export const useFeedActions = ({
resetFeed(feedId)
},
}),
+ MenuItemSeparator.default,
]
: []),
...(!isInMASReview
@@ -294,7 +300,7 @@ export const useFeedActions = ({
new MenuItemText({
label: t("sidebar.feed_actions.navigate_to_feed"),
shortcut: "$mod+G",
- disabled: isInbox || !isEntryList || getRouteParams().feedId === feedId,
+ disabled: getRouteParams().feedId === feedId,
click: () => {
navigateEntry({ feedId })
},
@@ -305,14 +311,14 @@ export const useFeedActions = ({
which: t(IN_ELECTRON ? "words.browser" : "words.newTab"),
}),
disabled: isEntryList,
- shortcut: "O",
+ shortcut: shortcuts[COMMAND_ID.subscription.openInBrowser],
click: () => window.open(UrlBuilder.shareFeed(feedId, view), "_blank"),
}),
new MenuItemText({
label: t("sidebar.feed_actions.open_site_in_browser", {
which: t(IN_ELECTRON ? "words.browser" : "words.newTab"),
}),
- shortcut: "$mod+O",
+ shortcut: shortcuts[COMMAND_ID.subscription.openSiteInBrowser],
disabled: isEntryList,
click: () => {
const feed = getFeedById(feedId)
@@ -364,7 +370,9 @@ export const useFeedActions = ({
feed,
inbox,
t,
+ shortcuts,
isEntryList,
+ isInMASReview,
isInbox,
listByView,
categories,
@@ -396,18 +404,33 @@ export const useListActions = ({ listId, view }: { listId: string; view?: FeedVi
const { present } = useModalStack()
const { mutateAsync: deleteSubscription } = useDeleteSubscription({})
+ const shortcuts = useCommandShortcuts()
const navigateEntry = useNavigateEntry()
const items = useMemo(() => {
if (!list) return []
const items: MenuItemInput[] = [
- list.ownerUserId === whoami()?.id &&
- new MenuItemText({
- label: t("sidebar.feed_actions.list_owned_by_you"),
- }),
- list.ownerUserId !== whoami()?.id && MenuItemSeparator.default,
+ ...(list.ownerUserId === whoami()?.id
+ ? [
+ new MenuItemText({
+ label: t("sidebar.feed_actions.list_owned_by_you"),
+ disabled: true,
+ }),
+ MenuItemSeparator.default,
+ ]
+ : []),
+ new MenuItemText({
+ label: t("sidebar.feed_actions.mark_all_as_read"),
+ shortcut: shortcuts[COMMAND_ID.subscription.markAllAsRead],
+ click: () => {
+ subscriptionActions.markReadByFeedIds({
+ feedIds: list.feedIds,
+ })
+ },
+ }),
+ MenuItemSeparator.default,
new MenuItemText({
label: t("sidebar.feed_actions.edit"),
shortcut: "E",
@@ -436,7 +459,7 @@ export const useListActions = ({ listId, view }: { listId: string; view?: FeedVi
label: t("sidebar.feed_actions.open_list_in_browser", {
which: t(IN_ELECTRON ? "words.browser" : "words.newTab"),
}),
- shortcut: shortcuts.subscriptions.openInBrowser.key,
+ shortcut: shortcuts[COMMAND_ID.subscription.openInBrowser],
click: () => window.open(UrlBuilder.shareList(listId, view), "_blank"),
}),
MenuItemSeparator.default,
@@ -457,7 +480,7 @@ export const useListActions = ({ listId, view }: { listId: string; view?: FeedVi
]
return items
- }, [list, t, present, deleteSubscription, subscription, navigateEntry, listId, view])
+ }, [list, t, shortcuts, listId, present, deleteSubscription, subscription, navigateEntry, view])
return items
}
diff --git a/apps/desktop/layer/renderer/src/modules/command/commands/id.ts b/apps/desktop/layer/renderer/src/modules/command/commands/id.ts
index 89119adb6..842b51379 100644
--- a/apps/desktop/layer/renderer/src/modules/command/commands/id.ts
+++ b/apps/desktop/layer/renderer/src/modules/command/commands/id.ts
@@ -77,5 +77,7 @@ export const COMMAND_ID = {
toggleFolderCollapse: "subscription:toggle-folder-collapse",
markAllAsRead: "subscription:mark-all-as-read",
+ openInBrowser: "subscription:open-in-browser",
+ openSiteInBrowser: "subscription:open-site-in-browser",
},
} as const
diff --git a/apps/desktop/layer/renderer/src/modules/command/commands/subscription.tsx b/apps/desktop/layer/renderer/src/modules/command/commands/subscription.tsx
index 371a7c1b5..f8088d19d 100644
--- a/apps/desktop/layer/renderer/src/modules/command/commands/subscription.tsx
+++ b/apps/desktop/layer/renderer/src/modules/command/commands/subscription.tsx
@@ -22,6 +22,8 @@ declare module "@follow/utils/event-bus" {
"subscription:previous": never
"subscription:toggle-folder-collapse": never
"subscription:mark-all-as-read": BizRouteParams
+ "subscription:open-in-browser": never
+ "subscription:open-site-in-browser": never
}
}
const LABEL_PREFIX = "Subscription"
@@ -112,6 +114,20 @@ export const useRegisterSubscriptionCommands = () => {
EventBus.dispatch(COMMAND_ID.subscription.markAllAsRead, routeParams)
},
},
+ {
+ id: COMMAND_ID.subscription.openInBrowser,
+ label: `${LABEL_PREFIX}: Open in Browser`,
+ run: () => {
+ EventBus.dispatch(COMMAND_ID.subscription.openInBrowser)
+ },
+ },
+ {
+ id: COMMAND_ID.subscription.openSiteInBrowser,
+ label: `${LABEL_PREFIX}: Open site in Browser`,
+ run: () => {
+ EventBus.dispatch(COMMAND_ID.subscription.openSiteInBrowser)
+ },
+ },
])
}
@@ -175,6 +191,16 @@ type MarkAllAsReadCommand = Command<{
fn: () => void
}>
+type OpenInBrowserCommand = Command<{
+ id: typeof COMMAND_ID.subscription.openInBrowser
+ fn: () => void
+}>
+
+type OpenSiteInBrowserCommand = Command<{
+ id: typeof COMMAND_ID.subscription.openSiteInBrowser
+ fn: () => void
+}>
+
export type SubscriptionCommand =
| SwitchTabToNextCommand
| SwitchTabToPreviousCommand
@@ -188,3 +214,5 @@ export type SubscriptionCommand =
| PreviousSubscriptionCommand
| ToggleFolderCollapseCommand
| MarkAllAsReadCommand
+ | OpenInBrowserCommand
+ | OpenSiteInBrowserCommand
diff --git a/apps/desktop/layer/renderer/src/modules/command/hooks/use-command-binding.ts b/apps/desktop/layer/renderer/src/modules/command/hooks/use-command-binding.ts
index 14a8cab53..6d3c9f70a 100644
--- a/apps/desktop/layer/renderer/src/modules/command/hooks/use-command-binding.ts
+++ b/apps/desktop/layer/renderer/src/modules/command/hooks/use-command-binding.ts
@@ -35,17 +35,23 @@ const defaultCommandShortcuts = {
[COMMAND_ID.subscription.toggleFolderCollapse]: shortcuts.subscriptions.toggleFolderCollapse.key,
[COMMAND_ID.subscription.markAllAsRead]: shortcuts.subscriptions.markAllAsRead.key,
+ [COMMAND_ID.subscription.openInBrowser]: shortcuts.subscriptions.openInBrowser.key,
+ [COMMAND_ID.subscription.openSiteInBrowser]: shortcuts.subscriptions.openSiteInBrowser.key,
} as const
export type BindingCommandId = keyof typeof defaultCommandShortcuts
// eslint-disable-next-line @eslint-react/hooks-extra/no-unnecessary-use-prefix, @eslint-react/hooks-extra/ensure-custom-hooks-using-other-hooks
-export const useCommandShortcut = (commandId: BindingCommandId): string => {
+const useCommandShortcut = (commandId: BindingCommandId): string => {
const commandShortcut = defaultCommandShortcuts[commandId]
return commandShortcut
}
+export const useCommandShortcuts = () => {
+ return defaultCommandShortcuts
+}
+
export const useCommandBinding =
({
commandId,
when = true,
diff --git a/locales/shortcuts/en.json b/locales/shortcuts/en.json
index 197a5f652..3ab296943 100644
--- a/locales/shortcuts/en.json
+++ b/locales/shortcuts/en.json
@@ -24,6 +24,7 @@
"keys.subscriptions.add": "Add Subscription",
"keys.subscriptions.nextSubscription": "Next Subscription",
"keys.subscriptions.openInBrowser": "Open in Browser",
+ "keys.subscriptions.openSiteInBrowser": "Open site in Browser",
"keys.subscriptions.previousSubscription": "Previous Subscription",
"keys.subscriptions.switchBetweenViews": "Switch Between Views",
"keys.subscriptions.switchNextView": "Switch to Next View",
diff --git a/packages/internal/utils/src/utils.ts b/packages/internal/utils/src/utils.ts
index 6e87c59a2..d22edbd4e 100644
--- a/packages/internal/utils/src/utils.ts
+++ b/packages/internal/utils/src/utils.ts
@@ -345,10 +345,10 @@ export const toScientificNotation = (
}
export function transformShortcut(shortcut: string, platform: OS = getOS()): string {
- if (platform === "Windows") {
- return shortcut.replace("Meta", "Ctrl").replace("meta", "ctrl")
+ if (platform === "macOS") {
+ return shortcut.replace("$mod", "Meta")
}
- return shortcut
+ return shortcut.replace("$mod", "Ctrl")
}
// time like 1:30:00