composer is almost finished, ramins to record compos order through ajax

This commit is contained in:
Bachir Soussi Chiadmi
2018-03-26 21:21:00 +02:00
parent 0fedff7573
commit 90c9c68dcd
26 changed files with 1048 additions and 89 deletions
@@ -1,22 +1,25 @@
(function ($, Drupal, drupalSettings) {
var settings = drupalSettings.edlp_studio;
var composer;
function init(){
console.log('Studio Init');
initEvents();
initAjaxLinks();
initStudio();
};
function initEvents(){
$('body')
.on('new-audio-cartel-loaded', initAjaxChutierLinks)
.on('new-content-ajax-loaded', initAjaxLinks);
.on('new-content-ajax-loaded', initStudio);
};
function initAjaxLinks(){
function initStudio(){
$composer = $('.composition_ui .composer', '#studio-ui');
initAjaxChutierLinks();
initAjaxCompoLinks();
initDragAndDropUI();
}
// ___ _ _ _ _ _ _ _ _ _
// / __| |_ _ _| |_(_)___ _ _ | \| |___ __| |___ | | (_)_ _ | |__ ___
@@ -29,14 +32,12 @@
.addClass('ajax-enabled')
.on('click', onClickChutierAjaxLink);
};
function onClickChutierAjaxLink(e){
console.log('studio onClickAjaxLink chutier');
e.preventDefault();
addRemoveToChutier($(this));
return false;
};
function addRemoveToChutier($link){
// var ajax_path = 'edlp_studio/ajax/chutier/add/'+id; // + '/' +cid;
var ajax_path = $link.attr('data-drupal-link-system-path');
@@ -50,7 +51,6 @@
onErrorActionToChutier(jqxhr, textStatus, error, $link);
});
};
function onActionToChutierDone($link, data){
console.log('onActionToChutierDone',data);
$('body').trigger({
@@ -64,7 +64,6 @@
// reload Studio chutier_ui's documents list
updateStudioChutier();
};
function onErrorActionToChutier(jqxhr, textStatus, error, $link){
console.warn('action to chuttier load failed : '+error, jqxhr.responseText);
};
@@ -77,18 +76,16 @@
function initAjaxCompoLinks(){
console.log('studio initAjaxCompoLinks');
$('.new-composition-link:not(.ajax-enabled)')
.addClass('ajax-enabled')
.on('click', onClickNewCompoLink);
.on('click', onClickNewCompoLink)
.addClass('ajax-enabled');
$('.composition-link:not(.ajax-enabled)')
.addClass('ajax-enabled')
.on('click', onClickCompoLink);
.on('click', onClickCompoLink)
.addClass('ajax-enabled');
$('.delete-composition-link:not(.ajax-enabled)')
.addClass('ajax-enabled')
.on('click', onClickDeleteCompoLink);
.on('click', onClickDeleteCompoLink)
.addClass('ajax-enabled');
};
// ___ ___
// / _ \ _ __ ___ _ _ / __|___ _ __ _ __ ___
// | (_) | '_ \/ -_) ' \ | (__/ _ \ ' \| '_ \/ _ \
@@ -97,21 +94,46 @@
function onClickCompoLink(e){
e.preventDefault();
console.log('onClickCompoLink');
openCompo($(this));
return false;
};
function openCompo($link){
var cid = $link.attr('cid');
var ajax_path = settings.open_compo_ajax_url+'/'+cid;
var path = window.location.origin + Drupal.url(ajax_path);
$link.addClass('ajax-loading');
$composer.addClass('ajax-loading');
$.getJSON(path, {})
.done(function(data){
onOpenCompoDone(data, $link);
})
.fail(function(jqxhr, textStatus, error){
onErrorOpenCompo(jqxhr, textStatus, error, $link);
});
};
function onOpenCompoDone(data, $link){
console.log('onActionToCompoDone',data);
$('.composition-link').removeClass('is-active');
$link.removeClass('ajax-loading').addClass('is-active');
$composer.html(data.compo);
$composer.removeClass('ajax-loading');
initDragAndDropUI();
};
function onErrorOpenCompo(jqxhr, textStatus, error, $link){
$link.removeClass('ajax-loading');
console.warn('open compo load failed : '+error, jqxhr.responseText);
};
// _ _ _____ __ __ __ ___ _ __ _ __ ___
// | ' \/ -_) V V / / _/ _ \ ' \| '_ \/ _ \
// |_||_\___|\_/\_/ \__\___/_|_|_| .__/\___/
// |_|
function onClickNewCompoLink(e){
e.preventDefault();
setInputForNewCompoName($(this));
return false;
};
function setInputForNewCompoName($link){
var $form = $('<form>').addClass('new-compo-form')
.append($('<input>').attr('type', 'text').attr('placeholder', 'new name'))
@@ -125,7 +147,6 @@
.addClass('folded');
$form.children('input[type="text"]').focus();
};
function onNewCompoFormSubmit(e, $link, $form){
var name = $('input[type="text"]',$form).val();
console.log('onNewCompoFormSubmit', name);
@@ -135,7 +156,6 @@
}
e.preventDefault();
};
function createNewCompo(name,$link, $form){
var ajax_path = $link.attr('data-drupal-link-system-path');
var path = window.location.origin + drupalSettings.path.baseUrl + ajax_path;
@@ -144,14 +164,13 @@
'new_name':name
})
.done(function(data){
onActionToCompoDone(data, $link, $form);
onCreateCompoDone(data, $link, $form);
})
.fail(function(jqxhr, textStatus, error){
onErrorActionToCompo(jqxhr, textStatus, error, $link);
onErrorCreateCompo(jqxhr, textStatus, error, $link);
});
};
function onActionToCompoDone(data, $link, $form){
function onCreateCompoDone(data, $link, $form){
console.log('onActionToCompoDone',data);
$link
.removeClass('folded')
@@ -160,12 +179,10 @@
$form.remove();
// TODO: open new composition to composer
};
function onErrorActionToCompo(jqxhr, textStatus, error, $link){
function onErrorCreateCompo(jqxhr, textStatus, error, $link){
console.warn('action to compo load failed : '+error, jqxhr.responseText);
};
// ___ _ _
// | \ ___| |___| |_ ___ __ ___ _ __ _ __ ___
// | |) / -_) / -_) _/ -_) / _/ _ \ ' \| '_ \/ _ \
@@ -223,7 +240,6 @@
});
}
};
function onLoadedChutier($studioChutier, data){
$studioChutier.replaceWith(data.rendered);
initAjaxChutierLinks();
@@ -231,12 +247,130 @@
'type':'on-studio-chutier-updated'
});
}
function onLoadChutierError(jqxhr, textStatus, error, $studioChutier){
console.warn('Chutier load failed', jqxhr.responseText);
$studioChutier.removeClass('loading');
}
// ___ __ ___ _ _ ___
// | \ _ _ __ _ __ _ / _|___ | \ _ _ ___ _ __ | | | |_ _|
// | |) | '_/ _` / _` | > _|_ _| | |) | '_/ _ \ '_ \ | |_| || |
// |___/|_| \__,_\__, | \_____| |___/|_| \___/ .__/ \___/|___|
// |___/ |_|
function initDragAndDropUI(){
// add real dom square element to handle sorting
$('.composition_ui .composer .composition .field--name-documents .field__item').each(function(i){
$(this).prepend($('<span>').addClass('handler'));
});
// create remove dropzone
var $remove_zone = $('<div>').addClass('remove-drop-zone')
.appendTo('.composition_ui .composer .composition')
.droppable({
tolerance:'pointer',
// scope:'composition_ui',
over:function(e,ui){
// console.log('on over remove : ui', ui);
ui.draggable.addClass('ready-to-remove');
},
out:function(e,ui){
// console.log('on over remove : ui', ui);
ui.draggable.removeClass('ready-to-remove');
},
drop:function(e,ui){
// console.log('on drop remove : ui', ui);
ui.draggable.remove();
// onOrderChanged(ui);
}
});
// create sortable
$('.composition_ui .composer .composition .field--name-documents').sortable({
revert:false,
handle: ".handler",
receive:function(e, ui){
$('.field__item', this).attr('style', '');
// TODO: trigger event to enable new audiolink player
},
update:function(e, ui){
onOrderChanged(e, ui);
},
connectWith : $remove_zone,
});
// set chutier element draggable
$('.chutier_ui .item-list li>div').draggable({
containment:$('#studio-ui'),
scroll:false,
helper:function(e){
// we reproduce here the irem structure of destination sortable elements
// var $audio_link = $('.audio-link',this);
return $('<div>').addClass('field__item')
.append(
$('<article>').addClass('node').append(
$('<h2>').addClass('node-title').append(
// $('<a>')
// .attr('nid', $audio_link.attr('nid'))
// .html($audio_link.html())
$('.audio-link',this).clone().removeClass('ajax-enable')
)
)
)
.prepend($('<span>').addClass('handler'));
},
// cursor:'grab',
cursorAt:{bottom:10,left:10},
zIndex:999,
revert:true,
revertDuration:0,
connectToSortable:$('.composition_ui .composer .composition .field--name-documents'),
});
};
// TODO: how to remove an item
function onOrderChanged(e, ui){
console.log('onOrderChanged : e', e);
// TODO: record the current order through ajax
var documents = [];
$('a', e.target).each(function(i) {
// console.log(this);
documents.push($(this).attr('nid'));
});
console.log(documents);
// recordCompoList(cid, documents);
};
function recordCompoList(cid, docs){
var ajax_path = 'path';
var path = window.location.origin + Drupal.url(ajax_path);
$.getJSON(path, {
documents:docs
})
.done(function(data){
onRecordCompoDone(data);
})
.fail(function(jqxhr, textStatus, error){
onErrorRecordCompo(jqxhr, textStatus, error);
});
}
function onRecordCompoDone(data){
console.log('onDeleteCompoDone',data);
if(data.status == "ok"){
}else{
console.warn(data.message);
}
};
function onErrorRecordCompo(jqxhr, textStatus, error){
console.warn('record compo failed : '+error, jqxhr.responseText);
};
init();
})(jQuery, Drupal, drupalSettings);
@@ -20,6 +20,7 @@ use Drupal\Core\Render\Element;
* - attributes: HTML attributes for the containing element.
*/
function template_preprocess_composition(array &$variables) {
// dpm($variables);
// Fetch Composition Entity Object.
$composition = $variables['elements']['#composition'];
@@ -4,3 +4,7 @@ edlp_studio-library:
dependencies:
- core/drupalSettings
- core/jquery
- core/jquery.once
- core/jquery.ui.draggable
- core/jquery.ui.droppable
- core/jquery.ui.sortable
@@ -32,6 +32,8 @@ function edlp_studio_page_attachments(array &$attachments) {
$attachments['#attached']['library'][] = 'edlp_studio/edlp_studio-library';
$url = Url::fromRoute('edlp_studio.studio_chutier_ui_ajax', [], ['absolute' => TRUE]);
$attachments['#attached']['drupalSettings']['edlp_studio']['chutier_ui_ajax'] = $url->getInternalPath();
$url = Url::fromRoute('edlp_studio.composition_controller_action_ajax', ['action'=>'open'], ['absolute' => TRUE]);
$attachments['#attached']['drupalSettings']['edlp_studio']['open_compo_ajax_url'] = $url->getInternalPath();
}
/**
@@ -54,7 +56,9 @@ function edlp_studio_theme($existing, $type, $theme, $path) {
'variables' => array(
'title' => t('Compositon'),
'compositions' => null,
'composer' => null,
'composer_header' => null,
'lastcomposition' => null,
'composer_actions' => null,
),
),
'edlp_compositions_list' => array(
@@ -147,3 +151,19 @@ function edlp_studio_node_view(array &$build, \Drupal\Core\Entity\EntityInterfac
}
}
}
/**
* Prepares variables for Composition templates.
*
* Default template: composition.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An associative array containing the user information and any
* - attributes: HTML attributes for the containing element.
*/
// function edlp_studio_preprocess_composition(array &$vars) {
// dpm($vars);
// $vars['test'] = 'test';
// }
@@ -28,7 +28,7 @@ function template_preprocess_edlp_chutier_ui(&$vars){
// get the title
$title = $node->getTitle();
if(!$title) continue;
$trunc_title = Unicode::truncate($title, 30, true, true);
$trunc_title = Unicode::truncate($title, 25, true, true);
// classes
$classes = array('audio-link', 'ajax-link');
// get the entries
@@ -2,9 +2,10 @@
function template_preprocess_edlp_composition_ui(&$vars){
// dpm($vars);
/*
@see https://www.drupal8.ovh/index.php/en/tutoriels/339/render-a-node-or-an-entity
*/
// $view_builder = \Drupal::entityTypeManager()->getViewBuilder($vars['entity_type']);
// $vars['content'] = $view_builder->view($vars['entity'], $vars['view_mode']);
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('composition');
$vars['composition'] = $view_builder->view($vars['lastcomposition']);
}
@@ -9,6 +9,7 @@ function template_preprocess_edlp_compositions_list(&$vars){
'#theme' => 'item_list',
'#items' => [],
);
$i = 0;
foreach($vars['composition_entities'] as $entity){
// get the url
$url = Url::fromRoute('entity.composition.canonical',
@@ -27,8 +28,8 @@ function template_preprocess_edlp_compositions_list(&$vars){
'#options'=>array(
'attributes' => array(
'data-drupal-link-system-path' => $url->getInternalPath(),
'nid' => $entity->id(),
'class' => ['composition-link'],
'cid' => $entity->id(),
'class' => ['composition-link', $i==0 ? 'is-active':''],
'title'=>$title,
),
),
@@ -40,13 +41,14 @@ function template_preprocess_edlp_compositions_list(&$vars){
'#options'=>array(
'attributes' => array(
'data-drupal-link-system-path' => $delete_url->getInternalPath(),
'nid' => $entity->id(),
'cid' => $entity->id(),
'class' => ['delete-composition-link'],
'title'=> t('Delete @title', array('@title'=>$title)),
),
),
)
);
$i++;
}
$vars['compositions']['#items'][] = array(
@@ -61,6 +61,13 @@ class CompositionController extends ControllerBase {
$this->error_message = t("Composition creation needs a name as query paramater!");
}
break;
case 'open':
if($cid){
$this->openComposition($cid);
}else{
$this->error_message = t("Composition opening needs a cid as url paramater!");
}
break;
case 'delete':
if($cid){
$this->deleteComposition($cid);
@@ -109,6 +116,12 @@ class CompositionController extends ControllerBase {
'new_link' => render($new_link_build),
);
break;
case 'open':
$this->getRendredComposition();
$data += array(
'compo' => $this->rendered_compo,
);
break;
// case 'delete':
// # code...
// break;
@@ -135,6 +148,16 @@ class CompositionController extends ControllerBase {
$this->compo->save();
}
private function getRendredComposition(){
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('composition');
$compobuild = $view_builder->view($this->compo, 'default');
$this->rendered_compo = render($compobuild);
}
private function openComposition($cid){
$this->compo = entity_load('composition', $cid);
}
private function deleteComposition($cid){
$this->compo = entity_load('composition', $cid);
$this->compo->delete();
@@ -114,7 +114,14 @@ class StudioUIController extends ControllerBase {
"#theme"=>'edlp_composition_ui',
"#title" => t('Composition'),
"#compositions" => $this->buildCompostionsList(),
"#composer" => $this->buildComposer(),
"#composer_header" => t("Drag and drop documents on the time line from your chutier above."),
"#lastcomposition" => $this->getLastCompo(),
'#composer_actions' => array(
'play_composition'=>array(
"#type"=>'container',
"#markup"=>t('Play my composition'),
),// TODO: add social media links (what about composition visibility uotside studio_ui ?)
),
);
return $composition_ui;
@@ -125,8 +132,8 @@ class StudioUIController extends ControllerBase {
$query = \Drupal::entityQuery('composition')
->condition('user_id', $this->user->id());
$compos_nids = $query->execute();
$compos = entity_load_multiple('composition', $compos_nids);
$compos_ids = $query->execute();
$compos = entity_load_multiple('composition', $compos_ids);
$createurl = Url::fromRoute('edlp_studio.composition_controller_action_ajax', ['action' => 'create'], ['absolute' => TRUE]);
@@ -137,7 +144,16 @@ class StudioUIController extends ControllerBase {
);
}
private function buildComposer(){
return array('#markup'=>'TODO : composer UI');
private function getLastCompo(){
// just get the last compositions
$query = \Drupal::entityQuery('composition')
->condition('user_id', $this->user->id())
->range(0,1)
->sort('created');
$compos_id = $query->execute();
$lastcompo = entity_load('composition', array_pop($compos_id));
return $lastcompo;
}
}
@@ -5,7 +5,15 @@
{{ compositions }}
</section>
<section class="composer">
{{ composer }}
<header>
{{ composer_header }}
</header>
<section class="composition">
{{ composition }}
</section>
<section class="actions">
{{ composer_actions }}
</section>
</section>
</div>
</div>