mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-06 07:46:32 +00:00
UBER-486: replaced avatar colors (#3724)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
a07f88033f
commit
07bcffe363
@ -50,11 +50,13 @@ const defineAvatarColor = (
|
|||||||
dark: boolean = false
|
dark: boolean = false
|
||||||
): ColorDefinition => {
|
): ColorDefinition => {
|
||||||
const background = rgbToHex(hslToRgb(h / 360, s / 100, l / 100))
|
const background = rgbToHex(hslToRgb(h / 360, s / 100, l / 100))
|
||||||
|
const icon = rgbToHex(hslToRgb(h / 360, 0.5, 0.6))
|
||||||
|
const title = rgbToHex(hslToRgb(h / 360, 0.9, 0.9))
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
color: background,
|
color: background,
|
||||||
icon: undefined,
|
icon,
|
||||||
title: undefined,
|
title,
|
||||||
number: undefined,
|
number: undefined,
|
||||||
background:
|
background:
|
||||||
gradient.length === 1
|
gradient.length === 1
|
||||||
@ -264,6 +266,21 @@ export function getPlatformAvatarColorForTextDef (text: string, darkTheme: boole
|
|||||||
return getPlatformAvatarColorDef(hashCode(text), darkTheme)
|
return getPlatformAvatarColorDef(hashCode(text), darkTheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export function getPlatformAvatarColorByName (name: string, darkTheme: boolean): ColorDefinition {
|
||||||
|
const palette = darkTheme ? avatarDarkColors : avatarWhiteColors
|
||||||
|
return palette.find((col) => col.name === name) ?? palette[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export function getPlatformAvatarColors (darkTheme: boolean): readonly ColorDefinition[] {
|
||||||
|
return darkTheme ? avatarDarkColors : avatarWhiteColors
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
|
@ -27,17 +27,19 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import contact, {
|
import contact, { AvatarProvider, AvatarType, getFirstName, getLastName } from '@hcengineering/contact'
|
||||||
AvatarProvider,
|
|
||||||
AvatarType,
|
|
||||||
getAvatarColorForId,
|
|
||||||
getFirstName,
|
|
||||||
getLastName
|
|
||||||
} from '@hcengineering/contact'
|
|
||||||
import { Client, Ref } from '@hcengineering/core'
|
import { Client, Ref } from '@hcengineering/core'
|
||||||
import { Asset, getResource } from '@hcengineering/platform'
|
import { Asset, getResource } from '@hcengineering/platform'
|
||||||
import { getBlobURL, getClient } from '@hcengineering/presentation'
|
import { getBlobURL, getClient } from '@hcengineering/presentation'
|
||||||
import { AnySvelteComponent, Icon, IconSize } from '@hcengineering/ui'
|
import {
|
||||||
|
AnySvelteComponent,
|
||||||
|
Icon,
|
||||||
|
IconSize,
|
||||||
|
getPlatformAvatarColorForTextDef,
|
||||||
|
getPlatformAvatarColorByName,
|
||||||
|
themeStore,
|
||||||
|
ColorDefinition
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import { getAvatarProviderId } from '../utils'
|
import { getAvatarProviderId } from '../utils'
|
||||||
import AvatarIcon from './icons/Avatar.svelte'
|
import AvatarIcon from './icons/Avatar.svelte'
|
||||||
|
|
||||||
@ -49,7 +51,7 @@
|
|||||||
|
|
||||||
let url: string[] | undefined
|
let url: string[] | undefined
|
||||||
let avatarProvider: AvatarProvider | undefined
|
let avatarProvider: AvatarProvider | undefined
|
||||||
let color: string | undefined = undefined
|
let color: ColorDefinition | undefined = undefined
|
||||||
|
|
||||||
$: fname = getFirstName(name ?? '')
|
$: fname = getFirstName(name ?? '')
|
||||||
$: lname = getLastName(name ?? '')
|
$: lname = getLastName(name ?? '')
|
||||||
@ -68,7 +70,7 @@
|
|||||||
|
|
||||||
if (!avatarProvider || avatarProvider.type === AvatarType.COLOR) {
|
if (!avatarProvider || avatarProvider.type === AvatarType.COLOR) {
|
||||||
url = undefined
|
url = undefined
|
||||||
color = avatar.split('://')[1]
|
color = getPlatformAvatarColorByName(avatar.split('://')[1], $themeStore.dark)
|
||||||
} else if (avatarProvider?.type === AvatarType.IMAGE) {
|
} else if (avatarProvider?.type === AvatarType.IMAGE) {
|
||||||
url = (await getResource(avatarProvider.getUrl))(avatar, size)
|
url = (await getResource(avatarProvider.getUrl))(avatar, size)
|
||||||
} else {
|
} else {
|
||||||
@ -76,7 +78,7 @@
|
|||||||
url = (await getResource(avatarProvider.getUrl))(uri, size)
|
url = (await getResource(avatarProvider.getUrl))(uri, size)
|
||||||
}
|
}
|
||||||
} else if (name != null) {
|
} else if (name != null) {
|
||||||
color = getAvatarColorForId(name)
|
color = getPlatformAvatarColorForTextDef(name, $themeStore.dark)
|
||||||
url = undefined
|
url = undefined
|
||||||
avatarProvider = undefined
|
avatarProvider = undefined
|
||||||
} else {
|
} else {
|
||||||
@ -95,7 +97,7 @@
|
|||||||
class="ava-{size} flex-center avatar-container"
|
class="ava-{size} flex-center avatar-container"
|
||||||
class:no-img={!url && color}
|
class:no-img={!url && color}
|
||||||
class:bordered={!url && color === undefined}
|
class:bordered={!url && color === undefined}
|
||||||
style:background-color={url ? 'var(--theme-button-default)' : color}
|
style:background-color={color && !url ? color.icon : 'var(--theme-button-default)'}
|
||||||
>
|
>
|
||||||
{#if url}
|
{#if url}
|
||||||
{#if size === 'large' || size === 'x-large' || size === '2x-large'}
|
{#if size === 'large' || size === 'x-large' || size === '2x-large'}
|
||||||
@ -103,7 +105,11 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<img class="ava-{size} ava-mask" src={url[0]} {srcset} alt={''} bind:this={imageElement} />
|
<img class="ava-{size} ava-mask" src={url[0]} {srcset} alt={''} bind:this={imageElement} />
|
||||||
{:else if name && displayName && displayName !== ''}
|
{:else if name && displayName && displayName !== ''}
|
||||||
<div class="ava-text" data-name={displayName.toLocaleUpperCase()} />
|
<div
|
||||||
|
class="ava-text"
|
||||||
|
style:color={color ? color.title : 'var(--accented-button-color)'}
|
||||||
|
data-name={displayName.toLocaleUpperCase()}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<Icon icon={icon ?? AvatarIcon} size={'full'} />
|
<Icon icon={icon ?? AvatarIcon} size={'full'} />
|
||||||
|
@ -15,8 +15,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
import { AnySvelteComponent, IconSize, showPopup } from '@hcengineering/ui'
|
import {
|
||||||
import { AvatarType, getAvatarColorForId } from '@hcengineering/contact'
|
AnySvelteComponent,
|
||||||
|
IconSize,
|
||||||
|
showPopup,
|
||||||
|
getPlatformAvatarColorForTextDef,
|
||||||
|
themeStore
|
||||||
|
} from '@hcengineering/ui'
|
||||||
|
import { AvatarType } from '@hcengineering/contact'
|
||||||
import { Asset, getResource } from '@hcengineering/platform'
|
import { Asset, getResource } from '@hcengineering/platform'
|
||||||
|
|
||||||
import AvatarComponent from './Avatar.svelte'
|
import AvatarComponent from './Avatar.svelte'
|
||||||
@ -41,7 +47,7 @@
|
|||||||
: AvatarType.IMAGE
|
: AvatarType.IMAGE
|
||||||
$: selectedAvatar = selectedAvatarType === AvatarType.IMAGE ? avatar : uri
|
$: selectedAvatar = selectedAvatarType === AvatarType.IMAGE ? avatar : uri
|
||||||
$: if (selectedAvatar === undefined && selectedAvatarType === AvatarType.COLOR) {
|
$: if (selectedAvatar === undefined && selectedAvatarType === AvatarType.COLOR) {
|
||||||
selectedAvatar = getAvatarColorForId(name)
|
selectedAvatar = getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createAvatar (): Promise<string | undefined> {
|
export async function createAvatar (): Promise<string | undefined> {
|
||||||
|
@ -15,16 +15,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte'
|
import { createEventDispatcher } from 'svelte'
|
||||||
|
|
||||||
import {
|
import { AvatarType, buildGravatarId, checkHasGravatar } from '@hcengineering/contact'
|
||||||
AvatarType,
|
|
||||||
buildGravatarId,
|
|
||||||
checkHasGravatar,
|
|
||||||
getAvatarColorForId,
|
|
||||||
getAvatarColors,
|
|
||||||
getAvatarColorName
|
|
||||||
} from '@hcengineering/contact'
|
|
||||||
import { Asset } from '@hcengineering/platform'
|
import { Asset } from '@hcengineering/platform'
|
||||||
import { AnySvelteComponent, Label, showPopup, TabList, eventToHTMLElement } from '@hcengineering/ui'
|
import {
|
||||||
|
AnySvelteComponent,
|
||||||
|
Label,
|
||||||
|
showPopup,
|
||||||
|
TabList,
|
||||||
|
eventToHTMLElement,
|
||||||
|
getPlatformAvatarColorForTextDef,
|
||||||
|
getPlatformAvatarColorByName,
|
||||||
|
getPlatformAvatarColors,
|
||||||
|
ColorDefinition,
|
||||||
|
themeStore
|
||||||
|
} from '@hcengineering/ui'
|
||||||
import { ColorsPopup } from '@hcengineering/view-resources'
|
import { ColorsPopup } from '@hcengineering/view-resources'
|
||||||
import presentation, { Card, getFileUrl } from '@hcengineering/presentation'
|
import presentation, { Card, getFileUrl } from '@hcengineering/presentation'
|
||||||
import contact from '../plugin'
|
import contact from '../plugin'
|
||||||
@ -40,8 +44,9 @@
|
|||||||
export let onSubmit: (avatarType?: AvatarType, avatar?: string, file?: Blob) => void
|
export let onSubmit: (avatarType?: AvatarType, avatar?: string, file?: Blob) => void
|
||||||
|
|
||||||
const [schema, uri] = avatar?.split('://') || []
|
const [schema, uri] = avatar?.split('://') || []
|
||||||
const colors = getAvatarColors()
|
const colors = getPlatformAvatarColors($themeStore.dark)
|
||||||
let color: string | undefined = (schema as AvatarType) === AvatarType.COLOR ? uri : undefined
|
let color: ColorDefinition | undefined =
|
||||||
|
(schema as AvatarType) === AvatarType.COLOR ? getPlatformAvatarColorByName(uri, $themeStore.dark) : undefined
|
||||||
|
|
||||||
const initialSelectedType = (() => {
|
const initialSelectedType = (() => {
|
||||||
if (file) {
|
if (file) {
|
||||||
@ -56,7 +61,7 @@
|
|||||||
|
|
||||||
const initialSelectedAvatar = (() => {
|
const initialSelectedAvatar = (() => {
|
||||||
if (!avatar) {
|
if (!avatar) {
|
||||||
return getAvatarColorForId(name)
|
return getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name
|
||||||
}
|
}
|
||||||
|
|
||||||
return avatar.includes('://') ? uri : avatar
|
return avatar.includes('://') ? uri : avatar
|
||||||
@ -96,7 +101,7 @@
|
|||||||
inputRef.click()
|
inputRef.click()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
selectedAvatar = color ?? getAvatarColorForId(name)
|
selectedAvatar = color ? color.name : getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,13 +124,13 @@
|
|||||||
if (blob === undefined) {
|
if (blob === undefined) {
|
||||||
if (!selectedFile && (!avatar || avatar.includes('://'))) {
|
if (!selectedFile && (!avatar || avatar.includes('://'))) {
|
||||||
selectedAvatarType = AvatarType.COLOR
|
selectedAvatarType = AvatarType.COLOR
|
||||||
selectedAvatar = getAvatarColorForId(name)
|
selectedAvatar = getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (blob === null) {
|
if (blob === null) {
|
||||||
selectedAvatarType = AvatarType.COLOR
|
selectedAvatarType = AvatarType.COLOR
|
||||||
selectedAvatar = getAvatarColorForId(name)
|
selectedAvatar = getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name
|
||||||
selectedFile = undefined
|
selectedFile = undefined
|
||||||
} else {
|
} else {
|
||||||
selectedFile = blob
|
selectedFile = blob
|
||||||
@ -151,7 +156,7 @@
|
|||||||
if (!inputRef.value.length) {
|
if (!inputRef.value.length) {
|
||||||
if (!selectedFile) {
|
if (!selectedFile) {
|
||||||
selectedAvatarType = AvatarType.COLOR
|
selectedAvatarType = AvatarType.COLOR
|
||||||
selectedAvatar = getAvatarColorForId(name)
|
selectedAvatar = getPlatformAvatarColorForTextDef(name ?? '', $themeStore.dark).name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,11 +164,17 @@
|
|||||||
const showColorPopup = (event: MouseEvent) => {
|
const showColorPopup = (event: MouseEvent) => {
|
||||||
showPopup(
|
showPopup(
|
||||||
ColorsPopup,
|
ColorsPopup,
|
||||||
{ colors, columns: 6, selected: getAvatarColorName(selectedAvatar) },
|
{
|
||||||
|
colors,
|
||||||
|
columns: 6,
|
||||||
|
selected: getPlatformAvatarColorByName(selectedAvatar, $themeStore.dark),
|
||||||
|
key: 'icon'
|
||||||
|
},
|
||||||
eventToHTMLElement(event),
|
eventToHTMLElement(event),
|
||||||
(col) => {
|
(col) => {
|
||||||
if (col != null) {
|
if (col != null) {
|
||||||
color = selectedAvatar = colors[col].color
|
color = colors[col]
|
||||||
|
selectedAvatar = color.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
export let colors: readonly ColorDefinition[] = getPlatformColors($themeStore.dark)
|
export let colors: readonly ColorDefinition[] = getPlatformColors($themeStore.dark)
|
||||||
export let columns: number = 8
|
export let columns: number = 8
|
||||||
export let selected: string | undefined = undefined
|
export let selected: string | undefined = undefined
|
||||||
|
export let key: 'color' | 'icon' = 'color'
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
</script>
|
</script>
|
||||||
@ -29,11 +30,12 @@
|
|||||||
<PopupDialog label={view.string.ChooseAColor}>
|
<PopupDialog label={view.string.ChooseAColor}>
|
||||||
<div class="color-grid" style="grid-template-columns: repeat({columns}, 1.5rem)">
|
<div class="color-grid" style="grid-template-columns: repeat({columns}, 1.5rem)">
|
||||||
{#each colors as color, i}
|
{#each colors as color, i}
|
||||||
|
{@const col = key === 'color' ? color.color : color.icon}
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<div
|
<div
|
||||||
class="color"
|
class="color"
|
||||||
class:selected={selected === color.name}
|
class:selected={selected === color.name}
|
||||||
style="background-color: {color.color}"
|
style="background-color: {col}"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
dispatch('close', i)
|
dispatch('close', i)
|
||||||
}}
|
}}
|
||||||
|
Loading…
Reference in New Issue
Block a user