VulpesOS/gaia/apps/camera/js/lib/sounds.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

162 lines
2.9 KiB
JavaScript
Executable file

define(function(require, exports, module) {
'use strict';
/**
* Exports
*/
module.exports = Sounds;
/**
* Initialize a new `Sounds` interface.
*
* @constructor
*/
function Sounds(list) {
this.items = {};
(list || []).forEach(this.add, this);
}
/**
* Add a new sound.
*
* Checks if this sound
* is enabled, and sets
* up an observer.
*
* @param {Object} data
*
*/
Sounds.prototype.add = function(data) {
var self = this;
var sound = {
name: data.name,
url: data.url,
setting: data.setting,
enabled: false
};
this.items[data.name] = sound;
this.isEnabled(sound, function(value) {
self.setEnabled(sound, value);
self.observeSetting(sound);
});
};
/**
* Check if a sound is
* enabled inside mozSettings.
*
* This is wrapped in a setTimeout
* to prevent expensive mozSettings
* API from blocking other operations.
*
* @param {Object} sound
* @param {Function} done
*/
Sounds.prototype.isEnabled = function(sound, done) {
setTimeout(function() {
var mozSettings = navigator.mozSettings;
var key = sound.setting;
// Requires navigator.mozSettings
if (!mozSettings) {
return;
}
mozSettings
.createLock()
.get(key)
.onsuccess = onSuccess;
function onSuccess(e) {
var result = e.target.result[key];
done(result);
}
});
};
/**
* Observe mozSettings for changes
* on the given settings key.
*
* @param {Object} sound
*
*/
Sounds.prototype.observeSetting = function(sound) {
var mozSettings = navigator.mozSettings;
var key = sound.setting;
var self = this;
if (mozSettings) {
mozSettings.addObserver(key, function(e) {
self.setEnabled(sound, e.settingValue);
});
}
};
/**
* Set a sounds `enabled` key.
*
* @param {Object} sound
* @param {Boolean} value
*
*/
Sounds.prototype.setEnabled = function(sound, value) {
sound.enabled = value;
};
/**
* Play a sound by name.
*
* @param {String} name
* @public
*/
Sounds.prototype.play = function(name) {
var sound = this.items[name];
if (!sound.audio) {
sound.audio = this.createAudio(sound.url);
}
this.playSound(sound);
};
/**
* Return a function that plays
* the given sound when called.
*
* @param {String} name
* @return {Funciton}
* @public
*/
Sounds.prototype.player = function(name) {
return (function() { this.play(name); }).bind(this);
};
/**
* Play a sound.
*
* @param {Object} sound
*
*/
Sounds.prototype.playSound = function(sound) {
if (sound.enabled) {
// cloneNode() lets us play overlapping sounds and is needed when the
// user takes pictures very rapidly.
// See http://robert.ocallahan.org/2011/11/latency-of-html5-sounds.html
sound.audio.cloneNode(true).play();
}
};
/**
* Create an audio element.
*
* @param {String} url
* @return {HTMLAudioElement}
*/
Sounds.prototype.createAudio = function(url) {
var audio = new Audio(url);
audio.mozAudioChannelType = 'notification';
return audio;
};
});