diff --git a/package.json b/package.json
index f8814139..65419c67 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"@headlessui/react": "^1.7.16",
"@nostr-dev-kit/ndk": "^0.8.11",
"@nostr-fetch/adapter-ndk": "^0.11.0",
+ "@radix-ui/react-alert-dialog": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-popover": "^1.0.6",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a4ee7ec8..49871a6f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -13,6 +13,9 @@ dependencies:
'@nostr-fetch/adapter-ndk':
specifier: ^0.11.0
version: 0.11.0(@nostr-dev-kit/ndk@0.8.11)(nostr-fetch@0.12.2)
+ '@radix-ui/react-alert-dialog':
+ specifier: ^1.0.4
+ version: 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-collapsible':
specifier: ^1.0.3
version: 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0)
@@ -1068,6 +1071,32 @@ packages:
'@babel/runtime': 7.22.10
dev: false
+ /@radix-ui/react-alert-dialog@1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-jbfBCRlKYlhbitueOAv7z74PXYeIQmWpKwm3jllsdkw7fGWNkxqP3v0nY9WmOzcPqpQuoorNtvViBgL46n5gVg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.22.10
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.20)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.20)(react@18.2.0)
+ '@radix-ui/react-dialog': 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.20)(react@18.2.0)
+ '@types/react': 18.2.20
+ '@types/react-dom': 18.2.7
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.20)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
peerDependencies:
diff --git a/src/app/space/components/modals/feed.tsx b/src/app/space/components/modals/feed.tsx
index c0c6bc78..aa91ec56 100644
--- a/src/app/space/components/modals/feed.tsx
+++ b/src/app/space/components/modals/feed.tsx
@@ -1,6 +1,5 @@
import { Combobox } from '@headlessui/react';
import * as Dialog from '@radix-ui/react-dialog';
-import { useMutation, useQueryClient } from '@tanstack/react-query';
import { nip19 } from 'nostr-tools';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
@@ -8,18 +7,15 @@ import { useHotkeys } from 'react-hotkeys-hook';
import { User } from '@app/auth/components/user';
-import { createWidget } from '@libs/storage';
-
import { CancelIcon, CheckCircleIcon, CommandIcon, LoaderIcon } from '@shared/icons';
import { BLOCK_KINDS, DEFAULT_AVATAR } from '@stores/constants';
import { ADD_FEEDBLOCK_SHORTCUT } from '@stores/shortcuts';
+import { useWidgets } from '@stores/widgets';
import { useAccount } from '@utils/hooks/useAccount';
export function FeedModal() {
- const queryClient = useQueryClient();
-
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [selected, setSelected] = useState([]);
@@ -27,16 +23,9 @@ export function FeedModal() {
const { status, account } = useAccount();
- useHotkeys(ADD_FEEDBLOCK_SHORTCUT, () => setOpen(true));
+ const setWidget = useWidgets((state) => state.setWidget);
- const block = useMutation({
- mutationFn: (data: { kind: number; title: string; content: string }) => {
- return createWidget(data.kind, data.title, data.content);
- },
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['blocks'] });
- },
- });
+ useHotkeys(ADD_FEEDBLOCK_SHORTCUT, () => setOpen(true));
const {
register,
@@ -55,7 +44,7 @@ export function FeedModal() {
});
// insert to database
- block.mutate({
+ setWidget({
kind: BLOCK_KINDS.feed,
title: data.title,
content: JSON.stringify(selected),
@@ -83,7 +72,7 @@ export function FeedModal() {
F
-
New feed block
+ Add newsfeed widget
diff --git a/src/app/space/components/modals/hashtag.tsx b/src/app/space/components/modals/hashtag.tsx
index ee47d528..96e7ebfa 100644
--- a/src/app/space/components/modals/hashtag.tsx
+++ b/src/app/space/components/modals/hashtag.tsx
@@ -1,22 +1,20 @@
import * as Dialog from '@radix-ui/react-dialog';
-import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { useHotkeys } from 'react-hotkeys-hook';
-import { createWidget } from '@libs/storage';
-
import { CancelIcon, CommandIcon, LoaderIcon } from '@shared/icons';
import { BLOCK_KINDS } from '@stores/constants';
import { ADD_HASHTAGBLOCK_SHORTCUT } from '@stores/shortcuts';
+import { useWidgets } from '@stores/widgets';
export function HashtagModal() {
- const queryClient = useQueryClient();
-
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
+ const setWidget = useWidgets((state) => state.setWidget);
+
useHotkeys(ADD_HASHTAGBLOCK_SHORTCUT, () => setOpen(false));
const {
@@ -26,20 +24,11 @@ export function HashtagModal() {
formState: { isDirty, isValid },
} = useForm();
- const block = useMutation({
- mutationFn: (data: { kind: number; title: string; content: string }) => {
- return createWidget(data.kind, data.title, data.content);
- },
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['blocks'] });
- },
- });
-
const onSubmit = async (data: { hashtag: string }) => {
setLoading(true);
// mutate
- block.mutate({
+ setWidget({
kind: BLOCK_KINDS.hashtag,
title: data.hashtag,
content: data.hashtag.replace('#', ''),
@@ -67,7 +56,7 @@ export function HashtagModal() {
T
- New hashtag block
+ Add hashtag widget
diff --git a/src/app/space/components/modals/image.tsx b/src/app/space/components/modals/image.tsx
index 188f018e..e51cbdc3 100644
--- a/src/app/space/components/modals/image.tsx
+++ b/src/app/space/components/modals/image.tsx
@@ -1,32 +1,25 @@
import * as Dialog from '@radix-ui/react-dialog';
-import { useMutation, useQueryClient } from '@tanstack/react-query';
-import { useEffect, useRef, useState } from 'react';
+import { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useHotkeys } from 'react-hotkeys-hook';
-import { createWidget } from '@libs/storage';
-
import { CancelIcon, CommandIcon, LoaderIcon } from '@shared/icons';
import { Image } from '@shared/image';
import { BLOCK_KINDS, DEFAULT_AVATAR } from '@stores/constants';
import { ADD_IMAGEBLOCK_SHORTCUT } from '@stores/shortcuts';
+import { useWidgets } from '@stores/widgets';
-import { useNostr } from '@utils/hooks/useNostr';
import { useImageUploader } from '@utils/hooks/useUploader';
export function ImageModal() {
- const queryClient = useQueryClient();
const upload = useImageUploader();
-
- const { publish } = useNostr();
+ const setWidget = useWidgets((state) => state.setWidget);
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [image, setImage] = useState('');
- const tags = useRef(null);
-
useHotkeys(ADD_IMAGEBLOCK_SHORTCUT, () => setOpen(false));
const {
@@ -37,17 +30,8 @@ export function ImageModal() {
formState: { isDirty, isValid },
} = useForm();
- const block = useMutation({
- mutationFn: (data: { kind: number; title: string; content: string }) => {
- return createWidget(data.kind, data.title, data.content);
- },
- onSuccess: () => {
- queryClient.invalidateQueries({ queryKey: ['blocks'] });
- },
- });
-
const uploadImage = async () => {
- const image = await upload(null);
+ const image = await upload(null, true);
if (image.url) {
setImage(image.url);
}
@@ -56,11 +40,8 @@ export function ImageModal() {
const onSubmit = async (data: { kind: number; title: string; content: string }) => {
setLoading(true);
- // publish file metedata
- await publish({ content: data.title, kind: 1063, tags: tags.current });
-
// mutate
- block.mutate({ kind: BLOCK_KINDS.image, title: data.title, content: data.content });
+ setWidget({ kind: BLOCK_KINDS.image, title: data.title, content: data.content });
setLoading(false);
// reset form
@@ -88,7 +69,7 @@ export function ImageModal() {
I
- New image block
+ Add image widget
diff --git a/src/app/splash.tsx b/src/app/splash.tsx
index bd70ebce..3e45d749 100644
--- a/src/app/splash.tsx
+++ b/src/app/splash.tsx
@@ -14,7 +14,8 @@ export function SplashScreen() {
const { status, account } = useAccount();
const { fetchChats, fetchNotes } = useNostr();
- const [loading, setLoading] = useState(true);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
const skip = async () => {
await invoke('close_splashscreen');
@@ -34,6 +35,7 @@ export function SplashScreen() {
invoke('close_splashscreen');
} else {
setLoading(false);
+ setError(notes.message || chats.message);
console.log('fetch notes failed, error: ', notes.message);
console.log('fetch chats failed, error: ', chats.message);
}
@@ -72,9 +74,7 @@ export function SplashScreen() {
Something wrong!
-
- Connect process failed, click skip to continue.
-
+ {error}