about summary refs log tree commit diff
path: root/src/view/com/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/util')
-rw-r--r--src/view/com/util/UserAvatar.tsx78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx
new file mode 100644
index 000000000..b38f1158c
--- /dev/null
+++ b/src/view/com/util/UserAvatar.tsx
@@ -0,0 +1,78 @@
+import React from 'react'
+import Svg, {Circle, Text, Defs, LinearGradient, Stop} from 'react-native-svg'
+import {colors} from '../../lib/styles'
+
+const GRADIENTS = [
+  [colors.pink3, colors.purple3],
+  [colors.purple3, colors.blue3],
+  [colors.blue3, colors.green3],
+  [colors.red3, colors.pink3],
+]
+
+export function UserAvatar({
+  size,
+  displayName,
+  name,
+}: {
+  size: number
+  displayName: string | undefined
+  name: string
+}) {
+  const initials = getInitials(displayName || name)
+  const gi = cyrb53(name) % GRADIENTS.length
+  return (
+    <Svg width={size} height={size} viewBox="0 0 100 100">
+      <Defs>
+        <LinearGradient id="grad" x1="0" y1="0" x2="1" y2="1">
+          <Stop offset="0" stopColor={GRADIENTS[gi][0]} stopOpacity="1" />
+          <Stop offset="1" stopColor={GRADIENTS[gi][1]} stopOpacity="1" />
+        </LinearGradient>
+      </Defs>
+      <Circle cx="50" cy="50" r="50" fill="url(#grad)" />
+      <Text
+        fill="white"
+        fontSize="50"
+        fontWeight="bold"
+        x="50"
+        y="67"
+        textAnchor="middle">
+        {initials}
+      </Text>
+    </Svg>
+  )
+}
+
+function getInitials(str: string): string {
+  const tokens = str
+    .split(' ')
+    .filter(Boolean)
+    .map(v => v.trim())
+  if (tokens.length >= 2 && tokens[0][0] && tokens[0][1]) {
+    return tokens[0][0].toUpperCase() + tokens[1][0].toUpperCase()
+  }
+  if (tokens.length === 1 && tokens[0][0]) {
+    return tokens[0][0].toUpperCase()
+  }
+  return 'X'
+}
+
+// deterministic string->hash
+// https://stackoverflow.com/a/52171480
+function cyrb53(str: string, seed = 0): number {
+  let h1 = 0xdeadbeef ^ seed,
+    h2 = 0x41c6ce57 ^ seed
+  for (let i = 0, ch; i < str.length; i++) {
+    ch = str.charCodeAt(i)
+    h1 = Math.imul(h1 ^ ch, 2654435761)
+    h2 = Math.imul(h2 ^ ch, 1597334677)
+  }
+
+  h1 =
+    Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
+    Math.imul(h2 ^ (h2 >>> 13), 3266489909)
+  h2 =
+    Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
+    Math.imul(h1 ^ (h1 >>> 13), 3266489909)
+
+  return 4294967296 * (2097151 & h2) + (h1 >>> 0)
+}