Skip to content

Commit

Permalink
wip: impl UI and fix errors
Browse files Browse the repository at this point in the history
  • Loading branch information
yamader committed Mar 15, 2024
1 parent cf65700 commit a17a97d
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 27 deletions.
8 changes: 2 additions & 6 deletions src/app/(main)/(narrow)/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
"use client"

import { Loader2 } from "lucide-react"
import BottomSpinner from "~/components/BottomSpinner"
import { useBottom } from "~/features/common"
import NotePreview from "~/features/note/NotePreview"
import { useTL } from "~/features/timeline"
import TLSwitch from "~/features/timeline/TLSwitch"

// todo: TLの切り替え
export default function HomePage() {
const { notes, more } = useTL()
useBottom(more)
Expand All @@ -21,10 +20,7 @@ export default function HomePage() {
</div>
))}
</div>
<div className="mx-auto mb-8 mt-6 flex items-center gap-1 font-bold">
<Loader2 className="animate-spin" size={24} />
<p className="text-center">Loading...</p>
</div>
<BottomSpinner />
</>
)
}
4 changes: 3 additions & 1 deletion src/app/(main)/(narrow)/notifications/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client"

import BottomSpinner from "~/components/BottomSpinner"
import { useBottom } from "~/features/common"
import { useNotifications } from "~/features/notifications"
import Notice from "~/features/notifications/Notice"
Expand All @@ -10,11 +11,12 @@ export default function NotificationsPage() {
useBottom(more)
return (
<>
<div className="flex flex-col bg-white rounded-xl">
<div className="flex flex-col rounded-xl bg-white">
{notifications.map(notice => {
return <Notice notice={notice} key={notice.id} />
})}
</div>
<BottomSpinner />
</>
)
}
49 changes: 39 additions & 10 deletions src/app/(main)/(narrow)/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
import { Tooltip } from "@radix-ui/themes"
import { useSearchParams } from "next/navigation"
import { Suspense, use } from "react"
import Anon from "~/assets/anon.png"
import BottomSpinner from "~/components/BottomSpinner"
import IdStr from "~/components/IdStr"
import TopAppBar from "~/components/TopAppBar"
import { useAPI } from "~/features/api"
import { Note, User } from "~/features/api/clients/entities"
import { useAccount } from "~/features/auth"
import NotePreview from "~/features/note/NotePreview"
import { statusEmoji } from "~/features/profile"
import UserIcon from "~/features/profile/UserIcon"
import { hostname } from "~/utils"

export default function ProfilePage() {
return (
Expand All @@ -20,7 +24,6 @@ export default function ProfilePage() {
function ProfileFetch() {
const api = useAPI()
const searchParams = useSearchParams()
const account = useAccount()

if (!api) return <ProfileContent />

Expand All @@ -34,8 +37,9 @@ function ProfileFetch() {
userFetch = api.me()
}
const user = use(userFetch)
if (user) user.host ??= hostname(api.host)

const notesFetch = user && api.notes(user.id)
const notesFetch = user && api.userNotes(user.id)
const notes = (notesFetch && use(notesFetch)) ?? []

return <ProfileContent user={user} notes={notes} />
Expand All @@ -46,19 +50,44 @@ function ProfileContent({ user = null, notes = [] }: { user?: User | null; notes

return (
<>
<div className="relative h-fit w-fit rounded-full border-4 bg-white p-2">
<div className="h-36 w-36 rounded-full border-4">
<UserIcon user={user} />
<TopAppBar
content={
<div>
<p className="text-lg font-bold">{user?.name}</p>
</div>
}
back
/>
<div className="min-h-48 w-full bg-black" />
<div className="-mb-20 ml-4 h-fit w-fit -translate-y-1/2">
{/* todo: grow */}
<div className="h-36 w-36 overflow-hidden rounded-[100%] border-4 transition-all hover:rounded-xl">
<img className="h-full w-full object-cover" src={user?.avatarUrl ?? Anon.src} />
</div>
<div className="absolute bottom-1.5 right-1.5 flex h-11 w-11 rounded-full border-4 bg-white">
<div className="absolute bottom-2 right-2 flex">
<Tooltip content={onlineStatus}>
<span className="m-auto cursor-default text-3xl leading-none">
<span className="cursor-default text-3xl leading-none">
{statusEmoji(onlineStatus)}
</span>
</Tooltip>
{JSON.stringify(notes)}
</div>
</div>
{user ? (
<div className="p-4">
<div className="text-2xl font-bold">{user.name}</div>
<div className="text-sm">
<IdStr username={user.username} host={user.host!} />
</div>
</div>
) : (
<div className="animate-pulse p-4">dummy</div>
)}
<div className="flex flex-col gap-px bg-gray-200 py-px">
{notes.map(note => (
<NotePreview note={note as any} key={note.id} />
))}
</div>
<BottomSpinner />
</>
)
}
10 changes: 10 additions & 0 deletions src/components/BottomSpinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Loader2 } from "lucide-react"

export default function BottomSpinner() {
return (
<div className="mx-auto flex items-center justify-center gap-1 py-4 font-bold">
<Loader2 className="animate-spin" size={24} />
<p>Loading...</p>
</div>
)
}
26 changes: 26 additions & 0 deletions src/components/TopAppBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use client"

import { Tooltip } from "@radix-ui/themes"
import { ArrowLeft } from "lucide-react"
import Link from "next/link"
import { useRouter } from "next/navigation"

export default function TopAppBar({ content, back }: { content: React.ReactNode; back?: boolean }) {
const router = useRouter()

return (
<div className="flex min-h-12 items-center border-b px-2">
{back && (
<Tooltip content="戻る">
<Link
className="mr-5 rounded-full p-2 hover:bg-neutral-100"
href="/home/"
onClick={router.back}>
<ArrowLeft className="text-neutral-600" size={18} />
</Link>
</Tooltip>
)}
{content}
</div>
)
}
4 changes: 2 additions & 2 deletions src/features/api/clients/misskey-latest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ export default class MisskeyLatestClient extends BaseClient {
* @param opts - オプション
* @returns
*/
async notes(userId: string, opts: NotesOpts = {}) {
return this.post<NotesResponse>("notes", {
async userNotes(userId: string, opts: NotesOpts = {}) {
return this.post<NotesResponse>("users/notes", {
body: { userId, ...opts },
})
}
Expand Down
4 changes: 2 additions & 2 deletions src/features/api/clients/misskey-v12.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Emoji } from ".."
import { Emoji } from "../types"
import MisskeyLatestClient from "./misskey-latest"

export default class MisskeyV12Client extends MisskeyLatestClient {
id = "misskey-v12"

override async emojiUrl(name: string): Promise<string | null> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { emojis } = await super.post<any>("meta")
const { emojis } = await super.post<any>("meta", {})
return emojis?.find?.((e: Record<keyof Emoji, unknown>) => e.name == name)?.url ?? null
}
}
4 changes: 2 additions & 2 deletions src/features/api/clients/misskey-v13.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Emoji } from ".."
import { Emoji } from "../types"
import MisskeyLatestClient from "./misskey-latest"

export default class MisskeyV13Client extends MisskeyLatestClient {
id = "misskey-v13"

override async emojiUrl(name: string): Promise<string | null> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { emojis } = await super.get<any>("emojis")
const { emojis } = await super.get<any>("emojis", {})
return emojis?.find?.((e: Record<keyof Emoji, unknown>) => e.name == name)?.url ?? null
}
}
2 changes: 1 addition & 1 deletion src/features/note/NotePreview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function NotePreview({ note }: NotePreviewProps) {

return (
<CustomEmojiCtx.Provider value={{ host }}>
<div className="rounded-xl bg-white p-3 shadow">
<div className="bg-white p-3">
{renotebar}
<div className="flex gap-1.5">
{/* アイコン */}
Expand Down
2 changes: 1 addition & 1 deletion src/features/timeline/TLSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client"

import { ReactNode } from "react"
import { TLChanNames } from "~/features/api/types"
import { useTLName } from "."
import { TLChanNames } from "../api"

const TLButton = ({ tl, children }: { tl: TLChanNames; children: ReactNode }) => {
const [currentTl, setCurrentTl] = useTLName()
Expand Down
4 changes: 2 additions & 2 deletions src/features/timeline/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { atom, useAtom, useAtomValue, useSetAtom } from "jotai"
import { atomWithStorage } from "jotai/utils"
import { entities } from "misskey-js"
import { useCallback, useEffect, useState } from "react"

import { TLChanNameToAPIEndpoint, TLChanNames, useMisskeyJS, useStream } from "~/features/api"
import { useMisskeyJS, useStream } from "~/features/api"
import { TLChanNameToAPIEndpoint, TLChanNames } from "~/features/api/types"
import { useLogin } from "~/features/auth"

////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit a17a97d

Please sign in to comment.