From 332dbf608d2b174f836deb1f3468ead6e2792c08 Mon Sep 17 00:00:00 2001
From: Ren Amamiya <123083837+reyamir@users.noreply.github.com>
Date: Fri, 30 Jun 2023 16:36:03 +0700
Subject: [PATCH] fully support nip05
---
package.json | 4 +-
pnpm-lock.yaml | 112 +++++++-------
.../20230418013219_initial_data.sql | 18 ---
src/app/chat/components/messages/form.tsx | 2 +-
src/app/chat/components/modal.tsx | 40 ++---
src/app/chat/components/sidebar.tsx | 16 +-
src/app/root.tsx | 2 +
src/app/space/components/blocks/feed.tsx | 2 -
src/app/space/components/blocks/following.tsx | 5 +-
src/libs/ndk.tsx | 29 +---
src/libs/storage.tsx | 58 +------
src/shared/composer/types/post.tsx | 4 +-
src/shared/editProfileModal.tsx | 142 +++++++++++++++---
src/shared/icons/index.tsx | 1 +
src/shared/icons/unverified.tsx | 23 +++
src/utils/hooks/useProfile.tsx | 34 ++---
src/utils/hooks/useSocial.tsx | 3 +
17 files changed, 250 insertions(+), 245 deletions(-)
create mode 100644 src/shared/icons/unverified.tsx
diff --git a/package.json b/package.json
index 62792b2c..5c58783f 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"dependencies": {
"@floating-ui/react": "^0.23.1",
"@headlessui/react": "^1.7.15",
- "@nostr-dev-kit/ndk": "^0.6.3",
+ "@nostr-dev-kit/ndk": "0.6.0",
"@radix-ui/react-tooltip": "^1.0.6",
"@tanstack/react-query": "^4.29.19",
"@tanstack/react-virtual": "3.0.0-beta.54",
@@ -27,7 +27,7 @@
"get-urls": "^11.0.0",
"immer": "^10.0.2",
"light-bolt11-decoder": "^3.0.0",
- "nostr-tools": "^1.12.0",
+ "nostr-tools": "^1.12.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.45.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7f389c3c..992e48bc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,8 +8,8 @@ dependencies:
specifier: ^1.7.15
version: 1.7.15(react-dom@18.2.0)(react@18.2.0)
'@nostr-dev-kit/ndk':
- specifier: ^0.6.3
- version: 0.6.3(typescript@4.9.5)
+ specifier: 0.6.0
+ version: 0.6.0(typescript@4.9.5)
'@radix-ui/react-tooltip':
specifier: ^1.0.6
version: 1.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
@@ -44,8 +44,8 @@ dependencies:
specifier: ^3.0.0
version: 3.0.0
nostr-tools:
- specifier: ^1.12.0
- version: 1.12.0
+ specifier: ^1.12.1
+ version: 1.12.1
react:
specifier: ^18.2.0
version: 18.2.0
@@ -424,8 +424,8 @@ packages:
resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==}
dev: false
- /@floating-ui/dom@1.4.2:
- resolution: {integrity: sha512-VKmvHVatWnewmGGy+7Mdy4cTJX71Pli6v/Wjb5RQBuq5wjUYx+Ef+kRThi8qggZqDgD8CogCpqhRoVp3+yQk+g==}
+ /@floating-ui/dom@1.4.3:
+ resolution: {integrity: sha512-nB/68NyaQlcdY22L+Fgd1HERQ7UGv7XFN+tPxwrEfQL4nKtAP/jIZnZtpUlXbtV+VEGHh6W/63Gy2C5biWI3sA==}
dependencies:
'@floating-ui/core': 1.3.1
dev: false
@@ -436,7 +436,7 @@ packages:
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
- '@floating-ui/dom': 1.4.2
+ '@floating-ui/dom': 1.4.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
@@ -447,7 +447,7 @@ packages:
react: '>=16.8.0'
react-dom: '>=16.8.0'
dependencies:
- '@floating-ui/dom': 1.4.2
+ '@floating-ui/dom': 1.4.3
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
@@ -591,8 +591,8 @@ packages:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.15.0
- /@nostr-dev-kit/ndk@0.6.3(typescript@4.9.5):
- resolution: {integrity: sha512-lXMahPRepqNmt7rIM/I7pJz/VB5PSCakZScV3+L0AmUpsN4UXHX+fFtkFjyfNpM/zW+YlxFMFbo/WM+jB55j0A==}
+ /@nostr-dev-kit/ndk@0.6.0(typescript@4.9.5):
+ resolution: {integrity: sha512-0ptE6OIZhFW+aRRIXAI8PvUIoVU6iQLpiwFtJj48XAUO2EC3WiSuqKLshjg6wj1bbo9qGs1PyFS9AUhUlWWJtg==}
dependencies:
'@noble/hashes': 1.3.1
'@noble/secp256k1': 2.0.0
@@ -605,11 +605,11 @@ packages:
eslint: 8.43.0
eslint-config-prettier: 8.8.0(eslint@8.43.0)
eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)
- esm-loader-typescript: 1.0.4
+ esm-loader-typescript: 1.0.5
eventemitter3: 5.0.1
light-bolt11-decoder: 3.0.0
node-fetch: 3.3.1
- nostr-tools: 1.12.0
+ nostr-tools: 1.12.1
tsd: 0.28.1
utf8-buffer: 1.0.0
websocket-polyfill: 0.0.3
@@ -1071,8 +1071,8 @@ packages:
resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==}
dev: false
- /@swc/core-darwin-arm64@1.3.66:
- resolution: {integrity: sha512-UijJsvuLy73vxeVYEy7urIHksXS+3BdvJ9s9AY+bRMSQW483NO7RLp8g4FdTyJbRaN0BH15SQnY0dcjQBkVuHw==}
+ /@swc/core-darwin-arm64@1.3.67:
+ resolution: {integrity: sha512-zCT2mCkOBVNf5uJDcQ3A9KDoO1OEaGdfjsRTZTo7sejDd9AXLfJg+xgyCBBrK2jNS/uWcT21IvSv3LqKp4K8pA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
@@ -1080,8 +1080,8 @@ packages:
dev: true
optional: true
- /@swc/core-darwin-x64@1.3.66:
- resolution: {integrity: sha512-xGsHKvViQnwTNLF30Y/5OqWdnN6RsiyUI8awZXfz1sHcXCEaLe+v+WLQ+/E8sgw0YUkYVHzzfV/sAN2CezJK5Q==}
+ /@swc/core-darwin-x64@1.3.67:
+ resolution: {integrity: sha512-hXTVsfTatPEec5gFVyjGj3NccKZsYj/OXyHn6XA+l3Q76lZzGm2ISHdku//XNwXu8OmJ0HhS7LPsC4XXwxXQhg==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
@@ -1089,8 +1089,8 @@ packages:
dev: true
optional: true
- /@swc/core-linux-arm-gnueabihf@1.3.66:
- resolution: {integrity: sha512-gNbLcSIV2pq90BkMSpzvK4xPXOl8GEF3YR4NaqF0CYSzQsVXXTTqMuX/r26xNYudBKzH0345S1MpoRk2qricnA==}
+ /@swc/core-linux-arm-gnueabihf@1.3.67:
+ resolution: {integrity: sha512-l8AKL0RkDL5FRTeWMmjoz9zvAc37amxC+0rheaNwE+gZya7ObyNjnIYz5FwN+3y+z6JFU7LS2x/5f6iwruv6pg==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
@@ -1098,8 +1098,8 @@ packages:
dev: true
optional: true
- /@swc/core-linux-arm64-gnu@1.3.66:
- resolution: {integrity: sha512-cJSQ0oplyWbJqy4rzVcnBYLAi6z1QT3QCcR7iAey0aAmCvfRBZJfXlyjggMjn4iosuadkauwCZR1xYNhBDRn7w==}
+ /@swc/core-linux-arm64-gnu@1.3.67:
+ resolution: {integrity: sha512-S8zOB1AXEpb7kmtgMaFNeLAj01VOky4B0RNZ+uJWigdrDiFT67FeZzNHUNmNSOU0QM79G+Lie/xD/beqEw0vDg==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
@@ -1107,8 +1107,8 @@ packages:
dev: true
optional: true
- /@swc/core-linux-arm64-musl@1.3.66:
- resolution: {integrity: sha512-GDQZpcB9aGxG9PTA2shdIkoMZlGK5omJ8NR49uoBTtLBVYiGeXAwV0U1Uaw8kXEZj9i7wZDkvjzjSaNH3evRsg==}
+ /@swc/core-linux-arm64-musl@1.3.67:
+ resolution: {integrity: sha512-Fex8J8ASrt13pmOr2xWh41tEeKWwXYGk3sV8L/aGHiYtIJEUi2f+RtMx3jp7LIdOD8pQptor7i5WBlfR9jhp8A==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
@@ -1116,8 +1116,8 @@ packages:
dev: true
optional: true
- /@swc/core-linux-x64-gnu@1.3.66:
- resolution: {integrity: sha512-lg8E4O/Pd9KfK0lajdinVMuGME8dSv7V9arhEpmlfGE2eXSDCWqDn5Htk5QVBstt9lt1lsRhWHJ/YYc2eQY30Q==}
+ /@swc/core-linux-x64-gnu@1.3.67:
+ resolution: {integrity: sha512-9bz9/bMphrv5vDg0os/d8ve0QgFpDzJgZgHUaHiGwcmfnlgdOSAaYJLIvWdcGTjZuQeV4L0m+iru357D9TXEzA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
@@ -1125,8 +1125,8 @@ packages:
dev: true
optional: true
- /@swc/core-linux-x64-musl@1.3.66:
- resolution: {integrity: sha512-lo8ZcAO/zL2pZWH+LZIyge8u2MklaeuT6+FpVVpBFktMVdYXbaVtzpvWbgRFBZHvL3SRDF+u8jxjtkXhvGUpTw==}
+ /@swc/core-linux-x64-musl@1.3.67:
+ resolution: {integrity: sha512-ED0H6oLvQmhgo9zs8usmEA/lcZPGTu7K9og9K871b7HhHX0h/R+Xg2pb5KD7S/GyUHpfuopxjVROm+h6X1jMUA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
@@ -1134,8 +1134,8 @@ packages:
dev: true
optional: true
- /@swc/core-win32-arm64-msvc@1.3.66:
- resolution: {integrity: sha512-cQoVwBuJY5WkHbfpCOlndNwYr1ZThatRjQQvKy540NUIeAEk9Fa6ozlDBtU75UdaWKtUG6YQ/bWz+KTemheVxw==}
+ /@swc/core-win32-arm64-msvc@1.3.67:
+ resolution: {integrity: sha512-J1yFDLgPFeRtA8t5E159OXX+ww1gbkFg70yr4OP7EsOkOD1uMkuTf9yK/woHfsaVJlUYjJHzw7MkUIEgQBucqQ==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
@@ -1143,8 +1143,8 @@ packages:
dev: true
optional: true
- /@swc/core-win32-ia32-msvc@1.3.66:
- resolution: {integrity: sha512-y/FrAIINK4UBeUQQknGlWXEyjo+MBvjF7WkUf2KP7sNr9EHHy8+dXohAGd5Anz0eJrqOM1ZXR/GEjxRp7bGQ1Q==}
+ /@swc/core-win32-ia32-msvc@1.3.67:
+ resolution: {integrity: sha512-bK11/KtasewqHxzkjKUBXRE9MSAidbZCxrgJUd49bItG2N/DHxkwMYu8Xkh5VDHdTYWv/2idYtf/VM9Yi+53qw==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
@@ -1152,8 +1152,8 @@ packages:
dev: true
optional: true
- /@swc/core-win32-x64-msvc@1.3.66:
- resolution: {integrity: sha512-yI64ACzS14qFLrfyO12qW+f/UROTotzDeEbuyJAaPD2IZexoT1cICznI3sBmIfrSt33mVuW8eF5m3AG/NUImzw==}
+ /@swc/core-win32-x64-msvc@1.3.67:
+ resolution: {integrity: sha512-GxzUU3+NA3cPcYxCxtfSQIS2ySD7Z8IZmKTVaWA9GOUQbKLyCE8H5js31u39+0op/1gNgxOgYFDoj2lUyvLCqw==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
@@ -1161,8 +1161,8 @@ packages:
dev: true
optional: true
- /@swc/core@1.3.66:
- resolution: {integrity: sha512-Hpf91kH5ly7fHkWnApwryTQryT+TO4kMMPH3WyciUSQOWLE3UuQz1PtETHQQk7PZ/b1QF0qQurJrgfBr5bSKUA==}
+ /@swc/core@1.3.67:
+ resolution: {integrity: sha512-9DROjzfAEt0xt0CDkOYsWpkUPyne8fl5ggWGon049678BOM7p0R0dmaalZGAsKatG5vYP1IWSKWsKhJIubDCsQ==}
engines: {node: '>=10'}
requiresBuild: true
peerDependencies:
@@ -1171,16 +1171,16 @@ packages:
'@swc/helpers':
optional: true
optionalDependencies:
- '@swc/core-darwin-arm64': 1.3.66
- '@swc/core-darwin-x64': 1.3.66
- '@swc/core-linux-arm-gnueabihf': 1.3.66
- '@swc/core-linux-arm64-gnu': 1.3.66
- '@swc/core-linux-arm64-musl': 1.3.66
- '@swc/core-linux-x64-gnu': 1.3.66
- '@swc/core-linux-x64-musl': 1.3.66
- '@swc/core-win32-arm64-msvc': 1.3.66
- '@swc/core-win32-ia32-msvc': 1.3.66
- '@swc/core-win32-x64-msvc': 1.3.66
+ '@swc/core-darwin-arm64': 1.3.67
+ '@swc/core-darwin-x64': 1.3.67
+ '@swc/core-linux-arm-gnueabihf': 1.3.67
+ '@swc/core-linux-arm64-gnu': 1.3.67
+ '@swc/core-linux-arm64-musl': 1.3.67
+ '@swc/core-linux-x64-gnu': 1.3.67
+ '@swc/core-linux-x64-musl': 1.3.67
+ '@swc/core-win32-arm64-msvc': 1.3.67
+ '@swc/core-win32-ia32-msvc': 1.3.67
+ '@swc/core-win32-x64-msvc': 1.3.67
dev: true
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
@@ -1551,7 +1551,7 @@ packages:
peerDependencies:
vite: ^4
dependencies:
- '@swc/core': 1.3.66
+ '@swc/core': 1.3.67
vite: 4.3.9(@types/node@18.16.18)
transitivePeerDependencies:
- '@swc/helpers'
@@ -1796,7 +1796,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001509
- electron-to-chromium: 1.4.444
+ electron-to-chromium: 1.4.446
node-releases: 2.0.12
update-browserslist-db: 1.0.11(browserslist@4.21.9)
dev: true
@@ -2227,8 +2227,8 @@ packages:
/eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
- /electron-to-chromium@1.4.444:
- resolution: {integrity: sha512-/AjkL4syRvOpowXWy3N4OHmVbFdWQpfSKHh0sCVYipDeEAtMce3rLjMJi/27Ia9jNIbw6P1JuPN32pSWybXXEQ==}
+ /electron-to-chromium@1.4.446:
+ resolution: {integrity: sha512-4Gnw7ztEQ/E0eOt5JWfPn9jjeupfUlKoeW5ETKP9nLdWj+4spFoS3Stj19fqlKIaX28UQs0fNX+uKEyoLCBnkw==}
dev: true
/emoji-regex@8.0.0:
@@ -2567,8 +2567,8 @@ packages:
- supports-color
dev: false
- /esm-loader-typescript@1.0.4:
- resolution: {integrity: sha512-ejo2f+NKIt23jaJKVpjcRQC0xTa6cTqt6VA+z8Ef/A/TCjQ5u7opPO1J4fJFeTiiHEo8JqU92EG4I1KwuXYZMg==}
+ /esm-loader-typescript@1.0.5:
+ resolution: {integrity: sha512-BeHp2TrYbRL9fUttlyzPQJPTvLDBXXUli09UNoAr87WKi8jedcULlMteNZgl7DtFZ3ZE1Mmv74SwRgwJDWyc0A==}
dependencies:
create-esm-loader: 0.2.3
npm-run-all: 4.1.5
@@ -3832,8 +3832,8 @@ packages:
engines: {node: '>=12.20'}
dev: false
- /nostr-tools@1.12.0:
- resolution: {integrity: sha512-fsIXaNJPKaSrO9MxsCEWbhI4tG4pToQK4D4sgLRD0fRDfZ6ocCg8CLlh9lcNx0o8pVErCMLVASxbJ+w4WNK0MA==}
+ /nostr-tools@1.12.1:
+ resolution: {integrity: sha512-ZeoV7g3jBUAlb4mKa3C+6hrc84htPkbebMShfGNgV4vAiz18e/sQukUBFL6vb/+sxZy+dBQFkRwsJIaVFs8Gfw==}
dependencies:
'@noble/curves': 1.0.0
'@noble/hashes': 1.3.0
@@ -4455,8 +4455,8 @@ packages:
glob: 7.2.3
dev: false
- /rollup@3.25.3:
- resolution: {integrity: sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw==}
+ /rollup@3.26.0:
+ resolution: {integrity: sha512-YzJH0eunH2hr3knvF3i6IkLO/jTjAEwU4HoMUbQl4//Tnl3ou0e7P5SjxdDr8HQJdeUJShlbEHXrrnEHy1l7Yg==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
@@ -5159,7 +5159,7 @@ packages:
vite: '>=2.8'
dependencies:
'@rollup/plugin-virtual': 3.0.1
- '@swc/core': 1.3.66
+ '@swc/core': 1.3.67
uuid: 9.0.0
vite: 4.3.9(@types/node@18.16.18)
transitivePeerDependencies:
@@ -5212,7 +5212,7 @@ packages:
'@types/node': 18.16.18
esbuild: 0.17.19
postcss: 8.4.24
- rollup: 3.25.3
+ rollup: 3.26.0
optionalDependencies:
fsevents: 2.3.2
dev: true
diff --git a/src-tauri/migrations/20230418013219_initial_data.sql b/src-tauri/migrations/20230418013219_initial_data.sql
index 0ab7a60a..c53aa131 100644
--- a/src-tauri/migrations/20230418013219_initial_data.sql
+++ b/src-tauri/migrations/20230418013219_initial_data.sql
@@ -14,24 +14,6 @@ CREATE TABLE
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
--- create plebs table
-CREATE TABLE
- plebs (
- id INTEGER NOT NULL PRIMARY KEY,
- npub TEXT NOT NULL UNIQUE,
- name TEXT,
- displayName TEXT,
- image TEXT,
- banner TEXT,
- bio TEXT,
- nip05 TEXT,
- lud06 TEXT,
- lud16 TEXT,
- about TEXT,
- zapService TEXT,
- created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
- );
-
-- create notes table
CREATE TABLE
notes (
diff --git a/src/app/chat/components/messages/form.tsx b/src/app/chat/components/messages/form.tsx
index 5d148b13..2549e5a9 100644
--- a/src/app/chat/components/messages/form.tsx
+++ b/src/app/chat/components/messages/form.tsx
@@ -20,7 +20,7 @@ export function ChatMessageForm({
const tags = [["p", receiverPubkey]];
// publish message
- publish({ content: message, kind: 4, tags });
+ await publish({ content: message, kind: 4, tags });
// reset state
setValue("");
diff --git a/src/app/chat/components/modal.tsx b/src/app/chat/components/modal.tsx
index 96349acd..7ee350ee 100644
--- a/src/app/chat/components/modal.tsx
+++ b/src/app/chat/components/modal.tsx
@@ -1,21 +1,17 @@
+import { User } from "@app/auth/components/user";
import { Dialog, Transition } from "@headlessui/react";
-import { getPlebs } from "@libs/storage";
import { CancelIcon, PlusIcon } from "@shared/icons";
-import { DEFAULT_AVATAR } from "@stores/constants";
-import { useQuery } from "@tanstack/react-query";
-import { nip19 } from "nostr-tools";
+import { useAccount } from "@utils/hooks/useAccount";
import { Fragment, useState } from "react";
import { useNavigate } from "react-router-dom";
export function NewMessageModal() {
const navigate = useNavigate();
-
- const { status, data }: any = useQuery(["plebs"], async () => {
- return await getPlebs();
- });
-
const [isOpen, setIsOpen] = useState(false);
+ const { status, account } = useAccount();
+ const follows = account ? JSON.parse(account.follows) : [];
+
const closeModal = () => {
setIsOpen(false);
};
@@ -24,8 +20,7 @@ export function NewMessageModal() {
setIsOpen(true);
};
- const openChat = (npub: string) => {
- const pubkey = nip19.decode(npub).data;
+ const openChat = (pubkey: string) => {
closeModal();
navigate(`/app/chat/${pubkey}`);
};
@@ -99,31 +94,16 @@ export function NewMessageModal() {
{status === "loading" ? (
Loading...
) : (
- data.map((pleb) => (
+ follows.map((follow) => (
-
-

-
-
- {pleb.displayName || pleb.name}
-
-
- {pleb.nip05 ||
- pleb.npub.substring(0, 16).concat("...")}
-
-
-
+
diff --git a/src/app/root.tsx b/src/app/root.tsx
index 1cfa6b32..53de7eb1 100644
--- a/src/app/root.tsx
+++ b/src/app/root.tsx
@@ -6,6 +6,7 @@ import {
createNote,
getChannels,
getLastLogin,
+ updateLastLogin,
} from "@libs/storage";
import { NDKFilter } from "@nostr-dev-kit/ndk";
import { LoaderIcon, LumeIcon } from "@shared/icons";
@@ -142,6 +143,7 @@ export function Root() {
const chats = await fetchChats();
// const channels = await fetchChannelMessages();
if (chats) {
+ await updateLastLogin(dateToUnix());
navigate("/app/space", { replace: true });
}
}
diff --git a/src/app/space/components/blocks/feed.tsx b/src/app/space/components/blocks/feed.tsx
index 0a623f76..2d835c0f 100644
--- a/src/app/space/components/blocks/feed.tsx
+++ b/src/app/space/components/blocks/feed.tsx
@@ -11,7 +11,6 @@ import { useVirtualizer } from "@tanstack/react-virtual";
import { useEffect, useRef } from "react";
const ITEM_PER_PAGE = 10;
-const TIME = Math.floor(Date.now() / 1000);
export function FeedBlock({ params }: { params: any }) {
const queryClient = useQueryClient();
@@ -21,7 +20,6 @@ export function FeedBlock({ params }: { params: any }) {
queryFn: async ({ pageParam = 0 }) => {
return await getNotesByAuthors(
params.content,
- TIME,
ITEM_PER_PAGE,
pageParam,
);
diff --git a/src/app/space/components/blocks/following.tsx b/src/app/space/components/blocks/following.tsx
index a5e572ee..1e81d4c4 100644
--- a/src/app/space/components/blocks/following.tsx
+++ b/src/app/space/components/blocks/following.tsx
@@ -9,7 +9,6 @@ import { useVirtualizer } from "@tanstack/react-virtual";
import { useEffect, useRef } from "react";
const ITEM_PER_PAGE = 10;
-const TIME = Math.floor(Date.now() / 1000);
export function FollowingBlock({ block }: { block: number }) {
// subscribe for live update
@@ -29,7 +28,7 @@ export function FollowingBlock({ block }: { block: number }) {
}: any = useInfiniteQuery({
queryKey: ["newsfeed-circle"],
queryFn: async ({ pageParam = 0 }) => {
- return await getNotes(TIME, ITEM_PER_PAGE, pageParam);
+ return await getNotes(ITEM_PER_PAGE, pageParam);
},
getNextPageParam: (lastPage) => lastPage.nextCursor,
});
@@ -64,7 +63,7 @@ export function FollowingBlock({ block }: { block: number }) {
const refreshFirstPage = () => {
// refetch
- refetch({ refetchPage: (page, index) => index === 0 });
+ refetch({ refetchPage: (_, index: number) => index === 0 });
// scroll to top
rowVirtualizer.scrollToIndex(1);
// stop notify
diff --git a/src/libs/ndk.tsx b/src/libs/ndk.tsx
index 5bd0b90a..f8862ce1 100644
--- a/src/libs/ndk.tsx
+++ b/src/libs/ndk.tsx
@@ -1,4 +1,3 @@
-import { createReplyNote } from "./storage";
import NDK, {
NDKConstructorParams,
NDKEvent,
@@ -15,21 +14,10 @@ export async function initNDK(relays?: string[]): Promise
{
const opts: NDKConstructorParams = {};
const defaultRelays = new Set(relays || FULL_RELAYS);
- /*
- for (const relay of defaultRelays) {
- const url = new URL(relay);
- url.protocol = url.protocol = url.protocol.replace("wss", "https");
- const res = await fetch(url.href, { method: "HEAD", timeout: 5 });
- if (!res.ok) {
- defaultRelays.delete(relay);
- }
- }
- */
-
opts.explicitRelayUrls = [...defaultRelays];
const ndk = new NDK(opts);
- await ndk.connect();
+ await ndk.connect(500);
return ndk;
}
@@ -57,15 +45,10 @@ export async function prefetchEvents(
}
export function usePublish() {
- const { account } = useAccount();
const ndk = useContext(RelayContext);
+ const { account } = useAccount();
- if (!ndk.signer) {
- const signer = new NDKPrivateKeySigner(account?.privkey);
- ndk.signer = signer;
- }
-
- const publish = ({
+ const publish = async ({
content,
kind,
tags,
@@ -73,8 +56,9 @@ export function usePublish() {
content: string;
kind: NDKKind;
tags: string[][];
- }): NDKEvent => {
+ }): Promise => {
const event = new NDKEvent(ndk);
+ const signer = new NDKPrivateKeySigner(account.privkey);
event.content = content;
event.kind = kind;
@@ -82,7 +66,8 @@ export function usePublish() {
event.pubkey = account.pubkey;
event.tags = tags;
- event.publish();
+ await event.sign(signer);
+ await event.publish();
return event;
};
diff --git a/src/libs/storage.tsx b/src/libs/storage.tsx
index 2d18fd25..2bab3ebc 100644
--- a/src/libs/storage.tsx
+++ b/src/libs/storage.tsx
@@ -1,6 +1,4 @@
-import { NDKTag, NDKUserProfile } from "@nostr-dev-kit/ndk";
import { getParentID } from "@utils/transform";
-import { nip19 } from "nostr-tools";
import Database from "tauri-plugin-sql-api";
let db: null | Database = null;
@@ -73,55 +71,6 @@ export async function updateAccount(
);
}
-// get all plebs
-export async function getPlebs() {
- const db = await connect();
- return await db.select("SELECT * FROM plebs ORDER BY created_at DESC;");
-}
-
-// get pleb by pubkey
-export async function getPleb(npub: string) {
- const db = await connect();
- const result = await db.select(`SELECT * FROM plebs WHERE npub = "${npub}";`);
-
- if (result) {
- return result[0];
- } else {
- return null;
- }
-}
-
-// create pleb
-export async function createPleb(key: string, data: NDKUserProfile) {
- const db = await connect();
- const now = Math.floor(Date.now() / 1000);
- let npub: string;
-
- if (key.substring(0, 4) === "npub") {
- npub = key;
- } else {
- npub = nip19.npubEncode(key);
- }
-
- return await db.execute(
- "INSERT OR REPLACE INTO plebs (npub, name, displayName, image, banner, bio, nip05, lud06, lud16, about, zapService, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);",
- [
- npub,
- data.name,
- data.displayName,
- data.image,
- data.banner,
- data.bio,
- data.nip05,
- data.lud06,
- data.lud16,
- data.about,
- data.zapService,
- now,
- ],
- );
-}
-
// count total notes
export async function countTotalChannels() {
const db = await connect();
@@ -139,14 +88,14 @@ export async function countTotalNotes() {
}
// get all notes
-export async function getNotes(time: number, limit: number, offset: number) {
+export async function getNotes(limit: number, offset: number) {
const db = await connect();
const totalNotes = await countTotalNotes();
const nextCursor = offset + limit;
const notes: any = { data: null, nextCursor: 0 };
const query: any = await db.select(
- `SELECT * FROM notes WHERE created_at <= "${time}" AND kind IN (1, 6, 1063) GROUP BY parent_id ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}";`,
+ `SELECT * FROM notes WHERE kind IN (1, 6, 1063) GROUP BY parent_id ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}";`,
);
notes["data"] = query;
@@ -169,7 +118,6 @@ export async function getNotesByPubkey(pubkey: string) {
// get all notes by authors
export async function getNotesByAuthors(
authors: string,
- time: number,
limit: number,
offset: number,
) {
@@ -181,7 +129,7 @@ export async function getNotesByAuthors(
const notes: any = { data: null, nextCursor: 0 };
const query: any = await db.select(
- `SELECT * FROM notes WHERE created_at <= "${time}" AND pubkey IN (${finalArray}) AND kind IN (1, 6, 1063) GROUP BY parent_id ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}";`,
+ `SELECT * FROM notes WHERE pubkey IN (${finalArray}) AND kind IN (1, 6, 1063) GROUP BY parent_id ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}";`,
);
notes["data"] = query;
diff --git a/src/shared/composer/types/post.tsx b/src/shared/composer/types/post.tsx
index 039ef952..53af1c96 100644
--- a/src/shared/composer/types/post.tsx
+++ b/src/shared/composer/types/post.tsx
@@ -97,7 +97,7 @@ export function Post() {
const refID = getRef();
- const submit = () => {
+ const submit = async () => {
let tags: string[][] = [];
let kind: number;
@@ -130,7 +130,7 @@ export function Post() {
const serializedContent = serialize(content);
// publish message
- publish({ content: serializedContent, kind, tags });
+ await publish({ content: serializedContent, kind, tags });
// close modal
toggle(false);
diff --git a/src/shared/editProfileModal.tsx b/src/shared/editProfileModal.tsx
index e48e98a3..11b4dc06 100644
--- a/src/shared/editProfileModal.tsx
+++ b/src/shared/editProfileModal.tsx
@@ -1,38 +1,51 @@
import { Dialog, Transition } from "@headlessui/react";
import { usePublish } from "@libs/ndk";
-import { getPleb } from "@libs/storage";
+import { NDKEvent } from "@nostr-dev-kit/ndk";
import { AvatarUploader } from "@shared/avatarUploader";
import { BannerUploader } from "@shared/bannerUploader";
-import { CancelIcon, LoaderIcon } from "@shared/icons";
+import {
+ CancelIcon,
+ CheckCircleIcon,
+ LoaderIcon,
+ UnverifiedIcon,
+} from "@shared/icons";
import { Image } from "@shared/image";
import { DEFAULT_AVATAR } from "@stores/constants";
+import { useQueryClient } from "@tanstack/react-query";
+import { fetch } from "@tauri-apps/api/http";
import { useAccount } from "@utils/hooks/useAccount";
-import { Fragment, useState } from "react";
+import { Fragment, useEffect, useState } from "react";
import { useForm } from "react-hook-form";
export function EditProfileModal() {
+ const queryClient = useQueryClient();
const publish = usePublish();
const [isOpen, setIsOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [picture, setPicture] = useState(DEFAULT_AVATAR);
- const [banner, setBanner] = useState(null);
+ const [banner, setBanner] = useState("");
+ const [nip05, setNIP05] = useState({ verified: false, text: "" });
const { account } = useAccount();
const {
register,
handleSubmit,
reset,
- formState: { isValid },
+ setError,
+ formState: { isValid, errors },
} = useForm({
defaultValues: async () => {
- const res = await getPleb(account.npub);
- if (res.picture) {
+ const res: any = queryClient.getQueryData(["user", account.pubkey]);
+ if (res.image) {
setPicture(res.image);
}
if (res.banner) {
setBanner(res.banner);
}
+ if (res.nip05) {
+ setNIP05((prev) => ({ ...prev, text: res.nip05 }));
+ }
return res;
},
});
@@ -45,24 +58,72 @@ export function EditProfileModal() {
setIsOpen(true);
};
- const onSubmit = (data: any) => {
+ const verifyNIP05 = async (data: string) => {
+ if (data) {
+ const url = data.split("@");
+ const username = url[0];
+ const service = url[1];
+ const verifyURL = `https://${service}/.well-known/nostr.json?name=${username}`;
+
+ const res: any = await fetch(verifyURL, {
+ method: "GET",
+ timeout: 30,
+ headers: {
+ "Content-Type": "application/json; charset=utf-8",
+ },
+ });
+
+ if (!res.ok) return false;
+ if (res.data.names[username] === account.pubkey) {
+ setNIP05((prev) => ({ ...prev, verified: true }));
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+
+ const onSubmit = async (data: any) => {
// start loading
setLoading(true);
- // publish
- const event = publish({
- content: JSON.stringify({
- ...data,
- display_name: data.name,
- bio: data.about,
- image: data.picture,
- }),
- kind: 0,
- tags: [],
- });
+ let event: NDKEvent;
- if (event) {
+ const content = {
+ ...data,
+ username: data.name,
+ display_name: data.name,
+ bio: data.about,
+ image: data.picture,
+ };
+
+ if (data.nip05) {
+ const verify = await verifyNIP05(data.nip05);
+ if (verify) {
+ event = await publish({
+ content: JSON.stringify({ ...content, nip05: data.nip05 }),
+ kind: 0,
+ tags: [],
+ });
+ } else {
+ setNIP05((prev) => ({ ...prev, verified: false }));
+ setError("nip05", {
+ type: "manual",
+ message: "Can't verify your Lume ID / NIP-05, please check again",
+ });
+ }
+ } else {
+ event = await publish({
+ content: JSON.stringify(content),
+ kind: 0,
+ tags: [],
+ });
+ }
+
+ if (event.id) {
setTimeout(() => {
+ // invalid cache
+ queryClient.invalidateQueries(["user", account.pubkey]);
// reset form
reset();
// reset state
@@ -71,9 +132,17 @@ export function EditProfileModal() {
setPicture(DEFAULT_AVATAR);
setBanner(null);
}, 1200);
+ } else {
+ setLoading(false);
}
};
+ useEffect(() => {
+ if (!nip05.verified && /\S+@\S+\.\S+/.test(nip05.text)) {
+ verifyNIP05(nip05.text);
+ }
+ }, [nip05.text]);
+
return (
<>
+
+
+
+
+
+ {nip05.verified ? (
+
+
+ Verified
+
+ ) : (
+
+
+ Unverified
+
+ )}
+
+ {errors.nip05 && (
+
+ {errors.nip05.message.toString()}
+
+ )}
+
+