Skip to content

Commit

Permalink
refactor: simplify useRegisterCommand types (RSSNext#1678)
Browse files Browse the repository at this point in the history
  • Loading branch information
lawvs authored Nov 21, 2024
1 parent 2158b1c commit 840c49e
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 160 deletions.
53 changes: 26 additions & 27 deletions apps/renderer/src/modules/command/commands/entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import { tipcClient } from "~/lib/client"
import { useTipModal } from "~/modules/wallet/hooks"
import { entryActions, useEntryStore } from "~/store/entry"

import { useRegisterCommandEffect } from "../hooks/use-register-command-effect"
import { defineFollowCommand } from "../registry/command"
import { useRegisterFollowCommand } from "../hooks/use-register-command"
import { COMMAND_ID } from "./id"

const useCollect = () => {
Expand Down Expand Up @@ -89,8 +88,8 @@ export const useRegisterEntryCommands = () => {
const read = useRead()
const unread = useUnread()

useRegisterCommandEffect([
defineFollowCommand({
useRegisterFollowCommand([
{
id: COMMAND_ID.entry.tip,
label: t("entry_actions.tip"),
icon: <i className="i-mgc-power-outline" />,
Expand All @@ -105,8 +104,8 @@ export const useRegisterEntryCommands = () => {
}),
)
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.star,
label: t("entry_actions.star"),
icon: <i className="i-mgc-star-cute-re" />,
Expand All @@ -127,8 +126,8 @@ export const useRegisterEntryCommands = () => {
// }
collect.mutate({ entryId, view })
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.unstar,
label: t("entry_actions.unstar"),
icon: <i className="i-mgc-star-cute-fi text-orange-500" />,
Expand All @@ -140,8 +139,8 @@ export const useRegisterEntryCommands = () => {
}
uncollect.mutate(entry.entries.id)
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.delete,
label: t("entry_actions.delete"),
icon: <i className="i-mgc-delete-2-cute-re" />,
Expand All @@ -153,8 +152,8 @@ export const useRegisterEntryCommands = () => {
}
deleteInboxEntry.mutate(entry.entries.id)
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.copyLink,
label: t("entry_actions.copy_link"),
icon: <i className="i-mgc-link-cute-re" />,
Expand All @@ -170,8 +169,8 @@ export const useRegisterEntryCommands = () => {
duration: 1000,
})
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.copyTitle,
label: t("entry_actions.copy_title"),
icon: <i className="i-mgc-copy-cute-re" />,
Expand All @@ -187,8 +186,8 @@ export const useRegisterEntryCommands = () => {
duration: 1000,
})
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.openInBrowser,
label: t("entry_actions.open_in_browser", {
which: t(IN_ELECTRON ? "words.browser" : "words.newTab"),
Expand All @@ -202,8 +201,8 @@ export const useRegisterEntryCommands = () => {
}
window.open(entry.entries.url, "_blank")
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.viewSourceContent,
label: t("entry_actions.view_source_content"),
icon: <i className="i-mgc-world-2-cute-re" />,
Expand Down Expand Up @@ -232,16 +231,16 @@ export const useRegisterEntryCommands = () => {
}
setShowSourceContent(true)
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.viewEntryContent,
label: t("entry_actions.view_source_content"),
icon: <i className="i-mgc-world-2-cute-fi" />,
run: () => {
setShowSourceContent(false)
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.share,
label: t("entry_actions.share"),
icon:
Expand All @@ -267,8 +266,8 @@ export const useRegisterEntryCommands = () => {
}
return
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.read,
label: t("entry_actions.mark_as_read"),
icon: <i className="i-mgc-round-cute-fi" />,
Expand All @@ -280,8 +279,8 @@ export const useRegisterEntryCommands = () => {
}
read.mutate({ entryId, feedId: entry.feedId })
},
}),
defineFollowCommand({
},
{
id: COMMAND_ID.entry.unread,
label: t("entry_actions.mark_as_unread"),
icon: <i className="i-mgc-round-cute-re" />,
Expand All @@ -293,6 +292,6 @@ export const useRegisterEntryCommands = () => {
}
unread.mutate({ entryId, feedId: entry.feedId })
},
}),
},
])
}
2 changes: 1 addition & 1 deletion apps/renderer/src/modules/command/commands/integration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { parseHtml } from "~/lib/parse-html"
import type { FlatEntryModel } from "~/store/entry"
import { useEntryStore } from "~/store/entry"

import { useRegisterCommandEffect } from "../hooks/use-register-command-effect"
import { useRegisterCommandEffect } from "../hooks/use-register-command"
import { defineFollowCommand } from "../registry/command"
import { COMMAND_ID } from "./id"

Expand Down
2 changes: 1 addition & 1 deletion apps/renderer/src/modules/command/commands/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { getRouteParams } from "~/hooks/biz/useRouteParams"
import { useDeleteSubscription } from "~/hooks/biz/useSubscriptionActions"
import { ListForm } from "~/modules/discover/list-form"

import { useRegisterCommandEffect } from "../hooks/use-register-command-effect"
import { useRegisterCommandEffect } from "../hooks/use-register-command"
import { COMMAND_ID } from "./id"

export const useRegisterListCommands = () => {
Expand Down
2 changes: 1 addition & 1 deletion apps/renderer/src/modules/command/commands/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"

import { useSetTheme } from "~/hooks/common"

import { useRegisterCommandEffect } from "../hooks/use-register-command-effect"
import { useRegisterCommandEffect } from "../hooks/use-register-command"

export const useRegisterThemeCommands = () => {
const [t] = useTranslation("settings")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { assertType, expectTypeOf, test } from "vitest"

import { COMMAND_ID } from "../commands/id"
import { useRegisterFollowCommand } from "./use-register-command"

test("useRegisterFollowCommand types", () => {
assertType(
useRegisterFollowCommand({
id: COMMAND_ID.entry.openInBrowser,
label: "",
run: ({ entryId }) => {
expectTypeOf(entryId).toEqualTypeOf<string>()
},
}),
)

assertType(
useRegisterFollowCommand({
id: "unknown id",
label: "",
run: (...args) => {
expectTypeOf(args).toEqualTypeOf<[]>()
},
}),
)

assertType(
useRegisterFollowCommand([
{
id: COMMAND_ID.entry.star,
label: "",
run: ({ entryId }) => {
expectTypeOf(entryId).toEqualTypeOf<string>()
},
},
{
id: COMMAND_ID.entry.viewEntryContent,
label: "",
run: (...args) => {
expectTypeOf(args).toEqualTypeOf<[]>()
},
},
]),
)

assertType(
useRegisterFollowCommand([
{
id: "unknown id",
label: "",
run: (...args) => {
expectTypeOf(args).toEqualTypeOf<[]>()
},
},
]),
)

assertType(
useRegisterFollowCommand([
{
id: "unknown id",
label: "",
run: (...args) => {
expectTypeOf(args).toEqualTypeOf<[]>()
},
},
{
id: COMMAND_ID.entry.star,
label: "",
run: ({ entryId }) => {
expectTypeOf(entryId).toEqualTypeOf<string>()
},
},
{
id: COMMAND_ID.entry.viewEntryContent,
label: "",
run: (...args) => {
expectTypeOf(args).toEqualTypeOf<[]>()
},
},
]),
)
})
66 changes: 66 additions & 0 deletions apps/renderer/src/modules/command/hooks/use-register-command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { useEffect } from "react"
import { useTranslation } from "react-i18next"

import { registerCommand } from "../registry/registry"
import type { CommandOptions, FollowCommandId, FollowCommandMap } from "../types"

export type RegisterOptions = {
deps?: unknown[]
enabled?: boolean
// forceMountSection?: boolean
// sectionMeta?: Record<string, unknown>
// orderSection?: OrderSectionInstruction
// orderCommands?: OrderCommandsInstruction
}

export const useRegisterCommandEffect = (
options: CommandOptions | CommandOptions[],
registerOptions?: RegisterOptions,
) => {
const { t } = useTranslation()
useEffect(() => {
if (!Array.isArray(options)) {
return registerCommand(options)
}

const unsubscribes = options.map((option) => registerCommand(option))
return () => {
unsubscribes.forEach((unsubscribe) => unsubscribe())
}
// eslint-disable-next-line react-hooks/exhaustive-deps -- we want to run this effect only once
}, [t, ...(registerOptions?.deps ?? [])])
}

/**
* Register a follow command.
*/
export function useRegisterFollowCommand<T extends FollowCommandId>(
options: CommandOptions<{ id: T; fn: FollowCommandMap[T]["run"] }>,
registerOptions?: RegisterOptions,
): void
/**
* Register a unknown command.
*/
export function useRegisterFollowCommand<T extends string>(
options: CommandOptions<{ id: T; fn: () => void }>,
registerOptions?: RegisterOptions,
): void
/**
* Register multiple follow commands or unknown commands.
*/
export function useRegisterFollowCommand<T extends (FollowCommandId | string)[]>(
options: [
...{
[K in keyof T]: T[K] extends FollowCommandId
? CommandOptions<{ id: T[K]; fn: FollowCommandMap[T[K]]["run"] }>
: CommandOptions<{ id: T[K]; fn: () => void }>
},
],
registerOptions?: RegisterOptions,
): void
export function useRegisterFollowCommand(
options: CommandOptions | CommandOptions[],
registerOptions?: RegisterOptions,
) {
return useRegisterCommandEffect(options as CommandOptions | CommandOptions[], registerOptions)
}
Loading

0 comments on commit 840c49e

Please sign in to comment.