3ccd8ba7cb0024995a79cccc9c643a544e539fa0
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ß [mod] style

Christian Fraß authored 2 years ago

97) 			case "private_message":
98) 			{
99) 				{
100) 					let dom_time: HTMLSpanElement = document.createElement("span");
101) 					dom_time.classList.add("event_time");
102) 					dom_time.textContent = timestring;
103) 					dom_event.appendChild(dom_time);
104) 				}
105) 				{
106) 					let dom_type: HTMLSpanElement = document.createElement("span");
107) 					dom_type.classList.add("event_type");
108) 					dom_type.textContent = 'private';
109) 					dom_event.appendChild(dom_type);
110) 				}
111) 				{
112) 					let dom_sender: HTMLSpanElement = document.createElement("span");
113) 					dom_sender.classList.add("event_sender");
114) 					dom_sender.style.color = get_usercolor(event["data"]["from"] ?? "");
115) 					dom_sender.textContent = event["data"]["from"];
116) 					dom_event.appendChild(dom_sender);
117) 				}
118) 				{
119) 					let dom_message: HTMLSpanElement = document.createElement("span");
120) 					dom_message.classList.add("event_message");
121) 					dom_message.textContent = event["data"]["message"];
122) 					dom_event.appendChild(dom_message);
123) 				}
124) 				break;
125) 			}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

127) 			{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

128) 				{
Christian Fraß [mod] style

Christian Fraß authored 2 years ago

129) 					let dom_time: HTMLSpanElement = document.createElement("span");
Christian Fraß [ini]

Christian Fraß authored 2 years ago

130) 					dom_time.classList.add("event_time");
131) 					dom_time.textContent = timestring;
132) 					dom_event.appendChild(dom_time);
133) 				}
134) 				{
Christian Fraß [mod] style

Christian Fraß authored 2 years ago

135) 					let dom_sender: HTMLSpanElement = document.createElement("span");
Christian Fraß [ini]

Christian Fraß authored 2 years ago

136) 					dom_sender.classList.add("event_sender");
137) 					dom_sender.style.color = get_usercolor(event["data"]["from"] ?? "");
138) 					dom_sender.textContent = event["data"]["from"];
139) 					dom_event.appendChild(dom_sender);
140) 				}
141) 				{
Christian Fraß [mod] style

Christian Fraß authored 2 years ago

142) 					let dom_message: HTMLSpanElement = document.createElement("span");
Christian Fraß [ini]

Christian Fraß authored 2 years ago

143) 					dom_message.classList.add("event_message");
144) 					dom_message.textContent = event["data"]["message"];
145) 					dom_event.appendChild(dom_message);
146) 				}
147) 				break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

148) 			}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

151) 	}
Christian Fraß [mod] style

Christian Fraß authored 2 years ago

152) 	if (events.length > 0)
153) 	{
154) 		dom_events.scrollTo(0, dom_events["scrollTopMax"]);
155) 	}
156) 	else
157) 	{
158) 		// do nothing
159) 	}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

160) }
161) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

162) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

167) 	const users_sorted: Array<{name: string; role: string;}> = users.sort
168) 	(
169) 		(x, y) =>
170) 		(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

171) 			(x.role >= y.role)
172) 			? -1
173) 			: (
174) 				(x.role === y.role)
175) 				? ((x.name < y.name) ? -1 : +1)
176) 				: +1
177) 			)
178) 		)
179) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

180) 	for (const user of users_sorted)
181) 	{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

182) 		let dom_user: HTMLLIElement = document.createElement("li");
183) 		dom_user.classList.add("user");
184) 		{
185) 			let dom_role: HTMLSpanElement = document.createElement("span");
186) 			dom_role.textContent = user.role;
187) 			dom_user.appendChild(dom_role);
188) 		}
189) 		{
190) 			let dom_name: HTMLSpanElement = document.createElement("span");
191) 			dom_name.textContent = user.name;
192) 			dom_name.style.color = get_usercolor(user.name);
193) 			dom_user.appendChild(dom_name);
194) 		}
195) 		dom_users.appendChild(dom_user);
196) 	}
197) }
198) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

203) 	update_state();
204) }
205) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

206) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

207) function setup_view(): void
208) {
209) 	document.querySelector<HTMLInputElement>("#channel").value = _conf["irc"]["predefined_channel"];
210) 	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

211) 	setInterval
212) 	(
213) 		async () =>
214) 		{
215) 			switch (_model.state)
216) 			{
217) 				default:
218) 				{
219) 					throw (new Error("invalid state: " + _model.state));
220) 					break;
221) 				}
222) 				case enum_state.offline:
223) 				{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

226) 				}
227) 				case enum_state.connecting:
228) 				{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

230) 					if (ready)
231) 					{
232) 						set_state(enum_state.online);
233) 					}
234) 					else
235) 					{
236) 						// do nothing
Christian Fraß [ini]

Christian Fraß authored 2 years ago

237) 					}
238) 					break;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

239) 				}
240) 				case enum_state.online:
241) 				{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

243) 					update_events(stuff["events"]);
244) 					const usershash: string = btoa(JSON.stringify(stuff["users"]));
245) 					if (_model.usershash !== usershash)
246) 					{
247) 						_model.usershash = usershash;
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

250) 					else
251) 					{
252) 						// do nothing
253) 					}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

255) 				}
Christian Fraß [ini]

Christian Fraß authored 2 years ago

256) 			}
257) 		},
258) 		_conf["settings"]["poll_interval_in_milliseconds"]
259) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

261) }
262) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

263) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

269) 		async (event) =>
270) 		{
Christian Fraß [mod] minor adjustments

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

272) 			let dom_nickname: HTMLInputElement = document.querySelector<HTMLInputElement>("#nickname");
273) 			let dom_channel: HTMLInputElement = document.querySelector<HTMLInputElement>("#channel");
274) 			const nickname: string = dom_nickname.value;
275) 			const channel: string = dom_channel.value;
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

276) 			const connection_id: string = await backend_call
277) 			(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

278) 				"connect",
279) 				{
280) 					"server": _conf["irc"]["server"],
281) 					"channels": [channel],
282) 					"nickname": nickname,
283) 				}
284) 			);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

285) 			_model.connection_id = connection_id;
286) 			_model.channel = channel;
287) 			_model.nickname = nickname;
288) 			set_state(enum_state.connecting);
Christian Fraß [ini]

Christian Fraß authored 2 years ago

289) 		}
290) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

291) 	document.querySelector("#disconnect").addEventListener
292) 	(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

294) 		async (event) =>
295) 		{
296) 			await backend_call
297) 			(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

298) 				"disconnect",
299) 				null
300) 			);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

303) 		}
304) 	);
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

308) 		async (event) =>
309) 		{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

310) 			event.preventDefault();
311) 			let dom_message: HTMLInputElement = document.querySelector<HTMLInputElement>("#message");
312) 			const message: string = dom_message.value;
313) 			dom_message.value = "";
314) 			dom_message.focus();
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

315) 			const event_: any =
316) 			{
Christian Fraß [ini]

Christian Fraß authored 2 years ago

317) 				"timestamp": get_timestamp(),
318) 				"kind": "channel_message",
319) 				"data": {
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

322) 					"message": message,
323) 				}
324) 			};
Christian Fraß [mod] pack model stuff into...

Christian Fraß authored 2 years ago

325) 			update_events([event_]);
326) 			await backend_call
327) 			(
328) 				"send",
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

331) 					"message": message,
332) 				}
333) 			);
334) 		}
335) 	);
336) }
337) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

338) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

339) async function main(): Promise<void>
340) {
341) 	_conf = await fetch("conf.json").then(x => x.json());
342) 	setup_view();
343) 	setup_control();
344) }
345) 
Christian Fraß [mod] adjustment for connec...

Christian Fraß authored 2 years ago

346) 
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

349) 	document.addEventListener
350) 	(
Christian Fraß [ini]

Christian Fraß authored 2 years ago

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

Christian Fraß authored 2 years ago

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