all repos — underbbs @ 84d72140fb2b7352e19c5e69ae3753b6e8c2d4e5

decentralized social media client

more boilerplate
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iHUEABYKAB0WIQT/foVVmI9pK13hPWFohAcXSWbK8wUCZkFeRAAKCRBohAcXSWbK
87cuAQDrw+Nm4f5wFY/KowcE9Kt1O3WKSflN3App6l3zq/ZJfAEAsDAj7oSOJyFR
smnUWIXw0fBbHv5q4CpQ+YGr16srJQc=
=1TBC
-----END PGP SIGNATURE-----
commit

84d72140fb2b7352e19c5e69ae3753b6e8c2d4e5

parent

295df2eeec10a8528ef9166c28b1bcb75bbe74dd

6 files changed, 143 insertions(+), 11 deletions(-)

jump to
M adapter/adapter.goadapter/adapter.go

@@ -2,10 +2,13 @@ package adapter

import ( . "forge.lightcrystal.systems/lightcrystal/underbbs/models" + nostr "github.com/nbd-wtf/go-nostr" + "strings" + "context" ) type Adapter interface { - Init(map[string]string, chan Message) error + Init(Settings, chan Message) error Subscribe(string) error SendMessage(Message) error Follow(Author) error

@@ -13,3 +16,48 @@ Unfollow(Author) error

GetFollowers() error UpdateMetadata(interface{}) error } + +type NostrAdapter struct { + msgChan chan Message + nickname string + privkey string + relays []*nostr.Relay +} + +func (self *NostrAdapter) Init(settings Settings, msgChan chan Message) error { + self.nickname = settings.Nickname + self.privkey = *settings.PrivKey + self.msgChan = msgChan + + ctx := context.Background() + + relays := strings.Split(*settings.Relays, ",") + + for _, r := range relays { + pr := nostr.RelayConnect(ctx, strings.Trim(r) + if pr == nil { + return errors.New("Relay connection could not be completed") + } + self.relays = append(self.relays, pr) + } + return nil +} + +func (self *NostrAdapter) Subscribe(filter string) error { + return nil +} +func (self *NostrAdapter) SendMessage(msg Message) error { + return nil +} +func (self *NostrAdapter) Follow(author Author) error { + return nil +} +func (self *NostrAdapter) Unfollow(author Author) error { + return nil +} +func (self *NostrAdapter) GetFollowers() error { + return nil +} +func (self *NostrAdapter) UpdateMetadata(data interface{}) error { + return nil +}
M dist/index.htmldist/index.html

@@ -22,6 +22,7 @@ <li><a href="#" onclick="showSettings()">settings</a></li>

</ul> </nav> <main> + <button id="connectbtn" onclick=">Connect</button> <div id="tabbar"></div> <div id="tabcontent"></div> </main>
A models/settings.go

@@ -0,0 +1,10 @@

+package models + +type Settings struct { + Nickname string + Protocol string + PrivKey *string `json:"privkey",omitempty` + Relays *string `json:"relays",omitempty` + Server *string `json:"server",omitempty` + ApiKey *string `json:"apiKey",omitempty` +}
M server/server.goserver/server.go

@@ -2,10 +2,11 @@ package server

import ( "forge.lightcrystal.systems/lightcrystal/underbbs/models" - "hacklab.nilfm.cc/quartzgun/auth" "hacklab.nilfm.cc/quartzgun/renderer" "net/http" "nhooyr.io/websocket" + "encoding/base64" + "encoding/json" )

@@ -54,6 +55,36 @@ if err != nil {

self.logf("%v", err) return } + + // decode subprotocol data into settings objects + data := c.Subprotocol() + + // base64 decode + decoded, err := base64.StdEncoding.DecodeString(data) + if err != nil { + c.Close(3000, err.Error()) + } + + settings := []models.Settings + // unmarshal the json into the settings array + err := json.Unmarshal([]byte(decoded), &settings) + if (err != nil) { + c.Close(3001, err.Erorr()) + } + + // attempt to initialize adapters + for i, s := range settings { + switch(s.Protocol) { + case "nostr": + break; + case "masto": + break; + default: + break; + } + } + // keep reference to the adapters? + defer c.Close(websocket.StatusInternalError, "") err = self.subscribe(r, c)
M ts/index.tsts/index.ts

@@ -18,7 +18,7 @@ const settings = _("settings", JSON.parse(localStorage.getItem("settings") ?? "{}"));

const adapters = _("adapters", []); if (settings != null) { - for (let s of settings.adapters) { + for (let s of settings.adapters ?? []) { let a: Adapter = Adapter.create() switch (s.protocol) { case "nostr":

@@ -37,8 +37,31 @@ console.log("no settings exist for this client");

_("settings", { adapters: [] }); showSettings(); } + registerServiceWorker(); }; +async function registerServiceWorker() { + if ("serviceWorker" in navigator) { + try { + const registration = await navigator.serviceWorker.register("/serviceWorker.js", { + scope: "/", + }); + if (registration.installing) { + console.log("Service worker installing"); + } else if (registration.waiting) { + console.log("Service worker installed"); + } else if (registration.active) { + console.log("Service worker active"); + } + } catch (error) { + console.error(`Registration failed with ${error}`); + } + const registration = await navigator.serviceWorker.ready; + (registration as any).sync.register("testdata").then((r:any)=>{console.log("but i will see this!")}); + } +}; + + function showSettings():void { // tab bar hidden const tabbar = $("tabbar");

@@ -48,7 +71,7 @@ }

// tabcontent to show settings ui const tabcontent = $("tabcontent"); - const adapters = _("adapters") as Adapter[]; + const adapters = _("adapters") as Adapter[] ?? []; if (tabcontent) { let html = "<p>this is our settings dialogue</p>";

@@ -156,6 +179,9 @@ }

const settings = _("settings"); const adapters = _("adapters"); if (settings && adapters) { + if (!settings.adapters) { + settings.adapters = []; + } settings.adapters.push(self); let a: Adapter = Adapter.create(); switch (self.protocol) {

@@ -171,10 +197,32 @@ showSettings();

} } + +let _conn: WebSocket | null = null; + +function connect() { + // import the data from the settings + const settings = _("settings"); + if (settings) { + + // base64 encode the settings data + let subprotocol: string = "["; + for (let a of settings.adapters) { + subprotocol += JSON.stringify(a) + ","; + } + subprotocol += "]"; + subprotocol = btoa(subprotocol); + // open the websocket connection with settings as subprotocol + + _conn = new WebSocket("/subscribe", subprotocol); + _("websocket", _conn); + } +} + _("addAdapter", addAdapter); _("saveAdapter", saveAdapter); _("fillAdapterProtocolOptions", fillAdapterProtocolOptions); _("showSettings", showSettings); _("saveSettings", saveSettings); - +_("connect", connect); main();
M underbbs.gounderbbs.go

@@ -2,12 +2,6 @@ package main

import ( "context" - "hacklab.nilfm.cc/felt/cmd" - "hacklab.nilfm.cc/felt/config" - "hacklab.nilfm.cc/felt/gametable" - "hacklab.nilfm.cc/felt/mongodb" - "hacklab.nilfm.cc/felt/register" - "hacklab.nilfm.cc/quartzgun/indentalUserDB" "log" "net" "net/http"