Compare commits
3 Commits
fix/modal-
...
refactor/s
Author | SHA1 | Date | |
---|---|---|---|
c5af7d377d | |||
1c6947d549 | |||
fabc920563 |
110
package-lock.json
generated
110
package-lock.json
generated
@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
|
"@hookform/resolvers": "^3.3.4",
|
||||||
"@mui/icons-material": "^5.14.19",
|
"@mui/icons-material": "^5.14.19",
|
||||||
"@mui/material": "^5.14.20",
|
"@mui/material": "^5.14.20",
|
||||||
"@nostr-dev-kit/ndk": "^2.0.5",
|
"@nostr-dev-kit/ndk": "^2.0.5",
|
||||||
@ -33,6 +34,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-hook-form": "^7.50.0",
|
||||||
"react-redux": "^9.0.3",
|
"react-redux": "^9.0.3",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
@ -51,7 +53,8 @@
|
|||||||
"workbox-range-requests": "^6.6.0",
|
"workbox-range-requests": "^6.6.0",
|
||||||
"workbox-routing": "^6.6.0",
|
"workbox-routing": "^6.6.0",
|
||||||
"workbox-strategies": "^6.6.0",
|
"workbox-strategies": "^6.6.0",
|
||||||
"workbox-streams": "^6.6.0"
|
"workbox-streams": "^6.6.0",
|
||||||
|
"yup": "^1.3.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash.isequal": "^4.5.8",
|
"@types/lodash.isequal": "^4.5.8",
|
||||||
@ -2738,6 +2741,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
|
||||||
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
|
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@hookform/resolvers": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz",
|
||||||
|
"integrity": "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react-hook-form": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.13",
|
"version": "0.11.13",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||||
@ -14286,6 +14297,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/property-expr": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="
|
||||||
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -14604,6 +14620,21 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
||||||
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-hook-form": {
|
||||||
|
"version": "7.50.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.50.0.tgz",
|
||||||
|
"integrity": "sha512-AOhuzM3RdP09ZCnq+Z0yvKGHK25yiOX5phwxjV9L7U6HMla10ezkBnvQ+Pk4GTuDfsC5P2zza3k8mawFwFLVuQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.22.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/react-hook-form"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17 || ^18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@ -16678,6 +16709,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/tiny-case": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="
|
||||||
|
},
|
||||||
"node_modules/tmpl": {
|
"node_modules/tmpl": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
||||||
@ -16715,6 +16751,11 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/toposort": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
|
||||||
|
},
|
||||||
"node_modules/tough-cookie": {
|
"node_modules/tough-cookie": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
@ -18316,6 +18357,28 @@
|
|||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yup": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yup/-/yup-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==",
|
||||||
|
"dependencies": {
|
||||||
|
"property-expr": "^2.0.5",
|
||||||
|
"tiny-case": "^1.0.3",
|
||||||
|
"toposort": "^2.0.2",
|
||||||
|
"type-fest": "^2.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yup/node_modules/type-fest": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -20090,6 +20153,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz",
|
||||||
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
|
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A=="
|
||||||
},
|
},
|
||||||
|
"@hookform/resolvers": {
|
||||||
|
"version": "3.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz",
|
||||||
|
"integrity": "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.11.13",
|
"version": "0.11.13",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz",
|
||||||
@ -28331,6 +28400,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"property-expr": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="
|
||||||
|
},
|
||||||
"proxy-addr": {
|
"proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
@ -28585,6 +28659,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
|
||||||
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
|
||||||
},
|
},
|
||||||
|
"react-hook-form": {
|
||||||
|
"version": "7.50.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.50.0.tgz",
|
||||||
|
"integrity": "sha512-AOhuzM3RdP09ZCnq+Z0yvKGHK25yiOX5phwxjV9L7U6HMla10ezkBnvQ+Pk4GTuDfsC5P2zza3k8mawFwFLVuQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
@ -30123,6 +30203,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
||||||
},
|
},
|
||||||
|
"tiny-case": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="
|
||||||
|
},
|
||||||
"tmpl": {
|
"tmpl": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
||||||
@ -30151,6 +30236,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
|
||||||
},
|
},
|
||||||
|
"toposort": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
|
||||||
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
|
||||||
@ -31375,6 +31465,24 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
||||||
|
},
|
||||||
|
"yup": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yup/-/yup-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw==",
|
||||||
|
"requires": {
|
||||||
|
"property-expr": "^2.0.5",
|
||||||
|
"tiny-case": "^1.0.3",
|
||||||
|
"toposort": "^2.0.2",
|
||||||
|
"type-fest": "^2.19.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"type-fest": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
|
"@hookform/resolvers": "^3.3.4",
|
||||||
"@mui/icons-material": "^5.14.19",
|
"@mui/icons-material": "^5.14.19",
|
||||||
"@mui/material": "^5.14.20",
|
"@mui/material": "^5.14.20",
|
||||||
"@nostr-dev-kit/ndk": "^2.0.5",
|
"@nostr-dev-kit/ndk": "^2.0.5",
|
||||||
@ -28,6 +29,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-hook-form": "^7.50.0",
|
||||||
"react-redux": "^9.0.3",
|
"react-redux": "^9.0.3",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
@ -46,7 +48,8 @@
|
|||||||
"workbox-range-requests": "^6.6.0",
|
"workbox-range-requests": "^6.6.0",
|
||||||
"workbox-routing": "^6.6.0",
|
"workbox-routing": "^6.6.0",
|
||||||
"workbox-strategies": "^6.6.0",
|
"workbox-strategies": "^6.6.0",
|
||||||
"workbox-streams": "^6.6.0"
|
"workbox-streams": "^6.6.0",
|
||||||
|
"yup": "^1.3.3"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"react-scripts": {
|
"react-scripts": {
|
||||||
|
@ -14,7 +14,7 @@ import { ACTION_TYPE } from '@/utils/consts'
|
|||||||
|
|
||||||
|
|
||||||
export const ModalConfirmConnect = () => {
|
export const ModalConfirmConnect = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_CONNECT)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_CONNECT)
|
||||||
|
|
||||||
const { npub = '' } = useParams<{ npub: string }>()
|
const { npub = '' } = useParams<{ npub: string }>()
|
||||||
@ -37,24 +37,20 @@ export const ModalConfirmConnect = () => {
|
|||||||
return setSelectedActionType(value)
|
return setSelectedActionType(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCloseModal = createHandleCloseReplace(
|
const handleCloseModal = handleClose(
|
||||||
MODAL_PARAMS_KEYS.CONFIRM_CONNECT,
|
MODAL_PARAMS_KEYS.CONFIRM_CONNECT,
|
||||||
{
|
async (sp) => {
|
||||||
onClose: async (sp) => {
|
sp.delete('appNpub')
|
||||||
sp.delete('appNpub')
|
sp.delete('reqId')
|
||||||
sp.delete('reqId')
|
await swicCall('confirm', pendingReqId, false, false)
|
||||||
await swicCall('confirm', pendingReqId, false, false)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const closeModalAfterRequest = createHandleCloseReplace(
|
const closeModalAfterRequest = handleClose(
|
||||||
MODAL_PARAMS_KEYS.CONFIRM_CONNECT,
|
MODAL_PARAMS_KEYS.CONFIRM_CONNECT,
|
||||||
{
|
(sp) => {
|
||||||
onClose: (sp) => {
|
sp.delete('appNpub')
|
||||||
sp.delete('appNpub')
|
sp.delete('reqId')
|
||||||
sp.delete('reqId')
|
},
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async function confirmPending(
|
async function confirmPending(
|
||||||
|
@ -50,7 +50,7 @@ type PendingRequest = DbPending & { checked: boolean }
|
|||||||
export const ModalConfirmEvent: FC<ModalConfirmEventProps> = ({
|
export const ModalConfirmEvent: FC<ModalConfirmEventProps> = ({
|
||||||
confirmEventReqs,
|
confirmEventReqs,
|
||||||
}) => {
|
}) => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_EVENT)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONFIRM_EVENT)
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
|
|
||||||
@ -86,27 +86,23 @@ export const ModalConfirmEvent: FC<ModalConfirmEventProps> = ({
|
|||||||
|
|
||||||
const selectedPendingRequests = pendingRequests.filter((pr) => pr.checked)
|
const selectedPendingRequests = pendingRequests.filter((pr) => pr.checked)
|
||||||
|
|
||||||
const handleCloseModal = createHandleCloseReplace(
|
const handleCloseModal = handleClose(
|
||||||
MODAL_PARAMS_KEYS.CONFIRM_EVENT,
|
MODAL_PARAMS_KEYS.CONFIRM_EVENT,
|
||||||
{
|
(sp) => {
|
||||||
onClose: (sp) => {
|
sp.delete('appNpub')
|
||||||
sp.delete('appNpub')
|
sp.delete('reqId')
|
||||||
sp.delete('reqId')
|
selectedPendingRequests.forEach(
|
||||||
selectedPendingRequests.forEach(
|
async (req) => await swicCall('confirm', req.id, false, false),
|
||||||
async (req) => await swicCall('confirm', req.id, false, false),
|
)
|
||||||
)
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const closeModalAfterRequest = createHandleCloseReplace(
|
const closeModalAfterRequest = handleClose(
|
||||||
MODAL_PARAMS_KEYS.CONFIRM_EVENT,
|
MODAL_PARAMS_KEYS.CONFIRM_EVENT,
|
||||||
{
|
(sp) => {
|
||||||
onClose: (sp) => {
|
sp.delete('appNpub')
|
||||||
sp.delete('appNpub')
|
sp.delete('reqId')
|
||||||
sp.delete('reqId')
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async function confirmPending(allow: boolean) {
|
async function confirmPending(allow: boolean) {
|
||||||
|
@ -12,18 +12,13 @@ import { useRef } from 'react'
|
|||||||
import { useParams } from 'react-router-dom'
|
import { useParams } from 'react-router-dom'
|
||||||
|
|
||||||
export const ModalConnectApp = () => {
|
export const ModalConnectApp = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace, handleOpen } = useModalSearchParams()
|
const { getModalOpened, handleClose, handleOpen } = useModalSearchParams()
|
||||||
const timerRef = useRef<NodeJS.Timeout>()
|
const timerRef = useRef<NodeJS.Timeout>()
|
||||||
|
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONNECT_APP)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.CONNECT_APP)
|
||||||
const handleCloseModal = createHandleCloseReplace(
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.CONNECT_APP, () => {
|
||||||
MODAL_PARAMS_KEYS.CONNECT_APP,
|
clearTimeout(timerRef.current)
|
||||||
{
|
})
|
||||||
onClose: () => {
|
|
||||||
clearTimeout(timerRef.current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const notify = useEnqueueSnackbar()
|
const notify = useEnqueueSnackbar()
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ import { StyledAppLogo } from './styled'
|
|||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
export const ModalImportKeys = () => {
|
export const ModalImportKeys = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.IMPORT_KEYS)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.IMPORT_KEYS)
|
||||||
const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.IMPORT_KEYS)
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.IMPORT_KEYS)
|
||||||
|
|
||||||
const notify = useEnqueueSnackbar()
|
const notify = useEnqueueSnackbar()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
@ -7,10 +7,10 @@ import { Fade, Stack } from '@mui/material'
|
|||||||
import { AppLink } from '@/shared/AppLink/AppLink'
|
import { AppLink } from '@/shared/AppLink/AppLink'
|
||||||
|
|
||||||
export const ModalInitial = () => {
|
export const ModalInitial = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace, handleOpen } = useModalSearchParams()
|
const { getModalOpened, handleClose, handleOpen } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.INITIAL)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.INITIAL)
|
||||||
|
|
||||||
const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.INITIAL)
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.INITIAL)
|
||||||
|
|
||||||
const [showAdvancedContent, setShowAdvancedContent] = useState(false)
|
const [showAdvancedContent, setShowAdvancedContent] = useState(false)
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
import { useEnqueueSnackbar } from '@/hooks/useEnqueueSnackbar'
|
import { useEnqueueSnackbar } from '@/hooks/useEnqueueSnackbar'
|
||||||
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
||||||
import { swicCall } from '@/modules/swic'
|
import { swicCall } from '@/modules/swic'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { IconButton, Stack, Typography } from '@mui/material'
|
import { IconButton, Stack, Typography } from '@mui/material'
|
||||||
import React, { ChangeEvent, useState } from 'react'
|
|
||||||
import { StyledAppLogo } from './styled'
|
import { StyledAppLogo } from './styled'
|
||||||
import { nip19 } from 'nostr-tools'
|
import { nip19 } from 'nostr-tools'
|
||||||
import { Input } from '@/shared/Input/Input'
|
import { Input } from '@/shared/Input/Input'
|
||||||
@ -12,39 +12,46 @@ import { Button } from '@/shared/Button/Button'
|
|||||||
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined'
|
import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined'
|
||||||
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined'
|
import VisibilityOutlinedIcon from '@mui/icons-material/VisibilityOutlined'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
import { FormInputType, schema } from './const'
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup'
|
||||||
|
|
||||||
export const ModalLogin = () => {
|
export const ModalLogin = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.LOGIN)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.LOGIN)
|
||||||
const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.LOGIN)
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.LOGIN)
|
||||||
|
|
||||||
const notify = useEnqueueSnackbar()
|
const notify = useEnqueueSnackbar()
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const [enteredUsername, setEnteredUsername] = useState('')
|
const {
|
||||||
const [enteredPassword, setEnteredPassword] = useState('')
|
handleSubmit,
|
||||||
|
reset,
|
||||||
|
register,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm<FormInputType>({
|
||||||
|
defaultValues: {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
},
|
||||||
|
resolver: yupResolver(schema),
|
||||||
|
mode: 'onSubmit',
|
||||||
|
})
|
||||||
|
|
||||||
const [isPasswordShown, setIsPasswordShown] = useState(false)
|
const [isPasswordShown, setIsPasswordShown] = useState(false)
|
||||||
|
|
||||||
const handleUsernameChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setEnteredUsername(e.target.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePasswordChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setEnteredPassword(e.target.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePasswordTypeChange = () =>
|
const handlePasswordTypeChange = () =>
|
||||||
setIsPasswordShown((prevState) => !prevState)
|
setIsPasswordShown((prevState) => !prevState)
|
||||||
|
|
||||||
const isFormValid =
|
const cleanUpStates = useCallback(() => {
|
||||||
enteredUsername.trim().length > 0 && enteredPassword.trim().length > 0
|
setIsPasswordShown(false)
|
||||||
|
reset()
|
||||||
|
}, [reset])
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const submitHandler = async (values: FormInputType) => {
|
||||||
e.preventDefault()
|
|
||||||
if (!isFormValid) return undefined
|
|
||||||
try {
|
try {
|
||||||
const [username, domain] = enteredUsername.split('@')
|
const [username, domain] = values.username.split('@')
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://${domain}/.well-known/nostr.json?name=${username}`,
|
`https://${domain}/.well-known/nostr.json?name=${username}`,
|
||||||
)
|
)
|
||||||
@ -56,18 +63,34 @@ export const ModalLogin = () => {
|
|||||||
|
|
||||||
const pubkey = getNpub.names[username]
|
const pubkey = getNpub.names[username]
|
||||||
const npub = nip19.npubEncode(pubkey)
|
const npub = nip19.npubEncode(pubkey)
|
||||||
const passphrase = enteredPassword
|
const passphrase = values.password
|
||||||
|
|
||||||
console.log('fetch', npub, passphrase)
|
console.log('fetch', npub, passphrase)
|
||||||
const k: any = await swicCall('fetchKey', npub, passphrase)
|
const k: any = await swicCall('fetchKey', npub, passphrase)
|
||||||
notify(`Fetched ${k.npub}`, 'success')
|
notify(`Fetched ${k.npub}`, 'success')
|
||||||
|
cleanUpStates()
|
||||||
navigate(`/key/${k.npub}`)
|
navigate(`/key/${k.npub}`)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
notify(error.message, 'error')
|
notify(error?.message || 'Something went wrong!', 'error')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (isModalOpened) {
|
||||||
|
// modal closed
|
||||||
|
cleanUpStates()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isModalOpened, cleanUpStates])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={isModalOpened} onClose={handleCloseModal}>
|
<Modal open={isModalOpened} onClose={handleCloseModal}>
|
||||||
<Stack gap={'1rem'} component={'form'} onSubmit={handleSubmit}>
|
<Stack
|
||||||
|
gap={'1rem'}
|
||||||
|
component={'form'}
|
||||||
|
onSubmit={handleSubmit(submitHandler)}
|
||||||
|
>
|
||||||
<Stack
|
<Stack
|
||||||
direction={'row'}
|
direction={'row'}
|
||||||
gap={'1rem'}
|
gap={'1rem'}
|
||||||
@ -83,15 +106,14 @@ export const ModalLogin = () => {
|
|||||||
label='Enter a Username'
|
label='Enter a Username'
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder='user@nsec.app'
|
placeholder='user@nsec.app'
|
||||||
onChange={handleUsernameChange}
|
{...register('username')}
|
||||||
value={enteredUsername}
|
error={!!errors.username}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
label='Password'
|
label='Password'
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder='Your password'
|
placeholder='Your password'
|
||||||
onChange={handlePasswordChange}
|
{...register('password')}
|
||||||
value={enteredPassword}
|
|
||||||
endAdornment={
|
endAdornment={
|
||||||
<IconButton
|
<IconButton
|
||||||
size='small'
|
size='small'
|
||||||
@ -105,8 +127,9 @@ export const ModalLogin = () => {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
}
|
}
|
||||||
type={isPasswordShown ? 'text' : 'password'}
|
type={isPasswordShown ? 'text' : 'password'}
|
||||||
|
error={!!errors.password}
|
||||||
/>
|
/>
|
||||||
<Button type='submit' fullWidth disabled={!isFormValid}>
|
<Button type='submit' fullWidth>
|
||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
18
src/components/Modal/ModalLogin/const.ts
Normal file
18
src/components/Modal/ModalLogin/const.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import * as yup from 'yup'
|
||||||
|
|
||||||
|
export const schema = yup.object().shape({
|
||||||
|
username: yup
|
||||||
|
.string()
|
||||||
|
.test('Domain validation', 'The domain is required!', function (value) {
|
||||||
|
if (!value || !value.trim().length) return false
|
||||||
|
|
||||||
|
const USERNAME_WITH_DOMAIN_REGEXP = new RegExp(
|
||||||
|
/^[\w-.]+@([\w-]+\.)+[\w-]{2,8}$/g,
|
||||||
|
)
|
||||||
|
return USERNAME_WITH_DOMAIN_REGEXP.test(value)
|
||||||
|
})
|
||||||
|
.required(),
|
||||||
|
password: yup.string().required().min(4),
|
||||||
|
})
|
||||||
|
|
||||||
|
export type FormInputType = yup.InferType<typeof schema>
|
@ -31,13 +31,13 @@ type ModalSettingsProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ModalSettings: FC<ModalSettingsProps> = ({ isSynced }) => {
|
export const ModalSettings: FC<ModalSettingsProps> = ({ isSynced }) => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const { npub = '' } = useParams<{ npub: string }>()
|
const { npub = '' } = useParams<{ npub: string }>()
|
||||||
|
|
||||||
const notify = useEnqueueSnackbar()
|
const notify = useEnqueueSnackbar()
|
||||||
|
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.SETTINGS)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.SETTINGS)
|
||||||
const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.SETTINGS)
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.SETTINGS)
|
||||||
|
|
||||||
const [enteredPassword, setEnteredPassword] = useState('')
|
const [enteredPassword, setEnteredPassword] = useState('')
|
||||||
const [isPasswordShown, setIsPasswordShown] = useState(false)
|
const [isPasswordShown, setIsPasswordShown] = useState(false)
|
||||||
@ -48,7 +48,7 @@ export const ModalSettings: FC<ModalSettingsProps> = ({ isSynced }) => {
|
|||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => setIsChecked(isSynced), [isModalOpened, isSynced])
|
useEffect(() => setIsChecked(isSynced), [isModalOpened])
|
||||||
|
|
||||||
const handlePasswordChange = (e: ChangeEvent<HTMLInputElement>) => {
|
const handlePasswordChange = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
setIsPasswordInvalid(false)
|
setIsPasswordInvalid(false)
|
||||||
|
@ -12,9 +12,9 @@ import { swicCall } from '@/modules/swic'
|
|||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
export const ModalSignUp = () => {
|
export const ModalSignUp = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.SIGN_UP)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.SIGN_UP)
|
||||||
const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.SIGN_UP)
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.SIGN_UP)
|
||||||
const notify = useEnqueueSnackbar()
|
const notify = useEnqueueSnackbar()
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ export const ModalSignUp = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
|
if (!enteredValue.trim().length) return
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
try {
|
try {
|
||||||
const k: any = await swicCall('generateKey')
|
const k: any = await swicCall('generateKey')
|
||||||
|
@ -17,11 +17,6 @@ export type IExtraOptions = {
|
|||||||
append?: boolean
|
append?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type IExtraCloseOptions = {
|
|
||||||
replace?: boolean
|
|
||||||
onClose?: (s: URLSearchParams) => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useModalSearchParams = () => {
|
export const useModalSearchParams = () => {
|
||||||
const [searchParams, setSearchParams] = useSearchParams()
|
const [searchParams, setSearchParams] = useSearchParams()
|
||||||
|
|
||||||
@ -34,20 +29,13 @@ export const useModalSearchParams = () => {
|
|||||||
]
|
]
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const createHandleClose =
|
const handleClose =
|
||||||
(modal: MODAL_PARAMS_KEYS, extraOptions?: IExtraCloseOptions) =>
|
(modal: MODAL_PARAMS_KEYS, onClose?: (s: URLSearchParams) => void) =>
|
||||||
() => {
|
() => {
|
||||||
const enumKey = getEnumParam(modal)
|
const enumKey = getEnumParam(modal)
|
||||||
searchParams.delete(enumKey)
|
searchParams.delete(enumKey)
|
||||||
extraOptions?.onClose && extraOptions?.onClose(searchParams)
|
onClose && onClose(searchParams)
|
||||||
console.log({ searchParams })
|
setSearchParams(searchParams)
|
||||||
setSearchParams(searchParams, { replace: !!extraOptions?.replace })
|
|
||||||
}
|
|
||||||
|
|
||||||
const createHandleCloseReplace =
|
|
||||||
(modal: MODAL_PARAMS_KEYS, extraOptions?: IExtraCloseOptions) =>
|
|
||||||
() => {
|
|
||||||
return createHandleClose(modal, { ...extraOptions, replace: true })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOpen = useCallback(
|
const handleOpen = useCallback(
|
||||||
@ -73,7 +61,7 @@ export const useModalSearchParams = () => {
|
|||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
search: searchString,
|
search: searchString,
|
||||||
},
|
},
|
||||||
{ replace: !!extraOptions?.replace },
|
{ replace: extraOptions?.replace || true },
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[location, navigate, getEnumParam],
|
[location, navigate, getEnumParam],
|
||||||
@ -90,8 +78,7 @@ export const useModalSearchParams = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
getModalOpened,
|
getModalOpened,
|
||||||
createHandleClose,
|
handleClose,
|
||||||
createHandleCloseReplace,
|
|
||||||
handleOpen,
|
handleOpen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { generatePrivateKey, getPublicKey, nip19 } from 'nostr-tools'
|
import { generatePrivateKey, getPublicKey, nip19 } from 'nostr-tools'
|
||||||
import { DbApp, dbi, DbKey, DbPending, DbPerm } from './db'
|
import { dbi, DbKey, DbPending, DbPerm } from './db'
|
||||||
import { Keys } from './keys'
|
import { Keys } from './keys'
|
||||||
import NDK, {
|
import NDK, {
|
||||||
IEventHandlingStrategy,
|
IEventHandlingStrategy,
|
||||||
@ -10,7 +10,7 @@ import NDK, {
|
|||||||
} from '@nostr-dev-kit/ndk'
|
} from '@nostr-dev-kit/ndk'
|
||||||
import { NOAUTHD_URL, WEB_PUSH_PUBKEY, NIP46_RELAYS } from '../utils/consts'
|
import { NOAUTHD_URL, WEB_PUSH_PUBKEY, NIP46_RELAYS } from '../utils/consts'
|
||||||
import { Nip04 } from './nip04'
|
import { Nip04 } from './nip04'
|
||||||
import { getReqPerm, getShortenNpub, isPackagePerm } from '@/utils/helpers/helpers'
|
import { getReqPerm, isPackagePerm } from '@/utils/helpers/helpers'
|
||||||
//import { PrivateKeySigner } from './signer'
|
//import { PrivateKeySigner } from './signer'
|
||||||
|
|
||||||
//const PERF_TEST = false
|
//const PERF_TEST = false
|
||||||
@ -32,7 +32,6 @@ interface Key {
|
|||||||
interface Pending {
|
interface Pending {
|
||||||
req: DbPending
|
req: DbPending
|
||||||
cb: (allow: boolean, remember: boolean, options?: any) => void
|
cb: (allow: boolean, remember: boolean, options?: any) => void
|
||||||
notified?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IAllowCallbackParams {
|
interface IAllowCallbackParams {
|
||||||
@ -146,7 +145,6 @@ export class NoauthBackend {
|
|||||||
private enckeys: DbKey[] = []
|
private enckeys: DbKey[] = []
|
||||||
private keys: Key[] = []
|
private keys: Key[] = []
|
||||||
private perms: DbPerm[] = []
|
private perms: DbPerm[] = []
|
||||||
private apps: DbApp[] = []
|
|
||||||
private doneReqIds: string[] = []
|
private doneReqIds: string[] = []
|
||||||
private confirmBuffer: Pending[] = []
|
private confirmBuffer: Pending[] = []
|
||||||
private accessBuffer: DbPending[] = []
|
private accessBuffer: DbPending[] = []
|
||||||
@ -195,25 +193,16 @@ export class NoauthBackend {
|
|||||||
.matchAll({ type: 'window' })
|
.matchAll({ type: 'window' })
|
||||||
.then((clientList) => {
|
.then((clientList) => {
|
||||||
console.log('clients', clientList.length)
|
console.log('clients', clientList.length)
|
||||||
// FIXME find a client that has our
|
|
||||||
// key page
|
|
||||||
for (const client of clientList) {
|
for (const client of clientList) {
|
||||||
console.log('client', client.url)
|
console.log('client', client.url)
|
||||||
if (
|
if (
|
||||||
new URL(client.url).pathname === '/' &&
|
new URL(client.url).pathname === '/' &&
|
||||||
'focus' in client
|
'focus' in client
|
||||||
) {
|
)
|
||||||
client.focus()
|
return client.focus()
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// if (self.swg.clients.openWindow)
|
||||||
// confirm screen url
|
// return self.swg.clients.openWindow("/");
|
||||||
const req = event.notification.data.req
|
|
||||||
console.log("req", req)
|
|
||||||
// const url = `${self.swg.location.origin}/key/${req.npub}?confirm-connect=true&appNpub=${req.appNpub}&reqId=${req.id}`
|
|
||||||
const url = `${self.swg.location.origin}/key/${req.npub}`
|
|
||||||
self.swg.clients.openWindow(url)
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -227,8 +216,6 @@ export class NoauthBackend {
|
|||||||
console.log('started encKeys', this.listKeys())
|
console.log('started encKeys', this.listKeys())
|
||||||
this.perms = await dbi.listPerms()
|
this.perms = await dbi.listPerms()
|
||||||
console.log('started perms', this.perms)
|
console.log('started perms', this.perms)
|
||||||
this.apps = await dbi.listApps()
|
|
||||||
console.log('started apps', this.apps)
|
|
||||||
|
|
||||||
const sub = await this.swg.registration.pushManager.getSubscription()
|
const sub = await this.swg.registration.pushManager.getSubscription()
|
||||||
|
|
||||||
@ -286,7 +273,7 @@ export class NoauthBackend {
|
|||||||
})
|
})
|
||||||
if (r.status !== 200 && r.status !== 201) {
|
if (r.status !== 200 && r.status !== 201) {
|
||||||
console.log('Fetch error', url, method, r.status)
|
console.log('Fetch error', url, method, r.status)
|
||||||
throw new Error('Failed to fetch' + url)
|
throw new Error('Failed to fetch ' + url)
|
||||||
}
|
}
|
||||||
|
|
||||||
return await r.json()
|
return await r.json()
|
||||||
@ -394,69 +381,21 @@ export class NoauthBackend {
|
|||||||
// and update the notifications
|
// and update the notifications
|
||||||
|
|
||||||
for (const r of this.confirmBuffer) {
|
for (const r of this.confirmBuffer) {
|
||||||
|
const text = `Confirm "${r.req.method}" by "${r.req.appNpub}"`
|
||||||
if (r.notified) continue
|
this.swg.registration.showNotification('Signer access', {
|
||||||
|
body: text,
|
||||||
const key = this.keys.find(k => k.npub === r.req.npub)
|
tag: 'confirm-' + r.req.appNpub,
|
||||||
if (!key) continue
|
actions: [
|
||||||
|
{
|
||||||
const app = this.apps.find(a => a.appNpub === r.req.appNpub)
|
action: 'allow:' + r.req.id,
|
||||||
if (r.req.method !== 'connect' && !app) continue
|
title: 'Yes',
|
||||||
|
},
|
||||||
// FIXME use Nsec.app icon!
|
{
|
||||||
const icon = 'https://nostr.band/android-chrome-192x192.png'
|
action: 'disallow:' + r.req.id,
|
||||||
|
title: 'No',
|
||||||
const appName = app?.name || getShortenNpub(r.req.appNpub)
|
},
|
||||||
// FIXME load profile?
|
],
|
||||||
const keyName = getShortenNpub(r.req.npub)
|
})
|
||||||
|
|
||||||
const tag = 'confirm-' + r.req.appNpub
|
|
||||||
const allowAction = 'allow:' + r.req.id
|
|
||||||
const disallowAction = 'disallow:' + r.req.id
|
|
||||||
const data = { req: r.req }
|
|
||||||
|
|
||||||
if (r.req.method === 'connect') {
|
|
||||||
const title = `Connect with new app`
|
|
||||||
const body = `Allow app "${appName}" to connect to key "${keyName}"`
|
|
||||||
this.swg.registration.showNotification(title, {
|
|
||||||
body,
|
|
||||||
tag,
|
|
||||||
icon,
|
|
||||||
data,
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
action: allowAction,
|
|
||||||
title: 'Connect',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
action: disallowAction,
|
|
||||||
title: 'Ignore',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const title = `Permission request`
|
|
||||||
const body = `Allow "${r.req.method}" by "${appName}" to "${keyName}"`
|
|
||||||
this.swg.registration.showNotification(title, {
|
|
||||||
body,
|
|
||||||
tag,
|
|
||||||
icon,
|
|
||||||
data,
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
action: allowAction,
|
|
||||||
title: 'Yes',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
action: disallowAction,
|
|
||||||
title: 'No',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark
|
|
||||||
r.notified = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.notifCallback) this.notifCallback()
|
if (this.notifCallback) this.notifCallback()
|
||||||
@ -570,9 +509,6 @@ export class NoauthBackend {
|
|||||||
icon: '',
|
icon: '',
|
||||||
url: '',
|
url: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
// reload
|
|
||||||
self.apps = await dbi.listApps()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -835,7 +771,6 @@ export class NoauthBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async deleteApp(appNpub: string) {
|
private async deleteApp(appNpub: string) {
|
||||||
this.apps = this.apps.filter((a) => a.appNpub !== appNpub)
|
|
||||||
this.perms = this.perms.filter((p) => p.appNpub !== appNpub)
|
this.perms = this.perms.filter((p) => p.appNpub !== appNpub)
|
||||||
await dbi.removeApp(appNpub)
|
await dbi.removeApp(appNpub)
|
||||||
await dbi.removeAppPerms(appNpub)
|
await dbi.removeAppPerms(appNpub)
|
||||||
|
@ -55,7 +55,7 @@ const AppPage = () => {
|
|||||||
try {
|
try {
|
||||||
await swicCall('deleteApp', appNpub)
|
await swicCall('deleteApp', appNpub)
|
||||||
notify(`App: «${appName}» successfully deleted!`, 'success')
|
notify(`App: «${appName}» successfully deleted!`, 'success')
|
||||||
navigate(`key/${npub}`)
|
navigate(`/key/${npub}`)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
notify(error?.message || 'Failed to delete app', 'error')
|
notify(error?.message || 'Failed to delete app', 'error')
|
||||||
}
|
}
|
||||||
@ -99,7 +99,9 @@ const AppPage = () => {
|
|||||||
<Button
|
<Button
|
||||||
fullWidth
|
fullWidth
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleOpenModal(MODAL_PARAMS_KEYS.ACTIVITY)
|
handleOpenModal(MODAL_PARAMS_KEYS.ACTIVITY, {
|
||||||
|
replace: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Activity
|
Activity
|
||||||
|
@ -12,9 +12,9 @@ type ModalActivitiesProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const ModalActivities: FC<ModalActivitiesProps> = ({ appNpub }) => {
|
export const ModalActivities: FC<ModalActivitiesProps> = ({ appNpub }) => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, handleClose } = useModalSearchParams()
|
||||||
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.ACTIVITY)
|
const isModalOpened = getModalOpened(MODAL_PARAMS_KEYS.ACTIVITY)
|
||||||
const handleCloseModal = createHandleCloseReplace(MODAL_PARAMS_KEYS.ACTIVITY)
|
const handleCloseModal = handleClose(MODAL_PARAMS_KEYS.ACTIVITY)
|
||||||
|
|
||||||
const history = useLiveQuery(
|
const history = useLiveQuery(
|
||||||
getActivityHistoryQuerier(appNpub),
|
getActivityHistoryQuerier(appNpub),
|
||||||
@ -27,7 +27,7 @@ export const ModalActivities: FC<ModalActivitiesProps> = ({ appNpub }) => {
|
|||||||
open={isModalOpened}
|
open={isModalOpened}
|
||||||
onClose={handleCloseModal}
|
onClose={handleCloseModal}
|
||||||
fixedHeight='calc(100% - 5rem)'
|
fixedHeight='calc(100% - 5rem)'
|
||||||
title='Activity history'
|
title='Activities history'
|
||||||
>
|
>
|
||||||
<Box overflow={'auto'}>
|
<Box overflow={'auto'}>
|
||||||
{history.map((item) => {
|
{history.map((item) => {
|
||||||
|
@ -6,11 +6,8 @@ export const getActivityHistoryQuerier = (appNpub: string) => () => {
|
|||||||
const result = db.history
|
const result = db.history
|
||||||
.where('appNpub')
|
.where('appNpub')
|
||||||
.equals(appNpub)
|
.equals(appNpub)
|
||||||
.reverse()
|
.limit(30)
|
||||||
.sortBy('timestamp')
|
.toArray()
|
||||||
.then(a => a.slice(0, 30))
|
|
||||||
// .limit(30)
|
|
||||||
// .toArray()
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
import { Input, InputProps } from '@/shared/Input/Input'
|
import { Input, InputProps } from '@/shared/Input/Input'
|
||||||
import { Stack, StackProps, styled } from '@mui/material'
|
import { Stack, StackProps, styled } from '@mui/material'
|
||||||
|
import { forwardRef } from 'react'
|
||||||
|
|
||||||
export const StyledInput = styled(({ className, ...props }: InputProps) => {
|
export const StyledInput = styled(
|
||||||
return (
|
forwardRef<HTMLInputElement, InputProps>(({ className, ...props }, ref) => {
|
||||||
<Input
|
return (
|
||||||
{...props}
|
<Input
|
||||||
className='input'
|
{...props}
|
||||||
containerProps={{
|
ref={ref}
|
||||||
className,
|
className='input'
|
||||||
}}
|
containerProps={{
|
||||||
fullWidth
|
className,
|
||||||
/>
|
}}
|
||||||
)
|
fullWidth
|
||||||
})(({ theme }) => ({
|
/>
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)(({ theme }) => ({
|
||||||
'& > .input': {
|
'& > .input': {
|
||||||
border: 'none',
|
border: 'none',
|
||||||
background: theme.palette.secondary.main,
|
background: theme.palette.secondary.main,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Input, InputProps } from '@/shared/Input/Input'
|
import { Input, InputProps } from '@/shared/Input/Input'
|
||||||
import { Box, Button, ButtonProps, styled, Badge } from '@mui/material'
|
import { Box, Button, ButtonProps, styled, Badge } from '@mui/material'
|
||||||
|
import { forwardRef } from 'react'
|
||||||
|
|
||||||
type StyledIconButtonProps = ButtonProps & {
|
type StyledIconButtonProps = ButtonProps & {
|
||||||
bgcolor_variant?: 'primary' | 'secondary'
|
bgcolor_variant?: 'primary' | 'secondary'
|
||||||
@ -57,18 +58,21 @@ export const StyledEmptyAppsBox = styled(Box)(({ theme }) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const StyledInput = styled(({ className, ...props }: InputProps) => {
|
export const StyledInput = styled(
|
||||||
return (
|
forwardRef<HTMLInputElement, InputProps>(({ className, ...props }, ref) => {
|
||||||
<Input
|
return (
|
||||||
{...props}
|
<Input
|
||||||
className='input'
|
{...props}
|
||||||
containerProps={{
|
ref={ref}
|
||||||
className,
|
className='input'
|
||||||
}}
|
containerProps={{
|
||||||
fullWidth
|
className,
|
||||||
/>
|
}}
|
||||||
)
|
fullWidth
|
||||||
})(({ theme }) => ({
|
/>
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)(({ theme }) => ({
|
||||||
'& > .input': {
|
'& > .input': {
|
||||||
border: 'none',
|
border: 'none',
|
||||||
background: theme.palette.secondary.main,
|
background: theme.palette.secondary.main,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { FC, ReactNode } from 'react'
|
import { ReactNode, forwardRef } from 'react'
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
BoxProps,
|
BoxProps,
|
||||||
@ -17,29 +17,33 @@ export type InputProps = InputBaseProps & {
|
|||||||
label?: string
|
label?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Input: FC<InputProps> = ({
|
export const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||||
helperText,
|
({ helperText, containerProps, helperTextProps, label, ...props }, ref) => {
|
||||||
containerProps,
|
return (
|
||||||
helperTextProps,
|
<StyledInputContainer {...containerProps}>
|
||||||
label,
|
{label ? (
|
||||||
...props
|
<FormLabel className='label' htmlFor={props.id}>
|
||||||
}) => {
|
{label}
|
||||||
return (
|
</FormLabel>
|
||||||
<StyledInputContainer {...containerProps}>
|
) : null}
|
||||||
{label ? (
|
<InputBase
|
||||||
<FormLabel className='label' htmlFor={props.id}>
|
className='input'
|
||||||
{label}
|
{...props}
|
||||||
</FormLabel>
|
classes={{ error: 'error' }}
|
||||||
) : null}
|
inputRef={ref}
|
||||||
<InputBase className='input' {...props} />
|
/>
|
||||||
{helperText ? (
|
{helperText ? (
|
||||||
<FormHelperText {...helperTextProps} className='helper_text'>
|
<FormHelperText
|
||||||
{helperText}
|
{...helperTextProps}
|
||||||
</FormHelperText>
|
className='helper_text'
|
||||||
) : null}
|
>
|
||||||
</StyledInputContainer>
|
{helperText}
|
||||||
)
|
</FormHelperText>
|
||||||
}
|
) : null}
|
||||||
|
</StyledInputContainer>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const StyledInputContainer = styled((props: BoxProps) => <Box {...props} />)(
|
const StyledInputContainer = styled((props: BoxProps) => <Box {...props} />)(
|
||||||
({ theme }) => {
|
({ theme }) => {
|
||||||
@ -56,6 +60,9 @@ const StyledInputContainer = styled((props: BoxProps) => <Box {...props} />)(
|
|||||||
'& input::placeholder': {
|
'& input::placeholder': {
|
||||||
color: '#fff',
|
color: '#fff',
|
||||||
},
|
},
|
||||||
|
'&.error': {
|
||||||
|
border: '0.3px solid ' + theme.palette.error.main,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'& > .helper_text': {
|
'& > .helper_text': {
|
||||||
margin: '0.5rem 1rem 0',
|
margin: '0.5rem 1rem 0',
|
||||||
|
Reference in New Issue
Block a user