Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/feat_redesign_user_menu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: minor
---

Redesign the user menu tab
2 changes: 1 addition & 1 deletion src/app/components/presence/Presence.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useId } from 'react';
import { Presence, usePresenceLabel } from '$hooks/useUserPresence';
import * as css from './styles.css';

const PresenceToColor: Record<Presence, MainColor> = {
export const PresenceToColor: Record<Presence, MainColor> = {
[Presence.Online]: 'Success',
[Presence.Unavailable]: 'Warning',
[Presence.Offline]: 'Secondary',
Expand Down
112 changes: 95 additions & 17 deletions src/app/components/user-profile/UserHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,26 @@ import * as css from './styles.css';
import { copyToClipboard } from '$utils/dom';
import { useTimeoutToggle } from '$hooks/useTimeoutToggle';
import { CopyIcon, CrossIcon } from '@phosphor-icons/react';
import { useOpenSettings } from '$features/settings';

type UserHeroProps = {
userId: string;
avatarUrl?: string;
bannerUrl?: string;
presence?: UserPresence;
autoplayGifs?: boolean;
showColor?: boolean;
allowEditing?: boolean;
};
export function UserHero({ userId, avatarUrl, bannerUrl, presence, autoplayGifs }: UserHeroProps) {
export function UserHero({
userId,
avatarUrl,
bannerUrl,
presence,
autoplayGifs,
allowEditing = false,
showColor = true,
}: UserHeroProps) {
const [viewAvatar, setViewAvatar] = useState<string>();
const [isFullStatus, setIsFullStatus] = useState(false);

Expand Down Expand Up @@ -96,9 +107,14 @@ export function UserHero({ userId, avatarUrl, bannerUrl, presence, autoplayGifs
((fetchedBrightness === 'light' || areColorsTooSimilar('#FFFFFF', cardColor)) && '#000000') ||
undefined;
const statusHoverBrightness = fetchedBrightness === 'light' ? 0.94 : 1.08;
const openSettings = useOpenSettings();

return (
<Box direction="Column" className={css.UserHero} style={{ backgroundColor: backgroundColor }}>
<Box
direction="Column"
className={css.UserHero}
style={showColor ? { backgroundColor: backgroundColor } : {}}
>
<div
className={css.UserHeroCoverContainer}
style={{
Expand Down Expand Up @@ -164,22 +180,28 @@ export function UserHero({ userId, avatarUrl, bannerUrl, presence, autoplayGifs
</Overlay>
)}
</div>
{status && status.length > 0 && (
{((status && status.length > 0) || allowEditing) && (
<div className={css.UserHeroStatusContainer}>
<Tooltip
radii="400"
variant="Surface"
onClick={isExpandable ? () => setIsFullStatus(!isFullStatus) : undefined}
role={allowEditing ? 'button' : undefined}
onClick={
allowEditing
? () => openSettings('account', 'status')
: isExpandable
? () => setIsFullStatus(!isFullStatus)
: undefined
}
className={classNames(
css.UserHeroStatusTooltip,
isExpandable && css.UserHeroStatusTooltipInteractive
)}
style={{
maxHeight: isFullStatus ? toRem(105) : toRem(48),
cursor: isExpandable ? 'pointer' : 'default',
transform: 'none',
transition: 'none',
cursor: allowEditing || isExpandable ? 'pointer' : 'default',
display: 'flex',
width: 'fit-content',
padding: `${toRem(8)} ${toRem(12)}`,
backgroundColor: statusSurfaceColor,
color: textColor,
Expand All @@ -195,8 +217,14 @@ export function UserHero({ userId, avatarUrl, bannerUrl, presence, autoplayGifs
<Box direction="Row" gap="100" style={{ height: '100%', width: '100%' }}>
{isFullStatus ? (
<Scroll visibility="Hover" hideTrack style={{ height: '100%', flex: 1 }}>
<Text size="T200" style={{ wordBreak: 'break-word' }}>
{status}
<Text
size="T200"
style={{
wordBreak: 'break-word',
fontStyle: allowEditing && !status ? 'italic' : 'normal',
}}
>
{status || (allowEditing && "What's on your mind?")}
</Text>
</Scroll>
) : (
Expand All @@ -208,9 +236,10 @@ export function UserHero({ userId, avatarUrl, bannerUrl, presence, autoplayGifs
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
overflow: 'hidden',
fontStyle: allowEditing && !status ? 'italic' : 'normal',
}}
>
{status}
{status || (allowEditing && "What's on your mind?")}
</Text>
)}

Expand Down Expand Up @@ -241,17 +270,29 @@ type UserHeroNameProps = {
server?: string;
customHeroCards?: boolean;
};
export function UserHeroName({ displayName, userId, server, customHeroCards }: UserHeroNameProps) {
const username = getMxIdLocalPart(userId);
const nick = useNickname(userId);

type UserHeroNameInnerProps = {
shownName: string;
username?: string;
nick?: string;
server?: string;
color?: string;
font?: string;
customHeroCards?: boolean;
};

function UserHeroNameInner({
shownName,
nick,
username,
server,
color,
font,
}: UserHeroNameInnerProps) {
const [copied, setCopied] = useTimeoutToggle();
const [isHovered, setIsHovered] = useState(false);
const isSuccess = useRef(false);

// Sable username color and fonts
const { color, font } = useSableCosmetics(userId, useRoom(), customHeroCards);
const shownName = nick ?? displayName ?? username ?? userId;

return (
<Box grow="Yes" direction="Column" gap="0">
<Box alignItems="Baseline" gap="200" wrap="Wrap">
Expand Down Expand Up @@ -296,3 +337,40 @@ export function UserHeroName({ displayName, userId, server, customHeroCards }: U
</Box>
);
}

export function UserHeroName({ displayName, userId, server, customHeroCards }: UserHeroNameProps) {
const username = getMxIdLocalPart(userId);
const nick = useNickname(userId);

// Sable username color and fonts
const { color, font } = useSableCosmetics(userId, useRoom(), customHeroCards);
const shownName = nick ?? displayName ?? username ?? userId;

return (
<UserHeroNameInner
username={username}
server={server}
shownName={shownName}
color={color}
font={font}
/>
);
}

export function GlobalUserHeroName({ displayName, userId, server }: UserHeroNameProps) {
const username = getMxIdLocalPart(userId);
const nick = useNickname(userId);
const profile = useUserProfile(userId);

const shownName = nick ?? displayName ?? username ?? userId;

return (
<UserHeroNameInner
username={username}
server={server}
shownName={shownName}
font={profile.resolvedFont}
color={profile.resolvedColor}
/>
);
}
15 changes: 4 additions & 11 deletions src/app/pages/client/SidebarNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,13 @@ import { stopPropagation } from '$utils/keyboard';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
import { Sidebar, SidebarContent, SidebarStack } from '$components/sidebar';
import {
DirectTab,
DirectDMsList,
HomeTab,
SpaceTabs,
InboxTab,
UnverifiedTab,
AccountSwitcherTab,
} from './sidebar';
import { DirectTab, DirectDMsList, HomeTab, SpaceTabs, InboxTab, UnverifiedTab } from './sidebar';
import { CreateTab } from './sidebar/CreateTab';
import { SearchTab } from './sidebar/SearchTab';
import { SettingsTab } from './sidebar/SettingsTab';
import { UserQuickTools } from './sidebar/UserQuickTools';
import { useScreenSizeContext, ScreenSize } from '$hooks/useScreenSize';
import { UserMenuTab } from './sidebar/UserMenuTab';

export function SidebarNav() {
const scrollRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -152,7 +145,7 @@ export function SidebarNav() {
<InboxTab />
<div style={{ paddingBottom: config.space.S100 }}>
{/*PROBS ADD SETTINGSTAB HERE WHEN ADDING THE STATUSES*/}
<AccountSwitcherTab />
<UserMenuTab />
</div>
</>
) : (
Expand All @@ -166,7 +159,7 @@ export function SidebarNav() {
)}

<Box style={{ height: toRem(57) }} alignItems="Center">
<AccountSwitcherTab />
<UserMenuTab />
</Box>
</>
)}
Expand Down
Loading
Loading