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:
parent
4a14738a99
commit
737d40c851
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue