--- /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);
+ }
+ }
+
+});
--- 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';
--- 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%;
--- /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;
+ }
+
+}
--- 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 @@
<span class="bar" onclick={{action 'setTime'}}><span class="value"></span></span>
<span class="remaining">- {{to-minutes remaining}}</span>
</div>
+ {{ player-sound-control popcorn=popcorn }}
<div class="controls extra">
{{#if player.model.video}}
{{#if player.videoscreen}}
--- /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 @@
+{{!--<span id="sound-control-speaker" class="fa {{speakerClass}}" {{action 'muteToggle'}} aria-hidden="true"></span>--}}
+<div id="sound-control-speaker" aria-hidden="true"><i class="fa {{speakerClass}}" {{action 'muteToggle'}}></i><i class="fa fa-times" {{action 'muteToggle'}}></i></div>
+<div id="sound-control-scale">
+ <div id="sound-control-scale-plus" class="sound-control-scale-indicator" {{ action 'clickPlus' }} disabled={{muted}}>+</div>
+ {{input
+ type="range"
+ min="0"
+ max="1"
+ step="0.05"
+ class="volume-slider"
+ value=volume
+ disabled=muted
+ }}
+ <div id="sound-control-scale-minus" class="sound-control-scale-indicator" {{ action 'clickMinus' }} disabled={{muted}}>-</div>
+</div>
--- 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: {
--- /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');
+});