diff --git a/apps/desktop/src/router.tsx b/apps/desktop/src/router.tsx
index 79f4e666..3fd3b071 100644
--- a/apps/desktop/src/router.tsx
+++ b/apps/desktop/src/router.tsx
@@ -35,81 +35,70 @@ export default function Router() {
return { Component: HomeScreen };
},
},
+ ],
+ },
+ {
+ path: "settings",
+ element: ,
+ children: [
{
- path: "settings",
- element: ,
- children: [
- {
- index: true,
- async lazy() {
- const { UserSettingScreen } = await import(
- "./routes/settings"
- );
- return { Component: UserSettingScreen };
- },
- },
- {
- path: "edit-profile",
- async lazy() {
- const { EditProfileScreen } = await import(
- "./routes/settings/editProfile"
- );
- return { Component: EditProfileScreen };
- },
- },
- {
- path: "edit-contact",
- async lazy() {
- const { EditContactScreen } = await import(
- "./routes/settings/editContact"
- );
- return { Component: EditContactScreen };
- },
- },
- {
- path: "general",
- async lazy() {
- const { GeneralSettingScreen } = await import(
- "./routes/settings/general"
- );
- return { Component: GeneralSettingScreen };
- },
- },
- {
- path: "backup",
- async lazy() {
- const { BackupSettingScreen } = await import(
- "./routes/settings/backup"
- );
- return { Component: BackupSettingScreen };
- },
- },
- {
- path: "advanced",
- async lazy() {
- const { AdvancedSettingScreen } = await import(
- "./routes/settings/advanced"
- );
- return { Component: AdvancedSettingScreen };
- },
- },
- {
- path: "nwc",
- async lazy() {
- const { NWCScreen } = await import("./routes/settings/nwc");
- return { Component: NWCScreen };
- },
- },
- {
- path: "about",
- async lazy() {
- const { AboutScreen } = await import(
- "./routes/settings/about"
- );
- return { Component: AboutScreen };
- },
- },
- ],
+ index: true,
+ async lazy() {
+ const { GeneralSettingScreen } = await import(
+ "./routes/settings/general"
+ );
+ return { Component: GeneralSettingScreen };
+ },
+ },
+ {
+ path: "profile",
+ async lazy() {
+ const { ProfileSettingScreen } = await import(
+ "./routes/settings/profile"
+ );
+ return { Component: ProfileSettingScreen };
+ },
+ },
+ {
+ path: "edit-contact",
+ async lazy() {
+ const { EditContactScreen } = await import(
+ "./routes/settings/editContact"
+ );
+ return { Component: EditContactScreen };
+ },
+ },
+ {
+ path: "backup",
+ async lazy() {
+ const { BackupSettingScreen } = await import(
+ "./routes/settings/backup"
+ );
+ return { Component: BackupSettingScreen };
+ },
+ },
+ {
+ path: "advanced",
+ async lazy() {
+ const { AdvancedSettingScreen } = await import(
+ "./routes/settings/advanced"
+ );
+ return { Component: AdvancedSettingScreen };
+ },
+ },
+ {
+ path: "nwc",
+ async lazy() {
+ const { NWCScreen } = await import("./routes/settings/nwc");
+ return { Component: NWCScreen };
+ },
+ },
+ {
+ path: "about",
+ async lazy() {
+ const { AboutScreen } = await import("./routes/settings/about");
+ return { Component: AboutScreen };
+ },
},
],
},
diff --git a/apps/desktop/src/routes/settings/components/avatarUpload.tsx b/apps/desktop/src/routes/settings/components/avatarUpload.tsx
new file mode 100644
index 00000000..54ae1618
--- /dev/null
+++ b/apps/desktop/src/routes/settings/components/avatarUpload.tsx
@@ -0,0 +1,43 @@
+import { useArk } from "@lume/ark";
+import { LoaderIcon } from "@lume/icons";
+import { useState } from "react";
+import { toast } from "sonner";
+
+export function AvatarUpload({ setPicture }) {
+ const ark = useArk();
+ const [loading, setLoading] = useState(false);
+
+ const upload = async () => {
+ try {
+ setLoading(true);
+
+ // upload image to nostr.build server
+ // #TODO: support multiple server
+ const image = await ark.upload({ fileExts: [] });
+
+ if (!image)
+ toast.error("Failed to upload image, please try again later.");
+
+ setPicture(image);
+ setLoading(false);
+ } catch (e) {
+ setLoading(false);
+ toast.error("Failed to upload image, please try again later.");
+ }
+ };
+
+ return (
+
+ );
+}
diff --git a/apps/desktop/src/routes/settings/components/coverUpload.tsx b/apps/desktop/src/routes/settings/components/coverUpload.tsx
new file mode 100644
index 00000000..88f1ebf8
--- /dev/null
+++ b/apps/desktop/src/routes/settings/components/coverUpload.tsx
@@ -0,0 +1,43 @@
+import { useArk } from "@lume/ark";
+import { LoaderIcon } from "@lume/icons";
+import { useState } from "react";
+import { toast } from "sonner";
+
+export function CoverUpload({ setBanner }) {
+ const ark = useArk();
+ const [loading, setLoading] = useState(false);
+
+ const upload = async () => {
+ try {
+ setLoading(true);
+
+ // upload image to nostr.build server
+ // #TODO: support multiple server
+ const image = await ark.upload({ fileExts: [] });
+
+ if (!image)
+ toast.error("Failed to upload image, please try again later.");
+
+ setBanner(image);
+ setLoading(false);
+ } catch (e) {
+ setLoading(false);
+ toast.error("Failed to upload image, please try again later.");
+ }
+ };
+
+ return (
+
+ );
+}
diff --git a/apps/desktop/src/routes/settings/index.tsx b/apps/desktop/src/routes/settings/index.tsx
deleted file mode 100644
index 9ec682df..00000000
--- a/apps/desktop/src/routes/settings/index.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { ContactCard } from "./components/contactCard";
-import { PostCard } from "./components/postCard";
-import { ProfileCard } from "./components/profileCard";
-import { RelayCard } from "./components/relayCard";
-import { ZapCard } from "./components/zapCard";
-
-export function UserSettingScreen() {
- return (
-
- );
-}
diff --git a/apps/desktop/src/routes/settings/editProfile.tsx b/apps/desktop/src/routes/settings/profile.tsx
similarity index 67%
rename from apps/desktop/src/routes/settings/editProfile.tsx
rename to apps/desktop/src/routes/settings/profile.tsx
index 6e01f923..99e48ed4 100644
--- a/apps/desktop/src/routes/settings/editProfile.tsx
+++ b/apps/desktop/src/routes/settings/profile.tsx
@@ -5,25 +5,27 @@ import {
PlusIcon,
UnverifiedIcon,
} from "@lume/icons";
+import { useStorage } from "@lume/storage";
import { NDKKind, NDKUserProfile } from "@nostr-dev-kit/ndk";
import { useQueryClient } from "@tanstack/react-query";
-import { message } from "@tauri-apps/plugin-dialog";
import { useState } from "react";
import { useForm } from "react-hook-form";
-import { useNavigate } from "react-router-dom";
+import { AvatarUpload } from "./components/avatarUpload";
+import { CoverUpload } from "./components/coverUpload";
+
+export function ProfileSettingScreen() {
+ const ark = useArk();
+ const storage = useStorage();
+ const queryClient = useQueryClient();
-export function EditProfileScreen() {
const [loading, setLoading] = useState(false);
const [picture, setPicture] = useState("");
const [banner, setBanner] = useState("");
const [nip05, setNIP05] = useState({ verified: true, text: "" });
- const ark = useArk();
-
const {
register,
handleSubmit,
- reset,
setError,
formState: { isValid, errors },
} = useForm({
@@ -45,48 +47,6 @@ export function EditProfileScreen() {
},
});
- const queryClient = useQueryClient();
- const navigate = useNavigate();
-
- const uploadAvatar = async () => {
- try {
- if (!ark.ndk.signer) return navigate("/new/privkey");
-
- setLoading(true);
-
- const image = await ark.upload({ fileExts: [] });
- if (image) {
- setPicture(image);
- setLoading(false);
- }
- } catch (e) {
- setLoading(false);
- await message(`Upload failed, error: ${e}`, {
- title: "Lume",
- type: "error",
- });
- }
- };
-
- const uploadBanner = async () => {
- try {
- setLoading(true);
-
- const image = await ark.upload({ fileExts: [] });
-
- if (image) {
- setBanner(image);
- setLoading(false);
- }
- } catch (e) {
- setLoading(false);
- await message(`Upload failed, error: ${e}`, {
- title: "Lume",
- type: "error",
- });
- }
- };
-
const onSubmit = async (data: NDKUserProfile) => {
// start loading
setLoading(true);
@@ -94,9 +54,12 @@ export function EditProfileScreen() {
let content = {
...data,
username: data.name,
- display_name: data.name,
+ display_name: data.displayName,
bio: data.about,
- image: data.picture,
+ image: picture,
+ cover: banner,
+ picture,
+ banner,
};
if (data.nip05) {
@@ -104,13 +67,14 @@ export function EditProfileScreen() {
pubkey: ark.account.pubkey,
nip05: data.nip05,
});
+
if (verify) {
content = { ...content, nip05: data.nip05 };
} else {
setNIP05((prev) => ({ ...prev, verified: false }));
setError("nip05", {
type: "manual",
- message: "Can't verify your Lume ID / NIP-05, please check again",
+ message: "Can't verify your NIP-05, please check again",
});
}
}
@@ -123,76 +87,59 @@ export function EditProfileScreen() {
if (publish) {
// invalid cache
- queryClient.invalidateQueries({
+ await storage.clearProfileCache(ark.account.pubkey);
+ await queryClient.invalidateQueries({
queryKey: ["user", ark.account.pubkey],
});
- // reset form
- reset();
+
// reset state
- setLoading(false);
setPicture(null);
setBanner(null);
- } else {
- setLoading(false);
}
+
+ setLoading(false);
};
return (
-