Skip to content
This repository was archived by the owner on Jan 31, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 50 additions & 8 deletions public/css/media-editor.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
.media-editor {

@titleBarHeight: 60px;
@addClipHeight: 165px;
@addClipHeight: 130px;
@durationInputHeight: 48px;
@ytUploaderHeight: 385px;

.butter-editor-body {
top: @titleBarHeight;
bottom: 0;
}

.fl-right {
Expand Down Expand Up @@ -50,6 +52,28 @@
}
}

.record-webcam {
&.hidden, .hidden {
display: none;
}
#youtube-upload {
margin-top: 20px;
}
a.close-btn {
position: absolute;
top: -2px;
right: -8px;

&:hover {
cursor: pointer;
}

&.hidden {
display: none;
}
}
}

&.add-media-collapsed {
.add-media-panel {
margin: 0;
Expand All @@ -59,22 +83,37 @@
.media-gallery {
top: 0;
}
iframe {
&.hidden {
display: none;
}
}
}

.add-media-panel {
height: @addClipHeight;
.transition( all 0.2s ease );
overflow: hidden;
opacity: 1;
margin: 0 20px;

&.hidden {
display: none;
}
}

.yt-upload-panel {
position: relative;
top: 0;
}

.media-gallery {
position: absolute;
bottom: @durationInputHeight;
top: @addClipHeight + 15px;
width: 100%;
margin-top: -1px;
left: 0;
right: 0;
position: absolute;
top: @titleBarHeight + @addClipHeight;
bottom: @durationInputHeight;

.media-gallery-heading {
background: #FFF;
Expand All @@ -85,11 +124,13 @@
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
position: absolute;
top: 0;
left: 0;
right: 0;
}

&.shrink-gallery {
top: @ytUploaderHeight;
}
}

.media-gallery-base-media.butter-form-inline.form-single {
Expand Down Expand Up @@ -119,11 +160,12 @@

.media-gallery-scroll-container {
position: absolute;
top: 46px;
top: 48px;
left: 0;
right: 0;
bottom: 0;
}

.media-gallery-list {
list-style: none;
padding: 0;
Expand Down
122 changes: 118 additions & 4 deletions public/src/editor/media-gallery-editor.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
/* This Source Code Form is subject to the terms of the MIT license
* If a copy of the MIT license was not distributed with this file, you can
* obtain one at https://raw.github.com/mozilla/butter/master/LICENSE */
/*global YT */

define( [ "util/lang", "util/uri", "util/keys", "util/mediatypes", "editor/editor",
"util/time", "util/dragndrop", "text!layouts/media-editor.html" ],
function( LangUtils, URI, KeysUtils, MediaUtils, Editor, Time, DragNDrop, EDITOR_LAYOUT ) {
"util/time", "util/dragndrop", "ui/widget/tooltip", "text!layouts/media-editor.html" ],
function( LangUtils, URI, KeysUtils, MediaUtils, Editor, Time, DragNDrop, ToolTip, EDITOR_LAYOUT ) {

var _parentElement = LangUtils.domFragment( EDITOR_LAYOUT,".media-editor" ),
var _parentElement = LangUtils.domFragment( EDITOR_LAYOUT, ".media-editor" ),
_addMediaTitle = _parentElement.querySelector( ".add-new-media" ),
_addMediaPanel = _parentElement.querySelector( ".add-media-panel" ),

_recordWebcam = _parentElement.querySelector( ".record-webcam a" ),
_progress = _parentElement.querySelector( ".record-webcam p.youtube-upload-progress" ),
_ytUploadError = _parentElement.querySelector( ".record-webcam p.youtube-upload-error" ),
_closeBtn = _parentElement.querySelector( ".record-webcam a.close-btn" ),

_urlInput = _addMediaPanel.querySelector( ".add-media-input" ),
_addBtn = _addMediaPanel.querySelector( ".add-media-btn" ),
_errorMessage = _parentElement.querySelector( ".media-error-message" ),
Expand Down Expand Up @@ -39,13 +45,14 @@ define( [ "util/lang", "util/uri", "util/keys", "util/mediatypes", "editor/edito
_urlInput.value = "";

clearTimeout( _mediaLoadTimeout );
clearTimeout( _cancelSpinner );
_urlInput.classList.remove( "error" );
_addMediaPanel.classList.remove( "invalid-field" );
_errorMessage.classList.add( "hidden" );
_loadingSpinner.classList.add( "hidden" );

_addBtn.classList.add( "hidden" );

_recordWebcam.classList.remove( "hidden" );
}

function setBaseDuration( duration ) {
Expand Down Expand Up @@ -193,7 +200,10 @@ define( [ "util/lang", "util/uri", "util/keys", "util/mediatypes", "editor/edito
var el = _GALLERYITEM.cloneNode( true ),
source = data.source;


if ( !_media.clipData[ source ] ) {
clearTimeout( _cancelSpinner );
_recordWebcam.classList.remove( "hidden" );
_media.clipData[ source ] = source;
_butter.dispatch( "mediaclipadded" );

Expand Down Expand Up @@ -234,8 +244,10 @@ define( [ "util/lang", "util/uri", "util/keys", "util/mediatypes", "editor/edito
function onInput() {
if ( _urlInput.value ) {
_addBtn.classList.remove( "hidden" );
_recordWebcam.classList.add( "hidden" );
} else {
_addBtn.classList.add( "hidden" );
_recordWebcam.classList.remove( "hidden" );
}
clearTimeout( _cancelSpinner );
clearTimeout( _mediaLoadTimeout );
Expand Down Expand Up @@ -285,6 +297,108 @@ define( [ "util/lang", "util/uri", "util/keys", "util/mediatypes", "editor/edito
}
}

var loadYouTubeRecorder = function() {

var widget,
pending = false;

_ytUploadError.classList.add( "hidden" );
_closeBtn.classList.remove( "hidden" );

function closeWidget() {
pending = false;
widget.destroy();
widget = null;
_galleryPanel.classList.remove( "shrink-gallery" );
_addMediaPanel.classList.remove( "hidden" );
_closeBtn.classList.add( "hidden" );
_closeBtn.removeEventListener( "click", clickCloseBtn );
}

function clickCloseBtn() {
closeWidget();
_recordWebcam.classList.remove( "hidden" );
_progress.classList.add( "hidden" );
}

_closeBtn.addEventListener( "click", clickCloseBtn );

widget = new YT.UploadWidget( "youtube-upload", {
width: 295,
height: 295,
events: {
"onApiReady": function() {
widget.setVideoKeywords([ "webcam", "video", "popcorn" ]);
widget.setVideoPrivacy( "unlisted" );
},
"onUploadSuccess": function() {
_progress.classList.remove( "hidden" );
},
"onProcessingComplete": function( event ) {
closeWidget();
_progress.classList.add( "hidden" );
// transitionend event is not reliable and not cross browser supported.
_cancelSpinner = setTimeout( function() {
_loadingSpinner.classList.remove( "hidden" );
}, 300 );
addMediaToGallery( "http://www.youtube.com/watch?v=" + event.data.videoId, onDenied );
},
"onStateChange": function( event ) {
var state = event.data.state;

if ( state === YT.UploadWidgetState.ERROR ) {
closeWidget();
_progress.classList.add( "hidden" );
_recordWebcam.classList.remove( "hidden" );
_ytUploadError.classList.remove( "hidden" );
} else if ( state === YT.UploadWidgetState.PENDING ) {
pending = true;
} else if ( state === YT.UploadWidgetState.STOPPED ) {
if ( !pending ) {
closeWidget();
_recordWebcam.classList.remove( "hidden" );
}
}
}
}
});
};

_recordWebcam.addEventListener( "click", function() {

var tag,
protocol,
youTubeReadyFn = window.onYouTubeIframeAPIReady;

_recordWebcam.classList.add( "hidden" );
_galleryPanel.classList.add( "shrink-gallery" );
_addMediaPanel.classList.add( "hidden" );

if ( window.YT ) {
loadYouTubeRecorder();
} else {
tag = document.createElement( "script" );
protocol = window.location.protocol === "file:" ? "http:" : "";

tag.src = protocol + "//www.youtube.com/iframe_api";
document.head.appendChild( tag );

window.onYouTubeIframeAPIReady = function() {
if ( youTubeReadyFn ) {
youTubeReadyFn();
}
loadYouTubeRecorder();
};
}
}, false );

ToolTip.create({
name: "tooltip-record-media",
element: _recordWebcam,
top: "35px",
message: "Record a video with your webcam and upload it to YouTube"
});

Editor.register( "media-editor", null, function( rootElement, butter ) {
rootElement = _parentElement;
_this = this;
Expand Down
21 changes: 18 additions & 3 deletions public/src/layouts/media-editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,23 @@ <h1 class="add-new-media">Create new media clip</h1>
</div>
</fieldset>

<fieldset class="yt-upload-panel">
<div class="record-webcam">
<a class="butter-btn btn-light">
<span class="icon icon-facetime-video"></span>
Record From Webcam
</a>
<a class="close-btn hidden">
<span class="icon icon-only icon-x"></span>
</a>
<div id="youtube-upload"></div>
<p class="youtube-upload-error hidden">There was an error uploading your video to YouTube. Please try again.</p>
<p class="youtube-upload-progress hidden">Video successfully uploaded. It will be added to the gallery once YouTube finishes processing it... <img src="/resources/icons/spinny.gif" alt="Loading spinner"></p>
</div>
</fieldset>

<div class="media-gallery">
<div class="media-gallery-heading">
<div class="media-gallery-heading editor-inner">
Media Gallery
</div>
<div class="media-gallery-scroll-container scrollbar-container">
Expand All @@ -34,16 +49,16 @@ <h1 class="add-new-media">Create new media clip</h1>
<label>Duration</label>
<input type="text" class="media-base-duration" value="">
</fieldset>

</div>
</div>

<!-- This is added to media-gallery for each new media item -->
<li class="media-gallery-item">
<li class="media-gallery-item editor-inner">
<div class="mg-thumbnail"></div>
<div class="mg-meta-data">
<div class="mg-title"></div>
<div class="mg-type"></div>
<div class="mg-url"></div>
<div class="mg-duration"></div>
<div class="mg-error"></div>
</div>
Expand Down