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,
} from "@nostr-dev-kit/ndk";
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 { save } from "@tauri-apps/plugin-dialog";
import { writeTextFile } from "@tauri-apps/plugin-fs";
import { useSetAtom } from "jotai";
import { nanoid } from "nanoid";
import { getPublicKey, nip19 } from "nostr-tools";
import { useState } from "react";
import { useForm } from "react-hook-form";
@ -66,18 +67,20 @@ export function CreateAccountScreen() {
ark.updateNostrSigner({ signer });
const downloadPath = await downloadDir();
const fileName = `nostr_keys_${new Date().getTime().toString(36)}.txt`;
const downloadPath = await desktopDir();
const fileName = `nostr_keys_${nanoid(4)}.txt`;
const filePath = await save({
defaultPath: `${downloadPath}/${fileName}`,
});
if (filePath) {
await writeTextFile(
filePath,
`Nostr account, generated by Lume (lume.nu)\nPublic key: ${npub}\nPrivate key: ${nsec}`,
);
} // else { user cancel action }
if (!filePath) {
return toast.info("You need to save account keys before continue.");
}
await writeTextFile(
filePath,
`Nostr Account\nGenerated by Lume (lume.nu)\n---\nPublic key: ${npub}\nPrivate key: ${nsec}`,
);
await storage.createAccount({
pubkey: pubkey,
@ -180,8 +183,8 @@ export function CreateAccountScreen() {
Let's get you set up on Nostr.
</h1>
<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
clients, all your data are synced.
Get started with familiar way, but all data belong to you and you
have ability controls everything.
</p>
</div>
{!services ? (
@ -221,7 +224,7 @@ export function CreateAccountScreen() {
</Select.Icon>
</Select.Trigger>
<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.Group>
<Select.Label className="mb-2 text-sm font-medium uppercase px-7 text-neutral-600">
@ -254,28 +257,35 @@ export function CreateAccountScreen() {
/>
</div>
</div>
<button
type="submit"
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" />
) : (
"Create Account"
)}
</button>
<div>
<button
type="submit"
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" />
) : (
"Create Account"
)}
</button>
</div>
</form>
<div className="flex flex-col gap-6">
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-neutral-900" />
</div>
<div className="relative flex justify-center">
<span className="px-2 font-medium bg-black text-neutral-600">
Or
</span>
<div className="flex flex-col">
<div className="relative">
<div className="absolute inset-0 flex items-center">
<div className="w-full border-t border-neutral-900" />
</div>
<div className="relative flex justify-center">
<span className="px-2 font-medium bg-black text-neutral-500">
Or
</span>
</div>
</div>
<span className="mx-auto text-xs font-medium bg-black text-neutral-600">
More compatible with other Nostr clients
</span>
</div>
<div>
<button

View File

@ -15,7 +15,7 @@ export function LoginScreen() {
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"
>
Login with address
Login with Address
</Link>
<Link
to="/auth/login-nsecbunker"
@ -31,7 +31,7 @@ export function LoginScreen() {
</div>
<div className="relative flex justify-center">
<span className="px-2 font-medium bg-black text-neutral-600">
Or (Not recommend)
Or (Not recommended)
</span>
</div>
</div>

View File

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

View File

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

View File

@ -17,13 +17,10 @@ export function AvatarUploadButton({
setLoading(true);
const image = await ark.upload({ fileExts: [] });
if (image) {
setPicture(image);
setLoading(false);
}
return;
} catch (e) {
setLoading(false);
toast.error(e);
@ -34,7 +31,7 @@ export function AvatarUploadButton({
<button
type="button"
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 ? (
<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 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 ? (
<button
type="button"
@ -29,9 +29,6 @@ export function AuthLayout({ platform }: { platform: Platform }) {
) : (
<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>
<Outlet />
</div>

View File

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

View File

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