studio-ui composer is ready to test actively
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
var _settings = drupalSettings.edlp_studio;
|
var _settings = drupalSettings.edlp_studio;
|
||||||
var $composer;
|
var $composer;
|
||||||
|
|
||||||
|
// audio play is handled by edlp_theme
|
||||||
|
|
||||||
function init(){
|
function init(){
|
||||||
console.log('Studio Init');
|
console.log('Studio Init');
|
||||||
initEvents();
|
initEvents();
|
||||||
@@ -21,11 +23,11 @@
|
|||||||
initAjaxCompoLinks();
|
initAjaxCompoLinks();
|
||||||
initDragAndDropUI();
|
initDragAndDropUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ___ _ _ _ _ _ _ _ _ _
|
// ___ _ _ _ _ _ _ _ _ _
|
||||||
// / __| |_ _ _| |_(_)___ _ _ | \| |___ __| |___ | | (_)_ _ | |__ ___
|
// / __| |_ _ _| |_(_)___ _ _ | \| |___ __| |___ | | (_)_ _ | |__ ___
|
||||||
// | (__| ' \ || | _| / -_) '_| | .` / _ \/ _` / -_) | |__| | ' \| / /(_-<
|
// | (__| ' \ || | _| / -_) '_| | .` / _ \/ _` / -_) | |__| | ' \| / /(_-<
|
||||||
// \___|_||_\_,_|\__|_\___|_| |_|\_\___/\__,_\___| |____|_|_||_|_\_\/__/
|
// \___|_||_\_,_|\__|_\___|_| |_|\_\___/\__,_\___| |____|_|_||_|_\_\/__/
|
||||||
|
|
||||||
function initAjaxChutierLinks(){
|
function initAjaxChutierLinks(){
|
||||||
console.log('studio initAjaxChutierLinks');
|
console.log('studio initAjaxChutierLinks');
|
||||||
$('.chutier-ajax-link:not(.ajax-enabled)')
|
$('.chutier-ajax-link:not(.ajax-enabled)')
|
||||||
@@ -119,6 +121,9 @@
|
|||||||
$('.composition', $composer).replaceWith(data.compo);
|
$('.composition', $composer).replaceWith(data.compo);
|
||||||
$composer.removeClass('ajax-loading');
|
$composer.removeClass('ajax-loading');
|
||||||
initDragAndDropUI();
|
initDragAndDropUI();
|
||||||
|
$('body').trigger({
|
||||||
|
'type':'on-studio-compo-opened'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
function onErrorOpenCompo(jqxhr, textStatus, error, $link){
|
function onErrorOpenCompo(jqxhr, textStatus, error, $link){
|
||||||
$link.removeClass('ajax-loading');
|
$link.removeClass('ajax-loading');
|
||||||
@@ -172,12 +177,15 @@
|
|||||||
};
|
};
|
||||||
function onCreateCompoDone(data, $link, $form){
|
function onCreateCompoDone(data, $link, $form){
|
||||||
console.log('onActionToCompoDone',data);
|
console.log('onActionToCompoDone',data);
|
||||||
|
var $new_link = $(data.new_link);
|
||||||
$link
|
$link
|
||||||
.removeClass('folded')
|
.removeClass('folded')
|
||||||
.parents('li')
|
.parents('li')
|
||||||
.before($('<li>').append(data.new_link));
|
.before($('<li>').append($new_link));
|
||||||
$form.remove();
|
$form.remove();
|
||||||
// TODO: open new composition to composer
|
// open new composition to composer
|
||||||
|
initAjaxCompoLinks();
|
||||||
|
openCompo($new_link);
|
||||||
};
|
};
|
||||||
function onErrorCreateCompo(jqxhr, textStatus, error, $link){
|
function onErrorCreateCompo(jqxhr, textStatus, error, $link){
|
||||||
console.warn('action to compo load failed : '+error, jqxhr.responseText);
|
console.warn('action to compo load failed : '+error, jqxhr.responseText);
|
||||||
@@ -219,7 +227,6 @@
|
|||||||
console.warn('delete compo load failed : '+error, jqxhr.responseText);
|
console.warn('delete compo load failed : '+error, jqxhr.responseText);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ___ _ _ _ _
|
// ___ _ _ _ _
|
||||||
// / __| |_ _ _ __| (_)___ ___ _ _(_)
|
// / __| |_ _ _ __| (_)___ ___ _ _(_)
|
||||||
// \__ \ _| || / _` | / _ \___| || | |
|
// \__ \ _| || / _` | / _ \___| || | |
|
||||||
@@ -253,7 +260,6 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ___ __ ___ _ _ ___
|
// ___ __ ___ _ _ ___
|
||||||
// | \ _ _ __ _ __ _ / _|___ | \ _ _ ___ _ __ | | | |_ _|
|
// | \ _ _ __ _ __ _ / _|___ | \ _ _ ___ _ __ | | | |_ _|
|
||||||
// | |) | '_/ _` / _` | > _|_ _| | |) | '_/ _ \ '_ \ | |_| || |
|
// | |) | '_/ _` / _` | > _|_ _| | |) | '_/ _ \ '_ \ | |_| || |
|
||||||
@@ -337,9 +343,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: how to remove an item
|
|
||||||
|
|
||||||
function onOrderChanged(e, ui){
|
function onOrderChanged(e, ui){
|
||||||
console.log('onOrderChanged : e', e);
|
console.log('onOrderChanged : e', e);
|
||||||
var cid = $(e.target).parents('.composition').attr('cid');
|
var cid = $(e.target).parents('.composition').attr('cid');
|
||||||
@@ -351,7 +354,6 @@
|
|||||||
// console.log(documents);
|
// console.log(documents);
|
||||||
recordCompoList(cid, documents);
|
recordCompoList(cid, documents);
|
||||||
};
|
};
|
||||||
|
|
||||||
function recordCompoList(cid, docs){
|
function recordCompoList(cid, docs){
|
||||||
console.log('recordCompoList '+cid, docs);
|
console.log('recordCompoList '+cid, docs);
|
||||||
var ajax_path = _settings.save_compo_ajax_url+'/'+cid;
|
var ajax_path = _settings.save_compo_ajax_url+'/'+cid;
|
||||||
@@ -366,8 +368,10 @@
|
|||||||
.fail(function(jqxhr, textStatus, error){
|
.fail(function(jqxhr, textStatus, error){
|
||||||
onErrorRecordCompo(jqxhr, textStatus, error);
|
onErrorRecordCompo(jqxhr, textStatus, error);
|
||||||
});
|
});
|
||||||
|
$('body').trigger({
|
||||||
|
'type':'on-studio-compo-updated'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRecordCompoDone(data){
|
function onRecordCompoDone(data){
|
||||||
console.log('onDeleteCompoDone',data);
|
console.log('onDeleteCompoDone',data);
|
||||||
if(data.status == "ok"){
|
if(data.status == "ok"){
|
||||||
@@ -379,7 +383,5 @@
|
|||||||
console.warn('record compo failed : '+error, jqxhr.responseText);
|
console.warn('record compo failed : '+error, jqxhr.responseText);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init();
|
init();
|
||||||
})(jQuery, Drupal, drupalSettings);
|
})(jQuery, Drupal, drupalSettings);
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class CompositionController extends ControllerBase {
|
|||||||
'#options'=>array(
|
'#options'=>array(
|
||||||
'attributes' => array(
|
'attributes' => array(
|
||||||
'data-drupal-link-system-path' => $url->getInternalPath(),
|
'data-drupal-link-system-path' => $url->getInternalPath(),
|
||||||
'nid' => $this->compo->id(),
|
'cid' => $this->compo->id(),
|
||||||
'class' => ['composition-link'],
|
'class' => ['composition-link'],
|
||||||
'title'=>$title,
|
'title'=>$title,
|
||||||
),
|
),
|
||||||
@@ -173,8 +173,10 @@ class CompositionController extends ControllerBase {
|
|||||||
$this->compo->setName($name);
|
$this->compo->setName($name);
|
||||||
}
|
}
|
||||||
$documents = array();
|
$documents = array();
|
||||||
foreach ($new_documents as $nid) {
|
if(count($new_documents)){
|
||||||
$documents[] = ['target_id'=>$nid];
|
foreach ($new_documents as $nid) {
|
||||||
|
$documents[] = ['target_id'=>$nid];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$this->compo->set('documents', $documents);
|
$this->compo->set('documents', $documents);
|
||||||
$this->compo->save();
|
$this->compo->save();
|
||||||
|
|||||||
@@ -119,7 +119,9 @@ class StudioUIController extends ControllerBase {
|
|||||||
'#composer_actions' => array(
|
'#composer_actions' => array(
|
||||||
'play_composition'=>array(
|
'play_composition'=>array(
|
||||||
"#type"=>'container',
|
"#type"=>'container',
|
||||||
"#markup"=>t('Play my composition'),
|
"#attributes"=>array(
|
||||||
|
"class"=>array("compo-player-controls")
|
||||||
|
)
|
||||||
),// TODO: add social media links (what about composition visibility uotside studio_ui ?)
|
),// TODO: add social media links (what about composition visibility uotside studio_ui ?)
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
+507
-271
@@ -6,8 +6,9 @@
|
|||||||
var _$corpus_canvas;
|
var _$corpus_canvas;
|
||||||
var _$row = $('main[role="main"]>.layout-content>.row');
|
var _$row = $('main[role="main"]>.layout-content>.row');
|
||||||
var _$ajaxLinks;
|
var _$ajaxLinks;
|
||||||
var _audio_player;
|
var _audioPlayer;
|
||||||
var _randomPlayer;
|
var _randomPlayer;
|
||||||
|
var _compoPlayer;
|
||||||
|
|
||||||
// ___ _ _
|
// ___ _ _
|
||||||
// |_ _|_ _ (_) |_
|
// |_ _|_ _ (_) |_
|
||||||
@@ -20,7 +21,8 @@
|
|||||||
|
|
||||||
_$body.on('corpus-map-ready', onCorpusMapReady);
|
_$body.on('corpus-map-ready', onCorpusMapReady);
|
||||||
|
|
||||||
_audio_player = new AudioPlayer();
|
_audioPlayer = new AudioPlayer();
|
||||||
|
_compoPlayer = new CompoPlayer();
|
||||||
|
|
||||||
initAjaxLinks();
|
initAjaxLinks();
|
||||||
|
|
||||||
@@ -42,271 +44,18 @@
|
|||||||
// |___|\_/\___|_||_\__/__/
|
// |___|\_/\___|_||_\__/__/
|
||||||
function initEvents(){
|
function initEvents(){
|
||||||
$('body')
|
$('body')
|
||||||
.on('on-studio-chutier-updated', function(e){
|
.on('on-studio-chutier-updated', initAjaxLinks)
|
||||||
|
.on('on-studio-compo-updated', function(e){
|
||||||
initAjaxLinks();
|
initAjaxLinks();
|
||||||
|
_compoPlayer.refresh();
|
||||||
})
|
})
|
||||||
.on('search-results-loaded',function(e){
|
.on('on-studio-compo-opened', function(e){
|
||||||
initAjaxLinks();
|
initAjaxLinks();
|
||||||
|
_compoPlayer.newCompo();
|
||||||
})
|
})
|
||||||
.on('open_entree', function(e){
|
.on('search-results-loaded', initAjaxLinks)
|
||||||
// e.tid available
|
.on('open_entree', closeAllModals)
|
||||||
closeAllModals();
|
.on('close_entree', backToFrontPage);
|
||||||
})
|
|
||||||
.on('close_entree', function(e){
|
|
||||||
// e.tid available
|
|
||||||
backToFrontPage();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// _ _ _
|
|
||||||
// /_\ _ _ __| (_)___
|
|
||||||
// / _ \ || / _` | / _ \
|
|
||||||
// /_/ \_\_,_\__,_|_\___/
|
|
||||||
//
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
|
|
||||||
// https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/samples/gg589528%28v%3dvs.85%29
|
|
||||||
// https://www.binarytides.com/using-html5-audio-element-javascript/
|
|
||||||
function AudioPlayer(){
|
|
||||||
var that = this;
|
|
||||||
this.fid;
|
|
||||||
this.audio = new Audio();
|
|
||||||
// audio events
|
|
||||||
this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended"];
|
|
||||||
|
|
||||||
// UI dom objects
|
|
||||||
this.$container = $('<div id="audio-player">');
|
|
||||||
// btns
|
|
||||||
this.$btns = $('<div>').addClass('btns').appendTo(this.$container);
|
|
||||||
this.$previous = $('<div>').addClass('previous').appendTo(this.$btns);
|
|
||||||
this.$playpause = $('<div>').addClass('play-pause').appendTo(this.$btns);
|
|
||||||
this.$next = $('<div>').addClass('next').appendTo(this.$btns);
|
|
||||||
// timeline
|
|
||||||
this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);
|
|
||||||
this.$timeline = $('<div>').addClass('time-line').appendTo(this.$timelinecont);
|
|
||||||
this.$loader = $('<div>').addClass('loader').appendTo(this.$timeline);
|
|
||||||
this.$cursor = $('<div>').addClass('cursor').appendTo(this.$timeline);
|
|
||||||
// time
|
|
||||||
this.$time = $('<div>').addClass('time').appendTo(this.$container);
|
|
||||||
this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);
|
|
||||||
this.$duration = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);
|
|
||||||
// favoris
|
|
||||||
this.$fav = $('<div>').addClass('favoris').appendTo(this.$container);
|
|
||||||
// cartel
|
|
||||||
this.$cartel = $('<div>').addClass('cartel').appendTo(this.$container);
|
|
||||||
|
|
||||||
// hiding
|
|
||||||
this.hideTimer = false;
|
|
||||||
this.hideTimeMS = 10000;
|
|
||||||
|
|
||||||
// history
|
|
||||||
this.currentHistoricIndex = null;
|
|
||||||
this.historic = [];
|
|
||||||
this.shuffle_is_active = false;
|
|
||||||
|
|
||||||
// object events
|
|
||||||
this.event_handlers = {
|
|
||||||
'audio-play-next':[],
|
|
||||||
'audio-ended':[],
|
|
||||||
'stop-shuffle':[]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
};
|
|
||||||
AudioPlayer.prototype = {
|
|
||||||
init(){
|
|
||||||
// append ui to document
|
|
||||||
this.$container.appendTo('header[role="banner"] .region-header');
|
|
||||||
// record timeline width
|
|
||||||
this.timeline_w = parseInt(this.$timeline.width());
|
|
||||||
// init audio events
|
|
||||||
var fn = '';
|
|
||||||
for (var i = 0; i < this.audio_events.length; i++) {
|
|
||||||
fn = this.audio_events[i];
|
|
||||||
// capitalize first letter of event (only cosmetic :p )
|
|
||||||
fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
|
|
||||||
this.audio.addEventListener(
|
|
||||||
this.audio_events[i],
|
|
||||||
this[fn].bind(this),
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
// init btns events
|
|
||||||
this.$previous.on('click', this.playPrevious.bind(this));
|
|
||||||
this.$playpause.on('click', this.togglePlayPause.bind(this));
|
|
||||||
this.$next.on('click', this.playNext.bind(this));
|
|
||||||
// TODO: previous and next btns
|
|
||||||
},
|
|
||||||
openDocument(node){
|
|
||||||
console.log('AudioPlayer openDocument', node);
|
|
||||||
this.historic.push(node);
|
|
||||||
this.currentHistoricIndex = this.historic.length-1;
|
|
||||||
// this.shuffle_mode = shuffle_mode || false;
|
|
||||||
this.launch();
|
|
||||||
},
|
|
||||||
launch(){
|
|
||||||
this.clearTimeOutToHide();
|
|
||||||
this.setSRC(this.historic[this.currentHistoricIndex].audio_url);
|
|
||||||
this.loadNode(this.historic[this.currentHistoricIndex].nid);
|
|
||||||
// emmit new playing doc (e.g.: corpus map nowing that audio played from RandomPlayer)
|
|
||||||
try {
|
|
||||||
_$corpus_canvas.trigger({
|
|
||||||
'type':'audio-node-opened',
|
|
||||||
'nid':this.historic[this.currentHistoricIndex].nid
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('AudioPlayer : _$corpus_canvas does not exists');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showHidePreviousBtn();
|
|
||||||
this.showHideNextBtn();
|
|
||||||
this.show();
|
|
||||||
},
|
|
||||||
// audio functions
|
|
||||||
setSRC(url){
|
|
||||||
// console.log('AudioPlayer setSRC : url', url);
|
|
||||||
this.audio.src = url;
|
|
||||||
},
|
|
||||||
onLoadedmetadata(){
|
|
||||||
var rem = parseInt(this.audio.duration, 10),
|
|
||||||
mins = Math.floor(rem/60,10),
|
|
||||||
secs = rem - mins*60;
|
|
||||||
this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
|
||||||
this.updateLoadingBar();
|
|
||||||
},
|
|
||||||
updateLoadingBar(){
|
|
||||||
this.$loader.css({
|
|
||||||
'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
|
|
||||||
});
|
|
||||||
if( this.audio.buffered.end(0) < this.audio.duration ){
|
|
||||||
// loop through this function until file is fully loaded
|
|
||||||
var that = this;
|
|
||||||
window.requestAnimationFrame(that.updateLoadingBar.bind(that));
|
|
||||||
}else{
|
|
||||||
console.log('Audio fully loaded');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCanplay(){
|
|
||||||
this.play();
|
|
||||||
},
|
|
||||||
play(){
|
|
||||||
this.audio.play();
|
|
||||||
},
|
|
||||||
playPrevious(){
|
|
||||||
if(this.currentHistoricIndex > 0){
|
|
||||||
this.currentHistoricIndex -= 1;
|
|
||||||
this.launch();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
playNext(){
|
|
||||||
if(this.currentHistoricIndex < this.historic.length-1){
|
|
||||||
this.currentHistoricIndex += 1;
|
|
||||||
this.launch();
|
|
||||||
}else{
|
|
||||||
this.emmit('audio-play-next');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
togglePlayPause(e){
|
|
||||||
if(this.audio.paused){
|
|
||||||
this.audio.play();
|
|
||||||
}else{
|
|
||||||
this.audio.pause();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stop(){
|
|
||||||
console.log('AudioPlayer stop()');
|
|
||||||
this.audio.pause();
|
|
||||||
this.timeOutToHide();
|
|
||||||
},
|
|
||||||
// audio events
|
|
||||||
onPlaying(){
|
|
||||||
this.$container.addClass('is-playing');
|
|
||||||
},
|
|
||||||
onPause(){
|
|
||||||
this.$container.removeClass('is-playing');
|
|
||||||
},
|
|
||||||
onTimeupdate(){
|
|
||||||
// move cursor
|
|
||||||
this.$cursor.css({
|
|
||||||
'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px"
|
|
||||||
});
|
|
||||||
// update time text display
|
|
||||||
var rem = parseInt(this.audio.currentTime, 10),
|
|
||||||
mins = Math.floor(rem/60,10),
|
|
||||||
secs = rem - mins*60;
|
|
||||||
this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
|
||||||
},
|
|
||||||
onEnded(){
|
|
||||||
this.emmit('audio-ended');
|
|
||||||
this.stop();
|
|
||||||
},
|
|
||||||
// cartel functions
|
|
||||||
loadNode(nid){
|
|
||||||
this.$cartel.addClass('loading');
|
|
||||||
$.getJSON('/edlp/ajax/json/node/'+nid+'/player_cartel', {})
|
|
||||||
.done(this.onNodeLoaded.bind(this))
|
|
||||||
.fail(this.onNodeLoadFail.bind(this));
|
|
||||||
},
|
|
||||||
onNodeLoaded(data){
|
|
||||||
console.log('AudioPlayer node loaded');
|
|
||||||
this.$cartel.html(data.rendered).removeClass('loading');
|
|
||||||
_$body.trigger({'type':'new-audio-cartel-loaded'});
|
|
||||||
initAjaxLinks();
|
|
||||||
},
|
|
||||||
onNodeLoadFail(jqxhr, textStatus, error){
|
|
||||||
console.warn('AudioPlayer node load failed', jqxhr.responseText);
|
|
||||||
this.$cartel.removeClass('loading').html('');
|
|
||||||
},
|
|
||||||
// global
|
|
||||||
show(){
|
|
||||||
this.$container.addClass('visible');
|
|
||||||
},
|
|
||||||
showHidePreviousBtn(){
|
|
||||||
if(this.historic.length > 1 && this.currentHistoricIndex > 0){
|
|
||||||
this.$previous.addClass('is-active');
|
|
||||||
}else{
|
|
||||||
this.$previous.removeClass('is-active');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showHideNextBtn(){
|
|
||||||
if(this.currentHistoricIndex < this.historic.length-1 || this.shuffle_is_active){
|
|
||||||
this.$next.addClass('is-active');
|
|
||||||
}else{
|
|
||||||
this.$next.removeClass('is-active');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timeOutToHide(){
|
|
||||||
console.log('AudioPlayer timeOutToHide()');
|
|
||||||
this.clearTimeOutToHide();
|
|
||||||
this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS);
|
|
||||||
},
|
|
||||||
clearTimeOutToHide(){
|
|
||||||
console.log('AudioPlayer clearTimeOutToHide()',this.hideTimer);
|
|
||||||
if(this.hideTimer){
|
|
||||||
clearTimeout(this.hideTimer);
|
|
||||||
this.hideTimer = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hide(){
|
|
||||||
console.log('AudioPlayer hide()');
|
|
||||||
this.$container.removeClass('visible');
|
|
||||||
// trigger highlighted node remove on corpus map
|
|
||||||
_$corpus_canvas.trigger('audio-node-closed');
|
|
||||||
},
|
|
||||||
// object events
|
|
||||||
on(event_name, handler){
|
|
||||||
if(typeof this.event_handlers[event_name] == 'undefined'){
|
|
||||||
console.warn('AudioPlayer : event '+event_name+' does not exists');
|
|
||||||
}
|
|
||||||
this.event_handlers[event_name].push(handler);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
emmit(event_name){
|
|
||||||
var handler;
|
|
||||||
for (var i = this.event_handlers[event_name].length; i >= 0 ; i--) {
|
|
||||||
handler = this.event_handlers[event_name][i];
|
|
||||||
setTimeout(handler, 0);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ___ _ _ ___
|
// ___ _ _ ___
|
||||||
@@ -365,7 +114,7 @@
|
|||||||
// Audio links
|
// Audio links
|
||||||
if($link.is('.audio-link')){
|
if($link.is('.audio-link')){
|
||||||
// TODO: stop randomplayer
|
// TODO: stop randomplayer
|
||||||
_audio_player
|
_audioPlayer
|
||||||
.emmit('stop-shuffle')
|
.emmit('stop-shuffle')
|
||||||
.openDocument({
|
.openDocument({
|
||||||
nid:$link.attr('nid'),
|
nid:$link.attr('nid'),
|
||||||
@@ -521,7 +270,7 @@
|
|||||||
})
|
})
|
||||||
.on('corpus-cliked-on-node', function(e) {
|
.on('corpus-cliked-on-node', function(e) {
|
||||||
console.log('theme : corpus-cliked-on-node', e);
|
console.log('theme : corpus-cliked-on-node', e);
|
||||||
_audio_player
|
_audioPlayer
|
||||||
.emmit('stop-shuffle')
|
.emmit('stop-shuffle')
|
||||||
.openDocument(e.target_node);
|
.openDocument(e.target_node);
|
||||||
});
|
});
|
||||||
@@ -531,6 +280,284 @@
|
|||||||
_$body.attr('corpus-map', 'ready');
|
_$body.attr('corpus-map', 'ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _ _ _
|
||||||
|
// /_\ _ _ __| (_)___
|
||||||
|
// / _ \ || / _` | / _ \
|
||||||
|
// /_/ \_\_,_\__,_|_\___/
|
||||||
|
//
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
|
||||||
|
// https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/samples/gg589528%28v%3dvs.85%29
|
||||||
|
// https://www.binarytides.com/using-html5-audio-element-javascript/
|
||||||
|
function AudioPlayer(){
|
||||||
|
var that = this;
|
||||||
|
this.fid;
|
||||||
|
this.audio = new Audio();
|
||||||
|
// audio events
|
||||||
|
this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended"];
|
||||||
|
|
||||||
|
// UI dom objects
|
||||||
|
this.$container = $('<div id="audio-player">');
|
||||||
|
// btns
|
||||||
|
this.$btns = $('<div>').addClass('btns').appendTo(this.$container);
|
||||||
|
this.$previous = $('<div>').addClass('previous').appendTo(this.$btns);
|
||||||
|
this.$playpause = $('<div>').addClass('play-pause').appendTo(this.$btns);
|
||||||
|
this.$next = $('<div>').addClass('next').appendTo(this.$btns);
|
||||||
|
// timeline
|
||||||
|
this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);
|
||||||
|
this.$timeline = $('<div>').addClass('time-line').appendTo(this.$timelinecont);
|
||||||
|
this.$loader = $('<div>').addClass('loader').appendTo(this.$timeline);
|
||||||
|
this.$cursor = $('<div>').addClass('cursor').appendTo(this.$timeline);
|
||||||
|
// time
|
||||||
|
this.$time = $('<div>').addClass('time').appendTo(this.$container);
|
||||||
|
this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);
|
||||||
|
this.$duration = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);
|
||||||
|
// favoris
|
||||||
|
this.$fav = $('<div>').addClass('favoris').appendTo(this.$container);
|
||||||
|
// cartel
|
||||||
|
this.$cartel = $('<div>').addClass('cartel').appendTo(this.$container);
|
||||||
|
|
||||||
|
// hiding
|
||||||
|
this.hideTimer = false;
|
||||||
|
this.hideTimeMS = 10000;
|
||||||
|
|
||||||
|
// history
|
||||||
|
this.currentHistoricIndex = null;
|
||||||
|
this.historic = [];
|
||||||
|
this.shuffle_is_active = false;
|
||||||
|
|
||||||
|
// object events
|
||||||
|
this.event_handlers = {
|
||||||
|
'audio-open-document':[],
|
||||||
|
'audio-play':[],
|
||||||
|
'audio-pause':[],
|
||||||
|
'audio-play-next':[],
|
||||||
|
'audio-ended':[],
|
||||||
|
'stop-shuffle':[]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
};
|
||||||
|
AudioPlayer.prototype = {
|
||||||
|
init(){
|
||||||
|
// append ui to document
|
||||||
|
this.$container.appendTo('header[role="banner"] .region-header');
|
||||||
|
// record timeline width
|
||||||
|
this.timeline_w = parseInt(this.$timeline.width());
|
||||||
|
// init audio events
|
||||||
|
var fn = '';
|
||||||
|
for (var i = 0; i < this.audio_events.length; i++) {
|
||||||
|
fn = this.audio_events[i];
|
||||||
|
// capitalize first letter of event (only cosmetic :p )
|
||||||
|
fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
|
||||||
|
this.audio.addEventListener(
|
||||||
|
this.audio_events[i],
|
||||||
|
this[fn].bind(this),
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
// init btns events
|
||||||
|
this.$previous.on('click', this.playPrevious.bind(this));
|
||||||
|
this.$playpause.on('click', this.togglePlayPause.bind(this));
|
||||||
|
this.$next.on('click', this.playNext.bind(this));
|
||||||
|
// TODO: previous and next btns
|
||||||
|
},
|
||||||
|
openDocument(node, caller){
|
||||||
|
// console.log('AudioPlayer openDocument', node);
|
||||||
|
if(typeof node == 'undefined'
|
||||||
|
|| typeof node.nid == 'undefined'
|
||||||
|
|| typeof node.audio_url == 'undfined'){
|
||||||
|
console.warn('AudioPlayer openDocument() node is malformed', node);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.historic.push(node);
|
||||||
|
this.currentHistoricIndex = this.historic.length-1;
|
||||||
|
// this.shuffle_mode = shuffle_mode || false;
|
||||||
|
|
||||||
|
this.emmit('audio-open-document', {caller:caller});
|
||||||
|
|
||||||
|
this.launch();
|
||||||
|
},
|
||||||
|
launch(){
|
||||||
|
this.clearTimeOutToHide();
|
||||||
|
this.setSRC(this.historic[this.currentHistoricIndex].audio_url);
|
||||||
|
this.loadNode(this.historic[this.currentHistoricIndex].nid);
|
||||||
|
// emmit new playing doc (e.g.: corpus map nowing that audio played from RandomPlayer)
|
||||||
|
try {
|
||||||
|
_$corpus_canvas.trigger({
|
||||||
|
'type':'audio-node-opened',
|
||||||
|
'nid':this.historic[this.currentHistoricIndex].nid
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.info('AudioPlayer : _$corpus_canvas does not exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showHidePreviousBtn();
|
||||||
|
this.showHideNextBtn();
|
||||||
|
this.show();
|
||||||
|
},
|
||||||
|
// audio functions
|
||||||
|
setSRC(url){
|
||||||
|
// console.log('AudioPlayer setSRC : url', url);
|
||||||
|
this.audio.src = url;
|
||||||
|
},
|
||||||
|
onLoadedmetadata(){
|
||||||
|
var rem = parseInt(this.audio.duration, 10),
|
||||||
|
mins = Math.floor(rem/60,10),
|
||||||
|
secs = rem - mins*60;
|
||||||
|
this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
||||||
|
this.updateLoadingBar();
|
||||||
|
},
|
||||||
|
updateLoadingBar(){
|
||||||
|
this.$loader.css({
|
||||||
|
'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
|
||||||
|
});
|
||||||
|
if( this.audio.buffered.end(0) < this.audio.duration ){
|
||||||
|
// loop through this function until file is fully loaded
|
||||||
|
var that = this;
|
||||||
|
window.requestAnimationFrame(that.updateLoadingBar.bind(that));
|
||||||
|
}else{
|
||||||
|
console.log('Audio fully loaded');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCanplay(){
|
||||||
|
this.play();
|
||||||
|
},
|
||||||
|
play(){
|
||||||
|
this.clearTimeOutToHide();
|
||||||
|
this.audio.play();
|
||||||
|
},
|
||||||
|
playPrevious(){
|
||||||
|
if(this.currentHistoricIndex > 0){
|
||||||
|
this.currentHistoricIndex -= 1;
|
||||||
|
this.launch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
playNext(){
|
||||||
|
if(this.currentHistoricIndex < this.historic.length-1){
|
||||||
|
this.currentHistoricIndex += 1;
|
||||||
|
this.launch();
|
||||||
|
}else{
|
||||||
|
this.emmit('audio-play-next');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
togglePlayPause(e){
|
||||||
|
if(this.audio.paused){
|
||||||
|
this.audio.play();
|
||||||
|
}else{
|
||||||
|
this.audio.pause();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stop(){
|
||||||
|
// console.log('AudioPlayer stop()');
|
||||||
|
this.audio.pause();
|
||||||
|
this.timeOutToHide();
|
||||||
|
},
|
||||||
|
// audio events
|
||||||
|
onPlaying(){
|
||||||
|
this.$btns.addClass('is-playing');
|
||||||
|
this.emmit('audio-play');
|
||||||
|
},
|
||||||
|
onPause(){
|
||||||
|
this.$btns.removeClass('is-playing');
|
||||||
|
this.emmit('audio-pause');
|
||||||
|
},
|
||||||
|
onTimeupdate(){
|
||||||
|
// move cursor
|
||||||
|
this.$cursor.css({
|
||||||
|
'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px"
|
||||||
|
});
|
||||||
|
// update time text display
|
||||||
|
var rem = parseInt(this.audio.currentTime, 10),
|
||||||
|
mins = Math.floor(rem/60,10),
|
||||||
|
secs = rem - mins*60;
|
||||||
|
this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
||||||
|
},
|
||||||
|
onEnded(){
|
||||||
|
this.emmit('audio-ended');
|
||||||
|
this.stop();
|
||||||
|
},
|
||||||
|
// cartel functions
|
||||||
|
loadNode(nid){
|
||||||
|
this.$cartel.addClass('loading');
|
||||||
|
$.getJSON('/edlp/ajax/json/node/'+nid+'/player_cartel', {})
|
||||||
|
.done(this.onNodeLoaded.bind(this))
|
||||||
|
.fail(this.onNodeLoadFail.bind(this));
|
||||||
|
},
|
||||||
|
onNodeLoaded(data){
|
||||||
|
// console.log('AudioPlayer node loaded');
|
||||||
|
this.$cartel.html(data.rendered).removeClass('loading');
|
||||||
|
_$body.trigger({'type':'new-audio-cartel-loaded'});
|
||||||
|
initAjaxLinks();
|
||||||
|
},
|
||||||
|
onNodeLoadFail(jqxhr, textStatus, error){
|
||||||
|
console.warn('AudioPlayer node load failed', jqxhr.responseText);
|
||||||
|
this.$cartel.removeClass('loading').html('');
|
||||||
|
},
|
||||||
|
// global
|
||||||
|
show(){
|
||||||
|
this.$container.addClass('visible');
|
||||||
|
},
|
||||||
|
showHidePreviousBtn(){
|
||||||
|
if(this.historic.length > 1 && this.currentHistoricIndex > 0){
|
||||||
|
this.$previous.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$previous.removeClass('is-active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showHideNextBtn(){
|
||||||
|
if(this.currentHistoricIndex < this.historic.length-1 || this.shuffle_is_active){
|
||||||
|
this.$next.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$next.removeClass('is-active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timeOutToHide(){
|
||||||
|
// console.log('AudioPlayer timeOutToHide()');
|
||||||
|
this.clearTimeOutToHide();
|
||||||
|
this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS);
|
||||||
|
},
|
||||||
|
clearTimeOutToHide(){
|
||||||
|
// console.log('AudioPlayer clearTimeOutToHide()',this.hideTimer);
|
||||||
|
if(this.hideTimer){
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.hideTimer = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hide(){
|
||||||
|
// console.log('AudioPlayer hide()');
|
||||||
|
this.$container.removeClass('visible');
|
||||||
|
// trigger highlighted node remove on corpus map
|
||||||
|
try {
|
||||||
|
_$corpus_canvas.trigger('audio-node-closed');
|
||||||
|
} catch (e) {
|
||||||
|
console.info('AudioPlayer hide() : _$corpus_canvas does not exists');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// object events
|
||||||
|
on(event_name, handler){
|
||||||
|
if(typeof this.event_handlers[event_name] == 'undefined'){
|
||||||
|
console.warn('AudioPlayer : event '+event_name+' does not exists');
|
||||||
|
}
|
||||||
|
this.event_handlers[event_name].push(handler);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
emmit(event_name, args){
|
||||||
|
// console.log('AudioPlayer emmit() event_name', event_name);
|
||||||
|
// console.log('AudioPlayer emmit() handlers', this.event_handlers[event_name]);
|
||||||
|
var handler;
|
||||||
|
var args = args || {};
|
||||||
|
for (var i = this.event_handlers[event_name].length-1; i >= 0 ; i--) {
|
||||||
|
handler = this.event_handlers[event_name][i];
|
||||||
|
// console.log('AudioPlayer emmit() loop handler', handler);
|
||||||
|
setTimeout(function(){
|
||||||
|
// console.log('AudioPlayer emmit() timeout handler', handler);
|
||||||
|
handler(args);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// ___ _ ___ _
|
// ___ _ ___ _
|
||||||
// | _ \__ _ _ _ __| |___ _ __ | _ \ |__ _ _ _ ___ _ _
|
// | _ \__ _ _ _ __| |___ _ __ | _ \ |__ _ _ _ ___ _ _
|
||||||
// | / _` | ' \/ _` / _ \ ' \| _/ / _` | || / -_) '_|
|
// | / _` | ' \/ _` / _ \ ' \| _/ / _` | || / -_) '_|
|
||||||
@@ -540,7 +567,7 @@
|
|||||||
this.active = false;
|
this.active = false;
|
||||||
this.playlist = playlist;
|
this.playlist = playlist;
|
||||||
this.$btn = $('<a>').html('Shuffle').addClass('random-player-btn');
|
this.$btn = $('<a>').html('Shuffle').addClass('random-player-btn');
|
||||||
this.init()
|
this.init();
|
||||||
};
|
};
|
||||||
RandomPlayer.prototype = {
|
RandomPlayer.prototype = {
|
||||||
init(){
|
init(){
|
||||||
@@ -554,7 +581,7 @@
|
|||||||
this.$btn.on('click', this.toggleActive.bind(this));
|
this.$btn.on('click', this.toggleActive.bind(this));
|
||||||
|
|
||||||
// attach an event on AudioPlayer
|
// attach an event on AudioPlayer
|
||||||
_audio_player
|
_audioPlayer
|
||||||
.on('audio-ended', this.onAudioPlayerEnded.bind(this))
|
.on('audio-ended', this.onAudioPlayerEnded.bind(this))
|
||||||
.on('audio-play-next', this.onAudioPlayNext.bind(this))
|
.on('audio-play-next', this.onAudioPlayNext.bind(this))
|
||||||
.on('stop-shuffle', this.stop.bind(this));
|
.on('stop-shuffle', this.stop.bind(this));
|
||||||
@@ -579,20 +606,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
start(){
|
start(){
|
||||||
this.active = _audio_player.shuffle_is_active = true;
|
this.active = _audioPlayer.shuffle_is_active = true;
|
||||||
this.$btn.addClass('is-active');
|
this.$btn.addClass('is-active');
|
||||||
this.shuffle();
|
this.shuffle();
|
||||||
this.next();
|
this.next();
|
||||||
},
|
},
|
||||||
stop(){
|
stop(){
|
||||||
this.active = _audio_player.shuffle_is_active = false;
|
this.active = _audioPlayer.shuffle_is_active = false;
|
||||||
this.$btn.removeClass('is-active');
|
this.$btn.removeClass('is-active');
|
||||||
// stop audio player
|
// stop audio player
|
||||||
// _audio_player.stop();
|
// _audioPlayer.stop();
|
||||||
},
|
},
|
||||||
next(){
|
next(){
|
||||||
if(this.active && this.shuffledPlaylist.length > 0)
|
if(this.active && this.shuffledPlaylist.length > 0)
|
||||||
_audio_player.openDocument(this.shuffledPlaylist.splice(0,1)[0]);
|
_audioPlayer.openDocument(this.shuffledPlaylist.splice(0,1)[0]);
|
||||||
},
|
},
|
||||||
onAudioPlayNext(){
|
onAudioPlayNext(){
|
||||||
console.log('RandomPlayer : onAudioPlayNext()');
|
console.log('RandomPlayer : onAudioPlayNext()');
|
||||||
@@ -604,6 +631,215 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ___ ___ _
|
||||||
|
// / __|___ _ __ _ __ ___| _ \ |__ _ _ _ ___ _ _
|
||||||
|
// | (__/ _ \ ' \| '_ \/ _ \ _/ / _` | || / -_) '_|
|
||||||
|
// \___\___/_|_|_| .__/\___/_| |_\__,_|\_, \___|_|
|
||||||
|
// |_| |__/
|
||||||
|
function CompoPlayer(){
|
||||||
|
this.playing = false;
|
||||||
|
this.paused = false;
|
||||||
|
this.playlist = [];
|
||||||
|
this.current_index = 0;
|
||||||
|
this.$compo = null;
|
||||||
|
this.init();
|
||||||
|
};
|
||||||
|
CompoPlayer.prototype = {
|
||||||
|
init(){
|
||||||
|
console.log('CompoPlayer init()');
|
||||||
|
// attach an event on AudioPlayer
|
||||||
|
_audioPlayer
|
||||||
|
.on('audio-open-document', this.onAudioOpenDocument.bind(this))
|
||||||
|
.on('audio-play', this.onAudioPlayerPlay.bind(this))
|
||||||
|
.on('audio-pause', this.onAudioPlayerPause.bind(this))
|
||||||
|
.on('audio-ended', this.onAudioPlayerEnded.bind(this));
|
||||||
|
// .on('audio-play-next', this.onAudioPlayNext.bind(this));
|
||||||
|
|
||||||
|
this.newCompo();
|
||||||
|
},
|
||||||
|
newCompo(){
|
||||||
|
console.log('CompoPlayer newCompo()');
|
||||||
|
// $('.composition_ui .composer .composition .field--name-documents')
|
||||||
|
this.$composer = $('.composition_ui .composer');
|
||||||
|
this.$compo = $('.composition_ui .composer .composition');
|
||||||
|
this.$controls = $('.composition_ui .composer .compo-player-controls');
|
||||||
|
this.$previous = $('<div>').addClass('previous')
|
||||||
|
.on('click', this.prev.bind(this))
|
||||||
|
.appendTo(this.$controls);
|
||||||
|
this.$playpause = $('<div>').addClass('play-pause')
|
||||||
|
.on('click', this.togglePlayPause.bind(this))
|
||||||
|
.appendTo(this.$controls);
|
||||||
|
this.$next = $('<div>').addClass('next')
|
||||||
|
.on('click', this.next.bind(this))
|
||||||
|
.appendTo(this.$controls);
|
||||||
|
// this.$playpause = $('.compo-player-controls', this.$composer)
|
||||||
|
// .on('click', this.togglePlayPause.bind(this));
|
||||||
|
this.refresh();
|
||||||
|
},
|
||||||
|
refresh(){
|
||||||
|
// console.log('CompoPlayer refresh(), this', this);
|
||||||
|
// this.playing = false;
|
||||||
|
// this.paused = false;
|
||||||
|
// this.resetIndex();
|
||||||
|
this.stop();
|
||||||
|
|
||||||
|
// load new playlist
|
||||||
|
this.playlist = [];
|
||||||
|
var that = this;
|
||||||
|
$('.field--name-documents .field__item',this.$compo).each(function(i,el){
|
||||||
|
var $link = $('a.audio-link',this);
|
||||||
|
that.playlist.push({
|
||||||
|
item:$(this),
|
||||||
|
audio_url:$link.attr("audio_url"),
|
||||||
|
nid:$link.attr("nid"),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.showHideControls();
|
||||||
|
},
|
||||||
|
togglePlayPause(){
|
||||||
|
// console.log('CompoPlayer togglePlayPause');
|
||||||
|
if (this.playing && !this.paused) {
|
||||||
|
this.pause();
|
||||||
|
}else{
|
||||||
|
if(this.playing && this.paused){
|
||||||
|
this.play();
|
||||||
|
}else{
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
start(){
|
||||||
|
console.log('start');
|
||||||
|
// console.log('CompoPlayer start()');
|
||||||
|
this.playing = true;
|
||||||
|
this.play();
|
||||||
|
},
|
||||||
|
play(){
|
||||||
|
// console.log('play');
|
||||||
|
if(this.paused){
|
||||||
|
this.paused = false;
|
||||||
|
_audioPlayer.play();
|
||||||
|
}else{
|
||||||
|
_audioPlayer.openDocument(this.playlist[this.current_index], this);
|
||||||
|
}
|
||||||
|
this.setActiveItem().showHideControls();
|
||||||
|
},
|
||||||
|
pause(){
|
||||||
|
console.log('pause');
|
||||||
|
this.paused = true;
|
||||||
|
this.showHideControls();
|
||||||
|
_audioPlayer.stop();
|
||||||
|
},
|
||||||
|
next(){
|
||||||
|
// console.log('CompoPlayer next()');
|
||||||
|
if(this.playing){
|
||||||
|
this.current_index += 1;
|
||||||
|
if(this.current_index < this.playlist.length){
|
||||||
|
this.play();
|
||||||
|
}else{
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
prev(){
|
||||||
|
// console.log('CompoPlayer prev()');
|
||||||
|
if(this.playing){
|
||||||
|
this.current_index -= 1;
|
||||||
|
if(this.current_index >= 0){
|
||||||
|
this.play();
|
||||||
|
}else{
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stop(){
|
||||||
|
_audioPlayer.stop();
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
reset(){
|
||||||
|
this.playing = false;
|
||||||
|
this.paused = false;
|
||||||
|
this.resetIndex();
|
||||||
|
},
|
||||||
|
resetIndex(){
|
||||||
|
this.current_index = 0;
|
||||||
|
this.showHideControls().resetActiveItems();
|
||||||
|
},
|
||||||
|
setActiveItem(){
|
||||||
|
this.resetActiveItems();
|
||||||
|
if(this.playing && this.current_index >= 0){
|
||||||
|
this.playlist[this.current_index].item.addClass('is-active');
|
||||||
|
}
|
||||||
|
// this call shoud not be here
|
||||||
|
this.showHideControls();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
resetActiveItems(){
|
||||||
|
for (var n = 0; n < this.playlist.length; n++) {
|
||||||
|
// console.log('node',node);
|
||||||
|
this.playlist[n].item.removeClass('is-active');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
showHideControls(){
|
||||||
|
// console.log('CompoPlayer showHideNextBtn(), playing:'+this.playing+', paused:'+this.paused);
|
||||||
|
// global playing
|
||||||
|
if(this.playing && !this.paused){
|
||||||
|
this.$controls.addClass('is-playing');
|
||||||
|
}else{
|
||||||
|
this.$controls.removeClass('is-playing');
|
||||||
|
}
|
||||||
|
// playpause
|
||||||
|
if(this.playlist.length > 0){
|
||||||
|
this.$playpause.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$playpause.removeClass('is-active');
|
||||||
|
}
|
||||||
|
// next
|
||||||
|
if(this.playing && this.playlist.length > 1 && this.current_index < this.playlist.length -1){
|
||||||
|
this.$next.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$next.removeClass('is-active');
|
||||||
|
}
|
||||||
|
// previous
|
||||||
|
if(this.playing && this.playlist.length > 1 && this.current_index > 0){
|
||||||
|
this.$previous.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$previous.removeClass('is-active');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
// _audioPlayer events
|
||||||
|
onAudioOpenDocument(args){
|
||||||
|
if(args.caller !== this){
|
||||||
|
// console.log('CompoPlayer onAudioOpenDocument() called by other');
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
// else{
|
||||||
|
// // console.log('CompoPlayer onAudioOpenDocument() self calling');
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
onAudioPlayerPlay(){
|
||||||
|
if(this.playing && this.paused){
|
||||||
|
this.paused = false;
|
||||||
|
this.showHideControls();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAudioPlayerPause(){
|
||||||
|
if(this.playing && !this.paused){
|
||||||
|
this.paused = true;
|
||||||
|
this.showHideControls();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAudioPlayerEnded(){
|
||||||
|
this.next();
|
||||||
|
},
|
||||||
|
// onAudioPlayNext(){
|
||||||
|
// this.next();
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ___ _ _ _
|
// ___ _ _ _
|
||||||
// | _ \_ _ ___ __| |_ _ __| |_(_)___ _ _ ___
|
// | _ \_ _ ___ __| |_ _ __| |_(_)___ _ _ ___
|
||||||
// | _/ '_/ _ \/ _` | || / _| _| / _ \ ' \(_-<
|
// | _/ '_/ _ \/ _` | || / _| _| / _ \ ' \(_-<
|
||||||
|
|||||||
@@ -1371,6 +1371,8 @@ main[role="main"] span.close-col-btn {
|
|||||||
background-image: url(../img/audio-player-play.svg);
|
background-image: url(../img/audio-player-play.svg);
|
||||||
padding: 0 0.3em;
|
padding: 0 0.3em;
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
#audio-player .btns.is-playing .play-pause {
|
||||||
|
background-image: url(../img/audio-player-pause.svg); }
|
||||||
#audio-player .btns .previous, #audio-player .btns .next {
|
#audio-player .btns .previous, #audio-player .btns .next {
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
-webkit-transition: opacity 0.3s ease-in-out;
|
-webkit-transition: opacity 0.3s ease-in-out;
|
||||||
@@ -1506,8 +1508,6 @@ main[role="main"] span.close-col-btn {
|
|||||||
font-size: 0.75em; }
|
font-size: 0.75em; }
|
||||||
#audio-player .cartel:hover .second-cartel {
|
#audio-player .cartel:hover .second-cartel {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
#audio-player.is-playing .btns .play-pause {
|
|
||||||
background-image: url(../img/audio-player-pause.svg); }
|
|
||||||
|
|
||||||
.chutier-icon {
|
.chutier-icon {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
@@ -1697,6 +1697,17 @@ main[role="main"] span.close-col-btn {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-right: 5px; }
|
margin-right: 5px; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .compositions-list a.composition-link.ajax-loading:before {
|
||||||
|
-webkit-animation: rotation 2s infinite linear;
|
||||||
|
animation: rotation 2s infinite linear; }
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
from {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
transform: rotate(0deg); }
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(359deg);
|
||||||
|
transform: rotate(359deg); } }
|
||||||
#studio-ui .composition_ui > .wrapper .compositions-list a.composition-link.is-active:before {
|
#studio-ui .composition_ui > .wrapper .compositions-list a.composition-link.is-active:before {
|
||||||
background-color: black; }
|
background-color: black; }
|
||||||
#studio-ui .composition_ui > .wrapper .compositions-list a.delete-composition-link {
|
#studio-ui .composition_ui > .wrapper .compositions-list a.delete-composition-link {
|
||||||
@@ -1751,13 +1762,19 @@ main[role="main"] span.close-col-btn {
|
|||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding-left: 0.5em;
|
padding-left: 0.5em;
|
||||||
width: 69%; }
|
width: 69%;
|
||||||
|
opacity: 1;
|
||||||
|
-webkit-transition: opacity 0.3s ease-in-out;
|
||||||
|
transition: opacity 0.3s ease-in-out; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer.ajax-loading {
|
||||||
|
opacity: 0.3; }
|
||||||
#studio-ui .composition_ui > .wrapper .composer > * {
|
#studio-ui .composition_ui > .wrapper .composer > * {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box; }
|
box-sizing: border-box; }
|
||||||
#studio-ui .composition_ui > .wrapper .composer > header {
|
#studio-ui .composition_ui > .wrapper .composer > header {
|
||||||
height: 25px;
|
height: 25px;
|
||||||
padding-bottom: 5px; }
|
padding-bottom: 5px;
|
||||||
|
font-size: 0.756em; }
|
||||||
#studio-ui .composition_ui > .wrapper .composer > .composition {
|
#studio-ui .composition_ui > .wrapper .composer > .composition {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(100% - 60px);
|
height: calc(100% - 60px);
|
||||||
@@ -1785,10 +1802,10 @@ main[role="main"] span.close-col-btn {
|
|||||||
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item {
|
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 25px;
|
|
||||||
height: 100%;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
width: 25px;
|
||||||
|
height: 100%;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
-webkit-transition: opacity 0.1s ease-in-out;
|
-webkit-transition: opacity 0.1s ease-in-out;
|
||||||
transition: opacity 0.1s ease-in-out; }
|
transition: opacity 0.1s ease-in-out; }
|
||||||
@@ -1810,6 +1827,7 @@ main[role="main"] span.close-col-btn {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
text-transform: none; }
|
text-transform: none; }
|
||||||
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item article h2 a {
|
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item article h2 a {
|
||||||
|
white-space: nowrap !important;
|
||||||
font-size: 0.756em; }
|
font-size: 0.756em; }
|
||||||
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item article h2 a:before {
|
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item article h2 a:before {
|
||||||
content: "";
|
content: "";
|
||||||
@@ -1835,6 +1853,8 @@ main[role="main"] span.close-col-btn {
|
|||||||
transform: rotateZ(-45deg);
|
transform: rotateZ(-45deg);
|
||||||
border: 1px solid red;
|
border: 1px solid red;
|
||||||
background-color: white; }
|
background-color: white; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .composition .field--name-documents .field__item.is-active .handler {
|
||||||
|
background-color: red; }
|
||||||
#studio-ui .composition_ui > .wrapper .composer > .composition .remove-drop-zone {
|
#studio-ui .composition_ui > .wrapper .composer > .composition .remove-drop-zone {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -1845,13 +1865,38 @@ main[role="main"] span.close-col-btn {
|
|||||||
#studio-ui .composition_ui > .wrapper .composer > .actions {
|
#studio-ui .composition_ui > .wrapper .composer > .actions {
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
height: 25px; }
|
height: 25px; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls > * {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 20px;
|
||||||
|
height: 30px;
|
||||||
|
background-position: center;
|
||||||
|
background-size: contain; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .play-pause {
|
||||||
|
background-image: url(../img/audio-player-play.svg);
|
||||||
|
padding: 0 0.3em;
|
||||||
|
cursor: pointer; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls.is-playing .play-pause {
|
||||||
|
background-image: url(../img/audio-player-pause.svg); }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .previous, #studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .next {
|
||||||
|
opacity: 0.3;
|
||||||
|
-webkit-transition: opacity 0.3s ease-in-out;
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
cursor: auto; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .previous.is-active, #studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .next.is-active {
|
||||||
|
opacity: 1;
|
||||||
|
cursor: pointer; }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .previous {
|
||||||
|
background-image: url(../img/audio-player-previous.svg); }
|
||||||
|
#studio-ui .composition_ui > .wrapper .composer > .actions .compo-player-controls .next {
|
||||||
|
background-image: url(../img/audio-player-next.svg); }
|
||||||
#studio-ui .field__item.ui-draggable-dragging {
|
#studio-ui .field__item.ui-draggable-dragging {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 25px;
|
|
||||||
height: 100%;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
width: 25px;
|
||||||
|
height: 100%;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
-webkit-transition: opacity 0.1s ease-in-out;
|
-webkit-transition: opacity 0.1s ease-in-out;
|
||||||
transition: opacity 0.1s ease-in-out; }
|
transition: opacity 0.1s ease-in-out; }
|
||||||
@@ -1873,6 +1918,7 @@ main[role="main"] span.close-col-btn {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
text-transform: none; }
|
text-transform: none; }
|
||||||
#studio-ui .field__item.ui-draggable-dragging article h2 a {
|
#studio-ui .field__item.ui-draggable-dragging article h2 a {
|
||||||
|
white-space: nowrap !important;
|
||||||
font-size: 0.756em; }
|
font-size: 0.756em; }
|
||||||
#studio-ui .field__item.ui-draggable-dragging article h2 a:before {
|
#studio-ui .field__item.ui-draggable-dragging article h2 a:before {
|
||||||
content: "";
|
content: "";
|
||||||
@@ -1898,6 +1944,8 @@ main[role="main"] span.close-col-btn {
|
|||||||
transform: rotateZ(-45deg);
|
transform: rotateZ(-45deg);
|
||||||
border: 1px solid red;
|
border: 1px solid red;
|
||||||
background-color: white; }
|
background-color: white; }
|
||||||
|
#studio-ui .field__item.ui-draggable-dragging.is-active .handler {
|
||||||
|
background-color: red; }
|
||||||
|
|
||||||
.col[theme="edlp_search_search_form"], .col[theme="edlp_search_search_form"] > .wrapper {
|
.col[theme="edlp_search_search_form"], .col[theme="edlp_search_search_form"] > .wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -6,8 +6,9 @@
|
|||||||
var _$corpus_canvas;
|
var _$corpus_canvas;
|
||||||
var _$row = $('main[role="main"]>.layout-content>.row');
|
var _$row = $('main[role="main"]>.layout-content>.row');
|
||||||
var _$ajaxLinks;
|
var _$ajaxLinks;
|
||||||
var _audio_player;
|
var _audioPlayer;
|
||||||
var _randomPlayer;
|
var _randomPlayer;
|
||||||
|
var _compoPlayer;
|
||||||
|
|
||||||
// ___ _ _
|
// ___ _ _
|
||||||
// |_ _|_ _ (_) |_
|
// |_ _|_ _ (_) |_
|
||||||
@@ -20,7 +21,8 @@
|
|||||||
|
|
||||||
_$body.on('corpus-map-ready', onCorpusMapReady);
|
_$body.on('corpus-map-ready', onCorpusMapReady);
|
||||||
|
|
||||||
_audio_player = new AudioPlayer();
|
_audioPlayer = new AudioPlayer();
|
||||||
|
_compoPlayer = new CompoPlayer();
|
||||||
|
|
||||||
initAjaxLinks();
|
initAjaxLinks();
|
||||||
|
|
||||||
@@ -42,271 +44,18 @@
|
|||||||
// |___|\_/\___|_||_\__/__/
|
// |___|\_/\___|_||_\__/__/
|
||||||
function initEvents(){
|
function initEvents(){
|
||||||
$('body')
|
$('body')
|
||||||
.on('on-studio-chutier-updated', function(e){
|
.on('on-studio-chutier-updated', initAjaxLinks)
|
||||||
|
.on('on-studio-compo-updated', function(e){
|
||||||
initAjaxLinks();
|
initAjaxLinks();
|
||||||
|
_compoPlayer.refresh();
|
||||||
})
|
})
|
||||||
.on('search-results-loaded',function(e){
|
.on('on-studio-compo-opened', function(e){
|
||||||
initAjaxLinks();
|
initAjaxLinks();
|
||||||
|
_compoPlayer.newCompo();
|
||||||
})
|
})
|
||||||
.on('open_entree', function(e){
|
.on('search-results-loaded', initAjaxLinks)
|
||||||
// e.tid available
|
.on('open_entree', closeAllModals)
|
||||||
closeAllModals();
|
.on('close_entree', backToFrontPage);
|
||||||
})
|
|
||||||
.on('close_entree', function(e){
|
|
||||||
// e.tid available
|
|
||||||
backToFrontPage();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// _ _ _
|
|
||||||
// /_\ _ _ __| (_)___
|
|
||||||
// / _ \ || / _` | / _ \
|
|
||||||
// /_/ \_\_,_\__,_|_\___/
|
|
||||||
//
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
|
|
||||||
// https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/samples/gg589528%28v%3dvs.85%29
|
|
||||||
// https://www.binarytides.com/using-html5-audio-element-javascript/
|
|
||||||
function AudioPlayer(){
|
|
||||||
var that = this;
|
|
||||||
this.fid;
|
|
||||||
this.audio = new Audio();
|
|
||||||
// audio events
|
|
||||||
this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended"];
|
|
||||||
|
|
||||||
// UI dom objects
|
|
||||||
this.$container = $('<div id="audio-player">');
|
|
||||||
// btns
|
|
||||||
this.$btns = $('<div>').addClass('btns').appendTo(this.$container);
|
|
||||||
this.$previous = $('<div>').addClass('previous').appendTo(this.$btns);
|
|
||||||
this.$playpause = $('<div>').addClass('play-pause').appendTo(this.$btns);
|
|
||||||
this.$next = $('<div>').addClass('next').appendTo(this.$btns);
|
|
||||||
// timeline
|
|
||||||
this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);
|
|
||||||
this.$timeline = $('<div>').addClass('time-line').appendTo(this.$timelinecont);
|
|
||||||
this.$loader = $('<div>').addClass('loader').appendTo(this.$timeline);
|
|
||||||
this.$cursor = $('<div>').addClass('cursor').appendTo(this.$timeline);
|
|
||||||
// time
|
|
||||||
this.$time = $('<div>').addClass('time').appendTo(this.$container);
|
|
||||||
this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);
|
|
||||||
this.$duration = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);
|
|
||||||
// favoris
|
|
||||||
this.$fav = $('<div>').addClass('favoris').appendTo(this.$container);
|
|
||||||
// cartel
|
|
||||||
this.$cartel = $('<div>').addClass('cartel').appendTo(this.$container);
|
|
||||||
|
|
||||||
// hiding
|
|
||||||
this.hideTimer = false;
|
|
||||||
this.hideTimeMS = 10000;
|
|
||||||
|
|
||||||
// history
|
|
||||||
this.currentHistoricIndex = null;
|
|
||||||
this.historic = [];
|
|
||||||
this.shuffle_is_active = false;
|
|
||||||
|
|
||||||
// object events
|
|
||||||
this.event_handlers = {
|
|
||||||
'audio-play-next':[],
|
|
||||||
'audio-ended':[],
|
|
||||||
'stop-shuffle':[]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
};
|
|
||||||
AudioPlayer.prototype = {
|
|
||||||
init(){
|
|
||||||
// append ui to document
|
|
||||||
this.$container.appendTo('header[role="banner"] .region-header');
|
|
||||||
// record timeline width
|
|
||||||
this.timeline_w = parseInt(this.$timeline.width());
|
|
||||||
// init audio events
|
|
||||||
var fn = '';
|
|
||||||
for (var i = 0; i < this.audio_events.length; i++) {
|
|
||||||
fn = this.audio_events[i];
|
|
||||||
// capitalize first letter of event (only cosmetic :p )
|
|
||||||
fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
|
|
||||||
this.audio.addEventListener(
|
|
||||||
this.audio_events[i],
|
|
||||||
this[fn].bind(this),
|
|
||||||
true);
|
|
||||||
}
|
|
||||||
// init btns events
|
|
||||||
this.$previous.on('click', this.playPrevious.bind(this));
|
|
||||||
this.$playpause.on('click', this.togglePlayPause.bind(this));
|
|
||||||
this.$next.on('click', this.playNext.bind(this));
|
|
||||||
// TODO: previous and next btns
|
|
||||||
},
|
|
||||||
openDocument(node){
|
|
||||||
console.log('AudioPlayer openDocument', node);
|
|
||||||
this.historic.push(node);
|
|
||||||
this.currentHistoricIndex = this.historic.length-1;
|
|
||||||
// this.shuffle_mode = shuffle_mode || false;
|
|
||||||
this.launch();
|
|
||||||
},
|
|
||||||
launch(){
|
|
||||||
this.clearTimeOutToHide();
|
|
||||||
this.setSRC(this.historic[this.currentHistoricIndex].audio_url);
|
|
||||||
this.loadNode(this.historic[this.currentHistoricIndex].nid);
|
|
||||||
// emmit new playing doc (e.g.: corpus map nowing that audio played from RandomPlayer)
|
|
||||||
try {
|
|
||||||
_$corpus_canvas.trigger({
|
|
||||||
'type':'audio-node-opened',
|
|
||||||
'nid':this.historic[this.currentHistoricIndex].nid
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.warn('AudioPlayer : _$corpus_canvas does not exists');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showHidePreviousBtn();
|
|
||||||
this.showHideNextBtn();
|
|
||||||
this.show();
|
|
||||||
},
|
|
||||||
// audio functions
|
|
||||||
setSRC(url){
|
|
||||||
// console.log('AudioPlayer setSRC : url', url);
|
|
||||||
this.audio.src = url;
|
|
||||||
},
|
|
||||||
onLoadedmetadata(){
|
|
||||||
var rem = parseInt(this.audio.duration, 10),
|
|
||||||
mins = Math.floor(rem/60,10),
|
|
||||||
secs = rem - mins*60;
|
|
||||||
this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
|
||||||
this.updateLoadingBar();
|
|
||||||
},
|
|
||||||
updateLoadingBar(){
|
|
||||||
this.$loader.css({
|
|
||||||
'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
|
|
||||||
});
|
|
||||||
if( this.audio.buffered.end(0) < this.audio.duration ){
|
|
||||||
// loop through this function until file is fully loaded
|
|
||||||
var that = this;
|
|
||||||
window.requestAnimationFrame(that.updateLoadingBar.bind(that));
|
|
||||||
}else{
|
|
||||||
console.log('Audio fully loaded');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCanplay(){
|
|
||||||
this.play();
|
|
||||||
},
|
|
||||||
play(){
|
|
||||||
this.audio.play();
|
|
||||||
},
|
|
||||||
playPrevious(){
|
|
||||||
if(this.currentHistoricIndex > 0){
|
|
||||||
this.currentHistoricIndex -= 1;
|
|
||||||
this.launch();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
playNext(){
|
|
||||||
if(this.currentHistoricIndex < this.historic.length-1){
|
|
||||||
this.currentHistoricIndex += 1;
|
|
||||||
this.launch();
|
|
||||||
}else{
|
|
||||||
this.emmit('audio-play-next');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
togglePlayPause(e){
|
|
||||||
if(this.audio.paused){
|
|
||||||
this.audio.play();
|
|
||||||
}else{
|
|
||||||
this.audio.pause();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
stop(){
|
|
||||||
console.log('AudioPlayer stop()');
|
|
||||||
this.audio.pause();
|
|
||||||
this.timeOutToHide();
|
|
||||||
},
|
|
||||||
// audio events
|
|
||||||
onPlaying(){
|
|
||||||
this.$container.addClass('is-playing');
|
|
||||||
},
|
|
||||||
onPause(){
|
|
||||||
this.$container.removeClass('is-playing');
|
|
||||||
},
|
|
||||||
onTimeupdate(){
|
|
||||||
// move cursor
|
|
||||||
this.$cursor.css({
|
|
||||||
'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px"
|
|
||||||
});
|
|
||||||
// update time text display
|
|
||||||
var rem = parseInt(this.audio.currentTime, 10),
|
|
||||||
mins = Math.floor(rem/60,10),
|
|
||||||
secs = rem - mins*60;
|
|
||||||
this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
|
||||||
},
|
|
||||||
onEnded(){
|
|
||||||
this.emmit('audio-ended');
|
|
||||||
this.stop();
|
|
||||||
},
|
|
||||||
// cartel functions
|
|
||||||
loadNode(nid){
|
|
||||||
this.$cartel.addClass('loading');
|
|
||||||
$.getJSON('/edlp/ajax/json/node/'+nid+'/player_cartel', {})
|
|
||||||
.done(this.onNodeLoaded.bind(this))
|
|
||||||
.fail(this.onNodeLoadFail.bind(this));
|
|
||||||
},
|
|
||||||
onNodeLoaded(data){
|
|
||||||
console.log('AudioPlayer node loaded');
|
|
||||||
this.$cartel.html(data.rendered).removeClass('loading');
|
|
||||||
_$body.trigger({'type':'new-audio-cartel-loaded'});
|
|
||||||
initAjaxLinks();
|
|
||||||
},
|
|
||||||
onNodeLoadFail(jqxhr, textStatus, error){
|
|
||||||
console.warn('AudioPlayer node load failed', jqxhr.responseText);
|
|
||||||
this.$cartel.removeClass('loading').html('');
|
|
||||||
},
|
|
||||||
// global
|
|
||||||
show(){
|
|
||||||
this.$container.addClass('visible');
|
|
||||||
},
|
|
||||||
showHidePreviousBtn(){
|
|
||||||
if(this.historic.length > 1 && this.currentHistoricIndex > 0){
|
|
||||||
this.$previous.addClass('is-active');
|
|
||||||
}else{
|
|
||||||
this.$previous.removeClass('is-active');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showHideNextBtn(){
|
|
||||||
if(this.currentHistoricIndex < this.historic.length-1 || this.shuffle_is_active){
|
|
||||||
this.$next.addClass('is-active');
|
|
||||||
}else{
|
|
||||||
this.$next.removeClass('is-active');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timeOutToHide(){
|
|
||||||
console.log('AudioPlayer timeOutToHide()');
|
|
||||||
this.clearTimeOutToHide();
|
|
||||||
this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS);
|
|
||||||
},
|
|
||||||
clearTimeOutToHide(){
|
|
||||||
console.log('AudioPlayer clearTimeOutToHide()',this.hideTimer);
|
|
||||||
if(this.hideTimer){
|
|
||||||
clearTimeout(this.hideTimer);
|
|
||||||
this.hideTimer = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hide(){
|
|
||||||
console.log('AudioPlayer hide()');
|
|
||||||
this.$container.removeClass('visible');
|
|
||||||
// trigger highlighted node remove on corpus map
|
|
||||||
_$corpus_canvas.trigger('audio-node-closed');
|
|
||||||
},
|
|
||||||
// object events
|
|
||||||
on(event_name, handler){
|
|
||||||
if(typeof this.event_handlers[event_name] == 'undefined'){
|
|
||||||
console.warn('AudioPlayer : event '+event_name+' does not exists');
|
|
||||||
}
|
|
||||||
this.event_handlers[event_name].push(handler);
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
emmit(event_name){
|
|
||||||
var handler;
|
|
||||||
for (var i = this.event_handlers[event_name].length; i >= 0 ; i--) {
|
|
||||||
handler = this.event_handlers[event_name][i];
|
|
||||||
setTimeout(handler, 0);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ___ _ _ ___
|
// ___ _ _ ___
|
||||||
@@ -365,7 +114,7 @@
|
|||||||
// Audio links
|
// Audio links
|
||||||
if($link.is('.audio-link')){
|
if($link.is('.audio-link')){
|
||||||
// TODO: stop randomplayer
|
// TODO: stop randomplayer
|
||||||
_audio_player
|
_audioPlayer
|
||||||
.emmit('stop-shuffle')
|
.emmit('stop-shuffle')
|
||||||
.openDocument({
|
.openDocument({
|
||||||
nid:$link.attr('nid'),
|
nid:$link.attr('nid'),
|
||||||
@@ -521,7 +270,7 @@
|
|||||||
})
|
})
|
||||||
.on('corpus-cliked-on-node', function(e) {
|
.on('corpus-cliked-on-node', function(e) {
|
||||||
console.log('theme : corpus-cliked-on-node', e);
|
console.log('theme : corpus-cliked-on-node', e);
|
||||||
_audio_player
|
_audioPlayer
|
||||||
.emmit('stop-shuffle')
|
.emmit('stop-shuffle')
|
||||||
.openDocument(e.target_node);
|
.openDocument(e.target_node);
|
||||||
});
|
});
|
||||||
@@ -531,6 +280,284 @@
|
|||||||
_$body.attr('corpus-map', 'ready');
|
_$body.attr('corpus-map', 'ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _ _ _
|
||||||
|
// /_\ _ _ __| (_)___
|
||||||
|
// / _ \ || / _` | / _ \
|
||||||
|
// /_/ \_\_,_\__,_|_\___/
|
||||||
|
//
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement
|
||||||
|
// https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/samples/gg589528%28v%3dvs.85%29
|
||||||
|
// https://www.binarytides.com/using-html5-audio-element-javascript/
|
||||||
|
function AudioPlayer(){
|
||||||
|
var that = this;
|
||||||
|
this.fid;
|
||||||
|
this.audio = new Audio();
|
||||||
|
// audio events
|
||||||
|
this.audio_events = ["loadedmetadata","canplay","playing","pause","timeupdate","ended"];
|
||||||
|
|
||||||
|
// UI dom objects
|
||||||
|
this.$container = $('<div id="audio-player">');
|
||||||
|
// btns
|
||||||
|
this.$btns = $('<div>').addClass('btns').appendTo(this.$container);
|
||||||
|
this.$previous = $('<div>').addClass('previous').appendTo(this.$btns);
|
||||||
|
this.$playpause = $('<div>').addClass('play-pause').appendTo(this.$btns);
|
||||||
|
this.$next = $('<div>').addClass('next').appendTo(this.$btns);
|
||||||
|
// timeline
|
||||||
|
this.$timelinecont= $('<div>').addClass('time-line-container').appendTo(this.$container);
|
||||||
|
this.$timeline = $('<div>').addClass('time-line').appendTo(this.$timelinecont);
|
||||||
|
this.$loader = $('<div>').addClass('loader').appendTo(this.$timeline);
|
||||||
|
this.$cursor = $('<div>').addClass('cursor').appendTo(this.$timeline);
|
||||||
|
// time
|
||||||
|
this.$time = $('<div>').addClass('time').appendTo(this.$container);
|
||||||
|
this.$currentTime = $('<div>').addClass('current-time').html('00:00').appendTo(this.$time);
|
||||||
|
this.$duration = $('<div>').addClass('duration').html('00:00').appendTo(this.$time);
|
||||||
|
// favoris
|
||||||
|
this.$fav = $('<div>').addClass('favoris').appendTo(this.$container);
|
||||||
|
// cartel
|
||||||
|
this.$cartel = $('<div>').addClass('cartel').appendTo(this.$container);
|
||||||
|
|
||||||
|
// hiding
|
||||||
|
this.hideTimer = false;
|
||||||
|
this.hideTimeMS = 10000;
|
||||||
|
|
||||||
|
// history
|
||||||
|
this.currentHistoricIndex = null;
|
||||||
|
this.historic = [];
|
||||||
|
this.shuffle_is_active = false;
|
||||||
|
|
||||||
|
// object events
|
||||||
|
this.event_handlers = {
|
||||||
|
'audio-open-document':[],
|
||||||
|
'audio-play':[],
|
||||||
|
'audio-pause':[],
|
||||||
|
'audio-play-next':[],
|
||||||
|
'audio-ended':[],
|
||||||
|
'stop-shuffle':[]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
};
|
||||||
|
AudioPlayer.prototype = {
|
||||||
|
init(){
|
||||||
|
// append ui to document
|
||||||
|
this.$container.appendTo('header[role="banner"] .region-header');
|
||||||
|
// record timeline width
|
||||||
|
this.timeline_w = parseInt(this.$timeline.width());
|
||||||
|
// init audio events
|
||||||
|
var fn = '';
|
||||||
|
for (var i = 0; i < this.audio_events.length; i++) {
|
||||||
|
fn = this.audio_events[i];
|
||||||
|
// capitalize first letter of event (only cosmetic :p )
|
||||||
|
fn = 'on'+fn.charAt(0).toUpperCase()+fn.slice(1);
|
||||||
|
this.audio.addEventListener(
|
||||||
|
this.audio_events[i],
|
||||||
|
this[fn].bind(this),
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
// init btns events
|
||||||
|
this.$previous.on('click', this.playPrevious.bind(this));
|
||||||
|
this.$playpause.on('click', this.togglePlayPause.bind(this));
|
||||||
|
this.$next.on('click', this.playNext.bind(this));
|
||||||
|
// TODO: previous and next btns
|
||||||
|
},
|
||||||
|
openDocument(node, caller){
|
||||||
|
// console.log('AudioPlayer openDocument', node);
|
||||||
|
if(typeof node == 'undefined'
|
||||||
|
|| typeof node.nid == 'undefined'
|
||||||
|
|| typeof node.audio_url == 'undfined'){
|
||||||
|
console.warn('AudioPlayer openDocument() node is malformed', node);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this.historic.push(node);
|
||||||
|
this.currentHistoricIndex = this.historic.length-1;
|
||||||
|
// this.shuffle_mode = shuffle_mode || false;
|
||||||
|
|
||||||
|
this.emmit('audio-open-document', {caller:caller});
|
||||||
|
|
||||||
|
this.launch();
|
||||||
|
},
|
||||||
|
launch(){
|
||||||
|
this.clearTimeOutToHide();
|
||||||
|
this.setSRC(this.historic[this.currentHistoricIndex].audio_url);
|
||||||
|
this.loadNode(this.historic[this.currentHistoricIndex].nid);
|
||||||
|
// emmit new playing doc (e.g.: corpus map nowing that audio played from RandomPlayer)
|
||||||
|
try {
|
||||||
|
_$corpus_canvas.trigger({
|
||||||
|
'type':'audio-node-opened',
|
||||||
|
'nid':this.historic[this.currentHistoricIndex].nid
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.info('AudioPlayer : _$corpus_canvas does not exists');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showHidePreviousBtn();
|
||||||
|
this.showHideNextBtn();
|
||||||
|
this.show();
|
||||||
|
},
|
||||||
|
// audio functions
|
||||||
|
setSRC(url){
|
||||||
|
// console.log('AudioPlayer setSRC : url', url);
|
||||||
|
this.audio.src = url;
|
||||||
|
},
|
||||||
|
onLoadedmetadata(){
|
||||||
|
var rem = parseInt(this.audio.duration, 10),
|
||||||
|
mins = Math.floor(rem/60,10),
|
||||||
|
secs = rem - mins*60;
|
||||||
|
this.$duration.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
||||||
|
this.updateLoadingBar();
|
||||||
|
},
|
||||||
|
updateLoadingBar(){
|
||||||
|
this.$loader.css({
|
||||||
|
'width':parseInt((100 * this.audio.buffered.end(0) / this.audio.duration), 10)+'%'
|
||||||
|
});
|
||||||
|
if( this.audio.buffered.end(0) < this.audio.duration ){
|
||||||
|
// loop through this function until file is fully loaded
|
||||||
|
var that = this;
|
||||||
|
window.requestAnimationFrame(that.updateLoadingBar.bind(that));
|
||||||
|
}else{
|
||||||
|
console.log('Audio fully loaded');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onCanplay(){
|
||||||
|
this.play();
|
||||||
|
},
|
||||||
|
play(){
|
||||||
|
this.clearTimeOutToHide();
|
||||||
|
this.audio.play();
|
||||||
|
},
|
||||||
|
playPrevious(){
|
||||||
|
if(this.currentHistoricIndex > 0){
|
||||||
|
this.currentHistoricIndex -= 1;
|
||||||
|
this.launch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
playNext(){
|
||||||
|
if(this.currentHistoricIndex < this.historic.length-1){
|
||||||
|
this.currentHistoricIndex += 1;
|
||||||
|
this.launch();
|
||||||
|
}else{
|
||||||
|
this.emmit('audio-play-next');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
togglePlayPause(e){
|
||||||
|
if(this.audio.paused){
|
||||||
|
this.audio.play();
|
||||||
|
}else{
|
||||||
|
this.audio.pause();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stop(){
|
||||||
|
// console.log('AudioPlayer stop()');
|
||||||
|
this.audio.pause();
|
||||||
|
this.timeOutToHide();
|
||||||
|
},
|
||||||
|
// audio events
|
||||||
|
onPlaying(){
|
||||||
|
this.$btns.addClass('is-playing');
|
||||||
|
this.emmit('audio-play');
|
||||||
|
},
|
||||||
|
onPause(){
|
||||||
|
this.$btns.removeClass('is-playing');
|
||||||
|
this.emmit('audio-pause');
|
||||||
|
},
|
||||||
|
onTimeupdate(){
|
||||||
|
// move cursor
|
||||||
|
this.$cursor.css({
|
||||||
|
'left':(this.audio.currentTime/this.audio.duration * this.timeline_w)+"px"
|
||||||
|
});
|
||||||
|
// update time text display
|
||||||
|
var rem = parseInt(this.audio.currentTime, 10),
|
||||||
|
mins = Math.floor(rem/60,10),
|
||||||
|
secs = rem - mins*60;
|
||||||
|
this.$currentTime.html('<span>'+(mins<10 ? '0':'')+mins+':'+(secs<10 ? '0':'')+secs+'</span>');
|
||||||
|
},
|
||||||
|
onEnded(){
|
||||||
|
this.emmit('audio-ended');
|
||||||
|
this.stop();
|
||||||
|
},
|
||||||
|
// cartel functions
|
||||||
|
loadNode(nid){
|
||||||
|
this.$cartel.addClass('loading');
|
||||||
|
$.getJSON('/edlp/ajax/json/node/'+nid+'/player_cartel', {})
|
||||||
|
.done(this.onNodeLoaded.bind(this))
|
||||||
|
.fail(this.onNodeLoadFail.bind(this));
|
||||||
|
},
|
||||||
|
onNodeLoaded(data){
|
||||||
|
// console.log('AudioPlayer node loaded');
|
||||||
|
this.$cartel.html(data.rendered).removeClass('loading');
|
||||||
|
_$body.trigger({'type':'new-audio-cartel-loaded'});
|
||||||
|
initAjaxLinks();
|
||||||
|
},
|
||||||
|
onNodeLoadFail(jqxhr, textStatus, error){
|
||||||
|
console.warn('AudioPlayer node load failed', jqxhr.responseText);
|
||||||
|
this.$cartel.removeClass('loading').html('');
|
||||||
|
},
|
||||||
|
// global
|
||||||
|
show(){
|
||||||
|
this.$container.addClass('visible');
|
||||||
|
},
|
||||||
|
showHidePreviousBtn(){
|
||||||
|
if(this.historic.length > 1 && this.currentHistoricIndex > 0){
|
||||||
|
this.$previous.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$previous.removeClass('is-active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showHideNextBtn(){
|
||||||
|
if(this.currentHistoricIndex < this.historic.length-1 || this.shuffle_is_active){
|
||||||
|
this.$next.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$next.removeClass('is-active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
timeOutToHide(){
|
||||||
|
// console.log('AudioPlayer timeOutToHide()');
|
||||||
|
this.clearTimeOutToHide();
|
||||||
|
this.hideTimer = setTimeout(this.hide.bind(this), this.hideTimeMS);
|
||||||
|
},
|
||||||
|
clearTimeOutToHide(){
|
||||||
|
// console.log('AudioPlayer clearTimeOutToHide()',this.hideTimer);
|
||||||
|
if(this.hideTimer){
|
||||||
|
clearTimeout(this.hideTimer);
|
||||||
|
this.hideTimer = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hide(){
|
||||||
|
// console.log('AudioPlayer hide()');
|
||||||
|
this.$container.removeClass('visible');
|
||||||
|
// trigger highlighted node remove on corpus map
|
||||||
|
try {
|
||||||
|
_$corpus_canvas.trigger('audio-node-closed');
|
||||||
|
} catch (e) {
|
||||||
|
console.info('AudioPlayer hide() : _$corpus_canvas does not exists');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// object events
|
||||||
|
on(event_name, handler){
|
||||||
|
if(typeof this.event_handlers[event_name] == 'undefined'){
|
||||||
|
console.warn('AudioPlayer : event '+event_name+' does not exists');
|
||||||
|
}
|
||||||
|
this.event_handlers[event_name].push(handler);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
emmit(event_name, args){
|
||||||
|
// console.log('AudioPlayer emmit() event_name', event_name);
|
||||||
|
// console.log('AudioPlayer emmit() handlers', this.event_handlers[event_name]);
|
||||||
|
var handler;
|
||||||
|
var args = args || {};
|
||||||
|
for (var i = this.event_handlers[event_name].length-1; i >= 0 ; i--) {
|
||||||
|
handler = this.event_handlers[event_name][i];
|
||||||
|
// console.log('AudioPlayer emmit() loop handler', handler);
|
||||||
|
setTimeout(function(){
|
||||||
|
// console.log('AudioPlayer emmit() timeout handler', handler);
|
||||||
|
handler(args);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// ___ _ ___ _
|
// ___ _ ___ _
|
||||||
// | _ \__ _ _ _ __| |___ _ __ | _ \ |__ _ _ _ ___ _ _
|
// | _ \__ _ _ _ __| |___ _ __ | _ \ |__ _ _ _ ___ _ _
|
||||||
// | / _` | ' \/ _` / _ \ ' \| _/ / _` | || / -_) '_|
|
// | / _` | ' \/ _` / _ \ ' \| _/ / _` | || / -_) '_|
|
||||||
@@ -540,7 +567,7 @@
|
|||||||
this.active = false;
|
this.active = false;
|
||||||
this.playlist = playlist;
|
this.playlist = playlist;
|
||||||
this.$btn = $('<a>').html('Shuffle').addClass('random-player-btn');
|
this.$btn = $('<a>').html('Shuffle').addClass('random-player-btn');
|
||||||
this.init()
|
this.init();
|
||||||
};
|
};
|
||||||
RandomPlayer.prototype = {
|
RandomPlayer.prototype = {
|
||||||
init(){
|
init(){
|
||||||
@@ -554,7 +581,7 @@
|
|||||||
this.$btn.on('click', this.toggleActive.bind(this));
|
this.$btn.on('click', this.toggleActive.bind(this));
|
||||||
|
|
||||||
// attach an event on AudioPlayer
|
// attach an event on AudioPlayer
|
||||||
_audio_player
|
_audioPlayer
|
||||||
.on('audio-ended', this.onAudioPlayerEnded.bind(this))
|
.on('audio-ended', this.onAudioPlayerEnded.bind(this))
|
||||||
.on('audio-play-next', this.onAudioPlayNext.bind(this))
|
.on('audio-play-next', this.onAudioPlayNext.bind(this))
|
||||||
.on('stop-shuffle', this.stop.bind(this));
|
.on('stop-shuffle', this.stop.bind(this));
|
||||||
@@ -579,20 +606,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
start(){
|
start(){
|
||||||
this.active = _audio_player.shuffle_is_active = true;
|
this.active = _audioPlayer.shuffle_is_active = true;
|
||||||
this.$btn.addClass('is-active');
|
this.$btn.addClass('is-active');
|
||||||
this.shuffle();
|
this.shuffle();
|
||||||
this.next();
|
this.next();
|
||||||
},
|
},
|
||||||
stop(){
|
stop(){
|
||||||
this.active = _audio_player.shuffle_is_active = false;
|
this.active = _audioPlayer.shuffle_is_active = false;
|
||||||
this.$btn.removeClass('is-active');
|
this.$btn.removeClass('is-active');
|
||||||
// stop audio player
|
// stop audio player
|
||||||
// _audio_player.stop();
|
// _audioPlayer.stop();
|
||||||
},
|
},
|
||||||
next(){
|
next(){
|
||||||
if(this.active && this.shuffledPlaylist.length > 0)
|
if(this.active && this.shuffledPlaylist.length > 0)
|
||||||
_audio_player.openDocument(this.shuffledPlaylist.splice(0,1)[0]);
|
_audioPlayer.openDocument(this.shuffledPlaylist.splice(0,1)[0]);
|
||||||
},
|
},
|
||||||
onAudioPlayNext(){
|
onAudioPlayNext(){
|
||||||
console.log('RandomPlayer : onAudioPlayNext()');
|
console.log('RandomPlayer : onAudioPlayNext()');
|
||||||
@@ -604,6 +631,215 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ___ ___ _
|
||||||
|
// / __|___ _ __ _ __ ___| _ \ |__ _ _ _ ___ _ _
|
||||||
|
// | (__/ _ \ ' \| '_ \/ _ \ _/ / _` | || / -_) '_|
|
||||||
|
// \___\___/_|_|_| .__/\___/_| |_\__,_|\_, \___|_|
|
||||||
|
// |_| |__/
|
||||||
|
function CompoPlayer(){
|
||||||
|
this.playing = false;
|
||||||
|
this.paused = false;
|
||||||
|
this.playlist = [];
|
||||||
|
this.current_index = 0;
|
||||||
|
this.$compo = null;
|
||||||
|
this.init();
|
||||||
|
};
|
||||||
|
CompoPlayer.prototype = {
|
||||||
|
init(){
|
||||||
|
console.log('CompoPlayer init()');
|
||||||
|
// attach an event on AudioPlayer
|
||||||
|
_audioPlayer
|
||||||
|
.on('audio-open-document', this.onAudioOpenDocument.bind(this))
|
||||||
|
.on('audio-play', this.onAudioPlayerPlay.bind(this))
|
||||||
|
.on('audio-pause', this.onAudioPlayerPause.bind(this))
|
||||||
|
.on('audio-ended', this.onAudioPlayerEnded.bind(this));
|
||||||
|
// .on('audio-play-next', this.onAudioPlayNext.bind(this));
|
||||||
|
|
||||||
|
this.newCompo();
|
||||||
|
},
|
||||||
|
newCompo(){
|
||||||
|
console.log('CompoPlayer newCompo()');
|
||||||
|
// $('.composition_ui .composer .composition .field--name-documents')
|
||||||
|
this.$composer = $('.composition_ui .composer');
|
||||||
|
this.$compo = $('.composition_ui .composer .composition');
|
||||||
|
this.$controls = $('.composition_ui .composer .compo-player-controls');
|
||||||
|
this.$previous = $('<div>').addClass('previous')
|
||||||
|
.on('click', this.prev.bind(this))
|
||||||
|
.appendTo(this.$controls);
|
||||||
|
this.$playpause = $('<div>').addClass('play-pause')
|
||||||
|
.on('click', this.togglePlayPause.bind(this))
|
||||||
|
.appendTo(this.$controls);
|
||||||
|
this.$next = $('<div>').addClass('next')
|
||||||
|
.on('click', this.next.bind(this))
|
||||||
|
.appendTo(this.$controls);
|
||||||
|
// this.$playpause = $('.compo-player-controls', this.$composer)
|
||||||
|
// .on('click', this.togglePlayPause.bind(this));
|
||||||
|
this.refresh();
|
||||||
|
},
|
||||||
|
refresh(){
|
||||||
|
// console.log('CompoPlayer refresh(), this', this);
|
||||||
|
// this.playing = false;
|
||||||
|
// this.paused = false;
|
||||||
|
// this.resetIndex();
|
||||||
|
this.stop();
|
||||||
|
|
||||||
|
// load new playlist
|
||||||
|
this.playlist = [];
|
||||||
|
var that = this;
|
||||||
|
$('.field--name-documents .field__item',this.$compo).each(function(i,el){
|
||||||
|
var $link = $('a.audio-link',this);
|
||||||
|
that.playlist.push({
|
||||||
|
item:$(this),
|
||||||
|
audio_url:$link.attr("audio_url"),
|
||||||
|
nid:$link.attr("nid"),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.showHideControls();
|
||||||
|
},
|
||||||
|
togglePlayPause(){
|
||||||
|
// console.log('CompoPlayer togglePlayPause');
|
||||||
|
if (this.playing && !this.paused) {
|
||||||
|
this.pause();
|
||||||
|
}else{
|
||||||
|
if(this.playing && this.paused){
|
||||||
|
this.play();
|
||||||
|
}else{
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
start(){
|
||||||
|
console.log('start');
|
||||||
|
// console.log('CompoPlayer start()');
|
||||||
|
this.playing = true;
|
||||||
|
this.play();
|
||||||
|
},
|
||||||
|
play(){
|
||||||
|
// console.log('play');
|
||||||
|
if(this.paused){
|
||||||
|
this.paused = false;
|
||||||
|
_audioPlayer.play();
|
||||||
|
}else{
|
||||||
|
_audioPlayer.openDocument(this.playlist[this.current_index], this);
|
||||||
|
}
|
||||||
|
this.setActiveItem().showHideControls();
|
||||||
|
},
|
||||||
|
pause(){
|
||||||
|
console.log('pause');
|
||||||
|
this.paused = true;
|
||||||
|
this.showHideControls();
|
||||||
|
_audioPlayer.stop();
|
||||||
|
},
|
||||||
|
next(){
|
||||||
|
// console.log('CompoPlayer next()');
|
||||||
|
if(this.playing){
|
||||||
|
this.current_index += 1;
|
||||||
|
if(this.current_index < this.playlist.length){
|
||||||
|
this.play();
|
||||||
|
}else{
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
prev(){
|
||||||
|
// console.log('CompoPlayer prev()');
|
||||||
|
if(this.playing){
|
||||||
|
this.current_index -= 1;
|
||||||
|
if(this.current_index >= 0){
|
||||||
|
this.play();
|
||||||
|
}else{
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stop(){
|
||||||
|
_audioPlayer.stop();
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
reset(){
|
||||||
|
this.playing = false;
|
||||||
|
this.paused = false;
|
||||||
|
this.resetIndex();
|
||||||
|
},
|
||||||
|
resetIndex(){
|
||||||
|
this.current_index = 0;
|
||||||
|
this.showHideControls().resetActiveItems();
|
||||||
|
},
|
||||||
|
setActiveItem(){
|
||||||
|
this.resetActiveItems();
|
||||||
|
if(this.playing && this.current_index >= 0){
|
||||||
|
this.playlist[this.current_index].item.addClass('is-active');
|
||||||
|
}
|
||||||
|
// this call shoud not be here
|
||||||
|
this.showHideControls();
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
resetActiveItems(){
|
||||||
|
for (var n = 0; n < this.playlist.length; n++) {
|
||||||
|
// console.log('node',node);
|
||||||
|
this.playlist[n].item.removeClass('is-active');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
showHideControls(){
|
||||||
|
// console.log('CompoPlayer showHideNextBtn(), playing:'+this.playing+', paused:'+this.paused);
|
||||||
|
// global playing
|
||||||
|
if(this.playing && !this.paused){
|
||||||
|
this.$controls.addClass('is-playing');
|
||||||
|
}else{
|
||||||
|
this.$controls.removeClass('is-playing');
|
||||||
|
}
|
||||||
|
// playpause
|
||||||
|
if(this.playlist.length > 0){
|
||||||
|
this.$playpause.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$playpause.removeClass('is-active');
|
||||||
|
}
|
||||||
|
// next
|
||||||
|
if(this.playing && this.playlist.length > 1 && this.current_index < this.playlist.length -1){
|
||||||
|
this.$next.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$next.removeClass('is-active');
|
||||||
|
}
|
||||||
|
// previous
|
||||||
|
if(this.playing && this.playlist.length > 1 && this.current_index > 0){
|
||||||
|
this.$previous.addClass('is-active');
|
||||||
|
}else{
|
||||||
|
this.$previous.removeClass('is-active');
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
// _audioPlayer events
|
||||||
|
onAudioOpenDocument(args){
|
||||||
|
if(args.caller !== this){
|
||||||
|
// console.log('CompoPlayer onAudioOpenDocument() called by other');
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
// else{
|
||||||
|
// // console.log('CompoPlayer onAudioOpenDocument() self calling');
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
onAudioPlayerPlay(){
|
||||||
|
if(this.playing && this.paused){
|
||||||
|
this.paused = false;
|
||||||
|
this.showHideControls();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAudioPlayerPause(){
|
||||||
|
if(this.playing && !this.paused){
|
||||||
|
this.paused = true;
|
||||||
|
this.showHideControls();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onAudioPlayerEnded(){
|
||||||
|
this.next();
|
||||||
|
},
|
||||||
|
// onAudioPlayNext(){
|
||||||
|
// this.next();
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ___ _ _ _
|
// ___ _ _ _
|
||||||
// | _ \_ _ ___ __| |_ _ __| |_(_)___ _ _ ___
|
// | _ \_ _ ___ __| |_ _ __| |_(_)___ _ _ ___
|
||||||
// | _/ '_/ _ \/ _` | || / _| _| / _ \ ' \(_-<
|
// | _/ '_/ _ \/ _` | || / _| _| / _ \ ' \(_-<
|
||||||
|
|||||||
@@ -258,6 +258,39 @@ main[role="main"]{
|
|||||||
// / _ \ || / _` | / _ \ _/ / _` | || / -_) '_|
|
// / _ \ || / _` | / _ \ _/ / _` | || / -_) '_|
|
||||||
// /_/ \_\_,_\__,_|_\___/_| |_\__,_|\_, \___|_|
|
// /_/ \_\_,_\__,_|_\___/_| |_\__,_|\_, \___|_|
|
||||||
// |__/
|
// |__/
|
||||||
|
@mixin audio_controls {
|
||||||
|
// outline: 1px dotted orange;
|
||||||
|
&>*{
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width:20px;height:30px;
|
||||||
|
background-position: center;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
.play-pause{
|
||||||
|
background-image: url(../img/audio-player-play.svg);
|
||||||
|
padding:0 0.3em;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
&.is-playing{
|
||||||
|
.play-pause{background-image: url(../img/audio-player-pause.svg);}
|
||||||
|
}
|
||||||
|
.previous, .next{
|
||||||
|
opacity: 0.3;
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
cursor: auto;
|
||||||
|
&.is-active{
|
||||||
|
opacity: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.previous{
|
||||||
|
background-image: url(../img/audio-player-previous.svg);
|
||||||
|
}
|
||||||
|
.next{
|
||||||
|
background-image: url(../img/audio-player-next.svg);
|
||||||
|
}
|
||||||
|
}
|
||||||
#audio-player{
|
#audio-player{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top:0; left:0;
|
top:0; left:0;
|
||||||
@@ -281,34 +314,7 @@ main[role="main"]{
|
|||||||
// outline: 1px solid green;
|
// outline: 1px solid green;
|
||||||
}
|
}
|
||||||
.btns{
|
.btns{
|
||||||
// outline: 1px dotted orange;
|
@include audio_controls;
|
||||||
&>*{
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
width:20px;height:30px;
|
|
||||||
background-position: center;
|
|
||||||
background-size: contain;
|
|
||||||
}
|
|
||||||
.play-pause{
|
|
||||||
background-image: url(../img/audio-player-play.svg);
|
|
||||||
padding:0 0.3em;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.previous, .next{
|
|
||||||
opacity: 0.3;
|
|
||||||
transition: opacity 0.3s ease-in-out;
|
|
||||||
cursor: auto;
|
|
||||||
&.is-active{
|
|
||||||
opacity: 1;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.previous{
|
|
||||||
background-image: url(../img/audio-player-previous.svg);
|
|
||||||
}
|
|
||||||
.next{
|
|
||||||
background-image: url(../img/audio-player-next.svg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.time-line-container{
|
.time-line-container{
|
||||||
.time-line{
|
.time-line{
|
||||||
@@ -413,9 +419,7 @@ main[role="main"]{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.is-playing{
|
|
||||||
.btns .play-pause{background-image: url(../img/audio-player-pause.svg);}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -473,18 +477,16 @@ main[role="main"]{
|
|||||||
#studio-ui{
|
#studio-ui{
|
||||||
height:100%;
|
height:100%;
|
||||||
@mixin draggable_sortable_field__item {
|
@mixin draggable_sortable_field__item {
|
||||||
// outline: 1px dotted green;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
// margin-right: 25px;
|
// margin-right: 25px;
|
||||||
width:25px;
|
width:25px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
&.ui-draggable-dragging{
|
&.ui-draggable-dragging{
|
||||||
height:100px;
|
height:100px;
|
||||||
// cursor: grabbing;
|
|
||||||
}
|
}
|
||||||
white-space: nowrap;
|
|
||||||
pointer-events: none;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 0.1s ease-in-out;
|
transition: opacity 0.1s ease-in-out;
|
||||||
&.ready-to-remove{
|
&.ready-to-remove{
|
||||||
@@ -504,6 +506,7 @@ main[role="main"]{
|
|||||||
margin:0;
|
margin:0;
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
a{
|
a{
|
||||||
|
white-space: nowrap!important;
|
||||||
&:before{
|
&:before{
|
||||||
content:"";
|
content:"";
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -530,6 +533,9 @@ main[role="main"]{
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
// TODO: entries color;
|
// TODO: entries color;
|
||||||
}
|
}
|
||||||
|
&.is-active .handler{
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
} // end mixin
|
} // end mixin
|
||||||
|
|
||||||
.chutier_ui{
|
.chutier_ui{
|
||||||
@@ -652,6 +658,9 @@ main[role="main"]{
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-right: $m;
|
margin-right: $m;
|
||||||
}
|
}
|
||||||
|
&.ajax-loading:before{
|
||||||
|
@include spining-loader-square;
|
||||||
|
}
|
||||||
&.is-active:before{
|
&.is-active:before{
|
||||||
background-color: black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
@@ -718,12 +727,18 @@ main[role="main"]{
|
|||||||
$header_height:25px;
|
$header_height:25px;
|
||||||
$actions_height:25px;
|
$actions_height:25px;
|
||||||
$padding:5px;
|
$padding:5px;
|
||||||
|
opacity:1;
|
||||||
|
transition: opacity 0.3s ease-in-out;
|
||||||
|
&.ajax-loading{
|
||||||
|
opacity:0.3;
|
||||||
|
}
|
||||||
>*{
|
>*{
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
>header{
|
>header{
|
||||||
height:$header_height;
|
height:$header_height;
|
||||||
padding-bottom:$padding;
|
padding-bottom:$padding;
|
||||||
|
font-size: 0.756em;
|
||||||
}
|
}
|
||||||
>.composition{
|
>.composition{
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -772,10 +787,14 @@ main[role="main"]{
|
|||||||
padding-top:$padding;
|
padding-top:$padding;
|
||||||
height:$actions_height;
|
height:$actions_height;
|
||||||
// outline: 1px solid blue;
|
// outline: 1px solid blue;
|
||||||
|
.compo-player-controls{
|
||||||
|
@include audio_controls;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// drag and drop specifics
|
// drag and drop specifics
|
||||||
// created by js
|
// created by js
|
||||||
.field__item.ui-draggable-dragging{
|
.field__item.ui-draggable-dragging{
|
||||||
|
|||||||
@@ -103,7 +103,6 @@ function edlptheme_preprocess_node__enregistrement__search_index(&$vars){
|
|||||||
// dpm($vars['link_attributes']);
|
// dpm($vars['link_attributes']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function edlptheme_preprocess_node__enregistrement__compo(&$vars){
|
function edlptheme_preprocess_node__enregistrement__compo(&$vars){
|
||||||
$node = $vars['elements']['#node'];
|
$node = $vars['elements']['#node'];
|
||||||
$options = ['absolute' => TRUE];
|
$options = ['absolute' => TRUE];
|
||||||
@@ -125,6 +124,10 @@ function edlptheme_preprocess_node__enregistrement__compo(&$vars){
|
|||||||
'nid' => $node->id(),
|
'nid' => $node->id(),
|
||||||
'class' => array('audio-link', 'ajax-link')
|
'class' => array('audio-link', 'ajax-link')
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// dpm($vars);
|
||||||
|
$title = $vars['label'][0]['#context']['value'];
|
||||||
|
$vars['label'][0]['#context']['value'] = Unicode::truncate($title, 25, true, true);
|
||||||
// dpm($vars['link_attributes']);
|
// dpm($vars['link_attributes']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -84,8 +84,9 @@
|
|||||||
<article{{ attributes.addClass(classes) }}>
|
<article{{ attributes.addClass(classes) }}>
|
||||||
<h2{{ title_attributes.addClass('node-title') }}>
|
<h2{{ title_attributes.addClass('node-title') }}>
|
||||||
<a href="{{ url }}" rel="bookmark" {{ link_attributes }}>
|
<a href="{{ url }}" rel="bookmark" {{ link_attributes }}>
|
||||||
{% set text = label|render|striptags %}
|
{{ label }}
|
||||||
{{ text|length > 25 ? text|slice(0, 25)|split(' ')|slice(0, -1)|join(' ') ~ '…' : text }}
|
{# set text = label|render|striptags #}
|
||||||
|
{# text|length > 25 ? text|slice(0, 25)|split(' ')|slice(0, -1)|join(' ') ~ '…' : text #}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
+9
-2
@@ -12,13 +12,20 @@ content:
|
|||||||
documents:
|
documents:
|
||||||
label: hidden
|
label: hidden
|
||||||
type: entity_reference_entity_view
|
type: entity_reference_entity_view
|
||||||
weight: 0
|
weight: 1
|
||||||
region: content
|
region: content
|
||||||
settings:
|
settings:
|
||||||
view_mode: compo
|
view_mode: compo
|
||||||
link: false
|
link: false
|
||||||
third_party_settings: { }
|
third_party_settings: { }
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
weight: 0
|
||||||
|
region: content
|
||||||
|
label: hidden
|
||||||
|
settings:
|
||||||
|
link_to_entity: false
|
||||||
|
third_party_settings: { }
|
||||||
hidden:
|
hidden:
|
||||||
langcode: true
|
langcode: true
|
||||||
name: true
|
|
||||||
user_id: true
|
user_id: true
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
uuid: d063513e-e6a2-471a-93e0-9b02fa1117d9
|
||||||
|
langcode: fr
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
config:
|
||||||
|
- core.entity_view_mode.composition.studio_ui
|
||||||
|
module:
|
||||||
|
- edlp_studio
|
||||||
|
id: composition.composition.studio_ui
|
||||||
|
targetEntityType: composition
|
||||||
|
bundle: composition
|
||||||
|
mode: studio_ui
|
||||||
|
content:
|
||||||
|
documents:
|
||||||
|
label: hidden
|
||||||
|
type: entity_reference_entity_view
|
||||||
|
weight: 0
|
||||||
|
region: content
|
||||||
|
settings:
|
||||||
|
view_mode: compo
|
||||||
|
link: false
|
||||||
|
third_party_settings: { }
|
||||||
|
hidden:
|
||||||
|
langcode: true
|
||||||
|
name: true
|
||||||
|
user_id: true
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
uuid: eff6d988-0963-4718-ad52-bf10a8e1463d
|
||||||
|
langcode: fr
|
||||||
|
status: true
|
||||||
|
dependencies:
|
||||||
|
module:
|
||||||
|
- edlp_studio
|
||||||
|
id: composition.studio_ui
|
||||||
|
label: studio-ui
|
||||||
|
targetEntityType: composition
|
||||||
|
cache: true
|
||||||
Reference in New Issue
Block a user