8000 [web-ui] Add apps · enggaraziz/threads-api@19d8435 · GitHub
[go: up one dir, main page]

Skip to content

Commit 19d8435

Browse files
committed
[web-ui] Add apps
1 parent 9976f17 commit 19d8435

File tree

11 files changed

+238
-41
lines changed

11 files changed

+238
-41
lines changed

threads-web-ui/app/apps/page.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AnalyticsTrackerLogView } from '@/components/AnalyticsTracker';
22
import { AppDirectoryItem } from '@/components/AppDirectoryItem';
3+
import { APPS } from '@/data/apps';
34

45
export default async function AppDirectory() {
56
return (
@@ -14,9 +15,9 @@ export default async function AppDirectory() {
1415
</header>
1516

1617
<ul className="flex flex-col w-full max-w-5xl gap-2 px-5 mx-auto">
17-
<AppDirectoryItem />
18-
<AppDirectoryItem />
19-
<AppDirectoryItem />
18+
{APPS.map((app) => (
19+
<AppDirectoryItem key={app.name} {...app} />
20+
))}
2021
</ul>
2122
</div>
2223
</>

threads-web-ui/components/AppDirectoryItem.tsx

+75-38
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,93 @@
11
import Image from 'next/image';
22
import PirateFlagIcon from '@/assets/pirate-flag.png';
33
import { ExternalLink, Github } from 'lucide-react';
4+
import { AppRegistry } from '@/data/apps';
45

5-
export const AppDirectoryItem: React.FC = () => {
6+
export const AppDirectoryItem: React.FC<AppRegistry> = ({ ...app }) => {
67
return (
78
<li className="flex p-4 rounded-lg bg-zinc-900">
8-
<div
9-
className="w-[100px] h-[100px] flex items-center justify-center rounded-xl relative"
10-
style={{
11-
backgroundImage: `url('/assets/mesh-gradient.png')`,
12-
backgroundSize: 'cover',
13-
}}
14-
>
15-
<Image
16-
src={PirateFlagIcon}
17-
alt="Pirate Flag"
18-
width={256}
19-
height={256}
20-
className="w-[64px] h-[64px] z-10"
9+
{!!app.avatar ? (
10+
<img
11+
src={app.avatar}
12+
alt={app.name}
13+
className="w-[100px] h-[100px] flex items-center justify-center rounded-xl relative bg-black"
2114
/>
22-
</div>
15+
) : (
16+
<div
17+
className="w-[100px] h-[100px] flex items-center justify-center rounded-xl relative bg-black"
18+
style={{
19+
backgroundImage: `url('/assets/mesh-gradient.png')`,
20+
backgroundSize: 'cover',
21+
}}
22+
>
23+
<Image
24+
src={PirateFlagIcon}
25+
alt="Pirate Flag"
26+
width={256}
27+
height={256}
28+
className="w-[64px] h-[64px] z-10"
29+
/>
30+
</div>
31+
)}
2332

2433
<div className="flex flex-col justify-start flex-1 ml-4">
2534
<div className="flex justify-between w-full">
2635
<div className="flex items-center gap-2">
27-
<h3 className="text-xl font-medium text-slate-200">Year Progress </h3>
28-
<a href="https://www.threads.net/@yearprog" target="_blank">
29-
<code className="h-fit w-fit px-2 py-0.5 text-sm font-normal rounded-md bg-zinc-700 text-slate-300">
30-
@yearprog
31-
</code>
32-
</a>
36+
<h3 className="text-xl font-medium text-slate-200">{app.name} </h3>
37+
{!!app.threads_username && (
38+
<a href={`https://www.threads.net/@${app.threads_username}`} target="_blank">
39+
<code className="h-fit w-fit px-2 py-0.5 text-sm font-normal rounded-md bg-zinc-700 text-slate-300">
40+
{`@${app.threads_username}`}
41+
</code>
42+
</a>
43+
)}
3344
</div>
3445
<div className="flex gap-1.5">
35-
<a href="https://www.threads.net/@yearprog" target="_blank">
36-
<button className="flex items-center gap-2 px-2 py-1 font-medium rounded-lg bg-slate-700 text-slate-300">
37-
<span>Threads</span>
38-
<ExternalLink size={18} />
39-
</button>
40-
</a>
41-
<a href="https://github.com/SethuSenthil/thread-year-prog-bot" target="_blank">
42-
<button className="flex items-center gap-2 px-2 py-1 font-medium rounded-lg bg-slate-700 text-slate-300">
43-
<span>GitHub</span>
44-
<Github size={18} />
45-
</button>
46-
</a>
46+
{!!app.threads_username && (
47+
<a href={`https://www.threads.net/@${app.threads_username}`} target="_blank">
48+
<button className="flex items-center gap-2 px-2 py-1 font-medium rounded-lg bg-slate-700 text-slate-300">
49+
<span>Threads</span>
50+
<ExternalLink size={18} />
51+
</button>
52+
</a>
53+
)}
54+
55+
{!!app.url && (
56+
<a href={app.url} target="_blank">
57+
<button className="flex items-center gap-2 px-2 py-1 font-medium rounded-lg bg-slate-700 text-slate-300">
58+
<span>App</span>
59+
<ExternalLink size={18} />
60+
</button>
61+
</a>
62+
)}
63+
64+
{!!app.repository && (
65+
<a href={app.repository} target="_blank">
66+
<button className="flex items-center gap-2 px-2 py-1 font-medium rounded-lg bg-slate-700 text-slate-300">
67+
<span>GitHub</span>
68+
<Github size={18} />
69+
</button>
70+
</a>
71+
)}
4772
</div>
4873
</div>
49-
<p className="text-sm text-slate-500">Built by @SethuSenthil</p>
50-
<p className="mt-2 text-slate-400">
51-
🤖 Year Progress Bar made by @sethui9 <br />
52-
🪡Weaving the fabric of ⏳ time, thread by thread 🧵
53-
</p>
74+
75+
{/* author */}
76+
{'author' in app && !!app.author && (
77+
<p className="text-sm text-slate-500 line-clamp-2">
78+
{/* FIXME: */}
79+
{`Built by ${app.author.name || app.author.github_username}`}
80+
</p>
81+
)}
82+
{'authors' in app && !!app.authors && (
83+
<p className="text-sm text-slate-500 line-clamp-2">
84+
{/* FIXME: */}
85+
{`Built by ${app.authors.map((v) => v.name || v.github_username).join(', ')}`}
86+
</p>
87+
)}
88+
89+
{/* description */}
90+
<p className="mt-2 text-slate-400 whitespace-break-spaces">{app.description}</p>
5491
</div>
5592
</li>
5693
);

threads-web-ui/data/apps.ts

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
type AppAuthor = {
2+
name: string;
3+
threads_username?: string; // WIP
4+
github_username?: string;
5+
};
6+
export type AppRegistry = {
7+
name: string;
8+
9+
// Add a new tag here if you want!
10+
tags?: ('api' | 'bot' | 'client' | 'app' | 'ui')[];
11+
12+
threads_username?: string;
13+
repository?: string;
14+
url?: string;
15+
description: string;
16+
avatar?: string;
17+
} & (
18+
| {
19+
author: AppAuthor;
20+
}
21+
| {
22+
authors: AppAuthor[];
23+
}
24+
);
25+
26+
export const APPS: AppRegistry[] = [
27+
{
28+
name: 'Threads Card',
29+
tags: ['app'],
30+
repository: 'https://github.com/yssf-io/threads-card',
31+
description: 'Simple read-only profile page for Threads',
32+
author: {
33+
name: 'yssf',
34+
github_username: 'yssf-io',
35+
},
36+
},
37+
{
38+
name: 'String',
39+
tags: ['client'],
40+
repository: 'https://github.com/yssf-io/threads-card',
41+
description:
42+
'String is a modern and innovative threads opensource frontend built with Next.js, Tailwind CSS, and the latest web development technologies.',
43+
author: {
44+
name: 'yssf',
45+
github_username: 'yssf-io',
46+
},
47+
},
48+
{
49+
name: 'Fortune Cookie Bot',
50+
tags: ['bot'],
51+
threads_username: 'fortune_cookie_bot',
52+
repository: 'https://github.com/AayushGithub/threads-projects#fortune-cookie-bot',
53+
description:
54+
'Provides valuable insights and a daily dose of wisdom. This bot leverages the Advice Slip API to fetch interesting advice and pairs it with a random image from various sources.',
55+
avatar: '/assets/apps/fortune_cookie_bot.jpg',
56+
author: {
57+
name: 'Aayush Gandhi',
58+
github_username: 'AayushGithub',
59+
},
60+
},
61+
{
62+
name: 'OPT Timeline Bot',
63+
tags: ['bot'],
64+
threads_username: 'opttimeline',
65+
repository: 'https://github.com/AayushGithub/threads-projects#opt-timeline-bot',
66+
description: 'Tracks F1 OPT cases statuses and posts updates!',
67+
avatar: '/assets/apps/opttimeline.jpg',
68+
author: {
69+
name: 'Aayush Gandhi',
70+
github_username: 'AayushGithub',
71+
},
72+
},
73+
{
74+
name: 'Thread Count',
75+
tags: ['api'],
76+
repository: 'https://github.com/AayushGithub/thread-count',
77+
description:
78+
'Thread Count is a service that allows you to generate custom status badges displaying Threads follower counts.',
79+
author: {
80+
name: 'Aayush Gandhi',
81+
github_username: 'AayushGithub',
82+
},
83+
},
84+
{
85+
name: 'Year Progress',
86+
tags: ['bot'],
87+
threads_username: 'yearprog',
88+
repository: 'https://github.com/SethuSenthil/thread-year-prog-bot',
89+
description: '🤖 Year Progress Bar \n🪡 Weaving the fabric of ⏳ time, thread by thread 🧵',
90+
avatar: '/assets/apps/yearprog.jpg',
91+
author: {
92+
name: 'Sethu Senthil',
93+
github_username: 'SethuSenthil',
94+
},
95+
},
96+
{
97+
name: 'Splatoon3.ink',
98+
tags: ['bot'],
99+
threads_username: 'splatoon3',
100+
repository: 'https://github.com/misenhower/splatoon3.ink',
101+
description:
102+
'🦑🐙 Splatoon 3 map rotations, Salmon Run schedules, and more. Not affiliated with Nintendo.',
103+
avatar: '/assets/apps/splatoon3-ink.png',
104+
authors: [
105+
{
106+
name: 'Matt Isenhower',
107+
github_username: 'misenhower',
108+
},
109+
{
110+
name: 'Jack',
111+
github_username: 'FieryFlames',
112+
},
113+
],
114+
},
115+
{
116+
name: 'Hacker News Bot',
117+
tags: ['bot'],
118+
threads_username: 'hackernewsbot',
119+
description: 'Top 5 HackerNews Stories, every hour. Not affiliated with HN or YC 🤖',
120+
avatar: '/assets/apps/hackernewsbot.jpg',
121+
author: {
122+
name: 'yssf',
123+
github_username: 'yssf-io',
124+
},
125+
},
126+
{
127+
name: '🤖쓰웨더봇 (Threads + Weather)',
128+
tags: ['bot'],
129+
threads_username: 'b__polarbear',
130+
description:
131+
'Threads API, GPT-4 기반 날씨알림 서비스! \n매일 아침 7시에 날씨 브리핑을 올려드려요! ⛅️ Made By 이민규⭐️',
132+
avatar: '/assets/apps/b__polarbear.jpg',
133+
author: {
134+
name: '이민규',
135+
threads_username: 'mingyu_9495',
136+
},
137+
},
138+
{
139+
name: 'Year Progress',
140+
tags: ['bot'],
141+
threads_username: 'progressyearly',
142+
description: 'The clock is always ticking. ⏰',
143+
avatar: '/assets/apps/progressyearly.jpg',
144+
author: {
145+
name: 'Siddhanth Kumar',
146+
},
147+
},
148+
{
149+
name: 'Year Progress Bar',
150+
tags: ['bot'],
151+
threads_username: 'yearsprogress',
152+
description: "The only progress bar you'd rather see go slower.",
153+
avatar: '/assets/apps/yearsprogress.jpg',
154+
author: {
155+
name: 'Max Mykhalchuk',
156+
threads_username: 's1mpsondev',
157+
},
158+
},
159+
];
Loading
Loading
Loading
Loading
Loading
Loading
4.04 KB
Loading
Loading

0 commit comments

Comments
 (0)
0