speaker-calibration 2.2.183 → 2.2.185
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.
- package/dist/example/i18n.js +1112 -1108
- package/dist/main.js +1 -1
- package/package.json +1 -1
- package/src/peer-connection/speaker.js +80 -91
package/package.json
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import QRCode from 'qrcode';
|
|
2
2
|
import AudioPeer from './audioPeer';
|
|
3
|
-
import {
|
|
4
|
-
sleep,
|
|
5
|
-
formatLineBreak,
|
|
6
|
-
createAndShowPopup
|
|
7
|
-
} from '../utils';
|
|
3
|
+
import {sleep, formatLineBreak, createAndShowPopup} from '../utils';
|
|
8
4
|
import {
|
|
9
5
|
UnsupportedDeviceError,
|
|
10
6
|
MissingSpeakerIdError,
|
|
@@ -54,7 +50,6 @@ class Speaker extends AudioPeer {
|
|
|
54
50
|
qrImage;
|
|
55
51
|
shortURL;
|
|
56
52
|
|
|
57
|
-
|
|
58
53
|
initPeer = async () => {
|
|
59
54
|
const id = await this.generateTimeBasedPeerID();
|
|
60
55
|
this.peer = new Peer(id, {
|
|
@@ -64,27 +59,27 @@ class Speaker extends AudioPeer {
|
|
|
64
59
|
config: {
|
|
65
60
|
iceServers: [
|
|
66
61
|
{
|
|
67
|
-
urls:
|
|
62
|
+
urls: 'stun:stun.relay.metered.ca:80',
|
|
68
63
|
},
|
|
69
64
|
{
|
|
70
|
-
urls:
|
|
71
|
-
username:
|
|
72
|
-
credential:
|
|
65
|
+
urls: 'turn:global.relay.metered.ca:80',
|
|
66
|
+
username: 'de884cfc34189cdf1a5dd616',
|
|
67
|
+
credential: 'IcOpouU9/TYBmpHU',
|
|
73
68
|
},
|
|
74
69
|
{
|
|
75
|
-
urls:
|
|
76
|
-
username:
|
|
77
|
-
credential:
|
|
70
|
+
urls: 'turn:global.relay.metered.ca:80?transport=tcp',
|
|
71
|
+
username: 'de884cfc34189cdf1a5dd616',
|
|
72
|
+
credential: 'IcOpouU9/TYBmpHU',
|
|
78
73
|
},
|
|
79
74
|
{
|
|
80
|
-
urls:
|
|
81
|
-
username:
|
|
82
|
-
credential:
|
|
75
|
+
urls: 'turn:global.relay.metered.ca:443',
|
|
76
|
+
username: 'de884cfc34189cdf1a5dd616',
|
|
77
|
+
credential: 'IcOpouU9/TYBmpHU',
|
|
83
78
|
},
|
|
84
79
|
{
|
|
85
|
-
urls:
|
|
86
|
-
username:
|
|
87
|
-
credential:
|
|
80
|
+
urls: 'turns:global.relay.metered.ca:443?transport=tcp',
|
|
81
|
+
username: 'de884cfc34189cdf1a5dd616',
|
|
82
|
+
credential: 'IcOpouU9/TYBmpHU',
|
|
88
83
|
},
|
|
89
84
|
],
|
|
90
85
|
},
|
|
@@ -94,31 +89,29 @@ class Speaker extends AudioPeer {
|
|
|
94
89
|
this.peer.on('close', this.onPeerClose);
|
|
95
90
|
this.peer.on('disconnected', this.#onPeerDisconnected);
|
|
96
91
|
this.peer.on('error', this.#onPeerError);
|
|
97
|
-
}
|
|
92
|
+
};
|
|
98
93
|
generateTimeBasedPeerID = async () => {
|
|
99
94
|
const now = new Date().getTime();
|
|
100
95
|
const randomBuffer = new Uint8Array(10);
|
|
101
96
|
crypto.getRandomValues(randomBuffer);
|
|
102
97
|
const randomPart = Array.from(randomBuffer)
|
|
103
|
-
.map(
|
|
104
|
-
.join(
|
|
98
|
+
.map(b => b.toString(36))
|
|
99
|
+
.join('');
|
|
105
100
|
const toHash = `${now}-${randomPart}`;
|
|
106
101
|
const encoder = new TextEncoder();
|
|
107
102
|
const data = encoder.encode(toHash);
|
|
108
|
-
const hash = await crypto.subtle.digest(
|
|
103
|
+
const hash = await crypto.subtle.digest('SHA-256', data);
|
|
109
104
|
const hashArray = Array.from(new Uint8Array(hash)); // Convert buffer to byte array
|
|
110
|
-
const hashString = hashArray
|
|
111
|
-
.map((b) => b.toString(16).padStart(2, "0"))
|
|
112
|
-
.join("");
|
|
105
|
+
const hashString = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
113
106
|
const shortHash = hashString.substring(0, 12); // Use more of the hash for a longer ID
|
|
114
107
|
// return shortHash; // Consider converting this to Base62
|
|
115
108
|
return this.encodeBase62(parseInt(shortHash, 16));
|
|
116
109
|
};
|
|
117
110
|
|
|
118
|
-
encodeBase62 =
|
|
111
|
+
encodeBase62 = num => {
|
|
119
112
|
const base = 36;
|
|
120
|
-
const characters =
|
|
121
|
-
let result =
|
|
113
|
+
const characters = '0123456789abcdefghijklmnopqrstuvwxyz';
|
|
114
|
+
let result = '';
|
|
122
115
|
while (num > 0) {
|
|
123
116
|
result = characters[num % base] + result;
|
|
124
117
|
num = Math.floor(num / base);
|
|
@@ -287,70 +280,66 @@ class Speaker extends AudioPeer {
|
|
|
287
280
|
const queryString = this.queryStringFromObject(queryStringParameters);
|
|
288
281
|
this.uri = this.siteUrl + queryString;
|
|
289
282
|
if (this.isSmartPhone) {
|
|
290
|
-
|
|
283
|
+
// if (true) { // test smartphone QR
|
|
291
284
|
// Display QR code for the participant to scan
|
|
292
285
|
const qrCanvas = document.createElement('canvas');
|
|
293
286
|
qrCanvas.setAttribute('id', 'qrCanvas');
|
|
294
287
|
QRCode.toCanvas(qrCanvas, this.uri, error => {
|
|
295
288
|
if (error) console.error(error);
|
|
296
289
|
});
|
|
297
|
-
const explanation = document.createElement(
|
|
298
|
-
explanation.id =
|
|
290
|
+
const explanation = document.createElement('h2');
|
|
291
|
+
explanation.id = 'skipQRExplanation';
|
|
299
292
|
explanation.style = `
|
|
300
293
|
user-select: text;
|
|
301
294
|
margin-top: 9px;
|
|
302
295
|
font-size: 1.1rem;
|
|
303
296
|
`;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
};
|
|
318
|
-
|
|
319
|
-
// Make the request using fetch
|
|
320
|
-
await fetch(url, options)
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
297
|
+
// Define the URL and options for the request
|
|
298
|
+
const url = 'https://api.short.io/links/public';
|
|
299
|
+
const options = {
|
|
300
|
+
method: 'POST',
|
|
301
|
+
headers: {
|
|
302
|
+
Accept: 'application/json',
|
|
303
|
+
'Content-Type': 'application/json',
|
|
304
|
+
Authorization: 'pk_fysLKGj3legZz4XZ',
|
|
305
|
+
},
|
|
306
|
+
body: JSON.stringify({
|
|
307
|
+
domain: 'listeners.link', // Ensure this domain is valid for your account
|
|
308
|
+
originalURL: this.uri,
|
|
309
|
+
}),
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// Make the request using fetch
|
|
313
|
+
await fetch(url, options)
|
|
314
|
+
.then(response => {
|
|
315
|
+
if (!response.ok) {
|
|
316
|
+
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
317
|
+
}
|
|
318
|
+
return response.json(); // Parse the JSON response
|
|
319
|
+
})
|
|
320
|
+
.then(data => {
|
|
321
|
+
explanation.innerHTML = formatLineBreak(
|
|
322
|
+
phrases.RC_skipQR_ExplanationWithoutPreferNot[this.language]
|
|
323
|
+
.replace('xxx', `<b style="user-select: text">${data.shortURL}</b>`)
|
|
324
|
+
.replace('XXX', `<b style="user-select: text">${data.shortURL}</b>`),
|
|
325
|
+
phrases.RC_checkInternetConnection[this.language]
|
|
326
|
+
);
|
|
327
|
+
const checkConnection = document.createElement('a');
|
|
328
|
+
checkConnection.id = 'check-connection';
|
|
329
|
+
checkConnection.href = '#';
|
|
330
|
+
checkConnection.innerHTML = "check the phone's internet connection";
|
|
331
|
+
const lang = this.language;
|
|
332
|
+
checkConnection.addEventListener('click', function (event) {
|
|
333
|
+
console.log('clicked');
|
|
334
|
+
event.preventDefault(); // Prevent the default link action
|
|
335
|
+
createAndShowPopup(lang);
|
|
336
|
+
});
|
|
337
|
+
explanation.querySelector('a#check-connection').replaceWith(checkConnection);
|
|
338
|
+
})
|
|
339
|
+
.catch(error => {
|
|
340
|
+
console.error('Error:', error.message); // Handle errors
|
|
341
|
+
});
|
|
342
|
+
|
|
354
343
|
const qrImage = new Image(400, 400);
|
|
355
344
|
qrImage.setAttribute('id', 'compatibilityCheckQRImage');
|
|
356
345
|
qrImage.style.zIndex = Infinity;
|
|
@@ -363,17 +352,17 @@ await fetch(url, options)
|
|
|
363
352
|
|
|
364
353
|
this.qrImage = qrImage;
|
|
365
354
|
|
|
366
|
-
const container = document.createElement(
|
|
367
|
-
container.style.display =
|
|
368
|
-
container.style.justifyContent =
|
|
369
|
-
container.style.alignItems =
|
|
370
|
-
container.id =
|
|
355
|
+
const container = document.createElement('div');
|
|
356
|
+
container.style.display = 'flex';
|
|
357
|
+
container.style.justifyContent = 'space-between';
|
|
358
|
+
container.style.alignItems = 'top';
|
|
359
|
+
container.id = 'skipQRContainer';
|
|
371
360
|
container.appendChild(qrImage);
|
|
372
361
|
container.appendChild(explanation);
|
|
373
362
|
container.appendChild(this.buttonsContainer);
|
|
374
|
-
const qrContainer = document.createElement(
|
|
363
|
+
const qrContainer = document.createElement('div');
|
|
375
364
|
qrContainer.appendChild(container);
|
|
376
|
-
|
|
365
|
+
|
|
377
366
|
document.getElementById(this.targetElement).appendChild(qrContainer);
|
|
378
367
|
} else {
|
|
379
368
|
// show the link to the user
|
|
@@ -389,7 +378,7 @@ await fetch(url, options)
|
|
|
389
378
|
const proceedButton = document.createElement('button');
|
|
390
379
|
proceedButton.setAttribute('id', 'calibrationProceedButton');
|
|
391
380
|
proceedButton.setAttribute('class', 'btn btn-success');
|
|
392
|
-
proceedButton.innerHTML = phrases.
|
|
381
|
+
proceedButton.innerHTML = phrases.T_proceed[this.language];
|
|
393
382
|
proceedButton.onclick = () => {
|
|
394
383
|
// open the link in a new tab
|
|
395
384
|
window.open(this.uri, '_blank');
|
|
@@ -687,7 +676,7 @@ await fetch(url, options)
|
|
|
687
676
|
params.calibrateSoundHz,
|
|
688
677
|
params.calibrateSoundIRSec,
|
|
689
678
|
params.calibrateSoundIIRSec,
|
|
690
|
-
params.
|
|
679
|
+
params.calibrateSoundIIRPhase,
|
|
691
680
|
params.calibrateSound1000HzPreSec,
|
|
692
681
|
params.calibrateSound1000HzSec,
|
|
693
682
|
params.calibrateSound1000HzPostSec,
|