From the development repository at 299f73d, 2026-10-11: hosting from the site documented; a page loaded from a notebook and left unchanged is not kept again; notebooks and pages are deleted from the chooser, to the system's Trash (--trash); the Notebooks button. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
190 lines
10 KiB
HTML
190 lines
10 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Kokkoja</title>
|
||
<link rel="stylesheet" href="kokkoja.css">
|
||
<script type="module" src="js/main.js"></script>
|
||
</head>
|
||
<body>
|
||
|
||
<main id="start" hidden>
|
||
<h1>Kokkoja</h1>
|
||
<label for="name">Your name, as others will see it</label>
|
||
<input id="name" type="text" maxlength="40" autocomplete="off">
|
||
|
||
<label for="notebook">Notebook for the pages of this session</label>
|
||
<select id="notebook" class="notebook_pick"
|
||
data-help="The notebook this session’s pages are saved in. The last entry makes a new notebook."></select>
|
||
<input id="notebook_name" type="text" maxlength="100" autocomplete="off" spellcheck="false"
|
||
placeholder="Name of the new notebook" aria-label="Name of the new notebook" hidden>
|
||
<p id="notebook_note" class="note notebook_directory"></p>
|
||
|
||
<section id="start_choice">
|
||
<h2>Start a session</h2>
|
||
<p>You will be given an invitation to send to the others.</p>
|
||
<button id="start_session" type="button">Start a session</button>
|
||
</section>
|
||
|
||
<section id="join_choice">
|
||
<h2>Join a session</h2>
|
||
<label for="invitation_entry">Invitation</label>
|
||
<input id="invitation_entry" type="text" autocomplete="off" spellcheck="false">
|
||
<button id="join_session" type="button">Join</button>
|
||
<p class="note"><a id="open_installed" href="#" hidden>Join with the Kokkoja program installed on this computer instead</a></p>
|
||
</section>
|
||
|
||
<p id="start_message" class="message" role="alert"></p>
|
||
</main>
|
||
|
||
<div id="session" hidden>
|
||
<header class="toolbar">
|
||
<div id="drawing" class="drawing" aria-label="Drawing">
|
||
<div class="group" role="radiogroup" aria-label="Tool">
|
||
<button type="button" data-tool="pen" aria-pressed="true"
|
||
data-help="Write on the page. Only your own writing can be erased.">Pen</button>
|
||
<button type="button" data-tool="text" aria-pressed="false"
|
||
data-help="Type on the page. Tap where the text should begin, or drag open a rectangle: a red box, white inside, in which the text wraps and which grows downward as you type. Tap your own text to change it; rest the pen on it to move it, or near a corner of a box to resize it.">Text</button>
|
||
</div>
|
||
<div id="settings" class="settings">
|
||
<div class="group" id="colors" role="radiogroup" aria-label="Color">
|
||
<button id="more_colors" type="button" class="swatch more"
|
||
data-help="Choose another color. It is added here.">+</button>
|
||
</div>
|
||
<div id="color_palette" class="palette" hidden></div>
|
||
<div class="group" id="widths" role="radiogroup" aria-label="Line width"></div>
|
||
<div class="group" id="text_style" hidden>
|
||
<select id="text_font" aria-label="Font" data-help="The font: a sans-serif, a serif or a monospaced one, as this computer has them.">
|
||
<option value="sans-serif" style="font-family: sans-serif">Sans</option>
|
||
<option value="serif" style="font-family: serif">Serif</option>
|
||
<option value="monospace" style="font-family: monospace">Mono</option>
|
||
</select>
|
||
<input id="text_size" type="number" min="6" max="100" step="1" value="14"
|
||
aria-label="Text size in points" data-help="Text size in points.">
|
||
</div>
|
||
</div>
|
||
<div class="group after_settings" role="radiogroup" aria-label="Hide and Eraser">
|
||
<button type="button" data-tool="hide" aria-pressed="false" hidden
|
||
data-help="Hide part of the page for everyone: drag open a rectangle, and what lies under it is covered in white, marked by blue corners. Rest the pen on it to move it, or near a corner to resize it; a tap of the eraser removes it.">Hide</button>
|
||
<button type="button" data-tool="eraser" aria-pressed="false"
|
||
data-help="Erase your own strokes and text by moving over them. A tap on an image, or on a Hide rectangle, removes it, if you are the host or a co-host (or added the image yourself). Two quick taps on empty paper, away from anything the eraser would remove, undo your latest mark; again, and the one before.">Eraser</button>
|
||
</div>
|
||
<button id="undo" type="button" disabled
|
||
data-help="Take back your latest mark: a stroke, an erasure, a text block typed or moved, a Hide rectangle. Again for the one before. Also Ctrl+Z (Command+Z on a Mac), or two quick taps of the eraser on empty paper. Only your own marks, and only on this page since you opened it.">Undo</button>
|
||
</div>
|
||
<div class="group page_view" aria-label="Page and view">
|
||
<button id="zoom_fit" type="button"
|
||
data-help="Show the whole page in the window. Pressed by the host, it does so on every screen. Ctrl (Command on a Mac) with the scroll wheel, or with a pen stroke up or down, zooms about the pointer.">Fit</button>
|
||
<button id="zoom_sheet" type="button"
|
||
data-help="Show the page at the scale a new page has: one A4 sheet filling the window. A shrunk page is then seen at its size on the sheet. Pressed by the host, it does so on every screen.">A4</button>
|
||
<button id="zoom_widen" type="button" hidden
|
||
data-help="Make the page wider, for everyone, until it fills the window at this zoom. Nothing on it moves.">Widen</button>
|
||
<button id="zoom_shrink" type="button" hidden
|
||
data-help="Make the page, for everyone, just large enough for what is on it, with the margin around. Nothing on it moves.">Shrink</button>
|
||
<label class="toggle" data-help="Let the page grow when your writing reaches an edge. Off, your writing stops at the edge. Images always get the room they need.">
|
||
Extend <input id="extend" type="checkbox" checked>
|
||
</label>
|
||
</div>
|
||
<div class="toolbar_right">
|
||
<div class="group" id="host_tools" hidden>
|
||
<button id="new_page" type="button"
|
||
data-help="Start a new blank page for everyone. The current page is kept in each notebook.">New</button>
|
||
<button id="load_image" type="button"
|
||
data-help="Put an image file, such as a scanned exercise, on the page for everyone: below the images already there, centred, at its own size. Rest the pen on an image to move it, or near a corner to scale it; it comes to the front. A tap of the eraser on an image removes it; writing on it stays.">Image</button>
|
||
<button id="load_notebook_page" type="button"
|
||
data-help="Start a new page for everyone from a page kept in a notebook, with everything on it. The current page is kept in each notebook.">Notebooks</button>
|
||
</div>
|
||
<div class="group" aria-label="Notebook">
|
||
<select id="session_notebook" class="notebook_pick" aria-label="Current notebook"
|
||
data-help="The notebook the page is saved in. Choosing another continues the page there; the last entry makes a new notebook."></select>
|
||
<input id="session_notebook_name" type="text" maxlength="100" autocomplete="off" spellcheck="false"
|
||
placeholder="Name of the new notebook" aria-label="Name of the new notebook" hidden>
|
||
<button id="keep_page" type="button"
|
||
data-help="Keep a dated copy of the page as it is now. The page is also kept by itself whenever it is about to be replaced.">Keep</button>
|
||
<button id="export_page" type="button"
|
||
data-help="Save a picture of the page, as it is shown here, in a PNG file at a place you choose.">Export</button>
|
||
</div>
|
||
<button id="session_button" type="button"
|
||
data-help="Who is here, and the invitation to send to others.">Session</button>
|
||
</div>
|
||
</header>
|
||
<div id="notice" class="notice" hidden></div>
|
||
|
||
<div class="workspace">
|
||
<div id="desk" class="desk">
|
||
<div id="page" class="page"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<dialog id="session_dialog" class="chooser session">
|
||
<header>
|
||
<h2>Session</h2>
|
||
<button id="session_close" type="button" aria-label="Close">×</button>
|
||
</header>
|
||
<div class="session_body">
|
||
<h3>Participants</h3>
|
||
<ul id="participants"></ul>
|
||
<h3>Invitation</h3>
|
||
<div class="invitation_line">
|
||
<input id="invitation" type="text" readonly spellcheck="false">
|
||
<button id="copy_invitation" type="button"
|
||
data-help="Copy the invitation, to send to the others by any means.">Copy</button>
|
||
</div>
|
||
<div id="invitation_code" class="invitation_code" hidden
|
||
data-help="The invitation as a QR code. Point the camera of a phone or a tablet at it, and the link opens there."></div>
|
||
<p class="note session_state">
|
||
<span id="page_number" class="page_number"></span>
|
||
<span id="status" class="status"></span>
|
||
<span id="save_status" class="save_status"></span>
|
||
</p>
|
||
<p class="note notebook_directory"></p>
|
||
<h3>Log</h3>
|
||
<div class="log_line">
|
||
<pre id="event_log" class="event_log"></pre>
|
||
<button id="copy_log" type="button"
|
||
data-help="Copy the log: what happened in this session and every press and release of the pen, for finding a fault.">Copy</button>
|
||
</div>
|
||
</div>
|
||
</dialog>
|
||
|
||
<dialog id="notebook_chooser" class="chooser">
|
||
<header>
|
||
<h2>Notebooks</h2>
|
||
<button id="chooser_delete" type="button" class="delete" hidden
|
||
data-help="Delete the marked notebooks and pages. The first press says what will happen; the second does it.">Delete</button>
|
||
<button id="chooser_close" type="button" aria-label="Close">×</button>
|
||
</header>
|
||
<div class="chooser_body">
|
||
<nav id="chooser_notebooks" class="chooser_notebooks"></nav>
|
||
<div id="chooser_pages" class="chooser_pages"></div>
|
||
</div>
|
||
<p id="chooser_message" class="note"></p>
|
||
</dialog>
|
||
|
||
<dialog id="file_chooser" class="chooser">
|
||
<header>
|
||
<h2 id="files_title">Image</h2>
|
||
<button id="files_close" type="button" aria-label="Close">×</button>
|
||
</header>
|
||
<div class="files_place">
|
||
<button id="files_up" type="button">Up</button>
|
||
<input id="files_directory" type="text" spellcheck="false" autocomplete="off"
|
||
aria-label="Directory">
|
||
</div>
|
||
<div class="files_body">
|
||
<nav id="files_directories" class="files_directories"></nav>
|
||
<div id="files_entries" class="files_entries"></div>
|
||
</div>
|
||
<div id="files_save" class="files_save" hidden>
|
||
<input id="files_name" type="text" spellcheck="false" autocomplete="off"
|
||
aria-label="File name">
|
||
<button id="files_save_here" type="button">Export</button>
|
||
</div>
|
||
<p id="files_message" class="note"></p>
|
||
</dialog>
|
||
|
||
</body>
|
||
</html>
|