mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #27209 from overleaf/dp-collaborator-colour
Adapt online user and chat user colors based on luminance GitOrigin-RevId: 1b0c843147ee3dc585866bc491a7c7613cb00e70
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
import { MessageProps } from '@/features/chat/components/message'
|
||||
import { User } from '../../../../../../types/user'
|
||||
import { getHueForUserId } from '@/shared/utils/colors'
|
||||
import {
|
||||
getBackgroundColorForUserId,
|
||||
hslStringToLuminance,
|
||||
} from '@/shared/utils/colors'
|
||||
import MessageContent from '@/features/chat/components/message-content'
|
||||
import classNames from 'classnames'
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { t } from 'i18next'
|
||||
|
||||
function hue(user?: User) {
|
||||
return user ? getHueForUserId(user.id) : 0
|
||||
}
|
||||
|
||||
function getAvatarStyle(user?: User) {
|
||||
if (!user?.id) {
|
||||
// Deleted user
|
||||
@@ -20,9 +19,15 @@ function getAvatarStyle(user?: User) {
|
||||
}
|
||||
}
|
||||
|
||||
const backgroundColor = getBackgroundColorForUserId(user.id)
|
||||
|
||||
return {
|
||||
borderColor: `hsl(${hue(user)}, 85%, 40%)`,
|
||||
backgroundColor: `hsl(${hue(user)}, 85%, 40%`,
|
||||
borderColor: backgroundColor,
|
||||
backgroundColor,
|
||||
color:
|
||||
hslStringToLuminance(backgroundColor) < 0.5
|
||||
? 'var(--content-primary-dark)'
|
||||
: 'var(--content-primary)',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,11 @@ import {
|
||||
DropdownToggle,
|
||||
} from '@/features/ui/components/bootstrap-5/dropdown-menu'
|
||||
import OLTooltip from '@/features/ui/components/ol/ol-tooltip'
|
||||
import { getBackgroundColorForUserId } from '@/shared/utils/colors'
|
||||
import {
|
||||
getBackgroundColorForUserId,
|
||||
hslStringToLuminance,
|
||||
} from '@/shared/utils/colors'
|
||||
import classNames from 'classnames'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@@ -86,9 +90,16 @@ const OnlineUserWidget = ({
|
||||
|
||||
const OnlineUserCircle = ({ user }: { user: OnlineUser }) => {
|
||||
const backgroundColor = getBackgroundColorForUserId(user.user_id)
|
||||
const luminance = hslStringToLuminance(backgroundColor)
|
||||
const [character] = [...user.name]
|
||||
return (
|
||||
<span className="online-user-circle" style={{ backgroundColor }}>
|
||||
<span
|
||||
className={classNames('online-user-circle', {
|
||||
'online-user-circle-light-font': luminance < 0.5,
|
||||
'online-user-circle-dark-font': luminance >= 0.5,
|
||||
})}
|
||||
style={{ backgroundColor }}
|
||||
>
|
||||
{character}
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -34,6 +34,51 @@ export function getBackgroundColorForUserId(userId?: string) {
|
||||
return `hsl(${getHueForUserId(userId)}, 70%, 50%)`
|
||||
}
|
||||
|
||||
export function hslStringToLuminance(hslString: string): number {
|
||||
// First extract the individual components from the HSL string
|
||||
const hslSplit = hslString.slice(4).split(')')[0].split(',')
|
||||
|
||||
const h = Number(hslSplit[0])
|
||||
const s = Number(hslSplit[1].slice(0, -1)) / 100
|
||||
const l = Number(hslSplit[2].slice(0, -1)) / 100
|
||||
|
||||
// Then we need to convert HSL to RGB
|
||||
const c = (1 - Math.abs(2 * l - 1)) * s
|
||||
const x = c * (1 - Math.abs(((h / 60) % 2) - 1))
|
||||
const m = l - c / 2
|
||||
let r = 0
|
||||
let g = 0
|
||||
let b = 0
|
||||
if (h >= 0 && h < 60) {
|
||||
r = c + m
|
||||
g = x + m
|
||||
b = m
|
||||
} else if (h >= 60 && h < 120) {
|
||||
r = x + m
|
||||
g = c + m
|
||||
b = m
|
||||
} else if (h >= 120 && h < 180) {
|
||||
r = m
|
||||
g = c + m
|
||||
b = x + m
|
||||
} else if (h >= 180 && h < 240) {
|
||||
r = m
|
||||
g = x + m
|
||||
b = c + m
|
||||
} else if (h >= 240 && h < 300) {
|
||||
r = x + m
|
||||
g = m
|
||||
b = c + m
|
||||
} else if (h >= 300 && h < 360) {
|
||||
r = c + m
|
||||
g = m
|
||||
b = x + m
|
||||
}
|
||||
|
||||
// Finally we calculate the luminance
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b
|
||||
}
|
||||
|
||||
const cachedHues = new Map()
|
||||
|
||||
export function getHueForId(id: string) {
|
||||
|
||||
@@ -124,4 +124,12 @@
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.online-user-circle-light-font {
|
||||
color: var(--content-primary-dark);
|
||||
}
|
||||
|
||||
.online-user-circle-dark-font {
|
||||
color: var(--content-primary);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user