mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-01 03:23:09 +03:00
dark-mode: adjusting sigils and tile colors
This commit is contained in:
parent
2a15658d2e
commit
c96b1ec700
17829
pkg/grid/package-lock.json
generated
17829
pkg/grid/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,8 @@ import classNames from 'classnames';
|
||||
import React, { useMemo } from 'react';
|
||||
import { sigil, reactRenderer } from '@tlon/sigil-js';
|
||||
import { deSig, Contact } from '@urbit/api';
|
||||
import { darken, lighten, parseToHsla } from 'color2k';
|
||||
import { usePreferencesStore } from '../nav/preferences/usePreferencesStore';
|
||||
|
||||
export type AvatarSizes = 'xs' | 'small' | 'default';
|
||||
|
||||
@ -45,10 +47,27 @@ const emptyContact: Contact = {
|
||||
'last-updated': 0
|
||||
};
|
||||
|
||||
function themeAdjustColor(color: string, theme: 'light' | 'dark'): string {
|
||||
const hsla = parseToHsla(color);
|
||||
const lightness = hsla[2];
|
||||
|
||||
if (lightness <= 0.1 && theme === 'dark') {
|
||||
return lighten(color, 0.1 - lightness);
|
||||
}
|
||||
|
||||
if (lightness >= 0.9 && theme === 'light') {
|
||||
return darken(color, lightness - 0.9);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
export const Avatar = ({ size, className, ...ship }: AvatarProps) => {
|
||||
const currentTheme = usePreferencesStore((s) => s.currentTheme);
|
||||
const { shipName, color, avatar } = { ...emptyContact, ...ship };
|
||||
const { classes, size: sigilSize } = sizeMap[size];
|
||||
const foregroundColor = foregroundFromBackground(color);
|
||||
const adjustedColor = themeAdjustColor(color, currentTheme);
|
||||
const foregroundColor = foregroundFromBackground(adjustedColor);
|
||||
const sigilElement = useMemo(() => {
|
||||
if (shipName.match(/[_^]/)) {
|
||||
return null;
|
||||
@ -59,9 +78,9 @@ export const Avatar = ({ size, className, ...ship }: AvatarProps) => {
|
||||
renderer: reactRenderer,
|
||||
size: sigilSize,
|
||||
icon: true,
|
||||
colors: [color, foregroundColor]
|
||||
colors: [adjustedColor, foregroundColor]
|
||||
});
|
||||
}, [shipName, color, foregroundColor]);
|
||||
}, [shipName, adjustedColor, foregroundColor]);
|
||||
|
||||
if (avatar) {
|
||||
return <img className={classNames('', classes)} src={avatar} alt="" />;
|
||||
@ -77,7 +96,7 @@ export const Avatar = ({ size, className, ...ship }: AvatarProps) => {
|
||||
size === 'default' && 'p-3',
|
||||
className
|
||||
)}
|
||||
style={{ backgroundColor: color }}
|
||||
style={{ backgroundColor: adjustedColor }}
|
||||
>
|
||||
{sigilElement}
|
||||
</div>
|
||||
|
@ -192,7 +192,8 @@ export const mockContacts: Contacts = {
|
||||
},
|
||||
'~nalbel_litzod': {
|
||||
...contact,
|
||||
nickname: 'Queen'
|
||||
nickname: 'Queen',
|
||||
color: '#0a1b0a'
|
||||
},
|
||||
'~litmus^ritten': {
|
||||
...contact
|
||||
@ -206,7 +207,8 @@ export const mockContacts: Contacts = {
|
||||
},
|
||||
'~nalrys': {
|
||||
...contact,
|
||||
status: 'hosting coming soon'
|
||||
status: 'hosting coming soon',
|
||||
color: '#130c06'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import classNames from 'classnames';
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { darken, hsla, lighten, parseToHsla, readableColorIsBlack } from 'color2k';
|
||||
import { chadIsRunning } from '@urbit/api/docket';
|
||||
import { TileMenu } from './TileMenu';
|
||||
import { Spinner } from '../components/Spinner';
|
||||
@ -14,28 +13,13 @@ type TileProps = {
|
||||
desk: string;
|
||||
};
|
||||
|
||||
function getMenuColor(color: string, lightText: boolean, active: boolean): string {
|
||||
const hslaColor = parseToHsla(color);
|
||||
const satAdjustedColor = hsla(
|
||||
hslaColor[0],
|
||||
active ? Math.max(0.2, hslaColor[1]) : 0,
|
||||
hslaColor[2],
|
||||
1
|
||||
);
|
||||
|
||||
return lightText ? lighten(satAdjustedColor, 0.1) : darken(satAdjustedColor, 0.1);
|
||||
}
|
||||
|
||||
export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
|
||||
const addRecentApp = useRecentsStore((state) => state.addRecentApp);
|
||||
const { title, image, color, chad, href } = charge;
|
||||
const { theme, tileColor } = useTileColor(color);
|
||||
const { lightText, tileColor, menuColor, suspendColor, suspendMenuColor } = useTileColor(color);
|
||||
const loading = 'install' in chad;
|
||||
const active = chadIsRunning(chad);
|
||||
const lightText = !readableColorIsBlack(color);
|
||||
const menuColor = getMenuColor(tileColor, theme === 'dark' ? !lightText : lightText, active);
|
||||
const suspendColor = 'rgb(220,220,220)';
|
||||
const suspended = 'suspend' in chad;
|
||||
const active = chadIsRunning(chad);
|
||||
const link = getAppHref(href);
|
||||
const backgroundColor = active ? tileColor || 'purple' : suspendColor;
|
||||
|
||||
@ -61,7 +45,7 @@ export const Tile: FunctionComponent<TileProps> = ({ charge, desk }) => {
|
||||
<TileMenu
|
||||
desk={desk}
|
||||
active={active}
|
||||
menuColor={menuColor}
|
||||
menuColor={active ? menuColor : suspendMenuColor}
|
||||
lightText={lightText}
|
||||
className="absolute z-10 top-2.5 right-2.5 sm:top-4 sm:right-4 opacity-0 hover-none:opacity-100 focus:opacity-100 group-hover:opacity-100"
|
||||
/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { hsla, parseToHsla } from 'color2k';
|
||||
import { darken, hsla, lighten, parseToHsla, readableColorIsBlack } from 'color2k';
|
||||
import { usePreferencesStore } from '../nav/preferences/usePreferencesStore';
|
||||
|
||||
function getDarkColor(color: string): string {
|
||||
@ -6,11 +6,31 @@ function getDarkColor(color: string): string {
|
||||
return hsla(hslaColor[0], hslaColor[1], 1 - hslaColor[2], 1);
|
||||
}
|
||||
|
||||
function bgAdjustedColor(color: string, darkBg: boolean): string {
|
||||
return darkBg ? lighten(color, 0.1) : darken(color, 0.1);
|
||||
}
|
||||
|
||||
function getMenuColor(color: string, darkBg: boolean): string {
|
||||
const hslaColor = parseToHsla(color);
|
||||
const satAdjustedColor = hsla(hslaColor[0], Math.max(0.2, hslaColor[1]), hslaColor[2], 1);
|
||||
|
||||
return bgAdjustedColor(satAdjustedColor, darkBg);
|
||||
}
|
||||
|
||||
export const useTileColor = (color: string) => {
|
||||
const theme = usePreferencesStore((s) => s.currentTheme);
|
||||
const darkTheme = theme === 'dark';
|
||||
const tileColor = darkTheme ? getDarkColor(color) : color;
|
||||
const darkBg = !readableColorIsBlack(tileColor);
|
||||
const lightText = darkBg !== darkTheme; // if not same, light text
|
||||
const suspendColor = darkTheme ? 'rgb(26,26,26)' : 'rgb(220,220,220)';
|
||||
|
||||
return {
|
||||
theme,
|
||||
tileColor: theme === 'dark' ? getDarkColor(color) : color
|
||||
tileColor: theme === 'dark' ? getDarkColor(color) : color,
|
||||
menuColor: getMenuColor(tileColor, darkBg),
|
||||
suspendColor,
|
||||
suspendMenuColor: bgAdjustedColor(suspendColor, darkBg),
|
||||
lightText
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user