diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad681335..6b255d6d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - node-version: [18.x] + node-version: [20.x] steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/src/main/tipc/player.ts b/src/main/tipc/player.ts index de6522e0..6d8ab117 100644 --- a/src/main/tipc/player.ts +++ b/src/main/tipc/player.ts @@ -7,7 +7,7 @@ import FFmpeg from '@main/lib/ffmpeg' import { getFilePathFromProtocolURL } from '@main/lib/protocols' import { coverSubtitleToAss } from '@main/lib/utils' import { showFileSelectionDialog } from '@main/modules/showDialog' -import { calculateFileHashByBuffer } from '@renderer/lib/calc-file-hash' +import { calculateFileHashByBuffer } from '@renderer/lib/file' import { dialog } from 'electron' import naturalCompare from 'string-natural-compare' diff --git a/src/main/tipc/utils.ts b/src/main/tipc/utils.ts index be429865..bc4b0949 100644 --- a/src/main/tipc/utils.ts +++ b/src/main/tipc/utils.ts @@ -1,13 +1,52 @@ +import path from 'node:path' + import { getFilePathFromProtocolURL } from '@main/lib/protocols' import { coverSubtitleToAss } from '@main/lib/utils' import { t } from './_instance' +type Actions = + | 'cover-path-from-protocol' + | 'get-file-name-from-path' + | 'url-to-base64' + | 'cover-subtitle-to-ass' + +// type FileAction = T extends 'cover-subtitle-to-ass' + export const utilsRoute = { - getFilePathFromProtocolURL: t.procedure.input<{ path: string }>().action(async ({ input }) => { - return getFilePathFromProtocolURL(input.path) - }), - coverSubtitleToAss: t.procedure.input<{ path: string }>().action(async ({ input }) => { + fileAction: t.procedure + .input<{ + action: Actions + url: string + }>() + .action(async ({ input }) => { + const { url, action } = input + + switch (action) { + case 'cover-path-from-protocol': { + return getFilePathFromProtocolURL(url) + } + case 'get-file-name-from-path': { + return path.basename(url) + } + case 'url-to-base64': { + try { + const response = await fetch(url) + const arrayBuffer = await response.arrayBuffer() + const buffer = Buffer.from(arrayBuffer) + const base64 = buffer.toString('base64') + return `data:${response.headers.get('content-type')};base64,${base64}` + } catch (error) { + console.error('Error converting image to base64:', error) + return + } + } + default: { + throw new Error(`Unsupported action: ${action}`) + } + } + }), + coverSubtitleToAss: t.procedure.input<{ path: string }>().action(({ input }) => { return coverSubtitleToAss(input.path) }), } diff --git a/src/renderer/src/atoms/settings/app.ts b/src/renderer/src/atoms/settings/app.ts index 96b32218..6466dd09 100644 --- a/src/renderer/src/atoms/settings/app.ts +++ b/src/renderer/src/atoms/settings/app.ts @@ -14,4 +14,4 @@ const createAppDefaultSettings = () => { export const appSettingAtom = createSettingATom('app', createAppDefaultSettings) export const useAppSettings = () => useAtom(appSettingAtom) -export const useAppSettingsValue = () => useAtomValue(appSettingAtom) +export const useAppSettingsValue = () => useAtomValue(appSettingAtom) \ No newline at end of file diff --git a/src/renderer/src/components/common/ErrorView.tsx b/src/renderer/src/components/common/ErrorView.tsx index 05ab3fa6..d80d933e 100644 --- a/src/renderer/src/components/common/ErrorView.tsx +++ b/src/renderer/src/components/common/ErrorView.tsx @@ -1,30 +1,48 @@ import { tipcClient } from '@renderer/lib/client' +import { RouteName } from '@renderer/router' import * as Sentry from '@sentry/react' import { useEffect } from 'react' -import { useRouteError } from 'react-router' +import { useLocation, useNavigate, useRouteError } from 'react-router' import { Button } from '../ui/button' export default function ErrorView() { const error = useRouteError() as { statusText: string; message: string } + const location = useLocation() + const navigate = useNavigate() console.error(error) useEffect(() => { Sentry.captureException(error) }, [error]) return ( -
+

糟糕发生错误了😭

-

- 错误信息: {error?.statusText ?? error?.message} -

- +
+

+ 错误信息: {error?.statusText ?? error?.message} +

+

+ 当前路由: {location.pathname} +

+
+
+ + + +
) } diff --git a/src/renderer/src/components/layout/root/RouterLayout.tsx b/src/renderer/src/components/layout/root/RouterLayout.tsx deleted file mode 100644 index 46e8a09d..00000000 --- a/src/renderer/src/components/layout/root/RouterLayout.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { cn, isWeb } from '@renderer/lib/utils' -import { RouteName, useCurrentRoute } from '@renderer/router' -import type { FC, PropsWithChildren, ReactNode } from 'react' - -interface RouterLayoutProps extends PropsWithChildren { - FunctionArea?: ReactNode -} - -export const RouterLayout: FC = ({ children, FunctionArea }) => { - const currentRoute = useCurrentRoute() - if (currentRoute?.path === RouteName.PLAYER) { - return - } - return ( -
-
-

- {currentRoute?.meta.title} -

- {FunctionArea} -
- {children} -
- ) -} diff --git a/src/renderer/src/components/layout/root/TitleBarLayout.tsx b/src/renderer/src/components/layout/root/TitleBarLayout.tsx new file mode 100644 index 00000000..64d64d41 --- /dev/null +++ b/src/renderer/src/components/layout/root/TitleBarLayout.tsx @@ -0,0 +1,28 @@ +import { cn } from '@renderer/lib/utils' +import { useCurrentRoute } from '@renderer/router' +import type { FC, PropsWithChildren, ReactNode } from 'react' + +interface TitleBarLayoutProps extends PropsWithChildren { + FunctionArea?: ReactNode + title?: ReactNode +} + +export const TitleBarLayout: FC = ({ children, FunctionArea, title }) => { + const currentRoute = useCurrentRoute() + + return ( +
+
+
+ {title ?? ( +

+ {currentRoute?.meta?.title} +

+ )} +
+ {FunctionArea} +
+ {children} +
+ ) +} diff --git a/src/renderer/src/components/layout/sidebar/index.tsx b/src/renderer/src/components/layout/sidebar/index.tsx index aa79db98..ea68c6e0 100644 --- a/src/renderer/src/components/layout/sidebar/index.tsx +++ b/src/renderer/src/components/layout/sidebar/index.tsx @@ -32,7 +32,7 @@ export const Sidebar = () => {

- showModal()} /> + showModal()} />