wip: update browse user screen

This commit is contained in:
Ren Amamiya 2023-09-24 15:42:49 +07:00
parent 41b12746a7
commit c049fa8865
8 changed files with 128 additions and 27 deletions

View File

@ -18,6 +18,7 @@
"**/*.{ts, tsx, css, md, html, json}": "prettier --cache --write"
},
"dependencies": {
"@dnd-kit/core": "^6.0.8",
"@getalby/sdk": "^2.4.0",
"@nostr-dev-kit/ndk": "^1.2.1",
"@nostr-fetch/adapter-ndk": "^0.12.2",
@ -57,6 +58,7 @@
"react-router-dom": "^6.16.0",
"react-textarea-autosize": "^8.5.3",
"react-virtuoso": "^4.6.0",
"react-zoom-pan-pinch": "^3.1.0",
"remark-gfm": "^3.0.1",
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql#v1",
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#v1",

View File

@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false
dependencies:
'@dnd-kit/core':
specifier: ^6.0.8
version: 6.0.8(react-dom@18.2.0)(react@18.2.0)
'@getalby/sdk':
specifier: ^2.4.0
version: 2.4.0
@ -122,6 +125,9 @@ dependencies:
react-virtuoso:
specifier: ^4.6.0
version: 4.6.0(react-dom@18.2.0)(react@18.2.0)
react-zoom-pan-pinch:
specifier: ^3.1.0
version: 3.1.0(react-dom@18.2.0)(react@18.2.0)
remark-gfm:
specifier: ^3.0.1
version: 3.0.1
@ -374,6 +380,37 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
/@dnd-kit/accessibility@3.0.1(react@18.2.0):
resolution: {integrity: sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==}
peerDependencies:
react: '>=16.8.0'
dependencies:
react: 18.2.0
tslib: 2.6.2
dev: false
/@dnd-kit/core@6.0.8(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
'@dnd-kit/accessibility': 3.0.1(react@18.2.0)
'@dnd-kit/utilities': 3.2.1(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
tslib: 2.6.2
dev: false
/@dnd-kit/utilities@3.2.1(react@18.2.0):
resolution: {integrity: sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==}
peerDependencies:
react: '>=16.8.0'
dependencies:
react: 18.2.0
tslib: 2.6.2
dev: false
/@emotion/babel-plugin@11.11.0:
resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==}
dependencies:
@ -5407,6 +5444,17 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
/react-zoom-pan-pinch@3.1.0(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-a3LlP8QPgTikvteCNkZ3X6wIWC0lrg1geP5WkUJyx2MXXAhHQek3r17N1nT/esOiWGuPIECnsd9AGoK8jOeGcg==}
engines: {node: '>=8', npm: '>=5'}
peerDependencies:
react: '*'
react-dom: '*'
dependencies:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}

View File

@ -1,10 +1,10 @@
import { useDraggable } from '@dnd-kit/core';
import * as Dialog from '@radix-ui/react-dialog';
import { memo, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useStorage } from '@libs/storage/provider';
import { PlusIcon } from '@shared/icons';
import { Image } from '@shared/image';
import { NIP05 } from '@shared/nip05';
import { TextNote } from '@shared/notes';
@ -18,9 +18,19 @@ export const UserDrawer = memo(function UserDrawer({ pubkey }: { pubkey: string
const { db } = useStorage();
const { status, user } = useProfile(pubkey);
const { addContact, removeContact } = useNostr();
const { attributes, listeners, setNodeRef, transform } = useDraggable({
id: pubkey,
});
const [followed, setFollowed] = useState(false);
const style = transform
? {
transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
zIndex: 20,
}
: undefined;
const followUser = (pubkey: string) => {
try {
addContact(pubkey);
@ -51,26 +61,20 @@ export const UserDrawer = memo(function UserDrawer({ pubkey }: { pubkey: string
return (
<Dialog.Root>
<div className="group relative">
<Dialog.Trigger asChild>
<button type="button" className="relative z-10">
<User pubkey={pubkey} variant="avatar" />
</button>
</Dialog.Trigger>
<div className="absolute -bottom-14 left-0 flex flex-col opacity-0 transition-all duration-300 ease-smooth group-hover:-bottom-16 group-hover:opacity-100">
<div className="mt-4">
<button
type="button"
className="inline-flex h-12 w-12 items-center justify-center rounded-lg bg-white/10 backdrop-blur-xl hover:bg-white/20"
>
<PlusIcon className="h-4 w-4 text-white" />
</button>
</div>
</div>
</div>
<Dialog.Trigger asChild>
<button
type="button"
ref={setNodeRef}
style={style}
{...listeners}
{...attributes}
>
<User pubkey={pubkey} variant="avatar" />
</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Content className="fixed right-0 top-0 z-50 flex h-full w-[400px] items-center justify-center px-4 pb-4 pt-16">
<div className="h-full w-full overflow-y-auto rounded-lg border-t border-white/10 bg-white/20 px-3 py-3 backdrop-blur-xl">
<div className="h-full w-full overflow-y-auto rounded-lg border-t border-white/10 bg-white/20 px-3 py-3 backdrop-blur-3xl">
{status === 'loading' ? (
<div>
<p>Loading...</p>

View File

@ -0,0 +1,22 @@
import { useDroppable } from '@dnd-kit/core';
import { twMerge } from 'tailwind-merge';
import { PlusIcon } from '@shared/icons';
export function UserDropable() {
const { isOver, setNodeRef } = useDroppable({
id: 'newBlock',
});
return (
<div
ref={setNodeRef}
className={twMerge(
'inline-flex h-12 w-12 items-center justify-center rounded-lg border-t border-white/10 backdrop-blur-xl',
isOver ? 'bg-fuchsia-500' : 'bg-white/20 hover:bg-white/30'
)}
>
<PlusIcon className="h-4 w-4 text-white" />
</div>
);
}

View File

@ -37,7 +37,7 @@ export function BrowseScreen() {
<div className="absolute z-10 h-full w-full">
<DotsPattern className="h-full w-full text-white/10" />
</div>
<div className="relative z-20">
<div className="relative z-20 h-full w-full">
<Outlet />
</div>
</div>

View File

@ -1,6 +1,8 @@
import { DndContext } from '@dnd-kit/core';
import { useMemo } from 'react';
import { UserDrawer } from '@app/browse/components/userDrawer';
import { UserDropable } from '@app/browse/components/userDropable';
import { useStorage } from '@libs/storage/provider';
@ -10,16 +12,31 @@ import { getMultipleRandom } from '@utils/transform';
export function BrowseUsersScreen() {
const { db } = useStorage();
const data = useMemo(() => getMultipleRandom(db.account.follows, 10), []);
const handleDragEnd = (event) => {
console.log(event.id);
};
return (
<div>
<User pubkey={db.account.pubkey} variant="avatar" />
<div className="flex items-center gap-4">
{data.map((user) => (
<UserDrawer key={user} pubkey={user} />
))}
<DndContext onDragEnd={handleDragEnd}>
<div className="scrollbar-hide flex h-full w-full flex-col items-center justify-center overflow-x-auto overflow-y-auto">
<div className="flex items-center gap-16">
<div className="flex flex-col gap-1">
<h3 className="text-sm font-semibold text-fuchsia-500">Follows</h3>
<div className="grid grid-cols-5 gap-6 rounded-lg border border-fuchsia-500/50 bg-fuchsia-500/10 p-4">
{data.map((user) => (
<UserDrawer key={user} pubkey={user} />
))}
</div>
</div>
<div className="flex items-center gap-16">
<User pubkey={db.account.pubkey} variant="avatar" />
<UserDropable />
</div>
</div>
</div>
</div>
</DndContext>
);
}

View File

@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;
.border {
background-clip: padding-box;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}

View File

@ -35,6 +35,10 @@ export const User = memo(function User({
const createdAt = time ? formatCreatedAt(time, variant === 'chat') : 0;
if (status === 'loading') {
if (variant === 'avatar') {
<div className="h-12 w-12 animate-pulse overflow-hidden rounded-lg bg-white/10 backdrop-blur-xl" />;
}
if (variant === 'mention') {
return (
<div className="relative flex items-center gap-3">