tangled
alpha
login
or
join now
t1c.dev
/
rocksky
forked from
rocksky.app/rocksky
2
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
2
fork
atom
overview
issues
pulls
pipelines
Render generic avatar for @jpeg placeholders
tsiry-sandratraina.com
1 month ago
9e2d62bc
fcfdf56d
+101
-36
7 changed files
expand all
collapse all
unified
split
apps
web
src
components
Handle
Handle.tsx
index.css
layouts
Navbar
Navbar.tsx
Search
Search.tsx
pages
home
feed
Feed.tsx
stories
Stories.tsx
profile
Profile.tsx
+13
-6
apps/web/src/components/Handle/Handle.tsx
···
14
import Stats from "../Stats";
15
import NowPlaying from "./NowPlaying";
16
import { followsAtom } from "../../atoms/follows";
17
-
import { IconCheck, IconPlus } from "@tabler/icons-react";
18
import { Button } from "baseui/button";
19
import SignInModal from "../SignInModal";
20
import {
···
176
<div className="flex flex-row items-start justify-between">
177
<div className="flex flex-row items-center">
178
<Link to={link} className="no-underline">
179
-
<Avatar
180
-
src={profiles[did]?.avatar}
181
-
name={profiles[did]?.displayName}
182
-
size={"60px"}
183
-
/>
0
0
0
0
0
0
0
184
</Link>
185
<div className="ml-[16px]">
186
<Link to={link} className="no-underline">
···
14
import Stats from "../Stats";
15
import NowPlaying from "./NowPlaying";
16
import { followsAtom } from "../../atoms/follows";
17
+
import { IconCheck, IconPlus, IconUser } from "@tabler/icons-react";
18
import { Button } from "baseui/button";
19
import SignInModal from "../SignInModal";
20
import {
···
176
<div className="flex flex-row items-start justify-between">
177
<div className="flex flex-row items-center">
178
<Link to={link} className="no-underline">
179
+
{!profiles[did]?.avatar.endsWith("/@jpeg") && (
180
+
<Avatar
181
+
src={profiles[did]?.avatar}
182
+
name={profiles[did]?.displayName}
183
+
size={"60px"}
184
+
/>
185
+
)}
186
+
{profiles[did]?.avatar.endsWith("/@jpeg") && (
187
+
<div className="w-[60px] h-[60px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center">
188
+
<IconUser size={30} color="#fff" />
189
+
</div>
190
+
)}
191
</Link>
192
<div className="ml-[16px]">
193
<Link to={link} className="no-underline">
+2
apps/web/src/index.css
···
92
--color-skeleton-background: #f3f3f3;
93
--color-skeleton-foreground: #ecebeb;
94
--color-genre: #3f03fb;
0
95
}
96
97
.dark {
···
115
--color-skeleton-background: #221538;
116
--color-skeleton-foreground: #2b1a4c;
117
--color-genre: #00f1f3;
0
118
}
119
120
::placeholder {
···
92
--color-skeleton-background: #f3f3f3;
93
--color-skeleton-foreground: #ecebeb;
94
--color-genre: #3f03fb;
95
+
--color-avatar-background: #8d2dffed;
96
}
97
98
.dark {
···
116
--color-skeleton-background: #221538;
117
--color-skeleton-foreground: #2b1a4c;
118
--color-genre: #00f1f3;
119
+
--color-avatar-background: #8d2dffed;
120
}
121
122
::placeholder {
+25
-10
apps/web/src/layouts/Navbar/Navbar.tsx
···
21
import { useProfileStatsByDidQuery } from "../../hooks/useProfile";
22
import LogoDark from "../../assets/rocksky-logo-dark.png";
23
import LogoLight from "../../assets/rocksky-logo-light.png";
0
24
25
const Container = styled.div`
26
position: fixed;
···
174
<div className="flex flex-col items-center">
175
<div className="mb-[5px]">
176
<Link to="/profile/$did" params={{ did: profile.handle }}>
177
-
<Avatar
178
-
src={profile.avatar}
179
-
name={profile.displayName}
180
-
size="80px"
181
-
/>
0
0
0
0
0
0
0
182
</Link>
183
</div>
184
···
339
)}
340
>
341
<button className="ml-[15px] border-none bg-transparent cursor-pointer">
342
-
<Avatar
343
-
src={profile.avatar}
344
-
name={profile.displayName}
345
-
size="scale1200"
346
-
/>
0
0
0
0
0
0
0
347
</button>
348
</StatefulPopover>
349
)}
···
21
import { useProfileStatsByDidQuery } from "../../hooks/useProfile";
22
import LogoDark from "../../assets/rocksky-logo-dark.png";
23
import LogoLight from "../../assets/rocksky-logo-light.png";
24
+
import { IconUser } from "@tabler/icons-react";
25
26
const Container = styled.div`
27
position: fixed;
···
175
<div className="flex flex-col items-center">
176
<div className="mb-[5px]">
177
<Link to="/profile/$did" params={{ did: profile.handle }}>
178
+
{!profile?.avatar?.endsWith("/@jpeg") && (
179
+
<Avatar
180
+
src={profile.avatar}
181
+
name={profile.displayName}
182
+
size="80px"
183
+
/>
184
+
)}
185
+
{profile?.avatar?.endsWith("/@jpeg") && (
186
+
<div className="w-[80px] h-[80px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center">
187
+
<IconUser size={40} color="#fff" />
188
+
</div>
189
+
)}
190
</Link>
191
</div>
192
···
347
)}
348
>
349
<button className="ml-[15px] border-none bg-transparent cursor-pointer">
350
+
{!profile?.avatar?.endsWith("/@jpeg") && (
351
+
<Avatar
352
+
src={profile.avatar}
353
+
name={profile.displayName}
354
+
size="scale1200"
355
+
/>
356
+
)}
357
+
{profile?.avatar?.endsWith("/@jpeg") && (
358
+
<div className="w-[48px] h-[48px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center">
359
+
<IconUser size={24} color="#fff" />
360
+
</div>
361
+
)}
362
</button>
363
</StatefulPopover>
364
)}
+14
-6
apps/web/src/layouts/Search/Search.tsx
···
13
import Disc from "../../components/Icons/Disc";
14
import Track from "../../components/Icons/Track";
15
import { useSearchMutation } from "../../hooks/useSearch";
0
16
17
const Link = styled(DefaultLink)`
18
color: initial;
···
84
{item._federation.indexUid === "users" && (
85
<Link to={`/profile/${item.handle}`} key={item.id}>
86
<div className="flex flex-row mb-[10px]">
87
-
<img
88
-
key={item.did}
89
-
src={item.avatar}
90
-
alt={item.displayName}
91
-
className="w-[50px] h-[50px] mr-[12px] rounded-full"
92
-
/>
0
0
0
0
0
0
0
93
<div>
94
<div className="overflow-hidden">
95
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-[var(--color-text)]">
···
13
import Disc from "../../components/Icons/Disc";
14
import Track from "../../components/Icons/Track";
15
import { useSearchMutation } from "../../hooks/useSearch";
16
+
import { IconUser } from "@tabler/icons-react";
17
18
const Link = styled(DefaultLink)`
19
color: initial;
···
85
{item._federation.indexUid === "users" && (
86
<Link to={`/profile/${item.handle}`} key={item.id}>
87
<div className="flex flex-row mb-[10px]">
88
+
{!item.avatar?.endsWith("/@jpeg") && (
89
+
<img
90
+
key={item.did}
91
+
src={item.avatar}
92
+
alt={item.displayName}
93
+
className="w-[50px] h-[50px] mr-[12px] rounded-full"
94
+
/>
95
+
)}
96
+
{item.avatar?.endsWith("/@jpeg") && (
97
+
<div className="w-[50px] h-[50px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center mr-[12px]">
98
+
<IconUser size={25} color="#fff" />
99
+
</div>
100
+
)}
101
<div>
102
<div className="overflow-hidden">
103
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-[var(--color-text)]">
+13
-5
apps/web/src/pages/home/feed/Feed.tsx
···
22
import FeedGenerators from "./FeedGenerators";
23
import { consola } from "consola";
24
import { Link } from "@tanstack/react-router";
0
25
26
dayjs.extend(relativeTime);
27
···
219
220
<div className="flex">
221
<div className="mr-[8px]">
222
-
<Avatar
223
-
src={song.userAvatar}
224
-
name={song.userDisplayName}
225
-
size={"20px"}
226
-
/>
0
0
0
0
0
0
0
227
</div>
228
<Handle
229
link={`/profile/${song.user}`}
···
22
import FeedGenerators from "./FeedGenerators";
23
import { consola } from "consola";
24
import { Link } from "@tanstack/react-router";
25
+
import { IconUser } from "@tabler/icons-react";
26
27
dayjs.extend(relativeTime);
28
···
220
221
<div className="flex">
222
<div className="mr-[8px]">
223
+
{!song.userAvatar.endsWith("/@jpeg") && (
224
+
<Avatar
225
+
src={song.userAvatar}
226
+
name={song.userDisplayName}
227
+
size={"20px"}
228
+
/>
229
+
)}
230
+
{song.userAvatar.endsWith("/@jpeg") && (
231
+
<div className="w-[20px] h-[20px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center">
232
+
<IconUser size={10} color="#fff" />
233
+
</div>
234
+
)}
235
</div>
236
<Handle
237
link={`/profile/${song.user}`}
+21
-3
apps/web/src/pages/home/stories/Stories.tsx
···
8
import relativeTime from "dayjs/plugin/relativeTime";
9
import utc from "dayjs/plugin/utc";
10
import { useEffect, useState, useRef } from "react";
11
-
import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react";
0
0
0
0
12
import { useStoriesQuery } from "../../../hooks/useStories";
13
import styles, { getModalStyles } from "./styles";
14
import _ from "lodash";
···
340
setIsOpen(true);
341
}}
342
>
343
-
<Story src={item.avatar} />
0
0
0
0
0
0
0
344
<StatefulTooltip
345
content={item.handle}
346
returnFocus
···
384
</div>
385
<div className="flex flex-row items-center">
386
<Link to={`/profile/${currentlyPlaying?.handle}`}>
387
-
<Avatar src={currentlyPlaying?.avatar} />
0
0
0
0
0
0
0
388
</Link>
389
<Link to={`/profile/${currentlyPlaying?.handle}`}>
390
<div className="text-[#fff] no-underline text-[15px]">
···
8
import relativeTime from "dayjs/plugin/relativeTime";
9
import utc from "dayjs/plugin/utc";
10
import { useEffect, useState, useRef } from "react";
11
+
import {
12
+
IconChevronLeft,
13
+
IconChevronRight,
14
+
IconUser,
15
+
} from "@tabler/icons-react";
16
import { useStoriesQuery } from "../../../hooks/useStories";
17
import styles, { getModalStyles } from "./styles";
18
import _ from "lodash";
···
344
setIsOpen(true);
345
}}
346
>
347
+
{!item.avatar?.endsWith("/@jpeg") && (
348
+
<Story src={item.avatar} />
349
+
)}
350
+
{item.avatar?.endsWith("/@jpeg") && (
351
+
<div className="w-[64px] h-[64px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center mr-[12px]">
352
+
<IconUser size={24} color="#fff" />
353
+
</div>
354
+
)}
355
<StatefulTooltip
356
content={item.handle}
357
returnFocus
···
395
</div>
396
<div className="flex flex-row items-center">
397
<Link to={`/profile/${currentlyPlaying?.handle}`}>
398
+
{!currentlyPlaying?.avatar?.endsWith("/@jpeg") && (
399
+
<Avatar src={currentlyPlaying?.avatar} />
400
+
)}
401
+
{currentlyPlaying?.avatar?.endsWith("/@jpeg") && (
402
+
<div className="w-[48px] h-[48px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center mr-[12px]">
403
+
<IconUser size={24} color="#fff" />
404
+
</div>
405
+
)}
406
</Link>
407
<Link to={`/profile/${currentlyPlaying?.handle}`}>
408
<div className="text-[#fff] no-underline text-[15px]">
+13
-6
apps/web/src/pages/profile/Profile.tsx
···
18
import Overview from "./overview";
19
import Playlists from "./playlists";
20
import { Button } from "baseui/button";
21
-
import { IconPlus, IconCheck } from "@tabler/icons-react";
22
import { followsAtom } from "../../atoms/follows";
23
import SignInModal from "../../components/SignInModal";
24
import {
···
231
<Group>
232
<ProfileInfo>
233
<div className="mr-[20px]">
234
-
<Avatar
235
-
name={profiles[did]?.displayName}
236
-
src={profiles[did]?.avatar}
237
-
size="150px"
238
-
/>
0
0
0
0
0
0
0
239
</div>
240
<div
241
style={{ marginTop: profiles[did]?.displayName ? 10 : 30 }}
···
18
import Overview from "./overview";
19
import Playlists from "./playlists";
20
import { Button } from "baseui/button";
21
+
import { IconPlus, IconCheck, IconUser } from "@tabler/icons-react";
22
import { followsAtom } from "../../atoms/follows";
23
import SignInModal from "../../components/SignInModal";
24
import {
···
231
<Group>
232
<ProfileInfo>
233
<div className="mr-[20px]">
234
+
{!profiles[did]?.avatar?.endsWith("/@jpeg") && (
235
+
<Avatar
236
+
name={profiles[did]?.displayName}
237
+
src={profiles[did]?.avatar}
238
+
size="150px"
239
+
/>
240
+
)}
241
+
{profiles[did]?.avatar?.endsWith("/@jpeg") && (
242
+
<div className="w-[150px] h-[150px] rounded-full bg-[var(--color-avatar-background)] flex items-center justify-center">
243
+
<IconUser size={80} color="#fff" />
244
+
</div>
245
+
)}
246
</div>
247
<div
248
style={{ marginTop: profiles[did]?.displayName ? 10 : 30 }}