import { Project } from "./project";
import { Session } from "./session";
import { GeoPosition } from "./geo-position";
import { Stream } from "./stream";
import { logger } from "./shims";
import { ApiClient } from "./api-client";
import { User } from "./user";
/** This class is the primary integration point between Roundware's server and your application
NOTE that we depend on jQuery being injected, because we use its $.ajax function. As browsers
evolve and the whatwg-fetch polyfill evolves, we may be able to switch over to using window.fetch
@example
var roundwareServerUrl = "http://localhost:8888/api/2";
var roundwareProjectId = 1;
var roundware = new Roundware(window,{
serverUrl: roundwareServerUrl,
projectId: roundwareProjectId
});
function ready() {
console.info("Connected to Roundware Server. Ready to play.");
// this is a good place to initialize audio player controls, etc.
}
// Generally we throw user-friendly messages and log a more technical message
function handleError(userErrMsg) {
console.error("Roundware Error: " + userErrMsg);
}
roundware.connect().
then(ready).
catch(handleError);
function startListening(streamURL) {
console.info("Loading " + streamURL);
// good place to connect your audio player to the audio stream
}
roundware.play(startListening).catch(handleError);
**/
class Roundware {
/** Initialize a new Roundware instance
* @param {Object} window - representing the context in which we are executing - provides references to window.navigator, window.console, etc.
* @param {Object} options - Collection of parameters for configuring this Roundware instance
* @param {String} options.serverUrl - identifies the Roundware server
* @param {Number} options.projectId - identifies the Roundware project to connect
* @param {Boolean} options.geoListenEnabled - whether or not to attempt to initialize geolocation-based listening
* @throws Will throw an error if serveUrl or projectId are missing **/
constructor(window,options = {}) {
this._serverUrl = options.serverUrl;
this._projectId = options.projectId;
if (this._serverUrl === undefined) {
throw "Roundware objects must be initialized with a serverUrl";
}
if (this._projectId === undefined) {
throw "Roundware objects must be initialized with a projectId";
}
this._apiClient = new ApiClient(window,this._serverUrl);
options.apiClient = this._apiClient;
let navigator = window.navigator;
this._user = options.user || new User(options);
this._geoPosition = options.geoPosition || new GeoPosition(navigator,options);
this._session = options.session || new Session(navigator,this._projectId,this._geoPosition.geoListenEnabled,options);
this._project = options.project || new Project(this._projectId,options);
this._stream = options.stream || new Stream(options);
}
/** Initiate a connection to Roundware
* @return {Promise} - Can be resolved in order to get the audio stream URL, or rejected to get an error message; see example above **/
connect() {
this._geoPosition.connect(this._stream.update); // want to start this process as soon as possible, as it can take a few seconds
logger.info("Initializing Roundware for project ID #" + this._projectId);
return this._user.connect().
then(this._session.connect).
then(this._project.connect).
then((sessionId) => this._sessionId = sessionId);
}
/** Create or resume the audio stream o
* @see Stream.play **/
play(firstPlayCallback = () => {}) {
return this._geoPosition.waitForInitialGeolocation().then((initialCoordinates) => {
return this._stream.play(this._sessionId,initialCoordinates,firstPlayCallback);
});
}
/** Tell Roundware server to pause the audio stream. You should always call this when the local audio player has been paused.
* @see Stream.pause **/
pause() {
this._stream.pause();
}
/** Update the Roundware stream with new tag IDs
* @param {string} tagIdStr - comma-separated list of tag IDs to send to the streams API **/
tags(tagIdStr) {
this._stream.update({ tag_ids: tagIdStr });
}
}
// Slight hack here to export Roundware module to browser properly; see https://github.com/webpack/webpack/issues/3929
module.exports = Roundware;