+
{editingNick ? (
Nickname
Save
@@ -543,10 +649,15 @@ export function OptionsChip({ userId }: { userId: string }) {
radii="300"
variant="Critical"
fill="None"
+ className={css.UserHeroMenuItem}
onClick={() => {
setNickname(userId, undefined);
close();
}}
+ style={{
+ backgroundColor: cardColor,
+ color: textColor,
+ }}
>
Clear
@@ -561,6 +672,11 @@ export function OptionsChip({ userId }: { userId: string }) {
radii="300"
before={}
onClick={() => setEditingNick(true)}
+ className={css.UserHeroMenuItem}
+ style={{
+ backgroundColor: cardColor,
+ color: textColor,
+ }}
>
{currentNick ? 'Edit Nickname' : 'Set Nickname'}
@@ -574,6 +690,8 @@ export function OptionsChip({ userId }: { userId: string }) {
toggleIgnore();
close();
}}
+ className={css.UserHeroMenuItem}
+ style={{ backgroundColor: cardColor }}
before={
ignoring ? (
@@ -583,14 +701,26 @@ export function OptionsChip({ userId }: { userId: string }) {
}
disabled={ignoring}
>
- {ignored ? 'Unblock User' : 'Block User'}
+
+ {ignored ? 'Unblock User' : 'Block User'}
+
}
>
-
+
{ignoring ? (
) : (
diff --git a/src/app/components/user-profile/UserHero.tsx b/src/app/components/user-profile/UserHero.tsx
index 34cf7635a..bb4acc103 100644
--- a/src/app/components/user-profile/UserHero.tsx
+++ b/src/app/components/user-profile/UserHero.tsx
@@ -2,6 +2,7 @@ import { useMemo, useState } from 'react';
import {
Avatar,
Box,
+ color as standardColors,
Icon,
Icons,
Modal,
@@ -28,6 +29,8 @@ import { ImageViewer } from '$components/image-viewer';
import { AvatarPresence, PresenceBadge } from '$components/presence';
import { UserAvatar } from '$components/user-avatar';
import { ClientSideHoverFreeze } from '$components/ClientSideHoverFreeze';
+import { useUserProfile } from '$hooks/useUserProfile';
+import { shadeColor, areColorsTooSimilar } from '$utils/shadeColor';
import * as css from './styles.css';
type UserHeroProps = {
@@ -69,8 +72,23 @@ export function UserHero({ userId, avatarUrl, bannerUrl, presence, autoplayGifs
const status = presence?.status;
const isExpandable = (status?.length ?? 0) > 70;
+ const fetchedProfile = useUserProfile(userId);
+ const backgroundColor = fetchedProfile.heroColor ?? standardColors.Surface.Container;
+ const fetchedBrightness = fetchedProfile?.heroBrightness;
+ const isBackgroundDark = fetchedBrightness ? fetchedBrightness === 'dark' : undefined;
+ const cardColor =
+ shadeColor(backgroundColor, isBackgroundDark ? -80 : 80) ?? standardColors.Background.Container;
+ const textColor =
+ ((fetchedBrightness === 'dark' || areColorsTooSimilar('#000000', cardColor)) && '#FFFFFF') ||
+ ((fetchedBrightness === 'light' || areColorsTooSimilar('#FFFFFF', cardColor)) && '#000000') ||
+ undefined;
+
return (
-
+
@@ -201,8 +221,7 @@ export function UserHeroName({ displayName, userId }: UserHeroNameProps) {
const nick = useNickname(userId);
// Sable username color and fonts
- const { color, font } = useSableCosmetics(userId, useRoom());
-
+ const { color, font } = useSableCosmetics(userId, useRoom(), true);
const shownName = nick ?? displayName ?? username ?? userId;
return (
diff --git a/src/app/components/user-profile/UserRoomProfile.tsx b/src/app/components/user-profile/UserRoomProfile.tsx
index 4f5c4a69a..8fb3ac253 100644
--- a/src/app/components/user-profile/UserRoomProfile.tsx
+++ b/src/app/components/user-profile/UserRoomProfile.tsx
@@ -1,4 +1,16 @@
-import { Box, Button, config, Icon, Icons, Menu, MenuItem, Scroll, Text, toRem } from 'folds';
+import {
+ Box,
+ Button,
+ color,
+ config,
+ Icon,
+ Icons,
+ Menu,
+ MenuItem,
+ Scroll,
+ Text,
+ toRem,
+} from 'folds';
import type { SyntheticEvent } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
@@ -38,12 +50,14 @@ import { filterPronounsByLanguage } from '$utils/pronouns';
import { useSetting } from '$state/hooks/settings';
import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl';
import { TextViewerContent } from '$components/text-viewer';
+import { areColorsTooSimilar, shadeColor } from '$utils/shadeColor';
import { CreatorChip } from './CreatorChip';
import { UserInviteAlert, UserBanAlert, UserModeration, UserKickAlert } from './UserModeration';
import { PowerChip } from './PowerChip';
import { IgnoredUserAlert, MutualRoomsChip, OptionsChip, ServerChip, ShareChip } from './UserChips';
import { UserHero, UserHeroName } from './UserHero';
import { KnownMembership } from '$types/matrix-sdk';
+import * as css from './styles.css';
const KNOWN_KEYS = new Set([
'moe.sable.app.bio',
@@ -64,6 +78,10 @@ type UserExtendedSectionProps = {
profile: UserProfile;
htmlReactParserOptions: HTMLReactParserOptions;
linkifyOpts: LinkifyOpts;
+ backgroundColor?: string;
+ innerColor?: string;
+ cardColor?: string;
+ textColor?: string;
};
const renderValue = (val: unknown) => {
@@ -77,6 +95,10 @@ function UserExtendedSection({
profile,
htmlReactParserOptions,
linkifyOpts,
+ backgroundColor,
+ innerColor,
+ cardColor,
+ textColor,
}: Readonly) {
const [showMisc, setShowMisc] = useState(false);
const [miscDataIndex, setMiscDataIndex] = useState(-1);
@@ -162,13 +184,24 @@ function UserExtendedSection({
return null;
}
return (
-