alpha
Login
or
Join now
nandi.uk
/
semble
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
This repository has no description
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
feat: mentions tab on collection page
author
pdelfan
date
3 months ago
(Apr 13, 2026, 5:23 PM -0700)
commit
61559951
61559951ca94e56e85680e2ceef7ad496e76aaf6
parent
77265cbc
77265cbc4bca8bc9a1f8455786056764b7276b8a
+77
-2
8 changed files
Expand all
Collapse all
Unified
Split
src
webapp
app
(dashboard)
profile
[handle]
(withoutHeader)
collections
[rkey]
mentions
layout.tsx
loading.tsx
page.tsx
features
collections
components
collectionTabs
CollectionTabs.tsx
platforms
bluesky
container
blueskyMentionsContainer
BlueskyMentionsContainer.tsx
leaflet
container
leafletMentionsContainer
LeafletMentionsContainer.tsx
semble
containers
sembleMentionsContainer
SembleMentionsContainer.tsx
Skeleton.SembleMentionsContainer.tsx
+42
src/webapp/app/(dashboard)/profile/[handle]/(withoutHeader)/collections/[rkey]/mentions/layout.tsx
View file
Reviewed
···
1
1
+
import { getCollectionPageByAtUri } from '@/features/collections/lib/dal';
2
2
+
3
3
+
import type { Metadata } from 'next';
4
4
+
5
5
+
interface Props {
6
6
+
params: Promise<{ rkey: string; handle: string }>;
7
7
+
children: React.ReactNode;
8
8
+
}
9
9
+
10
10
+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
11
11
+
const { rkey, handle } = await params;
12
12
+
13
13
+
const collection = await getCollectionPageByAtUri({
14
14
+
recordKey: rkey,
15
15
+
handle: handle,
16
16
+
});
17
17
+
18
18
+
return {
19
19
+
title: `${collection.name}'s mentions`,
20
20
+
description:
21
21
+
collection.description ??
22
22
+
`See where ${collection.name} is mentioned around the web`,
23
23
+
authors: [
24
24
+
{
25
25
+
name: collection.author.name,
26
26
+
url: `${process.env.APP_URL}/profile/${handle}`,
27
27
+
},
28
28
+
],
29
29
+
alternates: {
30
30
+
types: {
31
31
+
'': `${collection.uri}`,
32
32
+
},
33
33
+
},
34
34
+
other: {
35
35
+
'atprotocol:creator': `at://${collection.author.id}`,
36
36
+
},
37
37
+
};
38
38
+
}
39
39
+
40
40
+
export default function Layout(props: Props) {
41
41
+
return props.children;
42
42
+
}
+5
src/webapp/app/(dashboard)/profile/[handle]/(withoutHeader)/collections/[rkey]/mentions/loading.tsx
View file
Reviewed
···
1
1
+
import SembleMentionsContainerSkeleton from '@/features/semble/containers/sembleMentionsContainer/Skeleton.SembleMentionsContainer';
2
2
+
3
3
+
export default function Loading() {
4
4
+
return <SembleMentionsContainerSkeleton />;
5
5
+
}
+18
src/webapp/app/(dashboard)/profile/[handle]/(withoutHeader)/collections/[rkey]/mentions/page.tsx
View file
Reviewed
···
1
1
+
import SembleMentionsContainer from '@/features/semble/containers/sembleMentionsContainer/SembleMentionsContainer';
2
2
+
import { Container } from '@mantine/core';
3
3
+
4
4
+
interface Props {
5
5
+
params: Promise<{ handle: string; rkey: string }>;
6
6
+
}
7
7
+
8
8
+
export default async function Page({ params }: Props) {
9
9
+
const { handle, rkey } = await params;
10
10
+
const appUrl = process.env.NEXT_PUBLIC_APP_URL ?? 'http://127.0.0.1:4000';
11
11
+
const url = `${appUrl}/profile/${handle}/collections/${rkey}`;
12
12
+
13
13
+
return (
14
14
+
<Container p="xs" size="xl">
15
15
+
<SembleMentionsContainer url={url} />
16
16
+
</Container>
17
17
+
);
18
18
+
}
+3
src/webapp/features/collections/components/collectionTabs/CollectionTabs.tsx
View file
Reviewed
···
28
28
<TabItem value="similar-cards" href={`${basePath}/similar-cards`}>
29
29
Similar cards
30
30
</TabItem>
31
31
+
<TabItem value="mentions" href={`${basePath}/mentions`}>
32
32
+
Mentions
33
33
+
</TabItem>
31
34
<TabItem value="followers" href={`${basePath}/followers`}>
32
35
Followers
33
36
</TabItem>
+2
src/webapp/features/platforms/bluesky/container/blueskyMentionsContainer/BlueskyMentionsContainer.tsx
View file
Reviewed
···
1
1
+
'use client';
2
2
+
1
3
import SembleMentionsContainerError from '@/features/semble/containers/sembleMentionsContainer/Error.SembleMentionsContainer';
2
4
import useSearchBlueskyPosts from '../../lib/queries/useSearchBlueskyPosts';
3
5
import { BlueskySearchSortOptions } from '../../lib/types';
+2
src/webapp/features/platforms/leaflet/container/leafletMentionsContainer/LeafletMentionsContainer.tsx
View file
Reviewed
···
1
1
+
'use client';
2
2
+
1
3
import SembleMentionsContainerError from '@/features/semble/containers/sembleMentionsContainer/Error.SembleMentionsContainer';
2
4
import SembleEmptyTab from '@/features/semble/components/sembleEmptyTab/SembleEmptyTab';
3
5
import { MdOutlineAlternateEmail } from 'react-icons/md';
+2
src/webapp/features/semble/containers/sembleMentionsContainer/SembleMentionsContainer.tsx
View file
Reviewed
···
1
1
+
'use client';
2
2
+
1
3
import BlueskyMentionsContainer from '@/features/platforms/bluesky/container/blueskyMentionsContainer/BlueskyMentionsContainer';
2
4
import LeafletMentionsContainer from '@/features/platforms/leaflet/container/leafletMentionsContainer/LeafletMentionsContainer';
3
5
import { BlueskySearchSortOptions } from '@/features/platforms/bluesky/lib/types';
+3
-2
src/webapp/features/semble/containers/sembleMentionsContainer/Skeleton.SembleMentionsContainer.tsx
View file
Reviewed
···
2
2
import {
3
3
Button,
4
4
Combobox,
5
5
+
ComboboxTarget,
5
6
Grid,
6
7
GridCol,
7
8
Group,
···
15
16
<Stack gap={'xs'} align="center">
16
17
<Group justify="space-between" w={'100%'} maw={600}>
17
18
<Combobox>
18
18
-
<Combobox.Target>
19
19
+
<ComboboxTarget>
19
20
<Button variant="light" color="gray" loading>
20
21
<Skeleton height={16} width={60} />
21
22
</Button>
22
22
-
</Combobox.Target>
23
23
+
</ComboboxTarget>
23
24
</Combobox>
24
25
<Select ml={'auto'} size="sm" variant="filled" disabled />
25
26
</Group>