Skip to content

Commit

Permalink
Merge branch 'preview'
Browse files Browse the repository at this point in the history
  • Loading branch information
pdelfan committed Nov 20, 2024
2 parents 67731e8 + c3afba6 commit 79a3840
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/app/dashboard/feeds/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function Page(props: Props) {
<Search placeholder="Search for feeds" />
</div>
</div>
<Suspense key={query} fallback={<FeedListSkeleton />}>
<Suspense key={query} fallback={<FeedListSkeleton rounded={true} />}>
<FeedList query={query} />
</Suspense>
</div>
Expand Down
15 changes: 10 additions & 5 deletions src/components/contentDisplay/feedItem/FeedItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import { getAgentFromClient } from "@/lib/api/bsky/agent";

interface Props {
feedItem: GeneratorView;
saved: boolean;
saved?: boolean;
rounded?: boolean;
}

export default function FeedItem(props: Props) {
const { feedItem, saved } = props;
const { feedItem, saved, rounded = true } = props;
const { avatar, displayName, description, likeCount, creator } = feedItem;
const [isSaved, setIsSaved] = useState(saved);
const router = useRouter();
Expand All @@ -45,11 +46,13 @@ export default function FeedItem(props: Props) {
<Link
href={{
pathname: `/dashboard/feeds/${encodeURIComponent(
feedItem.uri.split(":")[3].split("/")[0],
feedItem.uri.split(":")[3].split("/")[0]
)}`,
query: { uri: feedItem.uri },
}}
className="border-skin-base hover:bg-skin-secondary flex flex-col gap-2 border border-x-0 p-3 last:border-b md:border-x md:first:rounded-t-2xl md:last:rounded-b-2xl odd:[&:not(:last-child)]:border-b-0 even:[&:not(:last-child)]:border-b-0"
className={`border-skin-base hover:bg-skin-secondary flex flex-col gap-2 border border-x-0 p-3 last:border-b md:border-x ${
rounded && "md:first:rounded-t-2xl"
} md:last:rounded-b-2xl odd:[&:not(:last-child)]:border-b-0 even:[&:not(:last-child)]:border-b-0`}
>
<div className="flex flex-wrap items-center justify-between gap-3">
<div className="flex flex-wrap items-center gap-3">
Expand All @@ -58,7 +61,9 @@ export default function FeedItem(props: Props) {
alt={displayName}
width={40}
height={40}
className={`rounded-lg ${!avatar && "border-skin-base bg-skin-muted border"}`}
className={`rounded-lg ${
!avatar && "border-skin-base bg-skin-muted border"
}`}
/>
<div className="flex flex-col">
<h2 className="text-skin-base break-words font-semibold">
Expand Down
2 changes: 1 addition & 1 deletion src/components/contentDisplay/feedList/FeedList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default async function FeedList(props: Props) {
<FeedItem
key={feed.cid}
feedItem={feed}
saved={savedFeeds.some((savedFeed) => savedFeed.uri === feed.uri)}
saved={savedFeeds.some((savedFeed) => savedFeed.uri === feed.uri)}
/>
))}
{popularFeeds.length === 0 && (
Expand Down
42 changes: 27 additions & 15 deletions src/components/contentDisplay/feedList/FeedListSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
function Skeleton() {
interface Props {
rounded?: boolean;
}

function Skeleton(props: Props) {
const { rounded = false } = props;

return (
<article className="border-skin-base flex flex-col gap-2 border border-x-0 p-3 last:border-b md:border-x md:first:rounded-t-2xl md:last:rounded-b-2xl odd:[&:not(:last-child)]:border-b-0 even:[&:not(:last-child)]:border-b-0">
<article
className={`border-skin-base flex flex-col gap-2 border border-x-0 p-3 last:border-b md:border-x ${
rounded && "md:first:rounded-t-2xl"
} md:last:rounded-b-2xl odd:[&:not(:last-child)]:border-b-0 even:[&:not(:last-child)]:border-b-0`}
>
<div className="flex flex-wrap items-center gap-3">
<div className="bg-skin-muted h-10 w-10 rounded-lg" />
<div className="flex flex-col gap-3">
Expand All @@ -16,21 +26,23 @@ function Skeleton() {
);
}

export default function FeedListSkeleton() {
export default function FeedListSkeleton(props: Props) {
const { rounded = false } = props;

return (
<section className="flex flex-col">
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
<Skeleton rounded={rounded} />
</section>
);
}
16 changes: 12 additions & 4 deletions src/components/contentDisplay/searchList/SearchList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ import UserSearchContainer from "@/containers/search/UserSearchContainer";
import { useSession } from "next-auth/react";
import Tabs from "@/components/navigational/tabs/Tabs";
import TabItem from "@/components/navigational/tabs/TabItem";
import FeedSearchContainer from "@/containers/search/FeedSearchContainer";

interface Props {
query: string;
}

export default function SearchList(props: Props) {
const { query } = props;
const [currentTab, setCurrentTab] = useState<"top" | "latest" | "users">(
"top",
);
const [currentTab, setCurrentTab] = useState<
"top" | "latest" | "users" | "feeds"
>("top");
const { data: session } = useSession();

const handleTabChange = (tab: "top" | "latest" | "users") => {
const handleTabChange = (tab: "top" | "latest" | "users" | "feeds") => {
setCurrentTab(tab);
};

Expand Down Expand Up @@ -51,6 +52,12 @@ export default function SearchList(props: Props) {
label="Users"
isActive={currentTab === "users"}
/>
<TabItem
asButton
onClick={() => handleTabChange("feeds")}
label="Feeds"
isActive={currentTab === "feeds"}
/>
</Tabs>

{currentTab === "latest" && (
Expand All @@ -60,6 +67,7 @@ export default function SearchList(props: Props) {
<PostSearchContainer query={onSearchPost(query)} sort={currentTab} />
)}
{currentTab === "users" && <UserSearchContainer query={query} />}
{currentTab === "feeds" && <FeedSearchContainer query={query} />}
</section>
);
}
41 changes: 41 additions & 0 deletions src/containers/search/FeedSearchContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import { getPopularFeeds } from "@/lib/api/bsky/feed";
import { useQuery } from "@tanstack/react-query";
import FeedAlert from "@/components/feedback/feedAlert/FeedAlert";
import { getAgentFromClient } from "@/lib/api/bsky/agent";
import FeedListSkeleton from "@/components/contentDisplay/feedList/FeedListSkeleton";
import FeedItem from "@/components/contentDisplay/feedItem/FeedItem";

interface Props {
query: string;
}

export default function FeedSearchContainer(props: Props) {
const { query } = props;
const { data: feeds, isFetching } = useQuery({
queryKey: ["searchFeeds", query],
queryFn: async () => {
const agent = await getAgentFromClient();
return getPopularFeeds(query, agent);
},
});

const isEmpty = !isFetching && feeds?.length === 0;

return (
<section>
{feeds &&
feeds.map((feed) => (
<FeedItem key={feed.cid} feedItem={feed} rounded={false} />
))}

{isEmpty && (
<div className="border-skin-base border-t">
<FeedAlert variant="empty" message={`No feeds found for ${query}`} />
</div>
)}
{isFetching && <FeedListSkeleton />}
</section>
);
}
4 changes: 2 additions & 2 deletions src/lib/api/bsky/feed/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { type Agent, AppBskyActorDefs } from "@atproto/api";
import { getAgentFromServer } from "../agent";
import { SavedFeed } from "../../../../../types/feed";

export const getPopularFeeds = async (search?: string) => {
const agent = await getAgentFromServer();
export const getPopularFeeds = async (search?: string, agent?: Agent) => {
if (!agent) agent = await getAgentFromServer();
const popularFeeds = await agent.app.bsky.unspecced.getPopularFeedGenerators({
query: search,
});
Expand Down

0 comments on commit 79a3840

Please sign in to comment.