diff --git a/server/config.example.toml b/server/config.example.toml
index e99eefa..50431d9 100644
--- a/server/config.example.toml
+++ b/server/config.example.toml
@@ -18,6 +18,19 @@ adminPasswordHash = "f52fbd32b2b3b86ff88ef6c490628285f482af15ddcb29541f94bcf526a
[chat.ratelimits]
chat = {seconds = 10, limit = 8}
+[motd]
+version = 1
+html = """
+
diff --git a/webapp/src/ts/MSWindow.ts b/webapp/src/ts/MSWindow.ts
index 005dc8e..47e512c 100644
--- a/webapp/src/ts/MSWindow.ts
+++ b/webapp/src/ts/MSWindow.ts
@@ -1,7 +1,8 @@
export interface MSWindowConfig {
- width: number,
- height: number,
- hasClose: boolean;
+ minWidth: number,
+ minHeight: number,
+ maxWidth?: number | undefined,
+ maxHeight?: number | undefined,
startPosition: MSWindowStartPosition
}
@@ -12,6 +13,7 @@ export enum MSWindowStartPosition {
export class MSWindow {
wnd: HTMLDivElement;
+ closeBtn: HTMLButtonElement | undefined;
config: MSWindowConfig;
titlebar: HTMLDivElement;
body: HTMLDivElement;
@@ -23,14 +25,27 @@ export class MSWindow {
this.shown = false;
this.wnd = wnd;
this.config = config;
- this.wnd.style.width = config.width + "px";
- this.wnd.style.height = config.height + "px";
+ this.wnd.style.minWidth = config.minWidth + "px";
+ this.wnd.style.minHeight = config.minHeight + "px";
+ if (config.maxWidth) {
+ this.wnd.style.maxWidth = config.maxWidth + "px";
+ }
+ if (config.maxHeight) {
+ this.wnd.style.maxHeight = config.maxHeight + "px";
+ }
let titlebar = this.wnd.querySelector("div.title-bar");
let body = this.wnd.querySelector("div.window-body");
if (!titlebar || !body)
throw new Error("MSWindow is missing titlebar or body element.");
this.titlebar = titlebar as HTMLDivElement;
this.body = body as HTMLDivElement;
+ let closeBtn = this.titlebar.querySelector("div.title-bar-controls > button[aria-label='Close']") as HTMLButtonElement;
+ if (closeBtn) {
+ this.closeBtn = closeBtn;
+ closeBtn.addEventListener('click', () => {
+ this.hide();
+ });
+ }
// Register window move handlers
this.dragging = false;
switch (this.config.startPosition) {
@@ -40,8 +55,8 @@ export class MSWindow {
break;
}
case MSWindowStartPosition.Center: {
- this.x = (document.documentElement.clientWidth / 2) - (this.config.width / 2);
- this.y = (document.documentElement.clientHeight / 2) - (this.config.height / 2);
+ this.x = (document.documentElement.clientWidth / 2) - (this.config.minWidth / 2);
+ this.y = (document.documentElement.clientHeight / 2) - (this.config.minHeight / 2);
break;
}
default: {
@@ -79,8 +94,8 @@ export class MSWindow {
private setLoc() {
if (this.x < 0) this.x = 0;
if (this.y < 0) this.y = 0;
- if (this.x > document.documentElement.clientWidth - this.config.width) this.x = document.documentElement.clientWidth - this.config.width;
- if (this.y > document.documentElement.clientHeight - this.config.height) this.y = document.documentElement.clientHeight - this.config.height;
+ if (this.x > document.documentElement.clientWidth - this.config.minWidth) this.x = document.documentElement.clientWidth - this.config.minWidth;
+ if (this.y > document.documentElement.clientHeight - this.config.minHeight) this.y = document.documentElement.clientHeight - this.config.minHeight;
this.wnd.style.top = this.y + "px";
this.wnd.style.left = this.x + "px";
}
diff --git a/webapp/src/ts/client.ts b/webapp/src/ts/client.ts
index e701bae..377c850 100644
--- a/webapp/src/ts/client.ts
+++ b/webapp/src/ts/client.ts
@@ -35,6 +35,11 @@ export interface APIAgentInfo {
filename: string;
}
+export interface MOTD {
+ version: number;
+ html: string;
+}
+
export class MSAgentClient {
private url: string;
private socket: WebSocket | null;
@@ -66,6 +71,21 @@ export class MSAgentClient {
return (await res.json()) as APIAgentInfo[];
}
+ async getMotd(): Promise {
+ let res = await fetch(this.url + "/api/motd/version");
+ let vs = await res.text();
+ let version = parseInt(vs);
+ if (isNaN(version)) {
+ throw new Error("Version was NaN");
+ }
+ res = await fetch(this.url + "/api/motd/html");
+ let html = await res.text();
+ return {
+ version,
+ html
+ };
+ }
+
getUsers() {
return this.users;
}
diff --git a/webapp/src/ts/main.ts b/webapp/src/ts/main.ts
index 63943f9..67c8001 100644
--- a/webapp/src/ts/main.ts
+++ b/webapp/src/ts/main.ts
@@ -4,6 +4,10 @@ import { MSAgentClient } from "./client.js";
const elements = {
+ motdWindow: document.getElementById("motdWindow") as HTMLDivElement,
+ motdContainer: document.getElementById("motdContainer") as HTMLDivElement,
+ rulesLink: document.getElementById("rulesLink") as HTMLAnchorElement,
+
logonView: document.getElementById("logonView") as HTMLDivElement,
logonWindow: document.getElementById("logonWindow") as HTMLDivElement,
logonForm: document.getElementById("logonForm") as HTMLFormElement,
@@ -33,10 +37,16 @@ function roomInit() {
});
}
+let motdWindow = new MSWindow(elements.motdWindow, {
+ minWidth: 600,
+ minHeight: 300,
+ maxWidth: 600,
+ startPosition: MSWindowStartPosition.Center
+});
+
let logonWindow = new MSWindow(elements.logonWindow, {
- width: 500,
- height: 275,
- hasClose: false,
+ minWidth: 500,
+ minHeight: 275,
startPosition: MSWindowStartPosition.Center
});
@@ -81,6 +91,16 @@ document.addEventListener('DOMContentLoaded', async () => {
option.value = agent.filename;
elements.agentSelect.appendChild(option);
}
+ let motd = await Room.getMotd();
+ elements.motdContainer.innerHTML = motd.html;
+ let ver = localStorage.getItem("msagent-chat-motd-version");
+ if (!ver || parseInt(ver) !== motd.version) {
+ motdWindow.show();
+ localStorage.setItem("msagent-chat-motd-version", motd.version.toString());
+ }
+ elements.rulesLink.addEventListener('click', () => {
+ motdWindow.show();
+ })
});
function talk() {