From 95203a462e6ba45142954dcfb89b15be2bd061e0 Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Thu, 10 Jan 2019 19:02:59 +0900 Subject: [PATCH 1/9] Change Mobile Chrome supported ver to 63+ --- src/views/faq/l10n.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/faq/l10n.json b/src/views/faq/l10n.json index 71617c3c0..0d9ba0167 100644 --- a/src/views/faq/l10n.json +++ b/src/views/faq/l10n.json @@ -24,7 +24,7 @@ "faq.requirementsDesktopSafari":"Safari (11+)", "faq.requirementsDesktopIE":"Internet Explorer is NOT supported.", "faq.requirementsTablet":"Tablet", - "faq.requirementsTabletChrome":"Mobile Chrome (62+)", + "faq.requirementsTabletChrome":"Mobile Chrome (63+)", "faq.requirementsTabletSafari":"Mobile Safari (11+)", "faq.requirementsNote":"Note:", "faq.requirementsNoteDesktop":"If your computer doesn’t meet these requirements, you can try the Scratch Desktop editor (see next item in FAQ). ", From f7e89227578991b2c3e00797265e87f8eaec504a Mon Sep 17 00:00:00 2001 From: Paul Kaplan Date: Thu, 10 Jan 2019 10:46:01 -0500 Subject: [PATCH 2/9] Allow loading more than 20 replies --- package.json | 1 + src/l10n.json | 2 +- src/redux/preview.js | 28 ++++++++++++++----- .../preview/comment/top-level-comment.jsx | 24 ++++++++-------- src/views/preview/presentation.jsx | 4 +++ src/views/preview/project-view.jsx | 11 ++++++++ 6 files changed, 51 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index edd610a5b..c5135a36e 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "lodash.defaultsdeep": "3.10.0", "lodash.isarray": "3.0.4", "lodash.merge": "3.3.2", + "lodash.mergewith": "4.6.1", "lodash.omit": "3.1.0", "lodash.range": "3.0.1", "minilog": "2.0.8", diff --git a/src/l10n.json b/src/l10n.json index f8d8f3285..90eaeba70 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -237,7 +237,7 @@ "comments.post": "Post", "comments.cancel": "Cancel", "comments.lengthWarning": "{remainingCharacters, plural, one {1 character left} other {{remainingCharacters} characters left}}", - "comments.seeMoreReplies": "{repliesCount, plural, one {See 1 more reply} other {See all {repliesCount} replies}}", + "comments.loadMoreReplies": "See more replies", "comments.status.delbyusr": "Deleted by project owner", "comments.status.censbyfilter": "Censored by filter", "comments.status.delbyparentcomment": "Parent comment deleted", diff --git a/src/redux/preview.js b/src/redux/preview.js index 24b746ca0..18afb9b59 100644 --- a/src/redux/preview.js +++ b/src/redux/preview.js @@ -1,11 +1,13 @@ const defaults = require('lodash.defaults'); const keyMirror = require('keymirror'); const async = require('async'); -const merge = require('lodash.merge'); +const mergeWith = require('lodash.mergewith'); const api = require('../lib/api'); const log = require('../lib/log'); +const COMMENT_LIMIT = 20; + module.exports.Status = keyMirror({ FETCHED: null, NOT_FETCHED: null, @@ -149,7 +151,19 @@ module.exports.previewReducer = (state, action) => { }); case 'SET_REPLIES': return Object.assign({}, state, { - replies: merge({}, state.replies, action.replies) + // Append new replies to the state.replies structure + replies: mergeWith({}, state.replies, action.replies, (replies, newReplies) => ( + (replies || []).concat(newReplies || []) + )), + // Also set the `moreRepliesToLoad` property on the top-level comments + comments: state.comments.map(comment => { + if (action.replies[comment.id]) { + return Object.assign({}, comment, { + moreRepliesToLoad: action.replies[comment.id].length === COMMENT_LIMIT + }); + } + return comment; + }) }); case 'SET_LOVED': return Object.assign({}, state, { @@ -448,7 +462,6 @@ module.exports.getFavedStatus = (id, username, token) => (dispatch => { }); module.exports.getTopLevelComments = (id, offset, isAdmin, token) => (dispatch => { - const COMMENT_LIMIT = 20; dispatch(module.exports.setFetchStatus('comments', module.exports.Status.FETCHING)); api({ uri: `${isAdmin ? '/admin' : ''}/projects/${id}/comments`, @@ -467,7 +480,7 @@ module.exports.getTopLevelComments = (id, offset, isAdmin, token) => (dispatch = } dispatch(module.exports.setFetchStatus('comments', module.exports.Status.FETCHED)); dispatch(module.exports.setComments(body)); - dispatch(module.exports.getReplies(id, body.map(comment => comment.id), isAdmin, token)); + dispatch(module.exports.getReplies(id, body.map(comment => comment.id), 0, isAdmin, token)); // If we loaded a full page of comments, assume there are more to load. // This will be wrong (1 / COMMENT_LIMIT) of the time, but does not require @@ -503,17 +516,18 @@ module.exports.getCommentById = (projectId, commentId, isAdmin, token) => (dispa // If the comment is not a reply, show it as top level and load replies dispatch(module.exports.setFetchStatus('comments', module.exports.Status.FETCHED)); dispatch(module.exports.setComments([body])); - dispatch(module.exports.getReplies(projectId, [body.id], isAdmin, token)); + dispatch(module.exports.getReplies(projectId, [body.id], 0, isAdmin, token)); }); }); -module.exports.getReplies = (projectId, commentIds, isAdmin, token) => (dispatch => { +module.exports.getReplies = (projectId, commentIds, offset, isAdmin, token) => (dispatch => { dispatch(module.exports.setFetchStatus('replies', module.exports.Status.FETCHING)); const fetchedReplies = {}; async.eachLimit(commentIds, 10, (parentId, callback) => { api({ uri: `${isAdmin ? '/admin' : ''}/projects/${projectId}/comments/${parentId}/replies`, - authentication: isAdmin ? token : null + authentication: isAdmin ? token : null, + params: {offset: offset || 0, limit: COMMENT_LIMIT} }, (err, body) => { if (err) { return callback(`Error fetching comment replies: ${err}`); diff --git a/src/views/preview/comment/top-level-comment.jsx b/src/views/preview/comment/top-level-comment.jsx index 188150d7b..86b20b9ac 100644 --- a/src/views/preview/comment/top-level-comment.jsx +++ b/src/views/preview/comment/top-level-comment.jsx @@ -28,9 +28,11 @@ class TopLevelComment extends React.Component { } handleExpandThread () { - this.setState({ - expanded: true - }); + if (this.state.expanded) { + this.props.onLoadMoreReplies(this.props.id, this.props.replies.length); + } else { + this.setState({expanded: true}); + } } handleDeleteReply (replyId) { @@ -79,6 +81,7 @@ class TopLevelComment extends React.Component { datetimeCreated, highlightedCommentId, id, + moreRepliesToLoad, onDelete, onReport, onRestore, @@ -143,17 +146,13 @@ class TopLevelComment extends React.Component { ))} } - {!this.state.expanded && replies.length > 3 && + {((!this.state.expanded && replies.length > 3) || + (this.state.expanded && moreRepliesToLoad)) && - + } @@ -178,8 +177,10 @@ TopLevelComment.propTypes = { deletable: PropTypes.bool, highlightedCommentId: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]), id: PropTypes.number, + moreRepliesToLoad: PropTypes.bool, onAddComment: PropTypes.func, onDelete: PropTypes.func, + onLoadMoreReplies: PropTypes.func, onReport: PropTypes.func, onRestore: PropTypes.func, parentId: PropTypes.number, @@ -189,7 +190,8 @@ TopLevelComment.propTypes = { }; TopLevelComment.defaultProps = { - defaultExpanded: false + defaultExpanded: false, + moreRepliesToLoad: false }; module.exports = TopLevelComment; diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index fdccd6c16..183099663 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -88,6 +88,7 @@ const PreviewPresentation = ({ onFavoriteClicked, onGreenFlag, onLoadMore, + onLoadMoreReplies, onLoveClicked, onOpenAdminPanel, onRemix, @@ -550,12 +551,14 @@ const PreviewPresentation = ({ highlightedCommentId={singleCommentId} id={comment.id} key={comment.id} + moreRepliesToLoad={comment.moreRepliesToLoad} parentId={comment.parent_id} projectId={projectId} replies={replies && replies[comment.id] ? replies[comment.id] : []} visibility={comment.visibility} onAddComment={onAddComment} onDelete={onDeleteComment} + onLoadMoreReplies={onLoadMoreReplies} onReport={onReportComment} onRestore={onRestoreComment} /> @@ -644,6 +647,7 @@ PreviewPresentation.propTypes = { onFavoriteClicked: PropTypes.func, onGreenFlag: PropTypes.func, onLoadMore: PropTypes.func, + onLoadMoreReplies: PropTypes.func, onLoveClicked: PropTypes.func, onOpenAdminPanel: PropTypes.func, onRemix: PropTypes.func, diff --git a/src/views/preview/project-view.jsx b/src/views/preview/project-view.jsx index c6ed64a96..70cdb3cdf 100644 --- a/src/views/preview/project-view.jsx +++ b/src/views/preview/project-view.jsx @@ -60,6 +60,7 @@ class Preview extends React.Component { 'handleToggleStudio', 'handleFavoriteToggle', 'handleLoadMore', + 'handleLoadMoreReplies', 'handleLoveToggle', 'handleMessage', 'handlePopState', @@ -440,6 +441,11 @@ class Preview extends React.Component { this.props.getTopLevelComments(this.state.projectId, this.props.comments.length, this.props.isAdmin, this.props.user && this.props.user.token); } + handleLoadMoreReplies (commentId, offset) { + this.props.getMoreReplies(this.state.projectId, commentId, offset, + this.props.isAdmin, this.props.user && this.props.user.token + ); + } handleLoveToggle () { if (!this.props.lovedLoaded) return; @@ -644,6 +650,7 @@ class Preview extends React.Component { onFavoriteClicked={this.handleFavoriteToggle} onGreenFlag={this.handleGreenFlag} onLoadMore={this.handleLoadMore} + onLoadMoreReplies={this.handleLoadMoreReplies} onLoveClicked={this.handleLoveToggle} onOpenAdminPanel={this.handleOpenAdminPanel} onRemix={this.handleRemix} @@ -736,6 +743,7 @@ Preview.propTypes = { getCuratedStudios: PropTypes.func.isRequired, getFavedStatus: PropTypes.func.isRequired, getLovedStatus: PropTypes.func.isRequired, + getMoreReplies: PropTypes.func.isRequired, getOriginalInfo: PropTypes.func.isRequired, getParentInfo: PropTypes.func.isRequired, getProjectInfo: PropTypes.func.isRequired, @@ -948,6 +956,9 @@ const mapDispatchToProps = dispatch => ({ getCommentById: (projectId, commentId, isAdmin, token) => { dispatch(previewActions.getCommentById(projectId, commentId, isAdmin, token)); }, + getMoreReplies: (projectId, commentId, offset, isAdmin, token) => { + dispatch(previewActions.getReplies(projectId, [commentId], offset, isAdmin, token)); + }, getFavedStatus: (id, username, token) => { dispatch(previewActions.getFavedStatus(id, username, token)); }, From ccbaa60e59aafb7a429a1380a258cf2e5a51235e Mon Sep 17 00:00:00 2001 From: chrisgarrity Date: Thu, 10 Jan 2019 10:50:37 -0500 Subject: [PATCH 3/9] =?UTF-8?q?Don=E2=80=99t=20allow=20remixing=20if=20the?= =?UTF-8?q?=20project=20is=20not=20loaded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Depends on https://github.com/LLK/scratch-gui/pull/4312 Adds new `isProjectLoaded` state to the project view, and disables the remix button until the project is loaded. Passes new callback to gui to be notified when the project is loaded. --- src/views/preview/presentation.jsx | 10 ++++++++-- src/views/preview/preview.scss | 4 +++- src/views/preview/project-view.jsx | 10 ++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/views/preview/presentation.jsx b/src/views/preview/presentation.jsx index fdccd6c16..45cc94a59 100644 --- a/src/views/preview/presentation.jsx +++ b/src/views/preview/presentation.jsx @@ -70,6 +70,7 @@ const PreviewPresentation = ({ isFullScreen, isLoggedIn, isNewScratcher, + isProjectLoaded, isRemixing, isScratcher, isShared, @@ -90,6 +91,7 @@ const PreviewPresentation = ({ onLoadMore, onLoveClicked, onOpenAdminPanel, + onProjectLoaded, onRemix, onRemixing, onReportClicked, @@ -250,10 +252,11 @@ const PreviewPresentation = ({ className={classNames([ 'remix-button', { - remixing: isRemixing, - spin: isRemixing + disabled: isRemixing || !isProjectLoaded, + remixing: isRemixing } ])} + disabled={isRemixing || !isProjectLoaded} title={intl.formatMessage({id: 'project.remixButton.altText'})} onClick={onRemix} > @@ -301,6 +304,7 @@ const PreviewPresentation = ({ projectHost={projectHost} projectId={projectId} onGreenFlag={onGreenFlag} + onProjectLoaded={onProjectLoaded} onRemixing={onRemixing} onUpdateProjectId={onUpdateProjectId} onUpdateProjectThumbnail={onUpdateProjectThumbnail} @@ -623,6 +627,7 @@ PreviewPresentation.propTypes = { isFullScreen: PropTypes.bool, isLoggedIn: PropTypes.bool, isNewScratcher: PropTypes.bool, + isProjectLoaded: PropTypes.bool, isRemixing: PropTypes.bool, isScratcher: PropTypes.bool, isShared: PropTypes.bool, @@ -646,6 +651,7 @@ PreviewPresentation.propTypes = { onLoadMore: PropTypes.func, onLoveClicked: PropTypes.func, onOpenAdminPanel: PropTypes.func, + onProjectLoaded: PropTypes.func, onRemix: PropTypes.func, onRemixing: PropTypes.func, onReportClicked: PropTypes.func.isRequired, diff --git a/src/views/preview/preview.scss b/src/views/preview/preview.scss index 9a6fce550..7a108a33a 100644 --- a/src/views/preview/preview.scss +++ b/src/views/preview/preview.scss @@ -283,9 +283,11 @@ $stage-width: 480px; background-image: url("/svgs/project/remix-white.svg"); } } + .remix-button.disabled { + opacity: .6; + } .remix-button.remixing { - opacity: .6; &:before { animation-name: remix-intro, remix-spin; diff --git a/src/views/preview/project-view.jsx b/src/views/preview/project-view.jsx index c6ed64a96..f7270d80b 100644 --- a/src/views/preview/project-view.jsx +++ b/src/views/preview/project-view.jsx @@ -74,6 +74,7 @@ class Preview extends React.Component { 'handleAddToStudioClick', 'handleAddToStudioClose', 'handleGreenFlag', + 'handleProjectLoaded', 'handleRemix', 'handleSeeAllComments', 'handleSeeInside', @@ -108,6 +109,7 @@ class Preview extends React.Component { clientLoved: false, extensions: [], favoriteCount: 0, + isProjectLoaded: false, isRemixing: false, invalidProject: parts.length === 1, justRemixed: false, @@ -382,6 +384,11 @@ class Preview extends React.Component { this.props.setFullScreen(fullScreen); } } + handleProjectLoaded () { + // Currently project view only needs to know when the project becomes loaded. It + // does not currently handle (or need to handle) the case where a project becomes unloaded. + this.setState({isProjectLoaded: true}); + } pushHistory (push) { // update URI to match mode const idPath = this.state.projectId ? `${this.state.projectId}/` : ''; @@ -611,6 +618,7 @@ class Preview extends React.Component { isFullScreen={this.state.isFullScreen} isLoggedIn={this.props.isLoggedIn} isNewScratcher={this.props.isNewScratcher} + isProjectLoaded={this.state.isProjectLoaded} isRemixing={this.state.isRemixing} isScratcher={this.props.isScratcher} isShared={this.props.isShared} @@ -646,6 +654,7 @@ class Preview extends React.Component { onLoadMore={this.handleLoadMore} onLoveClicked={this.handleLoveToggle} onOpenAdminPanel={this.handleOpenAdminPanel} + onProjectLoaded={this.handleProjectLoaded} onRemix={this.handleRemix} onRemixing={this.handleIsRemixing} onReportClicked={this.handleReportClick} @@ -691,6 +700,7 @@ class Preview extends React.Component { onGreenFlag={this.handleGreenFlag} onLogOut={this.props.handleLogOut} onOpenRegistration={this.props.handleOpenRegistration} + onProjectLoaded={this.handleProjectLoaded} onRemixing={this.handleIsRemixing} onSetLanguage={this.handleSetLanguage} onShare={this.handleShare} From 1277ca48767e62b49e056ba2320808b69fce9081 Mon Sep 17 00:00:00 2001 From: Paul Kaplan Date: Thu, 10 Jan 2019 10:58:34 -0500 Subject: [PATCH 4/9] Make "See more replies" only the width of the replies column --- src/views/preview/comment/comment.scss | 28 +++++++++---------- .../preview/comment/top-level-comment.jsx | 18 ++++++------ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/views/preview/comment/comment.scss b/src/views/preview/comment/comment.scss index 98e55ef6c..cff4c131b 100644 --- a/src/views/preview/comment/comment.scss +++ b/src/views/preview/comment/comment.scss @@ -235,22 +235,20 @@ .replies { width: calc(100% - 4rem); +} - &.collapsed .comment { - &:last-child { - &:after { - position: absolute; - bottom: 0; - background: linear-gradient( - $ui-light-primary-transparent, - $ui-light-primary - ); - width: 100%; - height: 100%; - content: ""; - pointer-events: none; - } - } +.replies.collapsed > .comment:last-of-type { + &:after { + position: absolute; + bottom: 0; + background: linear-gradient( + $ui-light-primary-transparent, + $ui-light-primary + ); + width: 100%; + height: 100%; + content: ""; + pointer-events: none; } } diff --git a/src/views/preview/comment/top-level-comment.jsx b/src/views/preview/comment/top-level-comment.jsx index 86b20b9ac..ecc15208e 100644 --- a/src/views/preview/comment/top-level-comment.jsx +++ b/src/views/preview/comment/top-level-comment.jsx @@ -144,17 +144,17 @@ class TopLevelComment extends React.Component { onRestore={this.handleRestoreReply} /> ))} + {((!this.state.expanded && replies.length > 3) || + (this.state.expanded && moreRepliesToLoad)) && + + + + } } - {((!this.state.expanded && replies.length > 3) || - (this.state.expanded && moreRepliesToLoad)) && - - - - } ); } From e2c743445f4a4f3893f5c44a81b25eacf396feed Mon Sep 17 00:00:00 2001 From: Paul Kaplan Date: Thu, 10 Jan 2019 10:59:35 -0500 Subject: [PATCH 5/9] Add unit test for setReplies action in preview reducer --- test/unit/redux/preview-test.js | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/unit/redux/preview-test.js b/test/unit/redux/preview-test.js index 46c6f7d87..0c75c27ff 100644 --- a/test/unit/redux/preview-test.js +++ b/test/unit/redux/preview-test.js @@ -128,3 +128,37 @@ tap.test('addNewComment, reply comment', t => { t.equal(state.replies.id1[2].id, 'new comment'); t.end(); }); + +tap.test('setReplies', t => { + // setReplies should append new replies + state = reducer(commentState, Preview.setReplies({ + id1: {id: 'id6'} + })); + t.equal(state.replies.id1[2].id, 'id6'); + t.equal(state.comments[0].moreRepliesToLoad, false); + + // setReplies can add replies to a comment that didn't have any + state = reducer(state, Preview.setReplies({ + id2: {id: 'id7'} + })); + t.equal(state.replies.id1.length, 3); + t.equal(state.replies.id2.length, 1); + t.equal(state.replies.id2[0].id, 'id7'); + t.equal(state.comments[0].moreRepliesToLoad, false); + t.equal(state.comments[1].moreRepliesToLoad, false); + + // Getting 20 (COMMENT_LIMIT) replies sets moreRepliesToLoad to true + state = reducer(state, Preview.setReplies({ + id3: (new Array(20)).map((_, i) => ({id: `id${i + 1}`})) + })); + t.equal(state.comments[0].moreRepliesToLoad, false); + t.equal(state.comments[1].moreRepliesToLoad, false); + t.equal(state.comments[2].moreRepliesToLoad, true); + + // Getting one more reply sets moreRepliesToLoad back to false + state = reducer(state, Preview.setReplies({ + id3: {id: 'id21'} + })); + t.equal(state.comments[2].moreRepliesToLoad, false); + t.end(); +}); From 16391f25ee3236448ac09a5ee647b364c21b4e25 Mon Sep 17 00:00:00 2001 From: Paul Kaplan Date: Thu, 10 Jan 2019 13:49:07 -0500 Subject: [PATCH 6/9] Strip out duplicates from replies and comments. Fixes https://github.com/LLK/scratch-www/issues/2575 --- package.json | 1 + src/redux/preview.js | 5 +++-- test/unit/redux/preview-test.js | 18 +++++++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c5135a36e..91eef6fa8 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "lodash.mergewith": "4.6.1", "lodash.omit": "3.1.0", "lodash.range": "3.0.1", + "lodash.uniqby": "4.7.0", "minilog": "2.0.8", "node-dir": "0.1.16", "node-sass": "4.6.1", diff --git a/src/redux/preview.js b/src/redux/preview.js index 18afb9b59..12a06ba7b 100644 --- a/src/redux/preview.js +++ b/src/redux/preview.js @@ -2,6 +2,7 @@ const defaults = require('lodash.defaults'); const keyMirror = require('keymirror'); const async = require('async'); const mergeWith = require('lodash.mergewith'); +const uniqBy = require('lodash.uniqby'); const api = require('../lib/api'); const log = require('../lib/log'); @@ -102,7 +103,7 @@ module.exports.previewReducer = (state, action) => { }); case 'SET_COMMENTS': return Object.assign({}, state, { - comments: [...state.comments, ...action.items] // TODO: consider a different way of doing this? + comments: uniqBy(state.comments.concat(action.items), 'id') }); case 'UPDATE_COMMENT': if (action.topLevelCommentId) { @@ -153,7 +154,7 @@ module.exports.previewReducer = (state, action) => { return Object.assign({}, state, { // Append new replies to the state.replies structure replies: mergeWith({}, state.replies, action.replies, (replies, newReplies) => ( - (replies || []).concat(newReplies || []) + uniqBy((replies || []).concat(newReplies || []), 'id') )), // Also set the `moreRepliesToLoad` property on the top-level comments comments: state.comments.map(comment => { diff --git a/test/unit/redux/preview-test.js b/test/unit/redux/preview-test.js index 0c75c27ff..24a91ce84 100644 --- a/test/unit/redux/preview-test.js +++ b/test/unit/redux/preview-test.js @@ -59,9 +59,9 @@ tap.test('setComments', t => { // Initial value t.deepEqual(initialState.comments, []); - state = reducer(initialState, Preview.setComments([1, 2])); - state = reducer(state, Preview.setComments([3, 4])); - t.deepEqual(state.comments, [1, 2, 3, 4]); + state = reducer(initialState, Preview.setComments([{id: 1}, {id: 2}])); + state = reducer(state, Preview.setComments([{id: 3}, {id: 4}])); + t.deepEqual(state.comments, [{id: 1}, {id: 2}, {id: 3}, {id: 4}]); t.end(); }); @@ -80,6 +80,13 @@ const commentState = { } }; +tap.test('setComments, discards duplicates', t => { + state = reducer(commentState, Preview.setComments([{id: 'id1'}])); + // Does not increase the number of comments, still 3 + t.equal(state.comments.length, 3); + t.end(); +}); + tap.test('setCommentDeleted, top level comment', t => { state = reducer(commentState, Preview.setCommentDeleted('id2')); t.equal(state.comments[1].visibility, 'deleted'); @@ -137,6 +144,11 @@ tap.test('setReplies', t => { t.equal(state.replies.id1[2].id, 'id6'); t.equal(state.comments[0].moreRepliesToLoad, false); + // setReplies should ignore duplicates, do the same as above again + t.equal(state.replies.id1.length, 3); + state = reducer(state, Preview.setReplies({id1: {id: 'id6'}})); + t.equal(state.replies.id1.length, 3); + // setReplies can add replies to a comment that didn't have any state = reducer(state, Preview.setReplies({ id2: {id: 'id7'} From e9899a7acb1245c7b5d86ce4ce4c4e49478f5e03 Mon Sep 17 00:00:00 2001 From: chrisgarrity Date: Thu, 10 Jan 2019 14:38:36 -0500 Subject: [PATCH 7/9] =?UTF-8?q?Bump=20gui=20version=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit so that https://github.com/LLK/scratch-www/pull/2656 can land (disable remixing until project loaded) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index edd610a5b..3f2d9fa13 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "redux": "3.5.2", "redux-thunk": "2.0.1", "sass-loader": "6.0.6", - "scratch-gui": "0.1.0-prerelease.20190109203727", + "scratch-gui": "0.1.0-prerelease.20190102131553", "scratch-l10n": "latest", "scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master", "slick-carousel": "1.6.0", From 2018f8534a954f58f2fe068e41265f26567dd2a8 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Thu, 10 Jan 2019 15:19:51 -0800 Subject: [PATCH 8/9] Update Scratch Desktop download links to v1.2.1 --- src/views/download/download.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/download/download.jsx b/src/views/download/download.jsx index 2ad476009..873708a1a 100644 --- a/src/views/download/download.jsx +++ b/src/views/download/download.jsx @@ -114,8 +114,8 @@ class Download extends React.Component { className="download-button" href={ this.state.OS === OS_ENUM.WINDOWS ? - 'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop%20Setup%201.2.0.exe' : - 'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop-1.2.0.dmg' + 'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop%20Setup%201.2.1.exe' : + 'https://downloads.scratch.mit.edu/desktop/Scratch%20Desktop-1.2.1.dmg' } > From 40e26ab636214af35e0b7753cac12ac33cb01733 Mon Sep 17 00:00:00 2001 From: Ben Wheeler Date: Fri, 11 Jan 2019 09:29:00 -0500 Subject: [PATCH 9/9] bump gui version so that scratch-gui #4319 bump gui version so that scratch-gui #4319 can land (resolve name conflict in project-fetcher-hoc) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c3852b435..05b9a0a86 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "redux": "3.5.2", "redux-thunk": "2.0.1", "sass-loader": "6.0.6", - "scratch-gui": "0.1.0-prerelease.20190102131553", + "scratch-gui": "0.1.0-prerelease.20190111141703", "scratch-l10n": "latest", "scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master", "slick-carousel": "1.6.0",