a11d59a1520e91e650827da076506f9c71ce9794
Christian Fraß [ini]

Christian Fraß authored 2 years ago

1) type int = number;
2) type float = number;
3) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

4) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

5) var _conf: any = null;
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

6) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

7) 
8) function get_timestamp(): int
9) {
10) 	return Math.floor(Date.now()/1000);
11) }
12) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

13) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

14) function hash_string_to_unit(x: string): float
15) {
16) 	return (x.split("").reduce((x, y) => ((x + y.charCodeAt(0)) % 32), 0) / 32);
17) }
18) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

19) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

20) function get_usercolor(name: string): string
21) {
22) 	const hue: float = hash_string_to_unit(name);
23) 	return `hsl(${(hue*360).toFixed(2)},50%,75%)`;
24) }
25) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

26) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

27) async function backend_call(action: string, data: any): Promise<any>
28) {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

29) 	const response = await fetch
30) 	(
Christian Fraß [mod] minor adjustments

Christian Fraß authored 2 years ago

31) 		`${_conf["backend"]["scheme"]}://${_conf["backend"]["host"]}:${_conf["backend"]["port"].toFixed(0)}/${_conf["backend"]["path"]}`,
Christian Fraß [ini]

Christian Fraß authored 2 years ago

32) 		{
33) 			"method": "POST",
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

34) 			"body": JSON.stringify({"action": action, "id": _model.connection_id, "data": data}),
Christian Fraß [ini]

Christian Fraß authored 2 years ago

35) 		}
36) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

37) 	if (response.ok)
38) 	{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

39) 		return response.json();
40) 	}
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

41) 	else
42) 	{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

43) 		console.error(response.text());
44) 		return Promise.reject<any>(new Error("backend call failed"));
45) 	}
46) }
47) 
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

48) enum enum_state
49) {
50) 	offline = "offline",
51) 	connecting = "connecting",
52) 	online = "online",
53) }
54) 
55) 
56) type type_model =
57) {
58) 	state: enum_state;
59) 	channel: (null | string);
60) 	nickname: (null | string);
61) 	connection_id: (null | string);
62) 	usershash: (null | string);
63) };
64) 
65) 
66) var _model: type_model =
67) {
68) 	"state": enum_state.offline,
69) 	"channel": null,
70) 	"nickname": null,
71) 	"connection_id": null,
72) 	"usershash": null,
73) };
74) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

75) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

76) function update_state(): void
77) {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

78) 	document.querySelector("body").setAttribute("class", _model.state);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

79) }
80) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

81) 
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

82) function update_events(events): void
Christian Fraß [ini]

Christian Fraß authored 2 years ago

83) {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

84) 	let dom_events: HTMLUListElement = document.querySelector("#events");
85) 	for (const event of events)
86) 	{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

87) 		const timestring: string = (new Date(event["timestamp"]*1000)).toISOString().slice(11, 19);
88) 		let dom_event: HTMLLIElement = document.createElement("li");
89) 		dom_event.classList.add("event");
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

90) 		switch (event["kind"])
91) 		{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

92) 			default:
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

93) 			{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

94) 				dom_event.textContent = ("-- unhandled event: " + JSON.stringify(event));
95) 				break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

96) 			}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

97) 			case "channel_message":
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

98) 			{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

99) 				{
100) 					let dom_time: HTMLDivElement = document.createElement("div");
101) 					dom_time.classList.add("event_time");
102) 					dom_time.textContent = timestring;
103) 					dom_event.appendChild(dom_time);
104) 				}
105) 				{
106) 					let dom_sender: HTMLDivElement = document.createElement("div");
107) 					dom_sender.classList.add("event_sender");
108) 					dom_sender.style.color = get_usercolor(event["data"]["from"] ?? "");
109) 					dom_sender.textContent = event["data"]["from"];
110) 					dom_event.appendChild(dom_sender);
111) 				}
112) 				{
113) 					let dom_message: HTMLDivElement = document.createElement("div");
114) 					dom_message.classList.add("event_message");
115) 					dom_message.textContent = event["data"]["message"];
116) 					dom_event.appendChild(dom_message);
117) 				}
118) 				break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

119) 			}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

120) 		}
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

121) 		dom_events.appendChild(dom_event);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

122) 	}
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

123) 	dom_events.scrollTo(0, dom_events["scrollTopMax"]);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

124) }
125) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

126) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

127) function update_users(users: Array<{name: string; role: string;}>): void
128) {
129) 	let dom_users: HTMLUListElement = document.querySelector("#users");
130) 	dom_users.textContent = "";
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

131) 	const users_sorted: Array<{name: string; role: string;}> = users.sort
132) 	(
133) 		(x, y) =>
134) 		(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

135) 			(x.role >= y.role)
136) 			? -1
137) 			: (
138) 				(x.role === y.role)
139) 				? ((x.name < y.name) ? -1 : +1)
140) 				: +1
141) 			)
142) 		)
143) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

144) 	for (const user of users_sorted)
145) 	{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

146) 		let dom_user: HTMLLIElement = document.createElement("li");
147) 		dom_user.classList.add("user");
148) 		{
149) 			let dom_role: HTMLSpanElement = document.createElement("span");
150) 			dom_role.textContent = user.role;
151) 			dom_user.appendChild(dom_role);
152) 		}
153) 		{
154) 			let dom_name: HTMLSpanElement = document.createElement("span");
155) 			dom_name.textContent = user.name;
156) 			dom_name.style.color = get_usercolor(user.name);
157) 			dom_user.appendChild(dom_name);
158) 		}
159) 		dom_users.appendChild(dom_user);
160) 	}
161) }
162) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

163) 
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

164) function set_state(state: enum_state): void
Christian Fraß [ini]

Christian Fraß authored 2 years ago

165) {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

166) 	_model.state = state;
Christian Fraß [ini]

Christian Fraß authored 2 years ago

167) 	update_state();
168) }
169) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

170) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

171) function setup_view(): void
172) {
173) 	document.querySelector<HTMLInputElement>("#channel").value = _conf["irc"]["predefined_channel"];
174) 	document.querySelector<HTMLInputElement>("#nickname").value = (_conf["irc"]["predefined_nickname_prefix"] + (Math.random()*100).toFixed(0));
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

175) 	setInterval
176) 	(
177) 		async () =>
178) 		{
179) 			switch (_model.state)
180) 			{
181) 				default:
182) 				{
183) 					throw (new Error("invalid state: " + _model.state));
184) 					break;
185) 				}
186) 				case enum_state.offline:
187) 				{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

188) 					// do nothing
189) 					break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

190) 				}
191) 				case enum_state.connecting:
192) 				{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

193) 					const ready: boolean = await backend_call("check", null);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

194) 					if (ready)
195) 					{
196) 						set_state(enum_state.online);
197) 					}
198) 					else
199) 					{
200) 						// do nothing
Christian Fraß [ini]

Christian Fraß authored 2 years ago

201) 					}
202) 					break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

203) 				}
204) 				case enum_state.online:
205) 				{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

206) 					const stuff: any = await backend_call("fetch", null);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

207) 					update_events(stuff["events"]);
208) 					const usershash: string = btoa(JSON.stringify(stuff["users"]));
209) 					if (_model.usershash !== usershash)
210) 					{
211) 						_model.usershash = usershash;
Christian Fraß [ini]

Christian Fraß authored 2 years ago

212) 						update_users(stuff["users"]);
213) 					}
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

214) 					else
215) 					{
216) 						// do nothing
217) 					}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

218) 					break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

219) 				}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

220) 			}
221) 		},
222) 		_conf["settings"]["poll_interval_in_milliseconds"]
223) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

224) 	set_state(enum_state.offline);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

225) }
226) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

227) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

228) function setup_control(): void
229) {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

230) 	document.querySelector("#connect > form").addEventListener
231) 	(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

232) 		"submit",
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

233) 		async (event) =>
234) 		{
Christian Fraß [mod] minor adjustments

Christian Fraß authored 2 years ago

235) 			event.preventDefault();
Christian Fraß [ini]

Christian Fraß authored 2 years ago

236) 			let dom_nickname: HTMLInputElement = document.querySelector<HTMLInputElement>("#nickname");
237) 			let dom_channel: HTMLInputElement = document.querySelector<HTMLInputElement>("#channel");
238) 			const nickname: string = dom_nickname.value;
239) 			const channel: string = dom_channel.value;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

240) 			const connection_id: string = await backend_call
241) 			(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

242) 				"connect",
243) 				{
244) 					"server": _conf["irc"]["server"],
245) 					"channels": [channel],
246) 					"nickname": nickname,
247) 				}
248) 			);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

249) 			_model.connection_id = connection_id;
250) 			_model.channel = channel;
251) 			_model.nickname = nickname;
252) 			set_state(enum_state.connecting);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

253) 		}
254) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

255) 	document.querySelector("#disconnect").addEventListener
256) 	(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

257) 		"click",
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

258) 		async (event) =>
259) 		{
260) 			await backend_call
261) 			(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

262) 				"disconnect",
263) 				null
264) 			);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

265) 			set_state(enum_state.offline);
266) 			_model.connection_id = null;
Christian Fraß [ini]

Christian Fraß authored 2 years ago

267) 		}
268) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

269) 	document.querySelector("#main > form").addEventListener
270) 	(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

271) 		"submit",
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

272) 		async (event) =>
273) 		{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

274) 			event.preventDefault();
275) 			let dom_message: HTMLInputElement = document.querySelector<HTMLInputElement>("#message");
276) 			const message: string = dom_message.value;
277) 			dom_message.value = "";
278) 			dom_message.focus();
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

279) 			const event_: any =
280) 			{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

281) 				"timestamp": get_timestamp(),
282) 				"kind": "channel_message",
283) 				"data": {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

284) 					"from": _model.nickname,
285) 					"to": _model.channel,
Christian Fraß [ini]

Christian Fraß authored 2 years ago

286) 					"message": message,
287) 				}
288) 			};
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

289) 			update_events([event_]);
290) 			await backend_call
291) 			(
292) 				"send",
Christian Fraß [ini]

Christian Fraß authored 2 years ago

293) 				{
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

294) 					"channel": _model.channel,
Christian Fraß [ini]

Christian Fraß authored 2 years ago

295) 					"message": message,
296) 				}
297) 			);
298) 		}
299) 	);
300) }
301) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

302) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

303) async function main(): Promise<void>
304) {
305) 	_conf = await fetch("conf.json").then(x => x.json());
306) 	setup_view();
307) 	setup_control();
308) }
309) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

310) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

311) function init(): void
312) {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

313) 	document.addEventListener
314) 	(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

315) 		"DOMContentLoaded",
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

316) 		(event) => {main();}