asdkjlfhlaskjdhf
This commit is contained in:
@@ -29,10 +29,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
primeNotifications();
|
||||
|
||||
const defaultName = "Anon";
|
||||
const MAX_NAME_LEN = 15; // server limit is NAME_MAX_LENGTH-1 (15 chars)
|
||||
const MAX_NAME_LEN = 15;
|
||||
|
||||
// Fetch WebSocket domain from the client server so deployments can point to a
|
||||
// remote websocket host without rebuilding the bundle.
|
||||
fetch("/ws-domain")
|
||||
.then((res) => res.json())
|
||||
.then(({ domain }) => domain || "")
|
||||
@@ -118,7 +116,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
input.focus();
|
||||
});
|
||||
|
||||
// Global Escape handler: clear reply context, focus input, and clear focused message.
|
||||
// Global Escape handler: clear reply context, focus input, and clear
|
||||
// focused message.
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") {
|
||||
setReplyTo(null);
|
||||
|
||||
@@ -1,50 +1,41 @@
|
||||
// coms/client/public/data.js
|
||||
// Data module: holds the in‐memory threads, notices and reply state
|
||||
|
||||
import { notifyNotice } from "./notifications.js";
|
||||
|
||||
// Map of all messages and notices by ID (string IDs)
|
||||
// Client’s own session ID
|
||||
// Client’s own session ID.
|
||||
let myId = null;
|
||||
|
||||
// Map of all messages and notices by ID (string IDs).
|
||||
const threads = new Map();
|
||||
|
||||
// Map of connected users by unique ID
|
||||
// Map of connected users by unique ID.
|
||||
const users = new Map();
|
||||
|
||||
// Ordered list of root‐level IDs (messages and notices, stored as strings)
|
||||
// Ordered list of root‐level IDs (messages and notices, stored as strings).
|
||||
const rootIds = [];
|
||||
|
||||
// Negative counter to generate unique IDs for notices
|
||||
// Negative counter to generate unique IDs for notices.
|
||||
let noticeCounter = -1;
|
||||
|
||||
// ID of the message we’re currently replying to (string or null)
|
||||
// ID of the message we’re currently replying to (string or null).
|
||||
let replyTo = null;
|
||||
|
||||
// ID of the message currently focused for navigation (string or null)
|
||||
// ID of the message currently focused for navigation (string or null).
|
||||
let focusedId = null;
|
||||
|
||||
/**
|
||||
* Set the focused message ID (or null to clear).
|
||||
* @param {string|null} id
|
||||
*/
|
||||
// Set the focused message ID (or null to clear).
|
||||
function setFocused(id) {
|
||||
focusedId = id;
|
||||
}
|
||||
/**
|
||||
* Get the currently focused message ID.
|
||||
* @returns {string|null}
|
||||
*/
|
||||
|
||||
// Get the currently focused message ID.
|
||||
function getFocused() {
|
||||
return focusedId;
|
||||
}
|
||||
/**
|
||||
* Clear the current focus.
|
||||
*/
|
||||
|
||||
function clearFocused() {
|
||||
focusedId = null;
|
||||
}
|
||||
|
||||
// -- User management API ---
|
||||
// USER MANAGEMENT STUFF.
|
||||
|
||||
/**
|
||||
* Register a user with their unique ID.
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
// Simple notification helpers for the chat client.
|
||||
|
||||
const APP_NAME = "COMS";
|
||||
|
||||
function supportsNotifications() {
|
||||
return typeof Notification !== "undefined";
|
||||
}
|
||||
@@ -12,9 +8,6 @@ function stripHtml(input) {
|
||||
return div.textContent || div.innerText || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask for permission if not already granted/denied.
|
||||
*/
|
||||
function primeNotifications() {
|
||||
if (!supportsNotifications()) return;
|
||||
if (Notification.permission === "default") {
|
||||
@@ -34,14 +27,10 @@ function showNotification(title, body) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the user of a system notice.
|
||||
* @param {string} content - HTML or text content of the notice.
|
||||
*/
|
||||
function notifyNotice(content) {
|
||||
const text = stripHtml(content);
|
||||
if (!text) return;
|
||||
showNotification(`${APP_NAME} notice`, text);
|
||||
showNotification(`COMS`, text);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +42,7 @@ function notifyDirectReply(authorName, content) {
|
||||
const text = stripHtml(content);
|
||||
if (!text) return;
|
||||
const name = authorName || "Anon";
|
||||
showNotification(`${name} replied to your thread`, text);
|
||||
showNotification(`${name} replied`, text);
|
||||
}
|
||||
|
||||
export { primeNotifications, notifyNotice, notifyDirectReply };
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
// Render module: handles chat UI rendering of messages and notices
|
||||
// this one sucked.
|
||||
import { getThreads, getRootIds, getReplyTo, getFocused } from "./data.js";
|
||||
|
||||
/**
|
||||
* Render the chat history and input container into the provided chat element.
|
||||
* @param {HTMLElement} chatEl - The container element for chat entries.
|
||||
* @param {HTMLElement} inputContainer - The message input area to append at bottom.
|
||||
*/
|
||||
// Render the chat history and input container into the provided chat element.
|
||||
export function renderChat(chatEl, inputContainer) {
|
||||
// Clear existing content.
|
||||
chatEl.innerHTML = "";
|
||||
@@ -49,7 +45,7 @@ export function renderChat(chatEl, inputContainer) {
|
||||
const shortTimestamp = `${h}:${m} ${ampm}`;
|
||||
const tsSpan = `<span class="ts" title="${fullTimestamp}">${shortTimestamp}</span>`;
|
||||
|
||||
// Distinguish notice vs normal message.
|
||||
// Distinguish notices and normal messages.
|
||||
if (msg.username) {
|
||||
div.classList.add("msg");
|
||||
if (getFocused() === id) div.classList.add("focused");
|
||||
@@ -59,7 +55,7 @@ export function renderChat(chatEl, inputContainer) {
|
||||
div.innerHTML = `${tsSpan} ${msg.content}`;
|
||||
}
|
||||
|
||||
// Append to chat and render children.
|
||||
// Append to chat and render the children.
|
||||
chatEl.appendChild(div);
|
||||
msg.children.forEach((childId) => renderNode(childId, depth + 1));
|
||||
}
|
||||
@@ -91,14 +87,12 @@ export function renderChat(chatEl, inputContainer) {
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll to bottom.
|
||||
// Scroll to bottom. Or at least try. Let the browser know that is our
|
||||
// intention. May or may not actually work.
|
||||
chatEl.scrollTop = chatEl.scrollHeight;
|
||||
const input = inputContainer.querySelector("input");
|
||||
if (input) {
|
||||
input.focus();
|
||||
// Ensure inputContainer margin resets if at root.
|
||||
if (replyTo === null) {
|
||||
inputContainer.style.marginLeft = "0";
|
||||
}
|
||||
if (replyTo === null) inputContainer.style.marginLeft = "0";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
/**
|
||||
* coms/client/public/wsModule.js
|
||||
* WebSocket module: handles connection, dispatching incoming packets to
|
||||
* data and render modules, and provides a sendMessage API.
|
||||
*/
|
||||
|
||||
import {
|
||||
addMessage,
|
||||
addNotice,
|
||||
|
||||
Reference in New Issue
Block a user