feat: polish

This commit is contained in:
reya
2024-01-17 08:50:43 +07:00
parent 33dd8b1d8a
commit c29b4e173e
8 changed files with 60 additions and 49 deletions

View File

@@ -9,11 +9,12 @@ import NDK, {
NDKPrivateKeySigner, NDKPrivateKeySigner,
} from "@nostr-dev-kit/ndk"; } from "@nostr-dev-kit/ndk";
import * as Select from "@radix-ui/react-select"; import * as Select from "@radix-ui/react-select";
import { downloadDir } from "@tauri-apps/api/path"; import { desktopDir } from "@tauri-apps/api/path";
import { Window } from "@tauri-apps/api/window"; import { Window } from "@tauri-apps/api/window";
import { save } from "@tauri-apps/plugin-dialog"; import { save } from "@tauri-apps/plugin-dialog";
import { writeTextFile } from "@tauri-apps/plugin-fs"; import { writeTextFile } from "@tauri-apps/plugin-fs";
import { useSetAtom } from "jotai"; import { useSetAtom } from "jotai";
import { nanoid } from "nanoid";
import { getPublicKey, nip19 } from "nostr-tools"; import { getPublicKey, nip19 } from "nostr-tools";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -66,18 +67,20 @@ export function CreateAccountScreen() {
ark.updateNostrSigner({ signer }); ark.updateNostrSigner({ signer });
const downloadPath = await downloadDir(); const downloadPath = await desktopDir();
const fileName = `nostr_keys_${new Date().getTime().toString(36)}.txt`; const fileName = `nostr_keys_${nanoid(4)}.txt`;
const filePath = await save({ const filePath = await save({
defaultPath: `${downloadPath}/${fileName}`, defaultPath: `${downloadPath}/${fileName}`,
}); });
if (filePath) { if (!filePath) {
await writeTextFile( return toast.info("You need to save account keys before continue.");
filePath, }
`Nostr account, generated by Lume (lume.nu)\nPublic key: ${npub}\nPrivate key: ${nsec}`,
); await writeTextFile(
} // else { user cancel action } filePath,
`Nostr Account\nGenerated by Lume (lume.nu)\n---\nPublic key: ${npub}\nPrivate key: ${nsec}`,
);
await storage.createAccount({ await storage.createAccount({
pubkey: pubkey, pubkey: pubkey,
@@ -180,8 +183,8 @@ export function CreateAccountScreen() {
Let's get you set up on Nostr. Let's get you set up on Nostr.
</h1> </h1>
<p className="text-lg font-medium leading-snug text-neutral-600 dark:text-neutral-500"> <p className="text-lg font-medium leading-snug text-neutral-600 dark:text-neutral-500">
With an account on Nostr, you'll be able to travel across all nostr Get started with familiar way, but all data belong to you and you
clients, all your data are synced. have ability controls everything.
</p> </p>
</div> </div>
{!services ? ( {!services ? (
@@ -221,7 +224,7 @@ export function CreateAccountScreen() {
</Select.Icon> </Select.Icon>
</Select.Trigger> </Select.Trigger>
<Select.Portal> <Select.Portal>
<Select.Content className="border rounded-lg bg-neutral-950 border-neutral-900"> <Select.Content className="rounded-lg border border-white/20 bg-white/10 backdrop-blur-xl">
<Select.Viewport className="p-3"> <Select.Viewport className="p-3">
<Select.Group> <Select.Group>
<Select.Label className="mb-2 text-sm font-medium uppercase px-7 text-neutral-600"> <Select.Label className="mb-2 text-sm font-medium uppercase px-7 text-neutral-600">
@@ -254,28 +257,35 @@ export function CreateAccountScreen() {
/> />
</div> </div>
</div> </div>
<button <div>
type="submit" <button
disabled={!isValid} type="submit"
className="inline-flex items-center justify-center w-full text-lg h-12 font-medium text-white bg-blue-500 rounded-xl hover:bg-blue-600 disabled:opacity-50" disabled={!isValid}
> className="inline-flex items-center justify-center w-full text-lg h-12 font-medium text-white bg-blue-500 rounded-xl hover:bg-blue-600 disabled:opacity-50"
{loading ? ( >
<LoaderIcon className="size-5 animate-spin" /> {loading ? (
) : ( <LoaderIcon className="size-5 animate-spin" />
"Create Account" ) : (
)} "Create Account"
</button> )}
</button>
</div>
</form> </form>
<div className="flex flex-col gap-6"> <div className="flex flex-col gap-6">
<div className="relative"> <div className="flex flex-col">
<div className="absolute inset-0 flex items-center"> <div className="relative">
<div className="w-full border-t border-neutral-900" /> <div className="absolute inset-0 flex items-center">
</div> <div className="w-full border-t border-neutral-900" />
<div className="relative flex justify-center"> </div>
<span className="px-2 font-medium bg-black text-neutral-600"> <div className="relative flex justify-center">
Or <span className="px-2 font-medium bg-black text-neutral-500">
</span> Or
</span>
</div>
</div> </div>
<span className="mx-auto text-xs font-medium bg-black text-neutral-600">
More compatible with other Nostr clients
</span>
</div> </div>
<div> <div>
<button <button

View File

@@ -15,7 +15,7 @@ export function LoginScreen() {
to="/auth/login-oauth" to="/auth/login-oauth"
className="inline-flex items-center justify-center w-full h-12 text-lg font-medium text-white bg-blue-500 rounded-xl hover:bg-blue-600" className="inline-flex items-center justify-center w-full h-12 text-lg font-medium text-white bg-blue-500 rounded-xl hover:bg-blue-600"
> >
Login with address Login with Address
</Link> </Link>
<Link <Link
to="/auth/login-nsecbunker" to="/auth/login-nsecbunker"
@@ -31,7 +31,7 @@ export function LoginScreen() {
</div> </div>
<div className="relative flex justify-center"> <div className="relative flex justify-center">
<span className="px-2 font-medium bg-black text-neutral-600"> <span className="px-2 font-medium bg-black text-neutral-600">
Or (Not recommend) Or (Not recommended)
</span> </span>
</div> </div>
</div> </div>

View File

@@ -88,8 +88,8 @@ export function ProfileSettingScreen() {
if (publish) { if (publish) {
// invalid cache // invalid cache
await storage.clearProfileCache(ark.account.pubkey); await storage.clearProfileCache(ark.account.pubkey);
await queryClient.invalidateQueries({ await queryClient.setQueryData(["user", ark.account.pubkey], () => {
queryKey: ["user", ark.account.pubkey], return content;
}); });
// reset state // reset state

View File

@@ -105,7 +105,11 @@ export class Ark {
public getCleanPubkey(pubkey: string) { public getCleanPubkey(pubkey: string) {
try { try {
let hexstring = pubkey.replace("nostr:", "").split("'")[0].split(".")[0]; let hexstring = pubkey
.replace("nostr:", "")
.split("'")[0]
.split(".")[0]
.split("?")[0];
if ( if (
hexstring.startsWith("npub1") || hexstring.startsWith("npub1") ||

View File

@@ -17,13 +17,10 @@ export function AvatarUploadButton({
setLoading(true); setLoading(true);
const image = await ark.upload({ fileExts: [] }); const image = await ark.upload({ fileExts: [] });
if (image) { if (image) {
setPicture(image); setPicture(image);
setLoading(false); setLoading(false);
} }
return;
} catch (e) { } catch (e) {
setLoading(false); setLoading(false);
toast.error(e); toast.error(e);
@@ -34,7 +31,7 @@ export function AvatarUploadButton({
<button <button
type="button" type="button"
onClick={() => uploadAvatar()} onClick={() => uploadAvatar()}
className="inline-flex items-center justify-center rounded-lg border border-blue-200 bg-blue-100 px-2 py-1.5 text-sm font-medium text-blue-500 hover:border-blue-300 hover:bg-blue-200 dark:border-blue-800 dark:bg-blue-900 dark:text-blue-500 dark:hover:border-blue-800 dark:hover:bg-blue-800" className="inline-flex items-center justify-center rounded-lg border border-blue-200 bg-blue-100 w-32 px-2 py-1.5 text-sm font-medium text-blue-500 hover:border-blue-300 hover:bg-blue-200 dark:border-blue-800 dark:bg-blue-900 dark:text-blue-500 dark:hover:border-blue-800 dark:hover:bg-blue-800"
> >
{loading ? ( {loading ? (
<LoaderIcon className="size-4 animate-spin" /> <LoaderIcon className="size-4 animate-spin" />

View File

@@ -17,7 +17,7 @@ export function AuthLayout({ platform }: { platform: Platform }) {
<div data-tauri-drag-region className="h-9 shrink-0" /> <div data-tauri-drag-region className="h-9 shrink-0" />
)} )}
<div className="relative w-full h-full"> <div className="relative w-full h-full">
<div className="absolute top-0 z-10 flex items-center justify-between w-full px-9"> <div className="absolute top-8 z-10 flex items-center justify-between w-full px-9">
{canGoBack ? ( {canGoBack ? (
<button <button
type="button" type="button"
@@ -29,9 +29,6 @@ export function AuthLayout({ platform }: { platform: Platform }) {
) : ( ) : (
<div /> <div />
)} )}
<div className="inline-flex items-center justify-center rounded-lg size-10 bg-neutral-950 group hover:bg-neutral-900">
<SettingsIcon className="size-6 text-neutral-700 group-hover:text-neutral-500" />
</div>
</div> </div>
<Outlet /> <Outlet />
</div> </div>

View File

@@ -7,7 +7,6 @@ import { useSetAtom } from "jotai";
import { useState } from "react"; import { useState } from "react";
export function OnboardingFinishScreen() { export function OnboardingFinishScreen() {
const ark = useArk();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const setOnboarding = useSetAtom(onboardingAtom); const setOnboarding = useSetAtom(onboardingAtom);
@@ -19,10 +18,6 @@ export function OnboardingFinishScreen() {
const queryCache = queryClient.getQueryCache(); const queryCache = queryClient.getQueryCache();
const queryKeys = queryCache.getAll().map((cache) => cache.queryKey); const queryKeys = queryCache.getAll().map((cache) => cache.queryKey);
await queryClient.refetchQueries({
queryKey: ["user", ark.account.pubkey],
});
for (const key of queryKeys) { for (const key of queryKeys) {
await queryClient.refetchQueries({ queryKey: key }); await queryClient.refetchQueries({ queryKey: key });
} }

View File

@@ -2,6 +2,7 @@ import { useArk } from "@lume/ark";
import { ArrowLeftIcon, LoaderIcon } from "@lume/icons"; import { ArrowLeftIcon, LoaderIcon } from "@lume/icons";
import { useStorage } from "@lume/storage"; import { useStorage } from "@lume/storage";
import { NDKKind, NDKUserProfile } from "@nostr-dev-kit/ndk"; import { NDKKind, NDKUserProfile } from "@nostr-dev-kit/ndk";
import { useQueryClient } from "@tanstack/react-query";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { minidenticon } from "minidenticons"; import { minidenticon } from "minidenticons";
import { useState } from "react"; import { useState } from "react";
@@ -16,6 +17,7 @@ export function OnboardingProfileSettingsScreen() {
const ark = useArk(); const ark = useArk();
const storage = useStorage(); const storage = useStorage();
const queryClient = useQueryClient();
const navigate = useNavigate(); const navigate = useNavigate();
const { register, handleSubmit } = useForm(); const { register, handleSubmit } = useForm();
@@ -52,6 +54,12 @@ export function OnboardingProfileSettingsScreen() {
}); });
if (publish) { if (publish) {
// invalid cache
await storage.clearProfileCache(ark.account.pubkey);
await queryClient.setQueryData(["user", ark.account.pubkey], () => {
return profile;
});
setLoading(false); setLoading(false);
navigate("/follow"); navigate("/follow");
} }