underbbs/frontend/ts/settings-element.ts

163 lines
No EOL
5.6 KiB
TypeScript

import util from "./util"
import {DatagramSocket} from "./websocket"
import {Settings} from "./settings"
export class SettingsElement extends HTMLElement {
static observedAttributes = [ "data-adapters" ]
private _adapters: string[] = [];
constructor() {
super();
}
connectedCallback() {
this.attributeChangedCallback();
}
attributeChangedCallback() {
const adapters = this.getAttribute("data-adapters");
if (adapters) {
this._adapters = this.getAttribute("data-adapters")?.split(",") ?? [];
} else {
this._adapters = [];
}
this.showSettings(this)();
}
showSettings(self: SettingsElement): ()=>void {
return ()=>{
let html = "";
html += "<button id='settings_adapter_create_btn'>New</button>";
html += self._adapters.reduce((self: string, a: string) => {
self += `<li><a id='settings_adapter_edit_${a}' href='#editadapter'>${a}</a></li>`
return self;
}, "<ul id='settings_adapterlist'>");
html += "</ul>";
html += "<button id='settings_connect_btn'>connect</button>";
self.innerHTML = html;
let create = util.$("settings_adapter_create_btn");
if (create) {
create.addEventListener("click", self.showCreateAdapter(self), false);
}
for (let a of this._adapters) {
let edit = util.$(`settings_adapter_edit_${a}`);
if (edit) {
edit.addEventListener("click", self.showEditAdapterFunc(a, self), false);
}
}
let connect = util.$("settings_connect_btn");
if (connect) {
connect.addEventListener("click", DatagramSocket.connect, false);
}
}
}
showCreateAdapter(self: SettingsElement): ()=>void {
return ()=>{
// dropdown for protocol
let html = "<select id='settings_newadapter_protocolselect'>";
html += [ "nostr", "mastodon", "misskey" ].reduce((self, p)=>{
self += `<option value='${p}'>${p}</option>`;
return self;
}, "");
html += "</select>";
// nostr is the first protocol, so show its options by default
html += "<div id='settings_newadapter_protocoloptions'>";
html += " <label>nickname<input id='settings_newadapter_nickname'/></label>";
html += " <label>privkey<input id='settings_newadapter_nostr_privkey'/></label>";
html += " <label>default relays<input id='settings_newadapter_nostr_default_relays'/></label>";
html += "</div>";
html += "<button id='settings_adapter_create_save_btn'>add</button>";
html += "<button id='settings_adapter_create_back_btn'>back</button>";
self.innerHTML = html;
let protocolSelect = util.$("settings_newadapter_protocolselect");
if (protocolSelect) {
protocolSelect.addEventListener("change", self.fillAdapterProtocolOptions, false);
}
let save = util.$("settings_adapter_create_save_btn");
if (save) {
save.addEventListener("click", self.saveAdapter(self), false);
}
let back = util.$("settings_adapter_create_back_btn");
if (back) {
back.addEventListener("click", self.showSettings(self), false);
}
}
}
saveAdapter(self: SettingsElement): ()=>void {
return ()=>{
let adapterdata: any = {};
// get selected adapter protocol
const proto = util.$("settings_newadapter_protocolselect") as HTMLSelectElement;
const nickname = (util.$("settings_newadapter_nickname") as HTMLInputElement)?.value ?? "" ;
// switch protocol
switch (proto.options[proto.selectedIndex].value) {
case "nostr":
const privkey = (util.$("settings_newadapter_nostr_privkey") as HTMLInputElement)?.value ?? "";
const relays = (util.$("settings_newadapter_nostr_default_relays") as HTMLInputElement)?.value ?? "";
adapterdata = { nickname: nickname, protocol: "nostr", privkey: privkey, relays: relays.split(",").map(r=>r.trim()) };
break;
case "mastodon":
case "misskey":
const server = (util.$("settings_newadapter_masto_server") as HTMLInputElement)?.value ?? "";
const apiKey = (util.$("settings_newadapter_masto_apikey") as HTMLInputElement)?.value ?? "";
adapterdata = { nickname: nickname, protocol: proto.options[proto.selectedIndex].value, server: server, apiKey: apiKey };
break;
}
const settings = Settings._instance;
if (settings) {
if (!settings.adapters) {
settings.adapters = [];
}
settings.adapters.push(adapterdata);
self._adapters.push(adapterdata.nickname);
localStorage.setItem("settings", JSON.stringify(settings));
self.showSettings(self)();
}
}
}
fillAdapterProtocolOptions() {
const proto = util.$("settings_newadapter_protocolselect") as HTMLSelectElement;
let html = "";
switch(proto?.options[proto.selectedIndex].value) {
case "nostr":
html += " <label>nickname<input id='settings_newadapter_nickname'/></label>";
html += " <label>privkey<input id='settings_newadapter_nostr_privkey'/></label>";
html += " <label>default relays<input id='settings_newadapter_nostr_default_relays'/></label>";
break;
case "mastodon":
case "misskey":
html += " <label>nickname<input id='settings_newadapter_nickname'/></label>";
html += " <label>server<input id='settings_newadapter_masto_server'/></label>";
html += " <label>API key<input id='settings_newadapter_masto_apikey'/></label>";
break;
}
const div = util.$("settings_newadapter_protocoloptions");
if (div) {
div.innerHTML = html;
}
}
showEditAdapterFunc(adapter: string, self: SettingsElement): ()=>void {
// this UI has to be able to edit an exiting adapter or delete it
return ()=>{};
}
}