Removed unused captions code.

This commit is contained in:
Storm Dragon
2026-07-09 11:15:35 -04:00
parent 9a9742e066
commit 704b1a9558
12 changed files with 28 additions and 99 deletions
+6 -11
View File
@@ -22,17 +22,12 @@ server.
## Workflow ## Workflow
- Use `todo.txt` as the source of truth for staged work. - Skald is production software; prefer small, scoped maintenance changes with
- Preserve the todo status markers: focused verification.
- `-` means open. - Use a temporary local plan file only for large or risky batches that need a
- `+` means implemented, needs testing. resumable checklist.
- `X` means tested and done. - Building the Arch package updates `distro-packages/Arch-Linux/skald-git/PKGBUILD`
- Work in small batches and update `todo.txt` only for items actually completed with the generated `pkgver`, so this file is often dirty after package builds.
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.
- Keep changes scoped to the current batch. Do not mix in unrelated cleanup. - 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 - Before behavior changes, inspect the current code path and tests rather than
assuming Galene behavior still applies. assuming Galene behavior still applies.
@@ -2,7 +2,7 @@
# shellcheck shell=bash disable=SC2034,SC2154 # shellcheck shell=bash disable=SC2034,SC2154
pkgname=skald-git pkgname=skald-git
pkgver=2026.07.08 pkgver=2026.07.08.r0.g9a9742e
pkgrel=1 pkgrel=1
pkgdesc='Audio-only hall-based conferencing server' pkgdesc='Audio-only hall-based conferencing server'
arch=('x86_64' 'aarch64') arch=('x86_64' 'aarch64')
+1 -2
View File
@@ -34,11 +34,10 @@ type Permissions struct {
} }
var permissionsMap = map[string][]string{ var permissionsMap = map[string][]string{
"op": {"op", "present", "message", "caption", "token"}, "op": {"op", "present", "message", "token"},
"present": {"present", "message"}, "present": {"present", "message"},
"message": {"message"}, "message": {"message"},
"observe": {}, "observe": {},
"caption": {"caption"},
"admin": {"admin"}, "admin": {"admin"},
} }
+6 -14
View File
@@ -396,8 +396,6 @@ var james = "james"
var paul = "paul" var paul = "paul"
var peter = "peter" var peter = "peter"
var admin = "admin" var admin = "admin"
var stt = "speech-to-text"
var badClients = []ClientCredentials{ var badClients = []ClientCredentials{
{Username: &jch, Password: "foo"}, {Username: &jch, Password: "foo"},
{Username: &john, Password: "foo"}, {Username: &john, Password: "foo"},
@@ -418,9 +416,7 @@ var desc2JSON = `
"john": {"password": "secret", "permissions": "present"}, "john": {"password": "secret", "permissions": "present"},
"james": {"password": "secret2", "permissions": "message"}, "james": {"password": "secret2", "permissions": "message"},
"peter": {"password": "secret4"}, "peter": {"password": "secret4"},
"admin": {"password": "admin", "permissions": "admin"}, "admin": {"password": "admin", "permissions": "admin"}
"speech-to-text": {"password": {"type": "wildcard"},
"permissions": "caption"}
}, },
"wildcard-user": "wildcard-user":
{"permissions": "message", "password": {"type":"wildcard"}} {"permissions": "message", "password": {"type":"wildcard"}}
@@ -429,7 +425,7 @@ var desc2JSON = `
var goodClients = []credPerm{ var goodClients = []credPerm{
{ {
ClientCredentials{Username: &jch, Password: "topsecret"}, ClientCredentials{Username: &jch, Password: "topsecret"},
[]string{"op", "present", "message", "caption", "token"}, []string{"op", "present", "message", "token"},
}, },
{ {
ClientCredentials{Username: &john, Password: "secret"}, ClientCredentials{Username: &john, Password: "secret"},
@@ -451,10 +447,6 @@ var goodClients = []credPerm{
ClientCredentials{Username: &admin, Password: "admin"}, ClientCredentials{Username: &admin, Password: "admin"},
[]string{"admin"}, []string{"admin"},
}, },
{
ClientCredentials{Username: &stt},
[]string{"caption"},
},
} }
func TestPermissions(t *testing.T) { 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("john", []string{"present", "message"})
doit("james", []string{}) doit("james", []string{})
@@ -521,7 +513,7 @@ func TestExtraPermissions(t *testing.T) {
d.UnrestrictedTokens = false d.UnrestrictedTokens = false
doit("jch", []string{ doit("jch", []string{
"op", "record", "token", "present", "message", "caption", "op", "record", "token", "present", "message",
}) })
doit("john", []string{"present", "message"}) doit("john", []string{"present", "message"})
doit("james", []string{}) doit("james", []string{})
@@ -529,7 +521,7 @@ func TestExtraPermissions(t *testing.T) {
d.AllowRecording = false d.AllowRecording = false
d.UnrestrictedTokens = true 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("john", []string{"token", "present", "message"})
doit("james", []string{}) doit("james", []string{})
@@ -537,7 +529,7 @@ func TestExtraPermissions(t *testing.T) {
d.UnrestrictedTokens = true d.UnrestrictedTokens = true
doit("jch", []string{ doit("jch", []string{
"op", "record", "token", "present", "message", "caption", "op", "record", "token", "present", "message",
}) })
doit("john", []string{"token", "present", "message"}) doit("john", []string{"token", "present", "message"})
doit("james", []string{}) doit("james", []string{})
+1 -5
View File
@@ -1606,11 +1606,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
return c.error(hall.UserError("join a hall first")) return c.error(hall.UserError("join a hall first"))
} }
required := "message" if !member("message", c.permissions) {
if m.Type == "chat" && m.Kind == "caption" {
required = "caption"
}
if !member(required, c.permissions) {
return c.error(hall.UserError("not authorised")) return c.error(hall.UserError("not authorised"))
} }
+2 -4
View File
@@ -306,7 +306,7 @@ A chat message may be sent using a `chat` message.
```javascript ```javascript
{ {
type: 'chat', type: 'chat',
kind: null or 'me' or 'caption', kind: null or 'me',
source: source-id, source: source-id,
username: username, username: username,
dest: dest-id, 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: The field `kind` can have one of the following values:
- `null` or the empty string, a normal chat message; - `null` or the empty string, a normal chat message;
- `'me'`, an IRC-style first-person message; - `'me'`, an IRC-style first-person message.
- `'caption'`, a caption or subtitle (this requires the sender to have
the `caption` permission).
If `dest` is empty, the message is a broadcast message, destined to all of 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 the clients in the hall. If `source` is empty, then the message was
-1
View File
@@ -434,7 +434,6 @@ following strings:
- `message`: a user with the right to send chat messages; - `message`: a user with the right to send chat messages;
- `observe`: a user that receives media streams and chat messages, but - `observe`: a user that receives media streams and chat messages, but
is not allowed to send them; 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). - `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 Usernames must be non-empty and unique among connected non-system clients in a
+1 -1
View File
@@ -97,7 +97,7 @@ func TestInteractiveHall(t *testing.T) {
func TestFormatPermissions(t *testing.T) { func TestFormatPermissions(t *testing.T) {
tests := []struct{ j, v, p string }{ tests := []struct{ j, v, p string }{
{`"op"`, "op", "[cmopt]"}, {`"op"`, "op", "[mopt]"},
{`"present"`, "present", "[mp]"}, {`"present"`, "present", "[mp]"},
{`"observe"`, "observe", "[]"}, {`"observe"`, "observe", "[]"},
{`"admin"`, "admin", "[a]"}, {`"admin"`, "admin", "[a]"},
-20
View File
@@ -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 { :root {
--skald-menu-bg: #eee; --skald-menu-bg: #eee;
--skald-menu-shadow: 1px 1px 1px #444; --skald-menu-shadow: 1px 1px 1px #444;
-3
View File
@@ -84,9 +84,6 @@
<button class="chat-btn show-chat invisible" id="show-chat" aria-label="Show chat"> <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> <i class="far fa-comment-alt icon-chat" aria-hidden="true"></i>
</button> </button>
<div id="captions-container" class="invisible">
<div id="captions"></div>
</div>
<div class="login-container invisible" id="login-container"> <div class="login-container invisible" id="login-container">
<div class="login-box"> <div class="login-box">
<form id="loginform" class="loginform"> <form id="loginform" class="loginform">
-37
View File
@@ -2881,11 +2881,6 @@ function announceUrgent(text) {
* @param {string|HTMLElement} message * @param {string|HTMLElement} message
*/ */
function addToChatbox(id, peerId, dest, nick, time, privileged, history, kind, message) { function addToChatbox(id, peerId, dest, nick, time, privileged, history, kind, message) {
if(kind === 'caption') {
displayCaption(message);
return;
}
let row = document.createElement('div'); let row = document.createElement('div');
row.classList.add('message-row'); row.classList.add('message-row');
let container = document.createElement('div'); let container = document.createElement('div');
@@ -3046,38 +3041,6 @@ function chatMessageMenu(elt, trigger) {
openActionMenu(items, trigger, `Actions for message from ${u}`); 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 * @param {string|HTMLElement} message
*/ */
+10
View File
@@ -69,6 +69,16 @@ func TestStaticLiveRegionAnnouncementsStayWired(t *testing.T) {
requireFunctionContains(t, js, "setUserStatus", "announceUrgent(`${username}: hand lowered`)") 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) { func TestHallHeadingIncludesCurrentStatus(t *testing.T) {
html := readStaticFile(t, "skald.html") html := readStaticFile(t, "skald.html")
js := readStaticFile(t, "skald.js") js := readStaticFile(t, "skald.js")