diff --git a/package.json b/package.json index 65929184..62792b2c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "dependencies": { "@floating-ui/react": "^0.23.1", "@headlessui/react": "^1.7.15", - "@nostr-dev-kit/ndk": "^0.5.13", + "@nostr-dev-kit/ndk": "^0.6.3", + "@radix-ui/react-tooltip": "^1.0.6", "@tanstack/react-query": "^4.29.19", "@tanstack/react-virtual": "3.0.0-beta.54", "@tauri-apps/api": "^1.4.0", @@ -29,7 +30,7 @@ "nostr-tools": "^1.12.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hook-form": "^7.45.0", + "react-hook-form": "^7.45.1", "react-hotkeys-hook": "^4.4.0", "react-player": "^2.12.0", "react-router-dom": "^6.14.0", @@ -55,7 +56,7 @@ "csstype": "^3.1.2", "encoding": "^0.1.13", "husky": "^8.0.3", - "lint-staged": "^13.2.2", + "lint-staged": "^13.2.3", "postcss": "^8.4.24", "prop-types": "^15.8.1", "rome": "12.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f975f53e..7f389c3c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,8 +8,11 @@ dependencies: specifier: ^1.7.15 version: 1.7.15(react-dom@18.2.0)(react@18.2.0) '@nostr-dev-kit/ndk': - specifier: ^0.5.13 - version: 0.5.13(typescript@4.9.5) + specifier: ^0.6.3 + version: 0.6.3(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) '@tanstack/react-query': specifier: ^4.29.19 version: 4.29.19(react-dom@18.2.0)(react@18.2.0) @@ -50,8 +53,8 @@ dependencies: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) react-hook-form: - specifier: ^7.45.0 - version: 7.45.0(react@18.2.0) + specifier: ^7.45.1 + version: 7.45.1(react@18.2.0) react-hotkeys-hook: specifier: ^4.4.0 version: 4.4.0(react-dom@18.2.0)(react@18.2.0) @@ -124,8 +127,8 @@ devDependencies: specifier: ^8.0.3 version: 8.0.3 lint-staged: - specifier: ^13.2.2 - version: 13.2.2 + specifier: ^13.2.3 + version: 13.2.3 postcss: specifier: ^8.4.24 version: 8.4.24 @@ -153,8 +156,8 @@ devDependencies: packages: - /@aashutoshrathi/word-wrap@1.2.5: - resolution: {integrity: sha512-plhoNEfSVdHMKXQyAxvH0Zyv3/4NL8r6pwgMQdmHR2vBUXn2t74PN2pBRppqKUa6RMT0yldyvOHG5Dbjwy2mBQ==} + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} dev: false @@ -184,6 +187,13 @@ packages: js-tokens: 4.0.0 dev: false + /@babel/runtime@7.22.5: + resolution: {integrity: sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + dev: false + /@emotion/is-prop-valid@0.8.8: resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} requiresBuild: true @@ -431,6 +441,17 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@floating-ui/react-dom@2.0.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.4.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@floating-ui/react@0.23.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OCc2ViQOBUKOGcE9NLAbpyqB+8Zz92IKIhxgz7XAkynKkVzcVSKtkWOcgyvO4SAzB2OybgRwk3WdzdzDRdh2QQ==} peerDependencies: @@ -570,8 +591,8 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - /@nostr-dev-kit/ndk@0.5.13(typescript@4.9.5): - resolution: {integrity: sha512-Lu5vHzKmV3NrQyIxbneft7QlY2KpxOhsNOo1sN71z1b4plBSDrUT8xBgPTzm1itfL1Xw0kxy6pa/LSdVlsA3oQ==} + /@nostr-dev-kit/ndk@0.6.3(typescript@4.9.5): + resolution: {integrity: sha512-lXMahPRepqNmt7rIM/I7pJz/VB5PSCakZScV3+L0AmUpsN4UXHX+fFtkFjyfNpM/zW+YlxFMFbo/WM+jB55j0A==} dependencies: '@noble/hashes': 1.3.1 '@noble/secp256k1': 2.0.0 @@ -613,6 +634,357 @@ packages: dev: false optional: true + /@radix-ui/primitive@1.0.1: + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + dependencies: + '@babel/runtime': 7.22.5 + dev: false + + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-context@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-dismissable-layer@1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-id@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@floating-ui/react-dom': 2.0.1(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-slot@1.0.2(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-tooltip@1.0.6(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-DmNFOiwEc2UDigsYj6clJENma58OelxD24O4IODoZ+3sQc3Zb+L8w1EP+y9laTuKCLAysPw4fD6/v0j4KNV8rg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.14)(react@18.2.0): + resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0) + '@types/react': 18.2.14 + react: 18.2.0 + dev: false + + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.5 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.6)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.14 + '@types/react-dom': 18.2.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/rect@1.0.1: + resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} + dependencies: + '@babel/runtime': 7.22.5 + dev: false + /@remix-run/router@1.7.0: resolution: {integrity: sha512-Eu1V3kz3mV0wUpVTiFHuaT8UD1gj/0VnoFHQYX35xlslQUpe8CuYoKFn9d4WZFHm3yDywz6ALZuGdnUPKrNeAw==} engines: {node: '>=14'} @@ -1020,13 +1392,11 @@ packages: /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - dev: true /@types/react-dom@18.2.6: resolution: {integrity: sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==} dependencies: '@types/react': 18.2.14 - dev: true /@types/react@18.2.14: resolution: {integrity: sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==} @@ -1034,11 +1404,9 @@ packages: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 csstype: 3.1.2 - dev: true /@types/scheduler@0.16.3: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} - dev: true /@types/semver@7.5.0: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} @@ -1379,7 +1747,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.9 - caniuse-lite: 1.0.30001508 + caniuse-lite: 1.0.30001509 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -1427,8 +1795,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001508 - electron-to-chromium: 1.4.442 + caniuse-lite: 1.0.30001509 + electron-to-chromium: 1.4.444 node-releases: 2.0.12 update-browserslist-db: 1.0.11(browserslist@4.21.9) dev: true @@ -1490,8 +1858,8 @@ packages: engines: {node: '>=6'} dev: false - /caniuse-lite@1.0.30001508: - resolution: {integrity: sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw==} + /caniuse-lite@1.0.30001509: + resolution: {integrity: sha512-2uDDk+TRiTX5hMcUYT/7CSyzMZxjfGu0vAUjS2g0LSD8UoXOv0LtpH4LxGMemsiPq6LCVIUjNwVM0erkOkGCDA==} dev: true /chalk@2.4.2: @@ -1697,7 +2065,6 @@ packages: /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - dev: true /d@1.0.1: resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} @@ -1860,8 +2227,8 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - /electron-to-chromium@1.4.442: - resolution: {integrity: sha512-RkrZF//Ya+0aJq2NM3OdisNh5ZodZq1rdXOS96G8DdDgpDKqKE81yTbbQ3F/4CKm1JBPsGu1Lp/akkna2xO06Q==} + /electron-to-chromium@1.4.444: + resolution: {integrity: sha512-/AjkL4syRvOpowXWy3N4OHmVbFdWQpfSKHh0sCVYipDeEAtMce3rLjMJi/27Ia9jNIbw6P1JuPN32pSWybXXEQ==} dev: true /emoji-regex@8.0.0: @@ -2192,7 +2559,7 @@ packages: lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.2 + optionator: 0.9.3 strip-ansi: 6.0.1 strip-json-comments: 3.1.1 text-table: 0.2.0 @@ -2206,7 +2573,7 @@ packages: create-esm-loader: 0.2.3 npm-run-all: 4.1.5 semver: 7.5.3 - typescript: 5.1.5 + typescript: 5.1.6 dev: false /espree@9.5.2: @@ -3024,8 +3391,8 @@ packages: /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - /lint-staged@13.2.2: - resolution: {integrity: sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA==} + /lint-staged@13.2.3: + resolution: {integrity: sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg==} engines: {node: ^14.13.1 || >=16.0.0} hasBin: true dependencies: @@ -3569,11 +3936,11 @@ packages: mimic-fn: 4.0.0 dev: true - /optionator@0.9.2: - resolution: {integrity: sha512-W/Q5m5jpuspnghjVKWcs+5sm9Xl9BIdDmNLWaQbwneNQEZFosaiVPC9vtwN0Dbxx4x7TLY7bxjvttW26AmcKrQ==} + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} dependencies: - '@aashutoshrathi/word-wrap': 1.2.5 + '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 @@ -3891,8 +4258,8 @@ packages: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} dev: false - /react-hook-form@7.45.0(react@18.2.0): - resolution: {integrity: sha512-AbHeZ4ad+0dEIknSW9dBgIwcvRDfZ1O97sgj75WaMdOX0eg8TBiUf9wxzVkIjZbk76BBIE9lmFOzyD4PN80ZQg==} + /react-hook-form@7.45.1(react@18.2.0): + resolution: {integrity: sha512-6dWoFJwycbuFfw/iKMcl+RdAOAOHDiF11KWYhNDRN/OkUt+Di5qsZHwA0OwsVnu9y135gkHpTw9DJA+WzCeR9w==} engines: {node: '>=12.22.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 @@ -4034,6 +4401,10 @@ packages: strip-indent: 3.0.0 dev: false + /regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: false + /regexp.prototype.flags@1.5.0: resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} engines: {node: '>= 0.4'} @@ -4686,8 +5057,8 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - /typescript@5.1.5: - resolution: {integrity: sha512-FOH+WN/DQjUvN6WgW+c4Ml3yi0PH+a/8q+kNIfRehv1wLhWONedw85iu+vQ39Wp49IzTJEsZ2lyLXpBF7mkF1g==} + /typescript@5.1.6: + resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} engines: {node: '>=14.17'} hasBin: true dev: false diff --git a/src/app/channel/components/messages/hideButton.tsx b/src/app/channel/components/messages/hideButton.tsx index 601b7cc9..158b6450 100644 --- a/src/app/channel/components/messages/hideButton.tsx +++ b/src/app/channel/components/messages/hideButton.tsx @@ -2,7 +2,7 @@ import { Dialog, Transition } from "@headlessui/react"; import { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk"; import { CancelIcon, HideIcon } from "@shared/icons"; import { RelayContext } from "@shared/relayProvider"; -import { Tooltip } from "@shared/tooltip"; +import { Tooltip } from "@shared/tooltip_dep"; import { useChannelMessages } from "@stores/channels"; import { dateToUnix } from "@utils/date"; import { useAccount } from "@utils/hooks/useAccount"; diff --git a/src/app/channel/components/messages/muteButton.tsx b/src/app/channel/components/messages/muteButton.tsx index 625cdb52..9c638a7d 100644 --- a/src/app/channel/components/messages/muteButton.tsx +++ b/src/app/channel/components/messages/muteButton.tsx @@ -2,7 +2,7 @@ import { Dialog, Transition } from "@headlessui/react"; import { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk"; import { CancelIcon, MuteIcon } from "@shared/icons"; import { RelayContext } from "@shared/relayProvider"; -import { Tooltip } from "@shared/tooltip"; +import { Tooltip } from "@shared/tooltip_dep"; import { useChannelMessages } from "@stores/channels"; import { dateToUnix } from "@utils/date"; import { useAccount } from "@utils/hooks/useAccount"; diff --git a/src/app/channel/components/messages/replyButton.tsx b/src/app/channel/components/messages/replyButton.tsx index e88bf952..7d5d8828 100644 --- a/src/app/channel/components/messages/replyButton.tsx +++ b/src/app/channel/components/messages/replyButton.tsx @@ -1,5 +1,5 @@ import { ReplyMessageIcon } from "@shared/icons"; -import { Tooltip } from "@shared/tooltip"; +import { Tooltip } from "@shared/tooltip_dep"; import { useChannelMessages } from "@stores/channels"; export function MessageReplyButton({ diff --git a/src/app/user/index.tsx b/src/app/user/index.tsx index bb6d5ad0..8ed02fec 100644 --- a/src/app/user/index.tsx +++ b/src/app/user/index.tsx @@ -1,9 +1,11 @@ import { UserFeed } from "@app/user/components/feed"; import { UserMetadata } from "@app/user/components/metadata"; import { Tab } from "@headlessui/react"; +import { EditProfileModal } from "@shared/editProfileModal"; import { ThreadsIcon, ZapIcon } from "@shared/icons"; import { Image } from "@shared/image"; import { DEFAULT_AVATAR } from "@stores/constants"; +import { useAccount } from "@utils/hooks/useAccount"; import { useProfile } from "@utils/hooks/useProfile"; import { useSocial } from "@utils/hooks/useSocial"; import { shortenKey } from "@utils/shortenKey"; @@ -13,6 +15,7 @@ import { Link, useParams } from "react-router-dom"; export function UserScreen() { const { pubkey } = useParams(); const { user } = useProfile(pubkey); + const { account } = useAccount(); const { status, userFollows, follow, unfollow } = useSocial(); const [followed, setFollowed] = useState(false); @@ -116,6 +119,8 @@ export function UserScreen() { > + + {account && account.pubkey === pubkey && }
diff --git a/src/shared/accounts/active.tsx b/src/shared/accounts/active.tsx index 88322647..12198783 100644 --- a/src/shared/accounts/active.tsx +++ b/src/shared/accounts/active.tsx @@ -8,6 +8,7 @@ import { useProfile } from "@utils/hooks/useProfile"; import { sendNativeNotification } from "@utils/notification"; import { produce } from "immer"; import { useContext, useEffect } from "react"; +import { Link } from "react-router-dom"; const lastLogin = await getLastLogin(); @@ -92,7 +93,10 @@ export function ActiveAccount({ data }: { data: any }) { } return ( -
+ -
+ ); } diff --git a/src/shared/avatarUploader.tsx b/src/shared/avatarUploader.tsx index 8a92379b..59c4cd05 100644 --- a/src/shared/avatarUploader.tsx +++ b/src/shared/avatarUploader.tsx @@ -1,11 +1,10 @@ -import { createBlobFromFile } from "@utils/createBlobFromFile"; - -import { LoaderIcon } from "./icons"; +import { LoaderIcon, PlusIcon } from "@shared/icons"; import { open } from "@tauri-apps/api/dialog"; import { Body, fetch } from "@tauri-apps/api/http"; +import { createBlobFromFile } from "@utils/createBlobFromFile"; import { useState } from "react"; -export function AvatarUploader({ valueState }: { valueState: any }) { +export function AvatarUploader({ setPicture }: { setPicture: any }) { const [loading, setLoading] = useState(false); const openFileDialog = async () => { @@ -44,23 +43,26 @@ export function AvatarUploader({ valueState }: { valueState: any }) { body: Body.bytes(buf), }, ); - const webpImage = `https://void.cat/d/${res.data.file.id}.webp`; + const image = `https://void.cat/d/${res.data.file.id}.jpg`; - valueState(webpImage); + // update parent state + setPicture(image); + + // disable loader setLoading(false); } }; return ( ); diff --git a/src/shared/bannerUploader.tsx b/src/shared/bannerUploader.tsx new file mode 100644 index 00000000..af417232 --- /dev/null +++ b/src/shared/bannerUploader.tsx @@ -0,0 +1,69 @@ +import { LoaderIcon, PlusIcon } from "@shared/icons"; +import { open } from "@tauri-apps/api/dialog"; +import { Body, fetch } from "@tauri-apps/api/http"; +import { createBlobFromFile } from "@utils/createBlobFromFile"; +import { useState } from "react"; + +export function BannerUploader({ setBanner }: { setBanner: any }) { + const [loading, setLoading] = useState(false); + + const openFileDialog = async () => { + const selected: any = await open({ + multiple: false, + filters: [ + { + name: "Image", + extensions: ["png", "jpeg", "jpg", "gif"], + }, + ], + }); + if (Array.isArray(selected)) { + // user selected multiple files + } else if (selected === null) { + // user cancelled the selection + } else { + setLoading(true); + + const filename = selected.split("/").pop(); + const file = await createBlobFromFile(selected); + const buf = await file.arrayBuffer(); + + const res: { data: { file: { id: string } } } = await fetch( + "https://void.cat/upload?cli=false", + { + method: "POST", + timeout: 5, + headers: { + accept: "*/*", + "Content-Type": "application/octet-stream", + "V-Filename": filename, + "V-Description": "Upload from https://lume.nu", + "V-Strip-Metadata": "true", + }, + body: Body.bytes(buf), + }, + ); + const image = `https://void.cat/d/${res.data.file.id}.jpg`; + + // update parent state + setBanner(image); + + // disable loader + setLoading(false); + } + }; + + return ( + + ); +} diff --git a/src/shared/editProfileModal.tsx b/src/shared/editProfileModal.tsx new file mode 100644 index 00000000..e48e98a3 --- /dev/null +++ b/src/shared/editProfileModal.tsx @@ -0,0 +1,226 @@ +import { Dialog, Transition } from "@headlessui/react"; +import { usePublish } from "@libs/ndk"; +import { getPleb } from "@libs/storage"; +import { AvatarUploader } from "@shared/avatarUploader"; +import { BannerUploader } from "@shared/bannerUploader"; +import { CancelIcon, LoaderIcon } from "@shared/icons"; +import { Image } from "@shared/image"; +import { DEFAULT_AVATAR } from "@stores/constants"; +import { useAccount } from "@utils/hooks/useAccount"; +import { Fragment, useState } from "react"; +import { useForm } from "react-hook-form"; + +export function EditProfileModal() { + 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 { account } = useAccount(); + const { + register, + handleSubmit, + reset, + formState: { isValid }, + } = useForm({ + defaultValues: async () => { + const res = await getPleb(account.npub); + if (res.picture) { + setPicture(res.image); + } + if (res.banner) { + setBanner(res.banner); + } + return res; + }, + }); + + const closeModal = () => { + setIsOpen(false); + }; + + const openModal = () => { + setIsOpen(true); + }; + + const onSubmit = (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: [], + }); + + if (event) { + setTimeout(() => { + // reset form + reset(); + // reset state + setLoading(false); + setIsOpen(false); + setPicture(DEFAULT_AVATAR); + setBanner(null); + }, 1200); + } + }; + + return ( + <> + + + + +
+ +
+ + +
+
+ + Edit profile + + +
+
+
+
+ + +
+
+ user's banner +
+ +
+
+
+
+ user's avatar +
+ +
+
+
+
+
+
+ + +
+
+ +