Skip to content

Commit

Permalink
fix: friend avatar image fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
Innei committed Oct 7, 2023
1 parent 15dc545 commit 00577cd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
4 changes: 3 additions & 1 deletion src/app/friends/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,14 @@ const Card: FC<{ link: LinkModel }> = ({ link }) => {
<AnimatePresence mode="wait">{enter && <LayoutBg />}</AnimatePresence>

<Avatar
randomColor
imageUrl={link.avatar}
lazy
radius={8}
text={link.name[0]}
alt={`Avatar of ${link.name}`}
size={64}
className="rounded-xl ring-2 ring-gray-400/30 dark:ring-slate-50"
className="ring-2 ring-gray-400/30 dark:ring-slate-50"
/>
<span className="flex h-full flex-col items-center justify-center space-y-2 py-3">
<span className="text-lg font-medium">{link.name}</span>
Expand Down
9 changes: 5 additions & 4 deletions src/app/says/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { useInfiniteQuery } from '@tanstack/react-query'
import { memo, useRef } from 'react'
import { memo, useMemo } from 'react'
import { m } from 'framer-motion'
import Markdown from 'markdown-to-jsx'
import type { SayModel } from '@mx-space/api-client'
Expand Down Expand Up @@ -110,9 +110,10 @@ const Item = memo<{
const hasSource = !!say.source
const hasAuthor = !!say.author
// const color = colorsMap.get(say.id)
const { dark: darkColors, light: lightColors } = useRef(
getColorScheme(stringToHue(say.id)),
).current
const { dark: darkColors, light: lightColors } = useMemo(
() => getColorScheme(stringToHue(say.id)),
[say.id],
)
const isDark = useIsDark()

return (
Expand Down
42 changes: 32 additions & 10 deletions src/components/ui/avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use client'

import React, { createElement, useRef, useState } from 'react'
import React, { createElement, useMemo, useRef, useState } from 'react'
import type { DetailedHTMLProps, FC, ImgHTMLAttributes } from 'react'

import { useIsDark } from '~/hooks/common/use-is-dark'
import { getColorScheme, stringToHue } from '~/lib/color'
import { clsxm } from '~/lib/helper'

import { FlexText } from '../text'
Expand All @@ -16,6 +18,8 @@ interface AvatarProps {

shadow?: boolean
text?: string
randomColor?: boolean
radius?: number

lazy?: boolean
}
Expand All @@ -32,13 +36,25 @@ export const Avatar: FC<
imageUrl,
text,
url,
randomColor,
radius,
...imageProps
} = props
const avatarRef = useRef<HTMLDivElement>(null)

const [loaded, setLoaded] = useState(!lazy)
const [loadError, setLoadError] = useState(false)

const { className, ...restProps } = wrapperProps
const colors = useMemo(
() =>
(text || imageUrl) &&
randomColor &&
(getColorScheme(stringToHue(text || imageUrl!)) as any),
[text, imageUrl, randomColor],
)
const isDark = useIsDark()
const bgColor = isDark ? colors?.dark.background : colors?.light.background

return (
<div
Expand All @@ -48,11 +64,13 @@ export const Avatar: FC<
className,
)}
ref={avatarRef}
style={
size
style={{
...(size
? { height: `${size || 80}px`, width: `${size || 80}px` }
: undefined
}
: undefined),
...(bgColor ? { backgroundColor: bgColor } : undefined),
...(radius ? { borderRadius: `${radius}px` } : undefined),
}}
{...restProps}
>
{createElement(
Expand All @@ -68,30 +86,34 @@ export const Avatar: FC<
}
: {}),
},
imageUrl ? (
imageUrl && !loadError ? (
<div
className={clsxm(
'h-full w-full bg-cover bg-center bg-no-repeat transition-opacity duration-300',
className,
)}
style={{ opacity: loaded ? 1 : 0 }}
>
<img
src={imageUrl}
style={{
...{ opacity: loaded ? 1 : 0 },
...(radius ? { borderRadius: `${radius}px` } : undefined),
}}
height={size}
width={size}
onLoad={() => setLoaded(true)}
onError={() => setLoadError(true)}
loading={lazy ? 'lazy' : 'eager'}
{...imageProps}
className={clsxm(
'aspect-square rounded-full',
'aspect-square rounded-full duration-200',
imageProps.className,
)}
/>
</div>
) : text ? (
<div className="relative flex h-full w-full flex-grow items-center justify-center">
<FlexText scale={0.8} text={text} />
<div className="relative flex h-full w-full flex-grow select-none items-center justify-center">
<FlexText scale={0.5} text={text} />
</div>
) : null,
)}
Expand Down
7 changes: 5 additions & 2 deletions src/components/ui/tag/Tag.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { memo } from 'react'
import { memo, useMemo } from 'react'

import { useIsDark } from '~/hooks/common/use-is-dark'
import { addAlphaToHSL, getColorScheme, stringToHue } from '~/lib/color'
Expand All @@ -12,7 +12,10 @@ export const Tag = memo(function Tag<T>(props: {
count?: number
}) {
const { text, count, passProps, onClick } = props
const { dark, light } = getColorScheme(stringToHue(text))
const { dark, light } = useMemo(
() => getColorScheme(stringToHue(text)),
[text],
)
const isDark = useIsDark()

const bgColor = isDark ? dark.background : light.background
Expand Down

1 comment on commit 00577cd

@vercel
Copy link

@vercel vercel bot commented on 00577cd Oct 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

shiro – ./

shiro-innei.vercel.app
shiro-git-main-innei.vercel.app
springtide.vercel.app
innei.in

Please sign in to comment.