updated overall design

This commit is contained in:
Ren Amamiya 2023-03-28 10:16:26 +07:00
parent a3ff254bc3
commit b0155bf334
14 changed files with 109 additions and 49 deletions

View File

@ -14,16 +14,7 @@ export default function AppHeader() {
<div data-tauri-drag-region className="flex h-full w-full flex-1 items-center px-2">
<AppActions />
<div data-tauri-drag-region className="flex h-full w-full items-center justify-between">
<div className="flex h-full items-center divide-x divide-zinc-900 px-4 py-px">
<div className="group inline-flex h-full w-24 items-center justify-center border-l border-zinc-900 hover:bg-zinc-900">
<span className="text-sm font-medium leading-none text-zinc-400 group-hover:text-zinc-100">Home</span>
</div>
<div className="inline-flex h-full w-16 items-center justify-center border-r border-zinc-900">
<button className="group inline-flex h-6 w-6 items-center justify-center rounded-md hover:bg-zinc-900">
<PlusIcon className="h-4 w-4 text-zinc-400 group-hover:text-zinc-100" />
</button>
</div>
</div>
<div className="flex h-full items-center divide-x divide-zinc-900 px-4 pt-px"></div>
<div>
<NoteConnector />
</div>

View File

@ -8,10 +8,12 @@ import { tagsToArray } from '@utils/transform';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { AvatarIcon, ExitIcon, GearIcon } from '@radix-ui/react-icons';
import { writeText } from '@tauri-apps/api/clipboard';
import destr from 'destr';
import { useAtomValue } from 'jotai';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { nip19 } from 'nostr-tools';
import { memo, useContext, useEffect, useRef } from 'react';
export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any }) {
@ -23,10 +25,14 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any }
const now = useRef(new Date());
const openProfile = () => {
const openProfilePage = () => {
router.push(`/users/${user.id}`);
};
const copyPublicKey = async () => {
await writeText(nip19.npubEncode(user.id));
};
useEffect(() => {
const unsubscribe = pool.subscribe(
[
@ -57,40 +63,51 @@ export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any }
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<button className="relative h-11 w-11 shrink rounded-lg ring-1 ring-fuchsia-500 ring-offset-2 ring-offset-black">
<Image src={userData.picture} alt="user's avatar" fill={true} className="rounded-lg object-cover" />
<button className="relative h-11 w-11 rounded-md">
<Image
src={userData.picture}
alt="user's avatar"
fill={true}
className="rounded-md object-cover"
placeholder="blur"
blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkqAcAAIUAgUW0RjgAAAAASUVORK5CYII="
priority
/>
</button>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content
className="min-w-[220px] rounded-lg bg-zinc-800 p-1.5 shadow-modal will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
className="min-w-[220px] rounded-md bg-zinc-900/80 p-1.5 shadow-input shadow-black/50 ring-1 ring-zinc-800 backdrop-blur-xl will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
side="right"
sideOffset={5}
align="start"
>
<DropdownMenu.Item
onClick={() => openProfile()}
className="group relative flex h-7 select-none items-center rounded-sm px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-500"
onClick={() => openProfilePage()}
className="group relative flex h-7 select-none items-center rounded-sm px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-800 data-[highlighted]:text-fuchsia-500"
>
<div className="absolute left-0 inline-flex w-6 items-center justify-center">
<AvatarIcon />
</div>
Open profile
</DropdownMenu.Item>
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-500">
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-800 data-[highlighted]:text-fuchsia-500">
Update profile
</DropdownMenu.Item>
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-500">
<DropdownMenu.Item
onClick={() => copyPublicKey()}
className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-800 data-[highlighted]:text-fuchsia-500"
>
Copy public key
</DropdownMenu.Item>
<DropdownMenu.Separator className="m-1 h-px bg-zinc-700/50" />
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-500">
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-800 data-[highlighted]:text-fuchsia-500">
<div className="absolute left-0 inline-flex w-6 items-center justify-center">
<GearIcon />
</div>
Settings
</DropdownMenu.Item>
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-500">
<DropdownMenu.Item className="group relative flex h-7 select-none items-center rounded px-1 pl-7 text-sm leading-none text-zinc-400 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-800 data-[highlighted]:text-fuchsia-500">
<div className="absolute left-0 inline-flex w-6 items-center justify-center">
<ExitIcon />
</div>

View File

@ -10,8 +10,8 @@ export const InactiveAccount = memo(function InactiveAccount({ user }: { user: a
};
return (
<button onClick={() => setCurrentUser()} className="relative h-11 w-11 shrink rounded-lg">
<Image src={userData.picture} alt="user's avatar" fill={true} className="rounded-lg object-cover" />
<button onClick={() => setCurrentUser()} className="relative h-11 w-11 shrink rounded-md">
<Image src={userData.picture} alt="user's avatar" fill={true} className="rounded-md object-cover" />
</button>
);
});

View File

@ -1,6 +1,7 @@
import AccountList from '@components/columns/account/list';
import LumeSymbol from '@assets/icons/Lume';
import { PlusIcon } from '@radix-ui/react-icons';
import { getVersion } from '@tauri-apps/api/app';
import Link from 'next/link';
@ -23,14 +24,14 @@ export default function AccountColumn() {
<div className="flex flex-col gap-4">
<Link
href="/explore"
className="group relative flex h-11 w-11 shrink cursor-pointer items-center justify-center overflow-hidden rounded-lg bg-zinc-900 hover:bg-zinc-800"
className="group relative flex h-11 w-11 shrink cursor-pointer items-center justify-center rounded-md bg-zinc-900 hover:bg-zinc-800"
>
<LumeSymbol className="h-6 w-auto text-zinc-400 group-hover:text-zinc-200" />
</Link>
<AccountList />
<Link
href="/onboarding"
className="group relative flex h-11 w-11 shrink cursor-pointer items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-zinc-600 hover:border-zinc-400"
className="group relative flex h-11 w-11 shrink cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-zinc-600 hover:border-zinc-400"
>
<PlusIcon className="h-4 w-4 text-zinc-400 group-hover:text-zinc-200" />
</Link>

View File

@ -3,7 +3,7 @@ import Newsfeed from '@components/columns/navigator/newsfeed';
export default function NavigatorColumn() {
return (
<div className="relative flex h-full flex-col gap-4 pt-4">
<div className="relative flex h-full flex-col gap-1 overflow-hidden pt-4">
{/* Newsfeed */}
<Newsfeed />
{/* Messages */}

View File

@ -1,14 +1,29 @@
import { MessageList } from '@components/columns/navigator/messages/list';
import { activeAccountAtom } from '@stores/account';
import { getAllFollowsByID } from '@utils/storage';
import * as Collapsible from '@radix-ui/react-collapsible';
import { TriangleUpIcon } from '@radix-ui/react-icons';
import { useState } from 'react';
import { useAtom } from 'jotai';
import { useEffect, useState } from 'react';
export default function Messages() {
const [open, setOpen] = useState(true);
const [follows, setFollows] = useState([]);
const [activeAccount] = useAtom(activeAccountAtom);
useEffect(() => {
getAllFollowsByID(activeAccount.id)
.then((res: any) => setFollows(res))
.catch(console.error);
}, [activeAccount.id]);
return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<div className="flex flex-col gap-1 px-2 pb-8">
<Collapsible.Trigger className="flex cursor-pointer items-center gap-2 rounded-md py-1 px-2 hover:bg-zinc-900">
<Collapsible.Root open={open} onOpenChange={setOpen} className="h-full shrink-0">
<div className="flex h-full flex-col gap-1 px-2 pb-8">
<Collapsible.Trigger className="flex cursor-pointer items-center gap-2 py-1 px-2">
<div
className={`inline-flex h-6 w-6 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''
@ -17,10 +32,12 @@ export default function Messages() {
<TriangleUpIcon className="h-4 w-4 text-zinc-500" />
</div>
<h3 className="bg-gradient-to-r from-red-300 via-pink-100 to-blue-300 bg-clip-text text-xs font-bold uppercase tracking-wide text-transparent">
Messages
Chats
</h3>
</Collapsible.Trigger>
<Collapsible.Content className="flex flex-col"></Collapsible.Content>
<Collapsible.Content className="h-full">
<MessageList data={follows} />
</Collapsible.Content>
</div>
</Collapsible.Root>
);

View File

@ -1,13 +1,33 @@
import { UserMini } from '@components/user/mini';
import { Key, memo } from 'react';
import { useVirtualizer } from '@tanstack/react-virtual';
import { Suspense, memo, useRef } from 'react';
export const MessageList = memo(function MessageList({ data }: { data: any }) {
const parentRef = useRef(null);
const virtualizer = useVirtualizer({
count: data.length,
estimateSize: () => 32,
getScrollElement: () => parentRef.current,
});
const items = virtualizer.getVirtualItems();
return (
<>
{data.map((item: { pubkey: string }, index: Key) => (
<UserMini key={index} pubkey={item.pubkey} />
))}
</>
<div ref={parentRef} className="scrollbar-hide h-full w-full overflow-y-auto" style={{ contain: 'strict' }}>
<Suspense fallback={<p className="text-sm text-zinc-400">Loading...</p>}>
{items.length > 0 && (
<div className="relative mb-24 w-full" style={{ height: virtualizer.getTotalSize() }}>
<div className="absolute top-0 left-0 w-full" style={{ transform: `translateY(${items[0].start}px)` }}>
{items.map((virtualRow) => (
<div key={virtualRow.key} data-index={virtualRow.index} ref={virtualizer.measureElement}>
<UserMini pubkey={data[virtualRow.index].pubkey} />
</div>
))}
</div>
</div>
)}
</Suspense>
</div>
);
});

View File

@ -10,7 +10,7 @@ export default function Newsfeed() {
return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<div className="flex flex-col gap-1 px-2">
<Collapsible.Trigger className="flex cursor-pointer items-center gap-2 rounded-md py-1 px-2 hover:bg-zinc-900">
<Collapsible.Trigger className="flex cursor-pointer items-center gap-2 py-1 px-2">
<div
className={`inline-flex h-6 w-6 transform items-center justify-center transition-transform duration-150 ease-in-out ${
open ? 'rotate-180' : ''

View File

@ -46,7 +46,7 @@ export default function FormBase() {
return (
<div className="p-3">
<div className="relative h-32 w-full shrink-0 overflow-hidden before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
<div className="relative h-32 w-full shrink-0 overflow-hidden before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-fuchsia-500 before:opacity-0 before:ring-2 before:ring-fuchsia-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-fuchsia-500/100 dark:focus-within:after:shadow-fuchsia-500/20">
<div>
<textarea
value={value}
@ -68,9 +68,9 @@ export default function FormBase() {
<button
onClick={() => submitEvent()}
disabled={value.length === 0 ? true : false}
className="inline-flex h-8 w-16 items-center justify-center rounded-md bg-fuchsia-500 px-4 text-sm font-medium shadow-md shadow-fuchsia-900/50 hover:bg-fuchsia-600 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50"
className="inline-flex h-8 w-16 items-center justify-center rounded-md bg-fuchsia-500 px-4 text-sm font-medium shadow-button hover:bg-fuchsia-600 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50"
>
<span className="text-white drop-shadow">Send</span>
Send
</button>
</div>
</div>

View File

@ -50,7 +50,7 @@ export default function FormComment({ eventID }: { eventID: any }) {
/>
</div>
</div>
<div className="relative h-24 w-full flex-1 overflow-hidden before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
<div className="relative h-24 w-full flex-1 overflow-hidden before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-fuchsia-500 before:opacity-0 before:ring-2 before:ring-fuchsia-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-fuchsia-500/100 dark:focus-within:after:shadow-fuchsia-500/20">
<div>
<textarea
name="content"
@ -66,9 +66,10 @@ export default function FormComment({ eventID }: { eventID: any }) {
<div className="flex items-center gap-2">
<button
onClick={() => submitEvent()}
className="inline-flex h-8 w-16 items-center justify-center rounded-md bg-fuchsia-500 px-4 text-sm font-medium shadow-md shadow-fuchsia-900/50 hover:bg-fuchsia-600"
disabled={value.length === 0 ? true : false}
className="inline-flex h-8 w-16 items-center justify-center rounded-md bg-fuchsia-500 px-4 text-sm font-medium shadow-button hover:bg-fuchsia-600 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50"
>
<span className="text-white drop-shadow">Send</span>
Send
</button>
</div>
</div>

View File

@ -30,7 +30,7 @@ export default function ImagePicker() {
<div>
<div className="flex flex-col gap-1">
<label className="text-sm font-semibold text-zinc-200">Image URL</label>
<div className="relative mb-1 shrink-0 before:pointer-events-none before:absolute before:-inset-px before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-1 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
<div className="relative mb-1 shrink-0 before:pointer-events-none before:absolute before:-inset-px before:rounded-[8px] before:border before:border-fuchsia-500 before:opacity-0 before:ring-1 before:ring-fuchsia-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-fuchsia-500/100 dark:focus-within:after:shadow-fuchsia-500/20">
<input
placeholder="https://..."
onKeyDown={handleEnter}

View File

@ -47,8 +47,11 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s
}, [fetchProfile, pubkey]);
return (
<div onClick={(e) => openUserPage(e)} className="group flex items-start gap-2">
<div className="relative h-11 w-11 shrink overflow-hidden rounded-md bg-zinc-900 ring-fuchsia-500 ring-offset-1 ring-offset-zinc-900 group-hover:ring-1">
<div className="group flex items-start gap-2">
<div
onClick={(e) => openUserPage(e)}
className="relative h-11 w-11 shrink overflow-hidden rounded-md bg-zinc-900 ring-fuchsia-500 ring-offset-1 ring-offset-zinc-900 group-hover:ring-1"
>
{profile?.picture ? (
<ImageWithFallback
src={profile.picture}
@ -69,7 +72,7 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s
<div className="flex w-full flex-1 items-start justify-between">
<div className="flex w-full justify-between">
<div className="flex items-baseline gap-2 text-sm">
<span className="font-bold leading-tight group-hover:underline">
<span onClick={(e) => openUserPage(e)} className="font-bold leading-tight group-hover:underline">
{profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')}
</span>
<span className="leading-tight text-zinc-500">·</span>

View File

@ -4,7 +4,11 @@ import WithSidebarLayout from '@layouts/withSidebar';
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
export default function Page() {
return <></>;
return (
<div className="flex h-full w-full items-center justify-center">
<p className="text-sm text-zinc-400">Sorry, this feature under development, it will come in the next version</p>
</div>
);
}
Page.getLayout = function getLayout(

View File

@ -28,6 +28,12 @@ module.exports = {
0 2px 2px rgb(4 4 7 / 45%),
0 8px 24px rgb(4 4 7 / 60%)
`,
button: `
rgba(112, 26, 117, 0.5) 0px 2px 8px,
rgb(112, 26, 117) 0px 2px 4px,
rgb(112, 26, 117) 0px 0px 0px 1px,
rgba(255, 255, 255, 0.2) 0px 0px 0px 1px inset
`,
},
backgroundColor: {
'near-black': '#07070d',