This commit is contained in:
Ren Amamiya 2023-05-01 07:42:34 +07:00
parent 4be369b671
commit 2922b1c025
15 changed files with 100 additions and 44 deletions

View File

@ -24,7 +24,6 @@
"@vidstack/react": "^0.4.5",
"dayjs": "^1.11.7",
"destr": "^1.2.2",
"iconoir-react": "^6.6.0",
"jotai": "^2.0.4",
"nostr-relaypool": "^0.6.27",
"nostr-tools": "^1.10.1",
@ -68,7 +67,7 @@
"tailwindcss": "^3.3.2",
"typescript": "^4.9.5",
"vite": "^4.3.3",
"vite-plugin-ssr": "^0.4.119",
"vite-plugin-ssr": "^0.4.120",
"vite-plugin-top-level-await": "^1.3.0",
"vite-tsconfig-paths": "^4.2.0",
"ws": "^8.13.0"

View File

@ -31,9 +31,6 @@ dependencies:
destr:
specifier: ^1.2.2
version: 1.2.2
iconoir-react:
specifier: ^6.6.0
version: 6.6.0(react@18.2.0)
jotai:
specifier: ^2.0.4
version: 2.0.4(react@18.2.0)
@ -160,8 +157,8 @@ devDependencies:
specifier: ^4.3.3
version: 4.3.3(@types/node@18.16.3)
vite-plugin-ssr:
specifier: ^0.4.119
version: 0.4.119(vite@4.3.3)
specifier: ^0.4.120
version: 0.4.120(vite@4.3.3)
vite-plugin-top-level-await:
specifier: ^1.3.0
version: 1.3.0(vite@4.3.3)
@ -2592,15 +2589,6 @@ packages:
hasBin: true
dev: true
/iconoir-react@6.6.0(react@18.2.0):
resolution:
{ integrity: sha512-7ueB0jQlSZFjEa4qUCaGbfWLRjGBtOc0E+RYHEb3Ek3zDwQuNh4VLtV9kwGoiATRfBYVv8bgCmXI0nr52TRXsw== }
peerDependencies:
react: ^16.8.6 || ^17 || ^18
dependencies:
react: 18.2.0
dev: false
/iconv-lite@0.6.3:
resolution:
{ integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== }
@ -4283,9 +4271,9 @@ packages:
type-fest: 3.9.0
dev: false
/vite-plugin-ssr@0.4.119(vite@4.3.3):
/vite-plugin-ssr@0.4.120(vite@4.3.3):
resolution:
{ integrity: sha512-YAStY1PEdF+tw1h5qYjvngJaHkNy+vLT89po9wEHuBbJGgd7WieDZdZJIb3TbVPiyAyxB+3z2nkpVKPDPUCZtg== }
{ integrity: sha512-crttExXYt98bEVeLJgqlJ6peaMgzN7YrL0TNIAWEjabWHaXgpQUO+pRXOf0MIyI/xcNh13e6kvalSPo9UEpPxQ== }
engines: { node: '>=12.19.0' }
hasBin: true
peerDependencies:

View File

@ -1,7 +1,7 @@
import CopyIcon from '@lume/shared/icons/copy';
import { DEFAULT_AVATAR } from '@lume/stores/constants';
import { useChannelProfile } from '@lume/utils/hooks/useChannelProfile';
import { Copy } from 'iconoir-react';
import { nip19 } from 'nostr-tools';
export default function ChannelMetadata({ id, pubkey }: { id: string; pubkey: string }) {
@ -28,7 +28,7 @@ export default function ChannelMetadata({ id, pubkey }: { id: string; pubkey: st
<div className="flex items-center gap-1">
<h5 className="truncate text-sm font-medium leading-none text-zinc-100">{metadata?.name}</h5>
<button onClick={() => copyNoteID()}>
<Copy width={14} height={14} className="text-zinc-400" />
<CopyIcon width={14} height={14} className="text-zinc-400" />
</button>
</div>
<p className="text-xs leading-none text-zinc-400">

View File

@ -1,4 +1,6 @@
import { AvatarUploader } from '@lume/shared/avatarUploader';
import CancelIcon from '@lume/shared/icons/cancel';
import EditIcon from '@lume/shared/icons/edit';
import { RelayContext } from '@lume/shared/relayProvider';
import { DEFAULT_AVATAR, WRITEONLY_RELAYS } from '@lume/stores/constants';
import { dateToUnix } from '@lume/utils/getDate';
@ -6,7 +8,6 @@ import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount';
import { getChannel, updateChannelMetadata } from '@lume/utils/storage';
import { Dialog, Transition } from '@headlessui/react';
import { Cancel, EditPencil } from 'iconoir-react';
import { getEventHash, signEvent } from 'nostr-tools';
import { Fragment, useContext, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
@ -83,7 +84,7 @@ export default function ChannelUpdateModal({ id }: { id: string }) {
onClick={() => openModal()}
className="group inline-flex h-8 w-8 items-center justify-center rounded-md bg-zinc-900 hover:bg-zinc-800 focus:outline-none"
>
<EditPencil width={16} height={16} className="text-zinc-400 group-hover:text-zinc-200" />
<EditIcon width={16} height={16} className="text-zinc-400 group-hover:text-zinc-200" />
</button>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
@ -124,7 +125,7 @@ export default function ChannelUpdateModal({ id }: { id: string }) {
autoFocus={false}
className="inline-flex h-5 w-5 items-center justify-center rounded hover:bg-zinc-900"
>
<Cancel width={20} height={20} className="text-zinc-300" />
<CancelIcon width={20} height={20} className="text-zinc-300" />
</button>
</div>
<Dialog.Description className="leading-tight text-zinc-400">

View File

@ -7,7 +7,6 @@ import { getNotes } from '@lume/utils/storage';
import { useInfiniteQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { ArrowUp } from 'iconoir-react';
import { useAtom } from 'jotai';
import { useEffect, useRef } from 'react';
@ -55,7 +54,6 @@ export function Page() {
{hasNewerNote && (
<div className="absolute left-1/2 top-2 z-50 -translate-x-1/2 transform">
<button className="inline-flex h-8 transform items-center justify-center gap-1 rounded-full bg-fuchsia-500 pl-3 pr-3.5 text-sm shadow-md shadow-fuchsia-800/20 active:translate-y-1">
<ArrowUp width={14} height={14} />
Load latest
</button>
</div>

View File

@ -1,4 +1,5 @@
import { ArrowLeft, ArrowRight } from 'iconoir-react';
import ArrowLeftIcon from '@lume/shared/icons/arrowLeft';
import ArrowRightIcon from '@lume/shared/icons/arrowRight';
let platformName = 'darwin';
@ -29,13 +30,13 @@ export function LayoutOnboarding({ children }: { children: React.ReactNode }) {
onClick={() => goBack()}
className="group inline-flex h-6 w-6 items-center justify-center rounded-md hover:bg-zinc-900"
>
<ArrowLeft width={16} height={16} className="text-zinc-500 group-hover:text-zinc-300" />
<ArrowLeftIcon width={16} height={16} className="text-zinc-500 group-hover:text-zinc-300" />
</button>
<button
onClick={() => goForward()}
className="group inline-flex h-6 w-6 items-center justify-center rounded-md hover:bg-zinc-900"
>
<ArrowRight width={16} height={16} className="text-zinc-500 group-hover:text-zinc-300" />
<ArrowRightIcon width={16} height={16} className="text-zinc-500 group-hover:text-zinc-300" />
</button>
</div>
</div>

View File

@ -1,6 +1,7 @@
import EyeOffIcon from '@lume/shared/icons/eyeOff';
import EyeOnIcon from '@lume/shared/icons/eyeOn';
import { onboardingAtom } from '@lume/stores/onboarding';
import { EyeClose, EyeEmpty } from 'iconoir-react';
import { useSetAtom } from 'jotai';
import { generatePrivateKey, getPublicKey, nip19 } from 'nostr-tools';
import { useMemo, useState } from 'react';
@ -60,9 +61,9 @@ export function Page() {
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-zinc-700"
>
{type === 'password' ? (
<EyeClose width={20} height={20} className="text-zinc-500 group-hover:text-zinc-200" />
<EyeOffIcon width={20} height={20} className="text-zinc-500 group-hover:text-zinc-200" />
) : (
<EyeEmpty width={20} height={20} className="text-zinc-500 group-hover:text-zinc-200" />
<EyeOnIcon width={20} height={20} className="text-zinc-500 group-hover:text-zinc-200" />
)}
</button>
</div>

View File

@ -1,11 +1,11 @@
import User from '@lume/auth/components/user';
import CheckCircleIcon from '@lume/shared/icons/checkCircle';
import { RelayContext } from '@lume/shared/relayProvider';
import { WRITEONLY_RELAYS } from '@lume/stores/constants';
import { onboardingAtom } from '@lume/stores/onboarding';
import { createAccount, createPleb } from '@lume/utils/storage';
import { arrayToNIP02 } from '@lume/utils/transform';
import { CheckCircle } from 'iconoir-react';
import { useAtom } from 'jotai';
import { getEventHash, signEvent } from 'nostr-tools';
import { useContext, useState } from 'react';
@ -100,7 +100,7 @@ export function Page() {
.then((res) => {
if (res) {
for (const tag of follows) {
fetch(`https://rbr.bio/${tag}/metadata.json`)
fetch(`https://us.rbr.bio/${tag}/metadata.json`)
.then((data) => data.json())
.then((data) => createPleb(tag, data ?? ''));
}
@ -140,7 +140,7 @@ export function Page() {
<User pubkey={item.pubkey} />
{follows.includes(item.pubkey) && (
<div>
<CheckCircle width={16} height={16} className="text-green-400" />
<CheckCircleIcon width={16} height={16} className="text-green-400" />
</div>
)}
</button>

View File

@ -1,5 +1,5 @@
import { RelayContext } from '@lume/shared/relayProvider';
import { DEFAULT_AVATAR } from '@lume/stores/constants';
import { DEFAULT_AVATAR, READONLY_RELAYS } from '@lume/stores/constants';
import { onboardingAtom } from '@lume/stores/onboarding';
import { shortenKey } from '@lume/utils/shortenKey';
import { createAccount, createPleb } from '@lume/utils/storage';
@ -17,7 +17,7 @@ export function Page() {
const [onboarding, setOnboarding] = useAtom(onboardingAtom);
const pubkey = useMemo(() => (onboarding.privkey ? getPublicKey(onboarding.privkey) : ''), [onboarding.privkey]);
const { data: user, error } = useSWRSubscription(pubkey && !loading ? pubkey : null, (key, { next }) => {
const { data, error } = useSWRSubscription(pubkey ? pubkey : null, (key, { next }) => {
const unsubscribe = pool.subscribe(
[
{
@ -25,7 +25,7 @@ export function Page() {
authors: [key],
},
],
null,
READONLY_RELAYS,
(event: any) => {
switch (event.kind) {
case 0:
@ -58,7 +58,7 @@ export function Page() {
.then((res) => {
if (res) {
for (const tag of onboarding.follows) {
fetch(`https://rbr.bio/${tag[1]}/metadata.json`)
fetch(`https://us.rbr.bio/${tag[1]}/metadata.json`)
.then((data) => data.json())
.then((data) => createPleb(tag[1], data ?? ''));
}
@ -78,7 +78,7 @@ export function Page() {
</div>
<div className="w-full rounded-lg border border-zinc-800 bg-zinc-900 p-4">
{error && <div>Failed to load profile</div>}
{!user ? (
{!data ? (
<div className="w-full">
<div className="flex items-center gap-2">
<div className="h-11 w-11 animate-pulse rounded-lg bg-zinc-800"></div>
@ -93,12 +93,12 @@ export function Page() {
<div className="flex items-center gap-2">
<img
className="relative inline-flex h-11 w-11 rounded-lg ring-2 ring-zinc-900"
src={user.picture || DEFAULT_AVATAR}
src={data.picture || DEFAULT_AVATAR}
alt={pubkey}
/>
<div>
<h3 className="font-medium leading-none text-zinc-200">{user.display_name || user.name}</h3>
<p className="text-sm text-zinc-400">{user.nip05 || shortenKey(pubkey)}</p>
<h3 className="font-medium leading-none text-zinc-200">{data.display_name || data.name}</h3>
<p className="text-sm text-zinc-400">{data.nip05 || shortenKey(pubkey)}</p>
</div>
</div>
<button

View File

@ -1,4 +1,4 @@
import { ArrowRight } from 'iconoir-react';
import ArrowRightIcon from '@lume/shared/icons/arrowRight';
const PLEBS = [
'https://133332.xyz/p.jpg',
@ -99,7 +99,7 @@ export function Page() {
className="relative inline-flex h-14 w-64 items-center justify-center gap-2 rounded-full bg-zinc-900 px-6 text-lg font-medium ring-1 ring-zinc-800 hover:bg-zinc-800"
>
Create new key
<ArrowRight width={20} height={20} />
<ArrowRightIcon width={20} height={20} />
</a>
<a
href="/auth/import"

View File

@ -0,0 +1,14 @@
import { SVGProps } from 'react';
export default function CheckCircleIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM15.5805 9.97493C15.8428 9.65434 15.7955 9.18183 15.4749 8.91953C15.1543 8.65724 14.6818 8.70449 14.4195 9.02507L10.4443 13.8837L9.03033 12.4697C8.73744 12.1768 8.26256 12.1768 7.96967 12.4697C7.67678 12.7626 7.67678 13.2374 7.96967 13.5303L9.96967 15.5303C10.1195 15.6802 10.3257 15.7596 10.5374 15.7491C10.749 15.7385 10.9463 15.6389 11.0805 15.4749L15.5805 9.97493Z"
fill="currentColor"
/>
</svg>
);
}

15
src/shared/icons/copy.tsx Normal file
View File

@ -0,0 +1,15 @@
import { SVGProps } from 'react';
export default function CopyIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M15.25 15.25V21.25H2.75V8.75H8.75M8.75 15.25H21.25V2.75H8.75V15.25Z"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

15
src/shared/icons/edit.tsx Normal file
View File

@ -0,0 +1,15 @@
import { SVGProps } from 'react';
export default function EditIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M13.25 6.25L17 2.5L21.5 7L17.75 10.75M13.25 6.25L2.75 16.75V21.25H7.25L17.75 10.75M13.25 6.25L17.75 10.75"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

View File

@ -0,0 +1,12 @@
import { SVGProps } from 'react';
export default function EyeOffIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M9.1654 4.42071C8.76876 4.5401 8.544 4.95841 8.66339 5.35505C8.78277 5.75169 9.20109 5.97645 9.59772 5.85706L9.1654 4.42071ZM22 12L22.671 12.3351C22.7763 12.1241 22.7763 11.8759 22.671 11.6649L22 12ZM19.1413 14.9666C18.8678 15.2776 18.8982 15.7515 19.2092 16.0251C19.5203 16.2986 19.9942 16.2682 20.2677 15.9571L19.1413 14.9666ZM3.28033 2.21967C2.98744 1.92678 2.51256 1.92678 2.21967 2.21967C1.92678 2.51256 1.92678 2.98744 2.21967 3.28033L3.28033 2.21967ZM2 11.9999L1.32902 11.6648C1.22366 11.8758 1.22366 12.124 1.32902 12.335L2 11.9999ZM17.4703 17.4703L18.0006 16.9399L17.4703 17.4703ZM20.7197 21.7803C21.0126 22.0732 21.4874 22.0732 21.7803 21.7803C22.0732 21.4874 22.0732 21.0126 21.7803 20.7197L20.7197 21.7803ZM10.2322 10.2322C10.5251 9.93934 10.5251 9.46447 10.2322 9.17157C9.93934 8.87868 9.46447 8.87868 9.17157 9.17157L10.2322 10.2322ZM14.8284 14.8284C15.1213 14.5355 15.1213 14.0607 14.8284 13.7678C14.5355 13.4749 14.0607 13.4749 13.7678 13.7678L14.8284 14.8284ZM9.59772 5.85706C13.745 4.60878 18.4769 6.624 21.329 12.3351L22.671 11.6649C19.5775 5.47055 14.1791 2.91165 9.1654 4.42071L9.59772 5.85706ZM20.2677 15.9571C21.1654 14.9364 21.9755 13.7277 22.671 12.3351L21.329 11.6649C20.6865 12.9515 19.9468 14.0507 19.1413 14.9666L20.2677 15.9571ZM2.21967 3.28033L5.99937 7.06003L7.06003 5.99937L3.28033 2.21967L2.21967 3.28033ZM2.67098 12.335C3.84083 9.99245 5.33197 8.27257 6.95699 7.14609L6.10242 5.91332C4.24158 7.20327 2.5948 9.13019 1.32902 11.6648L2.67098 12.335ZM5.99937 7.06003L16.9399 18.0006L18.0006 16.9399L7.06003 5.99937L5.99937 7.06003ZM16.9399 18.0006L20.7197 21.7803L21.7803 20.7197L18.0006 16.9399L16.9399 18.0006ZM1.32902 12.335C3.20469 16.0909 5.92036 18.5148 8.91701 19.5009C11.922 20.4898 15.1308 20.0045 17.8975 18.0866L17.043 16.8539C14.6436 18.5171 11.9221 18.9107 9.38589 18.0761C6.84135 17.2388 4.40494 15.1369 2.67098 11.6648L1.32902 12.335ZM12 14.5C10.6193 14.5 9.5 13.3807 9.5 12H8C8 14.2091 9.79086 16 12 16V14.5ZM9.5 12C9.5 11.3094 9.779 10.6855 10.2322 10.2322L9.17157 9.17157C8.44854 9.89461 8 10.8956 8 12H9.5ZM13.7678 13.7678C13.3145 14.221 12.6906 14.5 12 14.5V16C13.1044 16 14.1054 15.5515 14.8284 14.8284L13.7678 13.7678Z"
fill="currentColor"
/>
</svg>
);
}

View File

@ -0,0 +1,12 @@
import { SVGProps } from 'react';
export default function EyeOnIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg width={24} height={24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M2 11.9999L1.32902 11.6648C1.22366 11.8758 1.22366 12.124 1.32902 12.335L2 11.9999ZM22 12L22.671 12.3351C22.7763 12.1241 22.7763 11.8759 22.671 11.6649L22 12ZM2.67098 12.335C4.9893 7.69273 8.55546 5.49997 12 5.5C15.4445 5.50003 19.0107 7.69284 21.329 12.3351L22.671 11.6649C20.1618 6.64058 16.1417 4.00003 12 4C7.85827 3.99997 3.83815 6.64046 1.32902 11.6648L2.67098 12.335ZM1.32902 12.335C3.83815 17.3593 7.85826 19.9999 12 19.9999C16.1417 20 20.1618 17.3595 22.671 12.3351L21.329 11.6649C19.0107 16.3072 15.4445 18.4999 12 18.4999C8.55547 18.4999 4.9893 16.3071 2.67098 11.6648L1.32902 12.335ZM14.5 12C14.5 13.3807 13.3807 14.5 12 14.5V16C14.2091 16 16 14.2091 16 12H14.5ZM12 14.5C10.6193 14.5 9.5 13.3807 9.5 12H8C8 14.2091 9.79086 16 12 16V14.5ZM9.5 12C9.5 10.6193 10.6193 9.5 12 9.5V8C9.79086 8 8 9.79086 8 12H9.5ZM12 9.5C13.3807 9.5 14.5 10.6193 14.5 12H16C16 9.79086 14.2091 8 12 8V9.5Z"
fill="currentColor"
/>
</svg>
);
}