improve mailboxes
This commit is contained in:
@@ -16,7 +16,7 @@ The UDN project aims to provide decentralized and localhost-able infrastructure
|
|||||||
- [Getting Started](#getting-started)
|
- [Getting Started](#getting-started)
|
||||||
- [Configuration](#configuration)
|
- [Configuration](#configuration)
|
||||||
- [TLS](#tls)
|
- [TLS](#tls)
|
||||||
- [Connecting multiple servers](#connecting-multiple-servers)
|
- [Connecting Multiple Servers](#connecting-multiple-servers)
|
||||||
- [App Developer's Guide](#app-developers-guide)
|
- [App Developer's Guide](#app-developers-guide)
|
||||||
- [Guidelines](#guidelines)
|
- [Guidelines](#guidelines)
|
||||||
- [The Recommended Way](#the-recommended-way)
|
- [The Recommended Way](#the-recommended-way)
|
||||||
@@ -204,7 +204,7 @@ In local networks, you will likely need co create a self-signed certificate. Thi
|
|||||||
2. Create the certificate with `openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365`. This command will ask you a few questions and create the files required by your server.
|
2. Create the certificate with `openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365`. This command will ask you a few questions and create the files required by your server.
|
||||||
3. Provide the passphrase via the `TLS_PASSPHRASE` environment variable (i.e. `export TLS_PASSPHRASE="my-securepass-phrase"`);
|
3. Provide the passphrase via the `TLS_PASSPHRASE` environment variable (i.e. `export TLS_PASSPHRASE="my-securepass-phrase"`);
|
||||||
|
|
||||||
## Connecting multiple servers
|
## Connecting Multiple Servers
|
||||||
|
|
||||||
1. Add the WebSocket addresses of servers you want to connect to the `connectedServers` array in the configuration file.
|
1. Add the WebSocket addresses of servers you want to connect to the `connectedServers` array in the configuration file.
|
||||||
2. Add secondary channels to the `subscribedChannels` array in the configuration file.
|
2. Add secondary channels to the `subscribedChannels` array in the configuration file.
|
||||||
|
|||||||
Binary file not shown.
Vendored
+94
-39
@@ -231,16 +231,18 @@
|
|||||||
// node_modules/udn-frontend/index.ts
|
// node_modules/udn-frontend/index.ts
|
||||||
var UDNFrontend = class {
|
var UDNFrontend = class {
|
||||||
ws;
|
ws;
|
||||||
// handlers
|
// HANDLERS
|
||||||
connectionHandler = () => {
|
connectionHandler = () => {
|
||||||
};
|
};
|
||||||
disconnectionHandler = () => {
|
disconnectionHandler = () => {
|
||||||
};
|
};
|
||||||
messageHandler = (data) => {
|
messageHandler = (data) => {
|
||||||
};
|
};
|
||||||
mailboxHandler = (mailboxId2) => {
|
mailboxHandler = (mailboxId) => {
|
||||||
};
|
};
|
||||||
// init
|
mailboxConnectionHandler = (mailboxId) => {
|
||||||
|
};
|
||||||
|
// INIT
|
||||||
set onconnect(handler) {
|
set onconnect(handler) {
|
||||||
this.connectionHandler = handler;
|
this.connectionHandler = handler;
|
||||||
}
|
}
|
||||||
@@ -253,14 +255,18 @@
|
|||||||
set onmailbox(handler) {
|
set onmailbox(handler) {
|
||||||
this.mailboxHandler = handler;
|
this.mailboxHandler = handler;
|
||||||
}
|
}
|
||||||
// utility methods
|
set onmailboxconnect(handler) {
|
||||||
|
this.mailboxConnectionHandler = handler;
|
||||||
|
}
|
||||||
|
// UTILITY METHODS
|
||||||
send(messageObject) {
|
send(messageObject) {
|
||||||
if (this.ws == void 0) return false;
|
if (this.ws == void 0) return false;
|
||||||
const messageString = JSON.stringify(messageObject);
|
const messageString = JSON.stringify(messageObject);
|
||||||
this.ws.send(messageString);
|
this.ws.send(messageString);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// public methods
|
// PUBLIC METHODS
|
||||||
|
// connection
|
||||||
connect(address) {
|
connect(address) {
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
this.ws = new WebSocket(address);
|
this.ws = new WebSocket(address);
|
||||||
@@ -271,6 +277,8 @@
|
|||||||
const data = JSON.parse(dataString);
|
const data = JSON.parse(dataString);
|
||||||
if (data.assignedMailboxId) {
|
if (data.assignedMailboxId) {
|
||||||
return this.mailboxHandler(data.assignedMailboxId);
|
return this.mailboxHandler(data.assignedMailboxId);
|
||||||
|
} else if (data.connectedMailboxId) {
|
||||||
|
return this.mailboxConnectionHandler(data.assignedMailboxId);
|
||||||
} else {
|
} else {
|
||||||
this.messageHandler(data);
|
this.messageHandler(data);
|
||||||
}
|
}
|
||||||
@@ -279,6 +287,7 @@
|
|||||||
disconnect() {
|
disconnect() {
|
||||||
this.ws?.close();
|
this.ws?.close();
|
||||||
}
|
}
|
||||||
|
// message
|
||||||
sendMessage(channel, body) {
|
sendMessage(channel, body) {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
messageChannel: channel,
|
messageChannel: channel,
|
||||||
@@ -286,6 +295,7 @@
|
|||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
// subscription
|
||||||
subscribe(channel) {
|
subscribe(channel) {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
subscribeChannel: channel
|
subscribeChannel: channel
|
||||||
@@ -298,15 +308,22 @@
|
|||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
// mailbox
|
||||||
requestMailbox() {
|
requestMailbox() {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
requestingMailboxSetup: true
|
requestingMailboxSetup: true
|
||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
accessMailbox(mailboxId2) {
|
connectMailbox(mailboxId) {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
requestedMailbox: mailboxId2
|
requestedMailbox: mailboxId
|
||||||
|
};
|
||||||
|
return this.send(messageObject);
|
||||||
|
}
|
||||||
|
deleteMailbox(mailboxId) {
|
||||||
|
const messageObject = {
|
||||||
|
deletingMailbox: mailboxId
|
||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
@@ -315,7 +332,9 @@
|
|||||||
// src/translations.tsx
|
// src/translations.tsx
|
||||||
var staticTextEnglish = {
|
var staticTextEnglish = {
|
||||||
mailbox: "Mailbox",
|
mailbox: "Mailbox",
|
||||||
requestMailbox: "Request Mailbox",
|
requestMailbox: "Request",
|
||||||
|
deleteMailbox: "Delete",
|
||||||
|
mailboxConnected: "Mailbox connected",
|
||||||
channel: "Channel",
|
channel: "Channel",
|
||||||
channel_placeholder: "my-channel",
|
channel_placeholder: "my-channel",
|
||||||
disconnected: "Server disconnected",
|
disconnected: "Server disconnected",
|
||||||
@@ -339,7 +358,9 @@
|
|||||||
en: staticTextEnglish,
|
en: staticTextEnglish,
|
||||||
es: {
|
es: {
|
||||||
mailbox: "Buz\xF3n",
|
mailbox: "Buz\xF3n",
|
||||||
requestMailbox: "Solicitar buz\xF3n",
|
requestMailbox: "Solicitar",
|
||||||
|
deleteMailbox: "Eliminar",
|
||||||
|
mailboxConnected: "Buz\xF3n conectado",
|
||||||
channel: "Canal",
|
channel: "Canal",
|
||||||
channel_placeholder: "mi-canal",
|
channel_placeholder: "mi-canal",
|
||||||
disconnected: "Sin coneci\xF3n",
|
disconnected: "Sin coneci\xF3n",
|
||||||
@@ -361,7 +382,9 @@
|
|||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
mailbox: "Briefkasten",
|
mailbox: "Briefkasten",
|
||||||
requestMailbox: "Briefkasten beantragen",
|
requestMailbox: "Beantragen",
|
||||||
|
deleteMailbox: "L\xF6schen",
|
||||||
|
mailboxConnected: "Briefkasten verbunden",
|
||||||
channel: "Kanal",
|
channel: "Kanal",
|
||||||
channel_placeholder: "mein-kanal",
|
channel_placeholder: "mein-kanal",
|
||||||
disconnected: "Verbindung getrennt",
|
disconnected: "Verbindung getrennt",
|
||||||
@@ -398,35 +421,9 @@
|
|||||||
}
|
}
|
||||||
id = UUID();
|
id = UUID();
|
||||||
};
|
};
|
||||||
var UDN = new UDNFrontend();
|
|
||||||
UDN.onconnect = () => {
|
|
||||||
isDisconnected.value = false;
|
|
||||||
updateStats();
|
|
||||||
if (mailboxId.value != "") {
|
|
||||||
UDN.accessMailbox(mailboxId.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
UDN.onmessage = (data) => {
|
|
||||||
lastReceivedMessage.value = JSON.stringify(data, null, 4);
|
|
||||||
const { messageChannel, messageBody } = data;
|
|
||||||
if (messageChannel && messageBody) {
|
|
||||||
const messageObject = new Message(messageChannel, messageBody);
|
|
||||||
if (messageBody) messages.add(messageObject);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
UDN.onmailbox = (id) => {
|
|
||||||
mailboxId.value = id;
|
|
||||||
};
|
|
||||||
UDN.ondisconnect = () => {
|
|
||||||
isDisconnected.value = true;
|
|
||||||
setTimeout(connect, 2e3);
|
|
||||||
};
|
|
||||||
function connect() {
|
|
||||||
UDN.connect(`wss://${window.location.host}`);
|
|
||||||
}
|
|
||||||
connect();
|
|
||||||
var isDisconnected = new State(true);
|
var isDisconnected = new State(true);
|
||||||
var mailboxId = restoreState("mailbox-id", "");
|
var storedMailboxId = restoreState("mailbox-id", "");
|
||||||
|
var isMailboxDisonnected = new State(true);
|
||||||
var messages = new ListState();
|
var messages = new ListState();
|
||||||
var lastReceivedMessage = new State(
|
var lastReceivedMessage = new State(
|
||||||
getText("noMessagesReceived")
|
getText("noMessagesReceived")
|
||||||
@@ -451,6 +448,42 @@
|
|||||||
[newMessageChannel, newMessageBody],
|
[newMessageChannel, newMessageBody],
|
||||||
() => newMessageChannel.value == "" || newMessageBody.value == ""
|
() => newMessageChannel.value == "" || newMessageBody.value == ""
|
||||||
);
|
);
|
||||||
|
var UDN = new UDNFrontend();
|
||||||
|
UDN.onconnect = () => {
|
||||||
|
isDisconnected.value = false;
|
||||||
|
updateStats();
|
||||||
|
if (storedMailboxId.value != "") {
|
||||||
|
UDN.connectMailbox(storedMailboxId.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
UDN.onmessage = (data) => {
|
||||||
|
lastReceivedMessage.value = JSON.stringify(data, null, 4);
|
||||||
|
const { messageChannel, messageBody } = data;
|
||||||
|
if (messageChannel && messageBody) {
|
||||||
|
const messageObject = new Message(messageChannel, messageBody);
|
||||||
|
if (messageBody) messages.add(messageObject);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
UDN.onmailbox = (id) => {
|
||||||
|
console.log(id);
|
||||||
|
storedMailboxId.value = id;
|
||||||
|
UDN.connectMailbox(id);
|
||||||
|
};
|
||||||
|
UDN.onmailboxconnect = (id) => {
|
||||||
|
console.log(id);
|
||||||
|
isMailboxDisonnected.value = false;
|
||||||
|
};
|
||||||
|
UDN.ondisconnect = () => {
|
||||||
|
isDisconnected.value = true;
|
||||||
|
isMailboxDisonnected.value = true;
|
||||||
|
setTimeout(connect, 1e3);
|
||||||
|
};
|
||||||
|
function connect() {
|
||||||
|
UDN.connect(
|
||||||
|
`${window.location.protocol.replace("http", "ws")}//${window.location.host}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
connect();
|
||||||
function subscribe() {
|
function subscribe() {
|
||||||
UDN.subscribe(subscriptionChannel.value);
|
UDN.subscribe(subscriptionChannel.value);
|
||||||
}
|
}
|
||||||
@@ -463,8 +496,13 @@
|
|||||||
newMessageBody.value = "";
|
newMessageBody.value = "";
|
||||||
}
|
}
|
||||||
function requestMailbox() {
|
function requestMailbox() {
|
||||||
|
deleteMailbox();
|
||||||
UDN.requestMailbox();
|
UDN.requestMailbox();
|
||||||
}
|
}
|
||||||
|
function deleteMailbox() {
|
||||||
|
console.log("test");
|
||||||
|
UDN.deleteMailbox(storedMailboxId.value);
|
||||||
|
}
|
||||||
|
|
||||||
// src/infoScreen.tsx
|
// src/infoScreen.tsx
|
||||||
function InfoScreen() {
|
function InfoScreen() {
|
||||||
@@ -473,7 +511,24 @@
|
|||||||
|
|
||||||
// src/mainScreen.tsx
|
// src/mainScreen.tsx
|
||||||
function MainScreen() {
|
function MainScreen() {
|
||||||
return /* @__PURE__ */ createElement("article", { id: "main-screen" }, /* @__PURE__ */ createElement("header", null, getText("settings")), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("messageLastReceived")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": lastReceivedMessage }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("mailbox")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": mailboxId }))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement("button", { class: "primary width-100", "on:click": requestMailbox }, getText("requestMailbox"), /* @__PURE__ */ createElement("span", { class: "icon" }, "inbox"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("subscribeToChannel")), /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement("article", { id: "main-screen" }, /* @__PURE__ */ createElement("header", null, getText("settings")), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("messageLastReceived")), /* @__PURE__ */ createElement("p", { class: "secondary", "subscribe:innerText": lastReceivedMessage }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "tile width-input" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, getText("mailbox")), /* @__PURE__ */ createElement("p", { class: "secondary", "toggle:hidden": isMailboxDisonnected }, getText("mailboxConnected")))), /* @__PURE__ */ createElement("div", { class: "flex-row width-input justify-end" }, /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: "danger width-50",
|
||||||
|
"on:click": deleteMailbox,
|
||||||
|
"toggle:disabled": isMailboxDisonnected
|
||||||
|
},
|
||||||
|
getText("deleteMailbox")
|
||||||
|
), /* @__PURE__ */ createElement(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
class: "primary width-50",
|
||||||
|
"on:click": requestMailbox,
|
||||||
|
"toggle:disabled": isDisconnected
|
||||||
|
},
|
||||||
|
getText("requestMailbox"),
|
||||||
|
/* @__PURE__ */ createElement("span", { class: "icon" }, "inbox")
|
||||||
|
)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, getText("subscribeToChannel")), /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
placeholder: getText("channel_placeholder"),
|
placeholder: getText("channel_placeholder"),
|
||||||
|
|||||||
+16
-62
@@ -13,82 +13,36 @@ import UDNFrontend from "udn-frontend";
|
|||||||
|
|
||||||
// setup
|
// setup
|
||||||
const UDN = new UDNFrontend();
|
const UDN = new UDNFrontend();
|
||||||
|
|
||||||
|
// connect
|
||||||
UDN.onconnect = () => {
|
UDN.onconnect = () => {
|
||||||
console.log("connected!");
|
console.log("connected!");
|
||||||
};
|
};
|
||||||
UDN.ondisconnect = () => {
|
UDN.ondisconnect = () => {
|
||||||
console.log("disconnected!");
|
console.log("disconnected!");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UDN.connect("ws://192.168.0.69:1234");
|
||||||
|
UDN.disconnect();
|
||||||
|
|
||||||
|
// messages
|
||||||
UDN.onmessage = (data: Message) => {
|
UDN.onmessage = (data: Message) => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
// do stuff
|
|
||||||
UDN.connect("ws://192.168.0.69:1234");
|
|
||||||
|
|
||||||
UDN.subscribe("my-channel");
|
|
||||||
UDN.sendMessage("my-channel", "Hello, world!");
|
UDN.sendMessage("my-channel", "Hello, world!");
|
||||||
|
|
||||||
|
// subscribe
|
||||||
|
UDN.subscribe("my-channel");
|
||||||
UDN.unsubscribe("my-channel");
|
UDN.unsubscribe("my-channel");
|
||||||
```
|
|
||||||
|
|
||||||
# Type Reference
|
|
||||||
|
|
||||||
```TypeScript
|
|
||||||
export interface Message {
|
|
||||||
// connecting to server
|
|
||||||
requestingServerConnection?: boolean;
|
|
||||||
|
|
||||||
// mailbox
|
// mailbox
|
||||||
requestingMailboxSetup?: boolean;
|
UDN.onmailbox = (mailboxId: string) => {
|
||||||
assignedMailboxId?: string; // sent by server
|
UDN.connectMailbox(mailboxId);
|
||||||
requestedMailbox?: string;
|
}
|
||||||
|
UDN.onmailboxconnect = (mailboxId: string) => {
|
||||||
// subscribing to channel
|
UDN.deleteMailbox(mailboxId);
|
||||||
subscribeChannel?: string;
|
|
||||||
unsubscribeChannel?: string;
|
|
||||||
subscribed?: boolean; // sent by server to confirm subscription
|
|
||||||
|
|
||||||
//sending message
|
|
||||||
messageChannel?: string;
|
|
||||||
messageBody?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class UDNFrontend {
|
UDN.requestMailbox();
|
||||||
ws: WebSocket | undefined;
|
|
||||||
|
|
||||||
// handlers
|
|
||||||
private connectionHandler = () => {};
|
|
||||||
private disconnectionHandler = () => {};
|
|
||||||
private messageHandler = (data: Message) => {};
|
|
||||||
|
|
||||||
// init
|
|
||||||
set onconnect(handler: () => void);
|
|
||||||
set ondisconnect(handler: () => void);
|
|
||||||
set onmessage(handler: (data: Message) => void);
|
|
||||||
|
|
||||||
// methods
|
|
||||||
connect(address: string): void;
|
|
||||||
disconnect(address: string): void;
|
|
||||||
sendMessage(channel: string, body: string): boolean; // true if message is sent
|
|
||||||
subscribe(channel: string): boolean; // true if request is sent, NOT inherently when subscribed
|
|
||||||
unsubscribe(channel: string): boolean; // true if request is sent, NOT inherently when unsubscribed
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Changelog
|
|
||||||
|
|
||||||
## 1.0.1
|
|
||||||
|
|
||||||
- minor fixes
|
|
||||||
|
|
||||||
## 1.0.2
|
|
||||||
|
|
||||||
- minor fixes
|
|
||||||
|
|
||||||
## 1.0.3
|
|
||||||
|
|
||||||
- add `disconnect()` method
|
|
||||||
|
|
||||||
## 1.0.4
|
|
||||||
|
|
||||||
- make ws public
|
|
||||||
+25
-6
@@ -4,8 +4,10 @@ export interface Message {
|
|||||||
|
|
||||||
// mailbox
|
// mailbox
|
||||||
requestingMailboxSetup?: boolean;
|
requestingMailboxSetup?: boolean;
|
||||||
assignedMailboxId?: string; // sent by server
|
|
||||||
requestedMailbox?: string;
|
requestedMailbox?: string;
|
||||||
|
deletingMailbox?: string;
|
||||||
|
assignedMailboxId?: string; // sent by server
|
||||||
|
connectedMailboxId?: string; // sent by server
|
||||||
|
|
||||||
// subscribing to channel
|
// subscribing to channel
|
||||||
subscribeChannel?: string;
|
subscribeChannel?: string;
|
||||||
@@ -20,13 +22,14 @@ export interface Message {
|
|||||||
export default class UDNFrontend {
|
export default class UDNFrontend {
|
||||||
ws: WebSocket | undefined;
|
ws: WebSocket | undefined;
|
||||||
|
|
||||||
// handlers
|
// HANDLERS
|
||||||
private connectionHandler = () => {};
|
private connectionHandler = () => {};
|
||||||
private disconnectionHandler = () => {};
|
private disconnectionHandler = () => {};
|
||||||
private messageHandler = (data: Message) => {};
|
private messageHandler = (data: Message) => {};
|
||||||
private mailboxHandler = (mailboxId: string) => {};
|
private mailboxHandler = (mailboxId: string) => {};
|
||||||
|
private mailboxConnectionHandler = (mailboxId: string) => {};
|
||||||
|
|
||||||
// init
|
// INIT
|
||||||
set onconnect(handler: () => void) {
|
set onconnect(handler: () => void) {
|
||||||
this.connectionHandler = handler;
|
this.connectionHandler = handler;
|
||||||
}
|
}
|
||||||
@@ -39,8 +42,11 @@ export default class UDNFrontend {
|
|||||||
set onmailbox(handler: (mailboxId: string) => void) {
|
set onmailbox(handler: (mailboxId: string) => void) {
|
||||||
this.mailboxHandler = handler;
|
this.mailboxHandler = handler;
|
||||||
}
|
}
|
||||||
|
set onmailboxconnect(handler: (mailboxId: string) => void) {
|
||||||
|
this.mailboxConnectionHandler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
// utility methods
|
// UTILITY METHODS
|
||||||
private send(messageObject: Message): boolean {
|
private send(messageObject: Message): boolean {
|
||||||
if (this.ws == undefined) return false;
|
if (this.ws == undefined) return false;
|
||||||
|
|
||||||
@@ -49,7 +55,8 @@ export default class UDNFrontend {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public methods
|
// PUBLIC METHODS
|
||||||
|
// connection
|
||||||
connect(address: string): void {
|
connect(address: string): void {
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
|
|
||||||
@@ -62,6 +69,8 @@ export default class UDNFrontend {
|
|||||||
|
|
||||||
if (data.assignedMailboxId) {
|
if (data.assignedMailboxId) {
|
||||||
return this.mailboxHandler(data.assignedMailboxId);
|
return this.mailboxHandler(data.assignedMailboxId);
|
||||||
|
} else if (data.connectedMailboxId) {
|
||||||
|
return this.mailboxConnectionHandler(data.assignedMailboxId);
|
||||||
} else {
|
} else {
|
||||||
this.messageHandler(data);
|
this.messageHandler(data);
|
||||||
}
|
}
|
||||||
@@ -72,6 +81,7 @@ export default class UDNFrontend {
|
|||||||
this.ws?.close();
|
this.ws?.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// message
|
||||||
sendMessage(channel: string, body: string): boolean {
|
sendMessage(channel: string, body: string): boolean {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
messageChannel: channel,
|
messageChannel: channel,
|
||||||
@@ -80,6 +90,7 @@ export default class UDNFrontend {
|
|||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subscription
|
||||||
subscribe(channel: string): boolean {
|
subscribe(channel: string): boolean {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
subscribeChannel: channel,
|
subscribeChannel: channel,
|
||||||
@@ -94,6 +105,7 @@ export default class UDNFrontend {
|
|||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mailbox
|
||||||
requestMailbox(): boolean {
|
requestMailbox(): boolean {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
requestingMailboxSetup: true,
|
requestingMailboxSetup: true,
|
||||||
@@ -101,10 +113,17 @@ export default class UDNFrontend {
|
|||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
accessMailbox(mailboxId: string): boolean {
|
connectMailbox(mailboxId: string): boolean {
|
||||||
const messageObject = {
|
const messageObject = {
|
||||||
requestedMailbox: mailboxId,
|
requestedMailbox: mailboxId,
|
||||||
};
|
};
|
||||||
return this.send(messageObject);
|
return this.send(messageObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteMailbox(mailboxId: string): boolean {
|
||||||
|
const messageObject = {
|
||||||
|
deletingMailbox: mailboxId,
|
||||||
|
};
|
||||||
|
return this.send(messageObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "udn-frontend",
|
"name": "udn-frontend",
|
||||||
"version": "1.0.4-beta2",
|
"version": "1.0.4-beta4",
|
||||||
"description": "TypeScript library for UDN apps",
|
"description": "TypeScript library for UDN apps",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bloatless-react": "1.2.5-beta1",
|
"bloatless-react": "1.2.5-beta1",
|
||||||
"esbuild": "latest",
|
"esbuild": "latest",
|
||||||
"udn-frontend": "1.0.4-beta2"
|
"udn-frontend": "1.0.4-beta4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild src/index.tsx --bundle --outdir=dist"
|
"build": "esbuild src/index.tsx --bundle --outdir=dist"
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import * as React from "bloatless-react";
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
deleteMailbox,
|
||||||
|
isDisconnected,
|
||||||
|
isMailboxDisonnected,
|
||||||
isMessageEmpty,
|
isMessageEmpty,
|
||||||
lastReceivedMessage,
|
lastReceivedMessage,
|
||||||
mailboxId,
|
|
||||||
newMessageBody,
|
newMessageBody,
|
||||||
newMessageChannel,
|
newMessageChannel,
|
||||||
requestMailbox,
|
requestMailbox,
|
||||||
@@ -33,12 +35,25 @@ export function MainScreen() {
|
|||||||
<div class="tile width-input">
|
<div class="tile width-input">
|
||||||
<div>
|
<div>
|
||||||
<b>{getText("mailbox")}</b>
|
<b>{getText("mailbox")}</b>
|
||||||
<p class="secondary" subscribe:innerText={mailboxId}></p>
|
<p class="secondary" toggle:hidden={isMailboxDisonnected}>
|
||||||
|
{getText("mailboxConnected")}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-row width-input justify-end">
|
<div class="flex-row width-input justify-end">
|
||||||
<button class="primary width-100" on:click={requestMailbox}>
|
<button
|
||||||
|
class="danger width-50"
|
||||||
|
on:click={deleteMailbox}
|
||||||
|
toggle:disabled={isMailboxDisonnected}
|
||||||
|
>
|
||||||
|
{getText("deleteMailbox")}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="primary width-50"
|
||||||
|
on:click={requestMailbox}
|
||||||
|
toggle:disabled={isDisconnected}
|
||||||
|
>
|
||||||
{getText("requestMailbox")}
|
{getText("requestMailbox")}
|
||||||
<span class="icon">inbox</span>
|
<span class="icon">inbox</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
+54
-36
@@ -9,45 +9,11 @@ export class Message implements React.Identifiable {
|
|||||||
constructor(public channel: string, public body: string) {}
|
constructor(public channel: string, public body: string) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDN Frontend
|
|
||||||
const UDN = new UDNFrontend();
|
|
||||||
|
|
||||||
UDN.onconnect = () => {
|
|
||||||
isDisconnected.value = false;
|
|
||||||
updateStats();
|
|
||||||
if (mailboxId.value != "") {
|
|
||||||
UDN.accessMailbox(mailboxId.value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UDN.onmessage = (data) => {
|
|
||||||
lastReceivedMessage.value = JSON.stringify(data, null, 4);
|
|
||||||
|
|
||||||
const { messageChannel, messageBody } = data;
|
|
||||||
if (messageChannel && messageBody) {
|
|
||||||
const messageObject = new Message(messageChannel, messageBody);
|
|
||||||
if (messageBody) messages.add(messageObject);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UDN.onmailbox = (id) => {
|
|
||||||
mailboxId.value = id;
|
|
||||||
};
|
|
||||||
|
|
||||||
UDN.ondisconnect = () => {
|
|
||||||
isDisconnected.value = true;
|
|
||||||
setTimeout(connect, 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
function connect() {
|
|
||||||
UDN.connect(`wss://${window.location.host}`);
|
|
||||||
}
|
|
||||||
connect();
|
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
// connection
|
// connection
|
||||||
export const isDisconnected = new React.State(true);
|
export const isDisconnected = new React.State(true);
|
||||||
export const mailboxId = React.restoreState("mailbox-id", "");
|
export const storedMailboxId = React.restoreState("mailbox-id", "");
|
||||||
|
export const isMailboxDisonnected = new React.State(true);
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
export const messages = new React.ListState<Message>();
|
export const messages = new React.ListState<Message>();
|
||||||
@@ -87,6 +53,52 @@ export const isMessageEmpty = React.createProxyState(
|
|||||||
() => newMessageChannel.value == "" || newMessageBody.value == ""
|
() => newMessageChannel.value == "" || newMessageBody.value == ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// UDN Frontend
|
||||||
|
const UDN = new UDNFrontend();
|
||||||
|
|
||||||
|
UDN.onconnect = () => {
|
||||||
|
isDisconnected.value = false;
|
||||||
|
updateStats();
|
||||||
|
|
||||||
|
if (storedMailboxId.value != "") {
|
||||||
|
UDN.connectMailbox(storedMailboxId.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UDN.onmessage = (data) => {
|
||||||
|
lastReceivedMessage.value = JSON.stringify(data, null, 4);
|
||||||
|
|
||||||
|
const { messageChannel, messageBody } = data;
|
||||||
|
if (messageChannel && messageBody) {
|
||||||
|
const messageObject = new Message(messageChannel, messageBody);
|
||||||
|
if (messageBody) messages.add(messageObject);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UDN.onmailbox = (id) => {
|
||||||
|
console.log(id);
|
||||||
|
storedMailboxId.value = id;
|
||||||
|
UDN.connectMailbox(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
UDN.onmailboxconnect = (id) => {
|
||||||
|
console.log(id);
|
||||||
|
isMailboxDisonnected.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
UDN.ondisconnect = () => {
|
||||||
|
isDisconnected.value = true;
|
||||||
|
isMailboxDisonnected.value = true;
|
||||||
|
setTimeout(connect, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
UDN.connect(
|
||||||
|
`${window.location.protocol.replace("http", "ws")}//${window.location.host}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
connect();
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
export function subscribe() {
|
export function subscribe() {
|
||||||
UDN.subscribe(subscriptionChannel.value);
|
UDN.subscribe(subscriptionChannel.value);
|
||||||
@@ -103,5 +115,11 @@ export function sendMessage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function requestMailbox() {
|
export function requestMailbox() {
|
||||||
|
deleteMailbox();
|
||||||
UDN.requestMailbox();
|
UDN.requestMailbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function deleteMailbox() {
|
||||||
|
console.log("test");
|
||||||
|
UDN.deleteMailbox(storedMailboxId.value);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// STATIC
|
// STATIC
|
||||||
export const staticTextEnglish = {
|
export const staticTextEnglish = {
|
||||||
mailbox: "Mailbox",
|
mailbox: "Mailbox",
|
||||||
requestMailbox: "Request Mailbox",
|
requestMailbox: "Request",
|
||||||
|
deleteMailbox: "Delete",
|
||||||
|
mailboxConnected: "Mailbox connected",
|
||||||
channel: "Channel",
|
channel: "Channel",
|
||||||
channel_placeholder: "my-channel",
|
channel_placeholder: "my-channel",
|
||||||
disconnected: "Server disconnected",
|
disconnected: "Server disconnected",
|
||||||
@@ -26,7 +28,9 @@ export const translations: { [key: string]: typeof staticTextEnglish } = {
|
|||||||
en: staticTextEnglish,
|
en: staticTextEnglish,
|
||||||
es: {
|
es: {
|
||||||
mailbox: "Buzón",
|
mailbox: "Buzón",
|
||||||
requestMailbox: "Solicitar buzón",
|
requestMailbox: "Solicitar",
|
||||||
|
deleteMailbox: "Eliminar",
|
||||||
|
mailboxConnected: "Buzón conectado",
|
||||||
channel: "Canal",
|
channel: "Canal",
|
||||||
channel_placeholder: "mi-canal",
|
channel_placeholder: "mi-canal",
|
||||||
disconnected: "Sin coneción",
|
disconnected: "Sin coneción",
|
||||||
@@ -48,7 +52,9 @@ export const translations: { [key: string]: typeof staticTextEnglish } = {
|
|||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
mailbox: "Briefkasten",
|
mailbox: "Briefkasten",
|
||||||
requestMailbox: "Briefkasten beantragen",
|
requestMailbox: "Beantragen",
|
||||||
|
deleteMailbox: "Löschen",
|
||||||
|
mailboxConnected: "Briefkasten verbunden",
|
||||||
channel: "Kanal",
|
channel: "Kanal",
|
||||||
channel_placeholder: "mein-kanal",
|
channel_placeholder: "mein-kanal",
|
||||||
disconnected: "Verbindung getrennt",
|
disconnected: "Verbindung getrennt",
|
||||||
|
|||||||
+23
-7
@@ -14,14 +14,21 @@ export interface Subscriber {
|
|||||||
export class Mailbox implements Subscriber {
|
export class Mailbox implements Subscriber {
|
||||||
// basic data
|
// basic data
|
||||||
id = Crypto.randomUUID();
|
id = Crypto.randomUUID();
|
||||||
dateLastChecked = new Date();
|
dateLastUsed = new Date();
|
||||||
|
|
||||||
get expiryDate() {
|
get expiryDate() {
|
||||||
const expiryDate = new Date(this.dateLastChecked);
|
const expiryDate = new Date(this.dateLastUsed);
|
||||||
expiryDate.setDate(expiryDate.getDate() + 7);
|
expiryDate.setDate(expiryDate.getDate() + 7);
|
||||||
return expiryDate;
|
return expiryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isExpired() {
|
||||||
|
if (this.ws) return false;
|
||||||
|
|
||||||
|
const today = new Date();
|
||||||
|
return this.expiryDate < today;
|
||||||
|
}
|
||||||
|
|
||||||
// init
|
// init
|
||||||
constructor(ws: WS) {
|
constructor(ws: WS) {
|
||||||
this.ws = ws;
|
this.ws = ws;
|
||||||
@@ -39,6 +46,17 @@ export class Mailbox implements Subscriber {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
confirmConnection(): void {
|
||||||
|
if (!this.ws) return;
|
||||||
|
|
||||||
|
sendWebSocketMessage(
|
||||||
|
{
|
||||||
|
connectedMailboxId: this.id,
|
||||||
|
},
|
||||||
|
this.ws
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// storage
|
// storage
|
||||||
messages = new Set<string>();
|
messages = new Set<string>();
|
||||||
|
|
||||||
@@ -51,8 +69,9 @@ export class Mailbox implements Subscriber {
|
|||||||
|
|
||||||
set ws(ws: WS) {
|
set ws(ws: WS) {
|
||||||
this._ws = ws;
|
this._ws = ws;
|
||||||
this.dateLastChecked = new Date();
|
this.dateLastUsed = new Date();
|
||||||
|
|
||||||
|
this.confirmConnection();
|
||||||
this.sendUnreadMessages();
|
this.sendUnreadMessages();
|
||||||
|
|
||||||
const channels = subscriptionMap.getChannelList(ws);
|
const channels = subscriptionMap.getChannelList(ws);
|
||||||
@@ -66,14 +85,11 @@ export class Mailbox implements Subscriber {
|
|||||||
subscriptionMap.set(this, channelName);
|
subscriptionMap.set(this, channelName);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsubscribe(channelName: string): void {
|
|
||||||
subscriptionMap.delete(this, channelName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sending
|
// sending
|
||||||
send(message: string): void {
|
send(message: string): void {
|
||||||
if (this._ws?.readyState == 1) {
|
if (this._ws?.readyState == 1) {
|
||||||
this._ws.send(message);
|
this._ws.send(message);
|
||||||
|
this.dateLastUsed = new Date();
|
||||||
} else {
|
} else {
|
||||||
this.messages.add(message);
|
this.messages.add(message);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-17
@@ -1,14 +1,11 @@
|
|||||||
import { Mailbox, Subscriber } from "./subscriptionHandler";
|
|
||||||
import { PACKAGE_FILE, STATIC_DIR, WS } from ".";
|
import { PACKAGE_FILE, STATIC_DIR, WS } from ".";
|
||||||
import {
|
|
||||||
WebSocketMessage,
|
|
||||||
mailboxIdsPerClient,
|
|
||||||
mailboxes,
|
|
||||||
} from "./websocket-handler";
|
|
||||||
|
|
||||||
import Colors from "colors";
|
import Colors from "colors";
|
||||||
import Fs from "fs/promises";
|
import Fs from "fs/promises";
|
||||||
import Path from "path";
|
import Path from "path";
|
||||||
|
import {
|
||||||
|
WebSocketMessage,
|
||||||
|
} from "./websocket-handler";
|
||||||
|
|
||||||
// CONFIG
|
// CONFIG
|
||||||
const STAT_INDENT = 25;
|
const STAT_INDENT = 25;
|
||||||
@@ -70,14 +67,3 @@ export function stringifyMessage(messageObject: WebSocketMessage): string {
|
|||||||
export function parseMessage(messageString: string): Object {
|
export function parseMessage(messageString: string): Object {
|
||||||
return JSON.parse(messageString);
|
return JSON.parse(messageString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBSCRIBERS
|
|
||||||
export function getMailboxIfExists(ws: WS): Mailbox | undefined {
|
|
||||||
const id = mailboxIdsPerClient.get(ws);
|
|
||||||
if (!id) return;
|
|
||||||
return mailboxes.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getMostAppropriateSubscriber(ws: WS): Subscriber {
|
|
||||||
return getMailboxIfExists(ws) ?? ws;
|
|
||||||
}
|
|
||||||
|
|||||||
+12
-8
@@ -1,8 +1,6 @@
|
|||||||
import { Mailbox, Subscriber, SubscriptionMap } from "./subscriptionHandler";
|
import { Mailbox, Subscriber, SubscriptionMap } from "./subscriptionHandler";
|
||||||
import {
|
import {
|
||||||
doIfIsString,
|
doIfIsString,
|
||||||
getMailboxIfExists,
|
|
||||||
getMostAppropriateSubscriber,
|
|
||||||
parseMessage,
|
parseMessage,
|
||||||
stringifyMessage,
|
stringifyMessage,
|
||||||
writeError,
|
writeError,
|
||||||
@@ -22,8 +20,10 @@ export interface WebSocketMessage {
|
|||||||
|
|
||||||
// mailbox
|
// mailbox
|
||||||
requestingMailboxSetup?: boolean;
|
requestingMailboxSetup?: boolean;
|
||||||
assignedMailboxId?: string; // sent by server
|
|
||||||
requestedMailbox?: string;
|
requestedMailbox?: string;
|
||||||
|
deletingMailbox?: string;
|
||||||
|
assignedMailboxId?: string; // sent by server
|
||||||
|
connectedMailboxId?: string; // sent by server
|
||||||
|
|
||||||
// subscribing to channel
|
// subscribing to channel
|
||||||
subscribeChannel?: string;
|
subscribeChannel?: string;
|
||||||
@@ -42,7 +42,6 @@ export const subscriptionMap = new SubscriptionMap();
|
|||||||
|
|
||||||
export const clientsConnected = new Set<WS>();
|
export const clientsConnected = new Set<WS>();
|
||||||
export const mailboxes = new Map<string, Mailbox>();
|
export const mailboxes = new Map<string, Mailbox>();
|
||||||
export const mailboxIdsPerClient = new Map<WS, string>();
|
|
||||||
|
|
||||||
export const serversConnectedAsClient = new Set<WS>();
|
export const serversConnectedAsClient = new Set<WS>();
|
||||||
export const serversConnected = new Set<WebSocket>();
|
export const serversConnected = new Set<WebSocket>();
|
||||||
@@ -170,10 +169,10 @@ export function processMessage(
|
|||||||
|
|
||||||
// SUBSCRIPTIONS
|
// SUBSCRIPTIONS
|
||||||
doIfIsString(messageObject.subscribeChannel, (subscribeChannel) => {
|
doIfIsString(messageObject.subscribeChannel, (subscribeChannel) => {
|
||||||
trackSubscription(getMostAppropriateSubscriber(ws), subscribeChannel);
|
trackSubscription(ws, subscribeChannel);
|
||||||
});
|
});
|
||||||
doIfIsString(messageObject.unsubscribeChannel, (unsubscribeChannel) => {
|
doIfIsString(messageObject.unsubscribeChannel, (unsubscribeChannel) => {
|
||||||
forgetSubscription(getMostAppropriateSubscriber(ws), unsubscribeChannel);
|
forgetSubscription(ws, unsubscribeChannel);
|
||||||
});
|
});
|
||||||
|
|
||||||
// MESSAGE
|
// MESSAGE
|
||||||
@@ -192,6 +191,12 @@ export function processMessage(
|
|||||||
if (!mailbox) return;
|
if (!mailbox) return;
|
||||||
mailbox.ws = ws;
|
mailbox.ws = ws;
|
||||||
});
|
});
|
||||||
|
doIfIsString(messageObject.deletingMailbox, (deletingMailbox) => {
|
||||||
|
const mailbox = mailboxes.get(deletingMailbox);
|
||||||
|
if (!mailbox) return;
|
||||||
|
removeMailbox(mailbox);
|
||||||
|
ws.close();
|
||||||
|
});
|
||||||
|
|
||||||
// OTHER SERVER
|
// OTHER SERVER
|
||||||
if (messageObject.requestingServerConnection == true) {
|
if (messageObject.requestingServerConnection == true) {
|
||||||
@@ -205,8 +210,7 @@ export function processMessage(
|
|||||||
export function removeExpiredMailboxes() {
|
export function removeExpiredMailboxes() {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
mailboxes.forEach((mailbox) => {
|
mailboxes.forEach((mailbox) => {
|
||||||
if (mailbox.expiryDate > today) return;
|
if (mailbox.isExpired) removeMailbox(mailbox);
|
||||||
removeMailbox(mailbox);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user