re-enable nip-04 with more polish, prepare for nip-44

This commit is contained in:
Ren Amamiya 2023-08-24 09:05:34 +07:00
parent 3455eb701f
commit 4893ebd932
19 changed files with 376 additions and 242 deletions

View File

@ -46,13 +46,13 @@
"@tauri-apps/plugin-stronghold": "github:tauri-apps/tauri-plugin-stronghold#v2",
"@tauri-apps/plugin-upload": "github:tauri-apps/tauri-plugin-upload#v2",
"@tauri-apps/plugin-window": "github:tauri-apps/tauri-plugin-window#v2",
"@tiptap/extension-image": "^2.1.6",
"@tiptap/extension-mention": "^2.1.6",
"@tiptap/extension-placeholder": "^2.1.6",
"@tiptap/pm": "^2.1.6",
"@tiptap/react": "^2.1.6",
"@tiptap/starter-kit": "^2.1.6",
"@tiptap/suggestion": "^2.1.6",
"@tiptap/extension-image": "^2.1.7",
"@tiptap/extension-mention": "^2.1.7",
"@tiptap/extension-placeholder": "^2.1.7",
"@tiptap/pm": "^2.1.7",
"@tiptap/react": "^2.1.7",
"@tiptap/starter-kit": "^2.1.7",
"@tiptap/suggestion": "^2.1.7",
"@void-cat/api": "^1.0.7",
"dayjs": "^1.11.9",
"destr": "^2.0.1",
@ -80,7 +80,7 @@
"@tailwindcss/typography": "^0.5.9",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/html-to-text": "^9.0.1",
"@types/node": "^20.5.3",
"@types/node": "^20.5.4",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/youtube-player": "^5.5.7",

View File

@ -89,26 +89,26 @@ dependencies:
specifier: github:tauri-apps/tauri-plugin-window#v2
version: github.com/tauri-apps/tauri-plugin-window/09c9732d0c98c13ee8aeb51de61f7eef3eb33a4b
'@tiptap/extension-image':
specifier: ^2.1.6
version: 2.1.6(@tiptap/core@2.1.6)
specifier: ^2.1.7
version: 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-mention':
specifier: ^2.1.6
version: 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)(@tiptap/suggestion@2.1.6)
specifier: ^2.1.7
version: 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)(@tiptap/suggestion@2.1.7)
'@tiptap/extension-placeholder':
specifier: ^2.1.6
version: 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
specifier: ^2.1.7
version: 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/pm':
specifier: ^2.1.6
version: 2.1.6
specifier: ^2.1.7
version: 2.1.7
'@tiptap/react':
specifier: ^2.1.6
version: 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)(react-dom@18.2.0)(react@18.2.0)
specifier: ^2.1.7
version: 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)(react-dom@18.2.0)(react@18.2.0)
'@tiptap/starter-kit':
specifier: ^2.1.6
version: 2.1.6(@tiptap/pm@2.1.6)
specifier: ^2.1.7
version: 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/suggestion':
specifier: ^2.1.6
version: 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
specifier: ^2.1.7
version: 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@void-cat/api':
specifier: ^1.0.7
version: 1.0.7
@ -187,8 +187,8 @@ devDependencies:
specifier: ^9.0.1
version: 9.0.1
'@types/node':
specifier: ^20.5.3
version: 20.5.3
specifier: ^20.5.4
version: 20.5.4
'@types/react':
specifier: ^18.2.21
version: 18.2.21
@ -266,7 +266,7 @@ devDependencies:
version: 5.1.6
vite:
specifier: ^4.4.9
version: 4.4.9(@types/node@20.5.3)
version: 4.4.9(@types/node@20.5.4)
vite-tsconfig-paths:
specifier: ^4.2.0
version: 4.2.0(typescript@5.1.6)(vite@4.4.9)
@ -945,11 +945,22 @@ packages:
'@noble/hashes': 1.3.1
dev: false
/@noble/curves@1.2.0:
resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
dependencies:
'@noble/hashes': 1.3.2
dev: false
/@noble/hashes@1.3.1:
resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==}
engines: {node: '>= 16'}
dev: false
/@noble/hashes@1.3.2:
resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
engines: {node: '>= 16'}
dev: false
/@noble/secp256k1@2.0.0:
resolution: {integrity: sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==}
dev: false
@ -975,7 +986,7 @@ packages:
/@nostr-dev-kit/ndk@0.8.21(typescript@5.1.6):
resolution: {integrity: sha512-nthH3uoFuaXWqhZt96/p/iXTbYcMdkcee6pDm+Wi+MIcEsbj4o7r+ChoQ757TQZtEBLkOmku8/loi2LnHpkI9A==}
dependencies:
'@noble/hashes': 1.3.1
'@noble/hashes': 1.3.2
'@noble/secp256k1': 2.0.0
'@scure/base': 1.1.1
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.47.0)(typescript@5.1.6)
@ -1015,8 +1026,8 @@ packages:
/@nostr-fetch/kernel@0.12.2:
resolution: {integrity: sha512-ja7StOV33NmdtAMGfQIS0/R0dAkLRm3QxN6u/YAQdp5mXER4BYxiQKxUS/dCoTCSX986MH2zp9Fm0f76u4VaNQ==}
dependencies:
'@noble/curves': 1.1.0
'@noble/hashes': 1.3.1
'@noble/curves': 1.2.0
'@noble/hashes': 1.3.2
dev: false
/@popperjs/core@2.11.8:
@ -2000,222 +2011,222 @@ packages:
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-alpha.11
dev: false
/@tiptap/core@2.1.6(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-gm8n1oiBhSP6CDhalmmWwLD7yzIUqJJ246/t8rY3o+HJ/I+p0rqCx0mPvMiwcIBmYX8tUCVz7mb9aSFUu/umOQ==}
/@tiptap/core@2.1.7(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-1pqTwlTnwTKQSNQmmTWhs2lwdvd+hFFNFZnrRAfvZhQZA6qPmPmKMNTcYmK38Tn4axKth6mhBamzTJgMZFI7ng==}
peerDependencies:
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/pm': 2.1.6
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-blockquote@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-y3Jj9XcJaUjlEZZFBQUZcToOjamL64B/Jjlu7JUv87VArWWpg5Pnd2sQG3l9A/q1vfY0/TpHm7r5EvKoeIq6ag==}
/@tiptap/extension-blockquote@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-oAsUU1c0DDZKHwK7/uCtYpnTUQt0o3w+SsJSv4S2vlSHidiFl9gCQGozUQ/Alzc7GO1Y95rOscL28DJXgXESQg==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-bold@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-gZDVuhYdceBQ/xGGY1X7lmkgNrDHFuFYBFRWMK0pLe9YBlQtJPc6+hiOmCtRtGmbQADDnvMmSU2a0+8bckmbCw==}
/@tiptap/extension-bold@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-GZV2D91WENkWd1W29vM4kyGWObcxOKQrY8MuCvTdxni1kobEc/LPZzQ1XiQmiNTvXTMcBz5ckLpezdjASV1dNg==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-bubble-menu@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-13YDJB19xbDL/SZaPs8NvUAA+w5MIWugP8ByKQeIlL8vlcbiJjqoT77YP6v300DtFyVrnLo/iMJh9RMB4NOnwg==}
/@tiptap/extension-bubble-menu@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-VcwwUgiG17TEDZda1JBbyKCHLIBTu8B2OAzYrnd4ZqeRs5KTVAB279o/TVjsLVgEfC+c7IWwhhaPPMoXn/lJ3g==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
tippy.js: 6.3.7
dev: false
/@tiptap/extension-bullet-list@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-NjPL5cIa4wVqv62OEw4lQ4Dj4c2hxia7GtPKHZKjoot5iu1RDkzD9Cxy/0tmH0vfCwTqa0JbGf9FAxRCyok4kg==}
/@tiptap/extension-bullet-list@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-BReix1wkGNH12DSWGnWPKNu4do92Avh98aLkRS1o1V1Y49/+YGMYtfBXB9obq40o0WqKvk4MoM+rhKbfEc44Gg==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-code-block@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-tLK9YeHYz03qeG4Sy5uZMq6v5uo34315I4WrfIAujesDloG1v8nd+D9I8A7PD4BWHZOzv13ToVeDYpLYDdvE7Q==}
/@tiptap/extension-code-block@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-uiasfWCIQuk34vGoIENqAJOHf9m3hAkcELnb9T6+uNxA3O7PUZQqBVN/27oEipj7j15pqua50D6C1jql9kFe0g==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-code@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-vFWE74Aipt0kbmWyya+9zvsAgVusbbHx8g3Zqm8iKDt95BY3MWGurCZ3F5uoVuPuWD9VSrbNs4/T6oKbVKc9Ow==}
/@tiptap/extension-code@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-g0IA6Q6DFZE0AEOMXAV1mktl/XzIO3s1h/haPIKZ8GNes522qhBr9FYc5OUPQCCbgYjL7soTGzxA/W5Jk3f2AQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-document@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-econFqLeQR8pe0xv7kjw6ZPRhcNXGrNi9854celX0lhqTqtBxvU6nWHzUDzoq/lmnXYgpFTPv42AwUEspvpwdw==}
/@tiptap/extension-document@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-tZyoPPmvzti7PEnyulXomEtINd/Oi2S84uOt6gw7DTCnDq5bF5sn1IfN8Icqp9t4jDwyLXy2TL0Zg/sR0a2Ibg==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-dropcursor@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-+nk4XtCp2+lVf1pzwonaOdIolE9AI3HPAtUO7sthHYLDIm1JEQT2GS3+MVDGHdFKxEGUkB5DEcNLtr/xLTQjZQ==}
/@tiptap/extension-dropcursor@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-hNk2BuLnNSXlGOQphlzdpFKCKo7uHUFjWuBfzF1S9FMAQgcN7eTia+cCClmXABYfVLW4fT14PC1KiuGjxi9MuA==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-floating-menu@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-Xy4esdjsZlgNxMbBC6+wLoiTfqaqFjuFquqcYEPqzgBizYa15Ww6wIx5+h2K+hzyJkSPI7ZX/rPjKXML8lNteQ==}
/@tiptap/extension-floating-menu@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-K0bO7JKHAvgLM5MkhNgoYcD6SB0Z2tNIFhZHs5SCTuhg7dwduMSM3pC6QBrJGUk99DGsKuMPYQn3c2oG7MLbyQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
tippy.js: 6.3.7
dev: false
/@tiptap/extension-gapcursor@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-5AH6Je1B6JpZkMBslXw/UglMpxVwL8AXqX5xWKP2OSsKVYcL00jApq709FxfYhyqui/SukUVusKKQFstTNqIGA==}
/@tiptap/extension-gapcursor@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-7eoInzzk1sssoD3RMkwFC86U15Ja4ANve+8wIC+xhN4R3Oe3PY3lFbp1GQxCmaJj8b3rtjNKIQZ2zO0PH58afA==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-hard-break@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-znFYceEFbrgxhHZF+/wNQlAn3MWG9/VRqQAFxPGne0csewibKZRwZbeSYZQ16x1vSAlAQsKhIaAst/na/2H8LA==}
/@tiptap/extension-hard-break@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-6gFXXlCGAdXjy27BW29q4yfCQPAEFd18k7zRTnbd4aE/zIWUtLqdiTfI3kotUMab9Tt9/z1BRmCbEUxRsf1Nww==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-heading@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-V6PImalPhgAxsA95op70ssb8IXehLyr7wu5t1SeoTUUQtvMojKXPd+n+xF5b4b7VIhXHDlGSnoT0/XwjCJY0tQ==}
/@tiptap/extension-heading@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-jMeTqtq3kbMFtMvUb3SeIt4FFM3W+b6TAw5H4Qd6z3gYsAU3GahRK67MtbJfPmznUkZfimrqW9VCaBezScfrsQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-history@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-ltHz9cW3bWi7Z3m960F5eLPAqZDBNOpUP31t9YdKqhyxA16eygryj1USVeus9DX5OBoW79I8EecFAuRo3Rymlw==}
/@tiptap/extension-history@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-8SIEKSImrIkqJThym1bPD13sC4/76UrG+piQ30xKQU4B7zUFCbutvrwYuQHSRvaEt8BPdTv2LWIK+wBkIgbWVA==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-horizontal-rule@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-1epXM+4DRlhos+Awj4sHApceO2O26tuqyrZot0Mm+mF0yuCGy3B5fefAgUcxBu/oRuywfDl8cwCzN2E/d8KXtA==}
/@tiptap/extension-horizontal-rule@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-hJupsDxDVmjmKI/Ewl/gtiyUx52Y3wRUhT8dCXNOA5eldmPXN23E2Fa2BC8XB47dyc5pubyNcLuqaLeaZ5hedw==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-image@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-Ibu3yYDpWPJd9ajduzdJz8xscWNPYayWj+IATXU8FjsNvPkWpRoRZv+txfrTLOkmx8Qd3z30kriHNjZsIYLHkA==}
/@tiptap/extension-image@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-aWa/NPMc1U9Z6xuV0gk1O1nk4H7BAwQMwqXWdvUQCJhmW5+LJPdEiKvt3P6j+ClIN7sdyokZCgr6eGr817qTLA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-italic@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-o41hil+x2yqFciOiJPx67FnguJ4/aEMU8MotmXekFGHM+I0wFOd4lA5t7HqFU5Si0Z7gyTb/N0wLUbAnbyk/Aw==}
/@tiptap/extension-italic@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-7e37f+OFqisdY19nWIthbSNHMJy4+4dec06rUICPrkiuFaADj5HjUQr0dyWpL/LkZh92Wf/rWgp4V/lEwon3jA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-list-item@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-hgG8XzWRvhmEtb70ut2YTWfexMDu4PHgDS8WxYGOCVH0F+DwZqGF5KEARhFSPlmRUCWcmKey4sp8YDpLqShEWA==}
/@tiptap/extension-list-item@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-hd/E4qQopBXWa6kdFY19qFVgqj4fzdPgAnzdXJ2XW7bC6O2CusmHphRRZ5FBsuspYTN/6/fv0i0jK9rSGlsEyA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-mention@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)(@tiptap/suggestion@2.1.6):
resolution: {integrity: sha512-GgoiCRhcpAv6wH7vHPFxa3f+vhiicGMqwJo+ZKT0VdyegHfHfMVRIN57sTV8R9/ZXCAjL1smqwLhF+PlWheN2A==}
/@tiptap/extension-mention@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)(@tiptap/suggestion@2.1.7):
resolution: {integrity: sha512-GPVw8AiGwCozkY2TKLk/eMpo7IYfVuXnFB82yPlG3RQTGREpvf6L5Vv28HdXcgk7KMTo2IcEdH32EJDqjPYlEg==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
'@tiptap/suggestion': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/suggestion': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
'@tiptap/suggestion': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-ordered-list@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-7igbJBSeCByYM9G3XHlK1sqPQtIsOlezdc4PH7xBaOtvNDd1ruGvOGFovo9b5TW8+J08KCAqy25cV4Pn72fuGw==}
/@tiptap/extension-ordered-list@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-3XIXqbZmYkNzF+8PQ2jcCOCj0lpC3y9HGM/+joPIunhiUiktrIgpbUDv2E1Gq5lJHYqthIeujniI2dB85tkwJQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-paragraph@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-k0QSIaJPVgTn9+X2580JFCjV2RCH1Fo+gPodABDnjunfoUVSjuq0rlILEtTuha3evlS6kDKiz7lk7pIoCo36Cw==}
/@tiptap/extension-paragraph@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-cLqX27hNrXrwZCKrIW8OC3rW2+MT8hhS37+cdqOxZo5hUqQ9EF/puwS0w8uUZ7B3awX9Jm1QZDMjjERLkcmobw==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-placeholder@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-M6C80FnbDPiZWVGFIVVOUMbqNUMhXRzlJr7uwUWP98OJfj3Du4pk8mF5Lo5MsWH3C/XW3YRbqlGPpdas3onSkQ==}
/@tiptap/extension-placeholder@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-IiBoItYYNS7hb/zmPitw3w6Cylmp9qX+zW+QKe3lDkCNPeKxyQr86AnVLcQYOuXg62cLV9dp+4azZzHoz9SOcg==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@tiptap/extension-strike@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-LX7X2ohKEE0nUyWecSGxBcuzLxXTIbPmUnbkZvqYiWTaE02r3TxzkJMO0iuTnbygceC1TtiAfKwGgth0b9tMCQ==}
/@tiptap/extension-strike@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-ONLXYnuZGM2EoGcxkyvJSDMBeAp7K6l83UXkK9TSj+VpEEDdeV7m8mJs8/vACJjJxD5HMN61+EPgU7VTEukQCA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/extension-text@2.1.6(@tiptap/core@2.1.6):
resolution: {integrity: sha512-CqV0N6ngoXZFeJGlQ86FSZJ/0k7+BN3S6aSUcb5DRAKsSEv/Ga1LvSG24sHy+dwjTuj3EtRPJSVZTFcSB17ZSA==}
/@tiptap/extension-text@2.1.7(@tiptap/core@2.1.7):
resolution: {integrity: sha512-3xaMMMNydLgoS+o+yOvaZF04ui9spJwJZl8VyYgcJKVGGLGRlWHrireXN5/OqXG2jLb/jWqXVx5idppQjX+PMA==}
peerDependencies:
'@tiptap/core': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
dev: false
/@tiptap/pm@2.1.6:
resolution: {integrity: sha512-JkFlZp2z6Se2Ttnabi4lkP2yLNMH/eebO7ScYL1kXvwNLgELC/I3fwQVmnYA0E8pqJ5KQXOSl14NaB1mVPJqlg==}
/@tiptap/pm@2.1.7:
resolution: {integrity: sha512-RBVb/k9OjmClwdVl7fpekFgUsLAm1U+5I4w1qA2tj7L/hSPOuPzaEHwCqDYe0b2PR5dd8h0nylS9qXuXVlfwfQ==}
dependencies:
prosemirror-changeset: 2.2.1
prosemirror-collab: 1.3.1
@ -2237,56 +2248,56 @@ packages:
prosemirror-view: 1.31.7
dev: false
/@tiptap/react@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-HEsoFlcE61gQz9TllEtBa+5d909MA/ersbxGYOUWIY2HhH5lvNIUvyJ3pdzMkK/4cSniMsDDqobFexsGyTAsrw==}
/@tiptap/react@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-jCs5z/rXZ7mEOTPcJ+r/OSTtLOGBahS7D3xDu3pRX4P0wtWHlprsdptxxlWjkBHLav01XXJ+OtGZTfhWBio1QQ==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/extension-bubble-menu': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/extension-floating-menu': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/extension-bubble-menu': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/extension-floating-menu': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false
/@tiptap/starter-kit@2.1.6(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-JmTvexA90+VqsltAo9+MysYLoR9/dpEEy1LrFT09R1q9p6EJCWfxtyi/QsrZnwD6zthpTByChmDZRGv85Nb3Aw==}
/@tiptap/starter-kit@2.1.7(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-z2cmJRSC7ImaTGWrHv+xws9y1wIG0OCPosBYpmpwlEfA3JG3axWFmVRJlWnsQV4eSMi3QY3vaPgBAnrR4IxRhQ==}
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/extension-blockquote': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-bold': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-bullet-list': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-code': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-code-block': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/extension-document': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-dropcursor': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/extension-gapcursor': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/extension-hard-break': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-heading': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-history': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/extension-horizontal-rule': 2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6)
'@tiptap/extension-italic': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-list-item': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-ordered-list': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-paragraph': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-strike': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/extension-text': 2.1.6(@tiptap/core@2.1.6)
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/extension-blockquote': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-bold': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-bullet-list': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-code': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-code-block': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/extension-document': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-dropcursor': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/extension-gapcursor': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/extension-hard-break': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-heading': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-history': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/extension-horizontal-rule': 2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7)
'@tiptap/extension-italic': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-list-item': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-ordered-list': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-paragraph': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-strike': 2.1.7(@tiptap/core@2.1.7)
'@tiptap/extension-text': 2.1.7(@tiptap/core@2.1.7)
transitivePeerDependencies:
- '@tiptap/pm'
dev: false
/@tiptap/suggestion@2.1.6(@tiptap/core@2.1.6)(@tiptap/pm@2.1.6):
resolution: {integrity: sha512-8nMVARHbJ4Q9eeB7gmvqNommx6/RuFkrJEmmqxSrgyiqYEqb/if5ZTa1LGRWRNZYuzmeVN/r3eUu33jn+o5kJg==}
/@tiptap/suggestion@2.1.7(@tiptap/core@2.1.7)(@tiptap/pm@2.1.7):
resolution: {integrity: sha512-FKlXFMWf9rCnNJQsUfeX6WpS2VUs2O98ENkyhfV8ehCB7X5+57mkkxJxl/88SMbjZL+FbWPBKLaiOvsXfIUoww==}
peerDependencies:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
dependencies:
'@tiptap/core': 2.1.6(@tiptap/pm@2.1.6)
'@tiptap/pm': 2.1.6
'@tiptap/core': 2.1.7(@tiptap/pm@2.1.7)
'@tiptap/pm': 2.1.7
dev: false
/@trivago/prettier-plugin-sort-imports@4.2.0(prettier@3.0.2):
@ -2361,8 +2372,8 @@ packages:
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
dev: false
/@types/node@20.5.3:
resolution: {integrity: sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==}
/@types/node@20.5.4:
resolution: {integrity: sha512-Y9vbIAoM31djQZrPYjpTLo0XlaSwOIsrlfE3LpulZeRblttsLQRFRlBAppW0LOxyT3ALj2M5vU1ucQQayQH3jA==}
dev: true
/@types/normalize-package-data@2.4.1:
@ -2677,7 +2688,7 @@ packages:
vite: ^4
dependencies:
'@swc/core': 1.3.78
vite: 4.4.9(@types/node@20.5.3)
vite: 4.4.9(@types/node@20.5.4)
transitivePeerDependencies:
- '@swc/helpers'
dev: true
@ -2931,7 +2942,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001522
electron-to-chromium: 1.4.499
electron-to-chromium: 1.4.500
node-releases: 2.0.13
update-browserslist-db: 1.0.11(browserslist@4.21.10)
dev: true
@ -3316,8 +3327,8 @@ packages:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
dev: true
/electron-to-chromium@1.4.499:
resolution: {integrity: sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==}
/electron-to-chromium@1.4.500:
resolution: {integrity: sha512-P38NO8eOuWOKY1sQk5yE0crNtrjgjJj6r3NrbIKtG18KzCHmHE2Bt+aQA7/y0w3uYsHWxDa6icOohzjLJ4vJ4A==}
dev: true
/emoji-regex@8.0.0:
@ -6993,13 +7004,13 @@ packages:
debug: 4.3.4
globrex: 0.1.2
tsconfck: 2.1.2(typescript@5.1.6)
vite: 4.4.9(@types/node@20.5.3)
vite: 4.4.9(@types/node@20.5.4)
transitivePeerDependencies:
- supports-color
- typescript
dev: true
/vite@4.4.9(@types/node@20.5.3):
/vite@4.4.9(@types/node@20.5.4):
resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
@ -7027,7 +7038,7 @@ packages:
terser:
optional: true
dependencies:
'@types/node': 20.5.3
'@types/node': 20.5.4
esbuild: 0.18.20
postcss: 8.4.28
rollup: 3.28.1

32
src-tauri/Cargo.lock generated
View File

@ -148,9 +148,9 @@ dependencies = [
[[package]]
name = "anstyle"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea"
[[package]]
name = "anstyle-parse"
@ -763,9 +763,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.3.23"
version = "4.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03aef18ddf7d879c15ce20f04826ef8418101c7e528014c3eeea13321047dca3"
checksum = "fb690e81c7840c0d7aade59f242ea3b41b9bc27bcd5997890e7702ae4b32e487"
dependencies = [
"clap_builder",
"clap_derive",
@ -774,9 +774,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.3.23"
version = "4.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ce6fffb678c9b80a70b6b6de0aad31df727623a70fd9a842c30cd573e2fa98"
checksum = "5ed2e96bc16d8d740f6f48d663eddf4b8a0983e79210fd55479b7bcd0a69860e"
dependencies = [
"anstream",
"anstyle",
@ -1366,9 +1366,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.32"
version = "0.8.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
dependencies = [
"cfg-if",
]
@ -3845,9 +3845,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.11.19"
version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20b9b67e2ca7dd9e9f9285b759de30ff538aab981abaaf7bc9bd90b84a0126c3"
checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
dependencies = [
"base64 0.21.2",
"bytes",
@ -4129,18 +4129,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.185"
version = "1.0.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31"
checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.185"
version = "1.0.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec"
checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670"
dependencies = [
"proc-macro2",
"quote",
@ -4342,9 +4342,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "siphasher"
version = "0.3.10"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "slab"

View File

@ -5,10 +5,9 @@ import { Image } from '@shared/image';
import { useProfile } from '@utils/hooks/useProfile';
import { displayNpub } from '@utils/shortenKey';
import { Chats } from '@utils/types';
export function ChatsListItem({ data }: { data: Chats }) {
const { status, user } = useProfile(data.sender_pubkey);
export function ChatsListItem({ pubkey }: { pubkey: string }) {
const { status, user } = useProfile(pubkey);
if (status === 'loading') {
return (
@ -21,7 +20,7 @@ export function ChatsListItem({ data }: { data: Chats }) {
return (
<NavLink
to={`/chats/${data.sender_pubkey}`}
to={`/chats/${pubkey}`}
preventScrollReset={true}
className={({ isActive }) =>
twMerge(
@ -32,23 +31,13 @@ export function ChatsListItem({ data }: { data: Chats }) {
>
<Image
src={user?.picture || user?.image}
alt={data.sender_pubkey}
alt={pubkey}
className="h-6 w-6 shrink-0 rounded object-cover"
/>
<div className="inline-flex w-full flex-1 items-center justify-between">
<h5 className="max-w-[10rem] truncate">
{user?.nip05 ||
user?.name ||
user?.display_name ||
displayNpub(data.sender_pubkey, 16)}
{user?.nip05 || user?.name || user?.display_name || displayNpub(pubkey, 16)}
</h5>
<div className="flex items-center">
{data.new_messages > 0 && (
<span className="inline-flex w-8 items-center justify-center rounded bg-fuchsia-400/10 px-1 py-1 text-xs font-medium text-fuchsia-500 ring-1 ring-inset ring-fuchsia-400/20">
{data.new_messages}
</span>
)}
</div>
</div>
</NavLink>
);

View File

@ -8,18 +8,23 @@ import { UnknownsModal } from '@app/chats/components/unknowns';
import { useStorage } from '@libs/storage/provider';
import { Chats } from '@utils/types';
import { useNostr } from '@utils/hooks/useNostr';
export function ChatsList() {
const { db } = useStorage();
const { status, data: chats } = useQuery(['chats'], async () => {
return { follows: [], unknowns: [] };
});
const { fetchNIP04Chats } = useNostr();
const { status, data: chats } = useQuery(
['nip04-chats'],
async () => {
return await fetchNIP04Chats();
},
{ refetchOnWindowFocus: false }
);
const renderItem = useCallback(
(item: Chats) => {
if (db.account.pubkey !== item.sender_pubkey) {
return <ChatsListItem key={item.sender_pubkey} data={item} />;
(item: string) => {
if (db.account.pubkey !== item) {
return <ChatsListItem key={item} pubkey={item} />;
}
},
[chats]

View File

@ -1,8 +1,9 @@
import { nip04 } from 'nostr-tools';
import { useCallback, useState } from 'react';
import { MediaUploader } from '@app/chats/components/messages/mediaUploader';
import { EnterIcon } from '@shared/icons';
import { MediaUploader } from '@shared/mediaUploader';
import { useNostr } from '@utils/hooks/useNostr';
@ -34,7 +35,7 @@ export function ChatMessageForm({
const handleEnterPress = (e: {
key: string;
shiftKey: any;
shiftKey: KeyboardEvent['shiftKey'];
preventDefault: () => void;
}) => {
if (e.key === 'Enter' && !e.shiftKey) {

View File

@ -1,32 +1,31 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { useDecryptMessage } from '@app/chats/hooks/useDecryptMessage';
import { NoteContent } from '@shared/notes';
import { User } from '@shared/user';
import { parser } from '@utils/parser';
export function ChatMessageItem({
data,
message,
userPubkey,
userPrivkey,
}: {
data: any;
message: NDKEvent;
userPubkey: string;
userPrivkey: string;
}) {
const decryptedContent = useDecryptMessage(data, userPubkey, userPrivkey);
const decryptedContent = useDecryptMessage(message, userPubkey, userPrivkey);
// if we have decrypted content, use it instead of the encrypted content
if (decryptedContent) {
data['content'] = decryptedContent;
message['content'] = decryptedContent;
}
return (
<div className="flex h-min min-h-min w-full select-text flex-col px-5 py-3 hover:bg-white/10">
<div className="flex flex-col">
<User pubkey={data.sender_pubkey} time={data.created_at} isChat={true} />
<User pubkey={message.pubkey} time={message.created_at} isChat={true} />
<div className="-mt-[20px] pl-[49px]">
<p className="select-text whitespace-pre-line break-words text-base text-white">
{data.content}
{message.content}
</p>
</div>
</div>

View File

@ -1,22 +1,25 @@
import * as Tooltip from '@radix-ui/react-tooltip';
import { useState } from 'react';
import { Dispatch, SetStateAction, useState } from 'react';
import { LoaderIcon, MediaIcon } from '@shared/icons';
import { useImageUploader } from '@utils/hooks/useUploader';
export function MediaUploader({ setState }: { setState: any }) {
export function MediaUploader({
setState,
}: {
setState: Dispatch<SetStateAction<string>>;
}) {
const upload = useImageUploader();
const [loading, setLoading] = useState(false);
const uploadMedia = async () => {
setLoading(true);
const image = await upload(null);
if (image.url) {
// update state
setState((prev: string) => `${prev}\n${image.url}`);
// stop loading
setLoading(false);
}
setLoading(false);
};
return (

View File

@ -7,9 +7,8 @@ import { User } from '@app/auth/components/user';
import { CancelIcon, PlusIcon } from '@shared/icons';
import { compactNumber } from '@utils/number';
import { Chats } from '@utils/types';
export function UnknownsModal({ data }: { data: Chats[] }) {
export function UnknownsModal({ data }: { data: string[] }) {
const navigate = useNavigate();
const [open, setOpen] = useState(false);
@ -55,16 +54,16 @@ export function UnknownsModal({ data }: { data: Chats[] }) {
</div>
</div>
<div className="flex h-[500px] flex-col overflow-y-auto overflow-x-hidden pb-2 pt-2">
{data.map((user) => (
{data.map((pubkey) => (
<div
key={user.sender_pubkey}
key={pubkey}
className="group flex items-center justify-between px-4 py-2 hover:bg-white/10"
>
<User pubkey={user.sender_pubkey} />
<User pubkey={pubkey} />
<div>
<button
type="button"
onClick={() => openChat(user.sender_pubkey)}
onClick={() => openChat(pubkey)}
className="hidden w-max rounded bg-white/10 px-3 py-1 text-sm font-medium hover:bg-fuchsia-500 group-hover:inline-flex"
>
Chat

View File

@ -1,16 +1,21 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { nip04 } from 'nostr-tools';
import { useEffect, useState } from 'react';
import { Chats } from '@utils/types';
export function useDecryptMessage(data: Chats, userPubkey: string, userPriv: string) {
const [content, setContent] = useState(data.content);
export function useDecryptMessage(
message: NDKEvent,
userPubkey: string,
userPriv: string
) {
const [content, setContent] = useState(message.content);
useEffect(() => {
async function decrypt() {
const pubkey =
userPubkey === data.sender_pubkey ? data.receiver_pubkey : data.sender_pubkey;
const result = await nip04.decrypt(userPriv, pubkey, data.content);
userPubkey === message.pubkey
? message.tags.find((el) => el[0] === 'p')[1]
: message.pubkey;
const result = await nip04.decrypt(userPriv, pubkey, message.content);
setContent(result);
}

View File

@ -13,23 +13,27 @@ import { useStorage } from '@libs/storage/provider';
import { useStronghold } from '@stores/stronghold';
import { useNostr } from '@utils/hooks/useNostr';
export function ChatScreen() {
const virtuosoRef = useRef(null);
const { ndk } = useNDK();
const { db } = useStorage();
const { pubkey } = useParams();
const { status, data } = useQuery(['chat', pubkey], async () => {
return [];
});
const userPrivkey = useStronghold((state) => state.privkey);
const { db } = useStorage();
const { ndk } = useNDK();
const { pubkey } = useParams();
const { fetchNIP04Messages } = useNostr();
const { status, data } = useQuery(['nip04-dm', pubkey], async () => {
return await fetchNIP04Messages(pubkey);
});
const itemContent = useCallback(
(index: string | number) => {
const message = data[index];
if (!message) return;
return (
<ChatMessageItem
data={data[index]}
message={message}
userPubkey={db.account.pubkey}
userPrivkey={userPrivkey}
/>

View File

@ -131,8 +131,6 @@ export function NetworkWidget() {
};
sub(filter, async (event) => {
console.log('[network] new event', event.id);
let root: string;
let reply: string;
if (event.tags?.[0]?.[0] === 'e' && !event.tags?.[0]?.[3]) {

View File

@ -1,10 +1,16 @@
import { useState } from 'react';
import { Dispatch, SetStateAction, useState } from 'react';
import { LoaderIcon, PlusIcon } from '@shared/icons';
import { useImageUploader } from '@utils/hooks/useUploader';
export function AvatarUploader({ setPicture }: { setPicture: any }) {
export function AvatarUploader({
setPicture,
}: {
setPicture: Dispatch<
SetStateAction<{ url: undefined | string; error?: undefined | string }>
>;
}) {
const upload = useImageUploader();
const [loading, setLoading] = useState(false);

View File

@ -1,10 +1,16 @@
import { useState } from 'react';
import { Dispatch, SetStateAction, useState } from 'react';
import { LoaderIcon, PlusIcon } from '@shared/icons';
import { useImageUploader } from '@utils/hooks/useUploader';
export function BannerUploader({ setBanner }: { setBanner: any }) {
export function BannerUploader({
setBanner,
}: {
setBanner: Dispatch<
SetStateAction<{ url: undefined | string; error?: undefined | string }>
>;
}) {
const upload = useImageUploader();
const [loading, setLoading] = useState(false);

View File

@ -1,9 +1,9 @@
import * as Collapsible from '@radix-ui/react-collapsible';
import { useState } from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import { twMerge } from 'tailwind-merge';
// import { ChatsList } from '@app/chats/components/list';
import { ChatsList } from '@app/chats/components/list';
import { ComposerModal } from '@shared/composer/modal';
import {
ArrowLeftIcon,
@ -14,11 +14,13 @@ import {
} from '@shared/icons';
import { LumeBar } from '@shared/lumeBar';
import { useSidebar } from '@stores/sidebar';
export function Navigation() {
const navigate = useNavigate();
const [feeds, setFeeds] = useState(true);
// const [chats, setChats] = useState(true);
const [feeds, toggleFeeds] = useSidebar((state) => [state.feeds, state.toggleFeeds]);
const [chats, toggleChats] = useSidebar((state) => [state.chats, state.toggleChats]);
return (
<div className="relative h-full w-[232px] bg-black/80">
@ -43,7 +45,7 @@ export function Navigation() {
</button>
</div>
</div>
<Collapsible.Root open={feeds} onOpenChange={setFeeds}>
<Collapsible.Root open={feeds} onOpenChange={toggleFeeds}>
<div className="flex flex-col gap-1 px-2">
<Collapsible.Trigger asChild>
<button className="flex items-center gap-1">
@ -80,7 +82,7 @@ export function Navigation() {
<span className="inline-flex h-6 w-6 items-center justify-center rounded bg-white/10">
<SpaceIcon className="h-3 w-3 text-white" />
</span>
<span className="text-sm font-medium">Space</span>
Space
</NavLink>
<NavLink
to="/notifications"
@ -95,12 +97,34 @@ export function Navigation() {
<span className="inline-flex h-6 w-6 items-center justify-center rounded bg-white/10">
<BellIcon className="h-3 w-3 text-white" />
</span>
<span className="text-sm font-medium">Notifications</span>
Notifications
</NavLink>
</div>
</Collapsible.Content>
</div>
</Collapsible.Root>
<Collapsible.Root open={chats} onOpenChange={toggleChats}>
<div className="flex flex-col gap-1 px-2">
<Collapsible.Trigger asChild>
<button className="flex items-center gap-1">
<div
className={twMerge(
'inline-flex h-5 w-5 transform items-center justify-center transition-transform duration-150 ease-in-out',
open ? '' : 'rotate-180'
)}
>
<NavArrowDownIcon className="h-3 w-3 text-white/50" />
</div>
<h3 className="text-[11px] font-bold uppercase tracking-widest text-white/50">
Chats
</h3>
</button>
</Collapsible.Trigger>
<Collapsible.Content>
<ChatsList />
</Collapsible.Content>
</div>
</Collapsible.Root>
</div>
<LumeBar />
</div>

View File

@ -25,6 +25,7 @@ export function TextNote({ event }: { event: NDKEvent }) {
components={{
del: ({ children }) => {
const key = children[0] as string;
if (!key) return;
if (key.startsWith('pub') && key.length > 50 && key.length < 100)
return <MentionUser pubkey={key.replace('pub-', '')} />;
if (key.startsWith('tag')) return <Hashtag tag={key.replace('tag-', '')} />;

24
src/stores/sidebar.ts Normal file
View File

@ -0,0 +1,24 @@
import { create } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware';
interface SidebarState {
feeds: boolean;
chats: boolean;
toggleFeeds: () => void;
toggleChats: () => void;
}
export const useSidebar = create<SidebarState>()(
persist(
(set) => ({
feeds: true,
chats: true,
toggleFeeds: () => set((state) => ({ feeds: !state.feeds })),
toggleChats: () => set((state) => ({ chats: !state.chats })),
}),
{
name: 'sidebar',
storage: createJSONStorage(() => localStorage),
}
)
);

View File

@ -166,6 +166,54 @@ export function useNostr() {
}
};
const fetchNIP04Chats = async () => {
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
const events = await fetcher.fetchAllEvents(
relayUrls,
{
kinds: [NDKKind.EncryptedDirectMessage],
'#p': [db.account.pubkey],
},
{ since: 0 }
);
const senders = events.map((e) => e.pubkey);
const follows = new Set(senders.filter((el) => db.account.follows.includes(el)));
const unknowns = new Set(senders.filter((el) => !db.account.follows.includes(el)));
return { follows: [...follows], unknowns: [...unknowns] };
};
const fetchNIP04Messages = async (sender: string) => {
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
const senderMessages = await fetcher.fetchAllEvents(
relayUrls,
{
kinds: [NDKKind.EncryptedDirectMessage],
authors: [sender],
'#p': [db.account.pubkey],
},
{ since: 0 }
);
const userMessages = await fetcher.fetchAllEvents(
relayUrls,
{
kinds: [NDKKind.EncryptedDirectMessage],
authors: [db.account.pubkey],
'#p': [sender],
},
{ since: 0 }
);
const all = [...senderMessages, ...userMessages].sort(
(a, b) => a.created_at - b.created_at
);
return all as unknown as NDKEvent[];
};
const publish = async ({
content,
kind,
@ -207,5 +255,14 @@ export function useNostr() {
return res;
};
return { sub, fetchUserData, prefetchEvents, fetchActivities, publish, createZap };
return {
sub,
fetchUserData,
prefetchEvents,
fetchActivities,
fetchNIP04Chats,
fetchNIP04Messages,
publish,
createZap,
};
}

View File

@ -65,10 +65,12 @@ export function useImageUploader() {
return {
url: url,
error: null,
};
}
return {
url: null,
error: 'Upload failed',
};
};