Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 1x 2x 2x 3x 1x 1x 2x 2x 1x 1x 1x 1x 1x 1x 6x 1x 1x 4x 1x 3x 1x | // What a shared session shows and hears of the page it runs on: notices, the lights and pane, whether the page can
// be seen, and its going.
import { joinLink } from "./shared-session.js";
import { reloadAsMachine } from "./machine-switch.js";
import { watchPage } from "./session-log.js";
import { SessionPanel } from "./session-panel.js";
import { downloadBlob } from "./dom-utils.js";
import { toast } from "./toast.js";
const ToastTitle = "Shared session";
function notify(message) {
console.log(`Shared session: ${message}`);
toast(message, { title: ToastTitle });
}
async function copyJoinLink(room) {
if (!navigator.clipboard) {
notify(`Copying needs https. Guests join at ${joinLink(room)}`);
return;
}
try {
await navigator.clipboard.writeText(joinLink(room));
toast("The link to join is on the clipboard.", { title: ToastTitle });
} catch (error) {
notify(`Couldn't copy the link (${error.message}). Guests join at ${joinLink(room)}`);
}
}
function saveReport(session) {
const report = session.report();
const stamp = report.savedAt.replace(/[:.]/g, "-");
const blob = new Blob([JSON.stringify(report)], { type: "application/json" });
downloadBlob(blob, `jsbeeb-session-${report.role}-${stamp}.json`);
}
/**
* @typedef {object} SessionPage
* @property {function(string): void} notify tells this person something
* @property {function(): boolean} hidden whether the page is out of sight, as a hidden tab runs slowly
* @property {typeof watchPage} watch
* @property {function(function(): void, AbortSignal): void} onPageHide calls back as the page goes, until `signal`
* @property {function(string): string} joinLink the address a guest joins a room at
* @property {function(object): void} reloadAs reloads the page, in place, as the machine these parameters make
* @property {function(object, function(boolean): void=): SessionPanel} panel the lights and pane for a session, with
* the host's setter for whether a key press takes control
*/
/**
* @param {import("./url-state.js").UrlState} urlState
* @param {import("./floating-panel.js").PanelArrangement} arrangement what places the session's pane
* @returns {SessionPage}
*/
export function sessionPage(urlState, arrangement) {
return {
notify,
hidden: () => document.hidden,
watch: watchPage,
onPageHide: (listener, signal) => window.addEventListener("pagehide", listener, { signal }),
joinLink: (room) => joinLink(room),
reloadAs: (params) => reloadAsMachine(urlState, params, { replace: true }),
panel: (session, setTakeOnKey) =>
new SessionPanel({
name: session.name,
link: joinLink(session.room),
saveReport: () => saveReport(session),
copyLink: () => copyJoinLink(session.room),
requestControl: () => session.requestControl(null),
setTakeOnKey,
arrangement,
}),
};
}
|