-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Video: Redux state changes for custom video poster #11633
Changes from all commits
79dc087
90f2538
0841192
fd6fdd6
514500c
27880f0
95e6da9
1fdedcb
a1bba85
91cec7e
7b7515d
fde2264
121bd16
fffa8c2
5e6d625
34d26bb
e692e94
c192bf8
e1a0606
f69706a
ef2706f
425af57
7e22d20
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { mergeHandlers } from 'state/data-layer/utils'; | ||
import poster from './poster'; | ||
|
||
export default mergeHandlers( | ||
poster, | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { http } from 'state/data-layer/wpcom-http/actions'; | ||
import { dispatchRequest } from 'state/data-layer/wpcom-http/utils'; | ||
import { VIDEO_EDITOR_UPDATE_POSTER } from 'state/action-types'; | ||
import { | ||
closeModal, | ||
setPosterUrl, | ||
showError, | ||
showUploadProgress, | ||
} from 'state/ui/editor/video-editor/actions'; | ||
|
||
/** | ||
* Updates the poster for a video. | ||
* | ||
* @param {Object} store Redux store | ||
* @param {Object} action Action object | ||
* @param {Function} next Dispatches to next middleware in chain | ||
* @returns {Object} original action | ||
*/ | ||
export const updatePoster = ( { dispatch }, action, next ) => { | ||
if ( ! ( 'file' in action.params || 'atTime' in action.params ) ) { | ||
return next( action ); | ||
} | ||
|
||
const { atTime, file } = action.params; | ||
const params = Object.assign( | ||
{ | ||
apiVersion: '1.1', | ||
method: 'POST', | ||
path: `/videos/${ action.videoId }/poster`, | ||
}, | ||
file && { formData: [ [ 'poster', file ] ] }, | ||
atTime !== undefined && { body: { at_time: atTime } }, | ||
); | ||
|
||
dispatch( http( params, action ) ); | ||
|
||
return next( action ); | ||
}; | ||
|
||
export const receivePosterUrl = ( { dispatch }, action, next, { poster: posterUrl } ) => { | ||
dispatch( setPosterUrl( posterUrl ) ); | ||
dispatch( closeModal() ); | ||
}; | ||
|
||
export const receivePosterError = ( { dispatch } ) => { | ||
dispatch( showError() ); | ||
}; | ||
|
||
export const receiveUploadProgress = ( { dispatch }, action, next, progress ) => { | ||
let percentage = 0; | ||
|
||
if ( 'loaded' in progress && 'total' in progress ) { | ||
percentage = Math.min( Math.round( progress.loaded / progress.total * 100 ), 100 ); | ||
} | ||
|
||
dispatch( showUploadProgress( percentage ) ); | ||
}; | ||
|
||
export const dispatchPosterRequest = | ||
dispatchRequest( updatePoster, receivePosterUrl, receivePosterError, receiveUploadProgress ); | ||
|
||
export default { | ||
[ VIDEO_EDITOR_UPDATE_POSTER ]: [ dispatchPosterRequest ], | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Returns the poster upload progress. | ||
* | ||
* @param {Object} state Global state tree | ||
* @return {Number} Poster upload progress percentage. | ||
*/ | ||
export default function getPosterUploadProgress( state ) { | ||
return state.ui.editor.videoEditor.uploadProgress; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Returns the poster URL of the video. | ||
* | ||
* @param {Object} state Global state tree | ||
* @return {String} URL of the poster. | ||
*/ | ||
export default function getPosterUrl( state ) { | ||
return state.ui.editor.videoEditor.url; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* Returns true if the video editor modal should be closed. | ||
* | ||
* @param {Object} state Global state tree | ||
* @return {Boolean} true if the modal should be closed. | ||
* | ||
*/ | ||
export default function shouldCloseVideoEditorModal( state ) { | ||
return state.ui.editor.videoEditor.closeModal; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* Returns true if an error should be shown in the video editor. | ||
* | ||
* @param {Object} state Global state tree | ||
* @return {Boolean} true if an error should be shown. | ||
* | ||
*/ | ||
export default function shouldShowVideoEditorError( state ) { | ||
return state.ui.editor.videoEditor.showError; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { expect } from 'chai'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { getPosterUploadProgress } from '../'; | ||
|
||
describe( 'getPosterUploadProgress()', () => { | ||
it( 'should return the upload progress', () => { | ||
const percentage = 50; | ||
const uploadProgress = getPosterUploadProgress( { | ||
ui: { | ||
editor: { | ||
videoEditor: { | ||
uploadProgress: percentage | ||
} | ||
} | ||
} | ||
} ); | ||
|
||
expect( uploadProgress ).to.eql( percentage ); | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { expect } from 'chai'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { getPosterUrl } from '../'; | ||
|
||
describe( 'getPosterUrl()', () => { | ||
it( 'should return the current video editor poster', () => { | ||
const url = 'https://i1.wp.com/videos.files.wordpress.com/dummy-guid/thumbnail.jpg?ssl=1'; | ||
const poster = getPosterUrl( { | ||
ui: { | ||
editor: { | ||
videoEditor: { | ||
url | ||
} | ||
} | ||
} | ||
} ); | ||
|
||
expect( poster ).to.eql( url ); | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { expect } from 'chai'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { shouldCloseVideoEditorModal } from '../'; | ||
|
||
describe( 'shouldCloseVideoEditorModal()', () => { | ||
it( 'should return whether or not the video editor modal should be closed', () => { | ||
const shouldClose = shouldCloseVideoEditorModal( { | ||
ui: { | ||
editor: { | ||
videoEditor: { | ||
closeModal: false | ||
} | ||
} | ||
} | ||
} ); | ||
|
||
expect( shouldClose ).to.be.false; | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { expect } from 'chai'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { shouldShowVideoEditorError } from '../'; | ||
|
||
describe( 'shouldShowVideoEditorError()', () => { | ||
it( 'should return the poster error state', () => { | ||
const showError = shouldShowVideoEditorError( { | ||
ui: { | ||
editor: { | ||
videoEditor: { | ||
showError: true | ||
} | ||
} | ||
} | ||
} ); | ||
|
||
expect( showError ).to.be.true; | ||
} ); | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import { combineReducers } from 'redux'; | |
*/ | ||
import { EDITOR_START, POST_SAVE_SUCCESS } from 'state/action-types'; | ||
import imageEditor from './image-editor/reducer'; | ||
import videoEditor from './video-editor/reducer'; | ||
import lastDraft from './last-draft/reducer'; | ||
import contactForm from './contact-form/reducer'; | ||
|
||
|
@@ -33,6 +34,7 @@ export function postId( state = null, action ) { | |
export default combineReducers( { | ||
postId, | ||
imageEditor, | ||
videoEditor, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it appears like the video editor state has no reference to any particular media id or site or anything. it's "whatever is out front in the editor" but what happens if we change sites or change videos which we are working on? won't we have race-conditions with network requests on the wire? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The video editor is a modal that is opened from the media library modal. Media library modal handles passing the particular video and everything else the video editor needs to know. And because it's a modal, site switching should be a non-issue. Hope that helps clarify and makes sense. |
||
lastDraft, | ||
contactForm | ||
} ); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,8 @@ describe( 'reducer', () => { | |
'postId', | ||
'lastDraft', | ||
'contactForm', | ||
'imageEditor' | ||
'imageEditor', | ||
'videoEditor', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it proper to have a final comma in a JavaScript array? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in Calypso it is yeah. we encourage it for the effects on diffs |
||
] ); | ||
} ); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
VIDEO_EDITOR_CLOSE_MODAL, | ||
VIDEO_EDITOR_SET_POSTER_URL, | ||
VIDEO_EDITOR_SHOW_ERROR, | ||
VIDEO_EDITOR_SHOW_UPLOAD_PROGRESS, | ||
VIDEO_EDITOR_UPDATE_POSTER, | ||
} from 'state/action-types'; | ||
|
||
/** | ||
* Returns an action object to indicate that a request has been made to update the video poster. | ||
* | ||
* @param {String} videoId ID of the video | ||
* @param {Object} params Poster data | ||
* @param {Number} [params.atTime] Number of seconds into the video at which to get the poster | ||
* @param {Object} [params.file] An image to attach to the video | ||
* @return {Object} Action object | ||
*/ | ||
export const updatePoster = ( videoId, params ) => | ||
( { type: VIDEO_EDITOR_UPDATE_POSTER, videoId, params } ); | ||
|
||
/** | ||
* Returns an action object to indicate that the poster for the video has been updated successfully. | ||
* | ||
* @param {String} posterUrl Poster URL | ||
* @return {Object} Action object | ||
*/ | ||
export const setPosterUrl = posterUrl => ( { type: VIDEO_EDITOR_SET_POSTER_URL, posterUrl } ); | ||
|
||
/** | ||
* Returns an action object to indicate that the video editor modal should close. | ||
* | ||
* @return {Object} Action object | ||
*/ | ||
export const closeModal = () => ( { type: VIDEO_EDITOR_CLOSE_MODAL } ); | ||
|
||
/** | ||
* Returns an action object to indicate that the poster for the video failed to update. | ||
* | ||
* @return {Object} Action object | ||
*/ | ||
export const showError = () => ( { type: VIDEO_EDITOR_SHOW_ERROR } ); | ||
|
||
/** | ||
* Returns an action object to indicate the poster upload progress. | ||
* | ||
* @param {String} percentage Upload progress percentage | ||
* @return {Object} Action object | ||
*/ | ||
export const showUploadProgress = percentage => | ||
( { type: VIDEO_EDITOR_SHOW_UPLOAD_PROGRESS, percentage } ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comma?