diff --git a/src/App.ts b/src/App.ts
index d89fc6b..7f066a2 100644
--- a/src/App.ts
+++ b/src/App.ts
@@ -8,6 +8,8 @@ import { log, logID, renderLog, setLogVisibility } from "log"
declare let marked: any;
declare let QRCode: any;
+type PeerID = string;
+
class Post {
post_timestamp: Date;
post_id: string;
@@ -54,6 +56,63 @@ interface SyncItem {
}
+class StatusBar {
+ peerStatus = new Map();
+ headless = false;
+
+ setMessageHTML(html:string) {
+ let statusBarElement = document.getElementById('status_bar');
+
+ if (!statusBarElement) {
+ return;
+ }
+
+ statusBarElement.innerHTML = html;
+
+ }
+
+ setHeadless(headless:boolean) {
+ this.headless = headless;
+ }
+ updatePeerMessage(peerID: string, message: string) {
+ this.peerStatus.set(peerID, {message, data:this.peerStatus.get(peerID)?.data});
+ this.render();
+ }
+
+ updatePeerData(peerID:PeerID, data:any) {
+ this.peerStatus.set(peerID, {message:this.peerStatus.get(peerID)?.message, data:data});
+ }
+
+ updatePeerStatus(peerID:PeerID, message:string="", data={}) {
+ this.peerStatus.set(peerID, {message, data});
+ this.render();
+ }
+
+ getPeerData(peerID:PeerID) {
+ let status = this.peerStatus.get(peerID);
+ if (status) {
+ return status.data;
+ }
+
+ return null;
+ }
+
+ render() {
+ if (this.headless) {
+ // TODO:Make a nice htop-like display for headless at some point
+ return;
+ }
+
+ let newStatus = "";
+ for (let [peerID, status] of this.peerStatus.entries()) {
+ let statusBarItem = `(${logID(peerID)} | ${status.message}) `;
+ newStatus += statusBarItem;
+ }
+
+ this.setMessageHTML(newStatus);
+ }
+}
+
export class App {
username: string = '';
peername: string = '';
@@ -74,43 +133,43 @@ export class App {
firstRun = false;
peerManager: PeerManager | null = null;
sync: Sync = new Sync();
- renderTimer: ReturnType|null = null;
+ renderTimer: ReturnType | null = null;
syncQueues: Map = new Map();
syncing: Set = new Set();
- statusBar = "";
+ statusBar = new StatusBar();
- updateStatusBar() {
+ // updateStatusBar() {
- let statusBarElement = document.getElementById('status_bar');
+ // let statusBarElement = document.getElementById('status_bar');
- if (!statusBarElement) {
- return;
- }
+ // if (!statusBarElement) {
+ // return;
+ // }
- let newStatusBar = "";
+ // let newStatusBar = "";
- for (let [userID, syncItems] of this.syncQueues.entries()) {
- for (let item of syncItems) {
- let {peerID, postIDs} = item;
- let statusBarItem = ` checking ${postIDs.length} for user [${logID(userID)}] from peer [${logID(peerID)}]`;
- newStatusBar+= statusBarItem;
- }
+ // for (let [userID, syncItems] of this.syncQueues.entries()) {
+ // for (let item of syncItems) {
+ // let {peerID, postIDs} = item;
+ // // let statusBarItem = ` 🤔(${postIDs.length})✉️ [${this.getUserFunkyName(userID)}]${logID(userID)} from [${this.getPeerFunkyName(peerID)}]${logID(peerID)} `;
+ // // let statusBarItem = ` 🤔(${postIDs.length})✉️ [${this.getUserFunkyName(userID)}] from [${this.getPeerFunkyName(peerID)}] `;
+ // let statusBarItem = ` (${this.getUserFunkyName(userID)}+${this.getPeerFunkyName(peerID)})🧐 `;
+ // newStatusBar+= statusBarItem;
+ // }
- }
+ // }
- this.statusBar += newStatusBar;
- statusBarElement.innerHTML = this.statusBar;
- }
+ // this.statusBar += newStatusBar;
+ // statusBarElement.innerHTML = this.statusBar;
+ // }
async processSyncQueue(userID: string) {
if (this.syncing.has(userID)) {
- return;
+ return
}
- // this.updateStatusBar();
-
let syncQueue = this.syncQueues.get(userID) as SyncItem[];
while (syncQueue.length !== 0) {
@@ -127,12 +186,15 @@ export class App {
if (neededPostIDs.length > 0) {
console.log.apply(null, log(`[app] Need (${neededPostIDs.length}) posts for user ${logID(userID)} from peer ${logID(peerID)}`));
- let neededPosts = await this.peerManager?.rpc.getPostsForUser(peerID, this.peerID, userID, neededPostIDs);
- // console.log(neededPosts);
+ let neededPostCount = neededPostIDs.length;
+ this.statusBar.updatePeerStatus(peerID, `need(${logID(userID)} | ${neededPostCount})`, {havePostCount:0, neededPostCount:neededPostCount});
+ let neededPosts = await this.peerManager?.rpc.getPostsForUser(peerID, this.peerID, userID, neededPostIDs);
}
else {
console.log.apply(null, log(`[app] Don't need any posts for user ${logID(userID)} from peer ${logID(peerID)}`));
+ this.statusBar.updatePeerStatus(peerID, `synced(${logID(userID)})`);
+
}
}
@@ -169,18 +231,22 @@ export class App {
console.log.apply(null, log(`[app] got announceUsers from ${logID(sendingPeerID)}`, userIDs));
+ this.statusBar.updatePeerStatus(sendingPeerID, `announcePeers(${userIDs.length})⬇️`);
+
for (let userID of userIDs) {
// console.log.apply(null, log(`[app] announceUsers, got user:${userID} from peer ${sendingPeerID}`));
this.sync.addUserPeer(userID, sendingPeerID);
if (!(this.sync.shouldSyncUserID(userID) || (this.router.route === App.Route.USER && userID === this.router.userID))) {
console.log.apply(null, log(`[app] announceUser_rpc_response skipping user[${logID(userID)}] from[${logID(sendingPeerID)}]`));
-
continue;
}
console.log.apply(null, log(`[app] calling getPostIDsForUser for user [${logID(userID)}] on peer [${logID(sendingPeerID)}]`));
let postIDs = await this.peerManager?.rpc.getPostIDsForUser(sendingPeerID, userID);
+
+ this.statusBar.updatePeerStatus(sendingPeerID, `syncing(${logID(userID)} ${postIDs.length})`);
+
console.log.apply(null, log(`[app] Got (${postIDs.length}) post IDs for user [${logID(userID)}] from peer [${logID(sendingPeerID)}]`));
this.addPostIDsToSyncQueue(userID, sendingPeerID, postIDs);
}
@@ -243,10 +309,12 @@ export class App {
this.peerManager.registerRPC('getPostsForUser', async (requestingPeerID: string, userID: string, postIDs: string[]) => {
let posts = await this.sync.getPostsForUser(userID, postIDs);
-
+ let i=0;
for (let post of posts) {
console.log.apply(null, log(`[app] sendPostForUser sending post [${logID(post.post_id)}] to [${logID(requestingPeerID)}]`, userID, post.author, post.text));
+ i++;
+ this.statusBar.updatePeerStatus(this.peerID, `⬆️${logID(requestingPeerID)} ${i}/${posts.length}`);
await this.peerManager?.rpc.sendPostForUser(requestingPeerID, this.peerID, userID, post);
}
@@ -261,9 +329,19 @@ export class App {
// if (post.text === "image...") {
// debugger;
// }
+
+ let peerData = this.statusBar.getPeerData(sendingPeerID);
+ if (peerData) {
+ this.statusBar.updatePeerMessage(sendingPeerID, `⬇️${logID(userID)} ${peerData.havePostCount}/${peerData.neededPostCount}}`);
+ }
await this.sync.writePostForUser(userID, post);
// if (userID === this.userID) {
+ if (peerData) {
+ peerData.havePostCount++
+ this.statusBar.updatePeerMessage(sendingPeerID, `⬇️${logID(userID)} ${peerData.havePostCount}/${peerData.neededPostCount}}`);
+ }
+
if (this.renderTimer) {
clearTimeout(this.renderTimer);
}
@@ -275,8 +353,11 @@ export class App {
});
+ this.statusBar.setMessageHTML("Connecting to ddln network...")
await this.peerManager.connect();
console.log.apply(null, log("*************** after peerManager.connect"));;
+ this.statusBar.setMessageHTML("Connected to ddln network...")
+
if (this.isBootstrapPeer) {
@@ -699,6 +780,16 @@ export class App {
return { first, second }
}
+ getUserFunkyName(userID: string) {
+ let { first: adjective, second: animal } = this.funkyName(userID, this.adjectives, this.animals);
+ return `${adjective}_${animal}`
+ }
+
+ getPeerFunkyName(peerID: string) {
+ let { first: adjective, second: snake } = this.funkyName(peerID, this.adjectives, this.snakes);
+ return `${adjective}_${snake}`
+ }
+
getUsername() {
let username = localStorage.getItem("dandelion_username");
@@ -706,16 +797,15 @@ export class App {
return username;
}
- let { first: adjective, second: animal } = this.funkyName(this.userID, this.adjectives, this.animals);
- username = `${adjective}_${animal}`
+ username = this.getUserFunkyName(this.userID);
+
localStorage.setItem("dandelion_username", username);
return username;
}
getPeername() {
- let { first: adjective, second: snake } = this.funkyName(this.peerID, this.adjectives, this.snakes);
- let peername = `${adjective}_${snake}`
+ let peername = this.getPeerFunkyName(this.peerID);
return peername;
}
@@ -1107,12 +1197,16 @@ export class App {
console.log(`[headless]${this.isHeadless} [archive] ${this.isArchivePeer} [bootstrap] ${this.isBootstrapPeer}`);
+
+ this.statusBar.setHeadless(this.isHeadless);
+
+
let limitPostsParam = urlParams.get('limitPosts');
if (limitPostsParam) {
this.limitPosts = parseInt(limitPostsParam);
}
-
+
this.getRoute();
if (this.router.route === App.Route.CONNECT) {
diff --git a/src/PeerManager.ts b/src/PeerManager.ts
index 78dd64c..9b8978c 100644
--- a/src/PeerManager.ts
+++ b/src/PeerManager.ts
@@ -520,10 +520,10 @@ class PeerConnection {
{ urls: "stun:ddln.app" },
{ urls: "turn:ddln.app", username: "a", credential: "b" },
{ urls: "stun:stun.l.google.com" }, // keeping this for now as my STUN server is not returning ipv6
- // { urls: "stun:stun1.l.google.com" },
- // { urls: "stun:stun2.l.google.com" },
- // { urls: "stun:stun3.l.google.com" },
- // { urls: "stun:stun4.l.google.com" },
+ { urls: "stun:stun1.l.google.com" },
+ { urls: "stun:stun2.l.google.com" },
+ { urls: "stun:stun3.l.google.com" },
+ { urls: "stun:stun4.l.google.com" },
],
};
// longMessageQueue: string[] = [];
diff --git a/static/index.html b/static/index.html
index 582d039..fdba9bd 100644
--- a/static/index.html
+++ b/static/index.html
@@ -42,7 +42,7 @@
-
+ Connecting...
diff --git a/static/main.css b/static/main.css
index 7571c3c..f5c28a4 100644
--- a/static/main.css
+++ b/static/main.css
@@ -364,6 +364,9 @@ iframe {
.status-bar {
align-content: center;
+ padding-left: 55px;
+ font-size: 12px;
+ height:12px;
}
.spinner {