mirror of
https://github.com/lumehq/lume.git
synced 2025-03-26 01:31:48 +01:00
wip: update browse user screen
This commit is contained in:
parent
41b12746a7
commit
c049fa8865
@ -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",
|
||||
|
48
pnpm-lock.yaml
generated
48
pnpm-lock.yaml
generated
@ -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'}
|
||||
|
@ -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>
|
||||
|
22
src/app/browse/components/userDropable.tsx
Normal file
22
src/app/browse/components/userDropable.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -2,6 +2,10 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.border {
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user