Skip to content

Commit 999b58c

Browse files
committed
fix(User component): spinner positioning, level spacing
!nuf
1 parent a4fb88e commit 999b58c

2 files changed

Lines changed: 104 additions & 36 deletions

File tree

frontend/src/ts/components/common/User.tsx

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { AnimationParams } from "animejs";
33
import { createEffect, createSignal, JSXElement, on, Show } from "solid-js";
44

55
import {
6+
getMatchingFlags,
67
SupportsFlags,
78
UserFlagOptions,
89
} from "../../controllers/user-flag-controller";
@@ -83,23 +84,25 @@ export function User(props: Props): JSXElement {
8384
show={props.showNotificationBubble ?? false}
8485
class="z-2 m-0.5"
8586
/>
86-
<AnimeConditional
87-
exitBeforeEnter
88-
if={props.showSpinner ?? false}
89-
then={<Fa icon={"fa-circle-notch"} spin={true} />}
90-
else={
91-
<DiscordAvatar
92-
size={64}
93-
discordId={props.user.discordId}
94-
discordAvatar={props.user.discordAvatar}
95-
fallbackIcon={props.avatarFallback ?? "user"}
96-
class={cn(
97-
props.avatarColor === "text" && "text-text",
98-
props.avatarColor === "sub" && "text-sub",
99-
)}
100-
/>
101-
}
102-
/>
87+
<div class="grid place-items-center">
88+
<AnimeConditional
89+
exitBeforeEnter
90+
if={props.showSpinner ?? false}
91+
then={<Fa icon={"fa-circle-notch"} spin={true} />}
92+
else={
93+
<DiscordAvatar
94+
size={64}
95+
discordId={props.user.discordId}
96+
discordAvatar={props.user.discordAvatar}
97+
fallbackIcon={props.avatarFallback ?? "user"}
98+
class={cn(
99+
props.avatarColor === "text" && "text-text",
100+
props.avatarColor === "sub" && "text-sub",
101+
)}
102+
/>
103+
}
104+
/>
105+
</div>
103106
</div>
104107
</Show>
105108
<div
@@ -122,22 +125,31 @@ export function User(props: Props): JSXElement {
122125
/>
123126
</div>
124127

125-
<div
126-
class={cn(
127-
"flex items-center justify-center gap-[0.5em]",
128-
cn(
129-
props.flagsColor === "text" && "text-text",
130-
props.flagsColor === "sub" && "text-sub",
131-
),
132-
)}
128+
<Show
129+
when={
130+
getMatchingFlags({ ...props.user, isFriend: props.isFriend }).length >
131+
0
132+
}
133133
>
134-
<UserFlags
135-
{...props.user}
136-
isFriend={props.isFriend}
137-
iconsOnly={props.iconsOnly}
138-
/>
134+
<div
135+
class={cn(
136+
"flex items-center justify-center gap-[0.5em]",
137+
cn(
138+
props.flagsColor === "text" && "text-text",
139+
props.flagsColor === "sub" && "text-sub",
140+
),
141+
)}
142+
>
143+
<UserFlags
144+
{...props.user}
145+
isFriend={props.isFriend}
146+
iconsOnly={props.iconsOnly}
147+
/>
148+
</div>
149+
</Show>
150+
<Show when={props.user.badgeId !== undefined}>
139151
<UserBadge id={props.user.badgeId} />
140-
</div>
152+
</Show>
141153
<Show when={props.level !== undefined}>
142154
<Anime
143155
ref={(el) => (levelEl = el)}

frontend/storybook/stories/User.stories.tsx

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import preview from "#.storybook/preview";
2+
import { createSignal, onCleanup } from "solid-js";
23

34
import { User } from "../../src/ts/components/common/User";
45

@@ -16,14 +17,69 @@ const meta = preview.meta({
1617
},
1718
});
1819

20+
// oxlint-disable-next-line no-unused-vars
21+
function SpinnerCycleUser(props: {
22+
data: Record<string, unknown>;
23+
}): ReturnType<typeof User> {
24+
const [showSpinner, setShowSpinner] = createSignal(false);
25+
const interval = setInterval(() => {
26+
setShowSpinner((prev) => !prev);
27+
}, 2000);
28+
onCleanup(() => clearInterval(interval));
29+
//@ts-expect-error - just for testing, ignore type issues
30+
return <User user={{ ...props.data }} showSpinner={showSpinner()} />;
31+
}
32+
1933
export const Default = meta.story({
20-
args: {
21-
user: {
34+
// args: {
35+
// user: {
36+
// uid: "user123",
37+
// name: "monkeytyper",
38+
// discordId: undefined,
39+
// discordAvatar: undefined,
40+
// },
41+
// },
42+
43+
render: () => {
44+
const data = {
2245
uid: "user123",
2346
name: "monkeytyper",
24-
discordId: undefined,
25-
discordAvatar: undefined,
26-
},
47+
discordId: "102819690287489024",
48+
discordAvatar: "a_af6c0b8ad26fdd6bcb86ed7bb40ee6e5",
49+
isPremium: true,
50+
banned: true,
51+
};
52+
return (
53+
<div class="grid grid-cols-[auto_1fr] place-items-start gap-4 [--themable-button-text:var(--sub-color)]">
54+
<div class="text-sub">With avatar:</div>
55+
<User user={{ ...data }} />
56+
<div class="text-sub">No avatar:</div>
57+
<User user={{ ...data }} showAvatar={false} />
58+
<div class="text-sub">Avatar fallback:</div>
59+
<User user={{ ...data, discordAvatar: "" }} />
60+
<div class="text-sub">Avatar fallback with color:</div>
61+
<User
62+
user={{ ...data, discordAvatar: "" }}
63+
avatarFallback="user-circle"
64+
avatarColor="sub"
65+
/>
66+
<div class="text-sub">Flag color:</div>
67+
<User user={{ ...data }} flagsColor="sub" />
68+
<div class="text-sub">Hide name on small screen:</div>
69+
<User user={{ ...data }} hideNameOnSmallScreens={true} />
70+
<div class="text-sub">Level:</div>
71+
<User user={{ ...data }} level={10} />
72+
<div class="text-sub">Level no flags:</div>
73+
<User
74+
user={{ ...data, isPremium: undefined, banned: undefined }}
75+
level={10}
76+
/>
77+
<div class="text-sub">Show spinner (cycling):</div>
78+
<SpinnerCycleUser data={data} />
79+
<div class="text-sub">Show notification bubble:</div>
80+
<User user={{ ...data }} showNotificationBubble={true} />
81+
</div>
82+
);
2783
},
2884
});
2985

0 commit comments

Comments
 (0)