Merge pull request #100 from utopia-os/add-avatar-placeholder

feat(source): add avatar placeholder
This commit is contained in:
antontranelis 2025-02-04 20:00:02 +00:00 committed by GitHub
commit 061116151a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 5 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "utopia-ui", "name": "utopia-ui",
"version": "3.0.39", "version": "3.0.40",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "utopia-ui", "name": "utopia-ui",
"version": "3.0.39", "version": "3.0.40",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"dependencies": { "dependencies": {
"@heroicons/react": "^2.0.17", "@heroicons/react": "^2.0.17",

View File

@ -1,6 +1,6 @@
{ {
"name": "utopia-ui", "name": "utopia-ui",
"version": "3.0.39", "version": "3.0.40",
"description": "Reuseable React Components to build mapping apps for real life communities and networks", "description": "Reuseable React Components to build mapping apps for real life communities and networks",
"repository": "https://github.com/utopia-os/utopia-ui", "repository": "https://github.com/utopia-os/utopia-ui",
"homepage:": "https://utopia-os.org/", "homepage:": "https://utopia-os.org/",

View File

@ -9,7 +9,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { useState } from 'react' import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useAppState } from '#components/AppShell/hooks/useAppState' import { useAppState } from '#components/AppShell/hooks/useAppState'
@ -57,6 +57,12 @@ export function HeaderView({
const navigate = useNavigate() const navigate = useNavigate()
const appState = useAppState() const appState = useAppState()
const [imageLoaded, setImageLoaded] = useState(false)
useEffect(() => {
setImageLoaded(false)
}, [item])
const avatar = const avatar =
itemAvatarField && getValue(item, itemAvatarField) itemAvatarField && getValue(item, itemAvatarField)
? appState.assetsApi.url + ? appState.assetsApi.url +
@ -92,13 +98,21 @@ export function HeaderView({
{avatar && ( {avatar && (
<div className='tw-avatar'> <div className='tw-avatar'>
<div <div
className={`${big ? 'tw-w-20' : 'tw-w-10'} tw-inline tw-items-center tw-justify-center overflow-hidden`} className={`${
big ? 'tw-w-20' : 'tw-w-10'
} tw-inline tw-items-center tw-justify-center overflow-hidden`}
> >
<img <img
className={'tw-w-full tw-h-full tw-object-cover tw-rounded-full'} className={'tw-w-full tw-h-full tw-object-cover tw-rounded-full'}
src={avatar} src={avatar}
alt={item.name + ' logo'} alt={item.name + ' logo'}
onLoad={() => setImageLoaded(true)}
onError={() => setImageLoaded(false)}
style={{ display: imageLoaded ? 'block' : 'none' }}
/> />
{!imageLoaded && (
<div className='tw-w-full tw-h-full tw-bg-gray-200 tw-rounded-full' />
)}
</div> </div>
</div> </div>
)} )}