Skip to content

Commit 9dc5536

Browse files
committed
feat: add wikipedia icon
1 parent 1de4915 commit 9dc5536

File tree

6 files changed

+129
-99
lines changed

6 files changed

+129
-99
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { SVGProps } from 'react'
2+
3+
export function WikipediaIcon(props: SVGProps<SVGSVGElement>) {
4+
return (
5+
<svg
6+
xmlns="http://www.w3.org/2000/svg"
7+
width="1em"
8+
height="1em"
9+
viewBox="0 0 24 24"
10+
{...props}
11+
>
12+
<path
13+
fill="currentColor"
14+
d="m14.97 18.95l-2.56-6.03c-1.02 1.99-2.14 4.08-3.1 6.03c-.01.01-.47 0-.47 0C7.37 15.5 5.85 12.1 4.37 8.68C4.03 7.84 2.83 6.5 2 6.5v-.45h5.06v.45c-.6 0-1.62.4-1.36 1.05c.72 1.54 3.24 7.51 3.93 9.03c.47-.94 1.8-3.42 2.37-4.47c-.45-.88-1.87-4.18-2.29-5c-.32-.54-1.13-.61-1.75-.61c0-.15.01-.25 0-.44l4.46.01v.4c-.61.03-1.18.24-.92.82c.6 1.24.95 2.13 1.5 3.28c.17-.34 1.07-2.19 1.5-3.16c.26-.65-.13-.91-1.21-.91c.01-.12.01-.33.01-.43c1.39-.01 3.48-.01 3.85-.02v.42c-.71.03-1.44.41-1.82.99L13.5 11.3c.18.51 1.96 4.46 2.15 4.9l3.85-8.83c-.3-.72-1.16-.87-1.5-.87v-.45l4 .03v.42c-.88 0-1.43.5-1.75 1.25c-.8 1.79-3.25 7.49-4.85 11.2h-.43Z"
15+
/>
16+
</svg>
17+
)
18+
}

src/components/ui/link/MLink.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export const MLink: FC<{
7575
case isZhihuProfileUrl(url): {
7676
parsedType = 'ZH'
7777
parsedName = parseZhihuProfileUrl(url).id
78+
break
7879
}
7980
}
8081
} catch {

src/components/ui/markdown/renderers/LinkRenderer.tsx

+96-97
Original file line numberDiff line numberDiff line change
@@ -33,111 +33,110 @@ export const LinkRenderer = ({ href }: { href: string }) => {
3333
}
3434
}, [href])
3535

36-
if (url) {
37-
switch (true) {
38-
case isTweetUrl(url): {
39-
const id = getTweetId(url)
36+
if (!url) {
37+
return (
38+
<p>
39+
<MLink href={href}>
40+
<span>{href}</span>
41+
</MLink>
42+
</p>
43+
)
44+
}
45+
switch (true) {
46+
case isTweetUrl(url): {
47+
const id = getTweetId(url)
4048

41-
return <Tweet id={id} />
42-
}
49+
return <Tweet id={id} />
50+
}
4351

44-
case isGithubRepoUrl(url): {
45-
const { owner, repo } = parseGithubRepoUrl(url)
46-
return <LinkCard id={`${owner}/${repo}`} source="gh" />
47-
}
52+
case isGithubRepoUrl(url): {
53+
const { owner, repo } = parseGithubRepoUrl(url)
54+
return <LinkCard id={`${owner}/${repo}`} source="gh" />
55+
}
4856

49-
case isYoutubeUrl(url): {
50-
const id = url.searchParams.get('v')!
51-
return (
52-
<FixedRatioContainer>
53-
<iframe
54-
src={`https://www.youtube.com/embed/${id}`}
55-
className="absolute inset-0 h-full w-full border-0"
56-
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
57-
allowFullScreen
58-
title="YouTube video player"
59-
/>
60-
</FixedRatioContainer>
61-
)
62-
}
63-
case isGistUrl(url): {
64-
const { owner, id } = parseGithubGistUrl(url)
65-
return (
66-
<>
67-
<iframe
68-
src={`https://gist.github.com/${owner}/${id}.pibb`}
69-
className="h-[300px] w-full overflow-auto border-0"
70-
/>
57+
case isYoutubeUrl(url): {
58+
const id = url.searchParams.get('v')!
59+
return (
60+
<FixedRatioContainer>
61+
<iframe
62+
src={`https://www.youtube.com/embed/${id}`}
63+
className="absolute inset-0 h-full w-full border-0"
64+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
65+
allowFullScreen
66+
title="YouTube video player"
67+
/>
68+
</FixedRatioContainer>
69+
)
70+
}
71+
case isGistUrl(url): {
72+
const { owner, id } = parseGithubGistUrl(url)
73+
return (
74+
<>
75+
<iframe
76+
src={`https://gist.github.com/${owner}/${id}.pibb`}
77+
className="h-[300px] w-full overflow-auto border-0"
78+
/>
7179

72-
<a
73-
className="mt-2 flex space-x-2 center"
74-
href={href}
75-
target="_blank"
76-
rel="noreferrer"
77-
>
78-
<GitHubBrandIcon />
79-
<span>{href}</span>
80-
</a>
81-
</>
82-
)
83-
}
80+
<a
81+
className="mt-2 flex space-x-2 center"
82+
href={href}
83+
target="_blank"
84+
rel="noreferrer"
85+
>
86+
<GitHubBrandIcon />
87+
<span>{href}</span>
88+
</a>
89+
</>
90+
)
91+
}
8492

85-
case isGithubCommitUrl(url): {
86-
const { owner, repo, id } = parseGithubTypedUrl(url)
87-
return (
88-
<>
89-
<p>
90-
<MLink href={href}>{href}</MLink>
91-
</p>
92-
<LinkCard id={`${owner}/${repo}/commit/${id}`} source="gh-commit" />
93-
</>
94-
)
95-
}
96-
case isGithubFilePreviewUrl(url): {
97-
const { owner, repo, afterTypeString } = parseGithubTypedUrl(url)
98-
const splitString = afterTypeString.split('/')
99-
const ref = splitString[0]
100-
const path = ref ? splitString.slice(1).join('/') : afterTypeString
101-
return (
102-
<>
93+
case isGithubCommitUrl(url): {
94+
const { owner, repo, id } = parseGithubTypedUrl(url)
95+
return (
96+
<>
97+
<p>
10398
<MLink href={href}>{href}</MLink>
104-
<EmbedGithubFile
105-
owner={owner}
106-
repo={repo}
107-
path={path}
108-
refType={ref}
109-
/>
110-
</>
111-
)
112-
}
113-
case isCodesandboxUrl(url): {
114-
// https://codesandbox.io/s/framer-motion-layoutroot-prop-forked-p39g96
115-
// to
116-
// https://codesandbox.io/embed/framer-motion-layoutroot-prop-forked-p39g96?fontsize=14&hidenavigation=1&theme=dark
117-
return (
118-
<FixedRatioContainer>
119-
<iframe
120-
className="absolute inset-0 h-full w-full rounded-md border-0"
121-
src={`https://codesandbox.io/embed/${url.pathname.slice(
122-
2,
123-
)}?fontsize=14&hidenavigation=1&theme=dark${url.search}`}
124-
/>
125-
</FixedRatioContainer>
126-
)
127-
}
128-
case isSelfArticleUrl(url): {
129-
return <LinkCard source="self" id={url.pathname.slice(1)} />
130-
}
99+
</p>
100+
<LinkCard id={`${owner}/${repo}/commit/${id}`} source="gh-commit" />
101+
</>
102+
)
103+
}
104+
case isGithubFilePreviewUrl(url): {
105+
const { owner, repo, afterTypeString } = parseGithubTypedUrl(url)
106+
const splitString = afterTypeString.split('/')
107+
const ref = splitString[0]
108+
const path = ref ? splitString.slice(1).join('/') : afterTypeString
109+
return (
110+
<>
111+
<MLink href={href}>{href}</MLink>
112+
<EmbedGithubFile
113+
owner={owner}
114+
repo={repo}
115+
path={path}
116+
refType={ref}
117+
/>
118+
</>
119+
)
120+
}
121+
case isCodesandboxUrl(url): {
122+
// https://codesandbox.io/s/framer-motion-layoutroot-prop-forked-p39g96
123+
// to
124+
// https://codesandbox.io/embed/framer-motion-layoutroot-prop-forked-p39g96?fontsize=14&hidenavigation=1&theme=dark
125+
return (
126+
<FixedRatioContainer>
127+
<iframe
128+
className="absolute inset-0 h-full w-full rounded-md border-0"
129+
src={`https://codesandbox.io/embed/${url.pathname.slice(
130+
2,
131+
)}?fontsize=14&hidenavigation=1&theme=dark${url.search}`}
132+
/>
133+
</FixedRatioContainer>
134+
)
135+
}
136+
case isSelfArticleUrl(url): {
137+
return <LinkCard source="self" id={url.pathname.slice(1)} />
131138
}
132139
}
133-
// fallback to default renderer
134-
return (
135-
<p>
136-
<MLink href={href}>
137-
<span>{href}</span>
138-
</MLink>
139-
</p>
140-
)
141140
}
142141

143142
const FixedRatioContainer = ({

src/components/ui/rich-link/Favicon.tsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { BilibiliIcon } from '~/components/icons/platform/BilibiliIcon'
22
import { GitHubBrandIcon } from '~/components/icons/platform/GitHubBrandIcon'
33
import { IcBaselineTelegram } from '~/components/icons/platform/Telegram'
44
import { TwitterIcon } from '~/components/icons/platform/Twitter'
5+
import { WikipediaIcon } from '~/components/icons/platform/WikipediaIcon'
56
import { SimpleIconsZhihu } from '~/components/icons/platform/ZhihuIcon'
67
import { clsxm } from '~/lib/helper'
78
import {
89
isBilibiliUrl,
910
isGithubUrl,
1011
isTelegramUrl,
1112
isTwitterUrl,
13+
isWikipediaUrl,
1214
isZhihuUrl,
1315
} from '~/lib/link-parser'
1416

@@ -18,7 +20,8 @@ const prefixToIconMap = {
1820
TG: <IcBaselineTelegram className="text-[#2AABEE]" />,
1921
BL: <BilibiliIcon className="text-[#469ECF]" />,
2022
ZH: <SimpleIconsZhihu className="text-[#0084FF]" />,
21-
} as any
23+
WI: <WikipediaIcon className="text-current" />,
24+
}
2225

2326
const getUrlSource = (url: URL) => {
2427
const map = [
@@ -42,6 +45,10 @@ const getUrlSource = (url: URL) => {
4245
type: 'ZH',
4346
test: isZhihuUrl,
4447
},
48+
{
49+
type: 'WI',
50+
test: isWikipediaUrl,
51+
},
4552
]
4653

4754
return map.find((item) => item.test(url))?.type
@@ -57,7 +64,7 @@ type FaviconProps =
5764
export const Favicon: Component<FaviconProps> = (props) => {
5865
// @ts-expect-error
5966
const { source, href, className } = props
60-
let nextSource = source
67+
let nextSource = source as keyof typeof prefixToIconMap
6168

6269
try {
6370
if (href) {

src/components/ui/rich-link/RichLink.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const prefixToUrlMap = {
77
TW: 'https://twitter.com/',
88
TG: 'https://t.me/',
99
ZH: 'https://www.zhihu.com/people/',
10+
WI: 'https://zh.wikipedia.org/wiki/',
1011
}
1112

1213
export const RichLink: FC<{

src/lib/link-parser.ts

+4
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ export const isZhihuProfileUrl = (url: URL) => {
8383
return isZhihuUrl(url) && url.pathname.startsWith('/people/')
8484
}
8585

86+
export const isWikipediaUrl = (url: URL) => {
87+
return url.hostname.includes('wikipedia.org')
88+
}
89+
8690
export const parseSelfArticleUrl = (url: URL) => {
8791
const [_, type, ...rest] = url.pathname.split('/')
8892
switch (type) {

0 commit comments

Comments
 (0)