wip: port more component to new ui
This commit is contained in:
@@ -102,74 +102,64 @@ export function ResetScreen() {
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<div className="mx-auto w-full max-w-md">
|
||||
<div className="mb-8 text-center">
|
||||
<h1 className="text-xl font-semibold text-zinc-100">Reset unlock password</h1>
|
||||
<div className="mb-6 text-center">
|
||||
<h1 className="text-2xl font-semibold text-white">Reset unlock password</h1>
|
||||
</div>
|
||||
<div className="flex flex-col gap-4">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mb-0 flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="privkey" className="font-medium text-zinc-200">
|
||||
Private key
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
{...register('privkey', { required: true })}
|
||||
type="text"
|
||||
placeholder="nsec..."
|
||||
className="relative w-full rounded-lg bg-zinc-800 px-3.5 py-3 text-zinc-100 !outline-none placeholder:text-zinc-400"
|
||||
/>
|
||||
</div>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mb-0 flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="privkey" className="font-medium text-white/50">
|
||||
Private key
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
{...register('privkey', { required: true })}
|
||||
type="text"
|
||||
placeholder="nsec..."
|
||||
className="relative h-12 w-full rounded-lg bg-white/10 px-3.5 py-1 text-white !outline-none placeholder:text-white/10"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="password" className="font-medium text-zinc-200">
|
||||
Set a new password to protect your key
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
{...register('password', { required: true })}
|
||||
type={passwordInput}
|
||||
placeholder="min. 4 characters"
|
||||
className="relative w-full rounded-lg bg-zinc-800 py-3 pl-3.5 pr-11 text-zinc-100 !outline-none placeholder:text-zinc-400"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => showPassword()}
|
||||
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-zinc-700"
|
||||
>
|
||||
{passwordInput === 'password' ? (
|
||||
<EyeOffIcon
|
||||
width={20}
|
||||
height={20}
|
||||
className="text-zinc-500 group-hover:text-zinc-100"
|
||||
/>
|
||||
) : (
|
||||
<EyeOnIcon
|
||||
width={20}
|
||||
height={20}
|
||||
className="text-zinc-500 group-hover:text-zinc-100"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
<span className="text-sm text-red-400">
|
||||
{errors.password && <p>{errors.password.message}</p>}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-center">
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label htmlFor="password" className="font-medium text-white/50">
|
||||
Set a new password to protect your key
|
||||
</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
{...register('password', { required: true })}
|
||||
type={passwordInput}
|
||||
placeholder="min. 4 characters"
|
||||
className="relative h-12 w-full rounded-lg bg-white/10 px-3.5 py-1 text-white !outline-none placeholder:text-white/10"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!isDirty || !isValid}
|
||||
className="mt-3 inline-flex h-11 w-full items-center justify-center rounded-md bg-fuchsia-500 font-medium text-zinc-100 hover:bg-fuchsia-600 disabled:pointer-events-none disabled:opacity-50"
|
||||
type="button"
|
||||
onClick={() => showPassword()}
|
||||
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-white/10"
|
||||
>
|
||||
{loading ? (
|
||||
<LoaderIcon className="h-4 w-4 animate-spin text-black dark:text-zinc-100" />
|
||||
{passwordInput === 'password' ? (
|
||||
<EyeOffIcon className="h-5 w-5 text-white/50 group-hover:text-white" />
|
||||
) : (
|
||||
'Continue →'
|
||||
<EyeOnIcon className="h-5 w-5 text-white/50 group-hover:text-white" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<span className="text-sm text-red-400">
|
||||
{errors.password && <p>{errors.password.message}</p>}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-center">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!isDirty || !isValid}
|
||||
className="inline-flex h-12 w-full items-center justify-center rounded-md bg-fuchsia-500 font-medium text-white hover:bg-fuchsia-600 disabled:pointer-events-none disabled:opacity-50"
|
||||
>
|
||||
{loading ? (
|
||||
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
|
||||
) : (
|
||||
'Continue →'
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -84,7 +84,7 @@ export function UnlockScreen() {
|
||||
<div className="mb-6 text-center">
|
||||
<h1 className="text-2xl font-semibold text-white">Enter password to unlock</h1>
|
||||
</div>
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-3">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="mb-0 flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="relative">
|
||||
<input
|
||||
@@ -98,17 +98,9 @@ export function UnlockScreen() {
|
||||
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-white/10"
|
||||
>
|
||||
{passwordInput === 'password' ? (
|
||||
<EyeOffIcon
|
||||
width={20}
|
||||
height={20}
|
||||
className="text-white/50 group-hover:text-white"
|
||||
/>
|
||||
<EyeOffIcon className="h-5 w-5 text-white/50 group-hover:text-white" />
|
||||
) : (
|
||||
<EyeOnIcon
|
||||
width={20}
|
||||
height={20}
|
||||
className="text-white/50 group-hover:text-white"
|
||||
/>
|
||||
<EyeOnIcon className="h-5 w-5 text-white/50 group-hover:text-white" />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Dialog, Transition } from '@headlessui/react';
|
||||
import { Fragment, useState } from 'react';
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { User } from '@app/auth/components/user';
|
||||
@@ -10,114 +10,79 @@ import { useAccount } from '@utils/hooks/useAccount';
|
||||
|
||||
export function NewMessageModal() {
|
||||
const navigate = useNavigate();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const { status, account } = useAccount();
|
||||
|
||||
const follows = account ? JSON.parse(account.follows as string) : [];
|
||||
|
||||
const closeModal = () => {
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
const openModal = () => {
|
||||
setIsOpen(true);
|
||||
};
|
||||
|
||||
const openChat = (pubkey: string) => {
|
||||
closeModal();
|
||||
setOpen(false);
|
||||
navigate(`/app/chats/${pubkey}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openModal()}
|
||||
className="inline-flex h-9 items-center gap-2.5 rounded-md px-2"
|
||||
>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded bg-white/10">
|
||||
<PlusIcon className="h-3 w-3 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-white/50">New chat</h5>
|
||||
</div>
|
||||
</button>
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-10" onClose={closeModal}>
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 z-50 bg-black bg-opacity-30 backdrop-blur-md" />
|
||||
</Transition.Child>
|
||||
<div className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative flex h-min w-full max-w-lg flex-col gap-2 rounded-lg border-t border-zinc-800/50 bg-zinc-900">
|
||||
<div className="h-min w-full shrink-0 border-b border-zinc-800 px-5 py-5">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<Dialog.Title
|
||||
as="h3"
|
||||
className="text-lg font-semibold leading-none text-zinc-100"
|
||||
>
|
||||
New chat
|
||||
</Dialog.Title>
|
||||
<Dialog.Root open={open} onOpenChange={setOpen}>
|
||||
<Dialog.Trigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex h-9 items-center gap-2.5 rounded-md px-2"
|
||||
>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded bg-white/10">
|
||||
<PlusIcon className="h-3 w-3 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-white/50">New chat</h5>
|
||||
</div>
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
<Dialog.Portal className="relative z-10">
|
||||
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/80 backdrop-blur-xl" />
|
||||
<Dialog.Content className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
||||
<div className="relative h-min w-full max-w-xl rounded-xl bg-white/10">
|
||||
<div className="h-min w-full shrink-0 border-b border-white/10 bg-white/5 px-5 py-5">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<Dialog.Title className="text-lg font-semibold leading-none text-zinc-100">
|
||||
New chat
|
||||
</Dialog.Title>
|
||||
<Dialog.Close className="inline-flex h-6 w-6 items-center justify-center rounded-md hover:bg-white/10">
|
||||
<CancelIcon className="h-4 w-4 text-white/50" />
|
||||
</Dialog.Close>
|
||||
</div>
|
||||
<Dialog.Description className="text-sm leading-none text-zinc-400">
|
||||
All messages will be encrypted, but anyone can see who you chat
|
||||
</Dialog.Description>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-[500px] flex-col overflow-y-auto overflow-x-hidden pb-2 pt-2">
|
||||
{status === 'loading' ? (
|
||||
<div className="inline-flex items-center justify-center px-4 py-3">
|
||||
<LoaderIcon className="h-5 w-5 animate-spin text-white" />
|
||||
</div>
|
||||
) : (
|
||||
follows.map((follow) => (
|
||||
<div
|
||||
key={follow}
|
||||
className="group flex items-center justify-between px-4 py-2 hover:bg-white/10"
|
||||
>
|
||||
<User pubkey={follow} />
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeModal}
|
||||
className="inline-flex h-5 w-5 items-center justify-center rounded hover:bg-zinc-800"
|
||||
onClick={() => openChat(follow)}
|
||||
className="hidden w-max rounded bg-white/10 px-3 py-1 text-sm font-medium hover:bg-fuchsia-500 group-hover:inline-flex"
|
||||
>
|
||||
<CancelIcon className="h-4 w-4 text-zinc-300" />
|
||||
Chat
|
||||
</button>
|
||||
</div>
|
||||
<Dialog.Description className="text-sm leading-tight text-zinc-400">
|
||||
All messages will be encrypted, but anyone can see who you chat
|
||||
</Dialog.Description>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-[500px] flex-col overflow-y-auto overflow-x-hidden pb-5">
|
||||
{status === 'loading' ? (
|
||||
<div className="inline-flex items-center justify-center px-4 py-3">
|
||||
<LoaderIcon className="h-5 w-5 animate-spin text-black dark:text-zinc-100" />
|
||||
</div>
|
||||
) : (
|
||||
follows.map((follow) => (
|
||||
<div
|
||||
key={follow}
|
||||
className="group flex items-center justify-between px-4 py-3 hover:bg-zinc-800"
|
||||
>
|
||||
<User pubkey={follow} />
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openChat(follow)}
|
||||
className="hidden w-max rounded-md bg-zinc-700 px-3 py-1 text-sm font-medium hover:bg-fuchsia-500 group-hover:inline-flex"
|
||||
>
|
||||
Chat
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition>
|
||||
</>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,115 +1,81 @@
|
||||
import { Dialog, Transition } from '@headlessui/react';
|
||||
import { Fragment, useState } from 'react';
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { User } from '@app/auth/components/user';
|
||||
|
||||
import { CancelIcon, StrangersIcon } from '@shared/icons';
|
||||
import { CancelIcon, PlusIcon } from '@shared/icons';
|
||||
|
||||
import { compactNumber } from '@utils/number';
|
||||
import { Chats } from '@utils/types';
|
||||
|
||||
export function UnknownsModal({ data }: { data: Chats[] }) {
|
||||
const navigate = useNavigate();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const closeModal = () => {
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
const openModal = () => {
|
||||
setIsOpen(true);
|
||||
};
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const openChat = (pubkey: string) => {
|
||||
closeModal();
|
||||
setOpen(false);
|
||||
navigate(`/app/chats/${pubkey}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openModal()}
|
||||
className="inline-flex h-9 items-center gap-2.5 rounded-md px-2"
|
||||
>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded bg-white/10">
|
||||
<StrangersIcon className="h-3 w-3 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-white/50">{compactNumber.format(data.length)} unknowns</h5>
|
||||
</div>
|
||||
</button>
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
<Dialog as="div" className="relative z-10" onClose={closeModal}>
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 z-50 bg-black bg-opacity-30 backdrop-blur-md" />
|
||||
</Transition.Child>
|
||||
<div className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95"
|
||||
>
|
||||
<Dialog.Panel className="relative flex h-min w-full max-w-lg flex-col gap-2 rounded-lg border-t border-zinc-800/50 bg-zinc-900">
|
||||
<div className="h-min w-full shrink-0 border-b border-zinc-800 px-5 py-5">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<Dialog.Title
|
||||
as="h3"
|
||||
className="text-lg font-semibold leading-none text-zinc-100"
|
||||
>
|
||||
{data.length} unknowns
|
||||
</Dialog.Title>
|
||||
<button
|
||||
type="button"
|
||||
onClick={closeModal}
|
||||
className="inline-flex h-5 w-5 items-center justify-center rounded hover:bg-zinc-800"
|
||||
>
|
||||
<CancelIcon className="h-4 w-4 text-zinc-300" />
|
||||
</button>
|
||||
</div>
|
||||
<Dialog.Description className="text-sm leading-tight text-zinc-400">
|
||||
All messages from people you not follow
|
||||
</Dialog.Description>
|
||||
<Dialog.Root open={open} onOpenChange={setOpen}>
|
||||
<Dialog.Trigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex h-9 items-center gap-2.5 rounded-md px-2"
|
||||
>
|
||||
<div className="inline-flex h-6 w-6 shrink-0 items-center justify-center rounded bg-white/10">
|
||||
<PlusIcon className="h-3 w-3 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="text-white/50">
|
||||
{compactNumber.format(data.length)} unknowns
|
||||
</h5>
|
||||
</div>
|
||||
</button>
|
||||
</Dialog.Trigger>
|
||||
<Dialog.Portal className="relative z-10">
|
||||
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/80 backdrop-blur-xl" />
|
||||
<Dialog.Content className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
||||
<div className="relative h-min w-full max-w-xl rounded-xl bg-white/10">
|
||||
<div className="h-min w-full shrink-0 border-b border-white/10 bg-white/5 px-5 py-5">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-center justify-between">
|
||||
<Dialog.Title className="text-lg font-semibold leading-none text-zinc-100">
|
||||
{data.length} unknowns
|
||||
</Dialog.Title>
|
||||
<Dialog.Close className="inline-flex h-6 w-6 items-center justify-center rounded-md hover:bg-white/10">
|
||||
<CancelIcon className="h-4 w-4 text-white/50" />
|
||||
</Dialog.Close>
|
||||
</div>
|
||||
<Dialog.Description className="text-sm leading-none text-zinc-400">
|
||||
All messages from people you not follow
|
||||
</Dialog.Description>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-[500px] flex-col overflow-y-auto overflow-x-hidden pb-2 pt-2">
|
||||
{data.map((user) => (
|
||||
<div
|
||||
key={user.sender_pubkey}
|
||||
className="group flex items-center justify-between px-4 py-2 hover:bg-white/10"
|
||||
>
|
||||
<User pubkey={user.sender_pubkey} />
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openChat(user.sender_pubkey)}
|
||||
className="hidden w-max rounded bg-white/10 px-3 py-1 text-sm font-medium hover:bg-fuchsia-500 group-hover:inline-flex"
|
||||
>
|
||||
Chat
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex h-[500px] flex-col overflow-y-auto overflow-x-hidden pb-5">
|
||||
{data.map((user) => (
|
||||
<div
|
||||
key={user.sender_pubkey}
|
||||
className="group flex items-center justify-between px-4 py-3 hover:bg-zinc-800"
|
||||
>
|
||||
<User pubkey={user.sender_pubkey} />
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => openChat(user.sender_pubkey)}
|
||||
className="hidden w-max rounded-md bg-zinc-700 px-3 py-1 text-sm font-medium hover:bg-fuchsia-500 group-hover:inline-flex"
|
||||
>
|
||||
Chat
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition>
|
||||
</>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ export function SpaceScreen() {
|
||||
<AddBlock />
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[350px] shrink-0" />
|
||||
<div className="w-[250px] shrink-0" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,21 +58,19 @@ export function Profile({ data }: { data: any }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border-t border-zinc-800/50 bg-zinc-900 px-5 py-5">
|
||||
<div className="rounded-xl bg-white/10 px-5 py-5">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<div className="h-11 w-11 shrink-0">
|
||||
<Image
|
||||
src={profile.picture}
|
||||
fallback={DEFAULT_AVATAR}
|
||||
className="h-11 w-11 rounded-lg object-cover"
|
||||
/>
|
||||
</div>
|
||||
<Image
|
||||
src={profile.picture}
|
||||
fallback={DEFAULT_AVATAR}
|
||||
className="h-11 w-11 shrink-0 rounded-lg object-cover"
|
||||
/>
|
||||
<div className="inline-flex flex-col gap-1">
|
||||
<h3 className="max-w-[15rem] truncate font-semibold leading-none text-zinc-100">
|
||||
<h3 className="max-w-[15rem] truncate font-semibold leading-none text-white">
|
||||
{profile.display_name || profile.name}
|
||||
</h3>
|
||||
<p className="max-w-[10rem] truncate text-sm leading-none text-zinc-400">
|
||||
<p className="max-w-[10rem] truncate text-sm leading-none text-white/50">
|
||||
{profile.nip05 || shortenKey(data.pubkey)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -81,15 +79,15 @@ export function Profile({ data }: { data: any }) {
|
||||
{socialStatus === 'loading' ? (
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-zinc-900 hover:bg-fuchsia-500"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-white/10 hover:bg-fuchsia-500"
|
||||
>
|
||||
<LoaderIcon className="h-4 w-4 animate-spin text-black dark:text-zinc-100" />
|
||||
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
|
||||
</button>
|
||||
) : followed ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => unfollowUser(data.pubkey)}
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-zinc-800 text-zinc-400 hover:bg-fuchsia-500 hover:text-white"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-white/10 text-white hover:bg-fuchsia-500 hover:text-white"
|
||||
>
|
||||
<UnfollowIcon className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -97,7 +95,7 @@ export function Profile({ data }: { data: any }) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => followUser(data.pubkey)}
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-zinc-800 text-zinc-400 hover:bg-fuchsia-500 hover:text-white"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md bg-white/10 text-white hover:bg-fuchsia-500 hover:text-white"
|
||||
>
|
||||
<FollowIcon className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -105,7 +103,7 @@ export function Profile({ data }: { data: any }) {
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<p className="whitespace-pre-line break-words text-zinc-100">
|
||||
<p className="whitespace-pre-line break-words text-white">
|
||||
{profile.about || profile.bio}
|
||||
</p>
|
||||
</div>
|
||||
@@ -115,26 +113,26 @@ export function Profile({ data }: { data: any }) {
|
||||
) : (
|
||||
<div className="flex w-full items-center gap-8">
|
||||
<div className="inline-flex flex-col gap-1">
|
||||
<span className="font-semibold leading-none text-zinc-100">
|
||||
<span className="font-semibold leading-none text-white">
|
||||
{userStats.stats[data.pubkey].followers_pubkey_count ?? 0}
|
||||
</span>
|
||||
<span className="text-sm leading-none text-zinc-400">Followers</span>
|
||||
<span className="text-sm leading-none text-white/50">Followers</span>
|
||||
</div>
|
||||
<div className="inline-flex flex-col gap-1">
|
||||
<span className="font-semibold leading-none text-zinc-100">
|
||||
<span className="font-semibold leading-none text-white">
|
||||
{userStats.stats[data.pubkey].pub_following_pubkey_count ?? 0}
|
||||
</span>
|
||||
<span className="text-sm leading-none text-zinc-400">Following</span>
|
||||
<span className="text-sm leading-none text-white/50">Following</span>
|
||||
</div>
|
||||
<div className="inline-flex flex-col gap-1">
|
||||
<span className="font-semibold leading-none text-zinc-100">
|
||||
<span className="font-semibold leading-none text-white">
|
||||
{userStats.stats[data.pubkey].zaps_received
|
||||
? compactNumber.format(
|
||||
userStats.stats[data.pubkey].zaps_received.msats / 1000
|
||||
)
|
||||
: 0}
|
||||
</span>
|
||||
<span className="text-sm leading-none text-zinc-400">Zaps received</span>
|
||||
<span className="text-sm leading-none text-white/50">Zaps received</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -14,18 +14,18 @@ export function TrendingNotes() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex w-[360px] shrink-0 flex-col border-r border-zinc-900">
|
||||
<div className="scrollbar-hide relative h-full w-[400px] shrink-0 overflow-y-auto bg-white/10 pb-20">
|
||||
<TitleBar title="Trending Posts" />
|
||||
<div className="scrollbar-hide flex h-full w-full flex-col justify-between gap-1.5 overflow-y-auto pb-20 pt-1.5">
|
||||
<div className="h-full">
|
||||
{error && <p>Failed to fetch</p>}
|
||||
{status === 'loading' ? (
|
||||
<div className="px-3 py-1.5">
|
||||
<div className="shadow-input rounded-md bg-zinc-900 px-3 py-3 shadow-black/20">
|
||||
<div className="shadow-input rounded-md px-3 py-3">
|
||||
<NoteSkeleton />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="relative flex w-full flex-col pt-1.5">
|
||||
<div className="relative flex w-full flex-col">
|
||||
{data.notes.map((item) => (
|
||||
<NoteKind_1 key={item.id} event={item.event} skipMetadata={true} />
|
||||
))}
|
||||
|
||||
@@ -15,9 +15,9 @@ export function TrendingProfiles() {
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex w-[360px] shrink-0 flex-col border-r border-zinc-900">
|
||||
<div className="scrollbar-hide relative h-full w-[400px] shrink-0 overflow-y-auto bg-white/10 pb-20">
|
||||
<TitleBar title="Trending Profiles" />
|
||||
<div className="scrollbar-hide flex h-full w-full flex-col justify-between gap-1.5 overflow-y-auto pb-20 pt-1.5">
|
||||
<div className="h-full">
|
||||
{error && <p>Failed to fetch</p>}
|
||||
{status === 'loading' ? (
|
||||
<div className="px-3 py-1.5">
|
||||
@@ -26,7 +26,7 @@ export function TrendingProfiles() {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="relative flex w-full flex-col gap-3 px-3 pt-3">
|
||||
<div className="relative flex w-full flex-col gap-3 px-3 pt-1.5">
|
||||
{data.profiles.map((item) => (
|
||||
<Profile key={item.pubkey} data={item} />
|
||||
))}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { TrendingProfiles } from '@app/trending/components/trendingProfiles';
|
||||
|
||||
export function TrendingScreen() {
|
||||
return (
|
||||
<div className="scrollbar-hide flex h-full w-full flex-nowrap overflow-x-auto overflow-y-hidden">
|
||||
<div className="scrollbar-hide flex h-full w-full flex-nowrap divide-x divide-white/5 overflow-x-auto overflow-y-hidden">
|
||||
<TrendingProfiles />
|
||||
<TrendingNotes />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user