openvibers/openvibe.live Commits
Go Live says what viewers will get before the button (#512)
Changes
@@@ -2964,6 +2964,15 @@ body.bc-golive-dock-on #page-broadcast { padding-bottom: calc(104px + var(--ovnadisplay: flex; align-items: center; justify-content: center; gap: 10px; width: 100%;min-height: 52px; margin-top: 14px; padding: 12px 20px; border-radius: 14px; font-size: 1.02rem; font-weight: 700;}++/* What viewers will get, before the Go Live button (broadcast-workspace.js _wsPreflight). */++.bc-preflight { margin: 12px 0 12px; padding: 10px 12px; border: 1px dashed color-mix(in srgb, var(--accent) 45%, var(--border)); border-radius: 12px; background: color-mix(in srgb, var(--accent) 5%, transparent); }++.bc-preflight-h { margin: 0 0 6px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); }++.bc-preflight ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }++.bc-preflight li { display: flex; align-items: baseline; gap: 8px; font-size: 0.86rem; color: var(--text-secondary); min-width: 0; }++.bc-preflight li i { flex: 0 0 16px; text-align: center; color: var(--accent); }++.bc-preflight li span { min-width: 0; overflow-wrap: anywhere; }++.bc-preflight li b { color: var(--text-primary); font-weight: 650; }++.bc-preflight-note { margin: 8px 0 0; font-size: 0.76rem; line-height: 1.45; color: var(--text-muted); }.bc-ws-golive-section .bc-create-reassurance { margin: 10px 0 0 !important; text-align: center; font-size: 0.78rem !important; color: var(--text-muted); overflow-wrap: anywhere; }/* A wide panel keeps the setup and the button a readable width, centred under the two columns. */@container bcws (min-width: 960px) {@@@ -620,6 +620,8 @@ function _wsRenderPanel() {<select id="bc-screen-audio" style="display:none"><option value="default">Default</option></select><select id="bc-screen-camera" style="display:none"><option value="default">Default</option></select>++ ${_wsPreflight(browserMode)}++<button class="btn btn-primary btn-lg bc-ws-golive-btn"onclick="goLiveFromWorkspace()" id="bc-ws-golive-btn"><i class="fa-solid fa-tower-broadcast"></i> Go Live@@@ -1147,6 +1149,29 @@ function _wsPickHint(kind, id) {}/** The line over Allow …, before the browser may use the camera or microphone. */++/**++ * What viewers will get, said before the button (market outcome 6: a pre-flight summary of what will be captured; 5:++ * what can and cannot change once live, and the browsers). The device names are the setup card's own: each++ * [data-pick-for] here is kept current by _bcSyncPicks (broadcast-devices.js), like the card's rows.++ */++function _wsPreflight(mode) {++ const cam = '<b data-pick-for="bc-create-camera">Default</b>';++ const mic = '<b data-pick-for="bc-create-audio">Default</b>';++ const rows = mode === 'mic_only' ? [['fa-microphone', `Sound from ${mic}`], ['fa-eye-slash', 'No picture']]++ : mode === 'camera_only' ? [['fa-video', `Picture from ${cam}`], ['fa-volume-xmark', 'No sound']]++ : mode === 'screen' ? [['fa-display', 'Your screen, a window or a tab: your browser asks which when you press Go Live'], ['fa-microphone', 'Your microphone and camera bubble, as set above']]++ : [['fa-video', `Picture from ${cam}`], ['fa-microphone', `Sound from ${mic}`]];++ const can = mode === 'screen' ? 'While live you can mute the microphone. Switching to your camera means a new stream.'++ : mode === 'mic_only' ? 'While live you can mute the microphone. Adding a picture means a new stream.'++ : mode === 'camera_only' ? 'While live you can turn the camera off or switch cameras. Sharing your screen instead means a new stream.'++ : 'While live you can mute, turn the camera off or switch cameras. Sharing your screen instead means a new stream.';++ return `<div class="bc-preflight" role="group" aria-labelledby="bc-preflight-h">++ <p class="bc-preflight-h" id="bc-preflight-h">What viewers will get</p>++ <ul>${rows.map(([icon, text]) => `<li><i class="fa-solid ${icon}" aria-hidden="true"></i><span>${text}</span></li>`).join('')}</ul>++ <p class="bc-preflight-note">${can} Works in Chrome, Edge, Firefox and Safari.</p>++ </div>`;++}++function _wsPermHint(mode) {return mode === 'mic_only' ? 'Let your browser use the microphone to choose one.': mode === 'camera_only' ? 'Let your browser use the camera to choose one.'nnew file mode 100644@@@ -0,0 +1,27 @@++'use strict';++/**++ * The Go Live section says what viewers will get before the button (market outcomes 5 and 6; broadcast-workspace.js++ * _wsPreflight): the picture and sound by device name (the setup card's own [data-pick-for] labels, kept current by++ * _bcSyncPicks), what can change once live and what means a new stream, and the browsers it works in.++ */++const assert = require('assert');++const fs = require('fs');++const path = require('path');++++const src = fs.readFileSync(path.join(__dirname, '..', 'public', 'js', 'broadcast-workspace.js'), 'utf8');++const start = src.indexOf('function _wsPreflight(mode)');++const end = src.indexOf('\nfunction _wsPermHint', start);++assert.ok(start > 0 && end > start, 'the function is there');++const preflight = new Function(`${src.slice(start, end)}; return _wsPreflight;`)();++++const cam = preflight('camera');++assert.ok(cam.includes('Picture from <b data-pick-for="bc-create-camera">') && cam.includes('Sound from <b data-pick-for="bc-create-audio">'), 'camera: the chosen devices by name');++assert.ok(cam.includes('you can mute, turn the camera off or switch cameras') && cam.includes('Sharing your screen instead means a new stream'), 'what can change once live, and what cannot');++assert.ok(cam.includes('Works in Chrome, Edge, Firefox and Safari.'), 'the browsers');++assert.ok(preflight('screen').includes('your browser asks which when you press Go Live'), 'screen: what is captured is picked at the button');++assert.ok(preflight('mic_only').includes('No picture') && !preflight('mic_only').includes('bc-create-camera'), 'sound only');++assert.ok(preflight('camera_only').includes('No sound') && !preflight('camera_only').includes('bc-create-audio'), 'picture only');++assert.ok(src.includes('${_wsPreflight(browserMode)}'), 'it sits in the Go Live section');++const syncer = fs.readFileSync(path.join(__dirname, '..', 'public', 'js', 'broadcast-devices.js'), 'utf8');++assert.ok(syncer.includes("document.querySelectorAll('[data-pick-for]')"), 'and _bcSyncPicks keeps every [data-pick-for] current');++console.log('golive-preflight: what viewers will get, said before the button');
@@ -2964,6 +2964,15 @@ body.bc-golive-dock-on #page-broadcast { padding-bottom: calc(104px + var(--ovna
@@ -2964,6 +2964,15 @@ body.bc-golive-dock-on #page-broadcast { padding-bottom: calc(104px + var(--ovna
display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%;
display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%;
min-height: 52px; margin-top: 14px; padding: 12px 20px; border-radius: 14px; font-size: 1.02rem; font-weight: 700;
min-height: 52px; margin-top: 14px; padding: 12px 20px; border-radius: 14px; font-size: 1.02rem; font-weight: 700;
}
}
+/* What viewers will get, before the Go Live button (broadcast-workspace.js _wsPreflight). */
+.bc-preflight { margin: 12px 0 12px; padding: 10px 12px; border: 1px dashed color-mix(in srgb, var(--accent) 45%, var(--border)); border-radius: 12px; background: color-mix(in srgb, var(--accent) 5%, transparent); }
+.bc-preflight-h { margin: 0 0 6px; font-size: 0.72rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); }
+.bc-preflight ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
+.bc-preflight li { display: flex; align-items: baseline; gap: 8px; font-size: 0.86rem; color: var(--text-secondary); min-width: 0; }
+.bc-preflight li i { flex: 0 0 16px; text-align: center; color: var(--accent); }
+.bc-preflight li span { min-width: 0; overflow-wrap: anywhere; }
+.bc-preflight li b { color: var(--text-primary); font-weight: 650; }
+.bc-preflight-note { margin: 8px 0 0; font-size: 0.76rem; line-height: 1.45; color: var(--text-muted); }
.bc-ws-golive-section .bc-create-reassurance { margin: 10px 0 0 !important; text-align: center; font-size: 0.78rem !important; color: var(--text-muted); overflow-wrap: anywhere; }
.bc-ws-golive-section .bc-create-reassurance { margin: 10px 0 0 !important; text-align: center; font-size: 0.78rem !important; color: var(--text-muted); overflow-wrap: anywhere; }
/* A wide panel keeps the setup and the button a readable width, centred under the two columns. */
/* A wide panel keeps the setup and the button a readable width, centred under the two columns. */
@container bcws (min-width: 960px) {
@container bcws (min-width: 960px) {
@@ -620,6 +620,8 @@ function _wsRenderPanel() {
@@ -620,6 +620,8 @@ function _wsRenderPanel() {
<select id="bc-screen-audio" style="display:none"><option value="default">Default</option></select>
<select id="bc-screen-audio" style="display:none"><option value="default">Default</option></select>
<select id="bc-screen-camera" style="display:none"><option value="default">Default</option></select>
<select id="bc-screen-camera" style="display:none"><option value="default">Default</option></select>
+ ${_wsPreflight(browserMode)}
+
<button class="btn btn-primary btn-lg bc-ws-golive-btn"
<button class="btn btn-primary btn-lg bc-ws-golive-btn"
onclick="goLiveFromWorkspace()" id="bc-ws-golive-btn">
onclick="goLiveFromWorkspace()" id="bc-ws-golive-btn">
<i class="fa-solid fa-tower-broadcast"></i> Go Live
<i class="fa-solid fa-tower-broadcast"></i> Go Live
@@ -1147,6 +1149,29 @@ function _wsPickHint(kind, id) {
@@ -1147,6 +1149,29 @@ function _wsPickHint(kind, id) {
}
}
/** The line over Allow …, before the browser may use the camera or microphone. */
/** The line over Allow …, before the browser may use the camera or microphone. */
+/**
+ * What viewers will get, said before the button (market outcome 6: a pre-flight summary of what will be captured; 5:
+ * what can and cannot change once live, and the browsers). The device names are the setup card's own: each
+ * [data-pick-for] here is kept current by _bcSyncPicks (broadcast-devices.js), like the card's rows.
+ */
+function _wsPreflight(mode) {
+ const cam = '<b data-pick-for="bc-create-camera">Default</b>';
+ const mic = '<b data-pick-for="bc-create-audio">Default</b>';
+ const rows = mode === 'mic_only' ? [['fa-microphone', `Sound from ${mic}`], ['fa-eye-slash', 'No picture']]
+ : mode === 'camera_only' ? [['fa-video', `Picture from ${cam}`], ['fa-volume-xmark', 'No sound']]
+ : mode === 'screen' ? [['fa-display', 'Your screen, a window or a tab: your browser asks which when you press Go Live'], ['fa-microphone', 'Your microphone and camera bubble, as set above']]
+ : [['fa-video', `Picture from ${cam}`], ['fa-microphone', `Sound from ${mic}`]];
+ const can = mode === 'screen' ? 'While live you can mute the microphone. Switching to your camera means a new stream.'
+ : mode === 'mic_only' ? 'While live you can mute the microphone. Adding a picture means a new stream.'
+ : mode === 'camera_only' ? 'While live you can turn the camera off or switch cameras. Sharing your screen instead means a new stream.'
+ : 'While live you can mute, turn the camera off or switch cameras. Sharing your screen instead means a new stream.';
+ return `<div class="bc-preflight" role="group" aria-labelledby="bc-preflight-h">
+ <p class="bc-preflight-h" id="bc-preflight-h">What viewers will get</p>
+ <ul>${rows.map(([icon, text]) => `<li><i class="fa-solid ${icon}" aria-hidden="true"></i><span>${text}</span></li>`).join('')}</ul>
+ <p class="bc-preflight-note">${can} Works in Chrome, Edge, Firefox and Safari.</p>
+ </div>`;
+}
+
function _wsPermHint(mode) {
function _wsPermHint(mode) {
return mode === 'mic_only' ? 'Let your browser use the microphone to choose one.'
return mode === 'mic_only' ? 'Let your browser use the microphone to choose one.'
: mode === 'camera_only' ? 'Let your browser use the camera to choose one.'
: mode === 'camera_only' ? 'Let your browser use the camera to choose one.'
new file mode 100644
new file mode 100644
@@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
+'use strict';
+/**
+ * The Go Live section says what viewers will get before the button (market outcomes 5 and 6; broadcast-workspace.js
+ * _wsPreflight): the picture and sound by device name (the setup card's own [data-pick-for] labels, kept current by
+ * _bcSyncPicks), what can change once live and what means a new stream, and the browsers it works in.
+ */
+const assert = require('assert');
+const fs = require('fs');
+const path = require('path');
+
+const src = fs.readFileSync(path.join(__dirname, '..', 'public', 'js', 'broadcast-workspace.js'), 'utf8');
+const start = src.indexOf('function _wsPreflight(mode)');
+const end = src.indexOf('\nfunction _wsPermHint', start);
+assert.ok(start > 0 && end > start, 'the function is there');
+const preflight = new Function(`${src.slice(start, end)}; return _wsPreflight;`)();
+
+const cam = preflight('camera');
+assert.ok(cam.includes('Picture from <b data-pick-for="bc-create-camera">') && cam.includes('Sound from <b data-pick-for="bc-create-audio">'), 'camera: the chosen devices by name');
+assert.ok(cam.includes('you can mute, turn the camera off or switch cameras') && cam.includes('Sharing your screen instead means a new stream'), 'what can change once live, and what cannot');
+assert.ok(cam.includes('Works in Chrome, Edge, Firefox and Safari.'), 'the browsers');
+assert.ok(preflight('screen').includes('your browser asks which when you press Go Live'), 'screen: what is captured is picked at the button');
+assert.ok(preflight('mic_only').includes('No picture') && !preflight('mic_only').includes('bc-create-camera'), 'sound only');
+assert.ok(preflight('camera_only').includes('No sound') && !preflight('camera_only').includes('bc-create-audio'), 'picture only');
+assert.ok(src.includes('${_wsPreflight(browserMode)}'), 'it sits in the Go Live section');
+const syncer = fs.readFileSync(path.join(__dirname, '..', 'public', 'js', 'broadcast-devices.js'), 'utf8');
+assert.ok(syncer.includes("document.querySelectorAll('[data-pick-for]')"), 'and _bcSyncPicks keeps every [data-pick-for] current');
+console.log('golive-preflight: what viewers will get, said before the button');