From 3262ea02854102b14771ad9e192436f406c61d6d Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Thu, 1 Aug 2024 22:53:17 -0700 Subject: [PATCH] Updated avatar colors and events table. --- .../[websiteId]/events/EventsTable.tsx | 19 +++-- .../[websiteId]/sessions/SessionsTable.tsx | 4 +- .../[sessionId]/SessionDetailsPage.tsx | 4 +- src/components/common/Avatar.tsx | 80 ++++--------------- src/components/common/Profile.tsx | 41 ---------- src/lib/colors.ts | 45 +++++++++++ 6 files changed, 77 insertions(+), 116 deletions(-) delete mode 100644 src/components/common/Profile.tsx create mode 100644 src/lib/colors.ts diff --git a/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx b/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx index 5a625ee9..c34ac89b 100644 --- a/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/events/EventsTable.tsx @@ -2,7 +2,7 @@ import { GridTable, GridColumn } from 'react-basics'; import { useLocale, useMessages } from 'components/hooks'; import Empty from 'components/common/Empty'; import { formatDistance } from 'date-fns'; -import Profile from 'components/common/Profile'; +import Avatar from 'components/common/Avatar'; import Link from 'next/link'; export function EventsTable({ data = [] }) { @@ -15,18 +15,23 @@ export function EventsTable({ data = [] }) { return ( - - + {row => ( - + )} - - {row => formatMessage(row.eventName ? labels.triggeredEvent : labels.viewedPage)} + + {row => { + return ( + <> + {formatMessage(row.eventName ? labels.triggeredEvent : labels.viewedPage)} + {row.eventName} + + ); + }} - {row => diff --git a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx index 73148b83..9dd6a56d 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/SessionsTable.tsx @@ -1,7 +1,7 @@ import Link from 'next/link'; import { GridColumn, GridTable, useBreakpoint } from 'react-basics'; import { useFormat, useLocale, useMessages } from 'components/hooks'; -import Profile from 'components/common/Profile'; +import Avatar from 'components/common/Avatar'; import styles from './SessionsTable.module.css'; import { formatDate } from 'lib/date'; @@ -16,7 +16,7 @@ export function SessionsTable({ data = [] }: { data: any[]; showDomain?: boolean {row => ( - + {row.id} )} diff --git a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx index d4ed503e..059e041f 100644 --- a/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx +++ b/src/app/(main)/websites/[websiteId]/sessions/[sessionId]/SessionDetailsPage.tsx @@ -3,7 +3,7 @@ import WebsiteHeader from '../../WebsiteHeader'; import SessionInfo from './SessionInfo'; import { useWebsiteSession } from 'components/hooks'; import { Loading } from 'react-basics'; -import Profile from 'components/common/Profile'; +import Avatar from 'components/common/Avatar'; import { SessionActivity } from './SessionActivity'; import { SessionStats } from './SessionStats'; import { SessionData } from './SessionData'; @@ -27,7 +27,7 @@ export default function SessionDetailsPage({
- +
diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index b947704b..2e82b078 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -1,71 +1,23 @@ -import md5 from 'md5'; -import { colord, extend } from 'colord'; -import harmoniesPlugin from 'colord/plugins/harmonies'; -import mixPlugin from 'colord/plugins/mix'; +import { useMemo } from 'react'; +import { createAvatar } from '@dicebear/core'; +import { lorelei } from '@dicebear/collection'; +import { getColor, getPastel } from 'lib/colors'; -extend([harmoniesPlugin, mixPlugin]); +const lib = lorelei; -const harmonies = [ - //'analogous', - //'complementary', - 'double-split-complementary', - //'rectangle', - 'split-complementary', - 'tetradic', - //'triadic', -]; +function Avatar({ seed, size = 128, ...props }: { seed: string; size?: number }) { + const backgroundColor = getPastel(getColor(seed), 4); -const color = (value: string, invert: boolean = false) => { - const c = colord(value.startsWith('#') ? value : `#${value}`); + const avatar = useMemo(() => { + return createAvatar(lib, { + ...props, + seed, + size, + backgroundColor: [backgroundColor], + }).toDataUri(); + }, []); - if (invert && c.isDark()) { - return c.invert(); - } - - return c; -}; - -const remix = (hash: string) => { - const a = hash.substring(0, 6); - const b = hash.substring(6, 12); - const c = hash.substring(12, 18); - const d = hash.substring(18, 24); - const e = hash.substring(24, 30); - const f = hash.substring(30, 32); - - const base = [b, c, d, e] - .reduce((acc, val) => { - return acc.mix(color(val), 0.05); - }, color(a)) - .saturate(0.1) - .toHex(); - - const harmony = pick(parseInt(f, 16), harmonies); - - return color(base, true) - .harmonies(harmony) - .map(c => c.toHex()); -}; - -const pick = (num: number, arr: any[]) => { - return arr[num % arr.length]; -}; - -export function Avatar({ value }: { value: string }) { - const hash = md5(value); - const colors = remix(hash); - - return ( - - - - - - - - - - ); + return Avatar; } export default Avatar; diff --git a/src/components/common/Profile.tsx b/src/components/common/Profile.tsx deleted file mode 100644 index 40544994..00000000 --- a/src/components/common/Profile.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { useMemo } from 'react'; -import { createAvatar } from '@dicebear/core'; -import { lorelei } from '@dicebear/collection'; -import md5 from 'md5'; - -const lib = lorelei; - -function convertToPastel(hexColor: string, pastelFactor: number = 0.5) { - // Remove the # if present - hexColor = hexColor.replace(/^#/, ''); - - // Convert hex to RGB - let r = parseInt(hexColor.substring(0, 2), 16); - let g = parseInt(hexColor.substring(2, 4), 16); - let b = parseInt(hexColor.substring(4, 6), 16); - - // Calculate pastel version (mix with white) - //const pastelFactor = 0.5; // Adjust this value to control pastel intensity - - r = Math.floor((r + 255 * pastelFactor) / (1 + pastelFactor)); - g = Math.floor((g + 255 * pastelFactor) / (1 + pastelFactor)); - b = Math.floor((b + 255 * pastelFactor) / (1 + pastelFactor)); - - // Convert back to hex - return `#${((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)}`; -} - -function Profile({ seed, size = 128, ...props }: { seed: string; size?: number }) { - const avatar = useMemo(() => { - return createAvatar(lib, { - ...props, - seed, - size, - backgroundColor: [convertToPastel(md5(seed).substring(0, 6), 2).replace(/^#/, '')], - }).toDataUri(); - }, []); - - return Avatar; -} - -export default Profile; diff --git a/src/lib/colors.ts b/src/lib/colors.ts new file mode 100644 index 00000000..ba329805 --- /dev/null +++ b/src/lib/colors.ts @@ -0,0 +1,45 @@ +import md5 from 'md5'; + +export const pick = (num: number, arr: any[]) => { + return arr[num % arr.length]; +}; + +export function clamp(num: number, min: number, max: number) { + return num < min ? min : num > max ? max : num; +} + +export function hex2RGB(color: string, min: number = 0, max: number = 255) { + const c = color.replace(/^#/, ''); + const diff = max - min; + + const normalize = (num: number) => { + return Math.floor((num / 255) * diff + min); + }; + + const r = normalize(parseInt(c.substring(0, 2), 16)); + const g = normalize(parseInt(c.substring(2, 4), 16)); + const b = normalize(parseInt(c.substring(4, 6), 16)); + + return { r, g, b }; +} + +export function rgb2Hex(r: number, g: number, b: number, prefix = '') { + return `${prefix}${r.toString(16)}${g.toString(16)}${b.toString(16)}`; +} + +export function getPastel(color: string, factor: number = 0.5, prefix = '') { + let { r, g, b } = hex2RGB(color); + + r = Math.floor((r + 255 * factor) / (1 + factor)); + g = Math.floor((g + 255 * factor) / (1 + factor)); + b = Math.floor((b + 255 * factor) / (1 + factor)); + + return rgb2Hex(r, g, b, prefix); +} + +export function getColor(seed: string, min: number = 0, max: number = 255) { + const color = md5(seed).substring(0, 6); + const { r, g, b } = hex2RGB(color, min, max); + + return rgb2Hex(r, g, b); +}