Skip to content

Commit

Permalink
fix: some styles
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Feb 18, 2024
1 parent 184f652 commit 9b53db0
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 54 deletions.
15 changes: 10 additions & 5 deletions src/atoms/hooks/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { useAtomValue } from 'jotai'
import { selectAtom } from 'jotai/utils'
import type { ExtractAtomValue } from 'jotai'

import { jotaiStore } from '~/lib/store'

import { viewportAtom } from '../viewport'

export const useViewport = <T>(
Expand All @@ -17,9 +19,12 @@ export const useViewport = <T>(

export const useIsMobile = () =>
useViewport(
useCallback(
(v: ExtractAtomValue<typeof viewportAtom>) =>
(v.sm || v.md || !v.sm) && !v.lg,
[],
),
useCallback((v: ExtractAtomValue<typeof viewportAtom>) => isMobile(v), []),
)

const isMobile = (v: ExtractAtomValue<typeof viewportAtom>) =>
(v.sm || v.md || !v.sm) && !v.lg
export const currentIsMobile = () => {
const v = jotaiStore.get(viewportAtom)
return isMobile(v)
}
1 change: 1 addition & 0 deletions src/components/layout/footer/GatewayInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const GatewayInfo = () => {
<FloatPopover
asChild
placement="top"
trigger="both"
offset={10}
triggerElement={
<span key={count} className="cursor-pointer">
Expand Down
122 changes: 87 additions & 35 deletions src/components/ui/image/ZoomedImage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
'use client'

import { forwardRef, useCallback, useMemo, useRef, useState } from 'react'
import { forwardRef, memo, useCallback, useMemo, useRef, useState } from 'react'
import clsx from 'clsx'
import { useIsomorphicLayoutEffect } from 'foxact/use-isomorphic-layout-effect'
import mediumZoom from 'medium-zoom'
import Image from 'next/image'
import { tv } from 'tailwind-variants'
import type { Zoom } from 'medium-zoom'
import type { FC, ReactNode } from 'react'
import type {
AnimationEventHandler,
DetailedHTMLProps,
FC,
ImgHTMLAttributes,
ReactNode,
} from 'react'

import { useIsMobile } from '~/atoms/hooks'
import { LazyLoad } from '~/components/common/Lazyload'
import { useIsUnMounted } from '~/hooks/common/use-is-unmounted'
import { isDev, isServerSide } from '~/lib/env'
Expand Down Expand Up @@ -67,7 +74,7 @@ export const ImageLazy: Component<TImageProps & BaseImageProps> = ({
const [zoomer_] = useState(() => {
if (isServerSide) return null!
if (zoomer) return zoomer
const zoom = mediumZoom(undefined)
const zoom = mediumZoom(undefined, {})
zoomer = zoom
return zoom
})
Expand All @@ -86,6 +93,7 @@ export const ImageLazy: Component<TImageProps & BaseImageProps> = ({
[isUnmount],
)
const imageRef = useRef<HTMLImageElement>(null)
const isMobile = useIsMobile()
useIsomorphicLayoutEffect(() => {
if (imageLoadStatus !== ImageLoadStatus.Loaded) {
return
Expand All @@ -95,15 +103,50 @@ export const ImageLazy: Component<TImageProps & BaseImageProps> = ({
}
const $image = imageRef.current

if (!$image) return
if (isMobile) {
$image.onclick = () => {
// NOTE: document 上的 click 可以用 stopImmediatePropagation 阻止
// e.stopImmediatePropagation()
window.open(src)
}
return () => {
$image.onclick = null
}
}

if ($image) {
zoomer_.attach($image)

return () => {
zoomer_.detach($image)
}
}
}, [zoom, zoomer_, imageLoadStatus])
}, [zoom, zoomer_, imageLoadStatus, isMobile])

const handleOnLoad = useCallback(() => {
setImageLoadStatusSafe(ImageLoadStatus.Loaded)
}, [setImageLoadStatusSafe])
const handleError = useCallback(
() => setImageLoadStatusSafe(ImageLoadStatus.Error),
[setImageLoadStatusSafe],
)
const handleOnAnimationEnd: AnimationEventHandler<HTMLImageElement> =
useCallback((e) => {
if (ImageLoadStatus.Loaded) {
;(e.target as HTMLElement).classList.remove(
imageStyles[ImageLoadStatus.Loaded],
)
}
}, [])
const imageClassName = useMemo(
() =>
styles({
status: imageLoadStatus,
className: clsx(imageStyles[ImageLoadStatus.Loaded], className),
}),
[className, imageLoadStatus],
)
return (
<figure>
<span className="relative flex justify-center" data-hide-print>
Expand All @@ -130,21 +173,10 @@ export const ImageLazy: Component<TImageProps & BaseImageProps> = ({
title={title}
alt={alt || title || ''}
ref={imageRef}
onLoad={() => {
setImageLoadStatusSafe(ImageLoadStatus.Loaded)
}}
onError={() => setImageLoadStatusSafe(ImageLoadStatus.Error)}
className={styles({
status: imageLoadStatus,
className: clsx(imageStyles[ImageLoadStatus.Loaded], className),
})}
onAnimationEnd={(e: Event) => {
if (ImageLoadStatus.Loaded) {
;(e.target as HTMLElement).classList.remove(
imageStyles[ImageLoadStatus.Loaded],
)
}
}}
onLoad={handleOnLoad}
onError={handleError}
className={imageClassName}
onAnimationEnd={handleOnAnimationEnd}
/>
</LazyLoad>
</span>
Expand Down Expand Up @@ -256,21 +288,41 @@ const NoFixedPlaceholder = ({ accent }: { accent?: string }) => {
)
}

const OptimizedImage: FC<any> = forwardRef(({ src, alt, ...rest }, ref) => {
const { height, width } = useMarkdownImageRecord(src!) || rest
if (!height || !width) return <img alt={alt} src={src} ref={ref} {...rest} />
return (
<Image
alt={alt || ''}
fetchPriority="high"
priority
src={src!}
{...rest}
height={+height}
width={+width}
ref={ref as any}
/>
)
})
const OptimizedImage = memo(
forwardRef<
HTMLImageElement,
DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>
>(({ src, alt, ...rest }, ref) => {
const { height, width } = useMarkdownImageRecord(src!) || rest
const hasDim = !!(height && width)

const ImageEl = (
<img data-zoom-src={src} alt={alt} src={src} ref={ref} {...rest} />
)
return (
<>
{hasDim ? (
<>
{/* @ts-expect-error */}
<Image
alt={alt || ''}
fetchPriority="high"
priority
src={src!}
{...rest}
height={+height}
width={+width}
/>
<div className="absolute inset-0 flex justify-center opacity-0">
{ImageEl}
</div>
</>
) : (
ImageEl
)}
</>
)
}),
)

OptimizedImage.displayName = 'OptimizedImage'
31 changes: 18 additions & 13 deletions src/components/ui/markdown/renderers/heading.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createElement, useId } from 'react'
import type { DOMAttributes } from 'react'

import { useIsClient } from '~/hooks/common/use-is-client'
import { springScrollToElement } from '~/lib/scroller'

interface HeadingProps {
Expand All @@ -15,6 +16,8 @@ export const MHeader = (props: HeadingProps) => {

const rid = useId()

const isClient = useIsClient()

const nextId = `${rid}${id}`
return createElement<DOMAttributes<HTMLHeadingElement>, HTMLHeadingElement>(
`h${level}`,
Expand All @@ -27,19 +30,21 @@ export const MHeader = (props: HeadingProps) => {
null,
<>
<span>{children}</span>
<span
className="ml-2 inline-flex cursor-pointer select-none text-accent opacity-0 transition-opacity duration-200 center group-hover:opacity-100"
role="button"
tabIndex={0}
aria-hidden
onClick={() => {
const state = history.state
history.replaceState(state, '', `#${nextId}`)
springScrollToElement(document.getElementById(nextId)!, -100)
}}
>
<i className="icon-[mingcute--hashtag-line]" />
</span>
{isClient && (
<span
className="ml-2 inline-flex cursor-pointer select-none text-accent opacity-0 transition-opacity duration-200 center group-hover:opacity-100"
role="button"
tabIndex={0}
aria-hidden
onClick={() => {
const state = history.state
history.replaceState(state, '', `#${nextId}`)
springScrollToElement(document.getElementById(nextId)!, -100)
}}
>
<i className="icon-[mingcute--hashtag-line]" />
</span>
)}
</>,
)
}
2 changes: 1 addition & 1 deletion src/components/ui/rich-link/Favicon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const Favicon: Component<FaviconProps> = (props) => {
return (
<span
className={clsxm(
'mr-1 inline-flex [&_svg]:inline [&_svg]:!h-[0.8rem]',
'mr-1 inline-flex [&_svg]:inline [&_svg]:!h-[0.8em]',
className,
)}
>
Expand Down

0 comments on commit 9b53db0

Please sign in to comment.