diff --git a/.github/workflows/auto-fix-lint-format-commit.yml b/.github/workflows/auto-fix-lint-format-commit.yml index d8b4cb1dea..079727d061 100644 --- a/.github/workflows/auto-fix-lint-format-commit.yml +++ b/.github/workflows/auto-fix-lint-format-commit.yml @@ -7,9 +7,6 @@ on: jobs: auto-fix: runs-on: ubuntu-latest - permissions: - contents: write - pull-requests: write steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/apps/main/src/index.ts b/apps/main/src/index.ts index 037fdf658c..e806817e51 100644 --- a/apps/main/src/index.ts +++ b/apps/main/src/index.ts @@ -1,6 +1,5 @@ import { electronApp, optimizer } from "@electron-toolkit/utils" -import { APP_PROTOCOL, DEEPLINK_SCHEME } from "@follow/shared/constants" -import { extractElectronWindowOptions } from "@follow/shared/electron" +import { APP_PROTOCOL } from "@follow/shared/constants" import { env } from "@follow/shared/env" import { app, BrowserWindow, session } from "electron" import squirrelStartup from "electron-squirrel-startup" @@ -8,9 +7,10 @@ import squirrelStartup from "electron-squirrel-startup" import { isDev, isMacOS } from "./env" import { initializeAppStage0, initializeAppStage1 } from "./init" import { updateProxy } from "./lib/proxy" +import { handleUrlRouting } from "./lib/router" import { setAuthSessionToken } from "./lib/user" import { registerUpdater } from "./updater" -import { createMainWindow, createWindow } from "./window" +import { createMainWindow } from "./window" if (isDev) console.info("[main] env loaded:", env) @@ -138,17 +138,7 @@ function bootstrap() { mainWindow.reload() } } else { - const options = extractElectronWindowOptions(url) - - const { height, resizable = true, width } = options || {} - createWindow({ - extraPath: `#${url.replace(DEEPLINK_SCHEME, "/")}`, - width: width ?? 800, - height: height ?? 700, - minWidth: 600, - minHeight: 600, - resizable, - }) + handleUrlRouting(url) } } diff --git a/apps/main/src/lib/router.ts b/apps/main/src/lib/router.ts new file mode 100644 index 0000000000..8316cecfe5 --- /dev/null +++ b/apps/main/src/lib/router.ts @@ -0,0 +1,51 @@ +import { callWindowExpose } from "@follow/shared/bridge" +import { DEEPLINK_SCHEME } from "@follow/shared/constants" +import { extractElectronWindowOptions } from "@follow/shared/electron" + +import { logger } from "~/logger" +import { createMainWindow, createWindow, getMainWindow } from "~/window" + +export const handleUrlRouting = (url: string) => { + const options = extractElectronWindowOptions(url) + + const uri = url.replace(DEEPLINK_SCHEME, "/") + try { + const { pathname, searchParams } = new URL(uri, "https://follow.dev") + + switch (pathname) { + case "/add": { + const mainWindow = getMainWindow() + if (!mainWindow) { + createMainWindow() + + return handleUrlRouting(url) + } + mainWindow.restore() + mainWindow.focus() + const caller = callWindowExpose(mainWindow) + + const id = searchParams.get("id") + const isList = searchParams.get("type") === "list" + if (!id) return + caller.follow(id, { isList }) + return + } + default: { + break + } + } + + return + } catch (err) { + logger.error("routing error:", err) + } + const { height, resizable = true, width } = options || {} + createWindow({ + extraPath: `#${uri}`, + width: width ?? 800, + height: height ?? 700, + minWidth: 600, + minHeight: 600, + resizable, + }) +} diff --git a/apps/main/src/window.ts b/apps/main/src/window.ts index 3a4ffacf74..6a5ddfbcf0 100644 --- a/apps/main/src/window.ts +++ b/apps/main/src/window.ts @@ -220,7 +220,7 @@ export const createMainWindow = () => { } const caller = callWindowExpose(window) - caller.electronClose() + caller.onWindowClose() } else { windows.mainWindow = null } @@ -230,7 +230,7 @@ export const createMainWindow = () => { cancelPollingUpdateUnreadCount() const caller = callWindowExpose(window) - caller.electronShow() + caller.onWindowShow() }) window.on("hide", async () => { diff --git a/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx b/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx index 1b8282dc92..804789149c 100644 --- a/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx +++ b/apps/renderer/src/components/ui/markdown/renderers/BlockImage.tsx @@ -21,6 +21,7 @@ export const MarkdownBlockImage = ( "rounded", size.w < Number.parseInt(props.width as string) && "w-full", )} + showFallback popper className="inline-flex justify-center" /> diff --git a/apps/renderer/src/components/ui/media.tsx b/apps/renderer/src/components/ui/media.tsx index fb0ea76a49..e6c5891037 100644 --- a/apps/renderer/src/components/ui/media.tsx +++ b/apps/renderer/src/components/ui/media.tsx @@ -48,7 +48,7 @@ const MediaImpl: FC = ({ ...props }) => { const { src, style, type, previewImageUrl, showFallback, ...rest } = props - const [hidden, setHidden] = useState(!src) + const [imgSrc, setImgSrc] = useState(() => proxy && src && !failedList.has(src) ? getImageProxyUrl({ @@ -61,15 +61,17 @@ const MediaImpl: FC = ({ const [mediaLoadState, setMediaLoadState] = useState<"loading" | "loaded" | "error">("loading") const errorHandle: React.ReactEventHandler = useEventCallback((e) => { - setMediaLoadState("error") if (imgSrc !== props.src) { setImgSrc(props.src) failedList.add(props.src) } else { - setHidden(true) + setMediaLoadState("error") + props.onError?.(e as any) } }) + + const isError = mediaLoadState === "error" const previewMedia = usePreviewMedia() const handleClick = useEventCallback((e: React.MouseEvent) => { if (popper && src) { @@ -156,20 +158,30 @@ const MediaImpl: FC = ({ if (!type || !src) return null - if (hidden && (showFallback || (!showFallback && mediaLoadState === "error"))) { - return ( - - ) + if (isError) { + if (showFallback) { + return ( + + ) + } else { + return ( +
+ ) + } } + return (