feat(ui): ajoute un bloc audio mis en forme avec Plyr

master
Jérôme Lebleu 2019-09-18 12:17:49 +02:00
Parent 00c8f6a3d7
révision 1ee6af3fcc
11 fichiers modifiés avec 161 ajouts et 0 suppressions

Voir le fichier

@ -4,6 +4,7 @@ import './vendor/bootstrap';
import './lib/slider';
import './lib/sticky';
import initAudioPlayer from './lib/audio';
import initNavBar from './lib/navbar';
// Exporte jQuery pour un usage externe
@ -16,5 +17,19 @@ window.$ = $;
*/
$(window).on('load.app', () => {
// supprime la classe 'no-js' au chargement
document.querySelectorAll('.no-js')
.forEach((el) => el.classList.remove('no-js'));
// initialise le menu principal
initNavBar(document.querySelector('.navbar-main'));
// charge les lecteurs audio de la page
const plyrOptions = typeof window.STATIC_URL === 'undefined' ? {} : {
// évite de passer par un CDN tiers
blankUrl: `${window.STATIC_URL}vendor/plyr/blank.mp4`,
iconUrl: `${window.STATIC_URL}vendor/plyr/plyr.svg`
};
document.querySelectorAll('.audio-player')
.forEach((el) => initAudioPlayer(el, plyrOptions));
});

30
assets/js/lib/audio.js Normal file
Voir le fichier

@ -0,0 +1,30 @@
import Plyr from 'plyr/src/js/plyr';
/**
* ------------------------------------------------------------------------
* Constantes
* ------------------------------------------------------------------------
*/
const Default = {
controls: [
'play',
'progress',
'current-time',
'mute',
'volume'
],
invertTime: false
};
/**
* ------------------------------------------------------------------------
* Fonctions
* ------------------------------------------------------------------------
*/
function initAudioPlayer(element, options) {
return new Plyr(element, Object.assign({}, Default, options));
}
export default initAudioPlayer;

Voir le fichier

@ -7,6 +7,7 @@
// Vendors
@import "vendor/bootstrap";
@import "vendor/plyr";
@import "vendor/tiny-slider";
// Base styles
@ -20,6 +21,7 @@
@import "layout/footer";
// Components
@import "components/audio";
@import "components/badge";
@import "components/buttons";
@import "components/card";

Voir le fichier

@ -0,0 +1,25 @@
// -----------------------------------------------------------------------------
// Styles du lecteur d'un fichier audio
// -----------------------------------------------------------------------------
.audio-container {
padding: $spacer;
background-color: $secondary;
color: $white;
.plyr__controls {
padding: 0;
}
@include media-breakpoint-up(md) {
padding: $spacer * 1.5 $spacer * 2;
}
}
.audio-title{
text-align: center;
}
.no-js .audio-player {
display: block;
}

17
assets/scss/vendor/_plyr.scss externe Normal file
Voir le fichier

@ -0,0 +1,17 @@
// ----------------------------------------------------------------------------
// Plyr
// ----------------------------------------------------------------------------
// see: https://github.com/sampotts/plyr
$plyr-range-fill-bg: $white;
$plyr-range-thumb-shadow: 0 0 0 1px rgba($dark, .1);
$plyr-audio-range-thumb-shadow-color: rgba($dark, .1);
$plyr-audio-controls-bg: $secondary;
$plyr-audio-control-color: $white;
$plyr-audio-control-color-hover: $white;
$plyr-audio-control-bg-hover: rgba($white, .2);
$plyr-audio-progress-buffered-bg: scale-color($secondary, $lightness: 40%);
@import "plyr/src/sass/plyr";

Voir le fichier

@ -29,6 +29,11 @@ const CONFIG = {
'!assets/{img,js,scss}/**/*'
],
dest: ''
},
{
// Plyr
src: 'node_modules/plyr/dist/{blank.mp4,plyr.svg}',
dest: 'vendor/plyr'
}
],

Voir le fichier

@ -8,6 +8,7 @@ from wagtail.core import blocks
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.embeds.blocks import EmbedBlock
from wagtail.images.blocks import ImageChooserBlock
from wagtailmedia.blocks import AbstractMediaChooserBlock
from lens.blog.blocks import LastArticlesBlock
from lens.demarches.blocks import DemarchesBlock
@ -367,6 +368,26 @@ class IconTextBlock(ReactBlockMixin, StylizedBlockMixin, blocks.StructBlock):
template = 'blocks/icon_text_block.html'
# AUDIO
# ------------------------------------------------------------------------------
class AudioChooserBlock(AbstractMediaChooserBlock):
"""
Bloc d'un fichier audio choisi depuis un objet `SourceMedia` existant.
"""
class Meta:
label = "Audio"
icon = 'media'
template = 'blocks/audio_block.html'
def clean(self, value):
if value and value.type != 'audio':
raise ValidationError("Le média doit être un fichier audio.")
return super().clean(value)
# CONTENEURS
# ------------------------------------------------------------------------------
@ -455,6 +476,7 @@ class BaseStreamBlock(blocks.StreamBlock):
card_block = CardBlock()
embed_block = EmbedBlock(label="Média intégré")
audio_block = AudioChooserBlock()
class RowBlock(ReactBlockMixin, blocks.StructBlock):

Voir le fichier

@ -50,6 +50,7 @@
{% endblock %}
{% block javascript %}
<script>window.STATIC_URL = '{{ STATIC_URL }}';</script>
<script src="{% min_static "js/app.js" %}"></script>
{% endblock %}
</body>

Voir le fichier

@ -0,0 +1,6 @@
<div class="audio-container">
<h4 class="audio-title">{{ self.title }}</h4>
<audio class="audio-player d-none" controls>
{{ value.source_tag }}
</audio>
</div>

37
package-lock.json générée
Voir le fichier

@ -3180,6 +3180,11 @@
"is-plain-object": "^2.0.1"
}
},
"core-js": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz",
"integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ=="
},
"core-js-compat": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz",
@ -3416,6 +3421,11 @@
"array-find-index": "^1.0.1"
}
},
"custom-event-polyfill": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz",
"integrity": "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w=="
},
"cyclist": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
@ -7911,6 +7921,11 @@
}
}
},
"loadjs": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/loadjs/-/loadjs-3.6.1.tgz",
"integrity": "sha512-AZEBw2GWdJk2IzBgQ+Wohoao5j+t0rajqK8dJu8jQqgYxDTxhmCt0ayMo/vCa0ZAMvZxnJcam6uLICfnVd8KAw=="
},
"localtunnel": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz",
@ -9512,6 +9527,18 @@
"irregular-plurals": "^2.0.0"
}
},
"plyr": {
"version": "3.5.6",
"resolved": "https://registry.npmjs.org/plyr/-/plyr-3.5.6.tgz",
"integrity": "sha512-buudbt2qwZYjEdBXW9DvQ7t/LqaSbv9tSjCrqg7nTXVM5BXNdhuiJCyvko+5+DFMdp30mliyKGoOHGXz43OwrA==",
"requires": {
"core-js": "^3.1.4",
"custom-event-polyfill": "^1.0.7",
"loadjs": "^3.6.1",
"rangetouch": "^2.0.0",
"url-polyfill": "^1.1.5"
}
},
"popper.js": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz",
@ -9895,6 +9922,11 @@
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"dev": true
},
"rangetouch": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/rangetouch/-/rangetouch-2.0.0.tgz",
"integrity": "sha512-y66wTFbwh7KafYligRsmIYYR1kZY8U9tGHH9PgbVhBUFmGzPMsOSjslXPedgR5D3M9W1QKVbAf1AtaVAt7JJTw=="
},
"raw-body": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz",
@ -12959,6 +12991,11 @@
"prepend-http": "^1.0.1"
}
},
"url-polyfill": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/url-polyfill/-/url-polyfill-1.1.7.tgz",
"integrity": "sha512-ZrAxYWCREjmMtL8gSbSiKKLZZticgihCvVBtrFbUVpyoETt8GQJeG2okMWA8XryDAaHMjJfhnc+rnhXRbI4DXA=="
},
"url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",

Voir le fichier

@ -13,6 +13,7 @@
"dependencies": {
"bootstrap": "~4.3.1",
"jquery": "^3.4.1",
"plyr": "~3.5.6",
"popper.js": "^1.15.0",
"tiny-slider": "~2.9.2"
},