Add channel and permission management, sounds, themes and the public server list
- Channels: create, edit, delete, link and move (drag and drop for channels and people), right-click on free space in the channel list - Permission editor with inherited rules, allow/deny per permission, groups and members; menus grey out actions the server does not allow - Notification sounds for connection, channel, chat, mute and push-to-talk events; custom files and TeamSpeak 3 style sound packs (settings.ini), stored in IndexedDB - Color schemes: Dark, Light, Midnight, Frost and Windows 95 - Public server list with live UDP ping, fetched through Chromium's network stack - Kick, ban and connection-lost card with Reconnect - Right-click menus for text fields, links, images and message authors - Formatting toolbar in the message box, shared with the description editor - Resizable channel list, menu headers, registration from the self menu only - Fix: client-side pacing now mirrors Murmur's whole-second leaky bucket exactly, so quick actions are no longer dropped silently Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+11
-2
@@ -3,11 +3,20 @@
|
||||
import YouTubeEmbed from './YouTubeEmbed.svelte';
|
||||
import LinkPreview from './LinkPreview.svelte';
|
||||
import { store } from '../lib/settings.svelte.ts';
|
||||
import { session } from '../lib/session.svelte.ts';
|
||||
import { menu } from '../lib/menu.svelte.ts';
|
||||
import { userMenu } from '../lib/actions.ts';
|
||||
import type { ChatEntry } from '../lib/session.svelte.ts';
|
||||
|
||||
let { entry, grouped }: { entry: ChatEntry; grouped: boolean } = $props();
|
||||
|
||||
const time = $derived(new Date(entry.time));
|
||||
|
||||
// Right-click on the author opens the user menu while they are still online
|
||||
function authorMenu(e: MouseEvent) {
|
||||
const u = entry.authorSession != null ? session.user(entry.authorSession) : undefined;
|
||||
if (u) menu.show(e, userMenu(u));
|
||||
}
|
||||
const hhmm = $derived(time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }));
|
||||
</script>
|
||||
|
||||
@@ -22,13 +31,13 @@
|
||||
{#if grouped}
|
||||
<span class="time hover">{hhmm}</span>
|
||||
{:else}
|
||||
<Avatar name={entry.author} size={38} />
|
||||
<span role="presentation" oncontextmenu={authorMenu}><Avatar name={entry.author} size={38} /></span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="content">
|
||||
{#if !grouped}
|
||||
<header>
|
||||
<strong class:self={entry.self}>{entry.author}</strong>
|
||||
<strong class:self={entry.self} oncontextmenu={authorMenu}>{entry.author}</strong>
|
||||
<time datetime={time.toISOString()}>{time.toLocaleString([], { dateStyle: 'short', timeStyle: 'short' })}</time>
|
||||
</header>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user