1
1
'use client'
2
2
3
- import { memo , useCallback } from 'react'
3
+ import { memo , useCallback , useMemo } from 'react'
4
4
import { useRouter } from 'next/navigation'
5
5
import type { FC , ReactNode } from 'react'
6
6
7
+ import { isServerSide } from '~/lib/env'
8
+ import { useAppConfigSelector } from '~/providers/root/aggregation-data-provider'
9
+
7
10
import { FloatPopover } from '../float-popover'
8
11
import { Favicon } from '../rich-link/Favicon'
9
12
10
13
export const MLink : FC < {
11
14
href : string
12
15
title ?: string
13
16
children ?: ReactNode
14
- text ?: string
15
- } > = memo ( ( { href, children, title, text } ) => {
17
+ } > = memo ( ( { href, children, title } ) => {
16
18
const router = useRouter ( )
19
+ const isSelfUrl = useMemo ( ( ) => {
20
+ if ( isServerSide ) return false
21
+ const locateUrl = new URL ( location . href )
22
+
23
+ const toUrlParser = new URL ( href )
24
+ return (
25
+ toUrlParser . host === locateUrl . host ||
26
+ ( process . env . NODE_ENV === 'development' &&
27
+ toUrlParser . host === 'innei.in' )
28
+ )
29
+ } , [ href ] )
30
+
17
31
const handleRedirect = useCallback (
18
32
( e : React . MouseEvent < HTMLAnchorElement , MouseEvent > ) => {
19
- const locateUrl = new URL ( location . href )
20
-
21
33
const toUrlParser = new URL ( href )
34
+ if ( ! isSelfUrl ) {
35
+ return
36
+ }
37
+ e . preventDefault ( )
38
+ const pathArr = toUrlParser . pathname . split ( '/' ) . filter ( Boolean )
39
+ const headPath = pathArr [ 0 ]
22
40
23
- if (
24
- toUrlParser . host === locateUrl . host ||
25
- ( process . env . NODE_ENV === 'development' &&
26
- toUrlParser . host === 'innei.in' )
27
- ) {
28
- e . preventDefault ( )
29
- const pathArr = toUrlParser . pathname . split ( '/' ) . filter ( Boolean )
30
- const headPath = pathArr [ 0 ]
31
-
32
- switch ( headPath ) {
33
- case 'posts' :
34
- case 'notes' :
35
- case 'category' : {
36
- router . push ( toUrlParser . pathname )
37
- break
38
- }
39
- default : {
40
- window . open ( toUrlParser . pathname )
41
- }
41
+ switch ( headPath ) {
42
+ case 'posts' :
43
+ case 'notes' :
44
+ case 'category' : {
45
+ router . push ( toUrlParser . pathname )
46
+ break
47
+ }
48
+ default : {
49
+ window . open ( toUrlParser . pathname )
42
50
}
43
51
}
44
52
} ,
45
- [ href , router ] ,
53
+ [ href , isSelfUrl , router ] ,
46
54
)
47
55
48
56
return (
49
57
< FloatPopover
50
58
as = "span"
51
59
wrapperClassName = "!inline"
52
60
type = "tooltip"
53
- TriggerComponent = { useCallback (
54
- ( ) => (
55
- < span className = "inline items-center font-sans" >
56
- < Favicon href = { href } />
57
- < a
58
- className = "shiro-link--underline"
59
- href = { href }
60
- target = "_blank"
61
- onClick = { handleRedirect }
62
- title = { title }
63
- rel = "noreferrer"
64
- >
65
- { children }
66
- </ a >
61
+ triggerElement = {
62
+ < span className = "inline-flex items-center font-sans" >
63
+ { isSelfUrl ? < BizSelfFavicon /> : < Favicon href = { href } /> }
64
+ < a
65
+ className = "shiro-link--underline"
66
+ href = { href }
67
+ target = "_blank"
68
+ onClick = { handleRedirect }
69
+ title = { title }
70
+ rel = "noreferrer"
71
+ >
72
+ { children }
73
+ </ a >
67
74
68
- < i className = "icon-[mingcute--arrow-right-up-line] translate-y-[2px] opacity-70" />
69
- </ span >
70
- ) ,
71
- [ handleRedirect , children , href , title ] ,
72
- ) }
75
+ < i className = "icon-[mingcute--arrow-right-up-line] translate-y-[2px] opacity-70" />
76
+ </ span >
77
+ }
73
78
>
74
79
< a href = { href } target = "_blank" rel = "noreferrer" >
75
80
< span > { href } </ span >
@@ -78,3 +83,20 @@ export const MLink: FC<{
78
83
)
79
84
} )
80
85
MLink . displayName = 'MLink'
86
+
87
+ const BizSelfFavicon = ( ) => {
88
+ const { favicon, faviconDark } = useAppConfigSelector ( ( a ) => a . site ) || { }
89
+ if ( ! favicon && ! faviconDark ) return null
90
+ return (
91
+ < span className = "mr-1 inline-flex size-4 center" >
92
+ < img
93
+ className = "inline size-4 dark:hidden"
94
+ src = { favicon ? favicon : faviconDark ? faviconDark : '' }
95
+ />
96
+ < img
97
+ className = "hidden size-4 dark:inline"
98
+ src = { faviconDark ? faviconDark : favicon ? favicon : '' }
99
+ />
100
+ </ span >
101
+ )
102
+ }
0 commit comments