yup, lume is very solid now

This commit is contained in:
Ren Amamiya 2023-08-29 16:11:17 +07:00
parent 2914c54a47
commit 91e50efb1a
20 changed files with 177 additions and 88 deletions

View File

@ -1,6 +1,16 @@
{
"tauri": {
"windows": [
{
"width": 400,
"height": 500,
"decorations": false,
"title": "Lume",
"center": true,
"resizable": false,
"label": "splashscreen",
"url": "splashscreen"
},
{
"width": 1080,
"height": 800,
@ -14,21 +24,23 @@
"fullscreen": false,
"hiddenTitle": true,
"visible": false,
"fileDropEnabled": true,
"windowEffects": {
"effects": ["micaDark", "micaLight", "acrylic"],
"state": "followsWindowActiveState"
}
"fileDropEnabled": true
},
{
"width": 400,
"height": 500,
"decorations": false,
"title": "Lume",
"center": true,
"width": 1080,
"height": 800,
"resizable": false,
"label": "splashscreen",
"url": "splashscreen"
"theme": "Dark",
"label": "settings",
"url": "settings",
"title": "Settings",
"titleBarStyle": "Overlay",
"transparent": false,
"center": true,
"fullscreen": false,
"hiddenTitle": true,
"visible": false,
"fileDropEnabled": false
}
]
}

View File

@ -1,6 +1,18 @@
{
"tauri": {
"windows": [
{
"width": 400,
"height": 500,
"decorations": true,
"title": "Lume",
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"center": true,
"resizable": false,
"label": "splashscreen",
"url": "splashscreen"
},
{
"width": 1080,
"height": 800,
@ -22,16 +34,24 @@
}
},
{
"width": 400,
"height": 500,
"decorations": true,
"title": "Lume",
"titleBarStyle": "Overlay",
"hiddenTitle": true,
"center": true,
"width": 1080,
"height": 800,
"resizable": false,
"label": "splashscreen",
"url": "splashscreen"
"theme": "Dark",
"label": "settings",
"url": "settings",
"title": "Settings",
"titleBarStyle": "Overlay",
"transparent": true,
"center": true,
"fullscreen": false,
"hiddenTitle": true,
"visible": false,
"fileDropEnabled": false,
"windowEffects": {
"effects": ["hudWindow"],
"state": "followsWindowActiveState"
}
}
]
}

View File

@ -1,6 +1,16 @@
{
"tauri": {
"windows": [
{
"width": 400,
"height": 500,
"decorations": false,
"title": "Lume",
"center": true,
"resizable": false,
"label": "splashscreen",
"url": "splashscreen"
},
{
"width": 1080,
"height": 800,
@ -21,14 +31,24 @@
}
},
{
"width": 400,
"height": 500,
"decorations": false,
"title": "Lume",
"center": true,
"width": 1080,
"height": 800,
"resizable": false,
"label": "splashscreen",
"url": "splashscreen"
"theme": "Dark",
"label": "settings",
"url": "settings",
"title": "Settings",
"titleBarStyle": "Overlay",
"transparent": true,
"center": true,
"fullscreen": false,
"hiddenTitle": true,
"visible": false,
"fileDropEnabled": false,
"windowEffects": {
"effects": ["micaDark", "micaLight", "acrylic"],
"state": "followsWindowActiveState"
}
}
]
}

View File

@ -19,19 +19,17 @@ export function User({ pubkey, fallback }: { pubkey: string; fallback?: string }
}
return (
<div className="flex items-center gap-2">
<div className="relative h-10 w-10 shrink rounded-md">
<Image
src={user?.picture || user?.image}
alt={pubkey}
className="h-10 w-10 rounded-md object-cover"
/>
</div>
<div className="flex items-center gap-2.5">
<Image
src={user?.picture || user?.image}
alt={pubkey}
className="h-10 w-10 shrink-0 rounded-lg object-cover"
/>
<div className="flex w-full flex-1 flex-col items-start text-start">
<p className="max-w-[15rem] truncate font-medium leading-tight text-white">
{user?.name || user?.display_name || user?.nip05}
</p>
<span className="max-w-[15rem] truncate text-base leading-tight text-white/50">
<span className="max-w-[15rem] truncate leading-tight text-white/50">
{displayNpub(pubkey, 16)}
</span>
</div>

View File

@ -74,7 +74,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="mb-0 flex flex-col gap-1">
<form onSubmit={handleSubmit(onSubmit)} className="mb-0 flex flex-col">
<div className="flex flex-col rounded-lg bg-white/5">
<div className="w-full rounded-t-lg border-b border-white/10 bg-white/5 p-4">
<User pubkey={db.account.pubkey} />
@ -82,7 +82,7 @@ export function UnlockScreen() {
<div className="relative">
<input
{...register('password', { required: true, minLength: 4 })}
type={'password'}
type={showPassword ? 'text' : 'password'}
placeholder="Password"
className="relative h-12 w-full rounded-b-lg bg-white/10 py-1 text-center text-white !outline-none backdrop-blur-xl placeholder:text-white/50"
/>
@ -124,7 +124,7 @@ export function UnlockScreen() {
</button>
<Link
to="/auth/reset"
className="inline-flex h-14 items-center justify-center text-center text-white/50"
className="mt-1 inline-flex h-11 w-full items-center justify-center rounded-lg text-center text-white/50 hover:bg-white/10"
>
Reset password
</Link>

View File

@ -3,10 +3,10 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { useStorage } from '@libs/storage/provider';
import {
AddWidgetIcon,
FeedIcon,
FileIcon,
HashtagIcon,
PlusIcon,
ThreadsIcon,
TrendingIcon,
} from '@shared/icons';
@ -72,7 +72,7 @@ export function AddWidgetButton() {
<DropdownMenu.Trigger asChild>
<button type="button" className="flex flex-col items-center gap-2">
<div className="flex h-10 w-10 items-center justify-center rounded-lg bg-white/5 backdrop-blur-xl hover:bg-white/10">
<PlusIcon className="h-5 w-5 text-white" />
<AddWidgetIcon className="h-5 w-5 text-white" />
</div>
<p className="font-medium text-white/50">Add widget</p>
</button>
@ -82,7 +82,7 @@ export function AddWidgetButton() {
<DropdownMenu.Portal>
<DropdownMenu.Content
sideOffset={-20}
className="flex w-[256px] flex-col overflow-hidden rounded-md bg-white/10 p-2 backdrop-blur-3xl backdrop-blur-xl focus:outline-none"
className="flex w-[256px] flex-col overflow-hidden rounded-md bg-white/10 p-2 backdrop-blur-3xl focus:outline-none"
>
<DropdownMenu.Item asChild>
<button

View File

@ -18,6 +18,7 @@ import { NoteSkeleton } from '@shared/notes/skeleton';
import { TitleBar } from '@shared/titleBar';
import { useNostr } from '@utils/hooks/useNostr';
import { toRawEvent } from '@utils/rawEvent';
import { DBEvent } from '@utils/types';
export function NetworkWidget() {
@ -131,15 +132,19 @@ export function NetworkWidget() {
async (event) => {
let root: string;
let reply: string;
if (event.tags?.[0]?.[0] === 'e' && !event.tags?.[0]?.[3]) {
root = event.tags[0][1];
} else {
root = event.tags.find((el) => el[3] === 'root')?.[1];
reply = event.tags.find((el) => el[3] === 'reply')?.[1];
}
const rawEvent = toRawEvent(event);
await db.createEvent(
event.id,
JSON.stringify(event),
JSON.stringify(rawEvent),
event.pubkey,
event.kind,
root,
@ -154,7 +159,7 @@ export function NetworkWidget() {
return (
<div className="relative shrink-0 grow-0 basis-[400px] bg-white/10 backdrop-blur-xl">
<TitleBar title="Network" />
<TitleBar title="👋 Network" />
<div ref={parentRef} className="scrollbar-hide h-full overflow-y-auto pb-20">
{status === 'loading' ? (
<div className="px-3 py-1.5">

View File

@ -37,13 +37,15 @@ export default class TauriAdapter implements NDKCacheAdapter {
public async setEvent(event: NDKEvent): Promise<void> {
const nostrEvent = await event.toNostrEvent();
const key = `${nostrEvent.pubkey}:${nostrEvent.kind}`;
if (event.kind !== 3) {
const key = `${nostrEvent.pubkey}:${nostrEvent.kind}`;
return new Promise((resolve) => {
Promise.all([this.store.set(key, JSON.stringify(nostrEvent))]).then(() =>
resolve()
);
});
return new Promise((resolve) => {
Promise.all([this.store.set(key, JSON.stringify(nostrEvent))]).then(() =>
resolve()
);
});
}
}
public async saveCache(): Promise<void> {

View File

@ -4,13 +4,7 @@ import { twMerge } from 'tailwind-merge';
import { useStorage } from '@libs/storage/provider';
import { Composer, ComposerUser } from '@shared/composer';
import {
CancelIcon,
ChevronDownIcon,
ChevronRightIcon,
ComposeIcon,
ExpandIcon,
} from '@shared/icons';
import { CancelIcon, ChevronDownIcon, ChevronRightIcon, ExpandIcon } from '@shared/icons';
import { useComposer } from '@stores/composer';
@ -30,7 +24,6 @@ export function ComposerModal() {
type="button"
className="inline-flex h-10 w-full items-center justify-center gap-1.5 rounded-lg bg-white/20 px-4 font-bold text-white hover:bg-fuchsia-500 focus:outline-none active:translate-y-1"
>
<ComposeIcon className="h-5 w-5" />
Postr
</button>
</Dialog.Trigger>

View File

@ -0,0 +1,22 @@
import { SVGProps } from 'react';
export function AddWidgetIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
{...props}
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.5"
d="M12.25 21.25h-6.5a1 1 0 01-1-1V3.75a1 1 0 011-1h12.5a1 1 0 011 1v8.5m-1 3v3m0 0v3m0-3h-3m3 0h3"
></path>
</svg>
);
}

View File

@ -1,3 +1,4 @@
export * from './addWidget';
export * from './arrowLeft';
export * from './arrowRight';
export * from './bell';

View File

@ -28,7 +28,7 @@ export function NoteActions({
return (
<Tooltip.Provider>
<div className="-ml-1 mt-2 inline-flex w-full items-center">
<div className="-ml-1 mt-4 inline-flex w-full items-center">
<div className="inline-flex items-center gap-2">
<NoteReply id={id} pubkey={pubkey} root={root} />
<NoteReaction id={id} pubkey={pubkey} />

View File

@ -50,7 +50,7 @@ export function MoreActions({ id, pubkey }: { id: string; pubkey: string }) {
<button
type="button"
onClick={() => copyLink()}
className="inline-flex h-10 items-center rounded-md px-2 text-sm font-medium text-white backdrop-blur-xl hover:bg-white/10"
className="inline-flex h-10 items-center rounded-md px-2 text-sm font-medium text-white hover:bg-white/10"
>
Copy shareable link
</button>
@ -59,7 +59,7 @@ export function MoreActions({ id, pubkey }: { id: string; pubkey: string }) {
<button
type="button"
onClick={() => copyID()}
className="inline-flex h-10 items-center rounded-md px-2 text-sm font-medium text-white backdrop-blur-xl hover:bg-white/10"
className="inline-flex h-10 items-center rounded-md px-2 text-sm font-medium text-white hover:bg-white/10"
>
Copy ID
</button>
@ -67,7 +67,7 @@ export function MoreActions({ id, pubkey }: { id: string; pubkey: string }) {
<DropdownMenu.Item asChild>
<Link
to={`/users/${pubkey}`}
className="inline-flex h-10 items-center rounded-md px-2 text-sm font-medium text-white backdrop-blur-xl hover:bg-white/10"
className="inline-flex h-10 items-center rounded-md px-2 text-sm font-medium text-white hover:bg-white/10"
>
View profile
</Link>

View File

@ -4,7 +4,6 @@ import { QRCodeSVG } from 'qrcode.react';
import { useState } from 'react';
import { twMerge } from 'tailwind-merge';
import { Button } from '@shared/button';
import { CancelIcon, ZapIcon } from '@shared/icons';
import { useEvent } from '@utils/hooks/useEvent';
@ -42,7 +41,7 @@ export function NoteZap({ id }: { id: string }) {
<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 backdrop-blur-xl">
<div className="relative h-min w-full shrink-0 border-b border-white/10 bg-white/5 px-5 py-5">
<div className="relative h-min w-full shrink-0 border-b border-white/5 bg-white/5 px-5 py-5">
<div className="flex flex-col items-center gap-1.5">
<Dialog.Title className="font-medium leading-none text-white">
Zap (Beta)
@ -63,7 +62,7 @@ export function NoteZap({ id }: { id: string }) {
type="button"
onClick={() => setAmount(21000)}
className={twMerge(
'inline-flex flex-col items-center justify-center gap-2 rounded-md px-2 py-2 backdrop-blur-xl hover:bg-white/10',
'inline-flex flex-col items-center justify-center gap-2 rounded-lg px-2 py-2 backdrop-blur-xl hover:bg-white/10',
`${selected(21000) && 'bg-white/10 backdrop-blur-xl'}`
)}
>
@ -76,7 +75,7 @@ export function NoteZap({ id }: { id: string }) {
type="button"
onClick={() => setAmount(69000)}
className={twMerge(
'inline-flex flex-col items-center justify-center gap-2 rounded-md px-2 py-2 backdrop-blur-xl hover:bg-white/10',
'inline-flex flex-col items-center justify-center gap-2 rounded-lg px-2 py-2 backdrop-blur-xl hover:bg-white/10',
`${selected(69000) && 'bg-white/10 backdrop-blur-xl'}`
)}
>
@ -89,7 +88,7 @@ export function NoteZap({ id }: { id: string }) {
type="button"
onClick={() => setAmount(100000)}
className={twMerge(
'inline-flex flex-col items-center justify-center gap-2 rounded-md px-2 py-2 backdrop-blur-xl hover:bg-white/10',
'inline-flex flex-col items-center justify-center gap-2 rounded-lg px-2 py-2 backdrop-blur-xl hover:bg-white/10',
`${selected(100000) && 'bg-white/10 backdrop-blur-xl'}`
)}
>
@ -102,7 +101,7 @@ export function NoteZap({ id }: { id: string }) {
type="button"
onClick={() => setAmount(200000)}
className={twMerge(
'inline-flex flex-col items-center justify-center gap-2 rounded-md px-2 py-2 backdrop-blur-xl hover:bg-white/10',
'inline-flex flex-col items-center justify-center gap-2 rounded-lg px-2 py-2 backdrop-blur-xl hover:bg-white/10',
`${selected(200000) && 'bg-white/10 backdrop-blur-xl'}`
)}
>
@ -115,7 +114,7 @@ export function NoteZap({ id }: { id: string }) {
type="button"
onClick={() => setAmount(500000)}
className={twMerge(
'inline-flex flex-col items-center justify-center gap-2 rounded-md px-2 py-2 backdrop-blur-xl hover:bg-white/10',
'inline-flex flex-col items-center justify-center gap-2 rounded-lg px-2 py-2 backdrop-blur-xl hover:bg-white/10',
`${selected(500000) && 'bg-white/10 backdrop-blur-xl'}`
)}
>
@ -128,7 +127,7 @@ export function NoteZap({ id }: { id: string }) {
type="button"
onClick={() => setAmount(1000000)}
className={twMerge(
'inline-flex flex-col items-center justify-center gap-2 rounded-md px-2 py-2 backdrop-blur-xl hover:bg-white/10',
'inline-flex flex-col items-center justify-center gap-2 rounded-lg px-2 py-2 backdrop-blur-xl hover:bg-white/10',
`${selected(1000000) && 'bg-white/10 backdrop-blur-xl'}`
)}
>
@ -139,9 +138,13 @@ export function NoteZap({ id }: { id: string }) {
</button>
</div>
<div className="mt-4 flex w-full">
<Button onClick={() => createZapRequest()} preset="large">
<button
type="button"
onClick={() => createZapRequest()}
className="inline-flex h-11 w-full items-center justify-center rounded-lg bg-fuchsia-500 px-4 hover:bg-fuchsia-600"
>
Create invoice
</Button>
</button>
</div>
</>
) : (

View File

@ -25,8 +25,13 @@ export function ChildNote({ id, root }: { id: string; root?: string }) {
if (status === 'error') {
return (
<div className="mb-5 flex overflow-hidden rounded-xl bg-white/10 px-3 py-3 backdrop-blur-xl">
<p className="break-all text-white/50">Failed to fetch event: {id}</p>
<div className="mb-5 flex flex-col gap-1.5 overflow-hidden rounded-xl bg-white/10 px-3 py-3 backdrop-blur-xl">
<p className="text-sm font-bold text-white">
Lume cannot found the event with ID
</p>
<div className="inline-flex items-center justify-center rounded-xl border border-dashed border-red-400 bg-red-200/10 p-2">
<p className="select-text break-all text-sm font-medium text-red-400">{id}</p>
</div>
</div>
);
}

View File

@ -19,7 +19,7 @@ export function NoteWrapper({
reply?: string;
}) {
return (
<div className="h-min w-full px-3 py-1.5">
<div className="h-min w-full px-3 pb-3">
<div className="relative overflow-hidden rounded-xl bg-white/10 px-3 pt-3 backdrop-blur-xl">
<div className="relative">{root && <ChildNote id={root} />}</div>
<div className="relative">{reply && <ChildNote id={reply} root={root} />}</div>

View File

@ -11,15 +11,15 @@ export function TitleBar({ id, title }: { id?: string; title: string }) {
return (
<div
data-tauri-drag-region
className="group flex h-11 w-full shrink-0 items-center justify-between overflow-hidden px-3"
className="flex h-11 w-full shrink-0 items-center justify-between overflow-hidden px-3"
>
<div className="w-6" />
<h3 className="text-sm font-medium text-white">{title}</h3>
<h3 className="text-sm font-bold text-white">{title}</h3>
{id ? (
<button
type="button"
onClick={() => remove(db, id)}
className="inline-flex h-6 w-6 shrink translate-y-8 transform items-center justify-center rounded backdrop-blur-xl transition-transform duration-150 ease-in-out hover:bg-white/10 group-hover:translate-y-0"
className="inline-flex h-6 w-6 shrink-0 transform items-center justify-center rounded backdrop-blur-xl hover:bg-white/10"
>
<CancelIcon className="h-3 w-3 text-white" />
</button>

View File

@ -4,6 +4,8 @@ import { useQuery } from '@tanstack/react-query';
import { useNDK } from '@libs/ndk/provider';
import { useStorage } from '@libs/storage/provider';
import { toRawEvent } from '@utils/rawEvent';
export function useEvent(id: string, embed?: string) {
const { db } = useStorage();
const { ndk } = useNDK();
@ -34,9 +36,10 @@ export function useEvent(id: string, embed?: string) {
reply = event.tags.find((el) => el[3] === 'reply')?.[1];
}
const rawEvent = toRawEvent(event);
await db.createEvent(
event.id,
JSON.stringify(event),
JSON.stringify(rawEvent),
event.pubkey,
event.kind,
root,

View File

@ -45,14 +45,6 @@ export function useNostr() {
subManager.set(JSON.stringify(filter), subEvent);
subEvent.addListener('event', (event: NDKEvent) => {
delete event.ndk;
delete event.decrypt;
delete event.encrypt;
delete event.encode;
delete event.isParamReplaceable;
delete event.isReplaceable;
delete event.repost;
delete event.relay;
callback(event);
});
};

13
src/utils/rawEvent.ts Normal file
View File

@ -0,0 +1,13 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
export function toRawEvent(event: NDKEvent) {
delete event.ndk;
delete event.decrypt;
delete event.encrypt;
delete event.encode;
delete event.isParamReplaceable;
delete event.isReplaceable;
delete event.repost;
delete event.relay;
return event;
}