Merge pull request #4975 from LLK/release/2021-02-10

[Master] Release 2021-02-10
This commit is contained in:
Eric Rosenbaum 2021-02-11 11:09:24 -05:00 committed by GitHub
commit d8cd6bb030
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 178 additions and 79 deletions

145
package-lock.json generated
View file

@ -95,9 +95,9 @@
} }
}, },
"fsevents": { "fsevents": {
"version": "2.3.1", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true, "dev": true,
"optional": true "optional": true
}, },
@ -258,9 +258,9 @@
} }
}, },
"@babel/generator": { "@babel/generator": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
"integrity": "sha512-9qQ8Fgo8HaSvHEt6A5+BATP7XktD/AdAnObUeTRz5/e2y3kbrxZgz32qUJJsdmwUvBJzF4AeV21nGTNwv05Mpw==", "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/types": "^7.12.13", "@babel/types": "^7.12.13",
@ -309,9 +309,9 @@
} }
}, },
"@babel/parser": { "@babel/parser": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
"integrity": "sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw==", "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
"dev": true "dev": true
}, },
"@babel/template": { "@babel/template": {
@ -601,9 +601,9 @@
} }
}, },
"@babel/generator": { "@babel/generator": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
"integrity": "sha512-9qQ8Fgo8HaSvHEt6A5+BATP7XktD/AdAnObUeTRz5/e2y3kbrxZgz32qUJJsdmwUvBJzF4AeV21nGTNwv05Mpw==", "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/types": "^7.12.13", "@babel/types": "^7.12.13",
@ -652,9 +652,9 @@
} }
}, },
"@babel/parser": { "@babel/parser": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
"integrity": "sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw==", "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
"dev": true "dev": true
}, },
"@babel/template": { "@babel/template": {
@ -840,9 +840,9 @@
} }
}, },
"@babel/generator": { "@babel/generator": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
"integrity": "sha512-9qQ8Fgo8HaSvHEt6A5+BATP7XktD/AdAnObUeTRz5/e2y3kbrxZgz32qUJJsdmwUvBJzF4AeV21nGTNwv05Mpw==", "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/types": "^7.12.13", "@babel/types": "^7.12.13",
@ -891,9 +891,9 @@
} }
}, },
"@babel/parser": { "@babel/parser": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
"integrity": "sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw==", "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
"dev": true "dev": true
}, },
"@babel/template": { "@babel/template": {
@ -1087,9 +1087,9 @@
} }
}, },
"@babel/generator": { "@babel/generator": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
"integrity": "sha512-9qQ8Fgo8HaSvHEt6A5+BATP7XktD/AdAnObUeTRz5/e2y3kbrxZgz32qUJJsdmwUvBJzF4AeV21nGTNwv05Mpw==", "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/types": "^7.12.13", "@babel/types": "^7.12.13",
@ -1138,9 +1138,9 @@
} }
}, },
"@babel/parser": { "@babel/parser": {
"version": "7.12.13", "version": "7.12.15",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.13.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
"integrity": "sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw==", "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
"dev": true "dev": true
}, },
"@babel/template": { "@babel/template": {
@ -1319,9 +1319,9 @@
"dev": true "dev": true
}, },
"@babel/runtime": { "@babel/runtime": {
"version": "7.12.5", "version": "7.12.13",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.13.tgz",
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "integrity": "sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw==",
"dev": true, "dev": true,
"requires": { "requires": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
@ -1441,17 +1441,26 @@
} }
}, },
"@formatjs/intl-locale": { "@formatjs/intl-locale": {
"version": "2.4.13", "version": "2.4.14",
"resolved": "https://registry.npmjs.org/@formatjs/intl-locale/-/intl-locale-2.4.13.tgz", "resolved": "https://registry.npmjs.org/@formatjs/intl-locale/-/intl-locale-2.4.14.tgz",
"integrity": "sha512-hrglCuFjRpMrutmuL+Ck84KBxeHhouk7d5B/G9kqHL4zmrW6AsBwU+0KeyvareiY3MWzYZhQj1Nm3JEGulQRUQ==", "integrity": "sha512-BWjAx+1kiN2VvQvx2L41cv8gr40mBDA78PKhVKLq+cPeAp8lwMmnGWUYr1sUXNew31N1acb6fqNJUD5sBGB/wQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@formatjs/ecma402-abstract": "1.5.1", "@formatjs/ecma402-abstract": "1.5.2",
"@formatjs/intl-getcanonicallocales": "1.5.3", "@formatjs/intl-getcanonicallocales": "1.5.3",
"cldr-core": "38", "cldr-core": "38",
"tslib": "^2.0.1" "tslib": "^2.0.1"
}, },
"dependencies": { "dependencies": {
"@formatjs/ecma402-abstract": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.5.2.tgz",
"integrity": "sha512-rscxoLyIwH2x+l15Z4eD580ioO3CkFVoWDLgDtgiOnWzDzpL5EigDRg9V4mINb8W6bQRT1xnCxiRwvw3bgvqrA==",
"dev": true,
"requires": {
"tslib": "^2.0.1"
}
},
"tslib": { "tslib": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
@ -4709,9 +4718,9 @@
"dev": true "dev": true
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001183", "version": "1.0.30001185",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001183.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz",
"integrity": "sha512-7JkwTEE1hlRKETbCFd8HDZeLiQIUcl8rC6JgNjvHCNaxOeNmQ9V4LvQXRUsKIV2CC73qKxljwVhToaA3kLRqTw==", "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==",
"dev": true "dev": true
}, },
"canvas-fit": { "canvas-fit": {
@ -4974,9 +4983,9 @@
"dev": true "dev": true
}, },
"cldr-core": { "cldr-core": {
"version": "38.0.0", "version": "38.1.0",
"resolved": "https://registry.npmjs.org/cldr-core/-/cldr-core-38.0.0.tgz", "resolved": "https://registry.npmjs.org/cldr-core/-/cldr-core-38.1.0.tgz",
"integrity": "sha512-WkjA4zo5rLT/BWTZAxHJ0lJXwI33gCYucEz1+CpoI8Wu+rr5IrC57wyNXyrNNMdxfDE5RsWi/JCQ9qnG8sHTiw==", "integrity": "sha512-Da9xKjDp4qGGIX0VDsBqTan09iR5nuYD2a/KkfEaUyqKhu6wFVNRiCpPDXeRbpVwPBY6PgemV8WiHatMhcpy4A==",
"dev": true "dev": true
}, },
"clean-css": { "clean-css": {
@ -24168,9 +24177,9 @@
} }
}, },
"scratch-blocks": { "scratch-blocks": {
"version": "0.1.0-prerelease.20210202033410", "version": "0.1.0-prerelease.20210210034743",
"resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.20210202033410.tgz", "resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.20210210034743.tgz",
"integrity": "sha512-kIr+BpasQkMq7Slv8U7QMlqumQNYHGUdlUc5T6JiK2825pvcyDYaVQBnOIEYqpS2jPYZ6CGPiSTeSUlfTSRiBQ==", "integrity": "sha512-7yU1wkgDbQl72o3NaS767GCAMCYaZkrBT9XPWJejFCzORJJcBcbi1nKtLjGUWhei/H8sB1nubBDDR2Z0rRJtPw==",
"dev": true, "dev": true,
"requires": { "requires": {
"exports-loader": "0.6.3", "exports-loader": "0.6.3",
@ -24178,9 +24187,9 @@
} }
}, },
"scratch-gui": { "scratch-gui": {
"version": "0.1.0-prerelease.20210202035926", "version": "0.1.0-prerelease.20210210053415",
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20210202035926.tgz", "resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20210210053415.tgz",
"integrity": "sha512-UetM3sZqM69uia8Mgh8lNmGkMTint0uaI4gK+VZezVlPvWiGJRSMG/ae8Hkj75y+1j6OYS8CqJUahD3HPa3PRw==", "integrity": "sha512-2NFpAtXuva5wPsr343dNKIzdJW6RCQYuPsXJopeylCr5cd7fJSTS6j0UISzMWE7FDlRsTEAD3qozEbJlKAhc9g==",
"dev": true, "dev": true,
"requires": { "requires": {
"arraybuffer-loader": "^1.0.6", "arraybuffer-loader": "^1.0.6",
@ -24231,13 +24240,13 @@
"redux": "3.7.2", "redux": "3.7.2",
"redux-throttle": "0.1.1", "redux-throttle": "0.1.1",
"scratch-audio": "0.1.0-prerelease.20200528195344", "scratch-audio": "0.1.0-prerelease.20200528195344",
"scratch-blocks": "0.1.0-prerelease.20210202033410", "scratch-blocks": "0.1.0-prerelease.20210210034743",
"scratch-l10n": "3.11.20210202031504", "scratch-l10n": "3.11.20210210031517",
"scratch-paint": "0.2.0-prerelease.20210201044008", "scratch-paint": "0.2.0-prerelease.20210210044507",
"scratch-render": "0.1.0-prerelease.20210115005247", "scratch-render": "0.1.0-prerelease.20210115005247",
"scratch-storage": "1.3.3", "scratch-storage": "1.3.3",
"scratch-svg-renderer": "0.2.0-prerelease.20210114214521", "scratch-svg-renderer": "0.2.0-prerelease.20210114214521",
"scratch-vm": "0.2.0-prerelease.20210131100123", "scratch-vm": "0.2.0-prerelease.20210202100335",
"startaudiocontext": "1.2.1", "startaudiocontext": "1.2.1",
"style-loader": "^0.23.0", "style-loader": "^0.23.0",
"text-encoding": "0.7.0", "text-encoding": "0.7.0",
@ -24416,9 +24425,9 @@
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
"version": "1.3.650", "version": "1.3.661",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.650.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.661.tgz",
"integrity": "sha512-j6pRuNylFBbroG6NB8Lw/Im9oDY74s2zWHBP5TmdYg73cBuL6cz//SMgolVa0gIJk/DSL+kO7baJ1DSXW1FUZg==", "integrity": "sha512-INNzKoL9ceOpPCpF5J+Fp9AOHY1RegwKViohAyTzV3XbkuRUx04r4v8edsDbevsog8UuL0GvD/Qerr2HwVTlSA==",
"dev": true "dev": true
}, },
"file-loader": { "file-loader": {
@ -24654,18 +24663,6 @@
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
"dev": true "dev": true
}, },
"scratch-l10n": {
"version": "3.11.20210202031504",
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.11.20210202031504.tgz",
"integrity": "sha512-AcJc1MZyX10jPCRnFia0nfz3jhgDiaAp7OMjGtzjuUAwEJ92EYDYZUuOgMS5IeOZzUJkOXx7vBKaUhL580BAVQ==",
"dev": true,
"requires": {
"@babel/cli": "^7.1.2",
"@babel/core": "^7.1.2",
"babel-plugin-react-intl": "^3.0.1",
"transifex": "1.6.6"
}
},
"scratch-storage": { "scratch-storage": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-1.3.3.tgz", "resolved": "https://registry.npmjs.org/scratch-storage/-/scratch-storage-1.3.3.tgz",
@ -24733,9 +24730,9 @@
} }
}, },
"scratch-l10n": { "scratch-l10n": {
"version": "3.11.20210203031454", "version": "3.11.20210210031517",
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.11.20210203031454.tgz", "resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.11.20210210031517.tgz",
"integrity": "sha512-JwI3YIZokOxv+kS9oS0gGxss1FjCMI6Mw7Rpi/n8sb8omulJ6T5mEEVHAl1Wu9GKtJgsPvJr9LPMeShBC/MMBg==", "integrity": "sha512-mtBxXPsXzfXdTMMPEs+QXFTJ46e1GUKhmSSjFjQcFXVaOkTWDyjsgYn3eT0v5fS9xG+whRD6E1tAOdunCblwQQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/cli": "^7.1.2", "@babel/cli": "^7.1.2",
@ -24745,9 +24742,9 @@
} }
}, },
"scratch-paint": { "scratch-paint": {
"version": "0.2.0-prerelease.20210201044008", "version": "0.2.0-prerelease.20210210044507",
"resolved": "https://registry.npmjs.org/scratch-paint/-/scratch-paint-0.2.0-prerelease.20210201044008.tgz", "resolved": "https://registry.npmjs.org/scratch-paint/-/scratch-paint-0.2.0-prerelease.20210210044507.tgz",
"integrity": "sha512-yLNGtINGaufv9Rmqj7ZfGi+SfmiaCa1g/IOdMvra8novlRtesc2ams6xiwxNxAAIz6B5JLa4LVRbU4B+VEFbKA==", "integrity": "sha512-W05EU07pDNvqQL4kKlYAijslKhX2rmMXbWhUYrta1ykhfk485N1v6YC22iWzrpv7G5jO+EGfoauzzZbyYUC+8w==",
"dev": true, "dev": true,
"requires": { "requires": {
"@scratch/paper": "0.11.20200728195508", "@scratch/paper": "0.11.20200728195508",
@ -24973,9 +24970,9 @@
"dev": true "dev": true
}, },
"scratch-vm": { "scratch-vm": {
"version": "0.2.0-prerelease.20210131100123", "version": "0.2.0-prerelease.20210202100335",
"resolved": "https://registry.npmjs.org/scratch-vm/-/scratch-vm-0.2.0-prerelease.20210131100123.tgz", "resolved": "https://registry.npmjs.org/scratch-vm/-/scratch-vm-0.2.0-prerelease.20210202100335.tgz",
"integrity": "sha512-2ov+osjvJ7HDHKtYYFuBc6lnXYZOC3LjhYZpESOrbNA6Mhp550bjK0UGzH9XJtJQfcMBKXXR6cf6ymWNVvMBFQ==", "integrity": "sha512-QXTrpUfGgvvnEuzmOiZBWyy6SxUuY+kTK9qsukc5cPtl9g2tAXDB5oRrsChimHKC+lfscd2pKhrf9eC+PTuVHg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@vernier/godirect": "1.5.0", "@vernier/godirect": "1.5.0",

View file

@ -134,7 +134,7 @@
"redux-mock-store": "^1.2.3", "redux-mock-store": "^1.2.3",
"redux-thunk": "2.0.1", "redux-thunk": "2.0.1",
"sass-loader": "6.0.6", "sass-loader": "6.0.6",
"scratch-gui": "0.1.0-prerelease.20210202035926", "scratch-gui": "0.1.0-prerelease.20210210053415",
"scratch-l10n": "latest", "scratch-l10n": "latest",
"selenium-webdriver": "3.6.0", "selenium-webdriver": "3.6.0",
"slick-carousel": "1.6.0", "slick-carousel": "1.6.0",

View file

@ -37,7 +37,7 @@ class MuteModal extends React.Component {
this.numSteps = this.props.showWarning ? steps.BAN_WARNING : steps.MUTE_INFO; this.numSteps = this.props.showWarning ? steps.BAN_WARNING : steps.MUTE_INFO;
this.state = { this.state = {
step: steps.COMMENT_ISSUE step: this.props.startStep ? this.props.startStep : steps.COMMENT_ISSUE
}; };
} }
handleNext () { handleNext () {
@ -240,7 +240,8 @@ MuteModal.propTypes = {
}), }),
onRequestClose: PropTypes.func, onRequestClose: PropTypes.func,
showWarning: PropTypes.bool, showWarning: PropTypes.bool,
startStep: PropTypes.oneOf(Object.keys(steps)),
timeMuted: PropTypes.string timeMuted: PropTypes.string
}; };
MuteModal.steps = steps;
module.exports = injectIntl(MuteModal); module.exports = injectIntl(MuteModal);

View file

@ -231,6 +231,7 @@ class Comment extends React.Component {
{this.state.replying ? ( {this.state.replying ? (
<FlexRow className="comment-reply-row"> <FlexRow className="comment-reply-row">
<ComposeComment <ComposeComment
isReply
commenteeId={author.id} commenteeId={author.id}
parentId={parentId || id} parentId={parentId || id}
projectId={projectId} projectId={projectId}

View file

@ -50,7 +50,7 @@ class ComposeComment extends React.Component {
status: ComposeStatus.EDITING, status: ComposeStatus.EDITING,
error: null, error: null,
appealId: null, appealId: null,
muteOpen: false, muteOpen: muteExpiresAtMs > Date.now() && this.props.isReply,
muteExpiresAtMs: muteExpiresAtMs, muteExpiresAtMs: muteExpiresAtMs,
muteType: this.props.muteStatus.currentMessageType, muteType: this.props.muteStatus.currentMessageType,
showWarning: this.props.muteStatus.showWarning ? this.props.muteStatus.showWarning : false showWarning: this.props.muteStatus.showWarning ? this.props.muteStatus.showWarning : false
@ -147,6 +147,13 @@ class ComposeComment extends React.Component {
this.setState({ this.setState({
muteOpen: false muteOpen: false
}); });
// Cancel (i.e. complete) the reply action if the user clicked on the reply button while
// alreay muted. This "closes" the reply. If they just got muted, we want to leave it open
// so the blue CommentingStatus box shows.
if (this.props.isReply && this.state.status !== ComposeStatus.REJECTED_MUTE) {
this.handleCancel();
}
} }
handleMuteOpen () { handleMuteOpen () {
@ -187,6 +194,14 @@ class ComposeComment extends React.Component {
return creationTimeMinutesAgo < 2 && numOffenses === 1; return creationTimeMinutesAgo < 2 && numOffenses === 1;
} }
getMuteModalStartStep () {
// Decides which step of the mute modal to start on. If this was a reply button click,
// we show them the step that tells them how much time is left on their mute, otherwise
// they start at the beginning of the progression.
return this.props.isReply && this.state.status !== ComposeStatus.REJECTED_MUTE ?
MuteModal.steps.MUTE_INFO : MuteModal.steps.COMMENT_ISSUE;
}
getMuteMessageInfo () { getMuteMessageInfo () {
// return the ids for the messages that are shown for this mute type // return the ids for the messages that are shown for this mute type
// If mute modals have more than one unique "step" we could pass an array of steps // If mute modals have more than one unique "step" we could pass an array of steps
@ -232,7 +247,7 @@ class ComposeComment extends React.Component {
render () { render () {
return ( return (
<React.Fragment> <React.Fragment>
{this.isMuted() ? ( {(this.isMuted() && !(this.props.isReply && this.state.status !== ComposeStatus.REJECTED_MUTE)) ? (
<FlexRow className="comment"> <FlexRow className="comment">
<CommentingStatus> <CommentingStatus>
<p><FormattedMessage id={this.getMuteMessageInfo().commentType} /></p> <p><FormattedMessage id={this.getMuteMessageInfo().commentType} /></p>
@ -344,6 +359,7 @@ class ComposeComment extends React.Component {
muteModalMessages={this.getMuteMessageInfo()} muteModalMessages={this.getMuteMessageInfo()}
shouldCloseOnOverlayClick={false} shouldCloseOnOverlayClick={false}
showWarning={this.state.showWarning} showWarning={this.state.showWarning}
startStep={this.getMuteModalStartStep()}
timeMuted={formatTime.formatRelativeTime(this.state.muteExpiresAtMs, window._locale)} timeMuted={formatTime.formatRelativeTime(this.state.muteExpiresAtMs, window._locale)}
onRequestClose={this.handleMuteClose} onRequestClose={this.handleMuteClose}
/> />
@ -355,6 +371,7 @@ class ComposeComment extends React.Component {
ComposeComment.propTypes = { ComposeComment.propTypes = {
commenteeId: PropTypes.number, commenteeId: PropTypes.number,
isReply: PropTypes.bool,
muteStatus: PropTypes.shape({ muteStatus: PropTypes.shape({
offenses: PropTypes.array, offenses: PropTypes.array,
muteExpiresAt: PropTypes.number, muteExpiresAt: PropTypes.number,

View file

@ -101,6 +101,46 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow; global.Date.now = realDateNow;
}); });
test('Comment Status and compose box do not show on replies when muted, but mute modal does', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const store = mockStore({
session: {
session: {
user: {},
permissions: {
mute_status: {
muteExpiresAt: 5,
offenses: [],
showWarning: true
}
}
}
}
});
const component = mountWithIntl(
<ComposeComment
{...defaultProps()}
isReply
/>
, {context: {store}}
);
expect(component.find('FlexRow.compose-comment').exists()).toEqual(false);
expect(component.find('MuteModal').exists()).toBe(true);
expect(component.find('MuteModal').props().startStep).toBe(1);
expect(component.find('CommentingStatus').exists()).toEqual(false);
global.Date.now = realDateNow;
});
test('Comment Status and compose box show on replies when not muted', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({isReply: true});
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
expect(component.find('CommentingStatus').exists()).toEqual(false);
global.Date.now = realDateNow;
});
test('Comment Status initialized properly when muted', () => { test('Comment Status initialized properly when muted', () => {
jest.useFakeTimers(); jest.useFakeTimers();
const realDateNow = Date.now.bind(global.Date); const realDateNow = Date.now.bind(global.Date);
@ -133,6 +173,27 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow; global.Date.now = realDateNow;
}); });
test('Comment Status shows when user just submitted a reply comment that got them muted', () => {
const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0;
const component = getComposeCommentWrapper({isReply: true});
const commentInstance = component.instance();
commentInstance.setState({
status: 'REJECTED_MUTE',
muteExpiresAtMs: 100
});
component.update();
expect(component.find('FlexRow.compose-comment').exists()).toEqual(true);
expect(component.find('MuteModal').exists()).toEqual(false);
expect(component.find('CommentingStatus').exists()).toEqual(true);
// Compose box exists but is disabled
expect(component.find('InplaceInput.compose-input').exists()).toEqual(true);
expect(component.find('InplaceInput.compose-input').props().disabled).toBe(true);
expect(component.find('Button.compose-post').props().disabled).toBe(true);
expect(component.find('Button.compose-cancel').props().disabled).toBe(true);
global.Date.now = realDateNow;
});
test('Comment Status shows when user just submitted a comment that got them muted', () => { test('Comment Status shows when user just submitted a comment that got them muted', () => {
const realDateNow = Date.now.bind(global.Date); const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0; global.Date.now = () => 0;
@ -207,6 +268,7 @@ describe('Compose Comment test', () => {
commentInstance.setState({muteOpen: true}); commentInstance.setState({muteOpen: true});
component.update(); component.update();
expect(component.find('MuteModal').exists()).toEqual(true); expect(component.find('MuteModal').exists()).toEqual(true);
expect(component.find('MuteModal').props().startStep).toEqual(0);
expect(component.find('MuteModal').props().showWarning).toBe(false); expect(component.find('MuteModal').props().showWarning).toBe(false);
global.Date.now = realDateNow; global.Date.now = realDateNow;
}); });
@ -321,6 +383,27 @@ describe('Compose Comment test', () => {
global.Date.now = realDateNow; global.Date.now = realDateNow;
}); });
test('getMuteModalStartStep: not a reply ', () => {
const commentInstance = getComposeCommentWrapper({}).instance();
expect(commentInstance.getMuteModalStartStep()).toBe(0);
});
test('getMuteModalStartStep: A reply that got them muted ', () => {
const commentInstance = getComposeCommentWrapper({isReply: true}).instance();
commentInstance.setState({
status: 'REJECTED_MUTE'
});
expect(commentInstance.getMuteModalStartStep()).toBe(0);
});
test('getMuteModalStartStep: A reply click when already muted ', () => {
const commentInstance = getComposeCommentWrapper({isReply: true}).instance();
commentInstance.setState({
status: 'EDITING'
});
expect(commentInstance.getMuteModalStartStep()).toBe(1);
});
test('isMuted: expiration is in the future ', () => { test('isMuted: expiration is in the future ', () => {
const realDateNow = Date.now.bind(global.Date); const realDateNow = Date.now.bind(global.Date);
global.Date.now = () => 0; // Set "now" to 0 for easier testing. global.Date.now = () => 0; // Set "now" to 0 for easier testing.