added current user profile to navigatorbar

This commit is contained in:
Ren Amamiya
2023-02-24 10:34:47 +07:00
parent f6d687cec9
commit 745c9141a0
9 changed files with 519 additions and 15 deletions

View File

@@ -1,16 +1,36 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import ActiveLink from '@components/activeLink';
import CreatePost from '@components/navigatorBar/createPost';
import { ProfileMenu } from '@components/navigatorBar/profileMenu';
import { truncate } from '@utils/truncate';
import { currentUser } from '@stores/currentUser';
import { useStore } from '@nanostores/react';
import { PlusIcon } from '@radix-ui/react-icons';
export default function NavigatorBar() {
const $currentUser: any = useStore(currentUser);
const profile = JSON.parse($currentUser.metadata);
return (
<div className="flex h-full flex-col flex-wrap justify-between overflow-hidden px-2 pt-3 pb-4">
{/* main */}
<div className="flex flex-col gap-4">
{/* Create post */}
<div className="flex flex-col rounded-lg bg-zinc-900 ring-1 ring-white/10">
<div className="flex flex-col p-2">
<div className="flex items-center justify-between">
<h5 className="font-semibold leading-tight text-zinc-100">
{profile.display_name || profile.name}
</h5>
<ProfileMenu pubkey={$currentUser.pubkey} />
</div>
<span className="text-sm leading-tight text-zinc-500">
@{profile.username || truncate($currentUser.pubkey, 16, ' .... ')}
</span>
</div>
<div className="p-2">
<CreatePost />
</div>
@@ -28,15 +48,15 @@ export default function NavigatorBar() {
<div className="flex flex-col gap-1 text-zinc-500">
<ActiveLink
href={`/feed/following`}
activeClassName="rounded-lg ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
className="flex h-10 items-center gap-1 px-2.5 text-sm font-medium">
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900">
<span>#</span>
<span>following</span>
</ActiveLink>
<ActiveLink
href={`/feed/global`}
activeClassName="rounded-lg ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
className="flex h-10 items-center gap-1 px-2.5 text-sm font-medium">
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900">
<span>#</span>
<span>global</span>
</ActiveLink>

View File

@@ -0,0 +1,48 @@
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { DotsHorizontalIcon } from '@radix-ui/react-icons';
import { writeText } from '@tauri-apps/api/clipboard';
import { useRouter } from 'next/router';
import { nip19 } from 'nostr-tools';
import { memo } from 'react';
export const ProfileMenu = memo(function ProfileMenu({ pubkey }: { pubkey: string }) {
const router = useRouter();
const viewProfile = () => {
router.push(`/profile/${pubkey}`);
};
const copyPubkey = async () => {
const npub = nip19.npubEncode(pubkey);
await writeText(npub);
};
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<button className="rounded-lg p-1 hover:bg-zinc-800">
<DotsHorizontalIcon className="h-4 w-4 text-zinc-300" />
</button>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content
className="min-w-[220px] rounded-md border border-white/20 bg-zinc-800 p-1 shadow-lg shadow-black/30 will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
sideOffset={2}>
<DropdownMenu.Item
onClick={() => viewProfile()}
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
View profile
</DropdownMenu.Item>
<DropdownMenu.Item
onClick={() => copyPubkey()}
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
Copy public key
</DropdownMenu.Item>
<DropdownMenu.Item className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
Log out
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
);
});

View File

@@ -0,0 +1,35 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import BaseLayout from '@layouts/baseLayout';
import { GetStaticPaths } from 'next';
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
export default function Page({ pubkey }: { pubkey: string }) {
return <div>{pubkey}</div>;
}
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
};
};
export async function getStaticProps(context) {
const pubkey = context.params.pubkey;
return {
props: { pubkey },
};
}
Page.getLayout = function getLayout(
page:
| string
| number
| boolean
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
| ReactFragment
| ReactPortal
) {
return <BaseLayout>{page}</BaseLayout>;
};