# HG changeset patch # User ymh # Date 1482181082 -3600 # Node ID ce52f0fca330511f51bd724edfe46b0fa6b0dabf # Parent 9cffc7f32f14568917ce8a53f61a83689a73e610 add volume control to the player diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/app/components/player-sound-control.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/components/player-sound-control.js Mon Dec 19 21:58:02 2016 +0100 @@ -0,0 +1,118 @@ +import Ember from 'ember'; +import * as d3s from 'd3-scale'; + +const speakerClassScale = d3s.scaleQuantize() + .domain([0, 1]) + .range(['fa-volume-down', 'fa-volume-up']); + + +export default Ember.Component.extend({ + classNames: ['player-sound-control'], + + popcorn: null, + + volume: Ember.computed('popcorn', { + get: function() { + let popcorn = this.get('popcorn'); + if(!popcorn) { + return 0; + } + return popcorn.volume(); + }, + set: function(key, value) { + let popcorn = this.get('popcorn'); + if(!popcorn) { + return 0; + } + const newValue = Math.min(1.0, Math.max(0, value)); + popcorn.volume(newValue); + return newValue; + } + }), + + muted: Ember.computed('popcorn', { + get: function() { + let popcorn = this.get('popcorn'); + if(!popcorn) { + return false; + } + return popcorn.muted(); + }, + set: function(key, value) { + let popcorn = this.get('popcorn'); + if(!popcorn) { + return false; + } + if(value) { + popcorn.mute(); + } else { + popcorn.unmute(); + } + return value; + } + + }), + + popcornObserver: Ember.observer('popcorn', function() { + let popcorn = this.get('popcorn'); + if(!popcorn) { + return; + } + popcorn.on('volumechange', () => { this.notifyPropertyChange('volume'); this.notifyPropertyChange('muted'); }); + + }), + + speakerClass: Ember.computed('volume', 'muted', function() { + const volume = this.get('volume'); + const muted = this.get('muted'); + if(muted || volume === 0 ) { + return "fa-volume-off"; + } else { + return speakerClassScale(volume); + } + }), + + mouseEnter: function() { + let baseOffset = this.$("#sound-control-speaker").offset(); + if(this.get('muted')) { + return; + } + this.$("#sound-control-scale").show(400); + this.$("#sound-control-scale").offset({ top: baseOffset.top + 55, left: baseOffset.left}); + }, + mouseLeave: function() { + this.$("#sound-control-scale").hide(400); + }, + + didInsertElement: function() { + this.set('volumeSliderHandler', this.$(".volume-slider").on("input change", (event) => { this.set('volume',Ember.$(event.target).val()); })); + }, + + willDestroyElement: function() { + let volumeSliderHandler = this.get('volumeSliderHandler'); + if(volumeSliderHandler) { + this.$(".volume-slider").off({"input change": volumeSliderHandler}); + } + }, + + actions: { + muteToggle() { + this.set('muted', !this.get('muted')); + }, + clickMinus() { + if(this.get('muted')) { + return; + } + let volume = this.get('volume'); + this.set('volume', volume - 0.1); + }, + clickPlus() { + if(this.get('muted')) { + return; + } + let volume = this.get('volume'); + this.set('volume', volume + 0.1); + } + } + +}); diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/app/styles/app.scss --- a/cms/app-client/app/styles/app.scss Sun Dec 18 01:13:51 2016 +0100 +++ b/cms/app-client/app/styles/app.scss Mon Dec 19 21:58:02 2016 +0100 @@ -65,6 +65,7 @@ @import 'components/playlist-component'; @import 'components/discourses-component'; @import 'components/player-component'; +@import 'components/player-sound-control'; @import 'components/toolbar-component'; @import 'components/notice-component'; @import 'components/notice-location-component'; diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/app/styles/components/player-component.scss --- a/cms/app-client/app/styles/components/player-component.scss Sun Dec 18 01:13:51 2016 +0100 +++ b/cms/app-client/app/styles/components/player-component.scss Mon Dec 19 21:58:02 2016 +0100 @@ -80,7 +80,7 @@ .player-component #audio .progress { position: relative; - margin: 0px 50px; + margin: 0px 20px 0px 50px; background-color: transparent; border-radius: 0px; box-shadow: none; @@ -106,7 +106,7 @@ } .player-component #audio .progress .bar { - width: 226px; + width: 214px; height: 3px; background-color: $corpus-light-blue; margin: -1px 60px 0 60px; @@ -135,7 +135,7 @@ .player-component #audio .meta p { float: left; width: 170px; - margin: 0px 0px 0px 50px; + margin: 0px 0px 0px 45px; padding: 0px; box-sizing: border-box; top: 50%; diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/app/styles/components/player-sound-control.scss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/styles/components/player-sound-control.scss Mon Dec 19 21:58:02 2016 +0100 @@ -0,0 +1,189 @@ +.player-sound-control { + + & { + margin: 0px 19px 0px 0px; + font-size: 20px; + } + + #sound-control-speaker { + width: 2em; + line-height: 80px; + } + + #sound-control-speaker i { + cursor: pointer; + vertical-align: middle; + } + + #sound-control-speaker i::before { + font-size: 20px; + } + + #sound-control-speaker i.fa-times::before { + font-size: 16px; + } + + #sound-control-speaker i.fa-volume-off+i.fa-times { + display:inline-block; + } + + #sound-control-speaker i.fa-times { + display:none; + } + + #sound-control-scale { + background-color: $corpus-white; + width: 1em; + height: 90px; + position: fixed; + z-index: 1; + display: none; + } + + #sound-control-scale:hover { + display: block; + } + + .sound-control-scale-indicator { + color: $corpus-black; + text-align: center; + display: table; + margin: 0 auto; + cursor: pointer; + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Chrome/Safari/Opera */ + -khtml-user-select: none; /* Konqueror */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; + } + + .sound-control-scale-indicator[disabled] { + color: $corpus-grey; + cursor: default; + pointer-events: none; + } + + // taken from http://brennaobrien.com/blog/2014/05/style-input-type-range-in-every-browser.html + + .volume-slider { + height: 5px; + width: 50px; + position: absolute; + + /*removes default webkit styles*/ + -webkit-appearance: none; + + transform: rotate(270deg) translate(-15px, -20px); + -ms-transform: rotate(270deg) translate(30px, 20px); + transform-origin: bottom; + + } + .volume-slider::-webkit-slider-runnable-track { + height: 5px; + width: 50px; + background: #ddd; + border: none; + border-radius: 3px; + margin-top: 11px; + } + .volume-slider::-webkit-slider-thumb { + -webkit-appearance: none; + border: none; + height: 11px; + width: 11px; + border-radius: 50%; + background: $corpus-blue; + margin-top: -3px; + } + + .volume-slider[disabled]::-webkit-slider-thumb { + background: $corpus-grey; + } + + .volume-slider:focus { + outline: none; + } + .volume-slider:focus::-webkit-slider-runnable-track { + background: #ccc; + } + + .volume-slider::-moz-range-track { + width: 50px; + height: 5px; + background: #ddd; + border: none; + border-radius: 2px; + } + + .volume-slider::-moz-range-progress { + background-color: $corpus-light-blue; + } + + .volume-slider::-moz-range-thumb { + border: none; + height: 11px; + width: 11px; + border-radius: 50%; + background: $corpus-blue; + } + + .volume-slider[disabled]::-moz-range-thumb { + background: $corpus-grey; + } + + + /*hide the outline behind the border*/ + .volume-slider:-moz-focusring { + outline: 1px solid $corpus-white; + outline-offset: -1px; + } + + // .volume-slider::-ms-track { + // display:none; + // width: 50px; + // height: 5px; + + // /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ + // background-color: transparent; + + // /*leave room for the larger thumb to overflow with a transparent border */ + // border-color: transparent; + // border-width: 6px 0; + + // /*remove default tick marks*/ + // color: transparent; + // } + // .volume-slider::-ms-fill-lower { + // background-color: $corpus-light-blue; + // border-radius: 11px; + // } + // .volume-slider::-ms-fill-upper { + // background-color: #ddd; + // border-radius: 11px; + // } + // .volume-slider::-ms-thumb { + // border: none; + // height: 11px; + // width: 11px; + // border-radius: 50%; + // background: $corpus-blue; + // } + // .volume-slider[disabled]::-ms-thumb { + // background: $corpus-grey; + // } + + // .volume-slider:focus::-ms-fill-lower { + // background: $corpus-light-blue; + // } + // .volume-slider:focus::-ms-fill-upper { + // background: #ccc; + // } + + #sound-control-scale-minus { + position: absolute; + top: 67px; + left: 7px; + } + +} diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/app/templates/components/player-component.hbs --- a/cms/app-client/app/templates/components/player-component.hbs Sun Dec 18 01:13:51 2016 +0100 +++ b/cms/app-client/app/templates/components/player-component.hbs Mon Dec 19 21:58:02 2016 +0100 @@ -13,6 +13,7 @@ - {{to-minutes remaining}} + {{ player-sound-control popcorn=popcorn }}
{{#if player.model.video}} {{#if player.videoscreen}} diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/app/templates/components/player-sound-control.hbs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/app/templates/components/player-sound-control.hbs Mon Dec 19 21:58:02 2016 +0100 @@ -0,0 +1,15 @@ +{{!----}} + +
+
+
+ {{input + type="range" + min="0" + max="1" + step="0.05" + class="volume-slider" + value=volume + disabled=muted + }} +
-
+
diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/ember-cli-build.js --- a/cms/app-client/ember-cli-build.js Sun Dec 18 01:13:51 2016 +0100 +++ b/cms/app-client/ember-cli-build.js Mon Dec 19 21:58:02 2016 +0100 @@ -50,7 +50,6 @@ }); app.import('bower_components/interval-tree2/dist/interval-tree.js'); - //shims app.import('vendor/shims/ammaps.js', { exports: { diff -r 9cffc7f32f14 -r ce52f0fca330 cms/app-client/tests/integration/components/player-sound-control-test.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/app-client/tests/integration/components/player-sound-control-test.js Mon Dec 19 21:58:02 2016 +0100 @@ -0,0 +1,24 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('player-sound-control', 'Integration | Component | player sound control', { + integration: true +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`{{player-sound-control}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + {{#player-sound-control}} + template block text + {{/player-sound-control}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +});