feat: stop using smiley default avatar, use first letter of name on colored square as fallback

This commit is contained in:
Paul Bienkowski 2021-05-07 14:57:50 +02:00
parent 76620c5e8f
commit 34042ede54
9 changed files with 96 additions and 10 deletions

View file

@ -71,7 +71,7 @@ class User extends mongoose.Model {
email: this.email,
token: this.generateJWT(),
bio: this.bio,
image: this.image || 'https://static.productionready.io/images/smiley-cyrus.jpg',
image: this.image,
areTracksVisibleForAll: this.areTracksVisibleForAll,
apiKey: this._id,
};
@ -81,7 +81,7 @@ class User extends mongoose.Model {
return {
username: this.username,
bio: this.bio,
image: this.image || 'https://static.productionready.io/images/smiley-cyrus.jpg',
image: this.image,
};
}
}

View file

@ -1,8 +1,10 @@
html
head
base(href=baseUrl)
title block title
title
block title
| Authorization Server
| - OpenBikeSensor Account
link(rel="stylesheet", href="/semantic-ui/semantic.min.css")

View file

@ -16,7 +16,7 @@ import {
TracksPage,
UploadPage,
} from 'pages'
import {LoginButton} from 'components'
import {Avatar, LoginButton} from 'components'
const App = connect((state) => ({login: state.login}))(function App({login}) {
return (
@ -54,7 +54,7 @@ const App = connect((state) => ({login: state.login}))(function App({login}) {
<>
<li>
<Link to="/settings">
<Image src={login.image} avatar />
<Avatar user={login} />
</Link>
</li>
<li>

View file

@ -0,0 +1,38 @@
import React from 'react'
import {Comment} from 'semantic-ui-react'
import './styles.scss'
function hashCode(s) {
let hash = 0
for (let i = 0; i < s.length; i++) {
hash = (hash << 5) - hash + s.charCodeAt(i)
hash |= 0
}
return hash
}
function getColor(s) {
const h = Math.floor(hashCode(s)) % 360
return `hsl(${h}, 50%, 50%)`
}
export default function Avatar({user}) {
const {image, username} = user || {}
if (image) {
return <Comment.Avatar src={image} />
}
if (!username) {
return <div className="avatar empty-avatar" />
}
const color = getColor(username)
return (
<div className="avatar text-avatar" style={{background: color}}>
{username && <span>{username[0]}</span>}
</div>
)
}

View file

@ -0,0 +1,43 @@
.avatar.text-avatar {
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: -3px;
> span {
color: white;
font-size: 20pt;
text-transform: uppercase;
display: inline;
a:hover & {
text-decoration: none !important;
}
}
}
.avatar.empty-avatar {
background: #AAA;
}
.avatar.text-avatar,
.avatar.empty-avatar {
// border-radius: 0.25rem;
border-radius: 10%;
width: 2.5em;
height: 2.5em;
.ui.comments & {
display: inline-flex;
width: 2.5em;
height: 2.5em;
}
.tiny.image & {
width: 64px;
height: 64px;
}
}

View file

@ -1,3 +1,4 @@
export {default as Avatar} from './Avatar'
export {default as FileDrop} from './FileDrop'
export {default as FileUploadField} from './FileUploadField'
export {default as FormattedDate} from './FormattedDate'

View file

@ -2,7 +2,7 @@ import React from 'react'
import {Message, Segment, Form, Button, Loader, Header, Comment} from 'semantic-ui-react'
import Markdown from 'react-markdown'
import {FormattedDate} from 'components'
import {Avatar, FormattedDate} from 'components'
function CommentForm({onSubmit}) {
const [body, setBody] = React.useState('')
@ -32,7 +32,7 @@ export default function TrackComments({comments, onSubmit, onDelete, login, hide
{comments?.map((comment: TrackComment) => (
<Comment key={comment.id}>
<Comment.Avatar src={comment.author.image} />
<Avatar user={comment.author} />
<Comment.Content>
<Comment.Author as="a">{comment.author.username}</Comment.Author>
<Comment.Metadata>

View file

@ -8,7 +8,7 @@ import {map, switchMap, distinctUntilChanged} from 'rxjs/operators'
import _ from 'lodash'
import type {Track} from 'types'
import {Page, StripMarkdown} from 'components'
import {Avatar, Page, StripMarkdown} from 'components'
import api from 'api'
import {useQueryParam} from 'query'
@ -99,7 +99,9 @@ function maxLength(t, max) {
export function TrackListItem({track, privateTracks = false}) {
return (
<Item key={track.slug}>
<Item.Image size="tiny" src={track.author.image} />
<Item.Image size="tiny">
<Avatar user={track.author} />
</Item.Image>
<Item.Content>
<Item.Header as={Link} to={`/tracks/${track.slug}`}>
{track.title || 'Unnamed track'}

View file

@ -2,7 +2,7 @@ import type {FeatureCollection, Point} from 'geojson'
export type UserProfile = {
username: string
image: string
image?: string | null
bio?: string | null
}