Skip to content

Commit

Permalink
fix: image url replacement
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Aug 8, 2024
1 parent 8967d20 commit 8e75a8c
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 35 deletions.
15 changes: 4 additions & 11 deletions src/main/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fileURLToPath } from "node:url"

import { is } from "@electron-toolkit/utils"
import { callGlobalContextMethod } from "@shared/bridge"
import { imageRefererMatches } from "@shared/image"
import type { BrowserWindowConstructorOptions } from "electron"
import { BrowserWindow, Menu, shell } from "electron"

Expand Down Expand Up @@ -106,16 +107,6 @@ export function createWindow(
})
}

const refererMatchs = [
{
url: /^https:\/\/\w+\.sinaimg.cn/,
referer: "https://weibo.com",
},
{
url: /^https:\/\/i\.pximg\.net/,
referer: "https://www.pixiv.net",
},
]
window.webContents.session.webRequest.onBeforeSendHeaders(
(details, callback) => {
const trueUrl =
Expand All @@ -130,7 +121,9 @@ export function createWindow(
),
) :
details.url
const refererMatch = refererMatchs.find((item) => item.url.test(trueUrl))
const refererMatch = imageRefererMatches.find((item) =>
item.url.test(trueUrl),
)
callback({
requestHeaders: {
...details.requestHeaders,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { useWrappedElementSize } from "@renderer/providers/wrapped-element-provi
import { Media } from "../../media"

export const MarkdownBlockImage = (
props: React.ImgHTMLAttributes<HTMLImageElement>,
props: React.ImgHTMLAttributes<HTMLImageElement> & {
proxy?: {
width: number
height: number
}
},
) => {
const size = useWrappedElementSize()

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/components/ui/media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const MediaImpl: FC<MediaProps> = ({
}) => {
const { src, style, type, previewImageUrl, ...rest } = props
const [hidden, setHidden] = useState(!src)
const [imgSrc, setImgSrc] = useState(
const [imgSrc, setImgSrc] = useState(() =>
proxy && src && !failedList.has(src) ?
getProxyUrl({
url: src,
Expand Down
69 changes: 64 additions & 5 deletions src/renderer/src/components/ui/media/preview-media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import { m } from "@renderer/components/common/Motion"
import { COPY_MAP } from "@renderer/constants"
import { tipcClient } from "@renderer/lib/client"
import { stopPropagation } from "@renderer/lib/dom"
import { replaceImgUrlIfNeed } from "@renderer/lib/img-proxy"
import { showNativeMenu } from "@renderer/lib/native-menu"
import type { FC } from "react"
import { useCallback, useState } from "react"
import { Fragment, useCallback, useState } from "react"
import type { MediaModel } from "src/hono"
import { Keyboard, Mousewheel, Scrollbar } from "swiper/modules"
import { Swiper, SwiperSlide } from "swiper/react"

import { ActionButton } from "../button"
import { ActionButton, MotionButtonBase } from "../button"
import { microReboundPreset } from "../constants/spring"
import { useCurrentModal } from "../modal"

Expand Down Expand Up @@ -112,7 +113,7 @@ export const PreviewMediaContent: FC<{
onClick={(e) => e.stopPropagation()}
/>
) : (
<img
<FallbackableImage
className="size-full object-contain"
alt="cover"
src={src}
Expand Down Expand Up @@ -143,7 +144,11 @@ export const PreviewMediaContent: FC<{
className="size-full"
>
{media.map((med, index) => (
<SwiperSlide key={med.url} virtualIndex={index} className="center !flex">
<SwiperSlide
key={med.url}
virtualIndex={index}
className="center !flex"
>
{med.type === "video" ? (
<video
src={med.url}
Expand All @@ -152,7 +157,7 @@ export const PreviewMediaContent: FC<{
onClick={(e) => e.stopPropagation()}
/>
) : (
<img
<FallbackableImage
onContextMenu={(e) => handleContextMenu(med.url, e)}
className="size-full object-contain"
alt="cover"
Expand All @@ -166,3 +171,57 @@ export const PreviewMediaContent: FC<{
</Wrapper>
)
}

const FallbackableImage: FC<
Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src"> & {
src: string
}
> = ({ src, onError, ...props }) => {
const [currentSrc, setCurrentSrc] = useState(() => replaceImgUrlIfNeed(src))

const [isAllError, setIsAllError] = useState(false)

const handleError = useCallback(
(e) => {
if (currentSrc !== src) {
setCurrentSrc(src)
} else {
onError?.(e as any)
setIsAllError(true)
}
},
[currentSrc, onError, src],
)
return (
<Fragment>
{!isAllError && <img src={currentSrc} onError={handleError} {...props} />}
{isAllError && (
<div className="center flex-col gap-6">
<i className="i-mgc-close-cute-re text-[60px] text-red-500" />

<span>Failed to load image</span>
<div className="center gap-4">
<MotionButtonBase
className="underline underline-offset-4"
onClick={() => {
setCurrentSrc(replaceImgUrlIfNeed(src))
setIsAllError(false)
}}
>
Retry
</MotionButtonBase>
Or
<a
className="underline underline-offset-4"
href={src}
target="_blank"
rel="noreferrer"
>
Visit Original
</a>
</div>
</div>
)}
</Fragment>
)
}
15 changes: 14 additions & 1 deletion src/renderer/src/lib/img-proxy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { env } from "@env"
import { imageRefererMatches } from "@shared/image"

export const getProxyUrl = ({
url,
Expand All @@ -8,4 +9,16 @@ export const getProxyUrl = ({
url: string
width: number
height: number
}) => `${env.VITE_IMGPROXY_URL}/unsafe/${width}x${height}/${encodeURIComponent(url)}`
}) =>
`${env.VITE_IMGPROXY_URL}/unsafe/${width}x${height}/${encodeURIComponent(
url,
)}`

export const replaceImgUrlIfNeed = (url: string) => {
for (const rule of imageRefererMatches) {
if (rule.url.test(url)) {
return getProxyUrl({ url, width: 0, height: 0 })
}
}
return url
}
34 changes: 21 additions & 13 deletions src/renderer/src/lib/parse-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
MarkdownP,
} from "@renderer/components/ui/markdown/renderers"
import { Media } from "@renderer/components/ui/media"
import type { Components } from "hast-util-to-jsx-runtime"
import { toJsxRuntime } from "hast-util-to-jsx-runtime"
import { createElement } from "react"
import { Fragment, jsx, jsxs } from "react/jsx-runtime"
Expand Down Expand Up @@ -60,19 +61,7 @@ export const parseHtml = async (
components: {
a: ({ node, ...props }) =>
createElement(MarkdownLink, { ...props } as any),
img: ({ node, ...props }) => {
if (node?.properties.inline) {
return createElement(Media, {
type: "photo",
...props,
mediaContainerClassName: tw`max-w-full inline size-auto`,
popper: true,
className: tw`inline`,
})
}

return createElement(MarkdownBlockImage, props)
},
img: Img,
video: ({ node, ...props }) =>
createElement(Media, { ...props, popper: true, type: "video" }),
p: ({ node, ...props }) => {
Expand Down Expand Up @@ -142,3 +131,22 @@ export const parseHtml = async (
}),
}
}

const Img: Components["img"] = ({ node, ...props }) => {
const nextProps = {
...props,
proxy: { height: 0, width: 700 },
}
if (node?.properties.inline) {
return createElement(Media, {
type: "photo",
...nextProps,

mediaContainerClassName: tw`max-w-full inline size-auto`,
popper: true,
className: tw`inline`,
})
}

return createElement(MarkdownBlockImage, nextProps)
}
10 changes: 7 additions & 3 deletions src/renderer/src/modules/ai/ai-daily/daily.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ export const DailyItem = ({ view, day }: DailyItemProps) => {
return (
<Collapse
hideArrow
title={
<DailyReportTitle title={title} startDate={startDate} endDate={endDate} />
}
title={(
<DailyReportTitle
title={title}
startDate={startDate}
endDate={endDate}
/>
)}
className="mx-auto w-full max-w-lg border-b pb-6 last:border-b-0"
>
<DailyReportContent endDate={endDate} view={view} startDate={startDate} />
Expand Down
14 changes: 14 additions & 0 deletions src/shared/src/image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const imageRefererMatches = [
{
url: /^https:\/\/\w+\.sinaimg.cn/,
referer: "https://weibo.com",
},
{
url: /^https:\/\/i\.pximg\.net/,
referer: "https://www.pixiv.net",
},
{
url: /^https:\/\/cdnfile\.sspai\.com/,
referer: "https://sspai.com",
},
]

0 comments on commit 8e75a8c

Please sign in to comment.