mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-19 19:46:34 +00:00
fully support nip05
This commit is contained in:
parent
1ba7f823cb
commit
332dbf608d
@ -15,7 +15,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/react": "^0.23.1",
|
"@floating-ui/react": "^0.23.1",
|
||||||
"@headlessui/react": "^1.7.15",
|
"@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",
|
"@radix-ui/react-tooltip": "^1.0.6",
|
||||||
"@tanstack/react-query": "^4.29.19",
|
"@tanstack/react-query": "^4.29.19",
|
||||||
"@tanstack/react-virtual": "3.0.0-beta.54",
|
"@tanstack/react-virtual": "3.0.0-beta.54",
|
||||||
@ -27,7 +27,7 @@
|
|||||||
"get-urls": "^11.0.0",
|
"get-urls": "^11.0.0",
|
||||||
"immer": "^10.0.2",
|
"immer": "^10.0.2",
|
||||||
"light-bolt11-decoder": "^3.0.0",
|
"light-bolt11-decoder": "^3.0.0",
|
||||||
"nostr-tools": "^1.12.0",
|
"nostr-tools": "^1.12.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.45.1",
|
"react-hook-form": "^7.45.1",
|
||||||
|
112
pnpm-lock.yaml
112
pnpm-lock.yaml
@ -8,8 +8,8 @@ dependencies:
|
|||||||
specifier: ^1.7.15
|
specifier: ^1.7.15
|
||||||
version: 1.7.15(react-dom@18.2.0)(react@18.2.0)
|
version: 1.7.15(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@nostr-dev-kit/ndk':
|
'@nostr-dev-kit/ndk':
|
||||||
specifier: ^0.6.3
|
specifier: 0.6.0
|
||||||
version: 0.6.3(typescript@4.9.5)
|
version: 0.6.0(typescript@4.9.5)
|
||||||
'@radix-ui/react-tooltip':
|
'@radix-ui/react-tooltip':
|
||||||
specifier: ^1.0.6
|
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)
|
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
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
nostr-tools:
|
nostr-tools:
|
||||||
specifier: ^1.12.0
|
specifier: ^1.12.1
|
||||||
version: 1.12.0
|
version: 1.12.1
|
||||||
react:
|
react:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
@ -424,8 +424,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==}
|
resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@floating-ui/dom@1.4.2:
|
/@floating-ui/dom@1.4.3:
|
||||||
resolution: {integrity: sha512-VKmvHVatWnewmGGy+7Mdy4cTJX71Pli6v/Wjb5RQBuq5wjUYx+Ef+kRThi8qggZqDgD8CogCpqhRoVp3+yQk+g==}
|
resolution: {integrity: sha512-nB/68NyaQlcdY22L+Fgd1HERQ7UGv7XFN+tPxwrEfQL4nKtAP/jIZnZtpUlXbtV+VEGHh6W/63Gy2C5biWI3sA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/core': 1.3.1
|
'@floating-ui/core': 1.3.1
|
||||||
dev: false
|
dev: false
|
||||||
@ -436,7 +436,7 @@ packages:
|
|||||||
react: '>=16.8.0'
|
react: '>=16.8.0'
|
||||||
react-dom: '>=16.8.0'
|
react-dom: '>=16.8.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.4.2
|
'@floating-ui/dom': 1.4.3
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
@ -447,7 +447,7 @@ packages:
|
|||||||
react: '>=16.8.0'
|
react: '>=16.8.0'
|
||||||
react-dom: '>=16.8.0'
|
react-dom: '>=16.8.0'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/dom': 1.4.2
|
'@floating-ui/dom': 1.4.3
|
||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
@ -591,8 +591,8 @@ packages:
|
|||||||
'@nodelib/fs.scandir': 2.1.5
|
'@nodelib/fs.scandir': 2.1.5
|
||||||
fastq: 1.15.0
|
fastq: 1.15.0
|
||||||
|
|
||||||
/@nostr-dev-kit/ndk@0.6.3(typescript@4.9.5):
|
/@nostr-dev-kit/ndk@0.6.0(typescript@4.9.5):
|
||||||
resolution: {integrity: sha512-lXMahPRepqNmt7rIM/I7pJz/VB5PSCakZScV3+L0AmUpsN4UXHX+fFtkFjyfNpM/zW+YlxFMFbo/WM+jB55j0A==}
|
resolution: {integrity: sha512-0ptE6OIZhFW+aRRIXAI8PvUIoVU6iQLpiwFtJj48XAUO2EC3WiSuqKLshjg6wj1bbo9qGs1PyFS9AUhUlWWJtg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.1
|
||||||
'@noble/secp256k1': 2.0.0
|
'@noble/secp256k1': 2.0.0
|
||||||
@ -605,11 +605,11 @@ packages:
|
|||||||
eslint: 8.43.0
|
eslint: 8.43.0
|
||||||
eslint-config-prettier: 8.8.0(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)
|
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
|
eventemitter3: 5.0.1
|
||||||
light-bolt11-decoder: 3.0.0
|
light-bolt11-decoder: 3.0.0
|
||||||
node-fetch: 3.3.1
|
node-fetch: 3.3.1
|
||||||
nostr-tools: 1.12.0
|
nostr-tools: 1.12.1
|
||||||
tsd: 0.28.1
|
tsd: 0.28.1
|
||||||
utf8-buffer: 1.0.0
|
utf8-buffer: 1.0.0
|
||||||
websocket-polyfill: 0.0.3
|
websocket-polyfill: 0.0.3
|
||||||
@ -1071,8 +1071,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==}
|
resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@swc/core-darwin-arm64@1.3.66:
|
/@swc/core-darwin-arm64@1.3.67:
|
||||||
resolution: {integrity: sha512-UijJsvuLy73vxeVYEy7urIHksXS+3BdvJ9s9AY+bRMSQW483NO7RLp8g4FdTyJbRaN0BH15SQnY0dcjQBkVuHw==}
|
resolution: {integrity: sha512-zCT2mCkOBVNf5uJDcQ3A9KDoO1OEaGdfjsRTZTo7sejDd9AXLfJg+xgyCBBrK2jNS/uWcT21IvSv3LqKp4K8pA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
@ -1080,8 +1080,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-darwin-x64@1.3.66:
|
/@swc/core-darwin-x64@1.3.67:
|
||||||
resolution: {integrity: sha512-xGsHKvViQnwTNLF30Y/5OqWdnN6RsiyUI8awZXfz1sHcXCEaLe+v+WLQ+/E8sgw0YUkYVHzzfV/sAN2CezJK5Q==}
|
resolution: {integrity: sha512-hXTVsfTatPEec5gFVyjGj3NccKZsYj/OXyHn6XA+l3Q76lZzGm2ISHdku//XNwXu8OmJ0HhS7LPsC4XXwxXQhg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
@ -1089,8 +1089,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-linux-arm-gnueabihf@1.3.66:
|
/@swc/core-linux-arm-gnueabihf@1.3.67:
|
||||||
resolution: {integrity: sha512-gNbLcSIV2pq90BkMSpzvK4xPXOl8GEF3YR4NaqF0CYSzQsVXXTTqMuX/r26xNYudBKzH0345S1MpoRk2qricnA==}
|
resolution: {integrity: sha512-l8AKL0RkDL5FRTeWMmjoz9zvAc37amxC+0rheaNwE+gZya7ObyNjnIYz5FwN+3y+z6JFU7LS2x/5f6iwruv6pg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -1098,8 +1098,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-linux-arm64-gnu@1.3.66:
|
/@swc/core-linux-arm64-gnu@1.3.67:
|
||||||
resolution: {integrity: sha512-cJSQ0oplyWbJqy4rzVcnBYLAi6z1QT3QCcR7iAey0aAmCvfRBZJfXlyjggMjn4iosuadkauwCZR1xYNhBDRn7w==}
|
resolution: {integrity: sha512-S8zOB1AXEpb7kmtgMaFNeLAj01VOky4B0RNZ+uJWigdrDiFT67FeZzNHUNmNSOU0QM79G+Lie/xD/beqEw0vDg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -1107,8 +1107,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-linux-arm64-musl@1.3.66:
|
/@swc/core-linux-arm64-musl@1.3.67:
|
||||||
resolution: {integrity: sha512-GDQZpcB9aGxG9PTA2shdIkoMZlGK5omJ8NR49uoBTtLBVYiGeXAwV0U1Uaw8kXEZj9i7wZDkvjzjSaNH3evRsg==}
|
resolution: {integrity: sha512-Fex8J8ASrt13pmOr2xWh41tEeKWwXYGk3sV8L/aGHiYtIJEUi2f+RtMx3jp7LIdOD8pQptor7i5WBlfR9jhp8A==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -1116,8 +1116,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-linux-x64-gnu@1.3.66:
|
/@swc/core-linux-x64-gnu@1.3.67:
|
||||||
resolution: {integrity: sha512-lg8E4O/Pd9KfK0lajdinVMuGME8dSv7V9arhEpmlfGE2eXSDCWqDn5Htk5QVBstt9lt1lsRhWHJ/YYc2eQY30Q==}
|
resolution: {integrity: sha512-9bz9/bMphrv5vDg0os/d8ve0QgFpDzJgZgHUaHiGwcmfnlgdOSAaYJLIvWdcGTjZuQeV4L0m+iru357D9TXEzA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -1125,8 +1125,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-linux-x64-musl@1.3.66:
|
/@swc/core-linux-x64-musl@1.3.67:
|
||||||
resolution: {integrity: sha512-lo8ZcAO/zL2pZWH+LZIyge8u2MklaeuT6+FpVVpBFktMVdYXbaVtzpvWbgRFBZHvL3SRDF+u8jxjtkXhvGUpTw==}
|
resolution: {integrity: sha512-ED0H6oLvQmhgo9zs8usmEA/lcZPGTu7K9og9K871b7HhHX0h/R+Xg2pb5KD7S/GyUHpfuopxjVROm+h6X1jMUA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@ -1134,8 +1134,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-win32-arm64-msvc@1.3.66:
|
/@swc/core-win32-arm64-msvc@1.3.67:
|
||||||
resolution: {integrity: sha512-cQoVwBuJY5WkHbfpCOlndNwYr1ZThatRjQQvKy540NUIeAEk9Fa6ozlDBtU75UdaWKtUG6YQ/bWz+KTemheVxw==}
|
resolution: {integrity: sha512-J1yFDLgPFeRtA8t5E159OXX+ww1gbkFg70yr4OP7EsOkOD1uMkuTf9yK/woHfsaVJlUYjJHzw7MkUIEgQBucqQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -1143,8 +1143,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-win32-ia32-msvc@1.3.66:
|
/@swc/core-win32-ia32-msvc@1.3.67:
|
||||||
resolution: {integrity: sha512-y/FrAIINK4UBeUQQknGlWXEyjo+MBvjF7WkUf2KP7sNr9EHHy8+dXohAGd5Anz0eJrqOM1ZXR/GEjxRp7bGQ1Q==}
|
resolution: {integrity: sha512-bK11/KtasewqHxzkjKUBXRE9MSAidbZCxrgJUd49bItG2N/DHxkwMYu8Xkh5VDHdTYWv/2idYtf/VM9Yi+53qw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -1152,8 +1152,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core-win32-x64-msvc@1.3.66:
|
/@swc/core-win32-x64-msvc@1.3.67:
|
||||||
resolution: {integrity: sha512-yI64ACzS14qFLrfyO12qW+f/UROTotzDeEbuyJAaPD2IZexoT1cICznI3sBmIfrSt33mVuW8eF5m3AG/NUImzw==}
|
resolution: {integrity: sha512-GxzUU3+NA3cPcYxCxtfSQIS2ySD7Z8IZmKTVaWA9GOUQbKLyCE8H5js31u39+0op/1gNgxOgYFDoj2lUyvLCqw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
@ -1161,8 +1161,8 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@swc/core@1.3.66:
|
/@swc/core@1.3.67:
|
||||||
resolution: {integrity: sha512-Hpf91kH5ly7fHkWnApwryTQryT+TO4kMMPH3WyciUSQOWLE3UuQz1PtETHQQk7PZ/b1QF0qQurJrgfBr5bSKUA==}
|
resolution: {integrity: sha512-9DROjzfAEt0xt0CDkOYsWpkUPyne8fl5ggWGon049678BOM7p0R0dmaalZGAsKatG5vYP1IWSKWsKhJIubDCsQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1171,16 +1171,16 @@ packages:
|
|||||||
'@swc/helpers':
|
'@swc/helpers':
|
||||||
optional: true
|
optional: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@swc/core-darwin-arm64': 1.3.66
|
'@swc/core-darwin-arm64': 1.3.67
|
||||||
'@swc/core-darwin-x64': 1.3.66
|
'@swc/core-darwin-x64': 1.3.67
|
||||||
'@swc/core-linux-arm-gnueabihf': 1.3.66
|
'@swc/core-linux-arm-gnueabihf': 1.3.67
|
||||||
'@swc/core-linux-arm64-gnu': 1.3.66
|
'@swc/core-linux-arm64-gnu': 1.3.67
|
||||||
'@swc/core-linux-arm64-musl': 1.3.66
|
'@swc/core-linux-arm64-musl': 1.3.67
|
||||||
'@swc/core-linux-x64-gnu': 1.3.66
|
'@swc/core-linux-x64-gnu': 1.3.67
|
||||||
'@swc/core-linux-x64-musl': 1.3.66
|
'@swc/core-linux-x64-musl': 1.3.67
|
||||||
'@swc/core-win32-arm64-msvc': 1.3.66
|
'@swc/core-win32-arm64-msvc': 1.3.67
|
||||||
'@swc/core-win32-ia32-msvc': 1.3.66
|
'@swc/core-win32-ia32-msvc': 1.3.67
|
||||||
'@swc/core-win32-x64-msvc': 1.3.66
|
'@swc/core-win32-x64-msvc': 1.3.67
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
|
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.2):
|
||||||
@ -1551,7 +1551,7 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^4
|
vite: ^4
|
||||||
dependencies:
|
dependencies:
|
||||||
'@swc/core': 1.3.66
|
'@swc/core': 1.3.67
|
||||||
vite: 4.3.9(@types/node@18.16.18)
|
vite: 4.3.9(@types/node@18.16.18)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@swc/helpers'
|
- '@swc/helpers'
|
||||||
@ -1796,7 +1796,7 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001509
|
caniuse-lite: 1.0.30001509
|
||||||
electron-to-chromium: 1.4.444
|
electron-to-chromium: 1.4.446
|
||||||
node-releases: 2.0.12
|
node-releases: 2.0.12
|
||||||
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
||||||
dev: true
|
dev: true
|
||||||
@ -2227,8 +2227,8 @@ packages:
|
|||||||
/eastasianwidth@0.2.0:
|
/eastasianwidth@0.2.0:
|
||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
|
|
||||||
/electron-to-chromium@1.4.444:
|
/electron-to-chromium@1.4.446:
|
||||||
resolution: {integrity: sha512-/AjkL4syRvOpowXWy3N4OHmVbFdWQpfSKHh0sCVYipDeEAtMce3rLjMJi/27Ia9jNIbw6P1JuPN32pSWybXXEQ==}
|
resolution: {integrity: sha512-4Gnw7ztEQ/E0eOt5JWfPn9jjeupfUlKoeW5ETKP9nLdWj+4spFoS3Stj19fqlKIaX28UQs0fNX+uKEyoLCBnkw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/emoji-regex@8.0.0:
|
/emoji-regex@8.0.0:
|
||||||
@ -2567,8 +2567,8 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/esm-loader-typescript@1.0.4:
|
/esm-loader-typescript@1.0.5:
|
||||||
resolution: {integrity: sha512-ejo2f+NKIt23jaJKVpjcRQC0xTa6cTqt6VA+z8Ef/A/TCjQ5u7opPO1J4fJFeTiiHEo8JqU92EG4I1KwuXYZMg==}
|
resolution: {integrity: sha512-BeHp2TrYbRL9fUttlyzPQJPTvLDBXXUli09UNoAr87WKi8jedcULlMteNZgl7DtFZ3ZE1Mmv74SwRgwJDWyc0A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
create-esm-loader: 0.2.3
|
create-esm-loader: 0.2.3
|
||||||
npm-run-all: 4.1.5
|
npm-run-all: 4.1.5
|
||||||
@ -3832,8 +3832,8 @@ packages:
|
|||||||
engines: {node: '>=12.20'}
|
engines: {node: '>=12.20'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/nostr-tools@1.12.0:
|
/nostr-tools@1.12.1:
|
||||||
resolution: {integrity: sha512-fsIXaNJPKaSrO9MxsCEWbhI4tG4pToQK4D4sgLRD0fRDfZ6ocCg8CLlh9lcNx0o8pVErCMLVASxbJ+w4WNK0MA==}
|
resolution: {integrity: sha512-ZeoV7g3jBUAlb4mKa3C+6hrc84htPkbebMShfGNgV4vAiz18e/sQukUBFL6vb/+sxZy+dBQFkRwsJIaVFs8Gfw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/curves': 1.0.0
|
'@noble/curves': 1.0.0
|
||||||
'@noble/hashes': 1.3.0
|
'@noble/hashes': 1.3.0
|
||||||
@ -4455,8 +4455,8 @@ packages:
|
|||||||
glob: 7.2.3
|
glob: 7.2.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/rollup@3.25.3:
|
/rollup@3.26.0:
|
||||||
resolution: {integrity: sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw==}
|
resolution: {integrity: sha512-YzJH0eunH2hr3knvF3i6IkLO/jTjAEwU4HoMUbQl4//Tnl3ou0e7P5SjxdDr8HQJdeUJShlbEHXrrnEHy1l7Yg==}
|
||||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@ -5159,7 +5159,7 @@ packages:
|
|||||||
vite: '>=2.8'
|
vite: '>=2.8'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/plugin-virtual': 3.0.1
|
'@rollup/plugin-virtual': 3.0.1
|
||||||
'@swc/core': 1.3.66
|
'@swc/core': 1.3.67
|
||||||
uuid: 9.0.0
|
uuid: 9.0.0
|
||||||
vite: 4.3.9(@types/node@18.16.18)
|
vite: 4.3.9(@types/node@18.16.18)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -5212,7 +5212,7 @@ packages:
|
|||||||
'@types/node': 18.16.18
|
'@types/node': 18.16.18
|
||||||
esbuild: 0.17.19
|
esbuild: 0.17.19
|
||||||
postcss: 8.4.24
|
postcss: 8.4.24
|
||||||
rollup: 3.25.3
|
rollup: 3.26.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -14,24 +14,6 @@ CREATE TABLE
|
|||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
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 notes table
|
||||||
CREATE TABLE
|
CREATE TABLE
|
||||||
notes (
|
notes (
|
||||||
|
@ -20,7 +20,7 @@ export function ChatMessageForm({
|
|||||||
const tags = [["p", receiverPubkey]];
|
const tags = [["p", receiverPubkey]];
|
||||||
|
|
||||||
// publish message
|
// publish message
|
||||||
publish({ content: message, kind: 4, tags });
|
await publish({ content: message, kind: 4, tags });
|
||||||
|
|
||||||
// reset state
|
// reset state
|
||||||
setValue("");
|
setValue("");
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
|
import { User } from "@app/auth/components/user";
|
||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
import { getPlebs } from "@libs/storage";
|
|
||||||
import { CancelIcon, PlusIcon } from "@shared/icons";
|
import { CancelIcon, PlusIcon } from "@shared/icons";
|
||||||
import { DEFAULT_AVATAR } from "@stores/constants";
|
import { useAccount } from "@utils/hooks/useAccount";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
import { nip19 } from "nostr-tools";
|
|
||||||
import { Fragment, useState } from "react";
|
import { Fragment, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
export function NewMessageModal() {
|
export function NewMessageModal() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { status, data }: any = useQuery(["plebs"], async () => {
|
|
||||||
return await getPlebs();
|
|
||||||
});
|
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
const { status, account } = useAccount();
|
||||||
|
const follows = account ? JSON.parse(account.follows) : [];
|
||||||
|
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
};
|
};
|
||||||
@ -24,8 +20,7 @@ export function NewMessageModal() {
|
|||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openChat = (npub: string) => {
|
const openChat = (pubkey: string) => {
|
||||||
const pubkey = nip19.decode(npub).data;
|
|
||||||
closeModal();
|
closeModal();
|
||||||
navigate(`/app/chat/${pubkey}`);
|
navigate(`/app/chat/${pubkey}`);
|
||||||
};
|
};
|
||||||
@ -99,31 +94,16 @@ export function NewMessageModal() {
|
|||||||
{status === "loading" ? (
|
{status === "loading" ? (
|
||||||
<p>Loading...</p>
|
<p>Loading...</p>
|
||||||
) : (
|
) : (
|
||||||
data.map((pleb) => (
|
follows.map((follow) => (
|
||||||
<div
|
<div
|
||||||
key={pleb.npub}
|
key={follow}
|
||||||
className="group flex items-center justify-between px-4 py-3 hover:bg-zinc-800"
|
className="group flex items-center justify-between px-4 py-3 hover:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<User pubkey={follow} />
|
||||||
<img
|
|
||||||
alt={pleb.npub}
|
|
||||||
src={pleb.image || DEFAULT_AVATAR}
|
|
||||||
className="w-9 h-9 shrink-0 object-cover rounded"
|
|
||||||
/>
|
|
||||||
<div className="inline-flex flex-col gap-1">
|
|
||||||
<h3 className="leading-none max-w-[15rem] line-clamp-1 font-medium text-zinc-100">
|
|
||||||
{pleb.displayName || pleb.name}
|
|
||||||
</h3>
|
|
||||||
<span className="leading-none max-w-[10rem] line-clamp-1 text-sm text-zinc-400">
|
|
||||||
{pleb.nip05 ||
|
|
||||||
pleb.npub.substring(0, 16).concat("...")}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => openChat(pleb.npub)}
|
onClick={() => openChat(follow)}
|
||||||
className="inline-flex text-sm w-max px-3 py-1.5 rounded border-t border-zinc-600/50 bg-zinc-700 hover:bg-fuchsia-500 transform translate-x-20 group-hover:translate-x-0 transition-transform ease-in-out duration-150"
|
className="inline-flex text-sm w-max px-3 py-1.5 rounded border-t border-zinc-600/50 bg-zinc-700 hover:bg-fuchsia-500 transform translate-x-20 group-hover:translate-x-0 transition-transform ease-in-out duration-150"
|
||||||
>
|
>
|
||||||
Chat
|
Chat
|
||||||
|
@ -2,18 +2,11 @@ import { Image } from "@shared/image";
|
|||||||
import { DEFAULT_AVATAR } from "@stores/constants";
|
import { DEFAULT_AVATAR } from "@stores/constants";
|
||||||
import { useProfile } from "@utils/hooks/useProfile";
|
import { useProfile } from "@utils/hooks/useProfile";
|
||||||
import { shortenKey } from "@utils/shortenKey";
|
import { shortenKey } from "@utils/shortenKey";
|
||||||
import { nip19 } from "nostr-tools";
|
import { Link } from "react-router-dom";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
|
|
||||||
export function ChatSidebar({ pubkey }: { pubkey: string }) {
|
export function ChatSidebar({ pubkey }: { pubkey: string }) {
|
||||||
const navigate = useNavigate();
|
|
||||||
const { user } = useProfile(pubkey);
|
const { user } = useProfile(pubkey);
|
||||||
|
|
||||||
const viewProfile = () => {
|
|
||||||
const pubkey = nip19.decode(user.npub).data;
|
|
||||||
navigate(`/app/user/${pubkey}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-3 py-2">
|
<div className="px-3 py-2">
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
@ -36,13 +29,12 @@ export function ChatSidebar({ pubkey }: { pubkey: string }) {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="leading-tight">{user?.bio || user?.about}</p>
|
<p className="leading-tight">{user?.bio || user?.about}</p>
|
||||||
<button
|
<Link
|
||||||
type="button"
|
to={`/app/user/${pubkey}`}
|
||||||
onClick={() => viewProfile()}
|
|
||||||
className="mt-3 inline-flex w-full h-10 items-center justify-center rounded-md bg-zinc-900 hover:bg-zinc-800 text-sm text-zinc-300 hover:text-zinc-100 font-medium"
|
className="mt-3 inline-flex w-full h-10 items-center justify-center rounded-md bg-zinc-900 hover:bg-zinc-800 text-sm text-zinc-300 hover:text-zinc-100 font-medium"
|
||||||
>
|
>
|
||||||
View full profile
|
View full profile
|
||||||
</button>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
createNote,
|
createNote,
|
||||||
getChannels,
|
getChannels,
|
||||||
getLastLogin,
|
getLastLogin,
|
||||||
|
updateLastLogin,
|
||||||
} from "@libs/storage";
|
} from "@libs/storage";
|
||||||
import { NDKFilter } from "@nostr-dev-kit/ndk";
|
import { NDKFilter } from "@nostr-dev-kit/ndk";
|
||||||
import { LoaderIcon, LumeIcon } from "@shared/icons";
|
import { LoaderIcon, LumeIcon } from "@shared/icons";
|
||||||
@ -142,6 +143,7 @@ export function Root() {
|
|||||||
const chats = await fetchChats();
|
const chats = await fetchChats();
|
||||||
// const channels = await fetchChannelMessages();
|
// const channels = await fetchChannelMessages();
|
||||||
if (chats) {
|
if (chats) {
|
||||||
|
await updateLastLogin(dateToUnix());
|
||||||
navigate("/app/space", { replace: true });
|
navigate("/app/space", { replace: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import { useVirtualizer } from "@tanstack/react-virtual";
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
const ITEM_PER_PAGE = 10;
|
const ITEM_PER_PAGE = 10;
|
||||||
const TIME = Math.floor(Date.now() / 1000);
|
|
||||||
|
|
||||||
export function FeedBlock({ params }: { params: any }) {
|
export function FeedBlock({ params }: { params: any }) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@ -21,7 +20,6 @@ export function FeedBlock({ params }: { params: any }) {
|
|||||||
queryFn: async ({ pageParam = 0 }) => {
|
queryFn: async ({ pageParam = 0 }) => {
|
||||||
return await getNotesByAuthors(
|
return await getNotesByAuthors(
|
||||||
params.content,
|
params.content,
|
||||||
TIME,
|
|
||||||
ITEM_PER_PAGE,
|
ITEM_PER_PAGE,
|
||||||
pageParam,
|
pageParam,
|
||||||
);
|
);
|
||||||
|
@ -9,7 +9,6 @@ import { useVirtualizer } from "@tanstack/react-virtual";
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
const ITEM_PER_PAGE = 10;
|
const ITEM_PER_PAGE = 10;
|
||||||
const TIME = Math.floor(Date.now() / 1000);
|
|
||||||
|
|
||||||
export function FollowingBlock({ block }: { block: number }) {
|
export function FollowingBlock({ block }: { block: number }) {
|
||||||
// subscribe for live update
|
// subscribe for live update
|
||||||
@ -29,7 +28,7 @@ export function FollowingBlock({ block }: { block: number }) {
|
|||||||
}: any = useInfiniteQuery({
|
}: any = useInfiniteQuery({
|
||||||
queryKey: ["newsfeed-circle"],
|
queryKey: ["newsfeed-circle"],
|
||||||
queryFn: async ({ pageParam = 0 }) => {
|
queryFn: async ({ pageParam = 0 }) => {
|
||||||
return await getNotes(TIME, ITEM_PER_PAGE, pageParam);
|
return await getNotes(ITEM_PER_PAGE, pageParam);
|
||||||
},
|
},
|
||||||
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
||||||
});
|
});
|
||||||
@ -64,7 +63,7 @@ export function FollowingBlock({ block }: { block: number }) {
|
|||||||
|
|
||||||
const refreshFirstPage = () => {
|
const refreshFirstPage = () => {
|
||||||
// refetch
|
// refetch
|
||||||
refetch({ refetchPage: (page, index) => index === 0 });
|
refetch({ refetchPage: (_, index: number) => index === 0 });
|
||||||
// scroll to top
|
// scroll to top
|
||||||
rowVirtualizer.scrollToIndex(1);
|
rowVirtualizer.scrollToIndex(1);
|
||||||
// stop notify
|
// stop notify
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { createReplyNote } from "./storage";
|
|
||||||
import NDK, {
|
import NDK, {
|
||||||
NDKConstructorParams,
|
NDKConstructorParams,
|
||||||
NDKEvent,
|
NDKEvent,
|
||||||
@ -15,21 +14,10 @@ export async function initNDK(relays?: string[]): Promise<NDK> {
|
|||||||
const opts: NDKConstructorParams = {};
|
const opts: NDKConstructorParams = {};
|
||||||
const defaultRelays = new Set(relays || FULL_RELAYS);
|
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];
|
opts.explicitRelayUrls = [...defaultRelays];
|
||||||
|
|
||||||
const ndk = new NDK(opts);
|
const ndk = new NDK(opts);
|
||||||
await ndk.connect();
|
await ndk.connect(500);
|
||||||
|
|
||||||
return ndk;
|
return ndk;
|
||||||
}
|
}
|
||||||
@ -57,15 +45,10 @@ export async function prefetchEvents(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function usePublish() {
|
export function usePublish() {
|
||||||
const { account } = useAccount();
|
|
||||||
const ndk = useContext(RelayContext);
|
const ndk = useContext(RelayContext);
|
||||||
|
const { account } = useAccount();
|
||||||
|
|
||||||
if (!ndk.signer) {
|
const publish = async ({
|
||||||
const signer = new NDKPrivateKeySigner(account?.privkey);
|
|
||||||
ndk.signer = signer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const publish = ({
|
|
||||||
content,
|
content,
|
||||||
kind,
|
kind,
|
||||||
tags,
|
tags,
|
||||||
@ -73,8 +56,9 @@ export function usePublish() {
|
|||||||
content: string;
|
content: string;
|
||||||
kind: NDKKind;
|
kind: NDKKind;
|
||||||
tags: string[][];
|
tags: string[][];
|
||||||
}): NDKEvent => {
|
}): Promise<NDKEvent> => {
|
||||||
const event = new NDKEvent(ndk);
|
const event = new NDKEvent(ndk);
|
||||||
|
const signer = new NDKPrivateKeySigner(account.privkey);
|
||||||
|
|
||||||
event.content = content;
|
event.content = content;
|
||||||
event.kind = kind;
|
event.kind = kind;
|
||||||
@ -82,7 +66,8 @@ export function usePublish() {
|
|||||||
event.pubkey = account.pubkey;
|
event.pubkey = account.pubkey;
|
||||||
event.tags = tags;
|
event.tags = tags;
|
||||||
|
|
||||||
event.publish();
|
await event.sign(signer);
|
||||||
|
await event.publish();
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { NDKTag, NDKUserProfile } from "@nostr-dev-kit/ndk";
|
|
||||||
import { getParentID } from "@utils/transform";
|
import { getParentID } from "@utils/transform";
|
||||||
import { nip19 } from "nostr-tools";
|
|
||||||
import Database from "tauri-plugin-sql-api";
|
import Database from "tauri-plugin-sql-api";
|
||||||
|
|
||||||
let db: null | Database = null;
|
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
|
// count total notes
|
||||||
export async function countTotalChannels() {
|
export async function countTotalChannels() {
|
||||||
const db = await connect();
|
const db = await connect();
|
||||||
@ -139,14 +88,14 @@ export async function countTotalNotes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get all notes
|
// 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 db = await connect();
|
||||||
const totalNotes = await countTotalNotes();
|
const totalNotes = await countTotalNotes();
|
||||||
const nextCursor = offset + limit;
|
const nextCursor = offset + limit;
|
||||||
|
|
||||||
const notes: any = { data: null, nextCursor: 0 };
|
const notes: any = { data: null, nextCursor: 0 };
|
||||||
const query: any = await db.select(
|
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;
|
notes["data"] = query;
|
||||||
@ -169,7 +118,6 @@ export async function getNotesByPubkey(pubkey: string) {
|
|||||||
// get all notes by authors
|
// get all notes by authors
|
||||||
export async function getNotesByAuthors(
|
export async function getNotesByAuthors(
|
||||||
authors: string,
|
authors: string,
|
||||||
time: number,
|
|
||||||
limit: number,
|
limit: number,
|
||||||
offset: number,
|
offset: number,
|
||||||
) {
|
) {
|
||||||
@ -181,7 +129,7 @@ export async function getNotesByAuthors(
|
|||||||
|
|
||||||
const notes: any = { data: null, nextCursor: 0 };
|
const notes: any = { data: null, nextCursor: 0 };
|
||||||
const query: any = await db.select(
|
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;
|
notes["data"] = query;
|
||||||
|
@ -97,7 +97,7 @@ export function Post() {
|
|||||||
|
|
||||||
const refID = getRef();
|
const refID = getRef();
|
||||||
|
|
||||||
const submit = () => {
|
const submit = async () => {
|
||||||
let tags: string[][] = [];
|
let tags: string[][] = [];
|
||||||
let kind: number;
|
let kind: number;
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ export function Post() {
|
|||||||
const serializedContent = serialize(content);
|
const serializedContent = serialize(content);
|
||||||
|
|
||||||
// publish message
|
// publish message
|
||||||
publish({ content: serializedContent, kind, tags });
|
await publish({ content: serializedContent, kind, tags });
|
||||||
|
|
||||||
// close modal
|
// close modal
|
||||||
toggle(false);
|
toggle(false);
|
||||||
|
@ -1,38 +1,51 @@
|
|||||||
import { Dialog, Transition } from "@headlessui/react";
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
import { usePublish } from "@libs/ndk";
|
import { usePublish } from "@libs/ndk";
|
||||||
import { getPleb } from "@libs/storage";
|
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||||
import { AvatarUploader } from "@shared/avatarUploader";
|
import { AvatarUploader } from "@shared/avatarUploader";
|
||||||
import { BannerUploader } from "@shared/bannerUploader";
|
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 { Image } from "@shared/image";
|
||||||
import { DEFAULT_AVATAR } from "@stores/constants";
|
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 { useAccount } from "@utils/hooks/useAccount";
|
||||||
import { Fragment, useState } from "react";
|
import { Fragment, useEffect, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
export function EditProfileModal() {
|
export function EditProfileModal() {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const publish = usePublish();
|
const publish = usePublish();
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [picture, setPicture] = useState(DEFAULT_AVATAR);
|
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 { account } = useAccount();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
reset,
|
reset,
|
||||||
formState: { isValid },
|
setError,
|
||||||
|
formState: { isValid, errors },
|
||||||
} = useForm({
|
} = useForm({
|
||||||
defaultValues: async () => {
|
defaultValues: async () => {
|
||||||
const res = await getPleb(account.npub);
|
const res: any = queryClient.getQueryData(["user", account.pubkey]);
|
||||||
if (res.picture) {
|
if (res.image) {
|
||||||
setPicture(res.image);
|
setPicture(res.image);
|
||||||
}
|
}
|
||||||
if (res.banner) {
|
if (res.banner) {
|
||||||
setBanner(res.banner);
|
setBanner(res.banner);
|
||||||
}
|
}
|
||||||
|
if (res.nip05) {
|
||||||
|
setNIP05((prev) => ({ ...prev, text: res.nip05 }));
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -45,24 +58,72 @@ export function EditProfileModal() {
|
|||||||
setIsOpen(true);
|
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
|
// start loading
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
// publish
|
let event: NDKEvent;
|
||||||
const event = publish({
|
|
||||||
content: JSON.stringify({
|
const content = {
|
||||||
...data,
|
...data,
|
||||||
|
username: data.name,
|
||||||
display_name: data.name,
|
display_name: data.name,
|
||||||
bio: data.about,
|
bio: data.about,
|
||||||
image: data.picture,
|
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,
|
kind: 0,
|
||||||
tags: [],
|
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) {
|
if (event.id) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
// invalid cache
|
||||||
|
queryClient.invalidateQueries(["user", account.pubkey]);
|
||||||
// reset form
|
// reset form
|
||||||
reset();
|
reset();
|
||||||
// reset state
|
// reset state
|
||||||
@ -71,9 +132,17 @@ export function EditProfileModal() {
|
|||||||
setPicture(DEFAULT_AVATAR);
|
setPicture(DEFAULT_AVATAR);
|
||||||
setBanner(null);
|
setBanner(null);
|
||||||
}, 1200);
|
}, 1200);
|
||||||
|
} else {
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!nip05.verified && /\S+@\S+\.\S+/.test(nip05.text)) {
|
||||||
|
verifyNIP05(nip05.text);
|
||||||
|
}
|
||||||
|
}, [nip05.text]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
@ -179,6 +248,39 @@ export function EditProfileModal() {
|
|||||||
className="relative h-10 w-full rounded-lg px-3 py-2 !outline-none bg-zinc-800 text-zinc-100 placeholder:text-zinc-500"
|
className="relative h-10 w-full rounded-lg px-3 py-2 !outline-none bg-zinc-800 text-zinc-100 placeholder:text-zinc-500"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex flex-col gap-1">
|
||||||
|
<label className="text-sm font-semibold uppercase tracking-wider text-zinc-400">
|
||||||
|
Lume ID / NIP-05
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<input
|
||||||
|
{...register("nip05", {
|
||||||
|
required: true,
|
||||||
|
minLength: 4,
|
||||||
|
})}
|
||||||
|
spellCheck={false}
|
||||||
|
className="relative h-10 w-full rounded-lg px-3 py-2 !outline-none bg-zinc-800 text-zinc-100 placeholder:text-zinc-500"
|
||||||
|
/>
|
||||||
|
<div className="absolute top-1/2 right-2 transform -translate-y-1/2">
|
||||||
|
{nip05.verified ? (
|
||||||
|
<span className="inline-flex items-center gap-1 rounded h-6 px-2 bg-green-500 text-sm font-medium">
|
||||||
|
<CheckCircleIcon className="w-4 h-4 text-white" />
|
||||||
|
Verified
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="inline-flex items-center gap-1 rounded h-6 px-2 bg-red-500 text-sm font-medium">
|
||||||
|
<UnverifiedIcon className="w-4 h-4 text-white" />
|
||||||
|
Unverified
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{errors.nip05 && (
|
||||||
|
<p className="mt-1 text-sm text-red-400">
|
||||||
|
{errors.nip05.message.toString()}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<label className="text-sm font-semibold uppercase tracking-wider text-zinc-400">
|
<label className="text-sm font-semibold uppercase tracking-wider text-zinc-400">
|
||||||
Bio
|
Bio
|
||||||
|
@ -38,4 +38,5 @@ export * from "./empty";
|
|||||||
export * from "./cmd";
|
export * from "./cmd";
|
||||||
export * from "./verticalDots";
|
export * from "./verticalDots";
|
||||||
export * from "./signal";
|
export * from "./signal";
|
||||||
|
export * from "./unverified";
|
||||||
// @endindex
|
// @endindex
|
||||||
|
23
src/shared/icons/unverified.tsx
Normal file
23
src/shared/icons/unverified.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { SVGProps } from "react";
|
||||||
|
|
||||||
|
export function UnverifiedIcon(
|
||||||
|
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12zm7.53-3.53a.75.75 0 00-1.06 1.06L10.94 12l-2.47 2.47a.75.75 0 101.06 1.06L12 13.06l2.47 2.47a.75.75 0 101.06-1.06L13.06 12l2.47-2.47a.75.75 0 00-1.06-1.06L12 10.94 9.53 8.47z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
@ -1,38 +1,28 @@
|
|||||||
import { createPleb, getPleb } from "@libs/storage";
|
|
||||||
import { RelayContext } from "@shared/relayProvider";
|
import { RelayContext } from "@shared/relayProvider";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { nip19 } from "nostr-tools";
|
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
|
|
||||||
export function useProfile(id: string) {
|
export function useProfile(pubkey: string) {
|
||||||
const ndk = useContext(RelayContext);
|
const ndk = useContext(RelayContext);
|
||||||
const {
|
const {
|
||||||
status,
|
status,
|
||||||
data: user,
|
data: user,
|
||||||
error,
|
error,
|
||||||
isFetching,
|
isFetching,
|
||||||
} = useQuery(["user", id], async () => {
|
} = useQuery(
|
||||||
let npub: string;
|
["user", pubkey],
|
||||||
|
async () => {
|
||||||
if (id.substring(0, 4) === "npub") {
|
const user = ndk.getUser({ hexpubkey: pubkey });
|
||||||
npub = id;
|
|
||||||
} else {
|
|
||||||
npub = nip19.npubEncode(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const current = Math.floor(Date.now() / 1000);
|
|
||||||
const result = await getPleb(npub);
|
|
||||||
|
|
||||||
if (result && parseInt(result.created_at) + 86400 >= current) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
const user = ndk.getUser({ npub });
|
|
||||||
await user.fetchProfile();
|
await user.fetchProfile();
|
||||||
await createPleb(id, user.profile);
|
|
||||||
|
|
||||||
return user.profile;
|
return user.profile;
|
||||||
}
|
},
|
||||||
});
|
{
|
||||||
|
staleTime: Infinity,
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return { status, user, error, isFetching };
|
return { status, user, error, isFetching };
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,9 @@ export function useSocial() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: account ? true : false,
|
enabled: account ? true : false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user