diff --git a/src/components/profile/ProfileOverview.tsx b/src/components/profile/ProfileOverview.tsx deleted file mode 100644 index fb642a4..0000000 --- a/src/components/profile/ProfileOverview.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import type { ReactNode } from 'react' - -type ProfileOverviewProps = { - children: ReactNode -} - -export function ProfileOverview({ children }: ProfileOverviewProps) { - return ( -
- {children} -
- ) -} diff --git a/src/components/repo/RepoListItem.tsx b/src/components/repo/RepoListItem.tsx index 93d307e..c13b2ad 100644 --- a/src/components/repo/RepoListItem.tsx +++ b/src/components/repo/RepoListItem.tsx @@ -1,11 +1,10 @@ -import type { Did, Handle } from '@atcute/lexicons' -import { useEffect, useState } from 'react' -import Markdown from 'react-markdown' +import type { Handle } from '@atcute/lexicons' import { Link } from 'react-router-dom' -import { countStars } from '../../lib/tangled/feed' +import Markdown from 'react-markdown' import type { Repo } from '../../lib/tangled/index' import { getRepoName, getRepoRkey } from '../../lib/tangled/repo' -import { IconStar } from '@tabler/icons-react' +import { SurfaceCard } from '../shared/SurfaceCard' +import { RepoStarCount } from './RepoStarCount' const MAX_VISIBLE_TOPICS = 3 @@ -19,29 +18,16 @@ export function RepoListItem({ handle, repo }: RepoListItemProps) { const name = getRepoName(repo) const rkey = getRepoRkey(repo) const repoDid = value.repoDid - const [stars, setStars] = useState(null) - const [starsFailed, setStarsFailed] = useState(false) - - useEffect(() => { - if (repoDid === undefined) return - - async function loadStars(repoDid: Did) { - try { - setStars(await countStars(repoDid)) - } catch { - setStarsFailed(true) - } - } - - loadStars(repoDid) - }, [repoDid]) return ( -
+

@@ -53,17 +39,7 @@ export function RepoListItem({ handle, repo }: RepoListItemProps) { )}

- {repoDid !== undefined && ( - - - )} +
{value.description && ( @@ -81,7 +57,7 @@ export function RepoListItem({ handle, repo }: RepoListItemProps) { ))} )} -
+ ) } diff --git a/src/components/repo/RepoStarCount.tsx b/src/components/repo/RepoStarCount.tsx new file mode 100644 index 0000000..8464d14 --- /dev/null +++ b/src/components/repo/RepoStarCount.tsx @@ -0,0 +1,47 @@ +import type { Did } from '@atcute/lexicons' +import { useEffect, useState } from 'react' +import { IconStar } from '@tabler/icons-react' +import { countStars } from '../../lib/tangled/feed' + +type RepoStarCountProps = { + repoDid?: Did +} + +export function RepoStarCount({ repoDid }: RepoStarCountProps) { + const [stars, setStars] = useState(null) + const [starsFailed, setStarsFailed] = useState(false) + + useEffect(() => { + if (repoDid === undefined) return + + let cancelled = false + setStars(null) + setStarsFailed(false) + + countStars(repoDid) + .then((count) => { + if (!cancelled) setStars(count) + }) + .catch(() => { + if (!cancelled) setStarsFailed(true) + }) + + return () => { + cancelled = true + } + }, [repoDid]) + + if (repoDid === undefined) return null + + return ( + + + ) +} diff --git a/src/components/repo/RepoView.tsx b/src/components/repo/RepoView.tsx index a5c66b4..52d17e2 100644 --- a/src/components/repo/RepoView.tsx +++ b/src/components/repo/RepoView.tsx @@ -1,12 +1,10 @@ -import type { Did } from '@atcute/lexicons' -import { useEffect, useState } from 'react' import Markdown from 'react-markdown' import rehypeRaw from 'rehype-raw' import rehypeSanitize from 'rehype-sanitize' -import { countStars } from '../../lib/tangled/feed' import type { Repo } from '../../lib/tangled/index' import { getRepoName } from '../../lib/tangled/repo' -import { IconStar } from '@tabler/icons-react' +import { SurfaceCard } from '../shared/SurfaceCard' +import { RepoStarCount } from './RepoStarCount' type RepoProps = { repo: Repo @@ -16,42 +14,16 @@ export function RepoView({ repo }: RepoProps) { const { value } = repo const name = getRepoName(repo) const repoDid = value.repoDid - const [stars, setStars] = useState(null) - const [starsFailed, setStarsFailed] = useState(false) - - useEffect(() => { - if (repoDid === undefined) return - - async function loadStars(repoDid: Did) { - try { - setStars(await countStars(repoDid)) - } catch { - setStarsFailed(true) - } - } - - loadStars(repoDid) - }, [repoDid]) return ( -
+

{name}

{value.knot &&

{value.knot}

}
- {repoDid !== undefined && ( - - - )} +
{value.description && ( @@ -77,6 +49,6 @@ export function RepoView({ repo }: RepoProps) { )} -
+ ) } diff --git a/src/components/shared/SurfaceCard.tsx b/src/components/shared/SurfaceCard.tsx new file mode 100644 index 0000000..a0d7d7d --- /dev/null +++ b/src/components/shared/SurfaceCard.tsx @@ -0,0 +1,17 @@ +import type { ReactNode } from 'react' + +type SurfaceCardProps = { + as?: 'article' | 'div' + children: ReactNode + className?: string +} + +export function SurfaceCard({ as = 'div', children, className = '' }: SurfaceCardProps) { + const Component = as + + return ( + + {children} + + ) +} diff --git a/src/components/string/StringListItem.tsx b/src/components/string/StringListItem.tsx index 031b546..9ff4505 100644 --- a/src/components/string/StringListItem.tsx +++ b/src/components/string/StringListItem.tsx @@ -1,6 +1,7 @@ import { Link } from 'react-router-dom' import { parseResourceUri } from '@atcute/lexicons' import type { StringRecord } from '../../lib/tangled' +import { SurfaceCard } from '../shared/SurfaceCard' type StringListItemProps = { handle: string @@ -17,7 +18,10 @@ export function StringListItem({ handle, stringRecord }: StringListItemProps) { return ( -
+

{value.filename}

@@ -31,7 +35,7 @@ export function StringListItem({ handle, stringRecord }: StringListItemProps) {

{value.contents}

-
+ ) } diff --git a/src/index.css b/src/index.css index 93adc0e..f80bee2 100644 --- a/src/index.css +++ b/src/index.css @@ -226,10 +226,6 @@ text-align: left; } - main { - padding-block: 3rem; - } - article { border: 1px solid var(--app-border); border-radius: 0.25rem; diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index ae11cb7..641cbb1 100644 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -6,8 +6,8 @@ import { IconPin } from '@tabler/icons-react' import { type ReactNode, useEffect, useState } from 'react' import { useParams, useSearchParams } from 'react-router-dom' import { ProfilePageSkeleton } from '../components/shared/PageSkeletons' +import { PageContainer } from '../components/layout/PageContainer' import { ProfileHeader } from '../components/profile/ProfileHeader' -import { ProfileOverview } from '../components/profile/ProfileOverview' import { ProfileTabs } from '../components/profile/ProfileTabs' import { RepoListItem } from '../components/repo/RepoListItem' import { StringListItem } from '../components/string/StringListItem' @@ -123,71 +123,77 @@ export function ProfilePage() { const activeSection = parseProfileSection(searchParams.get('view')) return ( -
- - - -
- {activeSection === 'overview' && ( - -

-

- {pinnedRepos?.length === 0 &&

No repos found.

} - {pinnedRepos && pinnedRepos.length > 0 && ( -
- {pinnedRepos.map((repo) => ( - - ))} -
- )} -
- )} - - {activeSection === 'repos' && ( - - {repos.items.length === 0 &&

No repositories found.

} - {repos.items.length > 0 && ( -
- {repos.items.map((repo) => ( - - ))} -
- )} -
- )} - - {activeSection === 'strings' && ( - - {strings.items.length === 0 &&

No strings found.

} - {strings.items.length > 0 && ( -
- {strings.items.map((string) => ( - - ))} -
- )} -
- )} - - {activeSection === 'stars' && ( - - {starredRepos.length === 0 &&

No stars found.

} - - {starredRepos.length > 0 && ( -
- {starredRepos.map(({ repo, handle }) => ( - - ))} -
- )} -
- )} -
+
+ + + + +
+ {activeSection === 'overview' && ( +
+

+

+ {pinnedRepos?.length === 0 &&

No repos found.

} + {pinnedRepos && pinnedRepos.length > 0 && ( +
+ {pinnedRepos.map((repo) => ( + + ))} +
+ )} +
+ )} + + {activeSection === 'repos' && ( + + {repos.items.length === 0 &&

No repositories found.

} + {repos.items.length > 0 && ( +
+ {repos.items.map((repo) => ( + + ))} +
+ )} +
+ )} + + {activeSection === 'strings' && ( + + {strings.items.length === 0 &&

No strings found.

} + {strings.items.length > 0 && ( +
+ {strings.items.map((string) => ( + + ))} +
+ )} +
+ )} + + {activeSection === 'stars' && ( + + {starredRepos.length === 0 &&

No stars found.

} + + {starredRepos.length > 0 && ( +
+ {starredRepos.map(({ repo, handle }) => ( + + ))} +
+ )} +
+ )} +
+
) } diff --git a/src/pages/RepoPage.tsx b/src/pages/RepoPage.tsx index 09446f7..95a2569 100644 --- a/src/pages/RepoPage.tsx +++ b/src/pages/RepoPage.tsx @@ -6,6 +6,7 @@ import type { $output as RepoTreeResponse } from '@atcute/tangled/types/repo/tre import { useEffect, useState } from 'react' import { useParams } from 'react-router-dom' import { RepoPageSkeleton } from '../components/shared/PageSkeletons' +import { PageContainer } from '../components/layout/PageContainer' import { ProfileByline } from '../components/profile/ProfileByline' import { RepoReadme } from '../components/repo/RepoReadme' import { RepoView } from '../components/repo/RepoView' @@ -75,20 +76,22 @@ export function RepoPage() { } return ( -
- +
+ + -
- - +
+ + - -
+ +
+
) }