diff --git a/package-lock.json b/package-lock.json index 03ce76d4ab..153332f542 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,1514 @@ { "name": "nim-status-client", "version": "0.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "nim-status-client", + "version": "0.0.0", + "devDependencies": { + "create-dmg": "status-im/create-dmg#678fbd4", + "fileicon": "0.2.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansi-styles/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/appdmg": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.0.tgz", + "integrity": "sha512-vDz8cMf5c6BfoS72OmmHzzuxG5DFVDM6YCAkscjYh3GASGEBBRCZ10Bn515ZPSPHOpfI9Xu3MlApbd49C58pJg==", + "dev": true, + "os": [ + "darwin" + ], + "dependencies": { + "async": "^1.4.2", + "ds-store": "^0.1.5", + "execa": "^1.0.0", + "fs-temp": "^1.0.0", + "fs-xattr": "^0.3.0", + "image-size": "^0.7.4", + "is-my-json-valid": "^2.20.0", + "minimist": "^1.1.3", + "parse-color": "^1.0.0", + "path-exists": "^4.0.0", + "repeat-string": "^1.5.4" + }, + "bin": { + "appdmg": "bin/appdmg.js" + }, + "engines": { + "node": ">=8.5" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-parallel": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz", + "integrity": "sha1-j3hTCJJu1apHjEfmTRszS2wMlH0=", + "dev": true + }, + "node_modules/array-series": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz", + "integrity": "sha1-3103v8XC7wdV4qpPkv6ufUtaly8=", + "dev": true + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "node_modules/base32-encode": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.1.1.tgz", + "integrity": "sha512-eqa0BeGghj3guezlasdHJhr3+J5ZbbQvxeprkcDMbRQrjlqOT832IUDT4Al4ofAwekFYMqkkM9KMUHs9Cu0HKA==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bplist-creator": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", + "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", + "dev": true, + "dependencies": { + "stream-buffers": "~2.2.0" + } + }, + "node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", + "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", + "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=", + "dev": true + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/create-dmg": { + "version": "5.3.0", + "resolved": "git+ssh://git@github.com/status-im/create-dmg.git#678fbd411585c87a92a74b4314190b85037b66eb", + "integrity": "sha512-/H3vvTLpeynZeq9y3gxEHuShArOojgR+3k9NcQYvtbjkQoxtgHriXbnBQtPHREFl68BktoIwVWIXAGvrle7+Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "appdmg": "^0.6.0", + "execa": "^1.0.0", + "gm": "^1.23.1", + "icns-lib": "^1.0.1", + "meow": "^5.0.0", + "ora": "^4.0.3", + "plist": "^3.0.1", + "tempy": "^0.3.0" + }, + "bin": { + "create-dmg": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/ds-store": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", + "integrity": "sha1-0QJO90btDBPw9/7IXH6FjoxLfKc=", + "dev": true, + "dependencies": { + "bplist-creator": "~0.0.3", + "macos-alias": "~0.2.5", + "tn1150": "^0.1.0" + } + }, + "node_modules/encode-utf8": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/fileicon": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/fileicon/-/fileicon-0.2.4.tgz", + "integrity": "sha512-2gipEXOI2jvh6yp7FN/SZ5M67fbLknZ+Q3kizBQupe+4w12z51WnmCBiiGfdeMZzUmhCTPSJuCK/Sl1kEyWmhA==", + "dev": true, + "os": [ + "darwin" + ], + "bin": { + "fileicon": "bin/fileicon" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fmix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", + "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=", + "dev": true, + "dependencies": { + "imul": "^1.0.0" + } + }, + "node_modules/fs-temp": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", + "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", + "dev": true, + "dependencies": { + "random-path": "^0.1.0" + } + }, + "node_modules/fs-xattr": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", + "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", + "dev": true, + "hasInstallScript": true, + "os": [ + "!win32" + ], + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dev": true, + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "dependencies": { + "is-property": "^1.0.0" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/gm": { + "version": "1.23.1", + "resolved": "https://registry.npmjs.org/gm/-/gm-1.23.1.tgz", + "integrity": "sha1-Lt7rlYCE0PjqeYjl2ZWxx9/BR3c=", + "dev": true, + "dependencies": { + "array-parallel": "~0.1.3", + "array-series": "~0.1.5", + "cross-spawn": "^4.0.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/gm/node_modules/cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/icns-lib": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/icns-lib/-/icns-lib-1.0.1.tgz", + "integrity": "sha512-J7+RDRQApG/vChY5TP043NitBcNC7QMn1kOgGvlAkyrK65hozAaSwTNsTZ2HJh+br9e1NlzpBreAOpk4YuhOJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/image-size": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", + "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", + "dev": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/imul": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", + "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, + "node_modules/is-my-json-valid": { + "version": "2.20.5", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz", + "integrity": "sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A==", + "dev": true, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/jsonpointer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.1.0.tgz", + "integrity": "sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/macos-alias": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.11.tgz", + "integrity": "sha1-/u6mwTuhGYFKQ/xDxHCzHlnvcYo=", + "dev": true, + "hasInstallScript": true, + "os": [ + "darwin" + ], + "dependencies": { + "nan": "^2.4.0" + } + }, + "node_modules/map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "dependencies": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/murmur-32": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", + "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", + "dev": true, + "dependencies": { + "encode-utf8": "^1.0.3", + "fmix": "^0.1.0", + "imul": "^1.0.0" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.1.1.tgz", + "integrity": "sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", + "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", + "dev": true, + "dependencies": { + "color-convert": "~0.5.0" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "dev": true, + "dependencies": { + "base64-js": "^1.2.3", + "xmlbuilder": "^9.0.7", + "xmldom": "0.1.x" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/random-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", + "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", + "dev": true, + "dependencies": { + "base32-encode": "^0.1.0 || ^1.0.0", + "murmur-32": "^0.1.0 || ^0.2.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "dependencies": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "node_modules/stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tempy": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", + "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", + "dev": true, + "dependencies": { + "temp-dir": "^1.0.0", + "type-fest": "^0.3.1", + "unique-string": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tn1150": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", + "integrity": "sha1-ZzUD0k1WuH3ouMd/7j/AhT1ZoY0=", + "dev": true, + "dependencies": { + "unorm": "^1.4.1" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "dependencies": { + "crypto-random-string": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", + "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0", + "dev": true, + "engines": { + "node": ">=0.1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0" + } + } + }, "dependencies": { "ansi-regex": { "version": "5.0.0", @@ -161,9 +1667,9 @@ "dev": true }, "create-dmg": { - "version": "github:status-im/create-dmg#678fbd411585c87a92a74b4314190b85037b66eb", - "from": "github:status-im/create-dmg#678fbd4", + "version": "git+ssh://git@github.com/status-im/create-dmg.git#678fbd411585c87a92a74b4314190b85037b66eb", "dev": true, + "from": "create-dmg@status-im/create-dmg#678fbd4", "requires": { "appdmg": "^0.6.0", "execa": "^1.0.0", diff --git a/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml b/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml index c51a04e562..f66f46e068 100644 --- a/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml +++ b/ui/app/AppLayouts/WalletV2/WalletV2Layout.qml @@ -3,10 +3,14 @@ import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import "../../../imports" import "../../../shared" + +import "stores" +import "controls" import "views" +import "panels" +import "popups" import "views/assets" -import "." -import "./components" +import "views/collectibles" import StatusQ.Controls 0.1 import StatusQ.Layout 0.1 @@ -16,21 +20,10 @@ Item { id: walletView property bool hideSignPhraseModal: false + property RootStore store: RootStore { } - function showSavedAddressesView() { - layoutWalletTwoPanel.rightPanel.view.replace(cmpSavedAddresses); - } - - function hideSavedAddressesView() { - layoutWalletTwoPanel.rightPanel.view.replace(walletInfoContent); - } - - function openCollectibleDetailView(options) { - collectiblesDetailPage.active = true - collectiblesDetailPage.item.show(options) - } - - function showSigningPhrasePopup(){ + function showSigningPhrasePopup() { + //TODO improve this to not use dynamic scoping if(!hideSignPhraseModal && !appSettings.hideSignPhraseModal){ signPhrasePopup.open(); } @@ -38,12 +31,18 @@ Item { SignPhraseModal { id: signPhrasePopup + signingPhraseText: walletView.store.walletModelInst.utilsView.signingPhrase + onRemindLaterButtonClicked: { + hideSignPhraseModal = true; + signPhrasePopup.close(); + } } - - SeedPhraseBackupWarning { + + SeedPhraseBackupWarningPanel { id: seedPhraseWarning width: parent.width anchors.top: parent.top + visible: !walletView.store.profileModelInst.mnemonic.isBackedUp } StatusAppTwoPanelLayout { @@ -53,15 +52,23 @@ Item { width: walletView.width Component.onCompleted: { - if(onboardingModel.firstTimeLogin){ - onboardingModel.firstTimeLogin = false - walletModel.setInitialRange() + if (walletView.store.onboardingModelInst.firstTimeLogin) { + walletView.store.onboardingModelInst.firstTimeLogin = false; + walletView.store.walletModelInst.setInitialRange(); } } - leftPanel: LeftTab { + leftPanel: LeftTabView { id: leftTab anchors.fill: parent + store: walletView.store + onSavedAddressesClicked: { + if (selected) { + stackView.replace(cmpSavedAddresses); + } else { + stackView.replace(walletInfoContent); + } + } } rightPanel: Item { @@ -76,7 +83,6 @@ Item { anchors.left: parent.left anchors.leftMargin: 80 anchors.right: parent.right - visible: !collectiblesDetailPage.active anchors.rightMargin: 80 StackBaseView { id: stackView @@ -84,9 +90,16 @@ Item { Layout.fillHeight: true initialItem: Item { id: walletInfoContent - WalletHeader { + WalletHeaderPanel { id: walletHeader - changeSelectedAccount: leftTab.changeSelectedAccount + accountsModel: walletView.store.walletModelV2Inst.accountsView.accounts + currentAccount: walletView.store.walletModelV2Inst.accountsView.currentAccount + qrCode: walletView.store.profileModelInst.qrCode(walletView.store.selectedAccount.address) + allNetworksModel: walletView.store.walletModelV2Inst.networksView.allNetworks + enabledNetworksModel: walletView.store.walletModelV2Inst.networksView.enabledNetworks + onCopyText: { + walletView.store.copyText(text); + } } TabBar { id: walletTabBar @@ -96,9 +109,7 @@ Item { anchors.topMargin: Style.current.padding height: childrenRect.height spacing: 24 - background: Rectangle { - color: Style.current.transparent - } + background: null StatusTabButton { id: assetsBtn btnText: qsTr("Assets") @@ -115,12 +126,7 @@ Item { id: activityBtn btnText: qsTr("Activity") } - StatusTabButton { - id: settingsBtn - btnText: qsTr("Settings") - } } - StackLayout { id: stackLayout anchors.top: walletTabBar.bottom @@ -141,6 +147,10 @@ Item { } CollectiblesView { id: collectiblesTab + store: walletView.store + onCollectibleClicked: { + stackView.replace(collectibleDetailView); + } } ActivityView { id: activityTab @@ -148,40 +158,38 @@ Item { } } } + } - Component { - id: assetDetailView - AssetDetailView { - onBackPressed: { - stackView.replace(walletInfoContent); - } - - SettingsTab { - id: settingsTab - } + Component { + id: assetDetailView + AssetDetailView { + onBackPressed: { + stackView.replace(walletInfoContent); } } - Component { - id: cmpSavedAddresses - SavedAddresses {} + } + + Component { + id: collectibleDetailView + CollectibleDetailView { + store: walletView.store + onBackPressed: { + stackView.replace(walletInfoContent); + } } } - WalletFooter { + Component { + id: cmpSavedAddresses + SavedAddressesView { + store: walletView.store + } + } + + WalletFooterPanel { id: walletFooter anchors.bottom: parent.bottom - } - - Loader { - id: collectiblesDetailPage - anchors.bottom: walletFooter.top - anchors.left: parent.left - anchors.right: parent.right - anchors.top: parent.top - active: false - sourceComponent: CollectibleDetailsPage { - anchors.fill: parent - } + walletV2Model: walletView.store.walletModelV2Inst } } } diff --git a/ui/app/AppLayouts/WalletV2/components/AddAccountPopup.qml b/ui/app/AppLayouts/WalletV2/components/AddAccountPopup.qml deleted file mode 100644 index 72a3a213f2..0000000000 --- a/ui/app/AppLayouts/WalletV2/components/AddAccountPopup.qml +++ /dev/null @@ -1,240 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Controls 2.13 -import QtQuick.Dialogs 1.3 - -import "../../../../imports" -import "../../../../shared" -import "../../../../shared/status" - -import StatusQ.Core 0.1 -import StatusQ.Core.Theme 0.1 -import StatusQ.Controls 0.1 -import StatusQ.Controls.Validators 0.1 -import StatusQ.Popups 0.1 - -StatusModal { - id: popup - height: (keyOrSeedPhraseInput.input.edit.contentHeight > 56 || seedPhraseInserted) ? 517 : 498 - header.title: qsTr("Add account") - onOpened: { - keyOrSeedPhraseInput.input.edit.forceActiveFocus(Qt.MouseFocusReason); - } - - property bool loading: false - property int marginBetweenInputs: 20 - property bool seedPhraseInserted: false - property bool isSeedCountValid: false - signal addAccountClicked() - - function seedPhraseNotFound() { - var seedValidationError = onboardingModel.validateMnemonic(keyOrSeedPhraseInput.text); - var regex = new RegExp('word [a-z]+ not found in the dictionary', 'i'); - return regex.test(seedValidationError); - } - - function validate() { - if (popup.isSeedCountValid && !popup.seedPhraseNotFound()) { - var validCount = 0; - var accountsList = seedAccountDetails.activeAccountsList; - for (var i = 0; i < accountsList.count; i++) { - if (accountsList.itemAtIndex(i).nameInputValid) { - validCount++; - } - } - } - return (popup.isSeedCountValid && !popup.seedPhraseNotFound()) ? (validCount === accountsList.count) : - (keyOrSeedPhraseInput.valid && pkeyAccountDetails.nameInputValid); - } - - contentItem: Item { - id: contentItem - anchors.left: parent.left - anchors.leftMargin: 8 - anchors.right: parent.right - anchors.rightMargin: 10 - height: parent.height - - Item { - id: leftContent - StatusInput { - id: keyOrSeedPhraseInput - width: parent.width - anchors.top: parent.top - anchors.topMargin: popup.marginBetweenInputs - input.multiline: true - input.icon.width: 15 - input.icon.height: 11 - input.icon.name: (popup.isSeedCountValid) || Utils.isPrivateKey(keyOrSeedPhraseInput.text) ? "checkmark" : "" - input.icon.color: Theme.palette.primaryColor1 - input.leftIcon: false - input.implicitHeight: 56 - input.placeholderText: qsTr("Enter private key or seed phrase") - label: qsTr("Private key or seed phrase") - validators: [ - StatusValidator { - validate: function () { - return popup.seedPhraseInserted ? (popup.isSeedCountValid && - !popup.seedPhraseNotFound()) : Utils.isPrivateKey(keyOrSeedPhraseInput.text); - } - } - ] - onTextChanged: { - popup.seedPhraseInserted = keyOrSeedPhraseInput.text.includes(" "); - if (popup.seedPhraseInserted) { - popup.seedPhraseInserted = true; - seedAccountDetails.searching = true; - seedAccountDetails.timer.start(); - } - - popup.isSeedCountValid = (!!keyOrSeedPhraseInput.text && (keyOrSeedPhraseInput.text.match(/(\w+)/g).length === 12)); - if (text === "") { - errorMessage = qsTr("You need to enter a valid private key or seed phrase"); - } else { - if (!popup.seedPhraseInserted) { - errorMessage = !Utils.isPrivateKey(keyOrSeedPhraseInput.text) ? - qsTrId("enter-a-valid-private-key-(64-characters-hexadecimal-string)") : ""; - } else { - if (!popup.isSeedCountValid) { - errorMessage = qsTrId("enter-a-valid-mnemonic"); - } else if (popup.seedPhraseNotFound()) { - errorMessage = qsTrId("custom-seed-phrase") + '. ' + qsTrId("custom-seed-phrase-text-1"); - } else { - errorMessage = ""; - } - } - } - } - } - } - - Rectangle { - id: separator - color: Theme.palette.statusPopupMenu.separatorColor - } - - PKeyAccountDetails { - id: pkeyAccountDetails - width: parent.width - height: parent.height/2 - anchors.top: separator.bottom - } - - SeedAddAccountView { - id: seedAccountDetails - width: (parent.width/2) - height: parent.height - anchors.right: parent.right - } - - states: [ - State { - when: (popup.isSeedCountValid && !popup.seedPhraseNotFound()) - PropertyChanges { - target: popup - width: 907 - } - PropertyChanges { - target: pkeyAccountDetails - opacity: 0.0 - } - PropertyChanges { - target: leftContent - width: contentItem.width/2 - height: contentItem.height - } - PropertyChanges { - target: separator - width: 1 - height: contentItem.height - } - AnchorChanges { - target: separator - anchors.left: leftContent.right - } - PropertyChanges { - target: seedAccountDetails - opacity: 1.0 - } - }, - State { - when: !(popup.isSeedCountValid && !popup.seedPhraseNotFound()) - PropertyChanges { - target: popup - width: 574 - } - PropertyChanges { - target: seedAccountDetails - opacity: 0.0 - } - PropertyChanges { - target: leftContent - width: contentItem.width - height: 120 - } - PropertyChanges { - target: pkeyAccountDetails - opacity: 1.0 - } - PropertyChanges { - target: separator - width: contentItem.width - height: 1 - anchors.topMargin: (2*popup.marginBetweenInputs) - } - AnchorChanges { - target: separator - anchors.left: contentItem.left - anchors.top: leftContent.bottom - } - } - ] - } - - rightButtons: [ - StatusButton { - text: popup.loading ? qsTrId("loading") : qsTrId("add-account") - enabled: (!popup.loading && popup.validate()) - - MessageDialog { - id: accountError - title: qsTr("Adding the account failed") - icon: StandardIcon.Critical - standardButtons: StandardButton.Ok - } - - onClicked : { - popup.loading = true; - if (!popup.validate()) { - errorSound.play(); - popup.loading = false; - } else { - //TODO account color to be verified with design - var result; - if (popup.isSeedCountValid && !popup.seedPhraseNotFound()) { - var accountsList = seedAccountDetails.activeAccountsList; - for (var i = 0; i < accountsList.count; i++) { - //TODO remove password requirement - if (!!accountsList.itemAtIndex(i)) { - result = walletModel.accountsView.addAccountsFromSeed(accountsList.itemAtIndex(i).accountAddress, "", accountsList.itemAtIndex(i).accountName, "") - } - } - } else { - result = walletModel.accountsView.addAccountsFromPrivateKey(keyOrSeedPhraseInput.text, "", pkeyAccountDetails.accountName, ""); - } - popup.loading = false; - if (result) { - let resultJson = JSON.parse(result); - if (!Utils.isInvalidPasswordMessage(resultJson.error)) { - accountError.text = resultJson.error; - accountError.open(); - } - errorSound.play(); - return; - } - popup.addAccountClicked(); - popup.close(); - } - } - } - ] -} diff --git a/ui/app/AppLayouts/WalletV2/components/network/qmldir b/ui/app/AppLayouts/WalletV2/components/network/qmldir deleted file mode 100644 index 4a2a401ff1..0000000000 --- a/ui/app/AppLayouts/WalletV2/components/network/qmldir +++ /dev/null @@ -1 +0,0 @@ -NetworkSelect 1.0 NetworkSelect.qml \ No newline at end of file diff --git a/ui/app/AppLayouts/WalletV2/components/qmldir b/ui/app/AppLayouts/WalletV2/components/qmldir deleted file mode 100644 index 291e6249e4..0000000000 --- a/ui/app/AppLayouts/WalletV2/components/qmldir +++ /dev/null @@ -1,5 +0,0 @@ -AddAccount 1.0 AddAccount.qml -HeaderButton 1.0 HeaderButton.qml -CollectibleCollection 1.0 CollectibleCollection.qml -AddAccountPopup 1.0 AddAccountPopup.qml -CollectibleDetailsPage 1.0 CollectibleDetailsPage.qml diff --git a/ui/app/AppLayouts/WalletV2/components/CollectibleDetailsHeader.qml b/ui/app/AppLayouts/WalletV2/controls/CollectibleDetailsHeader.qml similarity index 69% rename from ui/app/AppLayouts/WalletV2/components/CollectibleDetailsHeader.qml rename to ui/app/AppLayouts/WalletV2/controls/CollectibleDetailsHeader.qml index 282ac287a8..81078e3e87 100644 --- a/ui/app/AppLayouts/WalletV2/components/CollectibleDetailsHeader.qml +++ b/ui/app/AppLayouts/WalletV2/controls/CollectibleDetailsHeader.qml @@ -9,52 +9,15 @@ import StatusQ.Controls 0.1 Item { id: collectiblesDetailHeader + height: childrenRect.height property alias primaryText: collectibleName.text property alias secondaryText: collectibleId.text - property StatusImageSettings image: StatusImageSettings { width: 40 height: 40 } - - height: childrenRect.height - - Layout.fillHeight: true - Layout.fillWidth: true - - Row { - id: backButtonRow - anchors.top: parent.top - anchors.topMargin: 19 - anchors.left: parent.left - spacing: 8 - StatusIcon { - id: arrowIcon - anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: -1 - icon: "chevron-up" - rotation: 270 - color: Theme.palette.primaryColor1 - } - StatusBaseText { - anchors.verticalCenter: parent.verticalCenter - id: collectiblesText - font.weight: Font.Medium - font.pixelSize: 15 - lineHeight: 22 - lineHeightMode: Text.FixedHeight - color: Theme.palette.primaryColor1 - text: qsTr("Collectibles") - } - } - - MouseArea { - anchors.fill: backButtonRow - onClicked: { - hide() - } - } + signal hideButtonClicked() Row { id: collectibleRow @@ -116,6 +79,6 @@ Item { anchors.right: parent.right icon.name: "send" text: qsTr("Send") - onClicked: () => console.log("TODO"); + onClicked: { console.log("TODO"); } } } diff --git a/ui/app/AppLayouts/WalletV2/components/HeaderButton.qml b/ui/app/AppLayouts/WalletV2/controls/HeaderButton.qml similarity index 80% rename from ui/app/AppLayouts/WalletV2/components/HeaderButton.qml rename to ui/app/AppLayouts/WalletV2/controls/HeaderButton.qml index e27860c94b..769392fb43 100644 --- a/ui/app/AppLayouts/WalletV2/components/HeaderButton.qml +++ b/ui/app/AppLayouts/WalletV2/controls/HeaderButton.qml @@ -5,19 +5,20 @@ import "../../../../shared" Rectangle { - property string text: "" - property url imageSource - property bool flipImage: false - property var onClicked: function () {} - id: headerButton width: buttonImage.width + buttonText.width + Style.current.smallPadding * 2 - + (text === "" ? 0 : walletMenu.btnMargin) + + (text === "" ? 0 : headerButton.btnMargin) height: buttonText.height + Style.current.smallPadding * 2 border.width: 0 color: Style.current.transparent radius: Style.current.radius + property int btnMargin + property string text: "" + property url imageSource + property bool flipImage: false + signal clicked() + SVGImage { id: buttonImage height: 18 @@ -25,7 +26,7 @@ Rectangle { anchors.leftMargin: Style.current.smallPadding anchors.verticalCenter: parent.verticalCenter fillMode: Image.PreserveAspectFit - source: imageSource + source: headerButton.imageSource rotation: flipImage ? 180 : 0 ColorOverlay { @@ -40,7 +41,7 @@ Rectangle { visible: !!headerButton.text text: headerButton.text anchors.left: buttonImage.right - anchors.leftMargin: walletMenu.btnMargin + anchors.leftMargin: headerButton.btnMargin anchors.verticalCenter: parent.verticalCenter font.pixelSize: 13 font.family: Style.current.fontMedium.name @@ -51,15 +52,15 @@ Rectangle { MouseArea { anchors.fill: parent hoverEnabled: true + cursorShape: Qt.PointingHandCursor onEntered: { - parent.color = Style.current.secondaryBackground + headerButton.color = Style.current.secondaryBackground; } onExited: { - parent.color = Style.current.transparent + headerButton.color = Style.current.transparent; } onClicked: { - headerButton.onClicked() + headerButton.clicked(); } - cursorShape: Qt.PointingHandCursor } } diff --git a/ui/app/AppLayouts/WalletV2/components/SavedAddressesError.qml b/ui/app/AppLayouts/WalletV2/controls/SavedAddressesError.qml similarity index 99% rename from ui/app/AppLayouts/WalletV2/components/SavedAddressesError.qml rename to ui/app/AppLayouts/WalletV2/controls/SavedAddressesError.qml index fd25348a5c..b3414a39cd 100644 --- a/ui/app/AppLayouts/WalletV2/components/SavedAddressesError.qml +++ b/ui/app/AppLayouts/WalletV2/controls/SavedAddressesError.qml @@ -9,12 +9,11 @@ import StatusQ.Controls 0.1 Item { id: addEditError - - property alias text: label.text - anchors.left: parent.left anchors.right: parent.right + property alias text: label.text + StatusIcon { id: errorIcon icon: "warning" diff --git a/ui/app/AppLayouts/WalletV2/components/SeedAccountDetailsDelegate.qml b/ui/app/AppLayouts/WalletV2/controls/SeedAccountDetailsDelegate.qml similarity index 97% rename from ui/app/AppLayouts/WalletV2/components/SeedAccountDetailsDelegate.qml rename to ui/app/AppLayouts/WalletV2/controls/SeedAccountDetailsDelegate.qml index c80c56620d..18a386ff06 100644 --- a/ui/app/AppLayouts/WalletV2/components/SeedAccountDetailsDelegate.qml +++ b/ui/app/AppLayouts/WalletV2/controls/SeedAccountDetailsDelegate.qml @@ -18,8 +18,8 @@ Item { property string accountName: accountNameInput.text property bool nameInputValid: accountNameInput.valid property string accountAddress: model.address - property string emoji: "" //TODO implement emoji selection + signal deleteClicked() RowLayout { anchors.fill: parent @@ -82,7 +82,7 @@ Item { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: { - walletModel.accountsView.deleteAccount(address); + root.deleteClicked(); } } } diff --git a/ui/app/AppLayouts/WalletV2/components/WalletButton.qml b/ui/app/AppLayouts/WalletV2/controls/WalletButton.qml similarity index 88% rename from ui/app/AppLayouts/WalletV2/components/WalletButton.qml rename to ui/app/AppLayouts/WalletV2/controls/WalletButton.qml index 3f219ac6d7..b9d4f7a053 100644 --- a/ui/app/AppLayouts/WalletV2/components/WalletButton.qml +++ b/ui/app/AppLayouts/WalletV2/controls/WalletButton.qml @@ -8,14 +8,13 @@ Rectangle { width: btnImage.width + btnImage.anchors.leftMargin + btnImage.anchors.rightMargin + btnText.width + btnText.anchors.leftMargin + btnText.anchors.rightMargin height: btnText.height + Style.current.smallPadding * 2 - border.width: 0 color: Style.current.transparent radius: Style.current.radius property string text: "" property url imageSource property bool flipImage: false - property var onClicked: function () {} + signal clicked() SVGImage { id: btnImage @@ -51,15 +50,15 @@ Rectangle { MouseArea { anchors.fill: parent hoverEnabled: true + cursorShape: Qt.PointingHandCursor onEntered: { - parent.color = Style.current.secondaryBackground + parent.color = Style.current.secondaryBackground; } onExited: { - parent.color = Style.current.transparent + parent.color = Style.current.transparent; } onClicked: { - walletBtnRoot.onClicked() + walletBtnRoot.clicked(); } - cursorShape: Qt.PointingHandCursor } } diff --git a/ui/app/AppLayouts/WalletV2/components/AccountNotFound.qml b/ui/app/AppLayouts/WalletV2/panels/AccountNotFoundPanel.qml similarity index 100% rename from ui/app/AppLayouts/WalletV2/components/AccountNotFound.qml rename to ui/app/AppLayouts/WalletV2/panels/AccountNotFoundPanel.qml diff --git a/ui/app/AppLayouts/WalletV2/components/network/NetworkFilter.qml b/ui/app/AppLayouts/WalletV2/panels/NetworkFilterPanel.qml similarity index 84% rename from ui/app/AppLayouts/WalletV2/components/network/NetworkFilter.qml rename to ui/app/AppLayouts/WalletV2/panels/NetworkFilterPanel.qml index 05cea17431..09c9827ce8 100644 --- a/ui/app/AppLayouts/WalletV2/components/network/NetworkFilter.qml +++ b/ui/app/AppLayouts/WalletV2/panels/NetworkFilterPanel.qml @@ -1,15 +1,17 @@ import QtQuick 2.13 -import "../../../../../shared" -import "../../../../../imports" +import "../../../../shared" +import "../../../../imports" Grid { id: root columns: 2 spacing: 2 + visible: (chainRepeater.count > 0) + property var model Repeater { id: chainRepeater - model: walletV2Model.networksView.enabledNetworks + model: root.model width: parent.width height: parent.height @@ -29,4 +31,4 @@ Grid { } } } -} \ No newline at end of file +} diff --git a/ui/app/AppLayouts/WalletV2/components/network/NetworkSelect.qml b/ui/app/AppLayouts/WalletV2/panels/NetworkSelectPanel.qml similarity index 77% rename from ui/app/AppLayouts/WalletV2/components/network/NetworkSelect.qml rename to ui/app/AppLayouts/WalletV2/panels/NetworkSelectPanel.qml index 60e4a3c2be..7bf2f93939 100644 --- a/ui/app/AppLayouts/WalletV2/components/network/NetworkSelect.qml +++ b/ui/app/AppLayouts/WalletV2/panels/NetworkSelectPanel.qml @@ -1,11 +1,14 @@ import QtQuick 2.13 -import "../../../../../shared" -import "../../../../../imports" +import "../../../../shared" +import "../../../../imports" +import "../popups" Item { id: root width: selectRectangle.width height: childrenRect.height + property var allNetworks + property var enabledNetworks Rectangle { id: selectRectangle @@ -41,23 +44,26 @@ Item { cursorShape: Qt.PointingHandCursor onClicked: { if (selectPopup.opened) { - selectPopup.close() - return + selectPopup.close(); + return; } - selectPopup.open() + selectPopup.open(); } } - NetworkFilter { - id: networkFilter + + NetworkFilterPanel { + id: networkFilterPanel + width: root.width anchors.topMargin: Style.current.halfPadding anchors.top: selectRectangle.bottom - width: root.width + model: root.enabledNetworks } NetworkSelectPopup { id: selectPopup x: (parent.width - width) - y: (root.height - networkFilter.height) + y: (root.height - networkFilterPanel.height) + model: root.allNetworks } } diff --git a/ui/app/AppLayouts/WalletV2/components/PKeyAccountDetails.qml b/ui/app/AppLayouts/WalletV2/panels/PKeyAccountDetailsPanel.qml similarity index 83% rename from ui/app/AppLayouts/WalletV2/components/PKeyAccountDetails.qml rename to ui/app/AppLayouts/WalletV2/panels/PKeyAccountDetailsPanel.qml index 73488c0db2..2ac6f1bbbd 100644 --- a/ui/app/AppLayouts/WalletV2/components/PKeyAccountDetails.qml +++ b/ui/app/AppLayouts/WalletV2/panels/PKeyAccountDetailsPanel.qml @@ -25,11 +25,13 @@ Item { input.implicitHeight: 56 input.placeholderText: qsTrId("enter-an-account-name...") label: qsTrId("account-name") - validators: [StatusMinLengthValidator { minLength: 1 }] - onTextChanged: { - errorMessage = (accountNameInput.text === "") ? - qsTrId("you-need-to-enter-an-account-name") : "" - } + validators: [ + StatusMinLengthValidator { + minLength: 1 + errorMessage: (accountNameInput.errors) ? + qsTrId("you-need-to-enter-an-account-name") : "" + } + ] } Item { //emoji placeholder diff --git a/ui/app/AppLayouts/WalletV2/SeedPhraseBackupWarning.qml b/ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml similarity index 89% rename from ui/app/AppLayouts/WalletV2/SeedPhraseBackupWarning.qml rename to ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml index 19689469d4..412be04b38 100644 --- a/ui/app/AppLayouts/WalletV2/SeedPhraseBackupWarning.qml +++ b/ui/app/AppLayouts/WalletV2/panels/SeedPhraseBackupWarningPanel.qml @@ -2,14 +2,13 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import QtGraphicalEffects 1.13 -import "../../../imports" -import "../../../shared" -import "../Profile/Sections" +import "../../../../imports" +import "../../../../shared" +import "../../Profile/Sections" import "." Rectangle { id: root - visible: !profileModel.mnemonic.isBackedUp height: visible ? 32 : 0 color: Style.current.red @@ -19,55 +18,54 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter StyledText { - //% "Back up your seed phrase" - text: qsTrId("back-up-your-seed-phrase") - font.pixelSize: 13 anchors.verticalCenter: parent.verticalCenter color: Style.current.white + font.pixelSize: 13 + text: qsTrId("back-up-your-seed-phrase") } - Button { + Control { width: 58 height: 24 - contentItem: Item { - anchors.fill: parent - Text { - text: "Back up" - font.pixelSize: 13 - font.weight: Font.Medium - font.family: Style.current.fontRegular.name - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - color: Style.current.white - } - } background: Rectangle { radius: 4 anchors.fill: parent border.color: Style.current.white color: "#19FFFFFF" } + contentItem: Item { + anchors.fill: parent + Text { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: 13 + font.weight: Font.Medium + font.family: Style.current.fontRegular.name + color: Style.current.white + text: "Back up" + } + } MouseArea { cursorShape: Qt.PointingHandCursor anchors.fill: parent - onClicked: backupSeedModal.open() + onClicked: { backupSeedModal.open(); } } } } SVGImage { id: closeImg + height: 20 + width: 20 anchors.top: parent.top anchors.topMargin: 6 anchors.right: parent.right anchors.rightMargin: 18 - source: "../../img/close-white.svg" - height: 20 - width: 20 + source: "../../../img/close-white.svg" } ColorOverlay { anchors.fill: closeImg @@ -88,5 +86,4 @@ Rectangle { BackupSeedModal { id: backupSeedModal } - } diff --git a/ui/app/AppLayouts/WalletV2/WalletFooter.qml b/ui/app/AppLayouts/WalletV2/panels/WalletFooterPanel.qml similarity index 55% rename from ui/app/AppLayouts/WalletV2/WalletFooter.qml rename to ui/app/AppLayouts/WalletV2/panels/WalletFooterPanel.qml index 02d930a7e6..4c90319e0a 100644 --- a/ui/app/AppLayouts/WalletV2/WalletFooter.qml +++ b/ui/app/AppLayouts/WalletV2/panels/WalletFooterPanel.qml @@ -1,15 +1,16 @@ import QtQuick 2.14 import QtQuick.Controls 2.14 -import "../../../imports" -import "./components" +import "../../../../imports" +import "../controls" +import "../popups" Item { id: walletFooterRoot height: 50 width: parent.width + property var walletV2Model Rectangle { - id: separatorLine anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right @@ -18,37 +19,37 @@ Item { } Row { - anchors.centerIn: parent spacing: 50 WalletButton { - id: swapBtn - imageSource: "../../img/swap-icon.svg" + imageSource: "../../../img/swap-icon.svg" text: qsTr("Swap") - onClicked: function (){ + onClicked: { + console.log("TODO"); } } WalletButton { - id: sendBtn - imageSource: "../../img/send.svg" + imageSource: "../../../img/send.svg" text: qsTr("Send") - onClicked: function (){ + onClicked: { + console.log("TODO"); } } WalletButton { - id: buySellBtn - imageSource: "../../img/crypto-icon.svg" + imageSource: "../../../img/crypto-icon.svg" text: qsTr("Buy / Sell") - onClicked: function (){ - cryptoServicesModal.open() + onClicked: { + cryptoServicesModal.open(); } } } CryptoServicesModal { id: cryptoServicesModal + anchors.centerIn: parent + walletV2Model: walletFooterRoot.walletV2Model } } diff --git a/ui/app/AppLayouts/WalletV2/WalletHeader.qml b/ui/app/AppLayouts/WalletV2/panels/WalletHeaderPanel.qml similarity index 55% rename from ui/app/AppLayouts/WalletV2/WalletHeader.qml rename to ui/app/AppLayouts/WalletV2/panels/WalletHeaderPanel.qml index ec8ad44afd..4d51a27ace 100644 --- a/ui/app/AppLayouts/WalletV2/WalletHeader.qml +++ b/ui/app/AppLayouts/WalletV2/panels/WalletHeaderPanel.qml @@ -1,11 +1,13 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 -import "../../../imports" -import "../../../shared" -import "../../../shared/status" -import "./components" -import "./components/network" + +import "../../../../imports" +import "../../../../shared" +import "../../../../shared/status" +import "../controls" +import "../panels" +import "../popups" Item { id: walletHeader @@ -13,17 +15,25 @@ Item { anchors.right: parent.right height: walletAddress.y + walletAddress.height - property var currentAccount: walletV2Model.accountsView.currentAccount - property var changeSelectedAccount + property var qrCode + property var accountsModel + property var currentAccount + property var enabledNetworksModel + property var allNetworksModel + signal copyText(string text) Row { id: accountRow + anchors.top: parent.top + anchors.topMargin: 24 + anchors.left: parent.left + anchors.leftMargin: 24 spacing: 8 StyledText { id: title anchors.verticalCenter: parent.verticalCenter - text: currentAccount.name + text: walletHeader.currentAccount.name font.weight: Font.Medium font.pixelSize: 28 } @@ -41,45 +51,48 @@ Item { StyledText { id: walletBalance anchors.verticalCenter: parent.verticalCenter - text: currentAccount.balance.toUpperCase() + text: walletHeader.currentAccount.balance.toUpperCase() font.pixelSize: 22 } - } MouseArea { anchors.fill: accountRow cursorShape: Qt.PointingHandCursor onClicked: { + //TOOD improve this to not use dynamic scoping openPopup(shareModalComponent); } } StatusExpandableAddress { id: walletAddress - address: currentAccount.address anchors.top: accountRow.bottom anchors.left: accountRow.left addressWidth: 180 + address: walletHeader.currentAccount.address } - NetworkSelect { + NetworkSelectPanel { id: networkSelect anchors.right: parent.right + allNetworks: walletHeader.allNetworksModel + enabledNetworks: walletHeader.enabledNetworksModel } Component { id: shareModalComponent ShareModal { + anchors.centerIn: parent + qrCode: walletHeader.qrCode + accountsModel: walletHeader.accountsModel + selectedAccount: walletHeader.currentAccount + onCopy: { + walletHeader.copyText(text); + } onClosed: { - destroy(); + this.destroy(); } } } } - -/*##^## -Designer { - D{i:0;formeditorColor:"#ffffff"} -} -##^##*/ diff --git a/ui/app/AppLayouts/WalletV2/popups/AddAccountPopup.qml b/ui/app/AppLayouts/WalletV2/popups/AddAccountPopup.qml new file mode 100644 index 0000000000..e455c5b259 --- /dev/null +++ b/ui/app/AppLayouts/WalletV2/popups/AddAccountPopup.qml @@ -0,0 +1,172 @@ +import QtQuick 2.13 +import QtQuick.Controls 2.13 +import QtQuick.Dialogs 1.3 + +import "../../../../imports" +import "../../../../shared" +import "../../../../shared/status" +import "../views" +import "../panels" + +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Controls 0.1 +import StatusQ.Controls.Validators 0.1 +import StatusQ.Popups 0.1 + +StatusModal { + id: root + height: (keyOrSeedPhraseInput.input.edit.contentHeight > 56 || root.store.seedPhraseInserted) ? 517 : 498 + header.title: qsTr("Add account") + + property int marginBetweenInputs: 20 + property var store + signal addAccountClicked() + + onOpened: { + keyOrSeedPhraseInput.input.edit.forceActiveFocus(Qt.MouseFocusReason); + } + contentItem: Item { + id: contentItem + anchors.left: parent.left + anchors.leftMargin: 8 + anchors.right: parent.right + anchors.rightMargin: 10 + height: parent.height + + Item { + id: leftContent + width: parent.width + height: parent.height/2 + anchors.top: parent.top + anchors.topMargin: root.marginBetweenInputs + StatusInput { + id: keyOrSeedPhraseInput + anchors.fill: parent + input.multiline: true + input.icon.width: 15 + input.icon.height: 11 + input.icon.name: (root.store.isSeedCountValid) || Utils.isPrivateKey(keyOrSeedPhraseInput.text) ? "checkmark" : "" + input.icon.color: Theme.palette.primaryColor1 + input.leftIcon: false + input.implicitHeight: 56 + input.placeholderText: qsTr("Enter private key or seed phrase") + label: qsTr("Private key or seed phrase") + validators: [ + StatusValidator { + validate: function (t) { + errorMessage = root.store.validateTextInput(t); + return ((t !== "") && ((root.store.isSeedCountValid && !root.store.seedPhraseNotFound(t)) + || Utils.isPrivateKey(t))) ? true : { actual: t } + } + } + ] + onTextChanged: { + if (root.store.seedPhraseInserted) { + root.store.seedPhraseInserted = true; + seedAccountDetails.searching = true; + seedAccountDetails.timer.start(); + } + } + } + } + + Rectangle { + id: separator + color: Theme.palette.statusPopupMenu.separatorColor + } + + PKeyAccountDetailsPanel { + id: pkeyAccountDetails + width: parent.width + height: parent.height/2 + anchors.top: separator.bottom + } + + SeedAddAccountView { + id: seedAccountDetails + width: (parent.width/2) + height: parent.height + anchors.right: parent.right + store: root.store + } + + states: [ + State { + when: (root.store.isSeedCountValid && !root.store.seedPhraseNotFound(keyOrSeedPhraseInput.text)) + PropertyChanges { + target: root + width: 907 + } + PropertyChanges { + target: pkeyAccountDetails + opacity: 0.0 + } + PropertyChanges { + target: leftContent + width: contentItem.width/2 + height: contentItem.height + } + PropertyChanges { + target: separator + width: 1 + height: contentItem.height + } + AnchorChanges { + target: separator + anchors.left: leftContent.right + } + PropertyChanges { + target: seedAccountDetails + opacity: 1.0 + } + }, + State { + when: !(root.store.isSeedCountValid && !root.store.seedPhraseNotFound(keyOrSeedPhraseInput.text)) + PropertyChanges { + target: root + width: 574 + } + PropertyChanges { + target: seedAccountDetails + opacity: 0.0 + } + PropertyChanges { + target: leftContent + width: contentItem.width + height: 120 + } + PropertyChanges { + target: pkeyAccountDetails + opacity: 1.0 + } + PropertyChanges { + target: separator + width: contentItem.width + height: 1 + anchors.topMargin: (2*root.marginBetweenInputs) + } + AnchorChanges { + target: separator + anchors.left: contentItem.left + anchors.top: leftContent.bottom + } + } + ] + } + + rightButtons: [ + StatusButton { + text: root.store.loadingAccounts ? qsTrId("loading") : qsTrId("add-account") + enabled: (!root.loadingAccounts && root.store.validateAddAccountPopup(keyOrSeedPhraseInput.text, seedAccountDetails.activeAccountsList, + keyOrSeedPhraseInput.valid, pkeyAccountDetails.nameInputValid)) + + onClicked : { + root.store.addAccount(keyOrSeedPhraseInput.text, seedAccountDetails.activeAccountsList, + keyOrSeedPhraseInput.valid, pkeyAccountDetails); + root.addAccountClicked(); + root.close(); + } + } + ] +} diff --git a/ui/app/AppLayouts/WalletV2/components/AddEditSavedAddress.qml b/ui/app/AppLayouts/WalletV2/popups/AddEditSavedAddressPopup.qml similarity index 93% rename from ui/app/AppLayouts/WalletV2/components/AddEditSavedAddress.qml rename to ui/app/AppLayouts/WalletV2/popups/AddEditSavedAddressPopup.qml index a8ba8090e2..71df15839e 100644 --- a/ui/app/AppLayouts/WalletV2/components/AddEditSavedAddress.qml +++ b/ui/app/AppLayouts/WalletV2/popups/AddEditSavedAddressPopup.qml @@ -24,8 +24,8 @@ StatusModal { addressInput.input.edit.forceActiveFocus(Qt.MouseFocusReason); } + property var store property bool loading: false - property var onBeforeSave: function() {} property bool edit: false property bool valid: addressInput.valid && nameInput.valid // TODO: Add network preference and emoji property bool dirty: addressInput.input.dirty && nameInput.input.dirty @@ -34,6 +34,7 @@ StatusModal { property int validationMode: edit ? StatusInput.ValidationMode.Always : StatusInput.ValidationMode.OnlyWhenDirty + signal beforeSave() contentItem: Column { anchors.left: parent.left @@ -125,10 +126,10 @@ StatusModal { onClicked: { root.loading = true; - root.onBeforeSave() + root.beforeSave(); edit ? - walletV2Model.savedAddressesView.editSavedAddress(name, address) : - walletV2Model.savedAddressesView.addSavedAddress(name, address); + root.store.walletModelV2Inst.savedAddressesView.editSavedAddress(name, address) : + root.store.walletModelV2Inst.savedAddressesView.addSavedAddress(name, address); root.close() root.loading = false; } diff --git a/ui/app/AppLayouts/WalletV2/components/CollectibleModal.qml b/ui/app/AppLayouts/WalletV2/popups/CollectibleModal.qml similarity index 78% rename from ui/app/AppLayouts/WalletV2/components/CollectibleModal.qml rename to ui/app/AppLayouts/WalletV2/popups/CollectibleModal.qml index 7a13c9ff61..681486e981 100644 --- a/ui/app/AppLayouts/WalletV2/components/CollectibleModal.qml +++ b/ui/app/AppLayouts/WalletV2/popups/CollectibleModal.qml @@ -6,22 +6,22 @@ import "../../../../shared/status" ModalPopup { id: root + title: root.name || qsTr("unnamed") property string name: "Furbeard" + property string collectibleId: "1423" property url imageUrl: "" property string description: "Avast ye! I'm the dread pirate Furbeard, and I'll most likely sleep" property string permalink: "https://www.cryptokitties.co/" property var openModal: function (options) { - root.name = options.name - root.collectibleId = options.collectibleId - root.description = options.description - root.imageUrl = options.imageUrl - root.permalink = options.permalink - root.open() + root.name = options.name; + root.collectibleId = options.collectibleId; + root.description = options.description; + root.imageUrl = options.imageUrl; + root.permalink = options.permalink; + root.open(); } - title: root.name || qsTr("unnamed") - Item { width: parent.width @@ -30,28 +30,26 @@ ModalPopup { width: 248 height: 248 anchors.horizontalCenter: parent.horizontalCenter - source: root.imageUrl radius: 16 fillMode: Image.PreserveAspectCrop + source: root.imageUrl } TextWithLabel { id: idText + anchors.top: collectibleImage.bottom label: qsTr("id") text: root.collectibleId - anchors.top: collectibleImage.bottom - anchors.topMargin:0 } TextWithLabel { id: description + anchors.top: idText.bottom visible: !!root.description + wrap: true label: qsTr("description") text: root.description - anchors.top: idText.bottom - anchors.topMargin: 0 - wrap: true } } @@ -59,10 +57,10 @@ ModalPopup { anchors.right: parent.right anchors.rightMargin: Style.current.padding text: qsTr("View in Opensea") - anchors.top: parent.top onClicked: { - appMain.openLink(root.permalink) - root.close() + //TOOD improve this to not use dynamic scoping + appMain.openLink(root.permalink); + root.close(); } } } diff --git a/ui/app/AppLayouts/WalletV2/components/CryptoServicesModal.qml b/ui/app/AppLayouts/WalletV2/popups/CryptoServicesModal.qml similarity index 80% rename from ui/app/AppLayouts/WalletV2/components/CryptoServicesModal.qml rename to ui/app/AppLayouts/WalletV2/popups/CryptoServicesModal.qml index e449e9241b..0b8983445a 100644 --- a/ui/app/AppLayouts/WalletV2/components/CryptoServicesModal.qml +++ b/ui/app/AppLayouts/WalletV2/popups/CryptoServicesModal.qml @@ -3,22 +3,27 @@ import QtQuick.Controls 2.14 import "../../../../imports" import "../../../../shared" +import StatusQ.Popups 0.1 import StatusQ.Components 0.1 -ModalPopup { +import "../controls" + +StatusModal { id: cryptoServicesPopupRoot - title: qsTr("Buy crypto") height: 400 + header.title: qsTr("Buy crypto") + property var walletV2Model onOpened: { - loader.active = true - walletV2Model.cryptoServiceController.fetchCryptoServices() + loader.active = true; + cryptoServicesPopupRoot.walletV2Model.cryptoServiceController.fetchCryptoServices(); } - Component.onCompleted: { - walletV2Model.cryptoServiceController.fetchCryptoServicesFetched.connect(function(){ - loader.sourceComponent = servicesComponent - }) + Connections { + target: cryptoServicesPopupRoot.walletV2Model.cryptoServiceController + function onFetchCryptoServicesFetched() { + loader.sourceComponent = servicesComponent; + } } Loader { @@ -50,7 +55,7 @@ ModalPopup { anchors.bottom: parent.bottom anchors.topMargin: Style.current.padding width: parent.width - model: walletV2Model.cryptoServiceController.cryptoServiceModel + model: cryptoServicesPopupRoot.walletV2Model.cryptoServiceController.cryptoServiceModel focus: true spacing: Style.current.padding clip: true @@ -99,8 +104,9 @@ ModalPopup { cursorShape: Qt.PointingHandCursor onClicked: { - appMain.openLink(siteUrl) - cryptoServicesPopupRoot.close() + //TOOD improve this to not use dynamic scoping + appMain.openLink(siteUrl); + cryptoServicesPopupRoot.close(); } } } diff --git a/ui/app/AppLayouts/WalletV2/components/network/NetworkSelectPopup.qml b/ui/app/AppLayouts/WalletV2/popups/NetworkSelectPopup.qml similarity index 94% rename from ui/app/AppLayouts/WalletV2/components/network/NetworkSelectPopup.qml rename to ui/app/AppLayouts/WalletV2/popups/NetworkSelectPopup.qml index 756d82b43a..20f6ceeaa5 100644 --- a/ui/app/AppLayouts/WalletV2/components/network/NetworkSelectPopup.qml +++ b/ui/app/AppLayouts/WalletV2/popups/NetworkSelectPopup.qml @@ -4,8 +4,8 @@ import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import StatusQ.Components 0.1 import StatusQ.Controls 0.1 -import "../../../../../imports" -import "../../../../../shared" +import "../../../../imports" +import "../../../../shared" Popup { id: popup @@ -13,6 +13,7 @@ Popup { width: 360 height: 432 closePolicy: Popup.CloseOnEscape + property var model background: Rectangle { radius: Style.current.radius @@ -45,7 +46,7 @@ Popup { Repeater { id: chainRepeater - model: walletV2Model.networksView.allNetworks + model: popup.model Item { width: content.width diff --git a/ui/app/AppLayouts/WalletV2/ShareModal.qml b/ui/app/AppLayouts/WalletV2/popups/ShareModal.qml similarity index 81% rename from ui/app/AppLayouts/WalletV2/ShareModal.qml rename to ui/app/AppLayouts/WalletV2/popups/ShareModal.qml index fc8977b648..8a91b25dd0 100644 --- a/ui/app/AppLayouts/WalletV2/ShareModal.qml +++ b/ui/app/AppLayouts/WalletV2/popups/ShareModal.qml @@ -5,28 +5,25 @@ import StatusQ.Popups 0.1 import StatusQ.Controls 0.1 import StatusQ.Core.Theme 0.1 -import "../../../shared" +import "../../../../shared" StatusModal { id: shareModal - - QtObject { - id: internal - property var selectedAccount: walletV2Model.accountsView.currentAccount - } - - anchors.centerIn: parent implicitWidth: 454 implicitHeight: 568 + property var selectedAccount + property var accountsModel + property var qrCode + signal copy(string text) // To-do Icon in header needs to be updated once emoji picker is ready - header.title: internal.selectedAccount.name + header.title: shareModal.selectedAccount.name header.subTitle: qsTr("Basic address") header.popupMenu: StatusPopupMenu { id: accountPickerPopUp Repeater { - id: repeaster - model: walletV2Model.accountsView.accounts + id: repeater + model: shareModal.accountsModel delegate: Loader { sourceComponent: accountPickerPopUp.delegate onLoaded: { @@ -35,10 +32,10 @@ StatusModal { item.action.iconSettings.name = "filled-account" } Connections { - enabled: !!item.action - target: item.action + enabled: (!!item && !!item.action) + target: enabled ? item.action : null onTriggered: { - internal.selectedAccount = { address, name, iconColor, fiatBalance } + shareModal.selectedAccount = { address, name, iconColor, fiatBalance } accountPickerPopUp.dismiss() } } @@ -58,7 +55,7 @@ StatusModal { fillMode: Image.PreserveAspectFit mipmap: true smooth: false - source: profileModel.qrCode(internal.selectedAccount.address) + source: shareModal.qrCode StatusIcon { width: 66 height: 66 @@ -86,7 +83,7 @@ StatusModal { StyledText { anchors.horizontalCenter: parent.horizontalCenter - text: internal.selectedAccount.address + text: shareModal.selectedAccount.address color: Theme.palette.directColor1 font.pixelSize: 13 font.weight: Font.Medium @@ -108,12 +105,11 @@ StatusModal { spacing: 5 StatusRoundButton { anchors.horizontalCenter: parent.horizontalCenter - icon.name: index === 0 ? "copy" : "link" onClicked: { if (index === 0) { - if (internal.selectedAccount.address) { - chatsModel.copyToClipboard(internal.selectedAccount.address) + if (shareModal.selectedAccount.address) { + shareModal.copy(shareModal.selectedAccount.address); } else { // To-do Get link functionality @@ -123,7 +119,6 @@ StatusModal { } StyledText { anchors.horizontalCenter: parent.horizontalCenter - text: index === 0 ? qsTr("Copy") : qsTr("Get link") color: Theme.palette.primaryColor1 font.pixelSize: 13 diff --git a/ui/app/AppLayouts/WalletV2/SignPhraseModal.qml b/ui/app/AppLayouts/WalletV2/popups/SignPhraseModal.qml similarity index 82% rename from ui/app/AppLayouts/WalletV2/SignPhraseModal.qml rename to ui/app/AppLayouts/WalletV2/popups/SignPhraseModal.qml index f3b6350e79..1a3ecf186a 100644 --- a/ui/app/AppLayouts/WalletV2/SignPhraseModal.qml +++ b/ui/app/AppLayouts/WalletV2/popups/SignPhraseModal.qml @@ -1,95 +1,95 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 -import "../../../imports" -import "../../../shared" -import "../../../shared/status" +import "../../../../imports" +import "../../../../shared" +import "../../../../shared/status" import "." ModalPopup { id: signPhrasePopup - //% "Signing phrase" title: qsTrId("signing-phrase") height: 390 closePolicy: Popup.NoAutoClose + property string signingPhraseText: "" + signal remindLaterButtonClicked() + Column { anchors.left: parent.left anchors.right: parent.right StyledText { + height: (Style.current.padding * 3) anchors.horizontalCenter: parent.horizontalCenter - //% "This is your signing phrase" - text: qsTrId("this-is-you-signing") + horizontalAlignment: Text.AlignHCenter font.pixelSize: 17 font.weight: Font.Bold - horizontalAlignment: Text.AlignHCenter - height: Style.current.padding * 3 + text: qsTrId("this-is-you-signing") } StyledText { - anchors.horizontalCenter: parent.horizontalCenter - //% "You should see these 3 words before signing each transaction" - text: qsTrId("three-words-description") - font.pixelSize: 15 width: 330 - wrapMode: Text.WordWrap - horizontalAlignment: Text.AlignHCenter height: Style.current.padding * 4 + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 15 + wrapMode: Text.WordWrap + text: qsTrId("three-words-description") } Rectangle { - color: Style.current.inputBackground - height: 44 width: parent.width + height: 44 + color: Style.current.inputBackground StyledText { id: signingPhrase anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter font.pixelSize: 15 - text: walletModel.utilsView.signingPhrase + text: signPhrasePopup.signingPhraseText } } Item { - height: 30 width: parent.width + height: 30 SVGImage { width: 13.33 height: 13.33 - sourceSize.height: height * 2 - sourceSize.width: width * 2 + sourceSize.height: (height * 2) + sourceSize.width: (width * 2) anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom fillMode: Image.PreserveAspectFit - source: "../../img/exclamation_outline.svg" + source: "../../../img/exclamation_outline.svg" } } StyledText { - //% "If you see a different combination, cancel the transaction and sign out" - text: qsTrId("three-words-description-2") + width: parent.width + height: 18 + anchors.horizontalCenter: parent.horizontalCenter verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - width: parent.width font.pixelSize: 13 - height: 18 color: Style.current.danger - anchors.horizontalCenter: parent.horizontalCenter + //% "If you see a different combination, cancel the transaction and sign out" + text: qsTrId("three-words-description-2") } } footer: Item { width: parent.width height: btnRemindLater.height - StatusButton { anchors.right: btnRemindLater.left anchors.rightMargin: Style.current.padding + type: "secondary" //% "Ok, got it" text: qsTrId("ens-got-it") - type: "secondary" onClicked: { + //TOOD improve this to not use dynamic scoping appSettings.hideSignPhraseModal = true; close(); } @@ -102,8 +102,7 @@ ModalPopup { //% "Remind me later" text: qsTrId("remind-me-later") onClicked: { - hideSignPhraseModal = true; - close(); + signPhrasePopup.remindLaterButtonClicked(); } } } diff --git a/ui/app/AppLayouts/WalletV2/qmldir b/ui/app/AppLayouts/WalletV2/qmldir deleted file mode 100644 index 31a3372cf0..0000000000 --- a/ui/app/AppLayouts/WalletV2/qmldir +++ /dev/null @@ -1,5 +0,0 @@ -LeftTab 1.0 LeftTab.qml -WalletHeader 1.0 WalletHeader.qml -AssetsTab 1.0 AssetsTab.qml -CollectiblesTab 1.0 CollectiblesTab.qml -SettingsTab SettingsTab.qml diff --git a/ui/app/AppLayouts/WalletV2/stores/CollectiblesStore.qml b/ui/app/AppLayouts/WalletV2/stores/CollectiblesStore.qml new file mode 100644 index 0000000000..4a3bbb87e7 --- /dev/null +++ b/ui/app/AppLayouts/WalletV2/stores/CollectiblesStore.qml @@ -0,0 +1,19 @@ +import QtQuick 2.13 +import QtQuick.Dialogs 1.3 +import "../../../../imports" + +QtObject { + id: root + + property string name + property string collectibleId + property string description: qsTr("Collectibles") + property color backgroundColor: "transparent" + property url collectibleImageUrl + property url permalink + property url imageUrl + property var properties + property var rankings + property var stats + property int collectionIndex +} diff --git a/ui/app/AppLayouts/WalletV2/stores/RootStore.qml b/ui/app/AppLayouts/WalletV2/stores/RootStore.qml new file mode 100644 index 0000000000..d939affb5a --- /dev/null +++ b/ui/app/AppLayouts/WalletV2/stores/RootStore.qml @@ -0,0 +1,212 @@ +import QtQuick 2.13 +import QtQuick.Dialogs 1.3 +import "../../../../imports" + +QtObject { + id: root + + property CollectiblesStore collectiblesStore: CollectiblesStore { } + property var walletModelInst: walletModel + property var walletModelV2Inst: walletV2Model + property var profileModelInst: profileModel + property var chatsModelInst: chatsModel + property var onboardingModelInst: onboardingModel + property int selectedAccount: 0 + + function getSavedAddressErrorText(savedAddresses, error) { + switch (error) { + case savedAddresses.Error.CreateSavedAddressError: + return qsTr("Error creating new saved address, please try again later."); + case savedAddresses.Error.DeleteSavedAddressError: + return qsTr("Error deleting saved address, please try again later."); + case savedAddresses.Error.ReadSavedAddressesError: + return qsTr("Error getting saved addresses, please try again later."); + case savedAddresses.Error.UpdateSavedAddressError: + return qsTr("Error updating saved address, please try again later."); + default: return ""; + } + } + + function copyText(text) { + root.chatsModelInst.copyToClipboard(text); + } + + function changeSelectedAccount(newIndex) { + if (newIndex > root.walletModelV2Inst.accountsView.accounts) { + return; + } + root.selectedAccount = newIndex; + root.walletModelV2Inst.setCurrentAccountByIndex(newIndex); + } + + function afterAddAccount() { + changeSelectedAccount(walletModelInst.accountsView.accounts.rowCount() - 1); + } + + function getCollectionMaxValue(traitType, value, maxValue, collectionIndex) { + if(maxValue !== "") + return parseInt(value) + qsTr(" of ") + maxValue; + else + return parseInt(value) + qsTr(" of ") + + walletModelV2Inst.collectiblesView.collections.getCollectionTraitMaxValue(collectionIndex, traitType).toString(); + } + + property bool seedPhraseInserted: false + property bool isSeedCountValid: false + property bool loadingAccounts: false + + function seedPhraseNotFound(text) { + var seedValidationError = root.onboardingModelInst.validateMnemonic(text); + var regex = new RegExp('word [a-z]+ not found in the dictionary', 'i'); + return regex.test(seedValidationError); + } + + function validateAddAccountPopup(text, model, keyOrSeedValid, accountNameValid) { + if (root.isSeedCountValid && !root.seedPhraseNotFound(text)) { + var validCount = 0; + for (var i = 0; i < model.count; i++) { + if (!!model.itemAtIndex(i) && model.itemAtIndex(i).nameInputValid) { + validCount++; + } + } + } + return (root.isSeedCountValid && !root.seedPhraseNotFound(text)) ? (validCount === model.count) : + (keyOrSeedValid && accountNameValid); + } + + function validateTextInput(text) { + root.seedPhraseInserted = text.includes(" "); + var errorMessage; + root.isSeedCountValid = (!!text && (text.match(/(\w+)/g).length === 12)); + if (text === "") { + errorMessage = qsTr("You need to enter a valid private key or seed phrase"); + } else { + if (!root.seedPhraseInserted) { + errorMessage = !Utils.isPrivateKey(text) ? + qsTrId("enter-a-valid-private-key-(64-characters-hexadecimal-string)") : ""; + } else { + if (!root.isSeedCountValid) { + errorMessage = qsTrId("enter-a-valid-mnemonic"); + } else if (root.seedPhraseNotFound(text)) { + errorMessage = qsTrId("custom-seed-phrase") + '. ' + qsTrId("custom-seed-phrase-text-1"); + } else { + errorMessage = ""; + } + } + } + return errorMessage; + } + + function addAccount(text, model, keyOrSeedValid, accountNameInput) { + root.loadingAccounts = true; + if (!root.validateAddAccountPopup(text, model, keyOrSeedValid, accountNameInput.nameInputValid)) { + //TOOD improve this to not use dynamic scoping + errorSound.play(); + root.loadingAccounts = false; + } else { + //TODO account color to be verified with design + var result; + if (root.isSeedCountValid && !root.seedPhraseNotFound(text)) { + for (var i = 0; i < model.count; i++) { + //TODO add authorization process when Authorization moadl is ready + if (!!model.itemAtIndex(i)) { + result = root.walletModelInst.accountsView.addAccountsFromSeed(model.itemAtIndex(i).accountAddress, "qwqwqw", model.itemAtIndex(i).accountName, "") + } + } + } else { + result = root.walletModelInst.accountsView.addAccountsFromPrivateKey(text, "qwqwqw", accountNameInput.text, ""); + } + root.loadingAccounts = false; + if (result) { + let resultJson = JSON.parse(result); + if (!Utils.isInvalidPasswordMessage(resultJson.error)) { + accountError.text = resultJson.error; + accountError.open(); + } + //TOOD improve this to not use dynamic scoping + errorSound.play(); + return; + } + } + } + + property MessageDialog accountError: MessageDialog { + id: accountError + title: qsTr("Adding the account failed") + icon: StandardIcon.Critical + standardButtons: StandardButton.Ok + } + + function deleteAccount(address) { + walletModelInst.accountsView.deleteAccount(address); + } + + property ListModel exampleWalletModel: ListModel { + id: exampleWalletModel + ListElement { + name: "Status account" + address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" + isFavorite: false + } + ListElement { + name: "Test account 1" + address: "0x2Ef1...E0Ba" + isFavorite: false + } + ListElement { + name: "Status account 2" + address: "0x2Ef1...E0Ba" + isFavorite: true + } + ListElement { + name: "Status account" + address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" + isFavorite: false + } + ListElement { + name: "Test account 1" + address: "0x2Ef1...E0Ba" + isFavorite: false + } + ListElement { + name: "Status account 2" + address: "0x2Ef1...E0Ba" + isFavorite: true + } + ListElement { + name: "Status account" + address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" + isFavorite: false + } + ListElement { + name: "Test account 1" + address: "0x2Ef1...E0Ba" + isFavorite: false + } + ListElement { + name: "Status account 2" + address: "0x2Ef1...E0Ba" + isFavorite: true + } + ListElement { + name: "Status account" + address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" + isFavorite: false + } + ListElement { + name: "Test account 1" + address: "0x2Ef1...E0Ba" + isFavorite: false + } + ListElement { + name: "Status account 2" + address: "0x2Ef1...E0Ba" + isFavorite: true + } + } + + property string imgPath: Qt.resolvedUrl("../../../img/") + function img(name) { + return imgPath + name + ".svg"; + } +} diff --git a/ui/app/AppLayouts/WalletV2/components/AddAccount.qml b/ui/app/AppLayouts/WalletV2/views/AddAccountView.qml similarity index 79% rename from ui/app/AppLayouts/WalletV2/components/AddAccount.qml rename to ui/app/AppLayouts/WalletV2/views/AddAccountView.qml index fdb3ab737f..086c497fc2 100644 --- a/ui/app/AppLayouts/WalletV2/components/AddAccount.qml +++ b/ui/app/AppLayouts/WalletV2/views/AddAccountView.qml @@ -5,6 +5,8 @@ import "../../../../shared" import "../../../../shared/status" import "../../../../imports" +import "../popups" + StatusFlatButton { id: btnAdd width: 138 @@ -14,9 +16,7 @@ StatusFlatButton { icon.name: "add" icon.width: 14 icon.height: 14 - readonly property var onAfterAddAccount: function() { - walletInfoContainer.changeSelectedAccount(walletModel.accountsView.accounts.rowCount() - 1); - } + property var store onClicked: { if (newAccountMenu.opened) { @@ -31,20 +31,18 @@ StatusFlatButton { width: 260 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent Action { - //% "Generate an account" - text: qsTrId("generate-a-new-account") - icon.source: "../../../img/generate_account.svg" icon.width: 19 icon.height: 19 - onTriggered: console.log("TODO") + icon.source: "../../../img/generate_account.svg" + text: qsTrId("generate-a-new-account") + onTriggered: { console.log("TODO"); } } Action { - //% "Add a watch-only address" - text: qsTrId("add-a-watch-account") - icon.source: "../../../img/eye.svg" icon.width: 19 icon.height: 19 - onTriggered: console.log("TODO") + icon.source: "../../../img/eye.svg" + text: qsTrId("add-a-watch-account") + onTriggered: { console.log("TODO"); } } Action { text: qsTr("Add with key or seed phrase") @@ -56,11 +54,11 @@ StatusFlatButton { } } onAboutToShow: { - btnAdd.state = "pressed" + btnAdd.state = "pressed"; } onAboutToHide: { - btnAdd.state = "default" + btnAdd.state = "default"; } } @@ -70,7 +68,10 @@ StatusFlatButton { sourceComponent: AddAccountPopup { id: addAccountPopup anchors.centerIn: parent - onAddAccountClicked: { btnAdd.onAfterAddAccount(); } + store: btnAdd.store + onAddAccountClicked: { + btnAdd.store.afterAddAccount(); + } onClosed: { addAccountPopupLoader.active = false; } diff --git a/ui/app/AppLayouts/WalletV2/views/CollectiblesView.qml b/ui/app/AppLayouts/WalletV2/views/CollectiblesView.qml index f8398891ea..805632a56b 100644 --- a/ui/app/AppLayouts/WalletV2/views/CollectiblesView.qml +++ b/ui/app/AppLayouts/WalletV2/views/CollectiblesView.qml @@ -4,12 +4,17 @@ import QtGraphicalEffects 1.13 import "../../../../imports" import "../../../../shared" import "../../../../shared/status/core" -import "../components" + +import "../popups" +import "collectibles" import StatusQ.Components 0.1 Item { - id: collectiblesTab + id: root + width: parent.width + property var store + signal collectibleClicked() Loader { id: contentLoader @@ -17,26 +22,24 @@ Item { height: parent.height sourceComponent: { - if (walletV2Model.collectiblesView.isLoading) { - return loading + if (root.store.walletModelV2Inst.collectiblesView.isLoading) { + return loading; } - if (walletV2Model.collectiblesView.collections.rowCount() == 0) { - return empty + if (root.store.walletModelV2Inst.collectiblesView.collections.rowCount() === 0) { + return empty; } - - return loaded + return loaded; } } Component { id: loading - Item { StatusLoadingIndicator { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter width: 20 height: 20 + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter } } } @@ -63,23 +66,29 @@ Item { Column { id: collectiblesSection - width: collectiblesTab.width + width: parent.width Repeater { id: collectionsRepeater - model: walletV2Model.collectiblesView.collections - - StatusExpandableItem { + model: root.store.walletModelV2Inst.collectiblesView.collections + //model: 5 + delegate: StatusExpandableItem { width: parent.width - 156 anchors.horizontalCenter: parent.horizontalCenter primaryText: model.name image.source: model.imageUrl type: StatusExpandableItem.Type.Secondary - expandableComponent: CollectibleCollection { + expandableComponent: CollectibleCollectionView { + store: root.store slug: model.slug - collectionImageUrl: model.imageUrl - collectionIndex: model.index + anchors.left: parent.left + anchors.leftMargin: Style.current.bigPadding + anchors.right: parent.right + anchors.rightMargin: Style.current.bigPadding + onCollectibleClicked: { + root.collectibleClicked(); + } } } } diff --git a/ui/app/AppLayouts/WalletV2/LeftTab.qml b/ui/app/AppLayouts/WalletV2/views/LeftTabView.qml similarity index 86% rename from ui/app/AppLayouts/WalletV2/LeftTab.qml rename to ui/app/AppLayouts/WalletV2/views/LeftTabView.qml index ca3e3edc6f..4302f1d4c8 100644 --- a/ui/app/AppLayouts/WalletV2/LeftTab.qml +++ b/ui/app/AppLayouts/WalletV2/views/LeftTabView.qml @@ -5,32 +5,24 @@ import QtGraphicalEffects 1.13 import StatusQ.Components 0.1 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 -import "../../../imports" -import "../../../shared" -import "./components" +import "../../../../imports" +import "../../../../shared" Rectangle { id: walletInfoContainer color: Style.current.secondaryMenuBackground - property int selectedAccount: 0 - property var changeSelectedAccount: function(newIndex) { - if (newIndex > walletV2Model.accountsView.accounts) { - return - } - selectedAccount = newIndex - walletV2Model.setCurrentAccountByIndex(newIndex) - collectiblesDetailPage.active = false - } + + property var store + signal savedAddressesClicked(bool selected) StyledText { id: title - //% "Wallet" - text: qsTrId("wallet") anchors.top: parent.top anchors.topMargin: Style.current.padding anchors.horizontalCenter: parent.horizontalCenter font.weight: Font.Bold font.pixelSize: 17 + text: qsTrId("wallet") } Item { @@ -46,19 +38,19 @@ Rectangle { StyledTextEdit { id: walletAmountValue color: Style.current.textColor - text: Utils.toLocaleString("0.00", globalSettings.locale, {"currency": true}) + " " + "USD" selectByMouse: true cursorVisible: true readOnly: true anchors.left: parent.left font.weight: Font.Medium font.pixelSize: 30 + //TOOD improve this to not use dynamic scoping + text: Utils.toLocaleString("0.00", globalSettings.locale, {"currency": true}) + " " + "USD" } StyledText { id: totalValue color: Style.current.secondaryText - //% "Total value" text: qsTrId("wallet-total-value") anchors.left: walletAmountValue.left anchors.top: walletAmountValue.bottom @@ -72,25 +64,18 @@ Rectangle { id: walletDelegate Rectangle { - property bool selected: index === selectedAccount - property bool hovered - id: rectangle - height: 64 - color: { - if (selected) { - return Style.current.menuBackgroundActive - } - if (hovered) { - return Style.current.backgroundHoverLight - } - return Style.current.transparent - } - radius: Style.current.radius - anchors.right: parent.right - anchors.rightMargin: Style.current.padding anchors.left: parent.left anchors.leftMargin: Style.current.padding + anchors.right: parent.right + anchors.rightMargin: Style.current.padding + height: 64 + property bool selected: (index === walletInfoContainer.store.selectedAccount) + property bool hovered + color: selected ? Style.current.menuBackgroundActive : + hovered ? Style.current.backgroundHoverLight + : Style.current.transparent + radius: Style.current.radius SVGImage { id: walletIcon @@ -100,7 +85,7 @@ Rectangle { anchors.topMargin: Style.current.smallPadding anchors.left: parent.left anchors.leftMargin: Style.current.padding - source: "../../img/walletIcon.svg" + source: "../../../img/walletIcon.svg" } ColorOverlay { anchors.fill: walletIcon @@ -109,7 +94,6 @@ Rectangle { } StyledText { id: walletName - text: name elide: Text.ElideRight anchors.right: walletBalance.left anchors.rightMargin: Style.current.smallPadding @@ -121,11 +105,11 @@ Rectangle { font.pixelSize: 15 font.weight: Font.Medium color: Style.current.textColor + text: name } StyledText { id: walletAddress font.family: Style.current.fontHexRegular.name - text: address anchors.right: parent.right anchors.rightMargin: parent.width/2 elide: Text.ElideMiddle @@ -136,10 +120,10 @@ Rectangle { font.weight: Font.Medium color: Style.current.secondaryText opacity: selected ? 0.7 : 1 + text: address } StyledText { id: walletBalance - text: isLoading ? "..." : Utils.toLocaleString(fiatBalance, globalSettings.locale, {"currency": true}) + " " + "USD" anchors.top: parent.top anchors.topMargin: Style.current.smallPadding anchors.right: parent.right @@ -147,19 +131,20 @@ Rectangle { font.pixelSize: 15 font.weight: Font.Medium color: Style.current.textColor + text: isLoading ? "..." : Utils.toLocaleString(fiatBalance, globalSettings.locale, {"currency": true}) + " " + "USD" } MouseArea { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onEntered: { - rectangle.hovered = true + rectangle.hovered = true; } onExited: { - rectangle.hovered = false + rectangle.hovered = false; } onClicked: { - walletInfoContainer.changeSelectedAccount(index) + walletInfoContainer.store.changeSelectedAccount(index); } } } @@ -181,9 +166,8 @@ Rectangle { anchors.fill: parent spacing: 5 boundsBehavior: Flickable.StopAtBounds - + model: walletInfoContainer.store.walletModelV2Inst.accountsView.accounts delegate: walletDelegate - ListModel { id: exampleWalletModel ListElement { @@ -263,17 +247,16 @@ Rectangle { iconColor: "#7CDA00" } } - - model: walletV2Model.accountsView.accounts } } - AddAccount { + AddAccountView { id: addAccountButton anchors.left: parent.left anchors.leftMargin: Style.current.padding anchors.top: accountsList.bottom anchors.topMargin: 31 + store: walletInfoContainer.store } StatusNavigationListItem { id: btnSavedAddresses @@ -286,15 +269,7 @@ Rectangle { onClicked: { selected = !selected; - selected ? - walletView.showSavedAddressesView() : - walletView.hideSavedAddressesView(); + walletInfoContainer.savedAddressesClicked(selected); } } } - -/*##^## -Designer { - D{i:0;formeditorColor:"#ffffff";formeditorZoom:0.75;height:770;width:340} -} -##^##*/ diff --git a/ui/app/AppLayouts/WalletV2/SavedAddresses.qml b/ui/app/AppLayouts/WalletV2/views/SavedAddressesView.qml similarity index 63% rename from ui/app/AppLayouts/WalletV2/SavedAddresses.qml rename to ui/app/AppLayouts/WalletV2/views/SavedAddressesView.qml index e126fbc198..3e176d184e 100644 --- a/ui/app/AppLayouts/WalletV2/SavedAddresses.qml +++ b/ui/app/AppLayouts/WalletV2/views/SavedAddressesView.qml @@ -2,9 +2,8 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 -import "../../../imports" -import "../../../shared" -import "./components" +import "../../../../imports" +import "../../../../shared" import StatusQ.Controls 0.1 import StatusQ.Components 0.1 @@ -12,14 +11,17 @@ import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Popups 0.1 +import "../popups" +import "../controls" + Item { id: root property bool loading: false - property int error: SavedAddresses.Error.None + property int error: SavedAddressesView.Error.None anchors.leftMargin: 80 anchors.rightMargin: 80 anchors.topMargin: 62 - + property var store enum Error { CreateSavedAddressError, @@ -30,20 +32,6 @@ Item { None } - function getErrorText(error) { - switch (error) { - case SavedAddresses.Error.CreateSavedAddressError: - return qsTr("Error creating new saved address, please try again later."); - case SavedAddresses.Error.DeleteSavedAddressError: - return qsTr("Error deleting saved address, please try again later."); - case SavedAddresses.Error.ReadSavedAddressesError: - return qsTr("Error getting saved addresses, please try again later."); - case SavedAddresses.Error.UpdateSavedAddressError: - return qsTr("Error updating saved address, please try again later."); - default: return ""; - } - } - Item { id: header anchors.left: parent.left @@ -75,14 +63,15 @@ Item { } Component { id: addEditSavedAddress - AddEditSavedAddress { + AddEditSavedAddressPopup { id: addEditModal anchors.centerIn: parent + store: root.store onClosed: { - destroy() + destroy(); } - onBeforeSave: function() { - root.loading = true + onBeforeSave: { + root.loading = true; } } } @@ -95,10 +84,12 @@ Item { rightPadding: 11 visible: !root.loading onClicked: { + //TODO improve this to not use dynamic scoping appMain.openPopup(addEditSavedAddress) } } StatusLoadingIndicator { + anchors.centerIn: parent visible: root.loading color: Theme.palette.directColor4 } @@ -128,6 +119,7 @@ Item { StatusRoundButton { icon.name: "pencil" visible: showButtons + //TODO improve this to not use dynamic scoping onClicked: appMain.openPopup(addEditSavedAddress, { edit: true, @@ -182,7 +174,7 @@ Item { text: qsTr("Delete") onClicked: { root.loading = true - walletV2Model.savedAddressesView.deleteSavedAddress( + root.store.walletModelV2Inst.savedAddressesView.deleteSavedAddress( deleteAddressConfirm.address) deleteAddressConfirm.close() } @@ -191,28 +183,28 @@ Item { } Connections { - target: walletV2Model.savedAddressesView + target: root.store.walletModelV2Inst.savedAddressesView onAddEditResultChanged: { root.loading = false - let resultRaw = walletV2Model.savedAddressesView.addEditResult + let resultRaw = root.store.walletModelV2Inst.savedAddressesView.addEditResult let result = JSON.parse(resultRaw) if (result.o) { - root.error = SavedAddresses.Error.None - walletV2Model.savedAddressesView.loadSavedAddresses(); + root.error = SavedAddressesView.Error.None + root.store.walletModelV2Inst.savedAddressesView.loadSavedAddresses(); } else { root.error = parseInt(result.e) } } } Connections { - target: walletV2Model.savedAddressesView + target: root.store.walletModelV2Inst.savedAddressesView onDeleteResultChanged: { root.loading = false - let resultRaw = walletV2Model.savedAddressesView.deleteResult + let resultRaw = root.store.walletModelV2Inst.savedAddressesView.deleteResult let result = JSON.parse(resultRaw) if (result.o) { - root.error = SavedAddresses.Error.None - walletV2Model.savedAddressesView.loadSavedAddresses(); + root.error = SavedAddressesView.Error.None + root.store.walletModelV2Inst.savedAddressesView.loadSavedAddresses(); deleteAddressConfirm.close(); } else { root.error = parseInt(result.e) @@ -220,13 +212,13 @@ Item { } } Connections { - target: walletV2Model.savedAddressesView + target: root.store.walletModelV2Inst.savedAddressesView onLoadResultChanged: { root.loading = false - let resultRaw = walletV2Model.savedAddressesView.loadResult + let resultRaw = root.store.walletModelV2Inst.savedAddressesView.loadResult let result = JSON.parse(resultRaw) if (result.o) { - root.error = SavedAddresses.Error.None + root.error = SavedAddressesView.Error.None } else { root.error = parseInt(result.e) } @@ -237,8 +229,8 @@ Item { id: errorMessage anchors.top: header.bottom anchors.topMargin: Style.current.padding - visible: root.error !== SavedAddresses.Error.None - text: getErrorText(root.error) + visible: root.error !== SavedAddressesView.Error.None + text: root.store.getSavedAddressErrorText(SavedAddressesView, root.error) height: visible ? 36 : 0 } @@ -267,80 +259,13 @@ Item { ListView { id: listView - + //model: root.store.exampleWalletModel + model: root.store.walletModelV2Inst.savedAddressesView.savedAddresses clip: true spacing: 5 anchors.fill: parent boundsBehavior: Flickable.StopAtBounds - delegate: delegateSavedAddress - - ListModel { - id: exampleWalletModel - ListElement { - name: "Status account" - address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" - isFavorite: false - } - ListElement { - name: "Test account 1" - address: "0x2Ef1...E0Ba" - isFavorite: false - } - ListElement { - name: "Status account 2" - address: "0x2Ef1...E0Ba" - isFavorite: true - } - ListElement { - name: "Status account" - address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" - isFavorite: false - } - ListElement { - name: "Test account 1" - address: "0x2Ef1...E0Ba" - isFavorite: false - } - ListElement { - name: "Status account 2" - address: "0x2Ef1...E0Ba" - isFavorite: true - } - ListElement { - name: "Status account" - address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" - isFavorite: false - } - ListElement { - name: "Test account 1" - address: "0x2Ef1...E0Ba" - isFavorite: false - } - ListElement { - name: "Status account 2" - address: "0x2Ef1...E0Ba" - isFavorite: true - } - ListElement { - name: "Status account" - address: "0xcfc9f08bbcbcb80760e8cb9a3c1232d19662fc6f" - isFavorite: false - } - ListElement { - name: "Test account 1" - address: "0x2Ef1...E0Ba" - isFavorite: false - } - ListElement { - name: "Status account 2" - address: "0x2Ef1...E0Ba" - isFavorite: true - } - } - - model: walletV2Model.savedAddressesView.savedAddresses //exampleWalletModel } } - -} \ No newline at end of file +} diff --git a/ui/app/AppLayouts/WalletV2/components/SeedAddAccountView.qml b/ui/app/AppLayouts/WalletV2/views/SeedAddAccountView.qml similarity index 91% rename from ui/app/AppLayouts/WalletV2/components/SeedAddAccountView.qml rename to ui/app/AppLayouts/WalletV2/views/SeedAddAccountView.qml index a532e5cc0f..7266dd47fd 100644 --- a/ui/app/AppLayouts/WalletV2/components/SeedAddAccountView.qml +++ b/ui/app/AppLayouts/WalletV2/views/SeedAddAccountView.qml @@ -1,6 +1,8 @@ import QtQuick 2.13 import "../../../../imports" +import "../panels" +import "../controls" import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 @@ -19,6 +21,7 @@ Item { searching = false; } } + property var store property var dummyModel: [] Column { @@ -45,13 +48,16 @@ Item { anchors.bottomMargin: 10 clip: true //TODO replace with active accounts model - model: walletModel.accountsView.accounts + model: root.store.walletModelInst.accountsView.accounts delegate: SeedAccountDetailsDelegate { deleteButtonVisible: (activeAccountsView.count > 1) + onDeleteClicked: { + root.store.deleteAccount(address); + } } } - AccountNotFound { + AccountNotFoundPanel { id: accountNotFound width: parent.width anchors.verticalCenter: parent.verticalCenter diff --git a/ui/app/AppLayouts/WalletV2/SettingsTab.qml b/ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml similarity index 83% rename from ui/app/AppLayouts/WalletV2/SettingsTab.qml rename to ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml index 2ccfa8dd59..f03769cfa3 100644 --- a/ui/app/AppLayouts/WalletV2/SettingsTab.qml +++ b/ui/app/AppLayouts/WalletV2/views/SettingsTabView.qml @@ -6,11 +6,12 @@ import StatusQ.Components 0.1 import StatusQ.Controls 0.1 import StatusQ.Core 0.1 -import "../../../imports" -import "../Profile/Sections" +import "../../../../imports" +import "../../Profile/Sections" Item { id: root + property var store Column { anchors.top:parent.top @@ -25,15 +26,15 @@ Item { anchors.right: parent.right anchors.rightMargin: 20 - visible : (walletV2Model.accountsView.currentAccount.walletType !== Constants.seedWalletType) && - (walletV2Model.accountsView.currentAccount.walletType !== Constants.watchWalletType) && - (walletV2Model.accountsView.currentAccount.walletType !== Constants.keyWalletType) + visible : (root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.seedWalletType) && + (root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.watchWalletType) && + (root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.keyWalletType) expandable: false icon.name: "seed-phrase" primaryText: qsTr("Back up seed phrase") secondaryText: qsTr("Back up your seed phrase now to secure this account") button.text: qsTr("Back up seed phrase") - button.enabled: !profileModel.mnemonic.isBackedUp + button.enabled: !root.store.profileModelInst.mnemonic.isBackedUp button.onClicked: backupSeedModal.open() } @@ -43,7 +44,7 @@ Item { anchors.right: parent.right anchors.rightMargin: 20 - visible : walletV2Model.accountsView.currentAccount.walletType !== Constants.watchWalletType + visible : root.store.walletModelV2Inst.accountsView.currentAccount.walletType !== Constants.watchWalletType expandable: true icon.name: "secret" primaryText: qsTr("Account signing phrase") @@ -57,8 +58,8 @@ Item { anchors.right: parent.right anchors.rightMargin: 20 - visible : (walletV2Model.accountsView.currentAccount.walletType === Constants.keyWalletType) || - (walletV2Model.accountsView.currentAccount.walletType === Constants.seedWalletType) + visible : (root.store.walletModelV2Inst.accountsView.currentAccount.walletType === Constants.keyWalletType) || + (root.store.walletModelV2Inst.accountsView.currentAccount.walletType === Constants.seedWalletType) expandable: true icon.name: "seed-phrase" primaryText: qsTr("View private key") @@ -67,7 +68,7 @@ Item { expandableComponent: notImplemented button.onClicked: { // To-do open enter password Modal - expanded = !expanded + expanded = !expanded; } } @@ -131,7 +132,7 @@ Item { lineHeightMode: Text.FixedHeight elide: Text.ElideRight wrapMode: Text.Wrap - text: walletV2Model.settingsView.signingPhrase + text: root.store.walletModelV2Inst.settingsView.signingPhrase } } Rectangle { diff --git a/ui/app/AppLayouts/WalletV2/components/CollectibleCollection.qml b/ui/app/AppLayouts/WalletV2/views/collectibles/CollectibleCollectionView.qml similarity index 55% rename from ui/app/AppLayouts/WalletV2/components/CollectibleCollection.qml rename to ui/app/AppLayouts/WalletV2/views/collectibles/CollectibleCollectionView.qml index a012e854a8..6e0790c247 100644 --- a/ui/app/AppLayouts/WalletV2/components/CollectibleCollection.qml +++ b/ui/app/AppLayouts/WalletV2/views/collectibles/CollectibleCollectionView.qml @@ -7,21 +7,20 @@ import StatusQ.Core.Theme 0.1 Item { id: root + width: parent.width + height: contentLoader.height property string slug: "" property bool assetsLoaded: false property string collectionImageUrl: "" property int collectionIndex: -1 - - signal clicked() - - width: parent.width - height: contentLoader.height + property var store + signal collectibleClicked() Connections { - target: walletV2Model.collectiblesView.getAssetsList(root.slug) + target: root.store.walletV2ModelInst.collectiblesView.getAssetsList(root.slug) onAssetsChanged: { - root.assetsLoaded = true + root.assetsLoaded = true; } } @@ -30,7 +29,6 @@ Item { width: parent.width anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter - sourceComponent: root.assetsLoaded ? loaded : loading } @@ -43,7 +41,6 @@ Item { StatusLoadingIndicator { width: 20 height: 20 - anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter } @@ -60,7 +57,7 @@ Item { spacing: 24 Repeater { - model: walletV2Model.collectiblesView.getAssetsList(root.slug) + model: root.store.walletV2ModelInst.collectiblesView.getAssetsList(root.slug) StatusRoundedImage { id: image width: 146 @@ -74,18 +71,18 @@ Item { MouseArea { anchors.fill: parent onClicked: { - openCollectibleDetailView({collectibleImageUrl:collectionImageUrl, - name: model.name, - collectibleId: model.id, - description: model.description, - permalink: model.permalink, - imageUrl: model.imageUrl, - backgroundColor: model.backgroundColor, - properties: model.properties, - rankings: model.rankings, - stats: model.stats, - collectionIndex: root.collectionIndex - }) + root.store.collectiblesStore.collectibleImageUrl = collectionImageUrl; + root.store.collectiblesStore.name = model.name; + root.store.collectiblesStore.collectibleId = model.id; + root.store.collectiblesStore.description = model.description; + root.store.collectiblesStore.permalink = model.permalink; + root.store.collectiblesStore.imageUrl = model.imageUrl; + root.store.collectiblesStore.backgroundColor = model.backgroundColor; + root.store.collectiblesStore.properties = model.properties; + root.store.collectiblesStore.rankings = model.rankings; + root.store.collectiblesStore.stats = model.stats; + root.store.collectiblesStore.collectionIndex = root.collectionIndex; + root.collectibleClicked(); } } } @@ -94,6 +91,6 @@ Item { } Component.onCompleted: { - walletV2Model.collectiblesView.loadAssets(walletV2Model.accountsView.currentAccount.address, root.slug) + root.store.walletV2ModelInst.collectiblesView.loadAssets(root.store.walletV2ModelInst.accountsView.currentAccount.address, root.slug); } } diff --git a/ui/app/AppLayouts/WalletV2/components/CollectibleDetailsPage.qml b/ui/app/AppLayouts/WalletV2/views/collectibles/CollectibleDetailView.qml similarity index 82% rename from ui/app/AppLayouts/WalletV2/components/CollectibleDetailsPage.qml rename to ui/app/AppLayouts/WalletV2/views/collectibles/CollectibleDetailView.qml index a8245149bf..4df44223a6 100644 --- a/ui/app/AppLayouts/WalletV2/components/CollectibleDetailsPage.qml +++ b/ui/app/AppLayouts/WalletV2/views/collectibles/CollectibleDetailView.qml @@ -7,54 +7,32 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Core 0.1 import StatusQ.Controls 0.1 -Item { - id: collectiblesDetailContainer +import "../" +import "../../controls" - property var assetProperties - property var assetRankings - property var assetStats - property int collectionIndex: -1 +StackDetailBase { + id: root + backButtonText: "Collectibles" - function show(options) { - collectibleHeader.image.source = options.collectibleImageUrl - collectibleHeader.primaryText = options.name - collectibleHeader.secondaryText = options.collectibleId - - collectibleimage.image.source = options.imageUrl - collectibleText.text = options.description - collectibleimage.color = options.backgroundColor - assetProperties = options.properties - assetRankings = options.rankings - assetStats = options.stats - collectionIndex = options.collectionIndex - } - - function hide() { - active = false - } - - function getCollectionMaxValue(traitType, value, maxValue) { - if(maxValue !== "") - return parseInt(value) + qsTr(" of ") + maxValue - else - return parseInt(value) + qsTr(" of ") + walletV2Model.collectiblesView.collections.getCollectionTraitMaxValue(collectionIndex, traitType).toString() - } + property var store + property var assetStats: root.store.collectiblesStore.stats + property var assetRankings: root.store.collectiblesStore.rankings + property var assetProperties: root.store.collectiblesStore.properties + property int collectionIndex: root.store.collectiblesStore.collectionIndex CollectibleDetailsHeader { id: collectibleHeader - anchors.right: parent.right - anchors.rightMargin: 79 anchors.left: parent.left - anchors.leftMargin: 79 - anchors.top: parent.top + anchors.right: parent.right + image.source: root.store.collectiblesStore.collectibleImageUrl + primaryText: root.store.collectiblesStore.name + secondaryText: root.store.collectiblesStore.collectibleId } Item { anchors.bottom: parent.bottom anchors.left: parent.left - anchors.leftMargin: 83 anchors.right: parent.right - anchors.rightMargin: 78 anchors.top: collectibleHeader.bottom anchors.topMargin: 46 @@ -69,16 +47,17 @@ Item { width: 253 height: 253 radius: 2 - color: "transparent" + color: root.store.collectiblesStore.backgroundColor border.color: Theme.palette.directColor8 border.width: 1 + image.source: root.store.collectiblesStore.imageUrl } StatusBaseText { id: collectibleText width: parent.width - collectibleimage.width - 24 height: collectibleimage.height - text: qsTr("Collectibles") + text: root.store.collectiblesStore.description color: Theme.palette.directColor1 font.pixelSize: 15 lineHeight: 22 @@ -202,7 +181,7 @@ Item { lineHeightMode: Text.FixedHeight horizontalAlignment: Text.AlignLeft elide: Text.ElideRight - text: collectiblesDetailContainer.getCollectionMaxValue(model.traitType, model.value, model.maxValue) + text: root.store.getCollectionMaxValue(model.traitType, model.value, model.maxValue, collectionIndex) } } } @@ -247,7 +226,7 @@ Item { lineHeightMode: Text.FixedHeight horizontalAlignment: Text.AlignLeft elide: Text.ElideRight - text: collectiblesDetailContainer.getCollectionMaxValue(model.traitType, model.value, model.maxValue) + text: root.store.getCollectionMaxValue(model.traitType, model.value, model.maxValue, collectionIndex) } } }