From 1375b63d44fb0ddfde741dd778a0a80a7774c8f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:02:03 -0400 Subject: [PATCH 01/27] Update dependency concurrently to v5 (#1631) --- package-lock.json | 27 ++++++++++----------------- package.json | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index b30053ffd..7ff151dee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,6 @@ "requires": { "chalk": "^2.4.1", "chokidar": "^2.0.4", - "concurrently": "^4.0.1", "js-yaml": "^3.12.0", "lodash": "^4.17.10", "minimist": "^1.2.0", @@ -3544,13 +3543,13 @@ } }, "concurrently": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-4.1.2.tgz", - "integrity": "sha512-Kim9SFrNr2jd8/0yNYqDTFALzUX1tvimmwFWxmp/D4mRI+kbqIIwE2RkBDrxS2ic25O1UgQMI5AtBqdtX3ynYg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.0.0.tgz", + "integrity": "sha512-1yDvK8mduTIdxIxV9C60KoiOySUl/lfekpdbI+U5GXaPrgdffEavFa9QZB3vh68oWOpbCC+TuvxXV9YRPMvUrA==", "dev": true, "requires": { "chalk": "^2.4.2", - "date-fns": "^1.30.1", + "date-fns": "^2.0.1", "lodash": "^4.17.15", "read-pkg": "^4.0.1", "rxjs": "^6.5.2", @@ -3579,12 +3578,6 @@ "which": "^1.2.9" } }, - "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true - }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", @@ -3678,9 +3671,9 @@ } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -3739,9 +3732,9 @@ } }, "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { "tslib": "^1.9.0" diff --git a/package.json b/package.json index 28cc53112..3fd5a8a9c 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "babel-plugin-lodash": "3.3.4", "babel-plugin-transform-react-remove-prop-types": "0.4.24", "classnames": "2.2.6", - "concurrently": "4.1.2", + "concurrently": "5.0.0", "css-loader": "3.2.0", "debug": "4.1.1", "electron": "4.2.8", From b1fe604d1a8465bf24d0b70ed6fe901f7d3cc047 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:05:29 -0400 Subject: [PATCH 02/27] Update dependency electron-rebuild to v1.8.6 (#1533) --- package-lock.json | 32 ++++++++++++++++---------------- package.json | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ff151dee..fa79349cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5095,20 +5095,20 @@ } }, "electron-rebuild": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-1.8.5.tgz", - "integrity": "sha512-gDwRA3utfiPnFwBZ1z8M4SEMwsdsy6Bg4VGO2ohelMOIO0vxiCrDQ/FVdLk3h2g7fLb06QFUsQU+86jiTSmZxw==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-1.8.6.tgz", + "integrity": "sha512-4BAPcNG0XP6stByqvFXggrjmf/C47P2L6HFFrWdR2ako1VLiTDIeZAOmU4WEBuWdaXYNqstleszVmcNHdRDojA==", "dev": true, "requires": { "colors": "^1.3.3", "debug": "^4.1.1", "detect-libc": "^1.0.3", "fs-extra": "^7.0.1", - "node-abi": "^2.8.0", - "node-gyp": "^4.0.0", + "node-abi": "^2.9.0", + "node-gyp": "^5.0.1", "ora": "^3.4.0", "spawn-rx": "^3.0.0", - "yargs": "^13.2.2" + "yargs": "^13.2.4" }, "dependencies": { "ansi-regex": { @@ -10470,18 +10470,18 @@ } }, "node-abi": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.10.0.tgz", - "integrity": "sha512-OT0WepUvYHXdki6DU8LWhEkuo3M44i2paWBYtH9qXtPb9YiKlYEKa5WUII20XEcOv7UJPzfB0kZfPZdW46zdkw==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", + "integrity": "sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==", "dev": true, "requires": { "semver": "^5.4.1" }, "dependencies": { "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } @@ -10502,17 +10502,17 @@ "dev": true }, "node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.0.3.tgz", + "integrity": "sha512-z/JdtkFGUm0QaQUusvloyYuGDub3nUbOo5de1Fz57cM++osBTvQatBUSTlF1k/w8vFHPxxXW6zxGvkxXSpaBkQ==", "dev": true, "requires": { + "env-paths": "^1.0.0", "glob": "^7.0.3", "graceful-fs": "^4.1.2", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", "request": "^2.87.0", "rimraf": "2", "semver": "~5.3.0", diff --git a/package.json b/package.json index 3fd5a8a9c..9cfff3261 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "debug": "4.1.1", "electron": "4.2.8", "electron-builder": "20.32.0", - "electron-rebuild": "1.8.5", + "electron-rebuild": "1.8.6", "enzyme": "3.10.0", "enzyme-adapter-react-16": "1.14.0", "eslint": "6.5.1", From 95829d9bcacaba8680bd44022c927f853419c684 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:06:19 -0400 Subject: [PATCH 03/27] Update dependency highlight.js to v9.15.10 (#1545) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index fa79349cc..eb1d9cf37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7705,9 +7705,9 @@ "dev": true }, "highlight.js": { - "version": "9.15.9", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.9.tgz", - "integrity": "sha512-M0zZvfLr5p0keDMCAhNBp03XJbKBxUx5AfyfufMdFMEP4N/Xj6dh0IqC75ys7BAzceR34NgcvXjupRVaHBPPVQ==" + "version": "9.15.10", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", + "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==" }, "hmac-drbg": { "version": "1.0.1", diff --git a/package.json b/package.json index 9cfff3261..1b6357fb3 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "file-saver": "2.0.2", "focus-visible": "5.0.2", "gridicons": "3.3.1", - "highlight.js": "9.15.9", + "highlight.js": "9.15.10", "isemail": "3.2.0", "js-yaml": "3.13.1", "jszip": "3.2.2", From 18d4bb829acf18494d02442f4972afee31c5cc40 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:07:37 -0400 Subject: [PATCH 04/27] Update dependency autoprefixer to v9.6.4 (#1628) --- package-lock.json | 74 ++++++++++++++++++++++++++++++++++++++++++----- package.json | 2 +- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb1d9cf37..9444b7ccb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2301,18 +2301,78 @@ } }, "autoprefixer": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz", - "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==", + "version": "9.6.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.4.tgz", + "integrity": "sha512-Koz2cJU9dKOxG8P1f8uVaBntOv9lP4yz9ffWvWaicv9gHBPhpQB22nGijwd8gqW9CNT+UdkbQOQNLVI8jN1ZfQ==", "dev": true, "requires": { - "browserslist": "^4.6.3", - "caniuse-lite": "^1.0.30000980", + "browserslist": "^4.7.0", + "caniuse-lite": "^1.0.30000998", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.17", - "postcss-value-parser": "^4.0.0" + "postcss": "^7.0.18", + "postcss-value-parser": "^4.0.2" + }, + "dependencies": { + "browserslist": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.0.tgz", + "integrity": "sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000989", + "electron-to-chromium": "^1.3.247", + "node-releases": "^1.1.29" + } + }, + "caniuse-lite": { + "version": "1.0.30000998", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000998.tgz", + "integrity": "sha512-8Tj5sPZR9kMHeDD9SZXIVr5m9ofufLLCG2Y4QwQrH18GIwG+kCc+zYdlR036ZRkuKjVVetyxeAgGA1xF7XdmzQ==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.274", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.274.tgz", + "integrity": "sha512-9bWkiXxGylowqMXoF1ec7k6akmsL2nOa1kzZ4CKzBuwK9WVz0VauE1w/RVyYraE1LpJM7+8fNCsW9b7ZSoxWIg==", + "dev": true + }, + "node-releases": { + "version": "1.1.34", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.34.tgz", + "integrity": "sha512-fNn12JTEfniTuCqo0r9jXgl44+KxRH/huV7zM/KAGOKxDKrHr6EbT7SSs4B+DNxyBE2mks28AD+Jw6PkfY5uwA==", + "dev": true, + "requires": { + "semver": "^6.3.0" + } + }, + "postcss": { + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz", + "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "aws-sign2": { diff --git a/package.json b/package.json index 1b6357fb3..7447fea21 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@babel/plugin-syntax-dynamic-import": "7.2.0", "@babel/preset-env": "7.6.2", "@babel/preset-react": "7.0.0", - "autoprefixer": "9.6.1", + "autoprefixer": "9.6.4", "babel-eslint": "10.0.3", "babel-loader": "8.0.6", "babel-plugin-dynamic-import-node": "2.3.0", From ed7902eeb89f6eb4dc6e17c09c1e6671628b6171 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:12:22 -0400 Subject: [PATCH 05/27] Update dependency react-overlays to v2 (#1620) --- package-lock.json | 128 +++++++++++----------------------------------- package.json | 2 +- 2 files changed, 30 insertions(+), 100 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9444b7ccb..d8f2ecca1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1473,6 +1473,11 @@ "nan": "^2.0.0" } }, + "@restart/hooks": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.14.tgz", + "integrity": "sha512-k57+iyGr6o1XHeWWsGe5aMHKYcw7fukL6mCE+ZrPjtt1gXei5wCUxj71yQYfFbNjg0z5xxX8Els/UmyJiEn4nw==" + }, "@types/babel__core": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz", @@ -4071,44 +4076,6 @@ "sha.js": "^2.4.8" } }, - "create-react-context": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz", - "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==", - "requires": { - "fbjs": "^0.8.0", - "gud": "^1.0.0" - }, - "dependencies": { - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" - }, - "fbjs": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", - "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - } - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - } - } - }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -7566,11 +7533,6 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, - "gud": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", - "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" - }, "handle-thing": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", @@ -11986,25 +11948,6 @@ "reflect.ownkeys": "^0.2.0" } }, - "prop-types-extra": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz", - "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==", - "requires": { - "react-is": "^16.3.2", - "warning": "^3.0.0" - }, - "dependencies": { - "warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", - "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", - "requires": { - "loose-envify": "^1.0.0" - } - } - } - }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -12241,11 +12184,6 @@ } } }, - "react-context-toolbox": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/react-context-toolbox/-/react-context-toolbox-2.0.2.tgz", - "integrity": "sha512-tY4j0imkYC3n5ZlYSgFkaw7fmlCp3IoQQ6DxpqeNHzcD0hf+6V+/HeJxviLUZ1Rv1Yn3N3xyO2EhkkZwHn0m1A==" - }, "react-dom": { "version": "16.10.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.10.1.tgz", @@ -12306,31 +12244,28 @@ "dev": true }, "react-overlays": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-1.2.0.tgz", - "integrity": "sha512-i/FCV8wR6aRaI+Kz/dpJhOdyx+ah2tN1RhT9InPrexyC4uzf3N4bNayFTGtUeQVacj57j1Mqh1CwV60/5153Iw==", - "requires": { - "classnames": "^2.2.6", - "dom-helpers": "^3.4.0", - "prop-types": "^15.6.2", - "prop-types-extra": "^1.1.0", - "react-context-toolbox": "^2.0.2", - "react-popper": "^1.3.2", - "uncontrollable": "^6.0.0", - "warning": "^4.0.2" - } - }, - "react-popper": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz", - "integrity": "sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-2.0.0.tgz", + "integrity": "sha512-eY9YxhvI/dc1D+pUtfR53jxINrAFInNW2rr5SQEa/X8F/nyrIqvUvGqSrZL4V4ENiTnusgrswMm3a1T9IZM6cQ==", "requires": { - "@babel/runtime": "^7.1.2", - "create-react-context": "<=0.2.2", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", - "warning": "^4.0.2" + "@babel/runtime": "^7.4.5", + "@restart/hooks": "^0.3.12", + "dom-helpers": "^5.1.0", + "popper.js": "^1.15.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.0.0", + "warning": "^4.0.3" + }, + "dependencies": { + "dom-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.0.tgz", + "integrity": "sha512-zRRYDhpiKuAJHasOqCm7lBnsd22nrM4+OYI4ASWCxen+ocTMl7BIAKgGag97TlLiTl6rrau5aPe1VGUm9jQBng==", + "requires": { + "@babel/runtime": "^7.5.5", + "csstype": "^2.6.6" + } + } } }, "react-redux": { @@ -14789,11 +14724,6 @@ "mime-types": "~2.1.24" } }, - "typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" - }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -14868,9 +14798,9 @@ } }, "uncontrollable": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.2.3.tgz", - "integrity": "sha512-VgOAoBU2ptCL2bfTG2Mra0I8i1u6Aq84AFonD5tmCAYSfs3hWvr2Rlw0q2ntoxXTHjcQOmZOh3FKaN+UZVyREQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.0.1.tgz", + "integrity": "sha512-MGlbii7jczJYfY2GbmZi4j1JmB/6giM0Xc/WcKfxEN5W86KS8NPH/Fq/AD1nKjiFEMq7/MRwTCtzKWCeYgiWMA==", "requires": { "@babel/runtime": "^7.4.5", "invariant": "^2.2.4" diff --git a/package.json b/package.json index 7447fea21..498bbd9dd 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "react-dom": "16.10.1", "react-dropzone": "10.1.9", "react-modal": "3.10.1", - "react-overlays": "1.2.0", + "react-overlays": "2.0.0", "react-redux": "7.1.1", "react-tabs": "3.0.0", "react-transition-group": "4.3.0", From 57bc1a41be7271ea53bbb8218069f5111affbcd7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:45:14 -0400 Subject: [PATCH 06/27] Update dependency react-dropzone to v10.1.10 (#1630) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index d8f2ecca1..097be46da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12207,9 +12207,9 @@ } }, "react-dropzone": { - "version": "10.1.9", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-10.1.9.tgz", - "integrity": "sha512-7iqALZ0mzk+4g/AsYxEy3QyWPMTVQYKQVkYUe9zIbH18u+pi7EBDg010KEwfIX6jeTDH2qP0E6/eUnXvBYrovA==", + "version": "10.1.10", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-10.1.10.tgz", + "integrity": "sha512-vcLBdkYo7wgZpw1o4cz7uk8/Mmm+sYHeiTfFSshA/EGthz/TjjrTOrKwvFHm3o1p1LPk+x+KbDDlw5OeIo6eYA==", "requires": { "attr-accept": "^1.1.3", "file-selector": "^0.1.11", diff --git a/package.json b/package.json index 498bbd9dd..249545dce 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "react": "16.10.1", "react-addons-update": "15.6.2", "react-dom": "16.10.1", - "react-dropzone": "10.1.9", + "react-dropzone": "10.1.10", "react-modal": "3.10.1", "react-overlays": "2.0.0", "react-redux": "7.1.1", From 5910eb03a51f0c65b62865beb7b64b8c390c8953 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:46:29 -0400 Subject: [PATCH 07/27] Update dependency eslint-config-prettier to v6.4.0 (#1629) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 097be46da..a9d6ffb55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5740,9 +5740,9 @@ } }, "eslint-config-prettier": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.3.0.tgz", - "integrity": "sha512-EWaGjlDAZRzVFveh2Jsglcere2KK5CJBhkNSa1xs3KfMUGdRiT7lG089eqPdvlzWHpAqaekubOsOMu8W8Yk71A==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.4.0.tgz", + "integrity": "sha512-YrKucoFdc7SEko5Sxe4r6ixqXPDP1tunGw91POeZTTRKItf/AMFYt/YLEQtZMkR2LVpAVhcAcZgcWpm1oGPW7w==", "dev": true, "requires": { "get-stdin": "^6.0.0" diff --git a/package.json b/package.json index 249545dce..d0b4c5adb 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "enzyme": "3.10.0", "enzyme-adapter-react-16": "1.14.0", "eslint": "6.5.1", - "eslint-config-prettier": "6.3.0", + "eslint-config-prettier": "6.4.0", "eslint-plugin-jest": "22.17.0", "eslint-plugin-prettier": "3.1.1", "eslint-plugin-react": "7.15.1", From 7ccd470dafe2f94c4700d30f259db640d55cacd4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:48:51 -0400 Subject: [PATCH 08/27] Update dependency eslint-plugin-react to v7.16.0 (#1623) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9d6ffb55..2e8d37761 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5775,9 +5775,9 @@ } }, "eslint-plugin-react": { - "version": "7.15.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.15.1.tgz", - "integrity": "sha512-YotSItgMPwLGlr3df44MGVyXnHkmKcpkHTzpte3QwJtocr3nFqCXCuoxFZeBtnT8RHdj038NlTvam3dcAFrMcA==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.16.0.tgz", + "integrity": "sha512-GacBAATewhhptbK3/vTP09CbFrgUJmBSaaRcWdbQLFvUZy9yVcQxigBNHGPU/KE2AyHpzj3AWXpxoMTsIDiHug==", "dev": true, "requires": { "array-includes": "^3.0.3", diff --git a/package.json b/package.json index d0b4c5adb..975a3c9c1 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-config-prettier": "6.4.0", "eslint-plugin-jest": "22.17.0", "eslint-plugin-prettier": "3.1.1", - "eslint-plugin-react": "7.15.1", + "eslint-plugin-react": "7.16.0", "fake-indexeddb": "2.1.1", "hard-source-webpack-plugin": "0.13.1", "html-webpack-plugin": "3.2.0", From 9e6df65f563976517a80ec6dad6980d5a6e0cf0b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 12:53:12 -0400 Subject: [PATCH 09/27] Update react monorepo to v16.10.2 (#1621) --- package-lock.json | 34 +++++++++++++++++----------------- package.json | 6 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e8d37761..6ef6fb089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12137,9 +12137,9 @@ } }, "react": { - "version": "16.10.1", - "resolved": "https://registry.npmjs.org/react/-/react-16.10.1.tgz", - "integrity": "sha512-2bisHwMhxQ3XQz4LiJJwG3360pY965pTl/MRrZYxIBKVj4fOHoDs5aZAkYXGxDRO1Li+SyjTAilQEbOmtQJHzA==", + "version": "16.10.2", + "resolved": "https://registry.npmjs.org/react/-/react-16.10.2.tgz", + "integrity": "sha512-MFVIq0DpIhrHFyqLU0S3+4dIcBhhOvBE8bJ/5kHPVOVaGdo0KuiQzpcjCPsf585WvhypqtrMILyoE2th6dT+Lw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -12185,20 +12185,20 @@ } }, "react-dom": { - "version": "16.10.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.10.1.tgz", - "integrity": "sha512-SmM4ZW0uug0rn95U8uqr52I7UdNf6wdGLeXDmNLfg3y5q5H9eAbdjF5ubQc3bjDyRrvdAB2IKG7X0GzSpnn5Mg==", + "version": "16.10.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.10.2.tgz", + "integrity": "sha512-kWGDcH3ItJK4+6Pl9DZB16BXYAZyrYQItU4OMy0jAkv5aNqc+mAKb4TpFtAteI6TJZu+9ZlNhaeNQSVQDHJzkw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.16.1" + "scheduler": "^0.16.2" }, "dependencies": { "scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-MIuie7SgsqMYOdCXVFZa8SKoNorJZUWHW8dPgto7uEHn1lX3fg2Gu0TzgK8USj76uxV7vB5eRMnZs/cdEHg+cg==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -12298,15 +12298,15 @@ } }, "react-test-renderer": { - "version": "16.10.1", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.10.1.tgz", - "integrity": "sha512-VT8nd7XrrUV7MQPxeIuH7WstfrK2A8kgcMwGUtVXa0ja+CiYkxdmLYNjwX1L7irRF7ydzJJWiSLsQf2xBj4Xaw==", + "version": "16.10.2", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.10.2.tgz", + "integrity": "sha512-k9Qzyev6cTIcIfrhgrFlYQAFxh5EEDO6ALNqYqmKsWVA7Q/rUMTay5nD3nthi6COmYsd4ghVYyi8U86aoeMqYQ==", "dev": true, "requires": { "object-assign": "^4.1.1", "prop-types": "^15.6.2", "react-is": "^16.8.6", - "scheduler": "^0.16.1" + "scheduler": "^0.16.2" } }, "react-transition-group": { @@ -13181,9 +13181,9 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-MIuie7SgsqMYOdCXVFZa8SKoNorJZUWHW8dPgto7uEHn1lX3fg2Gu0TzgK8USj76uxV7vB5eRMnZs/cdEHg+cg==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-BqYVWqwz6s1wZMhjFvLfVR5WXP7ZY32M/wYPo04CcuPM7XZEbV2TBNW7Z0UkguPTl0dWMA59VbNXxK6q+pHItg==", "dev": true, "requires": { "loose-envify": "^1.1.0", diff --git a/package.json b/package.json index 975a3c9c1..c1829942f 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "postcss-loader": "3.0.0", "prettier": "1.18.2", "react-onclickoutside": "6.9.0", - "react-test-renderer": "16.10.1", + "react-test-renderer": "16.10.2", "sass-loader": "8.0.0", "style-loader": "1.0.0", "wait-on": "3.3.0", @@ -109,9 +109,9 @@ "promise": "8.0.3", "prop-types": "15.7.2", "randombytes": "2.1.0", - "react": "16.10.1", + "react": "16.10.2", "react-addons-update": "15.6.2", - "react-dom": "16.10.1", + "react-dom": "16.10.2", "react-dropzone": "10.1.10", "react-modal": "3.10.1", "react-overlays": "2.0.0", From ec12a926cb72b93c0431602da81002c0c99e397f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 7 Oct 2019 15:05:15 -0400 Subject: [PATCH 10/27] Update dependency electron to v4.2.11 (#1483) --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ef6fb089..4753e8111 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4768,9 +4768,9 @@ "dev": true }, "electron": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/electron/-/electron-4.2.8.tgz", - "integrity": "sha512-/D9zfs+EWLN4yLV7tu2kWyXUnZQ3CKG1cmWbXeSFXF+0dNXQ8iFpY49dqZRoHGIBImFfp2x4N3Zc5Tu7rw3PJw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/electron/-/electron-4.2.11.tgz", + "integrity": "sha512-7tYrmvQaatP5A4OwcBx+zjvPBarrtsnXKM65338QH3ifblrAt64DnL7B2dnE0Anb8pehCayMLd3YRvbLRyV1hQ==", "dev": true, "requires": { "@types/node": "^10.12.18", @@ -5038,9 +5038,9 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } diff --git a/package.json b/package.json index c1829942f..e21c916bd 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "concurrently": "5.0.0", "css-loader": "3.2.0", "debug": "4.1.1", - "electron": "4.2.8", + "electron": "4.2.11", "electron-builder": "20.32.0", "electron-rebuild": "1.8.6", "enzyme": "3.10.0", From cab76ef5c10af07f5da18d08ef311b434aff8b90 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sun, 13 Oct 2019 16:27:54 -0700 Subject: [PATCH 11/27] Refactor tag operations to stop directly mutating tag objects (#1638) See #1614 As part of a broader effort to resolve data-flow issues in the app this PR is a first step in removing direct mutation where transactional atomic updates should be occurring. It's not clear if the existing code is the source of existing defects in the software and this is part of why the code is problematic; we have created inherent concurrency flaws that open up extremely-difficult-to-reproduce bugs. Resolving this may or may not resolve any existing bugs but it will definitely help guard us from introducing new ones. --- Previously we have been directly mutating note and tag objects when editing those tags. This mutation can lead to concurrency defects which expose themselves as inconsistent UI state. This breaks our Redux model which assumes that all UI updates happen atomically. In this patch we're building new note objects and tag objects when we make these updates in order to maintain our consistency. --- There should be no significant visual or behavioral changes with this PR. We are changing code related to removing tags, renaming tags, and reordering tags. In testing verify that with separate sessions the updates appear as expected. Add, reorder, and remove tags to make sure the changes synchronize. --- lib/state/domain/tags.js | 71 ++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/lib/state/domain/tags.js b/lib/state/domain/tags.js index 8858058ea..0fdb53ba2 100644 --- a/lib/state/domain/tags.js +++ b/lib/state/domain/tags.js @@ -28,54 +28,47 @@ export const createTag = ({ name }) => { tagBucket().update(tagId, { name }); }; -export const reorderTags = ({ tags }) => () => { - for (let i = 0; i < tags.length; i++) { - let tag = tags[i]; - tag.data.index = i; - tagBucket().update(tag.id, tag.data); - } -}; +export const reorderTags = ({ tags }) => () => + tags.forEach((tag, index) => + tagBucket().update(tag.id, { ...tag.data, index }) + ); + +export const renameTag = ({ tag, name: newName }) => (dispatch, getState) => { + const { notes } = getState().appState; + const tagName = tag.data.name; -export const renameTag = ({ tag, name }) => (dispatch, getState) => { - let oldTagName = tag.data.name; - if (oldTagName === name) { + if (tagName === newName) { return; } - let { notes } = getState().appState; - - tag.data.name = name; - - tagBucket().update(tag.id, tag.data); + tagBucket().update(tag.id, { ...tag.data, name: newName }); - // Replace tags in notes - for (let i = 0; i < notes.length; i++) { - let note = notes[i]; - let noteTags = note.data.tags || []; - let tagIndex = noteTags.indexOf(oldTagName); - - if (tagIndex !== -1) { - noteTags.splice(tagIndex, 1, name); - note.data.tags = noteTags.filter(noteTag => noteTag !== oldTagName); - noteBucket().update(note.id, note.data); - } - } + notes + .filter(({ data: { tags } }) => (tags || []).includes(tagName)) + .map(note => ({ + ...note, + data: { + ...note.data, + tags: note.data.tags.map(tag => (tag === tagName ? name : tag)), + }, + })) + .forEach(note => noteBucket().update(note.id, note.data)); }; export const trashTag = ({ tag }) => (dispatch, getState) => { - var { notes } = getState().appState; - var tagName = tag.data.name; + const { notes } = getState().appState; + const tagName = tag.data.name; - for (let i = 0; i < notes.length; i++) { - let note = notes[i]; - let noteTags = note.data.tags || []; - let newTags = noteTags.filter(noteTag => noteTag !== tagName); - - if (newTags.length !== noteTags.length) { - note.data.tags = newTags; - noteBucket().update(note.id, note.data); - } - } + notes + .filter(({ data: { tags } }) => (tags || []).includes(tagName)) + .map(note => ({ + ...note, + data: { + ...note.data, + tags: note.data.tags.filter(tag => tag !== tagName), + }, + })) + .forEach(note => noteBucket().update(note.id, note.data)); tagBucket().remove(tag.id, () => dispatch(loadTags())); }; From 3a31728f55beab36eac81864691cc4c7ca19214a Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sun, 13 Oct 2019 16:28:43 -0700 Subject: [PATCH 12/27] Refactor updating note content to stop directly mutating note object (#1634) See #1614 As part of a broader effort to resolve data-flow issues in the app this PR is a first step in removing direct mutation where transactional atomic updates should be occurring. It's not clear if the existing code is the source of existing defects in the software and this is part of why the code is problematic; we have created inherent concurrency flaws that open up extremely-difficult-to-reproduce bugs. Resolving this may or may not resolve any existing bugs but it will definitely help guard us from introducing new ones. --- Previously we have been directly mutating the note object when updating its content. This may have been an attempt to work around confusing data-flow issues that thankfully don't exist anymore. We have also been performing inline checks to make sure that we update the editor's contents if we receive these updates. This mutation can lead to concurrency defects which expose themselves as inconsistent UI state. This breaks our Redux model which assumes that all UI updates happen atomically. In this patch we're building a new note object when we update a note in order to maintain our consistency. In light of #1598 we're also removing some work-around code that attempted to force consistency when it didn't exist; that consistency now exists since we're tracking the underlying Simperium data closely now vs. storing it in separate places. When updating checklist items we're forcing a sync so that those changes will propagate immediately. We don't have a need to debounce those clicks. --- lib/app.jsx | 28 ++++++++++++++++++++++------ lib/flux/app-state.js | 24 ------------------------ lib/note-detail/index.jsx | 22 ++++++++++------------ 3 files changed, 32 insertions(+), 42 deletions(-) diff --git a/lib/app.jsx b/lib/app.jsx index 6fb0ca6b9..b9e8dfbd7 100644 --- a/lib/app.jsx +++ b/lib/app.jsx @@ -320,12 +320,28 @@ export const App = connect( }); }; - onUpdateContent = (note, content) => - this.props.actions.updateNoteContent({ - noteBucket: this.props.noteBucket, - note, - content, - }); + onUpdateContent = (note, content) => { + if (!note) { + return; + } + + const updatedNote = { + ...note, + data: { + ...note.data, + content, + modificationDate: Math.floor(Date.now() / 1000), + }, + }; + + // update the bucket but don't force sync right away + // as this happens per keystroke when the user is editing + // a note. The NoteEditor will notify via props when + // it's time to sync via Simperium + const { noteBucket } = this.props; + + noteBucket.update(note.id, updatedNote.data, {}, { sync: false }); + }; syncNote = noteId => { this.props.noteBucket.touch(noteId); diff --git a/lib/flux/app-state.js b/lib/flux/app-state.js index 76218d4d0..39377d95b 100644 --- a/lib/flux/app-state.js +++ b/lib/flux/app-state.js @@ -404,8 +404,6 @@ export const actionMap = new ActionMap({ return; } - state.note.data = data; - dispatch( this.action('loadAndSelectNote', { noteBucket, @@ -439,28 +437,6 @@ export const actionMap = new ActionMap({ }, }, - updateNoteContent: { - creator({ noteBucket, note, content }) { - return (dispatch, getState) => { - if (note) { - note.data.content = content; - note.data.modificationDate = Math.floor(Date.now() / 1000); - - // update the bucket don't sync right away - // as this happens per keystroke when the user is editing - // a note. The NoteEditor notify via props when its time - // to sync via Simperium - noteBucket.update(note.id, note.data, {}, { sync: false }); - - // Check if note is still selected (to avoid race conditions) - if (get(getState().appState, 'note.id') === note.id) { - dispatch(this.action('selectNote', { note })); - } - } - }; - }, - }, - trashNote: { creator({ noteBucket, note, previousIndex }) { return dispatch => { diff --git a/lib/note-detail/index.jsx b/lib/note-detail/index.jsx index dc1f01ae8..f5ba5a9ec 100644 --- a/lib/note-detail/index.jsx +++ b/lib/note-detail/index.jsx @@ -33,7 +33,6 @@ export class NoteDetail extends Component { spellCheckEnabled: PropTypes.bool.isRequired, storeFocusEditor: PropTypes.func, storeHasFocus: PropTypes.func, - updateNoteContent: PropTypes.func.isRequired, }; static defaultProps = { @@ -130,6 +129,8 @@ export class NoteDetail extends Component { hasFocus = () => this.editorHasFocus && this.editorHasFocus(); onPreviewClick = event => { + const { note, onChangeContent, syncNote } = this.props; + for (let node = event.target; node !== null; node = node.parentNode) { // open markdown preview links in a new window if (node.tagName === 'A') { @@ -137,18 +138,16 @@ export class NoteDetail extends Component { viewExternalUrl(node.href); break; } + // handle task list items if (node.className === 'task-list-item') { event.preventDefault(); - const { note, noteBucket, updateNoteContent } = this.props; - toggleTask({ - taskNode: node, - text: note.data.content, - }) - .then(newNoteContent => { - updateNoteContent({ noteBucket, note, content: newNoteContent }); - }) - .catch(console.log); + toggleTask({ taskNode: node, text: note.data.content }).then( + newContent => { + onChangeContent(note, newContent); + syncNote(note.id); + } + ); break; } } @@ -258,11 +257,10 @@ const mapStateToProps = ({ appState: state, settings }) => ({ spellCheckEnabled: settings.spellCheckEnabled, }); -const { setShouldPrintNote, updateNoteContent } = appState.actionCreators; +const { setShouldPrintNote } = appState.actionCreators; const mapDispatchToProps = { onNotePrinted: () => setShouldPrintNote({ shouldPrint: false }), - updateNoteContent, }; export default connect( From 3354b7fbb3475e9f92f2d590b25b0f75dffce107 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sun, 13 Oct 2019 16:29:14 -0700 Subject: [PATCH 13/27] Refactor note tag operation to stop directly mutating note object (#1639) See #1614 As part of a broader effort to resolve data-flow issues in the app this PR is a first step in removing direct mutation where transactional atomic updates should be occurring. It's not clear if the existing code is the source of existing defects in the software and this is part of why the code is problematic; we have created inherent concurrency flaws that open up extremely-difficult-to-reproduce bugs. Resolving this may or may not resolve any existing bugs but it will definitely help guard us from introducing new ones. --- Previously we have been directly mutating note objects when editing their tags. This mutation can lead to concurrency defects which expose themselves as inconsistent UI state. This breaks our Redux model which assumes that all UI updates happen atomically. In this patch we're building new note objects when we make these updates in order to maintain our consistency. --- There should be no significant visual or behavioral changes with this PR. We are changing code related to removing tags, renaming tags, and reordering tags. In testing verify that with separate sessions the updates appear as expected. Add, reorder, and remove tags to make sure the changes synchronize. --- lib/state/domain/notes.js | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/lib/state/domain/notes.js b/lib/state/domain/notes.js index 7f369f0f4..ff4624689 100644 --- a/lib/state/domain/notes.js +++ b/lib/state/domain/notes.js @@ -3,33 +3,25 @@ import appState from '../../flux/app-state'; import isEmailTag from '../../utils/is-email-tag'; import { createTag } from './tags'; -const { selectNote } = appState.actionCreators; - export const updateNoteTags = ({ note, tags }) => { return (dispatch, getState) => { - if (note) { - let state = getState().appState; - - note.data.tags = tags; - note.data.modificationDate = Math.floor(Date.now() / 1000); - noteBucket().update(note.id, note.data); - - dispatch(selectNote({ note })); - - let currentTagNames = state.tags.map(tag => tag.data.name); - for (let i = 0; i < tags.length; i++) { - let tag = tags[i]; + if (!note) { + return; + } - if (currentTagNames.indexOf(tag) !== -1) { - continue; - } + noteBucket().update(note.id, { + ...note.data, + tags, + modificationDate: Math.floor(Date.now() / 1000), + }); - if (isEmailTag(tag)) { - continue; - } + const existingTagNames = new Set( + getState().appState.tags.map(tag => tag.data.name) + ); - createTag({ name: tag }); - } - } + tags + .filter(name => !existingTagNames.has(name)) + .filter(name => !isEmailTag(name)) + .forEach(name => createTag({ name })); }; }; From 2b6eb87252af00ddabc2d79cedbffebed7ee9b02 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Sun, 13 Oct 2019 16:31:51 -0700 Subject: [PATCH 14/27] Fix: Broken oAuth flow (#1627) We have been experiencing problems when trying to login with the WordPress.com signin. Something appears to have changed in Electron such that the older versions of the app still work but newer versions are failing. In this patch we're rewriting the authentication flow to simplify it and prepare ourselves for better handling of the failure cases. In production we are seeing strange behaviors on failure and some on success: unending re-requests to `simplenote://auth` which trigger full CPU load; and no response after authentication. After this patch we should be able to wrangle in errors and add a timeout to better communicate when things are failing. Additionally, the unending loop should be closed due to a replacement of the old network intercept code with a single simplified model. We have also been sharing sessions between the main window and the auth window and also sharing sessions between teach time the auth window appears. This leads to leaked cookies and can result in confusing flows, largely because of the shared cookies. In this patch we're creating a new `Session` for the auth window every time we open it. By not including `persist:` in the "partition" name we're making sure it only exists in memory. By introducing randomness into its name we're making sure we don't share the same session from one auth attempt to the next. By freeing the window after close we're making sure we don't leak memory. Previously we were able to open the auth window after closing it and instead of logging in again it would open to the "Accept/Deny" view. After this change it requires logging in on every attempt. This will likely be more frustrating but much safer than the previous behavior. --- RELEASE-NOTES.txt | 6 +++ lib/auth/index.jsx | 121 +++++++++++++++++++++------------------------ 2 files changed, 61 insertions(+), 66 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index b5c9348bf..9b0eebbe8 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,5 +1,11 @@ # Changelog +## Future release + +### Fixes + + - Rework WordPress.com signin to prevent infinite looping and login failures [#1627](https://github.com/Automattic/simplenote-electron/pull/1627) + ## [v1.9.0] ### Enhancements diff --git a/lib/auth/index.jsx b/lib/auth/index.jsx index c01e2c19a..84524b5a2 100644 --- a/lib/auth/index.jsx +++ b/lib/auth/index.jsx @@ -216,84 +216,73 @@ export class Auth extends Component { }; setupAuthWindow = () => { - const remote = __non_webpack_require__('electron').remote; // eslint-disable-line no-undef - const BrowserWindow = remote.BrowserWindow; - const protocol = remote.protocol; + // eslint-disable-next-line no-undef + const { BrowserWindow, session } = __non_webpack_require__( + 'electron' + ).remote; + this.authWindow = new BrowserWindow({ width: 640, height: 640, show: false, webPreferences: { nodeIntegration: false, + session: session.fromPartition(`fresh-session-${Math.random()}`), }, }); - // Register simplenote:// protocol - protocol.registerHttpProtocol('simplenote', req => { - this.authWindow.loadURL(req.url); + this.authWindow.on('closed', () => { + // make sure to release this from memory + this.authWindow = null; }); - this.authWindow.webContents.on('will-navigate', (event, url) => - this.onBrowserNavigate(url) - ); - - this.authWindow.webContents.on( - 'did-get-redirect-request', - (event, oldUrl, newUrl) => this.onBrowserNavigate(newUrl) - ); - }; - - onBrowserNavigate = url => { - try { - this.authenticateWithUrl(new URL(url)); - } catch (error) { - // Do nothing if Url was invalid - } - }; - - authenticateWithUrl = url => { - // Bail out if the url is not the simplenote protocol - if (url.protocol !== 'simplenote:') { - return; - } - - const { authorizeUserWithToken, saveWPToken } = this.props; - const params = url.searchParams; - - // Display an error message if authorization failed. - if (params.get('error')) { - switch (params.get('code')) { - case '1': - return this.authError( - 'Please activate your WordPress.com account via email and try again.' - ); - default: - return this.authError('An error was encountered while signing in.'); + this.authWindow.webContents.session.protocol.registerHttpProtocol( + 'simplenote', + (req, callback) => { + const { searchParams } = new URL(req.url); + + // cancel the request by running callback() with no parameters + // we're going to close the window and continue processing the + // information we received in args of the simplenote://auth URL + callback(); + + const errorCode = searchParams.get('error') + ? searchParams.get('code') + : false; + const authState = searchParams.get('state'); + const userEmail = searchParams.get('user'); + const simpToken = searchParams.get('token'); + const wpccToken = searchParams.get('wp_token'); + + // Display an error message if authorization failed. + switch (errorCode) { + case false: + break; + case '1': + return this.authError( + 'Please activate your WordPress.com account via email and try again.' + ); + case '2': + return this.authError( + 'Please confirm your account with the confirmation email before signing in to Simplenote.' + ); + default: + return this.authError('An error was encountered while signing in.'); + } + + this.closeAuthWindow(); + + if (authState !== this.authState) { + return; + } + + const { authorizeUserWithToken, saveWPToken } = this.props; + authorizeUserWithToken(userEmail, simpToken); + if (wpccToken) { + saveWPToken(wpccToken); + } } - } - - const userEmail = params.get('user'); - const spToken = params.get('token'); - const state = params.get('state'); - - // Sanity check on params - if (!(spToken && userEmail && state)) { - return this.closeAuthWindow(); - } - - // Verify that the state strings match - if (state !== this.authState) { - return; - } - - authorizeUserWithToken(userEmail, spToken); - - const wpToken = params.get('wp_token'); - if (wpToken) { - saveWPToken(wpToken); - } - - this.closeAuthWindow(); + ); }; authError = errorMessage => { From 7e6c067a891b12691c1929aabfd2f2a799e59a30 Mon Sep 17 00:00:00 2001 From: Jonathan Belcher Date: Wed, 16 Oct 2019 09:53:29 -0700 Subject: [PATCH 15/27] Make system setting the default theme preference (#1581) * Make system setting the default theme preference * Update Release Notes * Make system the first item in the list * Update system theme logic --- RELEASE-NOTES.txt | 4 ++++ lib/app.jsx | 16 ++++++++++++++-- lib/dialogs/settings-group.jsx | 4 +++- lib/dialogs/settings/panels/display.jsx | 3 +++ lib/state/settings/reducer.js | 2 +- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 9b0eebbe8..bf9d837b0 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -2,6 +2,10 @@ ## Future release +### Enhancements + + - Add ability to select system as a theme option and make it the default + ### Fixes - Rework WordPress.com signin to prevent infinite looping and login failures [#1627](https://github.com/Automattic/simplenote-electron/pull/1627) diff --git a/lib/app.jsx b/lib/app.jsx index b9e8dfbd7..b51f04b54 100644 --- a/lib/app.jsx +++ b/lib/app.jsx @@ -309,8 +309,20 @@ export const App = connect( preferencesBucket: this.props.preferencesBucket, }); + getSystemColorMode = () => + window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'dark' + : 'light'; + + getTheme = () => { + const { + settings: { theme }, + } = this.props; + return 'system' === theme ? this.getSystemColorMode() : theme; + }; + initializeElectron = () => { - const remote = __non_webpack_require__('electron').remote; // eslint-disable-line no-undef + const { remote } = __non_webpack_require__('electron'); // eslint-disable-line no-undef this.setState({ electron: { @@ -404,7 +416,7 @@ export const App = connect( } = this.props; const isMacApp = isElectronMac(); - const themeClass = `theme-${settings.theme}`; + const themeClass = `theme-${this.getTheme()}`; const appClasses = classNames('app', themeClass, { 'is-line-length-full': settings.lineLength === 'full', diff --git a/lib/dialogs/settings-group.jsx b/lib/dialogs/settings-group.jsx index 5aa2dc776..0749c0a1c 100644 --- a/lib/dialogs/settings-group.jsx +++ b/lib/dialogs/settings-group.jsx @@ -27,11 +27,13 @@ export const SettingsGroup = ({ ); + const childElements = React.Children.toArray(children).filter(o => o); + return (
{groupTitle}
- {React.Children.map(children, ({ props: { slug, title } }) => ( + {childElements.map(({ props: { slug, title } }) => (