refactor: improve native menu item handling

* Refactor useFeedActions component to conditionally add a separator in the menu list based on the length of listByView array.
Refactor FeedCategoryImpl component to conditionally add a separator in the menu list based on the length of listList array.

* update

* fix: type

Signed-off-by: Innei <tukon479@gmail.com>

---------

Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: Innei <tukon479@gmail.com>
This commit is contained in:
Jerry Wong 2024-10-15 18:48:21 +08:00 committed by GitHub
parent 4a14738a99
commit 737d40c851
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 37 deletions

View File

@ -116,9 +116,7 @@ export const useFeedActions = ({
},
}
}),
{
type: "separator",
},
listByView.length > 0 && { type: "separator" as const },
{
label: t("sidebar.feed_actions.create_list"),
type: "text" as const,

View File

@ -4,22 +4,39 @@ import { get } from "lodash-es"
import { tipcClient } from "./client"
import { getOS } from "./utils"
export type NativeMenuItem = (
| {
type: "text"
label: string
click?: () => void
/** only work in web app */
icon?: React.ReactNode
shortcut?: string
disabled?: boolean
submenu?: NativeMenuItem[]
checked?: boolean
}
| { type: "separator"; disabled?: boolean }
) & { hide?: boolean }
type MenuItemWithHide<T> = T & {
hide?: boolean
}
export type NullableNativeMenuItem = NativeMenuItem | null | undefined | false | ""
type BaseMenuItemText = MenuItemWithHide<{
type: "text"
label: string
click?: () => void
/** only work in web app */
icon?: React.ReactNode
shortcut?: string
disabled?: boolean
checked?: boolean
}>
type BaseMenuItemSeparator = MenuItemWithHide<{
type: "separator"
disabled?: boolean
}>
type BaseMenuItem = BaseMenuItemText | BaseMenuItemSeparator
export type NativeMenuItem = BaseMenuItem & {
submenu?: NativeMenuItem[]
}
export type NullableNativeMenuItem =
| (BaseMenuItemText & { submenu?: NullableNativeMenuItem[] })
| BaseMenuItemSeparator
| null
| undefined
| false
| ""
function sortShortcutsString(shortcut: string) {
const order = ["Shift", "Ctrl", "Meta", "Alt"]
@ -37,19 +54,24 @@ function sortShortcutsString(shortcut: string) {
return [...sortedModifiers, ...otherKeys].join("+")
}
export const showNativeMenu = async (
items: Array<NullableNativeMenuItem>,
e?: MouseEvent | React.MouseEvent,
) => {
const nextItems = (items.filter((item) => item && !item.hide) as NativeMenuItem[]).map((item) => {
function processMenuItems(items: NullableNativeMenuItem[]): NativeMenuItem[] {
return (items.filter((item) => item && !item.hide) as NativeMenuItem[]).map((item) => {
if (item.type === "text") {
return {
...item,
shortcut: item.shortcut ? sortShortcutsString(item.shortcut) : undefined,
submenu: item.submenu ? processMenuItems(item.submenu) : undefined,
}
}
return item
}) as NativeMenuItem[]
})
}
export const showNativeMenu = async (
items: Array<NullableNativeMenuItem>,
e?: MouseEvent | React.MouseEvent,
) => {
const nextItems = processMenuItems(items)
const el = e && e.currentTarget

View File

@ -14,6 +14,7 @@ import { getRouteParams, useRouteParamsSelector } from "~/hooks/biz/useRoutePara
import { useAnyPointDown, useInputComposition, useRefValue } from "~/hooks/common"
import { stopPropagation } from "~/lib/dom"
import type { FeedViewType } from "~/lib/enum"
import type { NullableNativeMenuItem } from "~/lib/native-menu"
import { showNativeMenu } from "~/lib/native-menu"
import { cn, sortByAlphabet } from "~/lib/utils"
import { getPreferredTitle, useAddFeedToFeedList, useFeedStore } from "~/store/feed"
@ -166,6 +167,7 @@ function FeedCategoryImpl({ data: ids, view, categoryOpenStateData }: FeedCatego
}}
onContextMenu={(e) => {
setIsContextMenuOpen(true)
showNativeMenu(
[
{
@ -181,21 +183,23 @@ function FeedCategoryImpl({ data: ids, view, categoryOpenStateData }: FeedCatego
{
type: "text",
label: t("sidebar.feed_column.context_menu.add_feeds_to_list"),
// @ts-expect-error
submenu: listList
?.map((list) => ({
label: list.title || "",
type: "text",
click() {
return addMutation.mutate({
feedIds: ids,
listId: list.id,
})
},
}))
?.map(
(list) =>
({
label: list.title || "",
type: "text",
click() {
return addMutation.mutate({
feedIds: ids,
listId: list.id,
})
},
}) as NullableNativeMenuItem,
)
.concat(listList?.length > 0 ? [{ type: "separator" as const }] : [])
.concat([
// @ts-expect-error
{ type: "separator" as const },
{
label: t("sidebar.feed_actions.create_list"),
type: "text" as const,