diff --git a/src/components/repo.tsx b/src/components/repo.tsx index b28fc32..7b76047 100644 --- a/src/components/repo.tsx +++ b/src/components/repo.tsx @@ -29,8 +29,9 @@ import { marked } from 'marked'; import { A } from '@solidjs/router'; import { For, Show, createMemo, createSignal, onCleanup, onMount, type Component, type JSX } from 'solid-js'; import type { RepoContext, TreeEntry } from '../lib/api/repos'; +import type { Did } from '@atcute/lexicons/syntax'; import { createQuery } from '@tanstack/solid-query'; -import { getRepo, getRepoLanguages } from '../lib/api/repos'; +import { getRepo, getRepoLanguages, getRepoForkCount, getRepoByDid } from '../lib/api/repos'; import { getRepoStarCount } from '../lib/api/stars'; import { getRepoIssueCount } from '../lib/api/issues'; import { getRepoPullCount } from '../lib/api/pulls'; @@ -1654,13 +1655,29 @@ export interface RepoCardProps { showOwner?: boolean; } -export const RepoCard: Component = (props) => { - const linkHref = () => props.href || `/${props.owner}/${props.name}`; +export interface RepoStatsListProps { + repoDid?: string; + owner?: string; + name?: string; + language?: string; + stars?: number; + forks?: number; + openIssues?: number; + openPRs?: number; +} - // Define queries for statistics +export const RepoStatsList: Component = (props) => { const repoContextQuery = createQuery(() => ({ - queryKey: ['repo-context', props.owner, props.name], - queryFn: () => getRepo(props.owner, props.name), + queryKey: props.repoDid ? ['repo-by-did', props.repoDid] : ['repo-context', props.owner, props.name], + queryFn: async () => { + if (props.repoDid) { + return getRepoByDid(props.repoDid as Did); + } else if (props.owner && props.name) { + return getRepo(props.owner, props.name); + } + return null; + }, + enabled: Boolean(props.repoDid || (props.owner && props.name)), staleTime: 300_000, })); @@ -1669,28 +1686,35 @@ export const RepoCard: Component = (props) => { const starCountQuery = createQuery(() => ({ queryKey: ['repo-stars-count', repoContext()?.repoDid], queryFn: () => getRepoStarCount(repoContext()!), - enabled: !!repoContext(), + enabled: !!repoContext() && props.stars === undefined, + staleTime: 300_000, + })); + + const forkCountQuery = createQuery(() => ({ + queryKey: ['repo-fork-count', repoContext()?.repoDid], + queryFn: () => getRepoForkCount(repoContext()!), + enabled: !!repoContext() && props.forks === undefined, staleTime: 300_000, })); const issueCountQuery = createQuery(() => ({ queryKey: ['repo-issues-count', repoContext()?.repoDid], queryFn: () => getRepoIssueCount(repoContext()!), - enabled: !!repoContext(), + enabled: !!repoContext() && props.openIssues === undefined, staleTime: 300_000, })); const pullCountQuery = createQuery(() => ({ queryKey: ['repo-pulls-count', repoContext()?.repoDid], queryFn: () => getRepoPullCount(repoContext()!), - enabled: !!repoContext(), + enabled: !!repoContext() && props.openPRs === undefined, staleTime: 300_000, })); const languagesQuery = createQuery(() => ({ queryKey: ['repo-languages', repoContext()?.repoDid], queryFn: () => getRepoLanguages(repoContext()!, 'HEAD'), - enabled: !!repoContext(), + enabled: !!repoContext() && props.language === undefined, staleTime: 300_000, })); @@ -1708,18 +1732,74 @@ export const RepoCard: Component = (props) => { }; const stars = () => props.stars !== undefined ? props.stars : starCountQuery.data; + const forks = () => props.forks !== undefined ? props.forks : forkCountQuery.data; const openIssues = () => props.openIssues !== undefined ? props.openIssues : issueCountQuery.data; const openPRs = () => props.openPRs !== undefined ? props.openPRs : pullCountQuery.data; - const forks = () => props.forks; const isMetricsLoading = () => { - const langLoading = props.language === undefined && (languagesQuery.isLoading || repoContextQuery.isLoading); - const starsLoading = props.stars === undefined && (starCountQuery.isLoading || repoContextQuery.isLoading); - const issuesLoading = props.openIssues === undefined && (issueCountQuery.isLoading || repoContextQuery.isLoading); - const prsLoading = props.openPRs === undefined && (pullCountQuery.isLoading || repoContextQuery.isLoading); - return langLoading || starsLoading || issuesLoading || prsLoading; + const contextLoading = repoContextQuery.isLoading && (props.repoDid !== undefined || (props.owner !== undefined && props.name !== undefined)); + const langLoading = props.language === undefined && (languagesQuery.isLoading || contextLoading); + const starsLoading = props.stars === undefined && (starCountQuery.isLoading || contextLoading); + const forksLoading = props.forks === undefined && (forkCountQuery.isLoading || contextLoading); + const issuesLoading = props.openIssues === undefined && (issueCountQuery.isLoading || contextLoading); + const prsLoading = props.openPRs === undefined && (pullCountQuery.isLoading || contextLoading); + return langLoading || starsLoading || forksLoading || issuesLoading || prsLoading; }; + return ( + + + + + + + } + > +
+ +
+ + {resolvedLanguage()} +
+
+ 0}> +
+ + {stars()} +
+
+ 0}> +
+ + {forks()} +
+
+ 0}> +
+ + {openIssues()} +
+
+ 0}> +
+ + {openPRs()} +
+
+
+
+ ); +}; + +export const RepoCard: Component = (props) => { + const linkHref = () => props.href || `/${props.owner}/${props.name}`; + return (
= (props) => {
- - - - - - - } - > -
- -
- - {resolvedLanguage()} -
-
- 0}> -
- - {stars()} -
-
- 0}> -
- - {forks()} -
-
- 0}> -
- - {openIssues()} -
-
- 0}> -
- - {openPRs()} -
-
-
-
+ ); }; diff --git a/src/pages/search.tsx b/src/pages/search.tsx index 2b997b6..1535f09 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -17,6 +17,7 @@ import type { Did, ResourceUri } from '@atcute/lexicons/syntax'; import { For, Match, Show, Switch, createEffect, createMemo, createSignal, type Component, type JSX } from 'solid-js'; import { ErrorState, LoadingState, PaginationControls } from '../components/common'; +import { RepoStatsList } from '../components/repo'; import { getIssueRecord } from '../lib/api/issues'; import { getPullRecord } from '../lib/api/pulls'; import { getRepoByDid } from '../lib/api/repos'; @@ -109,17 +110,6 @@ const snippet = (value?: string, max = 220): string => { return `${normalized.slice(0, max - 1).trimEnd()}...`; }; -const collectionLabel = (nsid: SearchCollection): string => { - if (nsid === 'sh.tangled.repo') return 'repo'; - if (nsid === 'sh.tangled.repo.issue') return 'issue'; - if (nsid === 'sh.tangled.repo.pull') return 'pull'; - if (nsid === 'sh.tangled.repo.issue.comment') return 'issue comment'; - if (nsid === 'sh.tangled.repo.pull.comment') return 'pull comment'; - if (nsid === 'sh.tangled.actor.profile') return 'profile'; - if (nsid === 'sh.tangled.label.definition') return 'label'; - return 'string'; -}; - const SearchResultIcon: Component<{ hit: SearchHit }> = (props) => ( }> @@ -210,25 +200,26 @@ const CommentParentLink: Component<{ hit: SearchHit }> = (props) => { }); const parentQuery = createQuery(() => ({ queryKey: ['search-parent', props.hit.nsid, parentUri()], + enabled: Boolean(parentUri()), queryFn: async () => isIssueComment() - ? { kind: 'issue' as const, record: await getIssueRecord(parentUri()) } - : { kind: 'pull' as const, record: await getPullRecord(parentUri()) }, + ? { kind: 'issue' as const, record: await getIssueRecord(parentUri()!) } + : { kind: 'pull' as const, record: await getPullRecord(parentUri()!) }, staleTime: 300_000, })); return ( comment}> {(parent) => { - const repoDid = createMemo(() => parent().kind === 'issue' - ? (parent().record.value as { repo: Did }).repo - : (parent().record.value as { target: { repo: Did } }).target.repo); - return ( - - comment on {parent().kind} - - ); - }} - + const repoDid = createMemo(() => parent().kind === 'issue' + ? (parent().record.value as { repo: Did }).repo + : (parent().record.value as { target: { repo: Did } }).target.repo); + return ( + + comment on {parent().kind} + + ); + }} + ); }; @@ -297,12 +288,12 @@ const ResultTitle: Component<{ hit: SearchHit }> = (props) => { - + {title()} - + {title()} @@ -347,13 +338,9 @@ const SearchResultCard: Component<{ hit: SearchHit }> = (props) => {
-
- - {collectionLabel(props.hit.nsid)} -
- {props.hit.author.handle} + {props.hit.author.handle}
@@ -361,6 +348,9 @@ const SearchResultCard: Component<{ hit: SearchHit }> = (props) => { {formatRelativeTime(createdAt())}
+ + {(repoDid) => } + 0}> @@ -497,7 +487,7 @@ export const SearchPage: Component = () => {
-
+