speaker-calibration 2.2.93 → 2.2.95

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 (119) hide show
  1. package/.eslintignore +71 -71
  2. package/.eslintrc.json +40 -40
  3. package/.prettierignore +69 -69
  4. package/.prettierrc +14 -14
  5. package/LICENSE +20 -20
  6. package/README.md +133 -133
  7. package/__mocks__/fileMock.js +1 -1
  8. package/__mocks__/styleMock.js +1 -1
  9. package/babel.config.js +3 -3
  10. package/coverage/clover.xml +71 -71
  11. package/coverage/coverage-final.json +224 -224
  12. package/coverage/lcov-report/PythonServerInterface.js.html +265 -265
  13. package/coverage/lcov-report/base.css +354 -354
  14. package/coverage/lcov-report/block-navigation.js +82 -82
  15. package/coverage/lcov-report/index.html +123 -123
  16. package/coverage/lcov-report/prettify.css +101 -101
  17. package/coverage/lcov-report/prettify.js +937 -937
  18. package/coverage/lcov-report/sorter.js +189 -189
  19. package/coverage/lcov-report/src/index.html +121 -121
  20. package/coverage/lcov-report/src/server/PythonServerInterface.js.html +268 -268
  21. package/coverage/lcov-report/src/server/index.html +123 -123
  22. package/coverage/lcov-report/src/tasks/audioCalibrator.js.html +499 -499
  23. package/coverage/lcov-report/src/tasks/audioRecorder.js.html +412 -412
  24. package/coverage/lcov-report/src/tasks/index.html +143 -143
  25. package/coverage/lcov-report/src/tasks/volume/index.html +123 -123
  26. package/coverage/lcov-report/src/tasks/volume/volume.js.html +409 -409
  27. package/coverage/lcov-report/src/utils.js.html +172 -172
  28. package/coverage/lcov.info +91 -91
  29. package/dist/example/fetch-languages-sheets.js +77 -77
  30. package/dist/example/i18n.js +35846 -35846
  31. package/dist/example/index.html +47 -47
  32. package/dist/example/listener.html +62 -62
  33. package/dist/example/listener.js +95 -95
  34. package/dist/example/server.js +51 -51
  35. package/dist/example/speaker.html +145 -145
  36. package/dist/example/speakerUI.js +273 -273
  37. package/dist/example/styles.css +92 -92
  38. package/dist/main.js +17 -17
  39. package/dist/mlsGen.js +6814 -6814
  40. package/dist/mlsGen.wasm +0 -0
  41. package/dist/package-lock.json +1018 -1018
  42. package/dist/package.json +18 -18
  43. package/doc/AudioCalibrator.html +417 -417
  44. package/doc/AudioPeer.html +251 -251
  45. package/doc/AudioRecorder.html +195 -195
  46. package/doc/ImpulseResponse.html +215 -215
  47. package/doc/Listener.html +308 -308
  48. package/doc/MlsGenInterface.html +226 -226
  49. package/doc/MyEventEmitter.html +274 -274
  50. package/doc/PythonServerAPI.html +109 -109
  51. package/doc/Speaker.html +276 -276
  52. package/doc/Takes%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +128 -128
  53. package/doc/Takes%20the%20url%20of%20the%20current%20site%0Aand%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +138 -138
  54. package/doc/Takes%20the%20url%20of%20the%20current%20site%20and%20a%20target%20element%20where%20html%20elements%20will%20be%20appended..html +137 -137
  55. package/doc/Volume.html +88 -88
  56. package/doc/audioCalibrator.js.html +179 -179
  57. package/doc/audioPeer.js.html +175 -175
  58. package/doc/audioRecorder.js.html +163 -163
  59. package/doc/creates%20a%20new%20AudioRecorder%20instance.%20%0ASets%20up%20the%20audio%20context%20and%20file%20reader..html +114 -114
  60. package/doc/fonts/OpenSans-Bold-webfont.svg +1829 -1829
  61. package/doc/fonts/OpenSans-BoldItalic-webfont.svg +1829 -1829
  62. package/doc/fonts/OpenSans-Italic-webfont.svg +1829 -1829
  63. package/doc/fonts/OpenSans-Light-webfont.svg +1830 -1830
  64. package/doc/fonts/OpenSans-LightItalic-webfont.svg +1834 -1834
  65. package/doc/fonts/OpenSans-Regular-webfont.svg +1830 -1830
  66. package/doc/global.html +308 -308
  67. package/doc/index.html +58 -58
  68. package/doc/listener.js.html +170 -170
  69. package/doc/mlsGen_mlsGenInterface.js.html +117 -117
  70. package/doc/myEventEmitter.js.html +124 -124
  71. package/doc/peer-connection_audioPeer.js.html +188 -188
  72. package/doc/peer-connection_listener.js.html +311 -311
  73. package/doc/peer-connection_speaker.js.html +381 -381
  74. package/doc/scripts/linenumber.js +25 -25
  75. package/doc/scripts/prettify/Apache-License-2.0.txt +202 -202
  76. package/doc/scripts/prettify/lang-css.js +24 -24
  77. package/doc/scripts/prettify/prettify.js +640 -640
  78. package/doc/server_PythonServerAPI.js.html +160 -160
  79. package/doc/speaker.js.html +248 -248
  80. package/doc/styles/jsdoc-default.css +371 -371
  81. package/doc/styles/prettify-jsdoc.css +111 -111
  82. package/doc/styles/prettify-tomorrow.css +163 -163
  83. package/doc/tasks_audioCalibrator.js.html +207 -207
  84. package/doc/tasks_audioRecorder.js.html +190 -190
  85. package/doc/tasks_impulse-response_impulseResponse.js.html +442 -442
  86. package/doc/tasks_impulse-response_mlsGen_mlsGenInterface.js.html +175 -175
  87. package/doc/tasks_volume_volume.js.html +185 -185
  88. package/doc/utils.js.html +105 -105
  89. package/jest.config.js +173 -173
  90. package/makefile +74 -0
  91. package/netlify.toml +26 -26
  92. package/package.json +69 -69
  93. package/src/config/firebase.js +26 -26
  94. package/src/index.html +21 -21
  95. package/src/main.js +23 -23
  96. package/src/myEventEmitter.js +83 -83
  97. package/src/peer-connection/audioPeer.js +151 -151
  98. package/src/peer-connection/listener.js +318 -318
  99. package/src/peer-connection/peerErrors.js +25 -25
  100. package/src/peer-connection/speaker.js +464 -458
  101. package/src/server/PythonServerAPI.js +636 -636
  102. package/src/tasks/audioCalibrator.js +308 -308
  103. package/src/tasks/audioRecorder.js +301 -301
  104. package/src/tasks/combination/combination.js +2251 -2242
  105. package/src/tasks/combination/mlsGen/mlsGen.cpp +98 -98
  106. package/src/tasks/combination/mlsGen/mlsGen.hpp +303 -303
  107. package/src/tasks/combination/mlsGen/mlsGenInterface.js +131 -131
  108. package/src/tasks/combination/mlsGen/mlsGenTest.cpp +180 -180
  109. package/src/tasks/impulse-response/impulseResponse.js +610 -610
  110. package/src/tasks/impulse-response/mlsGen/mlsGen.cpp +98 -98
  111. package/src/tasks/impulse-response/mlsGen/mlsGen.hpp +303 -303
  112. package/src/tasks/impulse-response/mlsGen/mlsGenInterface.js +131 -131
  113. package/src/tasks/impulse-response/mlsGen/mlsGenTest.cpp +180 -180
  114. package/src/tasks/volume/volume.cpp +2 -2
  115. package/src/tasks/volume/volume.hpp +22 -22
  116. package/src/tasks/volume/volume.js +279 -279
  117. package/src/utils.js +88 -88
  118. package/webpack.config.js +37 -37
  119. package/.gitignore +0 -81
@@ -1,26 +1,26 @@
1
- // Import the functions you need from the SDKs you need
2
- import {initializeApp} from 'firebase/app';
3
- import {getDatabase} from 'firebase/database';
4
- import {getFirestore} from 'firebase/firestore';
5
- // TODO: Add SDKs for Firebase products that you want to use
6
- // https://firebase.google.com/docs/web/setup#available-libraries
7
-
8
- // Your web app's Firebase configuration
9
- // For Firebase JS SDK v7.20.0 and later, measurementId is optional
10
- const firebaseConfig = {
11
- apiKey: 'AIzaSyDZopCl6jqND4sFYCSiB1GpCXreXd6-Q9s',
12
- authDomain: 'speaker-calibration.firebaseapp.com',
13
- databaseURL: 'https://speaker-calibration-default-rtdb.firebaseio.com',
14
- projectId: 'speaker-calibration',
15
- storageBucket: 'speaker-calibration.appspot.com',
16
- messagingSenderId: '322038930574',
17
- appId: '1:322038930574:web:d10ca9e7d60b6da9bafddf',
18
- measurementId: 'G-3724GD92R6',
19
- };
20
-
21
- // Initialize Firebase
22
- const app = initializeApp(firebaseConfig);
23
- // const database = getDatabase();
24
- const database = getFirestore(app);
25
-
26
- export default database;
1
+ // Import the functions you need from the SDKs you need
2
+ import {initializeApp} from 'firebase/app';
3
+ import {getDatabase} from 'firebase/database';
4
+ import {getFirestore} from 'firebase/firestore';
5
+ // TODO: Add SDKs for Firebase products that you want to use
6
+ // https://firebase.google.com/docs/web/setup#available-libraries
7
+
8
+ // Your web app's Firebase configuration
9
+ // For Firebase JS SDK v7.20.0 and later, measurementId is optional
10
+ const firebaseConfig = {
11
+ apiKey: 'AIzaSyDZopCl6jqND4sFYCSiB1GpCXreXd6-Q9s',
12
+ authDomain: 'speaker-calibration.firebaseapp.com',
13
+ databaseURL: 'https://speaker-calibration-default-rtdb.firebaseio.com',
14
+ projectId: 'speaker-calibration',
15
+ storageBucket: 'speaker-calibration.appspot.com',
16
+ messagingSenderId: '322038930574',
17
+ appId: '1:322038930574:web:d10ca9e7d60b6da9bafddf',
18
+ measurementId: 'G-3724GD92R6',
19
+ };
20
+
21
+ // Initialize Firebase
22
+ const app = initializeApp(firebaseConfig);
23
+ // const database = getDatabase();
24
+ const database = getFirestore(app);
25
+
26
+ export default database;
package/src/index.html CHANGED
@@ -1,21 +1,21 @@
1
- <!DOCTYPE html>
2
- <html class="no-js" lang="">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta http-equiv="x-ua-compatible" content="ie=edge" />
6
- <title>Sound Check</title>
7
- <meta name="description" content="" />
8
- <meta name="viewport" content="width=device-width, initial-scale=1" />
9
-
10
- <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
11
- <!-- Place favicon.ico in the root directory -->
12
- </head>
13
- <body>
14
- <!--[if lt IE 8]>
15
- <p class="browserupgrade">
16
- You are using an <strong>outdated</strong> browser. Please
17
- <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.
18
- </p>
19
- <![endif]-->
20
- </body>
21
- </html>
1
+ <!DOCTYPE html>
2
+ <html class="no-js" lang="">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta http-equiv="x-ua-compatible" content="ie=edge" />
6
+ <title>Sound Check</title>
7
+ <meta name="description" content="" />
8
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
9
+
10
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
11
+ <!-- Place favicon.ico in the root directory -->
12
+ </head>
13
+ <body>
14
+ <!--[if lt IE 8]>
15
+ <p class="browserupgrade">
16
+ You are using an <strong>outdated</strong> browser. Please
17
+ <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.
18
+ </p>
19
+ <![endif]-->
20
+ </body>
21
+ </html>
package/src/main.js CHANGED
@@ -1,23 +1,23 @@
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
- Listener,
16
- Speaker,
17
- VolumeCalibration,
18
- ImpulseResponseCalibration,
19
- UnsupportedDeviceError,
20
- MissingSpeakerIdError,
21
- CalibrationTimedOutError,
22
- CombinationCalibration,
23
- };
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
+ Listener,
16
+ Speaker,
17
+ VolumeCalibration,
18
+ ImpulseResponseCalibration,
19
+ UnsupportedDeviceError,
20
+ MissingSpeakerIdError,
21
+ CalibrationTimedOutError,
22
+ CombinationCalibration,
23
+ };
@@ -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,151 +1,151 @@
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
- });
40
- this.conn = null;
41
- this.lastPeerId = null;
42
-
43
- // Display information to HTML elem with given id
44
- this.targetElement = param.targetElementId;
45
-
46
- this.siteUrl = param.siteUrl;
47
- this.debug = false;
48
- // Store for all incoming data
49
- this.dataStore = [];
50
-
51
- // Create and play sounds using this audio context
52
- this.sourceAudioContext = new (window.AudioContext ||
53
- window.webkitAudioContext ||
54
- window.audioContext)();
55
- }
56
-
57
- /** .
58
- * .
59
- * .
60
- * Helper method to display information to DOM element
61
- *
62
- * @param {string} message
63
- * @param {boolean} append
64
- * @example
65
- */
66
- displayUpdate = (message, append = true) => {
67
- // If the specified elem exists, update that elem
68
- if (document.getElementById(this.targetElement)) {
69
- const displayElement = document.getElementById(this.targetElement);
70
- if (append) {
71
- displayElement.innerText += `\n${message}`;
72
- } else {
73
- displayElement.innerText = message;
74
- }
75
- } else {
76
- console.log('MESSAGE: ', message);
77
- }
78
- };
79
-
80
- /**
81
- * Callback method for when a peer connection is lost
82
- * saves the last peer id, last server id, and attempts to reconnect.
83
- *
84
- * @example
85
- */
86
- onPeerDisconnected = () => {
87
- this.displayUpdate('Connection lost. Please reconnect');
88
-
89
- // Workaround for peer.reconnect deleting previous id
90
- this.peer.id = this.lastPeerId;
91
- // eslint-disable-next-line no-underscore-dangle
92
- this.peer._lastServerId = this.lastPeerId;
93
- this.peer.reconnect();
94
- };
95
-
96
- /** .
97
- * .
98
- * .
99
- * Callback method that cleans up after peer connection is closed
100
- *
101
- * @example
102
- */
103
- onPeerClose = () => {
104
- this.displayUpdate('Connection closed');
105
- this.conn = null;
106
- };
107
-
108
- /** .
109
- * .
110
- * .
111
- * Helper method for when an error occurs
112
- *
113
- * @param {*} err
114
- * @example
115
- */
116
- onPeerError = err => {
117
- this.displayUpdate(err);
118
- console.log(`${err}`);
119
- };
120
-
121
- /** .
122
- * .
123
- * .
124
- * Helper method that converts url paramters to an object
125
- *
126
- * @returns {object}
127
- * @example
128
- */
129
- parseURLSearchParams = () =>
130
- // SOURCE: chickens, https://stackoverflow.com/questions/8648892/how-to-convert-url-parameters-to-a-javascript-object
131
- // eslint-disable-next-line no-restricted-globals
132
- Object.fromEntries(new URLSearchParams(location.search));
133
-
134
- /** .
135
- * .
136
- * .
137
- * Helper method that converts an object to a query string
138
- *
139
- * @param {object} params
140
- * @returns {string}
141
- * @example
142
- */
143
- queryStringFromObject = params =>
144
- Object.keys(params)
145
- .map(key => `${key}=${params[key]}`)
146
- .join('&');
147
-
148
- static keypressFeedbackSound = pressFeedbackURI;
149
- }
150
-
151
- 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
+ // 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
+ });
40
+ this.conn = null;
41
+ this.lastPeerId = null;
42
+
43
+ // Display information to HTML elem with given id
44
+ this.targetElement = param.targetElementId;
45
+
46
+ this.siteUrl = param.siteUrl;
47
+ this.debug = false;
48
+ // Store for all incoming data
49
+ this.dataStore = [];
50
+
51
+ // Create and play sounds using this audio context
52
+ this.sourceAudioContext = new (window.AudioContext ||
53
+ window.webkitAudioContext ||
54
+ window.audioContext)();
55
+ }
56
+
57
+ /** .
58
+ * .
59
+ * .
60
+ * Helper method to display information to DOM element
61
+ *
62
+ * @param {string} message
63
+ * @param {boolean} append
64
+ * @example
65
+ */
66
+ displayUpdate = (message, append = true) => {
67
+ // If the specified elem exists, update that elem
68
+ if (document.getElementById(this.targetElement)) {
69
+ const displayElement = document.getElementById(this.targetElement);
70
+ if (append) {
71
+ displayElement.innerText += `\n${message}`;
72
+ } else {
73
+ displayElement.innerText = message;
74
+ }
75
+ } else {
76
+ console.log('MESSAGE: ', message);
77
+ }
78
+ };
79
+
80
+ /**
81
+ * Callback method for when a peer connection is lost
82
+ * saves the last peer id, last server id, and attempts to reconnect.
83
+ *
84
+ * @example
85
+ */
86
+ onPeerDisconnected = () => {
87
+ this.displayUpdate('Connection lost. Please reconnect');
88
+
89
+ // Workaround for peer.reconnect deleting previous id
90
+ this.peer.id = this.lastPeerId;
91
+ // eslint-disable-next-line no-underscore-dangle
92
+ this.peer._lastServerId = this.lastPeerId;
93
+ this.peer.reconnect();
94
+ };
95
+
96
+ /** .
97
+ * .
98
+ * .
99
+ * Callback method that cleans up after peer connection is closed
100
+ *
101
+ * @example
102
+ */
103
+ onPeerClose = () => {
104
+ this.displayUpdate('Connection closed');
105
+ this.conn = null;
106
+ };
107
+
108
+ /** .
109
+ * .
110
+ * .
111
+ * Helper method for when an error occurs
112
+ *
113
+ * @param {*} err
114
+ * @example
115
+ */
116
+ onPeerError = err => {
117
+ this.displayUpdate(err);
118
+ console.log(`${err}`);
119
+ };
120
+
121
+ /** .
122
+ * .
123
+ * .
124
+ * Helper method that converts url paramters to an object
125
+ *
126
+ * @returns {object}
127
+ * @example
128
+ */
129
+ parseURLSearchParams = () =>
130
+ // SOURCE: chickens, https://stackoverflow.com/questions/8648892/how-to-convert-url-parameters-to-a-javascript-object
131
+ // eslint-disable-next-line no-restricted-globals
132
+ Object.fromEntries(new URLSearchParams(location.search));
133
+
134
+ /** .
135
+ * .
136
+ * .
137
+ * Helper method that converts an object to a query string
138
+ *
139
+ * @param {object} params
140
+ * @returns {string}
141
+ * @example
142
+ */
143
+ queryStringFromObject = params =>
144
+ Object.keys(params)
145
+ .map(key => `${key}=${params[key]}`)
146
+ .join('&');
147
+
148
+ static keypressFeedbackSound = pressFeedbackURI;
149
+ }
150
+
151
+ export default AudioPeer;