speaker-calibration 2.2.219 → 2.2.221

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.eslintignore +71 -71
  2. package/.eslintrc.json +40 -40
  3. package/.gitignore +81 -0
  4. package/.prettierignore +69 -69
  5. package/.prettierrc +14 -14
  6. package/LICENSE +20 -20
  7. package/README.md +133 -133
  8. package/__mocks__/fileMock.js +1 -1
  9. package/__mocks__/styleMock.js +1 -1
  10. package/babel.config.js +3 -3
  11. package/coverage/clover.xml +71 -71
  12. package/coverage/coverage-final.json +224 -224
  13. package/coverage/lcov-report/PythonServerInterface.js.html +265 -265
  14. package/coverage/lcov-report/base.css +354 -354
  15. package/coverage/lcov-report/block-navigation.js +82 -82
  16. package/coverage/lcov-report/index.html +123 -123
  17. package/coverage/lcov-report/prettify.css +101 -101
  18. package/coverage/lcov-report/prettify.js +937 -937
  19. package/coverage/lcov-report/sorter.js +189 -189
  20. package/coverage/lcov-report/src/index.html +121 -121
  21. package/coverage/lcov-report/src/server/PythonServerInterface.js.html +268 -268
  22. package/coverage/lcov-report/src/server/index.html +123 -123
  23. package/coverage/lcov-report/src/tasks/audioCalibrator.js.html +499 -499
  24. package/coverage/lcov-report/src/tasks/audioRecorder.js.html +412 -412
  25. package/coverage/lcov-report/src/tasks/index.html +143 -143
  26. package/coverage/lcov-report/src/tasks/volume/index.html +123 -123
  27. package/coverage/lcov-report/src/tasks/volume/volume.js.html +409 -409
  28. package/coverage/lcov-report/src/utils.js.html +172 -172
  29. package/coverage/lcov.info +91 -91
  30. package/dist/example/NoSleep.min.js +1 -1
  31. package/dist/example/fetch-languages-sheets.js +77 -77
  32. package/dist/example/i18n.js +29082 -28681
  33. package/dist/example/index.html +47 -47
  34. package/dist/example/listener.html +81 -79
  35. package/dist/example/server.js +51 -51
  36. package/dist/example/speaker.html +145 -145
  37. package/dist/example/speakerUI.js +273 -273
  38. package/dist/example/styles.css +152 -152
  39. package/dist/listener.js +411 -4
  40. package/dist/main.js +11 -11
  41. package/dist/mlsGen.js +6814 -6814
  42. package/dist/mlsGen.wasm +0 -0
  43. package/dist/package-lock.json +1018 -1018
  44. package/dist/package.json +18 -18
  45. package/doc/AudioCalibrator.html +417 -417
  46. package/doc/AudioPeer.html +251 -251
  47. package/doc/AudioRecorder.html +195 -195
  48. package/doc/ImpulseResponse.html +215 -215
  49. package/doc/Listener.html +308 -308
  50. package/doc/MlsGenInterface.html +226 -226
  51. package/doc/MyEventEmitter.html +274 -274
  52. package/doc/PythonServerAPI.html +109 -109
  53. package/doc/Speaker.html +276 -276
  54. package/doc/Takes%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +128 -128
  55. package/doc/Takes%20the%20url%20of%20the%20current%20site%0Aand%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +138 -138
  56. package/doc/Takes%20the%20url%20of%20the%20current%20site%20and%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +137 -137
  57. package/doc/Volume.html +88 -88
  58. package/doc/audioCalibrator.js.html +179 -179
  59. package/doc/audioPeer.js.html +175 -175
  60. package/doc/audioRecorder.js.html +163 -163
  61. package/doc/creates%20a%20new%20AudioRecorder%20instance.%20%0ASets%20up%20the%20audio%20context%20and%20file%20reader..html +114 -114
  62. package/doc/fonts/OpenSans-Bold-webfont.svg +1829 -1829
  63. package/doc/fonts/OpenSans-BoldItalic-webfont.svg +1829 -1829
  64. package/doc/fonts/OpenSans-Italic-webfont.svg +1829 -1829
  65. package/doc/fonts/OpenSans-Light-webfont.svg +1830 -1830
  66. package/doc/fonts/OpenSans-LightItalic-webfont.svg +1834 -1834
  67. package/doc/fonts/OpenSans-Regular-webfont.svg +1830 -1830
  68. package/doc/global.html +308 -308
  69. package/doc/index.html +58 -58
  70. package/doc/listener.js.html +170 -170
  71. package/doc/mlsGen_mlsGenInterface.js.html +117 -117
  72. package/doc/myEventEmitter.js.html +124 -124
  73. package/doc/peer-connection_audioPeer.js.html +188 -188
  74. package/doc/peer-connection_listener.js.html +311 -311
  75. package/doc/peer-connection_speaker.js.html +381 -381
  76. package/doc/scripts/linenumber.js +25 -25
  77. package/doc/scripts/prettify/Apache-License-2.0.txt +202 -202
  78. package/doc/scripts/prettify/lang-css.js +24 -24
  79. package/doc/scripts/prettify/prettify.js +640 -640
  80. package/doc/server_PythonServerAPI.js.html +160 -160
  81. package/doc/speaker.js.html +248 -248
  82. package/doc/styles/jsdoc-default.css +371 -371
  83. package/doc/styles/prettify-jsdoc.css +111 -111
  84. package/doc/styles/prettify-tomorrow.css +163 -163
  85. package/doc/tasks_audioCalibrator.js.html +207 -207
  86. package/doc/tasks_audioRecorder.js.html +190 -190
  87. package/doc/tasks_impulse-response_impulseResponse.js.html +442 -442
  88. package/doc/tasks_impulse-response_mlsGen_mlsGenInterface.js.html +175 -175
  89. package/doc/tasks_volume_volume.js.html +185 -185
  90. package/doc/utils.js.html +105 -105
  91. package/jest.config.js +173 -173
  92. package/netlify.toml +26 -26
  93. package/package.json +78 -78
  94. package/src/config/firebase.js +26 -26
  95. package/src/index.html +21 -21
  96. package/src/listener-app/listener.js +377 -351
  97. package/src/main.js +22 -22
  98. package/src/myEventEmitter.js +83 -83
  99. package/src/peer-connection/audioPeer.js +148 -183
  100. package/src/peer-connection/listener.js +467 -389
  101. package/src/peer-connection/peerErrors.js +25 -25
  102. package/src/peer-connection/speaker.js +812 -810
  103. package/src/powerCheck.js +98 -98
  104. package/src/server/PythonServerAPI.js +869 -869
  105. package/src/tasks/audioCalibrator.js +360 -360
  106. package/src/tasks/audioRecorder.js +315 -315
  107. package/src/tasks/combination/combination.js +3171 -3167
  108. package/src/tasks/combination/mlsGen/mlsGen.cpp +98 -98
  109. package/src/tasks/combination/mlsGen/mlsGen.hpp +303 -303
  110. package/src/tasks/combination/mlsGen/mlsGenInterface.js +131 -131
  111. package/src/tasks/combination/mlsGen/mlsGenTest.cpp +180 -180
  112. package/src/tasks/impulse-response/impulseResponse.js +610 -610
  113. package/src/tasks/impulse-response/mlsGen/mlsGen.cpp +98 -98
  114. package/src/tasks/impulse-response/mlsGen/mlsGen.hpp +303 -303
  115. package/src/tasks/impulse-response/mlsGen/mlsGenInterface.js +131 -131
  116. package/src/tasks/impulse-response/mlsGen/mlsGenTest.cpp +180 -180
  117. package/src/tasks/volume/volume.cpp +2 -2
  118. package/src/tasks/volume/volume.hpp +22 -22
  119. package/src/tasks/volume/volume.js +279 -279
  120. package/src/utils.js +205 -205
  121. package/webpack.config.js +64 -64
  122. package/.github/workflows/update-phrases.yml +0 -37
  123. package/makefile +0 -74
package/src/main.js CHANGED
@@ -1,22 +1,22 @@
1
- // import Listener from './peer-connection/listener';
2
- import Speaker from './peer-connection/speaker';
3
-
4
- import VolumeCalibration from './tasks/volume/volume';
5
- import ImpulseResponseCalibration from './tasks/impulse-response/impulseResponse';
6
- import CombinationCalibration from './tasks/combination/combination';
7
-
8
- import {
9
- UnsupportedDeviceError,
10
- MissingSpeakerIdError,
11
- CalibrationTimedOutError,
12
- } from './peer-connection/peerErrors';
13
-
14
- export {
15
- Speaker,
16
- VolumeCalibration,
17
- ImpulseResponseCalibration,
18
- UnsupportedDeviceError,
19
- MissingSpeakerIdError,
20
- CalibrationTimedOutError,
21
- CombinationCalibration,
22
- };
1
+ // import Listener from './peer-connection/listener';
2
+ import Speaker from './peer-connection/speaker';
3
+
4
+ import VolumeCalibration from './tasks/volume/volume';
5
+ import ImpulseResponseCalibration from './tasks/impulse-response/impulseResponse';
6
+ import CombinationCalibration from './tasks/combination/combination';
7
+
8
+ import {
9
+ UnsupportedDeviceError,
10
+ MissingSpeakerIdError,
11
+ CalibrationTimedOutError,
12
+ } from './peer-connection/peerErrors';
13
+
14
+ export {
15
+ Speaker,
16
+ VolumeCalibration,
17
+ ImpulseResponseCalibration,
18
+ UnsupportedDeviceError,
19
+ MissingSpeakerIdError,
20
+ CalibrationTimedOutError,
21
+ CombinationCalibration,
22
+ };
@@ -1,83 +1,83 @@
1
- /**
2
- * A simple event emitter class. Objects that inheret this class or implement it can then bubble events up to the UI
3
- * similar to existings event emitter such as 'onChange' or 'onClick'.
4
- */
5
- class MyEventEmitter {
6
- #events;
7
-
8
- /** .
9
- * .
10
- * .
11
- * Default constructor, intializes an empty object to store events
12
- *
13
- * @example
14
- */
15
- constructor() {
16
- this.#events = {};
17
- }
18
-
19
- /**
20
- * The external API for this class. Gets called with an event name and a callback function that is fired when the event is emitted.
21
- *
22
- * @param name
23
- * @param listener
24
- * @example
25
- */
26
- on(name, listener) {
27
- if (!this.#events[name]) {
28
- this.#events[name] = [];
29
- }
30
-
31
- this.#events[name].push(listener);
32
- }
33
-
34
- /** .
35
- * .
36
- * .
37
- * Function to remove a listener that was previously set
38
- *
39
- * @param {*} name
40
- * @param {*} listenerToRemove
41
- * @example
42
- */
43
- removeListener(name, listenerToRemove) {
44
- if (!this.#events[name]) {
45
- throw new Error(`Can't remove a listener. Event "${name}" doesn't exits.`);
46
- }
47
-
48
- /**
49
- *
50
- * @param listener
51
- * @example
52
- */
53
- const filterListeners = listener => listener !== listenerToRemove;
54
-
55
- this.#events[name] = this.#events[name].filter(filterListeners);
56
- }
57
-
58
- /**
59
- * The internal API for this class. Gets called with an event name and a data object.
60
- * Any callbacks that have been set to listen to the matching event are dispatched.
61
- *
62
- * @param name
63
- * @param data
64
- * @example
65
- */
66
- emit(name, data) {
67
- if (!this.#events[name]) {
68
- throw new Error(`Can't emit an event. Event "${name}" doesn't exits.`);
69
- }
70
-
71
- /**
72
- *
73
- * @param {*} callback
74
- */
75
- const fireCallbacks = callback => {
76
- callback(data);
77
- };
78
-
79
- this.#events[name].forEach(fireCallbacks);
80
- }
81
- }
82
-
83
- export default MyEventEmitter;
1
+ /**
2
+ * A simple event emitter class. Objects that inheret this class or implement it can then bubble events up to the UI
3
+ * similar to existings event emitter such as 'onChange' or 'onClick'.
4
+ */
5
+ class MyEventEmitter {
6
+ #events;
7
+
8
+ /** .
9
+ * .
10
+ * .
11
+ * Default constructor, intializes an empty object to store events
12
+ *
13
+ * @example
14
+ */
15
+ constructor() {
16
+ this.#events = {};
17
+ }
18
+
19
+ /**
20
+ * The external API for this class. Gets called with an event name and a callback function that is fired when the event is emitted.
21
+ *
22
+ * @param name
23
+ * @param listener
24
+ * @example
25
+ */
26
+ on(name, listener) {
27
+ if (!this.#events[name]) {
28
+ this.#events[name] = [];
29
+ }
30
+
31
+ this.#events[name].push(listener);
32
+ }
33
+
34
+ /** .
35
+ * .
36
+ * .
37
+ * Function to remove a listener that was previously set
38
+ *
39
+ * @param {*} name
40
+ * @param {*} listenerToRemove
41
+ * @example
42
+ */
43
+ removeListener(name, listenerToRemove) {
44
+ if (!this.#events[name]) {
45
+ throw new Error(`Can't remove a listener. Event "${name}" doesn't exits.`);
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param listener
51
+ * @example
52
+ */
53
+ const filterListeners = listener => listener !== listenerToRemove;
54
+
55
+ this.#events[name] = this.#events[name].filter(filterListeners);
56
+ }
57
+
58
+ /**
59
+ * The internal API for this class. Gets called with an event name and a data object.
60
+ * Any callbacks that have been set to listen to the matching event are dispatched.
61
+ *
62
+ * @param name
63
+ * @param data
64
+ * @example
65
+ */
66
+ emit(name, data) {
67
+ if (!this.#events[name]) {
68
+ throw new Error(`Can't emit an event. Event "${name}" doesn't exits.`);
69
+ }
70
+
71
+ /**
72
+ *
73
+ * @param {*} callback
74
+ */
75
+ const fireCallbacks = callback => {
76
+ callback(data);
77
+ };
78
+
79
+ this.#events[name].forEach(fireCallbacks);
80
+ }
81
+ }
82
+
83
+ export default MyEventEmitter;
@@ -1,183 +1,148 @@
1
- import Peer from 'peerjs';
2
-
3
- // TODO: this was already here before, but appears to be unused
4
- const pressFeedbackURI =
5
- 'data:audio/mpeg;base64,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VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//uSZIIP9BFGHYksMlIAAA0gAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==';
6
-
7
- /**
8
- * @typedef initParameters - Parameters for initializing the AudioPeer
9
- * @type {object}
10
- * @property {string} targetElementId - Target element where new elements will be appended.
11
- * @property {string} siteUrl: The url of the current site.
12
- */
13
- const initParameters = {
14
- targetElementId: null,
15
- siteUrl: null,
16
- };
17
-
18
- /**
19
- * @class The first layer of abstraction on the PeerJS library.
20
- * It meant to be extended by the two seperate client classes, Speaker and Listener.
21
- * It implements the shared methods and properties of both classes.
22
- */
23
- class AudioPeer {
24
- /**
25
- * Creates an instance of AudioPeer
26
- * Takes the url of the current site and a target element where html elements will be appended.
27
- *
28
- * @param params - See type definition for initParameters.
29
- * @param param
30
- * @example
31
- */
32
- constructor(param = initParameters) {
33
- // PeerJS
34
- /* Create the Peer object for our end of the connection. */
35
- this.peer = new Peer({
36
- secure: true,
37
- host: 'easyeyes-peer-server.herokuapp.com',
38
- port: 443,
39
- config: {
40
- iceServers: [
41
- {
42
- urls: 'stun:stun.relay.metered.ca:80',
43
- },
44
- {
45
- urls: 'turn:global.relay.metered.ca:80',
46
- username: 'de884cfc34189cdf1a5dd616',
47
- credential: 'IcOpouU9/TYBmpHU',
48
- },
49
- {
50
- urls: 'turn:global.relay.metered.ca:80?transport=tcp',
51
- username: 'de884cfc34189cdf1a5dd616',
52
- credential: 'IcOpouU9/TYBmpHU',
53
- },
54
- {
55
- urls: 'turn:global.relay.metered.ca:443',
56
- username: 'de884cfc34189cdf1a5dd616',
57
- credential: 'IcOpouU9/TYBmpHU',
58
- },
59
- {
60
- urls: 'turns:global.relay.metered.ca:443?transport=tcp',
61
- username: 'de884cfc34189cdf1a5dd616',
62
- credential: 'IcOpouU9/TYBmpHU',
63
- },
64
- ],
65
- },
66
- });
67
- this.conn = null;
68
- this.lastPeerId = null;
69
-
70
- // Display information to HTML elem with given id
71
- this.targetElement = param.targetElementId;
72
-
73
- this.siteUrl = param.siteUrl;
74
- this.debug = false;
75
- // Store for all incoming data
76
- this.dataStore = [];
77
-
78
- // Create and play sounds using this audio context
79
- this.sourceAudioContext = new (window.AudioContext ||
80
- window.webkitAudioContext ||
81
- window.audioContext)();
82
- }
83
-
84
- /** .
85
- * .
86
- * .
87
- * Helper method to display information to DOM element
88
- *
89
- * @param {string} message
90
- * @param {boolean} append
91
- * @example
92
- */
93
- displayUpdate = (message, append = true) => {
94
- // If the specified elem exists, update that elem
95
- if (document.getElementById(this.targetElement)) {
96
- const displayElement = document.getElementById(this.targetElement);
97
- if (append) {
98
- displayElement.innerText += `\n${message}`;
99
- } else {
100
- displayElement.innerText = message;
101
- }
102
- } else {
103
- console.log('MESSAGE: ', message);
104
- }
105
- };
106
-
107
- /**
108
- * Callback method for when a peer connection is lost
109
- * saves the last peer id, last server id, and attempts to reconnect.
110
- *
111
- * @example
112
- */
113
- onPeerDisconnected = () => {
114
- this.displayUpdate('Connection lost. Please reconnect');
115
-
116
- // Workaround for peer.reconnect deleting previous id
117
- try {
118
- this.peer.id = this.lastPeerId;
119
- // eslint-disable-next-line no-underscore-dangle
120
- this.peer._lastServerId = this.lastPeerId;
121
- this.peer.reconnect();
122
- } catch(e) {
123
- console.log(e);
124
- }
125
-
126
- };
127
-
128
- /** .
129
- * .
130
- * .
131
- * Callback method that cleans up after peer connection is closed
132
- *
133
- * @example
134
- */
135
- onPeerClose = () => {
136
- this.displayUpdate('Connection closed');
137
- this.conn = null;
138
- };
139
-
140
- /** .
141
- * .
142
- * .
143
- * Helper method for when an error occurs
144
- *
145
- * @param {*} err
146
- * @example
147
- */
148
- onPeerError = err => {
149
- this.displayUpdate(err);
150
- console.log(`${err}`);
151
- };
152
-
153
- /** .
154
- * .
155
- * .
156
- * Helper method that converts url paramters to an object
157
- *
158
- * @returns {object}
159
- * @example
160
- */
161
- parseURLSearchParams = () =>
162
- // SOURCE: chickens, https://stackoverflow.com/questions/8648892/how-to-convert-url-parameters-to-a-javascript-object
163
- // eslint-disable-next-line no-restricted-globals
164
- Object.fromEntries(new URLSearchParams(location.search));
165
-
166
- /** .
167
- * .
168
- * .
169
- * Helper method that converts an object to a query string
170
- *
171
- * @param {object} params
172
- * @returns {string}
173
- * @example
174
- */
175
- queryStringFromObject = params =>
176
- Object.keys(params)
177
- .map(key => `${key}=${params[key]}`)
178
- .join('&');
179
-
180
- static keypressFeedbackSound = pressFeedbackURI;
181
- }
182
-
183
- export default AudioPeer;
1
+ import Peer from 'peerjs';
2
+
3
+ // TODO: this was already here before, but appears to be unused
4
+ const pressFeedbackURI =
5
+ 'data:audio/mpeg;base64,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VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//uSZIIP9BFGHYksMlIAAA0gAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==';
6
+
7
+ /**
8
+ * @typedef initParameters - Parameters for initializing the AudioPeer
9
+ * @type {object}
10
+ * @property {string} targetElementId - Target element where new elements will be appended.
11
+ * @property {string} siteUrl: The url of the current site.
12
+ */
13
+ const initParameters = {
14
+ targetElementId: null,
15
+ siteUrl: null,
16
+ };
17
+
18
+ /**
19
+ * @class The first layer of abstraction on the PeerJS library.
20
+ * It meant to be extended by the two seperate client classes, Speaker and Listener.
21
+ * It implements the shared methods and properties of both classes.
22
+ */
23
+ class AudioPeer {
24
+ /**
25
+ * Creates an instance of AudioPeer
26
+ * Takes the url of the current site and a target element where html elements will be appended.
27
+ *
28
+ * @param params - See type definition for initParameters.
29
+ * @param param
30
+ * @example
31
+ */
32
+ constructor(param = initParameters) {
33
+ this.conn = null;
34
+ this.lastPeerId = null;
35
+
36
+ // Display information to HTML elem with given id
37
+ this.targetElement = param.targetElementId;
38
+
39
+ this.siteUrl = param.siteUrl;
40
+ this.debug = false;
41
+ // Store for all incoming data
42
+ this.dataStore = [];
43
+
44
+ // Create and play sounds using this audio context
45
+ this.sourceAudioContext = new (window.AudioContext ||
46
+ window.webkitAudioContext ||
47
+ window.audioContext)();
48
+ }
49
+
50
+ /** .
51
+ * .
52
+ * .
53
+ * Helper method to display information to DOM element
54
+ *
55
+ * @param {string} message
56
+ * @param {boolean} append
57
+ * @example
58
+ */
59
+ displayUpdate = (message, append = true) => {
60
+ // If the specified elem exists, update that elem
61
+ if (document.getElementById(this.targetElement)) {
62
+ const displayElement = document.getElementById(this.targetElement);
63
+ if (append) {
64
+ displayElement.innerText += `\n${message}`;
65
+ } else {
66
+ displayElement.innerText = message;
67
+ }
68
+ } else {
69
+ console.log('MESSAGE: ', message);
70
+ }
71
+ };
72
+
73
+ /**
74
+ * Callback method for when a peer connection is lost
75
+ * saves the last peer id, last server id, and attempts to reconnect.
76
+ *
77
+ * @example
78
+ */
79
+ onPeerDisconnected = () => {
80
+ this.displayUpdate('Connection lost. Please reconnect');
81
+
82
+ // Workaround for peer.reconnect deleting previous id
83
+ try {
84
+ this.peer.id = this.lastPeerId;
85
+ // eslint-disable-next-line no-underscore-dangle
86
+ this.peer._lastServerId = this.lastPeerId;
87
+ this.peer.reconnect();
88
+ } catch (e) {
89
+ console.log(e);
90
+ }
91
+ };
92
+
93
+ /** .
94
+ * .
95
+ * .
96
+ * Callback method that cleans up after peer connection is closed
97
+ *
98
+ * @example
99
+ */
100
+ onPeerClose = () => {
101
+ this.displayUpdate('Connection closed');
102
+ this.conn = null;
103
+ };
104
+
105
+ /** .
106
+ * .
107
+ * .
108
+ * Helper method for when an error occurs
109
+ *
110
+ * @param {*} err
111
+ * @example
112
+ */
113
+ onPeerError = err => {
114
+ this.displayUpdate(err);
115
+ console.log(`${err}`);
116
+ };
117
+
118
+ /** .
119
+ * .
120
+ * .
121
+ * Helper method that converts url paramters to an object
122
+ *
123
+ * @returns {object}
124
+ * @example
125
+ */
126
+ parseURLSearchParams = () =>
127
+ // SOURCE: chickens, https://stackoverflow.com/questions/8648892/how-to-convert-url-parameters-to-a-javascript-object
128
+ // eslint-disable-next-line no-restricted-globals
129
+ Object.fromEntries(new URLSearchParams(location.search));
130
+
131
+ /** .
132
+ * .
133
+ * .
134
+ * Helper method that converts an object to a query string
135
+ *
136
+ * @param {object} params
137
+ * @returns {string}
138
+ * @example
139
+ */
140
+ queryStringFromObject = params =>
141
+ Object.keys(params)
142
+ .map(key => `${key}=${params[key]}`)
143
+ .join('&');
144
+
145
+ static keypressFeedbackSound = pressFeedbackURI;
146
+ }
147
+
148
+ export default AudioPeer;