From 29b0e23319d33613182f3ed4f33bc6fe0cbca7da Mon Sep 17 00:00:00 2001
From: Pavel Prichodko <14926950+prichodko@users.noreply.github.com>
Date: Mon, 13 Jun 2022 16:18:06 +0200
Subject: [PATCH] add support for identicon ring to avatar
---
.../status-react/src/system/avatar/avatar.tsx | 66 +++++++++----------
.../status-react/src/system/avatar/styles.tsx | 16 ++++-
.../status-react/src/system/avatar/utils.tsx | 60 +++++++++++++++++
3 files changed, 107 insertions(+), 35 deletions(-)
create mode 100644 packages/status-react/src/system/avatar/utils.tsx
diff --git a/packages/status-react/src/system/avatar/avatar.tsx b/packages/status-react/src/system/avatar/avatar.tsx
index 9994235..b1f6d6b 100644
--- a/packages/status-react/src/system/avatar/avatar.tsx
+++ b/packages/status-react/src/system/avatar/avatar.tsx
@@ -1,7 +1,8 @@
-import React from 'react'
+import React, { useMemo } from 'react'
import { Image } from '../image'
-import { Base, Indicator, Initials } from './styles'
+import { Base, Content, Indicator, Initials } from './styles'
+import { generateIdenticonRing } from './utils'
import type { Variants } from './styles'
@@ -11,46 +12,43 @@ interface Props {
indicator?: 'online' | 'offline'
src?: string
color?: string
+ colorHash?: number[][]
}
const Avatar = (props: Props) => {
- const { size, name, src, color, indicator } = props
+ const { size, name, src, color, indicator, colorHash } = props
- // const identicon = useMemo(() => {
- // const colors = colorWheel
- // .map((color, idx) => {
- // const prevDeg = idx === 0 ? '0deg' : `${colorWheel[idx - 1][1]}deg`
- // return `${color[0]} ${prevDeg} ${color[1]}deg`
- // })
- // .join(',')
- // return `conic-gradient(${colors})`
- // }, [colorWheel])
-
- // const intials = useMemo(() => {
- // if (contact && contact?.customName) {
- // return contact.customName.slice(0, 2)
- // }
- // if (contact && contact.trueName) {
- // return contact.trueName.slice(0, 2)
- // }
- // }, [contact])
+ const identiconRing = useMemo(() => {
+ if (colorHash) {
+ const gradient = generateIdenticonRing(colorHash)
+ return `conic-gradient(${gradient})`
+ }
+ }, [colorHash])
const initials = name ? name.slice(0, 1) : ''
return (
-
- {initials && {initials}}
- {src && (
-
- )}
- {indicator && }
+
+
+ {initials && {initials}}
+ {src && (
+
+ )}
+ {indicator && }
+
)
}
diff --git a/packages/status-react/src/system/avatar/styles.tsx b/packages/status-react/src/system/avatar/styles.tsx
index fd8d4ac..3761a43 100644
--- a/packages/status-react/src/system/avatar/styles.tsx
+++ b/packages/status-react/src/system/avatar/styles.tsx
@@ -6,7 +6,6 @@ export type Variants = VariantProps
export const Base = styled('div', {
position: 'relative',
- background: '$primary-1',
borderRadius: '100%',
flexShrink: 0,
@@ -15,39 +14,54 @@ export const Base = styled('div', {
20: {
width: 20,
height: 20,
+ padding: 1,
},
24: {
width: 24,
height: 24,
+ padding: 1,
},
32: {
width: 32,
height: 32,
+ padding: 2,
},
36: {
width: 36,
height: 36,
+ padding: 2,
},
44: {
width: 44,
height: 44,
+ padding: 2,
},
64: {
width: 64,
height: 64,
+ padding: 3,
},
80: {
width: 80,
height: 80,
+ padding: 4,
},
120: {
width: 120,
height: 120,
+ padding: 5,
},
},
},
})
+export const Content = styled('div', {
+ background: '$primary-1',
+ borderRadius: '100%',
+ width: '100%',
+ height: '100%',
+})
+
export const Indicator = styled('span', {
position: 'absolute',
right: -2,
diff --git a/packages/status-react/src/system/avatar/utils.tsx b/packages/status-react/src/system/avatar/utils.tsx
new file mode 100644
index 0000000..61984fb
--- /dev/null
+++ b/packages/status-react/src/system/avatar/utils.tsx
@@ -0,0 +1,60 @@
+/**
+ * returns value for conic-gradient
+ */
+export const generateIdenticonRing = (colorHash: number[][]) => {
+ const segments = colorHash.reduce((acc, segment) => (acc += segment[0]), 0)
+
+ let prevAngle = 0
+ const gradient = colorHash.reduce((acc, segment, index) => {
+ const [length, colorIndex] = segment
+ const color = COLORS[colorIndex]
+ const nextAngle = Math.round(prevAngle + (length * 360) / segments)
+
+ acc += `${color} ${prevAngle}deg ${nextAngle}deg`
+
+ if (index !== colorHash.length - 1) {
+ acc += `, `
+ }
+
+ prevAngle = nextAngle
+
+ return acc
+ }, '')
+
+ return gradient
+}
+
+const COLORS = [
+ '#000000',
+ '#726F6F',
+ '#C4C4C4',
+ '#E7E7E7',
+ '#FFFFFF',
+ '#00FF00',
+ '#009800',
+ '#B8FFBB',
+ '#FFC413',
+ '#9F5947',
+ '#FFFF00',
+ '#A8AC00',
+ '#FFFFB0',
+ '#FF5733',
+ '#FF0000',
+ '#9A0000',
+ '#FF9D9D',
+ '#FF0099',
+ '#C80078',
+ '#FF00FF',
+ '#900090',
+ '#FFB0FF',
+ '#9E00FF',
+ '#0000FF',
+ '#000086',
+ '#9B81FF',
+ '#3FAEF9',
+ '#9A6600',
+ '#00FFFF',
+ '#008694',
+ '#C2FFFF',
+ '#00F0B6',
+]