Removed unused captions code.
This commit is contained in:
@@ -22,17 +22,12 @@ server.
|
||||
|
||||
## Workflow
|
||||
|
||||
- Use `todo.txt` as the source of truth for staged work.
|
||||
- Preserve the todo status markers:
|
||||
- `-` means open.
|
||||
- `+` means implemented, needs testing.
|
||||
- `X` means tested and done.
|
||||
- Work in small batches and update `todo.txt` only for items actually completed
|
||||
or tested.
|
||||
- Before beginning a new phase or section, review all earlier `+` and `X`
|
||||
sections in `todo.txt`; confirm their status still matches the code, tests,
|
||||
docs, and user-facing surfaces, and downgrade stale `X` markers when evidence
|
||||
no longer supports them.
|
||||
- Skald is production software; prefer small, scoped maintenance changes with
|
||||
focused verification.
|
||||
- Use a temporary local plan file only for large or risky batches that need a
|
||||
resumable checklist.
|
||||
- Building the Arch package updates `distro-packages/Arch-Linux/skald-git/PKGBUILD`
|
||||
with the generated `pkgver`, so this file is often dirty after package builds.
|
||||
- Keep changes scoped to the current batch. Do not mix in unrelated cleanup.
|
||||
- Before behavior changes, inspect the current code path and tests rather than
|
||||
assuming Galene behavior still applies.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# shellcheck shell=bash disable=SC2034,SC2154
|
||||
|
||||
pkgname=skald-git
|
||||
pkgver=2026.07.08
|
||||
pkgver=2026.07.08.r0.g9a9742e
|
||||
pkgrel=1
|
||||
pkgdesc='Audio-only hall-based conferencing server'
|
||||
arch=('x86_64' 'aarch64')
|
||||
|
||||
+1
-2
@@ -34,11 +34,10 @@ type Permissions struct {
|
||||
}
|
||||
|
||||
var permissionsMap = map[string][]string{
|
||||
"op": {"op", "present", "message", "caption", "token"},
|
||||
"op": {"op", "present", "message", "token"},
|
||||
"present": {"present", "message"},
|
||||
"message": {"message"},
|
||||
"observe": {},
|
||||
"caption": {"caption"},
|
||||
"admin": {"admin"},
|
||||
}
|
||||
|
||||
|
||||
+6
-14
@@ -396,8 +396,6 @@ var james = "james"
|
||||
var paul = "paul"
|
||||
var peter = "peter"
|
||||
var admin = "admin"
|
||||
var stt = "speech-to-text"
|
||||
|
||||
var badClients = []ClientCredentials{
|
||||
{Username: &jch, Password: "foo"},
|
||||
{Username: &john, Password: "foo"},
|
||||
@@ -418,9 +416,7 @@ var desc2JSON = `
|
||||
"john": {"password": "secret", "permissions": "present"},
|
||||
"james": {"password": "secret2", "permissions": "message"},
|
||||
"peter": {"password": "secret4"},
|
||||
"admin": {"password": "admin", "permissions": "admin"},
|
||||
"speech-to-text": {"password": {"type": "wildcard"},
|
||||
"permissions": "caption"}
|
||||
"admin": {"password": "admin", "permissions": "admin"}
|
||||
},
|
||||
"wildcard-user":
|
||||
{"permissions": "message", "password": {"type":"wildcard"}}
|
||||
@@ -429,7 +425,7 @@ var desc2JSON = `
|
||||
var goodClients = []credPerm{
|
||||
{
|
||||
ClientCredentials{Username: &jch, Password: "topsecret"},
|
||||
[]string{"op", "present", "message", "caption", "token"},
|
||||
[]string{"op", "present", "message", "token"},
|
||||
},
|
||||
{
|
||||
ClientCredentials{Username: &john, Password: "secret"},
|
||||
@@ -451,10 +447,6 @@ var goodClients = []credPerm{
|
||||
ClientCredentials{Username: &admin, Password: "admin"},
|
||||
[]string{"admin"},
|
||||
},
|
||||
{
|
||||
ClientCredentials{Username: &stt},
|
||||
[]string{"caption"},
|
||||
},
|
||||
}
|
||||
|
||||
func TestPermissions(t *testing.T) {
|
||||
@@ -513,7 +505,7 @@ func TestExtraPermissions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
doit("jch", []string{"op", "token", "present", "message", "caption"})
|
||||
doit("jch", []string{"op", "token", "present", "message"})
|
||||
doit("john", []string{"present", "message"})
|
||||
doit("james", []string{})
|
||||
|
||||
@@ -521,7 +513,7 @@ func TestExtraPermissions(t *testing.T) {
|
||||
d.UnrestrictedTokens = false
|
||||
|
||||
doit("jch", []string{
|
||||
"op", "record", "token", "present", "message", "caption",
|
||||
"op", "record", "token", "present", "message",
|
||||
})
|
||||
doit("john", []string{"present", "message"})
|
||||
doit("james", []string{})
|
||||
@@ -529,7 +521,7 @@ func TestExtraPermissions(t *testing.T) {
|
||||
d.AllowRecording = false
|
||||
d.UnrestrictedTokens = true
|
||||
|
||||
doit("jch", []string{"op", "token", "present", "message", "caption"})
|
||||
doit("jch", []string{"op", "token", "present", "message"})
|
||||
doit("john", []string{"token", "present", "message"})
|
||||
doit("james", []string{})
|
||||
|
||||
@@ -537,7 +529,7 @@ func TestExtraPermissions(t *testing.T) {
|
||||
d.UnrestrictedTokens = true
|
||||
|
||||
doit("jch", []string{
|
||||
"op", "record", "token", "present", "message", "caption",
|
||||
"op", "record", "token", "present", "message",
|
||||
})
|
||||
doit("john", []string{"token", "present", "message"})
|
||||
doit("james", []string{})
|
||||
|
||||
@@ -1606,11 +1606,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||
return c.error(hall.UserError("join a hall first"))
|
||||
}
|
||||
|
||||
required := "message"
|
||||
if m.Type == "chat" && m.Kind == "caption" {
|
||||
required = "caption"
|
||||
}
|
||||
if !member(required, c.permissions) {
|
||||
if !member("message", c.permissions) {
|
||||
return c.error(hall.UserError("not authorised"))
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -306,7 +306,7 @@ A chat message may be sent using a `chat` message.
|
||||
```javascript
|
||||
{
|
||||
type: 'chat',
|
||||
kind: null or 'me' or 'caption',
|
||||
kind: null or 'me',
|
||||
source: source-id,
|
||||
username: username,
|
||||
dest: dest-id,
|
||||
@@ -320,9 +320,7 @@ A chat message may be sent using a `chat` message.
|
||||
The field `kind` can have one of the following values:
|
||||
|
||||
- `null` or the empty string, a normal chat message;
|
||||
- `'me'`, an IRC-style first-person message;
|
||||
- `'caption'`, a caption or subtitle (this requires the sender to have
|
||||
the `caption` permission).
|
||||
- `'me'`, an IRC-style first-person message.
|
||||
|
||||
If `dest` is empty, the message is a broadcast message, destined to all of
|
||||
the clients in the hall. If `source` is empty, then the message was
|
||||
|
||||
@@ -434,7 +434,6 @@ following strings:
|
||||
- `message`: a user with the right to send chat messages;
|
||||
- `observe`: a user that receives media streams and chat messages, but
|
||||
is not allowed to send them;
|
||||
- `caption`: a user with the right to display captions (only);
|
||||
- `admin`: a user with the right to administer the hall (only).
|
||||
|
||||
Usernames must be non-empty and unique among connected non-system clients in a
|
||||
|
||||
@@ -97,7 +97,7 @@ func TestInteractiveHall(t *testing.T) {
|
||||
|
||||
func TestFormatPermissions(t *testing.T) {
|
||||
tests := []struct{ j, v, p string }{
|
||||
{`"op"`, "op", "[cmopt]"},
|
||||
{`"op"`, "op", "[mopt]"},
|
||||
{`"present"`, "present", "[mp]"},
|
||||
{`"observe"`, "observe", "[]"},
|
||||
{`"admin"`, "admin", "[a]"},
|
||||
|
||||
@@ -1220,26 +1220,6 @@ header .collapse:hover {
|
||||
|
||||
}
|
||||
|
||||
#captions-container {
|
||||
position: absolute;
|
||||
bottom: 40px;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 1390;
|
||||
alpha: 0;
|
||||
}
|
||||
|
||||
#captions {
|
||||
margin: auto;
|
||||
padding: 0 0.4rem 0 0.4rem;
|
||||
width: max-content;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
pointer-events: none;
|
||||
background-color: rgba(255,255,255,.7);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
:root {
|
||||
--skald-menu-bg: #eee;
|
||||
--skald-menu-shadow: 1px 1px 1px #444;
|
||||
|
||||
@@ -84,9 +84,6 @@
|
||||
<button class="chat-btn show-chat invisible" id="show-chat" aria-label="Show chat">
|
||||
<i class="far fa-comment-alt icon-chat" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div id="captions-container" class="invisible">
|
||||
<div id="captions"></div>
|
||||
</div>
|
||||
<div class="login-container invisible" id="login-container">
|
||||
<div class="login-box">
|
||||
<form id="loginform" class="loginform">
|
||||
|
||||
@@ -2881,11 +2881,6 @@ function announceUrgent(text) {
|
||||
* @param {string|HTMLElement} message
|
||||
*/
|
||||
function addToChatbox(id, peerId, dest, nick, time, privileged, history, kind, message) {
|
||||
if(kind === 'caption') {
|
||||
displayCaption(message);
|
||||
return;
|
||||
}
|
||||
|
||||
let row = document.createElement('div');
|
||||
row.classList.add('message-row');
|
||||
let container = document.createElement('div');
|
||||
@@ -3046,38 +3041,6 @@ function chatMessageMenu(elt, trigger) {
|
||||
openActionMenu(items, trigger, `Actions for message from ${u}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string|HTMLElement} message
|
||||
*/
|
||||
function setCaption(message) {
|
||||
let container = document.getElementById('captions-container');
|
||||
let captions = document.getElementById('captions');
|
||||
if(!message) {
|
||||
captions.replaceChildren();
|
||||
container.classList.add('invisible');
|
||||
} else {
|
||||
if(message instanceof HTMLElement)
|
||||
captions.replaceChildren(message);
|
||||
else
|
||||
captions.textContent = message;
|
||||
container.classList.remove('invisible');
|
||||
}
|
||||
}
|
||||
|
||||
let captionsTimer = null;
|
||||
|
||||
/**
|
||||
* @param {string|HTMLElement} message
|
||||
*/
|
||||
function displayCaption(message) {
|
||||
if(captionsTimer != null) {
|
||||
clearTimeout(captionsTimer);
|
||||
captionsTimer = null;
|
||||
}
|
||||
setCaption(message);
|
||||
captionsTimer = setTimeout(() => setCaption(null), 3000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string|HTMLElement} message
|
||||
*/
|
||||
|
||||
@@ -69,6 +69,16 @@ func TestStaticLiveRegionAnnouncementsStayWired(t *testing.T) {
|
||||
requireFunctionContains(t, js, "setUserStatus", "announceUrgent(`${username}: hand lowered`)")
|
||||
}
|
||||
|
||||
func TestCaptionOverlayHasBeenRemoved(t *testing.T) {
|
||||
html := readStaticFile(t, "skald.html")
|
||||
js := readStaticFile(t, "skald.js")
|
||||
css := readStaticFile(t, "skald.css")
|
||||
|
||||
requireNotContains(t, html, "captions", "hall page")
|
||||
requireNotContains(t, js, "caption", "hall script")
|
||||
requireNotContains(t, css, "caption", "hall styles")
|
||||
}
|
||||
|
||||
func TestHallHeadingIncludesCurrentStatus(t *testing.T) {
|
||||
html := readStaticFile(t, "skald.html")
|
||||
js := readStaticFile(t, "skald.js")
|
||||
|
||||
Reference in New Issue
Block a user