mirror of
https://github.com/2ec0b4/kaamelott-soundboard.git
synced 2025-12-08 15:43:24 +00:00
Partage de sons (#4)
* Permet la lecture d'un son passé en paramètre d'URL * Remplace du code créé par l'utilisation d'un template * Ajoute un bouton de partage * Ajoute une région pour gérer une modal * Affiche une modal de partage * Améliore le style du flash de sélection de son * Corrige un mauvais appel de fonction * Supprime la destruction de la vue au scroll de la fenêtre : le comportement n'est pas idéal sur iOS quand il y a le focus sur l'input * Ne joue pas automatiquement le son partagé sur iOS (après avoir tenté : https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ ) * Permet d'éviter le zoom au focus sur l'input * Ajoute, dans le style, des préfixes manquants
This commit is contained in:
@@ -12,10 +12,12 @@ define("app", function(require) {
|
||||
app = Marionette.Application.extend({
|
||||
initialize: function intialize() {
|
||||
this.addRegions({
|
||||
mainRegion: "#main"
|
||||
mainRegion: "#main",
|
||||
modalRegion: "#modal"
|
||||
});
|
||||
|
||||
Radio.channel("App").reply("region:show", this.showRegion.bind(this));
|
||||
Radio.channel("App").reply("modal:show", this.showModal.bind(this));
|
||||
|
||||
this.router = new Marionette.AppRouter();
|
||||
|
||||
@@ -26,7 +28,8 @@ define("app", function(require) {
|
||||
var soundboardController = new SoundboardController();
|
||||
|
||||
this.router.processAppRoutes(soundboardController, {
|
||||
"": "index"
|
||||
"": "index",
|
||||
"son/:slug": "index"
|
||||
});
|
||||
|
||||
if (Backbone.history) {
|
||||
@@ -39,6 +42,10 @@ define("app", function(require) {
|
||||
|
||||
showRegion: function showRegion(params) {
|
||||
this.mainRegion.show(params.view);
|
||||
},
|
||||
|
||||
showModal: function showModal(params) {
|
||||
this.modalRegion.show(params.view);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ define("controllers/soundboard", function(require) {
|
||||
initialize: function() {
|
||||
var soundsRadio = new SoundsRadio();
|
||||
},
|
||||
index: function() {
|
||||
var view = new SoundboardView();
|
||||
index: function(slug) {
|
||||
var view = new SoundboardView({slug: slug});
|
||||
|
||||
Radio.channel("App").request("region:show", { view: view });
|
||||
}
|
||||
|
||||
@@ -34,6 +34,16 @@ define("models/sound", function(require) {
|
||||
},
|
||||
getSoundDetail: function() {
|
||||
return this.get("character")+", "+this.get("episode");
|
||||
},
|
||||
getSlug: function() {
|
||||
return this.get("file").slice(0, this.get("file").lastIndexOf('.'));
|
||||
},
|
||||
toJSON: function(){
|
||||
var json = Backbone.Model.prototype.toJSON.apply(this, arguments);
|
||||
|
||||
json.slug = this.getSlug();
|
||||
|
||||
return json;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
12
js/app/templates/share.hbs
Normal file
12
js/app/templates/share.hbs
Normal file
@@ -0,0 +1,12 @@
|
||||
<div class="share-link">
|
||||
<form action="index.html" method="get">
|
||||
<label for="url">Lien à partager</label>
|
||||
<input type="text" name="url" id="url" value="{{url}}">
|
||||
</form>
|
||||
|
||||
<div class="likely" data-title="#Kaamelott Soundboard - {{title}}" data-url="{{url}}">
|
||||
<div class="facebook">Partager</div>
|
||||
<div class="twitter" data-via="2ec0b4">Tweet</div>
|
||||
<div class="gplus">+1</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1 +1,4 @@
|
||||
<a href="#" role="button" class="btn btn-play">{{title}}</a>
|
||||
<div>
|
||||
<a href="#son/{{slug}}" role="button" class="btn btn-play">{{title}}</a>
|
||||
</div>
|
||||
<a href="#son{{slug}}" role="button" class="btn btn-share"></a>
|
||||
|
||||
3
js/app/templates/soundDetail.hbs
Normal file
3
js/app/templates/soundDetail.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="tooltip">
|
||||
<p>{{detail}}</p>
|
||||
</div>
|
||||
74
js/app/views/share.js
Normal file
74
js/app/views/share.js
Normal file
@@ -0,0 +1,74 @@
|
||||
define("views/share", function(require) {
|
||||
"use strict";
|
||||
|
||||
var Marionette = require("marionette"),
|
||||
ShareTemplate = require("hbs!templates/share"),
|
||||
ShareView;
|
||||
|
||||
require("likely");
|
||||
|
||||
ShareView = Marionette.LayoutView.extend({
|
||||
template: ShareTemplate,
|
||||
templateHelpers: function () {
|
||||
return {
|
||||
title: this.model.get("title"),
|
||||
url: this.getAbsoluteUrl("#son/"+this.model.getSlug())
|
||||
};
|
||||
},
|
||||
ui: {
|
||||
background: "#modal-back",
|
||||
body: ".share-link",
|
||||
field: "input:text"
|
||||
},
|
||||
events: {
|
||||
"click @ui.background": "destroy"
|
||||
},
|
||||
initialize: function(options) {
|
||||
this.model = options.model;
|
||||
|
||||
$(window).on("resize", this.center.bind(this));
|
||||
},
|
||||
onDestroy: function() {
|
||||
$(this.ui.background).remove();
|
||||
|
||||
$(window).off("resize", this.center.bind(this));
|
||||
},
|
||||
onBeforeShow: function() {
|
||||
this.$el.append($("<div/>").attr("id", "modal-back"));
|
||||
},
|
||||
onShow: function() {
|
||||
var that = this;
|
||||
|
||||
likely.initiate();
|
||||
|
||||
this.center();
|
||||
|
||||
window.setTimeout(function() {
|
||||
that.$el
|
||||
.find(that.ui.field)
|
||||
.focus(function() {
|
||||
$(this).select();
|
||||
})
|
||||
.focus();
|
||||
}, 1000);
|
||||
},
|
||||
center: function() {
|
||||
var $body = this.$el.find(this.ui.body);
|
||||
|
||||
$body.css({
|
||||
"top": Math.max(0, (($(window).height() - $body.outerHeight()) / 2) + $(window).scrollTop()) + "px",
|
||||
"left": Math.max(0, (($(window).width() - $body.outerWidth()) / 2) + $(window).scrollLeft()) + "px"
|
||||
});
|
||||
},
|
||||
getAbsoluteUrl: function(url) {
|
||||
var a = document.createElement('a');
|
||||
this.getAbsoluteUrl = function(url) {
|
||||
a.href=url;
|
||||
return a.href;
|
||||
}
|
||||
return this.getAbsoluteUrl(url);
|
||||
}
|
||||
});
|
||||
|
||||
return ShareView;
|
||||
});
|
||||
@@ -1,9 +1,10 @@
|
||||
define("views/sound", function(require) {
|
||||
"use strict";
|
||||
|
||||
var Marionette = require("marionette"),
|
||||
SoundModel = require("models/sound"),
|
||||
SoundTemplate = require("hbs!templates/sound"),
|
||||
var Marionette = require("marionette"),
|
||||
SoundModel = require("models/sound"),
|
||||
SoundTemplate = require("hbs!templates/sound"),
|
||||
SoundDetailTemplate = require("hbs!templates/soundDetail"),
|
||||
SoundView;
|
||||
|
||||
SoundView = Marionette.ItemView.extend({
|
||||
@@ -11,16 +12,39 @@ define("views/sound", function(require) {
|
||||
model: SoundModel,
|
||||
tagName: "li",
|
||||
ui: {
|
||||
soundItem: "a"
|
||||
btn: ".btn",
|
||||
btnPlay: ".btn-play",
|
||||
btnShare: ".btn-share"
|
||||
},
|
||||
events: {
|
||||
"click @ui.soundItem": "toggleSound",
|
||||
"mouseenter @ui.soundItem": "toggleSoundDetail",
|
||||
"mouseleave @ui.soundItem": "toggleSoundDetail"
|
||||
"mouseenter @ui.btnPlay": "toggleSoundDetail",
|
||||
"mouseleave @ui.btnPlay": "toggleSoundDetail",
|
||||
"click @ui.btnPlay": "toggleSound"
|
||||
},
|
||||
triggers: {
|
||||
"click @ui.btnShare": {
|
||||
event: "sound:share",
|
||||
preventDefault: true
|
||||
},
|
||||
},
|
||||
initialize: function() {
|
||||
this.listenTo(this.model, "change:playing", this.playingAttributeChanged);
|
||||
},
|
||||
onShow: function() {
|
||||
var that = this,
|
||||
height;
|
||||
|
||||
if( this.model.get('selected') ) {
|
||||
height = $('header').outerHeight();
|
||||
$('html, body').animate({scrollTop: this.$el.offset().top-height}, 750, 'swing', function() {
|
||||
that.$el.find(that.ui.btn).addClass('flash');
|
||||
});
|
||||
|
||||
if( !/iPhone|iPad|iPod/i.test(navigator.userAgent) ) {
|
||||
this.$el.find(this.ui.btnPlay).click();
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleSound: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -36,26 +60,24 @@ define("views/sound", function(require) {
|
||||
},
|
||||
playingAttributeChanged: function() {
|
||||
if( this.model.get("playing") ) {
|
||||
$(this.ui.soundItem).addClass("playing");
|
||||
$(this.ui.btnPlay).addClass("playing");
|
||||
} else {
|
||||
$(this.ui.soundItem).removeClass("playing");
|
||||
$(this.ui.btnPlay).removeClass("playing");
|
||||
}
|
||||
},
|
||||
toggleSoundDetail: function(e) {
|
||||
var offset;
|
||||
var offset,
|
||||
template;
|
||||
|
||||
if (e.type === "mouseleave") {
|
||||
$(".tooltip").remove();
|
||||
return;
|
||||
}
|
||||
|
||||
offset = $(this.el).offset();
|
||||
offset = $(this.el).offset();
|
||||
template = SoundDetailTemplate({detail: this.model.getSoundDetail()});
|
||||
|
||||
$("<div/>")
|
||||
.addClass("tooltip")
|
||||
.append(
|
||||
$("<p/>").text(this.model.getSoundDetail())
|
||||
)
|
||||
$(template)
|
||||
.css({left: (offset.left+25)+"px", top: (offset.top+30)+"px"})
|
||||
.appendTo("body")
|
||||
.delay(1000)
|
||||
|
||||
@@ -13,9 +13,14 @@ define("views/soundboard", function(require) {
|
||||
regFilter: "#filter",
|
||||
regList: "#list"
|
||||
},
|
||||
initialize: function(options) {
|
||||
this.slug = typeof options.slug !== 'undefined' ? options.slug : '';
|
||||
},
|
||||
onShow: function() {
|
||||
this.showChildView("regFilter", new SoundsFilterView());
|
||||
this.showChildView("regList", new SoundsView());
|
||||
this.showChildView("regList", new SoundsView({
|
||||
slug: this.slug
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ define("views/sounds", function(require) {
|
||||
Radio = require("backbone.radio"),
|
||||
SoundsCollection = require("collections/sounds"),
|
||||
SoundView = require("views/sound"),
|
||||
SoundShareView = require("views/share"),
|
||||
SoundsCollectionView;
|
||||
|
||||
SoundsCollectionView = Marionette.CollectionView.extend({
|
||||
@@ -12,11 +13,14 @@ define("views/sounds", function(require) {
|
||||
collection: new SoundsCollection(),
|
||||
tagName: "ul",
|
||||
childEvents: {
|
||||
"sound:play": "stopPlayingSound"
|
||||
"sound:play": "stopPlayingSound",
|
||||
"sound:share": "shareSoundLink"
|
||||
},
|
||||
initialize: function() {
|
||||
initialize: function(options) {
|
||||
var that = this;
|
||||
|
||||
this.slug = typeof options.slug !== 'undefined' ? options.slug : '';
|
||||
|
||||
this.data = {
|
||||
collection: this.collection
|
||||
};
|
||||
@@ -25,6 +29,17 @@ define("views/sounds", function(require) {
|
||||
this.channel.request("getSounds").then(this.initCollection.bind(this));
|
||||
this.channel.on("sounds:filter", this.filterCollection.bind(this));
|
||||
},
|
||||
onBeforeRender: function() {
|
||||
var sound;
|
||||
|
||||
if( this.slug ) {
|
||||
sound = this.collection.findWhere({file: this.slug+".mp3"});
|
||||
|
||||
if( sound ) {
|
||||
sound.set('selected', true);
|
||||
}
|
||||
}
|
||||
},
|
||||
initCollection: function(sounds) {
|
||||
this.data.collection = new SoundsCollection(sounds);
|
||||
this.collection = this.data.collection;
|
||||
@@ -42,6 +57,11 @@ define("views/sounds", function(require) {
|
||||
if( playingSound ) {
|
||||
playingSound.stop();
|
||||
}
|
||||
},
|
||||
shareSoundLink: function(args) {
|
||||
var view = new SoundShareView({model: args.model});
|
||||
|
||||
Radio.channel("App").request("modal:show", { view: view });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user