mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 19:57:52 +01:00
web: add support for setting user profile
This commit is contained in:
201
apps/web/package-lock.json
generated
201
apps/web/package-lock.json
generated
@@ -67,6 +67,7 @@
|
|||||||
"platform": "^1.3.6",
|
"platform": "^1.3.6",
|
||||||
"qclone": "^1.2.0",
|
"qclone": "^1.2.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-avatar-editor": "^13.0.2",
|
||||||
"react-complex-tree": "^2.2.4",
|
"react-complex-tree": "^2.2.4",
|
||||||
"react-day-picker": "^8.9.1",
|
"react-day-picker": "^8.9.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
@@ -97,6 +98,7 @@
|
|||||||
"@types/node-fetch": "^2.5.10",
|
"@types/node-fetch": "^2.5.10",
|
||||||
"@types/platform": "^1.3.4",
|
"@types/platform": "^1.3.4",
|
||||||
"@types/react": "^18.2.39",
|
"@types/react": "^18.2.39",
|
||||||
|
"@types/react-avatar-editor": "^13.0.2",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^18.2.17",
|
||||||
"@types/react-modal": "3.16.3",
|
"@types/react-modal": "3.16.3",
|
||||||
"@types/tinycolor2": "^1.4.3",
|
"@types/tinycolor2": "^1.4.3",
|
||||||
@@ -34707,7 +34709,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/gen-mapping": "^0.3.0",
|
"@jridgewell/gen-mapping": "^0.3.0",
|
||||||
@@ -34845,7 +34846,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/compat-data": {
|
"node_modules/@babel/compat-data": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -34853,7 +34853,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/core": {
|
"node_modules/@babel/core": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ampproject/remapping": "^2.2.0",
|
"@ampproject/remapping": "^2.2.0",
|
||||||
@@ -34882,7 +34881,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/generator": {
|
"node_modules/@babel/generator": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.23.3",
|
"@babel/types": "^7.23.3",
|
||||||
@@ -34918,7 +34916,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-compilation-targets": {
|
"node_modules/@babel/helper-compilation-targets": {
|
||||||
"version": "7.22.15",
|
"version": "7.22.15",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/compat-data": "^7.22.9",
|
"@babel/compat-data": "^7.22.9",
|
||||||
@@ -34986,7 +34983,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-environment-visitor": {
|
"node_modules/@babel/helper-environment-visitor": {
|
||||||
"version": "7.22.20",
|
"version": "7.22.20",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -34994,7 +34990,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-function-name": {
|
"node_modules/@babel/helper-function-name": {
|
||||||
"version": "7.23.0",
|
"version": "7.23.0",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/template": "^7.22.15",
|
"@babel/template": "^7.22.15",
|
||||||
@@ -35006,7 +35001,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-hoist-variables": {
|
"node_modules/@babel/helper-hoist-variables": {
|
||||||
"version": "7.22.5",
|
"version": "7.22.5",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.22.5"
|
"@babel/types": "^7.22.5"
|
||||||
@@ -35027,10 +35021,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-module-imports": {
|
"node_modules/@babel/helper-module-imports": {
|
||||||
"version": "7.22.15",
|
"version": "7.24.3",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz",
|
||||||
|
"integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.22.15"
|
"@babel/types": "^7.24.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -35038,7 +35033,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-module-transforms": {
|
"node_modules/@babel/helper-module-transforms": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-environment-visitor": "^7.22.20",
|
"@babel/helper-environment-visitor": "^7.22.20",
|
||||||
@@ -35066,9 +35060,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-plugin-utils": {
|
"node_modules/@babel/helper-plugin-utils": {
|
||||||
"version": "7.22.5",
|
"version": "7.24.0",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
|
||||||
"license": "MIT",
|
"integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -35107,7 +35101,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-simple-access": {
|
"node_modules/@babel/helper-simple-access": {
|
||||||
"version": "7.22.5",
|
"version": "7.22.5",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.22.5"
|
"@babel/types": "^7.22.5"
|
||||||
@@ -35129,7 +35122,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-split-export-declaration": {
|
"node_modules/@babel/helper-split-export-declaration": {
|
||||||
"version": "7.22.6",
|
"version": "7.22.6",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.22.5"
|
"@babel/types": "^7.22.5"
|
||||||
@@ -35139,8 +35131,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-string-parser": {
|
"node_modules/@babel/helper-string-parser": {
|
||||||
"version": "7.22.5",
|
"version": "7.24.1",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
|
||||||
|
"integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -35154,7 +35147,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helper-validator-option": {
|
"node_modules/@babel/helper-validator-option": {
|
||||||
"version": "7.22.15",
|
"version": "7.22.15",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -35175,7 +35167,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/helpers": {
|
"node_modules/@babel/helpers": {
|
||||||
"version": "7.23.2",
|
"version": "7.23.2",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/template": "^7.22.15",
|
"@babel/template": "^7.22.15",
|
||||||
@@ -35257,7 +35248,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/parser": {
|
"node_modules/@babel/parser": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
@@ -36133,6 +36123,63 @@
|
|||||||
"@babel/core": "^7.0.0-0"
|
"@babel/core": "^7.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/plugin-transform-runtime": {
|
||||||
|
"version": "7.24.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz",
|
||||||
|
"integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-module-imports": "^7.24.3",
|
||||||
|
"@babel/helper-plugin-utils": "^7.24.0",
|
||||||
|
"babel-plugin-polyfill-corejs2": "^0.4.10",
|
||||||
|
"babel-plugin-polyfill-corejs3": "^0.10.1",
|
||||||
|
"babel-plugin-polyfill-regenerator": "^0.6.1",
|
||||||
|
"semver": "^6.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/plugin-transform-runtime/node_modules/@babel/helper-define-polyfill-provider": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-compilation-targets": "^7.22.6",
|
||||||
|
"@babel/helper-plugin-utils": "^7.22.5",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"resolve": "^1.14.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-corejs3": {
|
||||||
|
"version": "0.10.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz",
|
||||||
|
"integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-define-polyfill-provider": "^0.6.1",
|
||||||
|
"core-js-compat": "^3.36.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-regenerator": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-define-polyfill-provider": "^0.6.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/plugin-transform-shorthand-properties": {
|
"node_modules/@babel/plugin-transform-shorthand-properties": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -36386,7 +36433,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.22.15",
|
"version": "7.22.15",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.22.13",
|
"@babel/code-frame": "^7.22.13",
|
||||||
@@ -36399,7 +36445,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@babel/traverse": {
|
"node_modules/@babel/traverse": {
|
||||||
"version": "7.23.3",
|
"version": "7.23.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.22.13",
|
"@babel/code-frame": "^7.22.13",
|
||||||
@@ -36418,10 +36463,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.23.3",
|
"version": "7.24.0",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
|
||||||
|
"integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-string-parser": "^7.22.5",
|
"@babel/helper-string-parser": "^7.23.4",
|
||||||
"@babel/helper-validator-identifier": "^7.22.20",
|
"@babel/helper-validator-identifier": "^7.22.20",
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
},
|
},
|
||||||
@@ -36632,7 +36678,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/set-array": "^1.0.1",
|
"@jridgewell/set-array": "^1.0.1",
|
||||||
@@ -36645,7 +36690,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/resolve-uri": {
|
"node_modules/@jridgewell/resolve-uri": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
@@ -36653,7 +36697,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/set-array": {
|
"node_modules/@jridgewell/set-array": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
@@ -36670,12 +36713,10 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@jridgewell/sourcemap-codec": {
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.4.15",
|
"version": "1.4.15",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/trace-mapping": {
|
"node_modules/@jridgewell/trace-mapping": {
|
||||||
"version": "0.3.20",
|
"version": "0.3.20",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/resolve-uri": "^3.1.0",
|
"@jridgewell/resolve-uri": "^3.1.0",
|
||||||
@@ -38049,6 +38090,15 @@
|
|||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/react-avatar-editor": {
|
||||||
|
"version": "13.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-avatar-editor/-/react-avatar-editor-13.0.2.tgz",
|
||||||
|
"integrity": "sha512-vnGU4sx5TDB9JMCuw+kB3+jfDNMhVlpBbgMRZG9NzVnaBb5xUjVV4VmHdD2O8gj/pb5GN+QXKk7jan09aMjG2A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/react-dom": {
|
"node_modules/@types/react-dom": {
|
||||||
"version": "18.2.19",
|
"version": "18.2.19",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -38658,18 +38708,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-plugin-polyfill-corejs2": {
|
"node_modules/babel-plugin-polyfill-corejs2": {
|
||||||
"version": "0.4.6",
|
"version": "0.4.10",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz",
|
||||||
"license": "MIT",
|
"integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/compat-data": "^7.22.6",
|
"@babel/compat-data": "^7.22.6",
|
||||||
"@babel/helper-define-polyfill-provider": "^0.4.3",
|
"@babel/helper-define-polyfill-provider": "^0.6.1",
|
||||||
"semver": "^6.3.1"
|
"semver": "^6.3.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/babel-plugin-polyfill-corejs2/node_modules/@babel/helper-define-polyfill-provider": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-compilation-targets": "^7.22.6",
|
||||||
|
"@babel/helper-plugin-utils": "^7.22.5",
|
||||||
|
"debug": "^4.1.1",
|
||||||
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"resolve": "^1.14.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/babel-plugin-polyfill-corejs3": {
|
"node_modules/babel-plugin-polyfill-corejs3": {
|
||||||
"version": "0.8.6",
|
"version": "0.8.6",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -38808,8 +38873,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.22.1",
|
"version": "4.23.0",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
|
||||||
|
"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -38824,11 +38890,10 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"caniuse-lite": "^1.0.30001541",
|
"caniuse-lite": "^1.0.30001587",
|
||||||
"electron-to-chromium": "^1.4.535",
|
"electron-to-chromium": "^1.4.668",
|
||||||
"node-releases": "^2.0.13",
|
"node-releases": "^2.0.14",
|
||||||
"update-browserslist-db": "^1.0.13"
|
"update-browserslist-db": "^1.0.13"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -38954,8 +39019,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001562",
|
"version": "1.0.30001599",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz",
|
||||||
|
"integrity": "sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -38969,8 +39035,7 @@
|
|||||||
"type": "github",
|
"type": "github",
|
||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"license": "CC-BY-4.0"
|
|
||||||
},
|
},
|
||||||
"node_modules/canvas": {
|
"node_modules/canvas": {
|
||||||
"version": "2.11.2",
|
"version": "2.11.2",
|
||||||
@@ -39184,15 +39249,14 @@
|
|||||||
},
|
},
|
||||||
"node_modules/convert-source-map": {
|
"node_modules/convert-source-map": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/core-js-compat": {
|
"node_modules/core-js-compat": {
|
||||||
"version": "3.33.2",
|
"version": "3.36.1",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz",
|
||||||
"license": "MIT",
|
"integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.22.1"
|
"browserslist": "^4.23.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -39572,9 +39636,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.4.585",
|
"version": "1.4.713",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.713.tgz",
|
||||||
"license": "ISC"
|
"integrity": "sha512-vDarADhwntXiULEdmWd77g2dV6FrNGa8ecAC29MZ4TwPut2fvosD0/5sJd1qWNNe8HcJFAC+F5Lf9jW1NPtWmw=="
|
||||||
},
|
},
|
||||||
"node_modules/electron-trpc": {
|
"node_modules/electron-trpc": {
|
||||||
"version": "0.5.2",
|
"version": "0.5.2",
|
||||||
@@ -39955,7 +40019,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/escalade": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -40400,7 +40463,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/gensync": {
|
"node_modules/gensync": {
|
||||||
"version": "1.0.0-beta.2",
|
"version": "1.0.0-beta.2",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -40513,7 +40575,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "11.12.0",
|
"version": "11.12.0",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
@@ -41317,7 +41378,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/jsesc": {
|
"node_modules/jsesc": {
|
||||||
"version": "2.5.2",
|
"version": "2.5.2",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"jsesc": "bin/jsesc"
|
"jsesc": "bin/jsesc"
|
||||||
@@ -41353,7 +41413,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/json5": {
|
"node_modules/json5": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"json5": "lib/cli.js"
|
"json5": "lib/cli.js"
|
||||||
@@ -41680,7 +41739,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"yallist": "^3.0.2"
|
"yallist": "^3.0.2"
|
||||||
@@ -42771,9 +42829,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.13",
|
"version": "2.0.14",
|
||||||
"dev": true,
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
|
||||||
"license": "MIT"
|
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
|
||||||
},
|
},
|
||||||
"node_modules/nopt": {
|
"node_modules/nopt": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
@@ -43029,7 +43087,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
@@ -43331,6 +43388,20 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-avatar-editor": {
|
||||||
|
"version": "13.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-avatar-editor/-/react-avatar-editor-13.0.2.tgz",
|
||||||
|
"integrity": "sha512-a4ajbi7lwDh98kgEtSEeKMu0vs0CHTczkq4Xcxr1EiwMFH1GlgHCEtwGU8q/H5W8SeLnH4KPK8LUjEEaZXklxQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/plugin-transform-runtime": "^7.12.1",
|
||||||
|
"@babel/runtime": "^7.12.5",
|
||||||
|
"prop-types": "^15.7.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^0.14.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^0.14.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-complex-tree": {
|
"node_modules/react-complex-tree": {
|
||||||
"version": "2.3.4",
|
"version": "2.3.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -44916,7 +44987,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.0.13",
|
"version": "1.0.13",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -45902,7 +45972,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"dev": true,
|
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
"platform": "^1.3.6",
|
"platform": "^1.3.6",
|
||||||
"qclone": "^1.2.0",
|
"qclone": "^1.2.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-avatar-editor": "^13.0.2",
|
||||||
"react-complex-tree": "^2.2.4",
|
"react-complex-tree": "^2.2.4",
|
||||||
"react-day-picker": "^8.9.1",
|
"react-day-picker": "^8.9.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
@@ -95,6 +96,7 @@
|
|||||||
"@types/node-fetch": "^2.5.10",
|
"@types/node-fetch": "^2.5.10",
|
||||||
"@types/platform": "^1.3.4",
|
"@types/platform": "^1.3.4",
|
||||||
"@types/react": "^18.2.39",
|
"@types/react": "^18.2.39",
|
||||||
|
"@types/react-avatar-editor": "^13.0.2",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^18.2.17",
|
||||||
"@types/react-modal": "3.16.3",
|
"@types/react-modal": "3.16.3",
|
||||||
"@types/tinycolor2": "^1.4.3",
|
"@types/tinycolor2": "^1.4.3",
|
||||||
|
|||||||
@@ -33,8 +33,13 @@ import { ConfirmDialogProps } from "../dialogs/confirm";
|
|||||||
import { getFormattedDate } from "@notesnook/common";
|
import { getFormattedDate } from "@notesnook/common";
|
||||||
import { downloadUpdate } from "../utils/updater";
|
import { downloadUpdate } from "../utils/updater";
|
||||||
import { ThemeMetadata } from "@notesnook/themes-server";
|
import { ThemeMetadata } from "@notesnook/themes-server";
|
||||||
import { Color, Reminder, Tag } from "@notesnook/core";
|
import {
|
||||||
import { AuthenticatorType } from "@notesnook/core/dist/api/user-manager";
|
Color,
|
||||||
|
Profile,
|
||||||
|
Reminder,
|
||||||
|
Tag,
|
||||||
|
AuthenticatorType
|
||||||
|
} from "@notesnook/core";
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import { PasswordDialogProps } from "../dialogs/password-dialog";
|
import { PasswordDialogProps } from "../dialogs/password-dialog";
|
||||||
|
|
||||||
@@ -476,6 +481,12 @@ export function showAttachmentsDialog() {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showEditProfileDialog(profile?: Profile) {
|
||||||
|
return showDialog("EditProfileDialog", (Dialog, perform) => (
|
||||||
|
<Dialog onClose={(res: boolean) => perform(res)} profile={profile} />
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
export function showSettings() {
|
export function showSettings() {
|
||||||
return showDialog("SettingsDialog", (Dialog, perform) => (
|
return showDialog("SettingsDialog", (Dialog, perform) => (
|
||||||
<Dialog onClose={(res: boolean) => perform(res)} />
|
<Dialog onClose={(res: boolean) => perform(res)} />
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ import {
|
|||||||
Login,
|
Login,
|
||||||
Circle,
|
Circle,
|
||||||
Icon,
|
Icon,
|
||||||
Reminders
|
Reminders,
|
||||||
|
User
|
||||||
} from "../icons";
|
} from "../icons";
|
||||||
import { AnimatedFlex } from "../animated";
|
import { AnimatedFlex } from "../animated";
|
||||||
import NavigationItem, { SortableNavigationItem } from "./navigation-item";
|
import NavigationItem, { SortableNavigationItem } from "./navigation-item";
|
||||||
@@ -134,6 +135,7 @@ function NavigationMenu(props: NavigationMenuProps) {
|
|||||||
const shortcuts = useAppStore((store) => store.shortcuts);
|
const shortcuts = useAppStore((store) => store.shortcuts);
|
||||||
const refreshNavItems = useAppStore((store) => store.refreshNavItems);
|
const refreshNavItems = useAppStore((store) => store.refreshNavItems);
|
||||||
const isLoggedIn = useUserStore((store) => store.isLoggedIn);
|
const isLoggedIn = useUserStore((store) => store.isLoggedIn);
|
||||||
|
const profile = useUserStore((store) => store.profile);
|
||||||
const isMobile = useMobile();
|
const isMobile = useMobile();
|
||||||
const theme = useThemeStore((store) => store.colorScheme);
|
const theme = useThemeStore((store) => store.colorScheme);
|
||||||
const toggleNightMode = useThemeStore((store) => store.toggleColorScheme);
|
const toggleNightMode = useThemeStore((store) => store.toggleColorScheme);
|
||||||
@@ -463,8 +465,9 @@ function NavigationMenu(props: NavigationMenuProps) {
|
|||||||
id={settings.id}
|
id={settings.id}
|
||||||
isTablet={isTablet}
|
isTablet={isTablet}
|
||||||
key={settings.path}
|
key={settings.path}
|
||||||
title={settings.title}
|
title={profile?.fullName || settings.title}
|
||||||
icon={settings.icon}
|
icon={profile?.fullName ? User : settings.icon}
|
||||||
|
image={profile?.fullName ? profile?.profilePicture : undefined}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!isMobile && location === settings.path)
|
if (!isMobile && location === settings.path)
|
||||||
return toggleNavigationContainer();
|
return toggleNavigationContainer();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, Flex, FlexProps, Text } from "@theme-ui/components";
|
import { Button, Flex, FlexProps, Image, Text } from "@theme-ui/components";
|
||||||
import { useStore as useAppStore } from "../../stores/app-store";
|
import { useStore as useAppStore } from "../../stores/app-store";
|
||||||
import { Menu } from "../../hooks/use-menu";
|
import { Menu } from "../../hooks/use-menu";
|
||||||
import useMobile from "../../hooks/use-mobile";
|
import useMobile from "../../hooks/use-mobile";
|
||||||
@@ -29,7 +29,8 @@ import { useSortable } from "@dnd-kit/sortable";
|
|||||||
import { CSS } from "@dnd-kit/utilities";
|
import { CSS } from "@dnd-kit/utilities";
|
||||||
|
|
||||||
type NavigationItemProps = {
|
type NavigationItemProps = {
|
||||||
icon: Icon;
|
icon?: Icon;
|
||||||
|
image?: string;
|
||||||
color?: SchemeColors;
|
color?: SchemeColors;
|
||||||
title: string;
|
title: string;
|
||||||
isTablet?: boolean;
|
isTablet?: boolean;
|
||||||
@@ -49,6 +50,7 @@ function NavigationItem(
|
|||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
|
image,
|
||||||
color,
|
color,
|
||||||
title,
|
title,
|
||||||
isLoading,
|
isLoading,
|
||||||
@@ -121,11 +123,15 @@ function NavigationItem(
|
|||||||
if (onClick) onClick();
|
if (onClick) onClick();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon
|
{image ? (
|
||||||
size={isTablet ? 16 : 15}
|
<Image src={image} sx={{ borderRadius: 50, size: 20 }} />
|
||||||
color={color || (selected ? "icon-selected" : "icon")}
|
) : Icon ? (
|
||||||
rotate={isLoading}
|
<Icon
|
||||||
/>
|
size={isTablet ? 16 : 15}
|
||||||
|
color={color || (selected ? "icon-selected" : "icon")}
|
||||||
|
rotate={isLoading}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
{isShortcut && (
|
{isShortcut && (
|
||||||
<Shortcut
|
<Shortcut
|
||||||
size={8}
|
size={8}
|
||||||
|
|||||||
166
apps/web/src/dialogs/edit-profile-dialog.tsx
Normal file
166
apps/web/src/dialogs/edit-profile-dialog.tsx
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
This file is part of the Notesnook project (https://notesnook.com/)
|
||||||
|
|
||||||
|
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Perform } from "../common/dialog-controller";
|
||||||
|
import Dialog from "../components/dialog";
|
||||||
|
import { Profile } from "@notesnook/core";
|
||||||
|
import Field from "../components/field";
|
||||||
|
import AvatarEditor from "react-avatar-editor";
|
||||||
|
import { Avatar, Button, Flex, Slider } from "@theme-ui/components";
|
||||||
|
import { User } from "../components/icons";
|
||||||
|
import { useRef, useState } from "react";
|
||||||
|
import { showFilePicker } from "../utils/file-picker";
|
||||||
|
import { db } from "../common/db";
|
||||||
|
import { useStore as useUserStore } from "../stores/user-store";
|
||||||
|
import { showToast } from "../utils/toast";
|
||||||
|
|
||||||
|
export type EditProfileDialogProps = {
|
||||||
|
onClose: Perform;
|
||||||
|
profile?: Profile;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function EditProfileDialog(props: EditProfileDialogProps) {
|
||||||
|
const { profile } = props;
|
||||||
|
const [profilePicture, setProfilePicture] = useState<
|
||||||
|
File | string | undefined
|
||||||
|
>(profile?.profilePicture);
|
||||||
|
const profileRef = useRef<AvatarEditor>(null);
|
||||||
|
const [fullName, setFullName] = useState<string | undefined>(
|
||||||
|
profile?.fullName
|
||||||
|
);
|
||||||
|
const [scale, setScale] = useState(1);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [clearProfilePicture, setClearProfilePicture] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
isOpen={true}
|
||||||
|
title={"Edit profile"}
|
||||||
|
description="Your profile data is stored 100% end-to-end encrypted."
|
||||||
|
onClose={() => props.onClose(false)}
|
||||||
|
positiveButton={{
|
||||||
|
loading: isLoading,
|
||||||
|
disabled: isLoading,
|
||||||
|
text: "Save",
|
||||||
|
onClick: async () => {
|
||||||
|
setIsLoading(true);
|
||||||
|
try {
|
||||||
|
await db.user.setProfile({
|
||||||
|
fullName,
|
||||||
|
profilePicture: profileRef.current
|
||||||
|
? profileRef.current
|
||||||
|
.getImageScaledToCanvas()
|
||||||
|
.toDataURL("image/jpeg", 1)
|
||||||
|
: clearProfilePicture
|
||||||
|
? undefined
|
||||||
|
: profile?.profilePicture
|
||||||
|
});
|
||||||
|
await useUserStore.getState().refreshUser();
|
||||||
|
showToast("success", "Profile updated!");
|
||||||
|
props.onClose(true);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
showToast("error", (e as Error).message);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
width={400}
|
||||||
|
negativeButton={{ text: "Cancel", onClick: () => props.onClose(false) }}
|
||||||
|
>
|
||||||
|
<Flex sx={{ gap: 2, mt: 2 }}>
|
||||||
|
<Flex sx={{ flexDirection: "column" }}>
|
||||||
|
{profilePicture ? (
|
||||||
|
<AvatarEditor
|
||||||
|
ref={profileRef}
|
||||||
|
image={profilePicture}
|
||||||
|
width={150}
|
||||||
|
height={150}
|
||||||
|
border={0}
|
||||||
|
color={[255, 255, 255]}
|
||||||
|
borderRadius={100}
|
||||||
|
scale={scale}
|
||||||
|
style={{
|
||||||
|
width: 150,
|
||||||
|
height: 150
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Flex
|
||||||
|
variant="columnCenter"
|
||||||
|
sx={{
|
||||||
|
bg: "shade",
|
||||||
|
mr: 2,
|
||||||
|
size: 150,
|
||||||
|
borderRadius: 200,
|
||||||
|
alignSelf: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<User size={60} />
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
<Flex sx={{ gap: 1, alignItems: "center", mt: 2 }}>
|
||||||
|
<Button
|
||||||
|
sx={{ flex: 1 }}
|
||||||
|
variant="secondary"
|
||||||
|
onClick={async () =>
|
||||||
|
setProfilePicture(
|
||||||
|
await showFilePicker({ acceptedFileTypes: "image/*" })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{profilePicture ? "Change" : "Set picture"}
|
||||||
|
</Button>
|
||||||
|
{profilePicture ? (
|
||||||
|
<Button
|
||||||
|
sx={{ flex: 1 }}
|
||||||
|
variant="secondary"
|
||||||
|
onClick={async () => {
|
||||||
|
if (profile?.profilePicture) setClearProfilePicture(true);
|
||||||
|
setProfilePicture(undefined);
|
||||||
|
setScale(1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{profile?.profilePicture ? "Clear" : "Reset"}
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</Flex>
|
||||||
|
{profilePicture ? (
|
||||||
|
<Slider
|
||||||
|
max={5}
|
||||||
|
min={1}
|
||||||
|
step={0.1}
|
||||||
|
value={scale}
|
||||||
|
sx={{ color: "accent" }}
|
||||||
|
onChange={(e) => setScale(e.target.valueAsNumber)}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</Flex>
|
||||||
|
<Field
|
||||||
|
label="Full name"
|
||||||
|
maxLength={200}
|
||||||
|
value={fullName}
|
||||||
|
autoFocus
|
||||||
|
onChange={(e) => setFullName(e.target.value)}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -56,6 +56,7 @@ const BackupPasswordDialog = React.lazy(
|
|||||||
() => import("./backup-password-dialog")
|
() => import("./backup-password-dialog")
|
||||||
);
|
);
|
||||||
const CreateColorDialog = React.lazy(() => import("./create-color-dialog"));
|
const CreateColorDialog = React.lazy(() => import("./create-color-dialog"));
|
||||||
|
const EditProfileDialog = React.lazy(() => import("./edit-profile-dialog"));
|
||||||
|
|
||||||
export const Dialogs = {
|
export const Dialogs = {
|
||||||
AddNotebookDialog,
|
AddNotebookDialog,
|
||||||
@@ -85,5 +86,6 @@ export const Dialogs = {
|
|||||||
SettingsDialog,
|
SettingsDialog,
|
||||||
ThemeDetailsDialog,
|
ThemeDetailsDialog,
|
||||||
BackupPasswordDialog,
|
BackupPasswordDialog,
|
||||||
CreateColorDialog
|
CreateColorDialog,
|
||||||
|
EditProfileDialog
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,17 +17,19 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Flex, Text } from "@theme-ui/components";
|
import { Button, Flex, Image, Text } from "@theme-ui/components";
|
||||||
import { User } from "../../../components/icons";
|
import { Edit, User } from "../../../components/icons";
|
||||||
import { useStore as useUserStore } from "../../../stores/user-store";
|
import { useStore as useUserStore } from "../../../stores/user-store";
|
||||||
import { getObjectIdTimestamp } from "@notesnook/core/dist/utils/object-id";
|
import { getObjectIdTimestamp } from "@notesnook/core/dist/utils/object-id";
|
||||||
import { getFormattedDate } from "@notesnook/common";
|
import { getFormattedDate } from "@notesnook/common";
|
||||||
import { SUBSCRIPTION_STATUS } from "../../../common/constants";
|
import { SUBSCRIPTION_STATUS } from "../../../common/constants";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
|
import { showEditProfileDialog } from "../../../common/dialog-controller";
|
||||||
|
|
||||||
export function UserProfile() {
|
export function UserProfile() {
|
||||||
const user = useUserStore((store) => store.user);
|
const user = useUserStore((store) => store.user);
|
||||||
|
const profile = useUserStore((store) => store.profile);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isTrial,
|
isTrial,
|
||||||
@@ -88,42 +90,82 @@ export function UserProfile() {
|
|||||||
sx={{
|
sx={{
|
||||||
borderRadius: "default",
|
borderRadius: "default",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
|
justifyContent: "space-between",
|
||||||
bg: "var(--background-secondary)",
|
bg: "var(--background-secondary)",
|
||||||
p: 2,
|
p: 2,
|
||||||
mb: 4
|
mb: 4
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Flex
|
<Flex sx={{ alignItems: "center" }}>
|
||||||
variant="columnCenter"
|
<Flex
|
||||||
sx={{
|
variant="columnCenter"
|
||||||
bg: "shade",
|
|
||||||
mr: 2,
|
|
||||||
size: 60,
|
|
||||||
borderRadius: 80
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<User size={30} />
|
|
||||||
</Flex>
|
|
||||||
<Flex sx={{ flexDirection: "column" }}>
|
|
||||||
<Text
|
|
||||||
variant="subBody"
|
|
||||||
sx={{
|
sx={{
|
||||||
color: "accent"
|
bg: "shade",
|
||||||
|
mr: 2,
|
||||||
|
size: 60,
|
||||||
|
borderRadius: 80,
|
||||||
|
overflow: "hidden"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{remainingDays > 0 && (isPro || isProCancelled)
|
{profile?.profilePicture ? (
|
||||||
? `PRO`
|
<Image
|
||||||
: remainingDays > 0 && isTrial
|
sx={{ width: "100%", height: "100%", objectFit: "contain" }}
|
||||||
? "TRIAL"
|
src={profile.profilePicture}
|
||||||
: isBeta
|
/>
|
||||||
? "BETA TESTER"
|
) : (
|
||||||
: "BASIC"}
|
<User size={30} />
|
||||||
</Text>
|
)}
|
||||||
<Text variant={"title"}>{user.email}</Text>
|
</Flex>
|
||||||
<Text variant={"subBody"}>
|
<Flex sx={{ flexDirection: "column" }}>
|
||||||
Member since {getFormattedDate(getObjectIdTimestamp(user.id), "date")}
|
<Text
|
||||||
</Text>
|
variant="subBody"
|
||||||
|
sx={{
|
||||||
|
color: "accent"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{remainingDays > 0 && (isPro || isProCancelled)
|
||||||
|
? `PRO`
|
||||||
|
: remainingDays > 0 && isTrial
|
||||||
|
? "TRIAL"
|
||||||
|
: isBeta
|
||||||
|
? "BETA TESTER"
|
||||||
|
: "BASIC"}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{profile?.fullName ? (
|
||||||
|
<>
|
||||||
|
<Text variant={"title"}>{profile?.fullName}</Text>
|
||||||
|
<Text variant={"subBody"}>
|
||||||
|
{user.email} • Member since{" "}
|
||||||
|
{getFormattedDate(getObjectIdTimestamp(user.id), "date")}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Text variant={"title"}>{user.email}</Text>
|
||||||
|
<Text variant={"subBody"}>
|
||||||
|
Member since
|
||||||
|
{getFormattedDate(getObjectIdTimestamp(user.id), "date")}
|
||||||
|
</Text>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
<Button
|
||||||
|
variant="icon"
|
||||||
|
sx={{
|
||||||
|
borderRadius: 50,
|
||||||
|
p: 0,
|
||||||
|
m: 0,
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
alignSelf: "end"
|
||||||
|
}}
|
||||||
|
title="Edit profile"
|
||||||
|
onClick={() => showEditProfileDialog(profile)}
|
||||||
|
>
|
||||||
|
<Edit size={18} />
|
||||||
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import { hashNavigate } from "../navigation";
|
|||||||
import { isUserPremium } from "../hooks/use-is-user-premium";
|
import { isUserPremium } from "../hooks/use-is-user-premium";
|
||||||
import { SUBSCRIPTION_STATUS } from "../common/constants";
|
import { SUBSCRIPTION_STATUS } from "../common/constants";
|
||||||
import { ANALYTICS_EVENTS, trackEvent } from "../utils/analytics";
|
import { ANALYTICS_EVENTS, trackEvent } from "../utils/analytics";
|
||||||
import { User } from "@notesnook/core/dist/api/user-manager";
|
import { AuthenticatorType, Profile, User } from "@notesnook/core";
|
||||||
|
|
||||||
class UserStore extends BaseStore<UserStore> {
|
class UserStore extends BaseStore<UserStore> {
|
||||||
isLoggedIn?: boolean;
|
isLoggedIn?: boolean;
|
||||||
@@ -39,6 +39,7 @@ class UserStore extends BaseStore<UserStore> {
|
|||||||
isSigningIn = false;
|
isSigningIn = false;
|
||||||
|
|
||||||
user?: User = undefined;
|
user?: User = undefined;
|
||||||
|
profile?: Profile;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
init = () => {
|
init = () => {
|
||||||
@@ -47,32 +48,35 @@ class UserStore extends BaseStore<UserStore> {
|
|||||||
window.location.replace("/sessionexpired");
|
window.location.replace("/sessionexpired");
|
||||||
});
|
});
|
||||||
|
|
||||||
db.user.getUser().then(async (user) => {
|
db.user.getUser().then((user) => {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
this.set((state) => {
|
this.set({ isLoggedIn: false });
|
||||||
state.isLoggedIn = false;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.set((state) => {
|
this.set({
|
||||||
state.user = user;
|
user,
|
||||||
state.isLoggedIn = true;
|
isLoggedIn: true
|
||||||
});
|
});
|
||||||
if (Config.get("sessionExpired")) EV.publish(EVENTS.userSessionExpired);
|
if (Config.get("sessionExpired")) EV.publish(EVENTS.userSessionExpired);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
db.user.getProfile().then((profile) => this.set({ profile }));
|
||||||
|
|
||||||
if (Config.get("sessionExpired")) return;
|
if (Config.get("sessionExpired")) return;
|
||||||
|
|
||||||
return db.user.fetchUser().then(async (user) => {
|
return db.user.fetchUser().then(async (user) => {
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
|
|
||||||
EV.remove(EVENTS.userSubscriptionUpdated, EVENTS.userEmailConfirmed);
|
const profile = await db.user.getProfile();
|
||||||
|
|
||||||
this.set((state) => {
|
this.set({
|
||||||
state.user = user;
|
profile,
|
||||||
state.isLoggedIn = true;
|
user,
|
||||||
|
isLoggedIn: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
EV.remove(EVENTS.userSubscriptionUpdated, EVENTS.userEmailConfirmed);
|
||||||
|
|
||||||
EV.subscribe(EVENTS.userSubscriptionUpdated, (subscription) => {
|
EV.subscribe(EVENTS.userSubscriptionUpdated, (subscription) => {
|
||||||
const wasUserPremium = isUserPremium();
|
const wasUserPremium = isUserPremium();
|
||||||
this.set((state) => {
|
this.set((state) => {
|
||||||
@@ -107,18 +111,29 @@ class UserStore extends BaseStore<UserStore> {
|
|||||||
|
|
||||||
refreshUser = async () => {
|
refreshUser = async () => {
|
||||||
return db.user.fetchUser().then(async (user) => {
|
return db.user.fetchUser().then(async (user) => {
|
||||||
this.set((state) => (state.user = user));
|
const profile = await db.user.getProfile();
|
||||||
|
this.set({ user, profile });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
login = async (form, skipInit = false, sessionExpired = false) => {
|
login = async (
|
||||||
|
form:
|
||||||
|
| { email: string }
|
||||||
|
| { email: string; password: string }
|
||||||
|
| { code: string; method: AuthenticatorType },
|
||||||
|
skipInit = false,
|
||||||
|
sessionExpired = false
|
||||||
|
) => {
|
||||||
this.set((state) => (state.isLoggingIn = true));
|
this.set((state) => (state.isLoggingIn = true));
|
||||||
const { email, password, code, method } = form;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (code) {
|
if ("email" in form && !("password" in form)) {
|
||||||
|
return await db.user.authenticateEmail(form.email);
|
||||||
|
} else if ("code" in form) {
|
||||||
|
const { code, method } = form;
|
||||||
return await db.user.authenticateMultiFactorCode(code, method);
|
return await db.user.authenticateMultiFactorCode(code, method);
|
||||||
} else if (password) {
|
} else if ("password" in form) {
|
||||||
|
const { email, password } = form;
|
||||||
await db.user.authenticatePassword(
|
await db.user.authenticatePassword(
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
@@ -129,15 +144,13 @@ class UserStore extends BaseStore<UserStore> {
|
|||||||
|
|
||||||
if (skipInit) return true;
|
if (skipInit) return true;
|
||||||
return this.init();
|
return this.init();
|
||||||
} else if (email) {
|
|
||||||
return await db.user.authenticateEmail(email);
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.set((state) => (state.isLoggingIn = false));
|
this.set((state) => (state.isLoggingIn = false));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
signup = (form) => {
|
signup = (form: { email: string; password: string }) => {
|
||||||
this.set((state) => (state.isSigningIn = true));
|
this.set((state) => (state.isSigningIn = true));
|
||||||
return db.user
|
return db.user
|
||||||
.signup(form.email.toLowerCase(), form.password)
|
.signup(form.email.toLowerCase(), form.password)
|
||||||
|
|||||||
Reference in New Issue
Block a user