feat(channels): rename channels, and quieter defaults for sound and streams
CI / Build & test (Node 20) (push) Canceled after 0s
CI / Build & test (Node 24) (push) Canceled after 0s
CI / Build & test (push) Canceled after 0s
CodeQL / Analyze (javascript-typescript) (push) Canceled after 0s
Security / Secret scan (gitleaks) (push) Canceled after 0s
Security / Dependency scan (OSV-Scanner) (push) Canceled after 0s
Security / IaC/config scan (Trivy) (push) Canceled after 0s
Security / License compliance scan (Trivy) (push) Canceled after 0s
OpenSSF Scorecard / Scorecard analysis (push) Canceled after 0s
CI / Build & test (Node 20) (push) Canceled after 0s
CI / Build & test (Node 24) (push) Canceled after 0s
CI / Build & test (push) Canceled after 0s
CodeQL / Analyze (javascript-typescript) (push) Canceled after 0s
Security / Secret scan (gitleaks) (push) Canceled after 0s
Security / Dependency scan (OSV-Scanner) (push) Canceled after 0s
Security / IaC/config scan (Trivy) (push) Canceled after 0s
Security / License compliance scan (Trivy) (push) Canceled after 0s
OpenSSF Scorecard / Scorecard analysis (push) Canceled after 0s
Four owner requests in one pass. Rename: the PATCH /api/channels/:id route already accepted a name and a topic, and the API client already exposed it — the only thing missing was a way to reach it. The channel settings Overview tab now edits both, gated on MANAGE_CHANNELS like the server is, with Save/Discard appearing only when the form is dirty. The server's lowercase-and-hyphenate rule moved to @backspace/shared so the field can show what a name will actually become instead of letting it change shape on save; one copy of the rule, used by both sides. Stream volume: someone else's screen share now starts at 50 instead of 100 (DEFAULT_STREAM_VOLUME). The publisher boosts system audio before sending, so the old default arrived far too loud for a viewer who never touched the slider. Only the default moves — the slider still covers the full range and a value the user set is still persisted. Sound effects: SFX_BASE_VOLUME 0.8 -> 0.4, halving every cue. The .ogg files were left alone; they already peak below full scale, so the harshness was level, not recorded distortion. Every SFX playback path goes through getSfxVolume(), so this is the single knob. Translations: channel settings (including the override editor's permission labels), the friends page end to end — tabs, lists, requests, the add tab and discovery cards — the invite modal including its per-invite failure reasons, and the group-DM member actions. Failure reasons are carried as translation keys rather than finished text, so results already on screen re-label when the language changes. Verified: web build (tsc + vite), server typecheck, 490 web tests, 804 server tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,11 @@ import type {
|
||||
Channel,
|
||||
ChannelCategory,
|
||||
} from '@backspace/shared';
|
||||
import {
|
||||
normalizeChannelName,
|
||||
CHANNEL_NAME_MIN_LENGTH,
|
||||
CHANNEL_NAME_MAX_LENGTH,
|
||||
} from '@backspace/shared/src/constants.js';
|
||||
|
||||
function rowToChannel(row: typeof schema.channels.$inferSelect): Channel {
|
||||
return {
|
||||
@@ -190,8 +195,8 @@ export async function channelRoutes(app: FastifyInstance): Promise<void> {
|
||||
return reply.code(400).send({ error: 'Channel name is required', statusCode: 400 });
|
||||
}
|
||||
|
||||
const trimmedName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
||||
if (trimmedName.length < 1 || trimmedName.length > 100) {
|
||||
const trimmedName = normalizeChannelName(name);
|
||||
if (trimmedName.length < CHANNEL_NAME_MIN_LENGTH || trimmedName.length > CHANNEL_NAME_MAX_LENGTH) {
|
||||
return reply.code(400).send({ error: 'Channel name must be between 1 and 100 characters', statusCode: 400 });
|
||||
}
|
||||
|
||||
@@ -296,8 +301,8 @@ export async function channelRoutes(app: FastifyInstance): Promise<void> {
|
||||
const updates: Partial<typeof schema.channels.$inferInsert> = {};
|
||||
|
||||
if (name !== undefined) {
|
||||
const trimmedName = name.trim().toLowerCase().replace(/\s+/g, '-');
|
||||
if (trimmedName.length < 1 || trimmedName.length > 100) {
|
||||
const trimmedName = normalizeChannelName(name);
|
||||
if (trimmedName.length < CHANNEL_NAME_MIN_LENGTH || trimmedName.length > CHANNEL_NAME_MAX_LENGTH) {
|
||||
return reply.code(400).send({ error: 'Channel name must be between 1 and 100 characters', statusCode: 400 });
|
||||
}
|
||||
updates.name = trimmedName;
|
||||
|
||||
Reference in New Issue
Block a user