Skip to content

Commit

Permalink
feat: profiles page
Browse files Browse the repository at this point in the history
  • Loading branch information
DIYgod committed Jul 9, 2024
1 parent 7a6bc2f commit ddb1cd9
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 68 deletions.
1 change: 1 addition & 0 deletions src/renderer/src/components/feed-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function FeedIcon({
return (
<Image
src={image}
loading="lazy"
className={cn("mr-2 shrink-0 rounded-sm", className)}
style={{
width: size,
Expand Down
9 changes: 5 additions & 4 deletions src/renderer/src/hono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ declare const routes: hono_hono_base.HonoBase<hono_types.BlankEnv, {
view: number;
feedId: string;
category: string | null;
isPrivate: boolean | null;
isPrivate: boolean;
} | undefined;
};
};
Expand Down Expand Up @@ -882,6 +882,7 @@ declare const routes: hono_hono_base.HonoBase<hono_types.BlankEnv, {
$get: {
input: {
query: {
userId?: string | undefined;
view?: string | undefined;
};
};
Expand Down Expand Up @@ -909,7 +910,7 @@ declare const routes: hono_hono_base.HonoBase<hono_types.BlankEnv, {
ownerUserId: string | null;
};
category: string | null;
isPrivate: boolean | null;
isPrivate: boolean;
}[];
};
outputFormat: "json";
Expand All @@ -921,7 +922,7 @@ declare const routes: hono_hono_base.HonoBase<hono_types.BlankEnv, {
view: number;
url: string;
category?: string | null | undefined;
isPrivate?: boolean | null | undefined;
isPrivate?: boolean | undefined;
};
};
output: {
Expand Down Expand Up @@ -949,7 +950,7 @@ declare const routes: hono_hono_base.HonoBase<hono_types.BlankEnv, {
view: number;
feedId: string;
category?: string | null | undefined;
isPrivate?: boolean | null | undefined;
isPrivate?: boolean | undefined;
};
};
output: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export function Component() {
{feed.data.feed.title}
{" "}
|
{" "}
{APP_NAME}
</title>
</Helmet>
Expand Down Expand Up @@ -98,8 +99,6 @@ export function Component() {
<a className="mb-8" href={`${DEEPLINK_SCHEME}add?id=${id}`}>
<StyledButton>
<FollowIcon className="mr-1 size-3" />
follow on
{" "}
{APP_NAME}
</StyledButton>
</a>
Expand Down
115 changes: 115 additions & 0 deletions src/renderer/src/pages/(external)/(with-layout)/profile/[id]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { FeedIcon } from "@renderer/components/feed-icon"
import { FollowIcon } from "@renderer/components/icons/follow"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@renderer/components/ui/avatar"
import { StyledButton } from "@renderer/components/ui/button"
import { useAuthQuery } from "@renderer/hooks/common"
import { apiClient } from "@renderer/lib/api-fetch"
import { APP_NAME } from "@renderer/lib/constants"
import { defineQuery } from "@renderer/lib/defineQuery"
import { capitalizeFirstLetter } from "@renderer/lib/utils"
import { DEEPLINK_SCHEME } from "@shared/constants"
import { Helmet } from "react-helmet-async"
import { useParams } from "react-router-dom"
import { parse } from "tldts"

export function Component() {
const { id } = useParams()

const user = useAuthQuery(defineQuery(["profiles", id], async () => {
const res = await apiClient.profiles.$get({
query: { id: id! },
})
return res.data
}), {
enabled: !!id,
})

const subscriptions = useAuthQuery(defineQuery(["subscriptions", user.data?.id], async () => {
const res = await apiClient.subscriptions.$get({
query: { userId: user.data?.id },
})
const groupFolder = {} as Record<string, typeof res.data>

for (const subscription of (res.data || [])) {
if (!subscription.category && subscription.feeds) {
const { siteUrl } = subscription.feeds
if (!siteUrl) continue
const parsed = parse(siteUrl)
parsed.domain &&
(subscription.category = capitalizeFirstLetter(parsed.domain))
}
if (subscription.category) {
if (!groupFolder[subscription.category]) {
groupFolder[subscription.category] = []
}
groupFolder[subscription.category].push(subscription)
}
}

return groupFolder
}), {
enabled: !!user.data?.id,
})

return (
<>
{user.data && (
<div className="mx-auto mt-12 flex max-w-5xl flex-col items-center justify-center p-4 lg:p-0">
<Helmet>
<title>
{user.data.name}
{" "}
|
{" "}
{APP_NAME}
</title>
</Helmet>
<Avatar className="aspect-square size-16">
<AvatarImage src={user.data.image || undefined} />
<AvatarFallback>{user.data.name?.slice(0, 2)}</AvatarFallback>
</Avatar>
<div className="flex flex-col items-center">
<div className="mb-2 mt-4 flex items-center text-2xl font-bold">
<h1>{user.data.name}</h1>
</div>
<div className="mb-8 text-sm text-zinc-500">
{user.data.handle}
</div>
</div>
<div className="mb-12 w-96 space-y-10">
{Object.keys(subscriptions.data || {}).map((category) => (
<div key={category}>
<div className="mb-4 flex items-center text-2xl font-bold">
<h3>{category}</h3>
</div>
<div>
{subscriptions.data?.[category].map((subscription) => (
<div key={subscription.feedId} className="group relative border-b py-5">
<a className="flex flex-1" href={subscription.feeds.siteUrl!} target="_blank">
<FeedIcon feed={subscription.feeds} size={22} className="mr-3" />
<div className="flex-1">
<div className="truncate font-medium leading-none">{subscription.feeds?.title}</div>
<div className="mt-1 line-clamp-1 text-xs text-zinc-500">{subscription.feeds?.description}</div>
</div>
</a>
<a className="absolute left-full top-5 opacity-0 transition-opacity group-hover:opacity-100" href={`${DEEPLINK_SCHEME}add?id=${subscription.feeds?.id}`}>
<StyledButton>
<FollowIcon className="mr-1 size-3" />
{APP_NAME}
</StyledButton>
</a>
</div>
))}
</div>
</div>
))}
</div>
</div>
)}
</>
)
}
62 changes: 0 additions & 62 deletions src/renderer/src/pages/(main)/(layer)/(subview)/profile/index.tsx

This file was deleted.

0 comments on commit ddb1cd9

Please sign in to comment.