player display first part of cartel

This commit is contained in:
Bachir Soussi Chiadmi
2018-03-07 18:08:28 +01:00
parent efac93e50d
commit 608e9f6ae2
14 changed files with 343 additions and 75 deletions
@@ -14,7 +14,8 @@ function edlp_ajax_node_theme($existing, $type, $theme, $path) {
'edlp_ajax_node' => array(
'file' => 'includes/edlp_ajax_node.inc',
'variables' => array(
'node' => NULL
'node_object' => NULL,
'view_mode' => 'default'
),
),
);
@@ -7,17 +7,19 @@
# @License: GPL-V3
edlp_ajax_node.node:
path: '/edlp/node/{nid}'
path: '/edlp/node/{nid}/{viewmode}'
defaults:
_controller: '\Drupal\edlp_ajax_node\Controller\EdlpAjaxNodeController::node'
_title: 'Node'
viewmode: 'default'
requirements:
_permission: 'access content'
edlp_ajax_node.ajaxnode:
path: '/edlp/node/{nid}/ajax'
path: '/edlp/node/{nid}/ajax/{viewmode}'
defaults:
_controller: '\Drupal\edlp_ajax_node\Controller\EdlpAjaxNodeController::nodejson'
_title: 'AjaxNode'
viewmode: 'default'
requirements:
_permission: 'access content'
@@ -8,5 +8,5 @@ function template_preprocess_edlp_ajax_node(&$vars){
@see https://www.drupal8.ovh/index.php/en/tutoriels/339/render-a-node-or-an-entity
*/
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
$vars['node'] = $view_builder->view($vars['node'], 'default');
$vars['node'] = $view_builder->view($vars['node_object'], $vars['view_mode']);
}
@@ -14,11 +14,18 @@ class EdlpAjaxNodeController extends ControllerBase {
private function toRenderable(){
$this->query();
// dpm($this->future_nodes);
return array(
"#theme"=>'edlp_ajax_node',
'#node' => $this->node,
);
if($this->node){
return array(
"#theme"=>'edlp_ajax_node',
'#node_object' => $this->node,
'#view_mode' => $this->viewmode,
);
}else{
return array(
'#markup'=>'404! Node '.$this->nid." not found!"
);
}
}
/**
@@ -26,8 +33,9 @@ class EdlpAjaxNodeController extends ControllerBase {
*
* @return renderable array
*/
public function node($nid) {
public function node($nid, $viewmode) {
$this->nid = $nid;
$this->viewmode = $viewmode;
return $this->toRenderable();
}
@@ -36,16 +44,18 @@ class EdlpAjaxNodeController extends ControllerBase {
*
* @return json
*/
public function nodejson($nid) {
public function nodejson($nid, $viewmode) {
$this->nid = $nid;
$response = new JsonResponse();
$this->viewmode = $viewmode;
$renderable = $this->toRenderable();
$rendered = render($renderable);
$response = new JsonResponse();
$response->setData([
'test'=>'hello edlp ajax node',
'test' => 'hello edlp ajax node',
'nid' => $this->nid,
'rendered'=> $rendered
'view_mode' => $this->viewmode,
'rendered'=> $rendered,
]);
return $response;
@@ -379,13 +379,14 @@
var event = {
'type':'corpus-cliked-on-node',
'target_node':{
'nid':_node_hover_id,
'id':_node_hover_id,
'nid':_nodes[_node_hover_id].nid,
'audio_url':_nodes[_node_hover_id].son_url
},
};
_$canvas.trigger(event);
}else{
console.log('corpus : click on map');
// console.log('corpus : click on map');
_$canvas.trigger('corpus-cliked-on-map');
}
}
@@ -379,13 +379,14 @@
var event = {
'type':'corpus-cliked-on-node',
'target_node':{
'nid':_node_hover_id,
'id':_node_hover_id,
'nid':_nodes[_node_hover_id].nid,
'audio_url':_nodes[_node_hover_id].son_url
},
};
_$canvas.trigger(event);
}else{
console.log('corpus : click on map');
// console.log('corpus : click on map');
_$canvas.trigger('corpus-cliked-on-map');
}
}
@@ -41,11 +41,9 @@ class CorpusController extends ControllerBase {
$nodes_data = [];
foreach ($nodes as $node) {
// this is ideal but it's too heavy to load : the whole ajax json goes from 138kb to 1.23Md (even optimized)...
// this would be ideal but it's too heavy to load : the whole ajax json goes from 138kb to 1.23Md (even optimized)...
// $node_builder = $view_builder->view($node, 'popup');
$entrees = [];
foreach ($node->get('field_entrees')->getValue() as $key => $term) {
$entrees[] = $term['target_id'];
@@ -81,6 +81,10 @@ edlp_vars = {
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;
@@ -109,8 +113,28 @@ edlp_vars = {
this.$playpause.on('click', this.togglePlayPause.bind(this));
// TODO: previous and next btns
},
openDocument(node){
this.setSRC(node.audio_url);
this.loadNode(node.nid);
},
// cartel functions
loadNode(nid){
this.$cartel.addClass('loading');
$.getJSON('/edlp/node/'+nid+'/ajax/player_cartel', {})
.done(this.onNodeLoaded.bind(this))
.fail(this.onNodeLoadFail.bind(this));
},
onNodeLoaded(data){
console.log('AudioPlayer node loaded', data);
this.$cartel.html(data.rendered);
this.$cartel.removeClass('loading');
},
onNodeLoadFail(jqxhr, textStatus, error){
console.warn('AudioPlayer node load failed', jqxhr.responseText);
},
// audio functions
setSRC(url){
console.log('AudioPlayer setSRC : url', url);
// console.log('AudioPlayer setSRC : url', url);
this.clearTimeOutToHide();
this.audio.src = url;
this.show();
@@ -168,6 +192,7 @@ edlp_vars = {
this.$container.removeClass('is-playing');
this.timeOutToHide();
},
// global
show(){
this.$container.addClass('visible');
},
@@ -182,8 +207,12 @@ edlp_vars = {
},
hide(){
this.$container.removeClass('visible');
// TODO: trigger highlighted node remove on corpus map
}
}
// ___ _ _ ___
// / __| __ _ _ ___| | | _ ) __ _ _ _ ___
// \__ \/ _| '_/ _ \ | | _ \/ _` | '_(_-<
@@ -256,7 +285,7 @@ edlp_vars = {
};
function onAjaxLinkLoadError(jqxhr, textStatus, error, $link, sys_path){
console.warn('ajaxlink load failed', jqxhr.responseText);
console.warn('ajaxlink load failed for '+sys_path+' : '+error, jqxhr.responseText);
$link.removeClass('ajax-loading');
_$body.removeClass('ajax-loading');
};
@@ -311,7 +340,7 @@ edlp_vars = {
})
.on('corpus-cliked-on-node', function(e) {
console.log('theme : corpus-cliked-on-node', e);
_audio_player.setSRC(e.target_node.audio_url);
_audio_player.openDocument(e.target_node);
});
}
@@ -1099,7 +1099,7 @@ div.layout-container {
position: relative;
width: 100%;
height: 100%;
padding: 1em;
padding: 0.5em 1em;
-webkit-box-sizing: border-box;
box-sizing: border-box;
z-index: 1; }
@@ -1135,9 +1135,10 @@ footer[role="contentinfo"] {
header[role="banner"] {
position: relative;
padding: 0 0 1em 0;
padding: 0 0 0.5em 0;
border-bottom: 1px solid red;
pointer-events: all; }
pointer-events: all;
height: 70px; }
#block-edlptheme-branding {
display: inline-block; }
@@ -1297,7 +1298,7 @@ body.ajax-loading main[role="main"]:before {
left: 0;
background-color: white;
height: 100%;
width: 300px;
min-width: 300px;
z-index: 20;
opacity: 0;
pointer-events: none;
@@ -1306,10 +1307,11 @@ body.ajax-loading main[role="main"]:before {
#audio-player.visible {
opacity: 1;
pointer-events: all; }
#audio-player .btns, #audio-player .time-line-container, #audio-player .time {
#audio-player > * {
display: inline-block;
vertical-align: middle;
padding: 0 1em 0 0; }
padding: 0;
max-height: 100%; }
#audio-player .btns {
cursor: pointer; }
#audio-player .btns > * {
@@ -1358,6 +1360,69 @@ body.ajax-loading main[role="main"]:before {
#audio-player .time .duration {
font-size: 0.75em;
font-weight: 400; }
#audio-player .favoris {
height: 100%; }
#audio-player .cartel {
max-width: 400px;
margin-left: 1em;
background-color: white;
opacity: 1;
-webkit-transition: opacity 0.5s ease-in-out;
transition: opacity 0.5s ease-in-out; }
#audio-player .cartel.loading {
opacity: 0; }
#audio-player .cartel .entrees {
line-height: 0; }
#audio-player .cartel .entrees span {
display: inline-block;
width: 8px;
height: 8px;
background-color: black;
margin-right: 3px; }
#audio-player .cartel .entrees span[tid='134'] {
background-color: #2b8f2f; }
#audio-player .cartel .entrees span[tid='121'] {
background-color: #3a33b6; }
#audio-player .cartel .entrees span[tid='125'] {
background-color: #2c9f57; }
#audio-player .cartel .entrees span[tid='119'] {
background-color: #c48978; }
#audio-player .cartel .entrees span[tid='132'] {
background-color: #5270bb; }
#audio-player .cartel .entrees span[tid='122'] {
background-color: #fb54d3; }
#audio-player .cartel .entrees span[tid='129'] {
background-color: #e07483; }
#audio-player .cartel .entrees span[tid='120'] {
background-color: #655845; }
#audio-player .cartel .entrees span[tid='130'] {
background-color: #7e0868; }
#audio-player .cartel .entrees span[tid='118'] {
background-color: #0e7121; }
#audio-player .cartel .entrees span[tid='127'] {
background-color: #dabd42; }
#audio-player .cartel .entrees span[tid='133'] {
background-color: #0399bb; }
#audio-player .cartel .entrees span[tid='128'] {
background-color: #399a1c; }
#audio-player .cartel .entrees span[tid='124'] {
background-color: #708540; }
#audio-player .cartel .entrees span[tid='116'] {
background-color: #191bff; }
#audio-player .cartel .entrees span[tid='117'] {
background-color: #279d84; }
#audio-player .cartel .entrees span[tid='131'] {
background-color: #5219ab; }
#audio-player .cartel .entrees span[tid='126'] {
background-color: #d49cb6; }
#audio-player .cartel .entrees span[tid='123'] {
background-color: #497715; }
#audio-player .cartel h2.node-title {
margin: 0.2em 0 0;
font-size: 1em; }
#audio-player .cartel p {
margin: 0;
font-size: 0.75em; }
#audio-player.is-playing .btns .play-pause {
background-image: url(../img/audio-player-pause.svg); }
@@ -58,6 +58,10 @@
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;
@@ -86,8 +90,28 @@
this.$playpause.on('click', this.togglePlayPause.bind(this));
// TODO: previous and next btns
},
openDocument(node){
this.setSRC(node.audio_url);
this.loadNode(node.nid);
},
// cartel functions
loadNode(nid){
this.$cartel.addClass('loading');
$.getJSON('/edlp/node/'+nid+'/ajax/player_cartel', {})
.done(this.onNodeLoaded.bind(this))
.fail(this.onNodeLoadFail.bind(this));
},
onNodeLoaded(data){
console.log('AudioPlayer node loaded', data);
this.$cartel.html(data.rendered);
this.$cartel.removeClass('loading');
},
onNodeLoadFail(jqxhr, textStatus, error){
console.warn('AudioPlayer node load failed', jqxhr.responseText);
},
// audio functions
setSRC(url){
console.log('AudioPlayer setSRC : url', url);
// console.log('AudioPlayer setSRC : url', url);
this.clearTimeOutToHide();
this.audio.src = url;
this.show();
@@ -145,6 +169,7 @@
this.$container.removeClass('is-playing');
this.timeOutToHide();
},
// global
show(){
this.$container.addClass('visible');
},
@@ -159,8 +184,12 @@
},
hide(){
this.$container.removeClass('visible');
// TODO: trigger highlighted node remove on corpus map
}
}
// ___ _ _ ___
// / __| __ _ _ ___| | | _ ) __ _ _ _ ___
// \__ \/ _| '_/ _ \ | | _ \/ _` | '_(_-<
@@ -233,7 +262,7 @@
};
function onAjaxLinkLoadError(jqxhr, textStatus, error, $link, sys_path){
console.warn('ajaxlink load failed', jqxhr.responseText);
console.warn('ajaxlink load failed for '+sys_path+' : '+error, jqxhr.responseText);
$link.removeClass('ajax-loading');
_$body.removeClass('ajax-loading');
};
@@ -288,7 +317,7 @@
})
.on('corpus-cliked-on-node', function(e) {
console.log('theme : corpus-cliked-on-node', e);
_audio_player.setSRC(e.target_node.audio_url);
_audio_player.openDocument(e.target_node);
});
}
@@ -13,6 +13,43 @@
@import 'base/layout';
@import 'base/fonts';
@mixin spining-loader-square{
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(359deg);}
}
animation: rotation 2s infinite linear;
}
@mixin entrie-micro-square {
display:inline-block;
$s:8px;
width:$s; height:$s;
background-color: black;
margin-right: 3px;
&[tid='134']{background-color: $e_col_134;}
&[tid='121']{background-color: $e_col_121;}
&[tid='125']{background-color: $e_col_125;}
&[tid='119']{background-color: $e_col_119;}
&[tid='132']{background-color: $e_col_132;}
&[tid='122']{background-color: $e_col_122;}
&[tid='129']{background-color: $e_col_129;}
&[tid='120']{background-color: $e_col_120;}
&[tid='130']{background-color: $e_col_130;}
&[tid='118']{background-color: $e_col_118;}
&[tid='127']{background-color: $e_col_127;}
&[tid='133']{background-color: $e_col_133;}
&[tid='128']{background-color: $e_col_128;}
&[tid='124']{background-color: $e_col_124;}
&[tid='116']{background-color: $e_col_116;}
&[tid='117']{background-color: $e_col_117;}
&[tid='131']{background-color: $e_col_131;}
&[tid='126']{background-color: $e_col_126;}
&[tid='123']{background-color: $e_col_123;}
}
// header
.layout-container{
@@ -21,17 +58,11 @@
header[role="banner"]{
position: relative;
padding:0 0 1em 0;
padding:0 0 0.5em 0;
border-bottom: 1px solid red;
pointer-events: all;
}
@mixin spining-loader-square{
@keyframes rotation {
from {transform: rotate(0deg);}
to {transform: rotate(359deg);}
}
animation: rotation 2s infinite linear;
// TODO: what header height to fit well with player ??
height:70px;
}
#block-edlptheme-branding{
@@ -192,19 +223,22 @@ main[role="main"]{
position: absolute;
top:0; left:0;
background-color: white;
height:100%; width:300px;
height:100%; min-width:300px;
z-index: 20;
opacity: 0;
// outline: 1px solid blue;
pointer-events: none;
transition: opacity 0.7s ease-in-out;
&.visible{
opacity: 1;
pointer-events:all;
}
.btns, .time-line-container, .time{
&>*{
display: inline-block;
vertical-align: middle;
padding:0 1em 0 0;
padding:0;
max-height: 100%;
// outline: 1px solid green;
}
.btns{
// outline: 1px dotted orange;
@@ -227,13 +261,11 @@ main[role="main"]{
opacity: 0.3;}
}
.time-line-container{
// outline: 1px dotted purple;
.time-line{
position: relative;
width:70px; height:1px;
background-color: #000;
overflow: visible;
// border-top: 1px solid #000;
transform: rotateZ(-45deg);
.loader{
width:0; height:100%;
@@ -249,11 +281,9 @@ main[role="main"]{
}
}
.time{
// outline: 1px dotted brown;
&>*{
width:70px;
text-align: right;
// outline: 1px dotted red;
}
.current-time{
font-size: 1.4em;
@@ -264,7 +294,33 @@ main[role="main"]{
font-weight: 400;
}
}
.favoris{
height:100%;
}
.cartel{
// TODO: set max-width regarding responsive
max-width: 400px;
margin-left: 1em;
background-color: white;
opacity: 1;
transition: opacity 0.5s ease-in-out;
&.loading{opacity: 0;}
.entrees{
line-height: 0;
span{
@include entrie-micro-square;
}
}
h2.node-title{
margin:0.2em 0 0;
font-size: 1em;
}
p{
margin:0;
font-size: 0.75em;
}
}
&.is-playing{
.btns .play-pause{background-image: url(../img/audio-player-pause.svg);}
}
@@ -726,7 +782,6 @@ footer{
}
// _ _ _ ___
// | \| |___ __| |___ | _ \___ _ __ _ _ _ __
// | .` / _ \/ _` / -_) | _/ _ \ '_ \ || | '_ \
@@ -736,30 +791,7 @@ footer{
.inner{
.entrees{
span{
display:inline-block;
$s:8px;
width:$s; height:$s;
background-color: black;
margin-right: 3px;
&[tid='134']{background-color: $e_col_134;}
&[tid='121']{background-color: $e_col_121;}
&[tid='125']{background-color: $e_col_125;}
&[tid='119']{background-color: $e_col_119;}
&[tid='132']{background-color: $e_col_132;}
&[tid='122']{background-color: $e_col_122;}
&[tid='129']{background-color: $e_col_129;}
&[tid='120']{background-color: $e_col_120;}
&[tid='130']{background-color: $e_col_130;}
&[tid='118']{background-color: $e_col_118;}
&[tid='127']{background-color: $e_col_127;}
&[tid='133']{background-color: $e_col_133;}
&[tid='128']{background-color: $e_col_128;}
&[tid='124']{background-color: $e_col_124;}
&[tid='116']{background-color: $e_col_116;}
&[tid='117']{background-color: $e_col_117;}
&[tid='131']{background-color: $e_col_131;}
&[tid='126']{background-color: $e_col_126;}
&[tid='123']{background-color: $e_col_123;}
@include entrie-micro-square;
}
}
.title{
@@ -13,7 +13,7 @@ body, html{
div.layout-container{
position: relative;
width:100%; height:100%;
padding:1em;
padding:0.5em 1em;
box-sizing: border-box;
z-index: 1;
}
@@ -0,0 +1,100 @@
{#
/**
* @file
* Theme override to display a node.
*
* Available variables:
* - node: The node entity with limited access to object properties and methods.
* Only method names starting with "get", "has", or "is" and a few common
* methods such as "id", "label", and "bundle" are available. For example:
* - node.getCreatedTime() will return the node creation timestamp.
* - node.hasField('field_example') returns TRUE if the node bundle includes
* field_example. (This does not indicate the presence of a value in this
* field.)
* - node.isPublished() will return whether the node is published or not.
* Calling other methods, such as node.delete(), will result in an exception.
* See \Drupal\node\Entity\Node for a full list of public properties and
* methods for the node object.
* - label: The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: Themed creation date field.
* - author_name: Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
* - readmore: Flag for more state. Will be true if the teaser content of the
* node cannot hold the main body content.
* - logged_in: Flag for authenticated user status. Will be true when the
* current user is a logged-in member.
* - is_admin: Flag for admin user status. Will be true when the current user
* is an administrator.
*
* @see template_preprocess_node()
*
* @todo Remove the id attribute (or make it a class), because if that gets
* rendered twice on a page this is invalid CSS for example: two lists
* in different view modes.
*/
#}
{%
set classes = [
'node',
'node--type-' ~ node.bundle|clean_class,
node.isPromoted() ? 'node--promoted',
node.isSticky() ? 'node--sticky',
not node.isPublished() ? 'node--unpublished',
view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
]
%}
{{ attach_library('classy/node') }}
<article{{ attributes.addClass(classes) }}>
<div class="entrees">
{# THIS IS REALLY DIRTY !! #}
{% for key, child in content.field_entrees if key|first != '#' %}
{% set tid = child['#cache']['tags'][0]|replace({'taxonomy_term:':''}) %}
<span class="entree" tid="{{ tid }}" title="{{ child }}"></span>
{% endfor %}
</div>
<h2{{ title_attributes.addClass('node-title') }}>
{{ label }}
</h2>
<div{{ content_attributes.addClass('node__content') }}>
{{ content|without('field_entrees') }}
</div>
</article>