Skip to content

Commit

Permalink
feat: self favicon in MLink
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Apr 18, 2024
1 parent 44f7151 commit 4aac9b8
Showing 1 changed file with 66 additions and 44 deletions.
110 changes: 66 additions & 44 deletions src/components/ui/link/MLink.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,80 @@
'use client'

import { memo, useCallback } from 'react'
import { memo, useCallback, useMemo } from 'react'
import { useRouter } from 'next/navigation'
import type { FC, ReactNode } from 'react'

import { isServerSide } from '~/lib/env'
import { useAppConfigSelector } from '~/providers/root/aggregation-data-provider'

import { FloatPopover } from '../float-popover'
import { Favicon } from '../rich-link/Favicon'

export const MLink: FC<{
href: string
title?: string
children?: ReactNode
text?: string
}> = memo(({ href, children, title, text }) => {
}> = memo(({ href, children, title }) => {
const router = useRouter()
const isSelfUrl = useMemo(() => {
if (isServerSide) return false
const locateUrl = new URL(location.href)

const toUrlParser = new URL(href)
return (
toUrlParser.host === locateUrl.host ||
(process.env.NODE_ENV === 'development' &&
toUrlParser.host === 'innei.in')
)
}, [href])

const handleRedirect = useCallback(
(e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
const locateUrl = new URL(location.href)

const toUrlParser = new URL(href)
if (!isSelfUrl) {
return
}
e.preventDefault()
const pathArr = toUrlParser.pathname.split('/').filter(Boolean)
const headPath = pathArr[0]

if (
toUrlParser.host === locateUrl.host ||
(process.env.NODE_ENV === 'development' &&
toUrlParser.host === 'innei.in')
) {
e.preventDefault()
const pathArr = toUrlParser.pathname.split('/').filter(Boolean)
const headPath = pathArr[0]

switch (headPath) {
case 'posts':
case 'notes':
case 'category': {
router.push(toUrlParser.pathname)
break
}
default: {
window.open(toUrlParser.pathname)
}
switch (headPath) {
case 'posts':
case 'notes':
case 'category': {
router.push(toUrlParser.pathname)
break
}
default: {
window.open(toUrlParser.pathname)
}
}
},
[href, router],
[href, isSelfUrl, router],
)

return (
<FloatPopover
as="span"
wrapperClassName="!inline"
type="tooltip"
TriggerComponent={useCallback(
() => (
<span className="inline items-center font-sans">
<Favicon href={href} />
<a
className="shiro-link--underline"
href={href}
target="_blank"
onClick={handleRedirect}
title={title}
rel="noreferrer"
>
{children}
</a>
triggerElement={
<span className="inline-flex items-center font-sans">
{isSelfUrl ? <BizSelfFavicon /> : <Favicon href={href} />}
<a
className="shiro-link--underline"
href={href}
target="_blank"
onClick={handleRedirect}
title={title}
rel="noreferrer"
>
{children}
</a>

<i className="icon-[mingcute--arrow-right-up-line] translate-y-[2px] opacity-70" />
</span>
),
[handleRedirect, children, href, title],
)}
<i className="icon-[mingcute--arrow-right-up-line] translate-y-[2px] opacity-70" />
</span>
}
>
<a href={href} target="_blank" rel="noreferrer">
<span>{href}</span>
Expand All @@ -78,3 +83,20 @@ export const MLink: FC<{
)
})
MLink.displayName = 'MLink'

const BizSelfFavicon = () => {
const { favicon, faviconDark } = useAppConfigSelector((a) => a.site) || {}
if (!favicon && !faviconDark) return null
return (
<span className="mr-1 inline-flex size-4 center">
<img
className="inline size-4 dark:hidden"
src={favicon ? favicon : faviconDark ? faviconDark : ''}
/>
<img
className="hidden size-4 dark:inline"
src={faviconDark ? faviconDark : favicon ? favicon : ''}
/>
</span>
)
}

0 comments on commit 4aac9b8

Please sign in to comment.