From ddc0ed1b9a2528d51e3592acfd4fcc223345a1e9 Mon Sep 17 00:00:00 2001 From: lilia Date: Mon, 2 Mar 2015 11:49:23 -0800 Subject: [PATCH] Add audio and video players Basic implementation using html5 audio/video tags and data URIs. --- js/views/attachment_view.js | 50 +++++++++++++++++++++++++++++++--- stylesheets/_conversation.scss | 6 ++-- stylesheets/manifest.css | 6 ++-- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/js/views/attachment_view.js b/js/views/attachment_view.js index 03b2b248..c71eec42 100644 --- a/js/views/attachment_view.js +++ b/js/views/attachment_view.js @@ -16,9 +16,42 @@ (function () { 'use strict'; + var ImageView = Backbone.View.extend({ + tagName: 'img', + render: function(dataUrl) { + this.$el.attr('src', dataUrl); + return this; + } + }); + + var AudioView = Backbone.View.extend({ + tagName: 'audio', + initialize: function() { + this.$el.attr('controls', ''); + }, + render: function(dataUrl) { + this.$el.attr('src', dataUrl); + return this; + } + }); + + var VideoView = Backbone.View.extend({ + tagName: 'video', + initialize: function() { + this.$el.attr('controls', ''); + }, + render: function(dataUrl, contentType) { + var $el = $(''); + $el.attr('src', dataUrl); + $el.attr('type', contentType); + this.$el.append($el); + return this; + } + }); + Whisper.AttachmentView = Backbone.View.extend({ - tagName: "img", - encode: function () { + className: 'attachment', + encodeAsDataUrl: function () { return new Promise(function(resolve, reject) { var blob = new Blob([this.model.data], { type: this.model.contentType }); var FR = new FileReader(); @@ -30,8 +63,17 @@ }.bind(this)); }, render: function() { - this.encode().then(function(base64) { - this.$el.attr('src', base64); + var view; + switch(this.model.contentType.split('/')[0]) { + case 'image': view = new ImageView(); break; + case 'audio': view = new AudioView(); break; + case 'video': view = new VideoView(); break; + default: + throw 'Unsupported attachment type'; + } + this.encodeAsDataUrl().then(function(base64) { + view.render(base64, this.model.contentType); + view.$el.appendTo(this.$el); this.$el.trigger('update'); }.bind(this)); return this; diff --git a/stylesheets/_conversation.scss b/stylesheets/_conversation.scss index defa91be..c8fc6361 100644 --- a/stylesheets/_conversation.scss +++ b/stylesheets/_conversation.scss @@ -177,8 +177,10 @@ } - .attachments img { - max-width: 100%; + .attachments { + img, audio, video { + max-width: 100%; + } } .outgoing img.avatar { diff --git a/stylesheets/manifest.css b/stylesheets/manifest.css index 30cad05e..6e061944 100644 --- a/stylesheets/manifest.css +++ b/stylesheets/manifest.css @@ -412,8 +412,10 @@ input.new-message { .message-list .outgoing .bubble::after { right: -8px; border-left: 8px solid #2a92e7; } - .message-detail .attachments img, - .message-list .attachments img { + .message-detail .attachments img, .message-detail .attachments audio, .message-detail .attachments video, + .message-list .attachments img, + .message-list .attachments audio, + .message-list .attachments video { max-width: 100%; } .message-detail .outgoing img.avatar, .message-list .outgoing img.avatar {