4.4.4 Prevents global shortcuts on inputs

- Adds a control on the origin of keyboard shortcuts
This prevents pausing the song when typing "space" in the search input.

- Moves volume management to player-service. Adds getters and setters.
The setter also checks the volume so it stays between 0 and 1.
This commit is contained in:
Hyzual 2015-02-15 14:47:58 +01:00
parent 91a5c6d3c3
commit faf004b5b0
10 changed files with 170 additions and 75 deletions

View file

@ -309,38 +309,52 @@ angular.module('JamStash')
}
};
/**
* Returns true if the target of this event is an input
* @param {jQuery event} event
* @return {Boolean}
*/
function isTargetInput (event) {
return (event && event.target.tagName === "INPUT");
}
/* We define player-related methods here instead of in player controller
in order to bind keypresses to <body> and have global shortcuts */
$scope.togglePause = function () {
in order to bind keypresses to <body> and have global shortcuts.
We also check the event so we don't do anything if it's on an input */
$scope.togglePause = function (event) {
if(!isTargetInput(event)) {
if(globals.settings.Jukebox) {
$scope.sendToJukebox('stop');
} else {
player.togglePause();
}
};
$scope.turnVolumeUp = function () {
var volume = player.volume;
if ((volume+0.1) > 1 || volume < 0) {
volume = 0.9;
}
volume += 0.1;
player.volume = volume;
persistence.saveVolume(volume);
};
$scope.turnVolumeDown = function () {
var volume = player.volume;
if (volume > 1 || (volume-0.1) < 0) {
volume = 0.1;
$scope.turnVolumeUp = function (event) {
if(!isTargetInput(event)) {
var volume = player.turnVolumeUp();
persistence.saveVolume(volume);
}
volume -= 0.1;
player.volume = volume;
persistence.saveVolume(volume);
};
$scope.nextTrack = player.nextTrack;
$scope.previousTrack = player.previousTrack;
$scope.turnVolumeDown = function (event) {
if(!isTargetInput(event)) {
var volume = player.turnVolumeDown();
persistence.saveVolume(volume);
}
};
$scope.nextTrack = function (event) {
if(!isTargetInput(event)) {
player.nextTrack();
}
};
$scope.previousTrack = function (event) {
if(!isTargetInput(event)) {
player.previousTrack();
}
};
$rootScope.addToJukebox = function (id) {
if (globals.settings.Debug) { console.log("LOAD JUKEBOX"); }
@ -410,7 +424,7 @@ angular.module('JamStash')
persistence.loadQueue();
persistence.loadTrackPosition();
}
player.volume = persistence.getVolume();
player.setVolume(persistence.getVolume());
}
/* End Startup */
}]);

View file

@ -17,9 +17,8 @@ describe("Main controller", function() {
});
// Mock the player service
player = jasmine.createSpyObj("player", ["togglePause"]);
player = jasmine.createSpyObj("player", ["togglePause", "turnVolumeUp", "turnVolumeDown", "nextTrack", "previousTrack", "setVolume"]);
player.queue = [];
player.volume = 1.0;
// Mock the persistence service
persistence = jasmine.createSpyObj("persistence", ["loadQueue", "loadTrackPosition", "getVolume", "saveVolume"]);
@ -108,41 +107,63 @@ describe("Main controller", function() {
});
});
describe("When I turn the volume up,", function() {
it("it sets the player's volume up by 10% and saves it using the persistence service", function() {
player.volume = 0.5;
it("When I turn the volume up, it sets the player's volume up and saves it using the persistence service", function() {
player.turnVolumeUp.and.returnValue(0.6);
scope.turnVolumeUp();
expect(player.volume).toBe(0.6);
expect(player.turnVolumeUp).toHaveBeenCalled();
expect(persistence.saveVolume).toHaveBeenCalledWith(0.6);
});
it("if the player's resulting volume won't be between 0 and 1, it sets it to 1", function() {
player.volume = 5.91488;
scope.turnVolumeUp();
expect(player.volume).toBe(1.0);
});
});
describe("When I turn the volume down,", function() {
it("it sets the player's volume down by 10% and saves it using the persistence service", function() {
player.volume = 0.5;
it("When I turn the volume down, it sets the player's volume down and saves it using the persistence service", function() {
player.turnVolumeDown.and.returnValue(0.4);
scope.turnVolumeDown();
expect(player.volume).toBe(0.4);
expect(player.turnVolumeDown).toHaveBeenCalled();
expect(persistence.saveVolume).toHaveBeenCalledWith(0.4);
});
it("if the player's resulting volume won't be between 0 and 1, it sets it to 0", function() {
player.volume = 5.91488;
it("When I go to the next track, it calls next track on the player", function() {
scope.nextTrack();
expect(player.nextTrack).toHaveBeenCalled();
});
scope.turnVolumeDown();
it("When I go to the previous track, it calls previous track on the player", function() {
scope.previousTrack();
expect(player.previousTrack).toHaveBeenCalled();
});
expect(player.volume).toBe(0);
describe("Given that I am targeting an input,", function() {
var event;
beforeEach(function() {
event = { target: { tagName: "INPUT" } };
});
it("when I use a shortcut to toggle pause, it doesn't do anything", function() {
scope.togglePause(event);
expect(player.togglePause).not.toHaveBeenCalled();
});
it("when I use a shortcut to turn the volume up, it doesn't do anything", function() {
scope.turnVolumeUp(event);
expect(player.turnVolumeUp).not.toHaveBeenCalled();
expect(persistence.saveVolume).not.toHaveBeenCalled();
});
it("when I use a shortcut to turn the volume down, it doesn't do anything", function() {
scope.turnVolumeDown(event);
expect(player.turnVolumeDown).not.toHaveBeenCalled();
expect(persistence.saveVolume).not.toHaveBeenCalled();
});
it("when I use a shortcut to go to the next track, it doesn't do anything", function() {
scope.nextTrack(event);
expect(player.nextTrack).not.toHaveBeenCalled();
});
it("when I use a shortcut to go to the previous track, it doesn't do anything", function() {
scope.previousTrack(event);
expect(player.previousTrack).not.toHaveBeenCalled();
});
});
});
@ -154,7 +175,7 @@ describe("Main controller", function() {
$controller('AppController', controllerParams);
expect(persistence.getVolume).toHaveBeenCalled();
expect(player.volume).toBe(0.551835);
expect(player.setVolume).toHaveBeenCalledWith(0.551835);
});
});
});

View file

@ -20,7 +20,7 @@
<link href="styles/Mobile.css" rel="stylesheet" type="text/css" data-name="main" />
<link href="" rel="stylesheet" type="text/css" data-name="theme" />
</head>
<body ui-keypress="{'32 179': 'togglePause()', '43 61 187': 'turnVolumeUp()', '45 95 189': 'turnVolumeDown()'}" ui-keydown="{'right 176': 'nextTrack()', 'left 177': 'previousTrack()'}">
<body ui-keypress="{'32 179': 'togglePause($event)', '43 61 187': 'turnVolumeUp($event)', '45 95 189': 'turnVolumeDown($event)'}" ui-keydown="{'right 176': 'nextTrack($event)', 'left 177': 'previousTrack($event)'}">
<div id="container">
<div id="header">
<div id="messages">

View file

@ -160,7 +160,7 @@ angular.module('jamstash.player.directive', ['jamstash.player.service', 'jamstas
});
scope.$watch(function () {
return playerService.volume;
return playerService.getVolume();
}, function (newVal) {
$player.jPlayer('volume', newVal);
if (globals.settings.Debug) { console.log('Volume: ' + Math.round(newVal * 100) + '%'); }

View file

@ -22,10 +22,10 @@ describe("jplayer directive", function() {
$delegate.pauseSong = false;
$delegate.restartSong = false;
$delegate.loadSong = false;
$delegate.volume = 1.0;
$delegate.getPlayingSong = jasmine.createSpy('getPlayingSong').and.callFake(function() {
return playingSong;
});
$delegate.getVolume = jasmine.createSpy('getVolume').and.returnValue(1.0);
$delegate.nextTrack = jasmine.createSpy('nextTrack');
$delegate.songEnded = jasmine.createSpy('songEnded');
$delegate.isLastSongPlaying = jasmine.createSpy('isLastSongPlaying');
@ -170,7 +170,7 @@ describe("jplayer directive", function() {
});
it("When the player service's volume changes, it sets jPlayer's volume", function() {
playerService.volume = 0.2034;
playerService.getVolume.and.returnValue(0.2034);
scope.$apply();
expect($player.jPlayer).toHaveBeenCalledWith('volume', 0.2034);
});

View file

@ -8,6 +8,8 @@ angular.module('jamstash.player.service', ['angular-underscore/utils', 'jamstash
.factory('player', ['globals', function (globals) {
'use strict';
var playerVolume = 1.0;
var player = {
// playingIndex and playingSong aren't meant to be used, they only are public for unit-testing purposes
_playingIndex: -1,
@ -16,7 +18,6 @@ angular.module('jamstash.player.service', ['angular-underscore/utils', 'jamstash
pauseSong: false,
restartSong: false,
loadSong: false,
volume: 1.0,
play: function (song) {
// Find the song's index in the queue, if it's in there
@ -140,6 +141,37 @@ angular.module('jamstash.player.service', ['angular-underscore/utils', 'jamstash
}
}
return undefined;
},
turnVolumeUp: function () {
var volume = playerVolume;
if ((volume + 0.1) > 1 || volume < 0) {
volume = 0.9;
}
volume += 0.1;
playerVolume = Math.round(volume * 100) / 100;
return volume;
},
turnVolumeDown: function () {
var volume = playerVolume;
if (volume > 1 || (volume - 0.1) < 0) {
volume = 0.1;
}
volume -= 0.1;
playerVolume = Math.round(volume * 100) / 100;
return volume;
},
getVolume: function () {
return playerVolume;
},
setVolume: function (volume) {
if (volume > 1) { volume = 1; }
else if(volume < 0) { volume = 0; }
playerVolume = Math.round(volume * 100) / 100;
return player;
}
};

View file

@ -277,4 +277,32 @@ describe("Player service -", function() {
expect(player._playingIndex).toBe(-1);
});
});
describe("When I turn the volume up,", function() {
it("it sets the player's volume up by 10%", function() {
player.setVolume(0.5);
player.turnVolumeUp();
expect(player.getVolume()).toBe(0.6);
});
it("if the player's resulting volume won't be between 0 and 1, it sets it to 1", function() {
player.setVolume(5.91488);
player.turnVolumeUp();
expect(player.getVolume()).toBe(1.0);
});
});
describe("When I turn the volume down,", function() {
it("it sets the player's volume down by 10%", function() {
player.setVolume(0.5);
player.turnVolumeDown();
expect(player.getVolume()).toBe(0.4);
});
it("if the player's resulting volume won't be between 0 and 1, it sets it to 0", function() {
player.setVolume(0.05);
player.turnVolumeDown();
expect(player.getVolume()).toBe(0);
});
});
});

View file

@ -1,6 +1,6 @@
{
"name": "jamstash",
"version": "4.4.3",
"version": "4.4.4",
"description": "HTML5 Audio Streamer for Subsonic, Archive.org browsing and streaming",
"authors": [
"tsquillario (https://github.com/tsquillario)",

View file

@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "Jamstash",
"description": "HTML5 Player for Subsonic & Archive.org",
"version": "4.4.3",
"version": "4.4.4",
"app": {
"launch": {
"web_url": "http://jamstash.com"

View file

@ -1,6 +1,6 @@
{
"name": "jamstash",
"version": "4.4.3",
"version": "4.4.4",
"description": "HTML5 Audio Streamer for Subsonic, Archive.org browsing and streaming",
"author": "Trevor Squillario (https://github.com/tsquillario)",
"contributors": [