diff --git a/static/App.js b/static/App.js
index 146bc69..050deaa 100644
--- a/static/App.js
+++ b/static/App.js
@@ -16,6 +16,52 @@ class Post {
this.importSource = importSource;
}
}
+class StatusBar {
+ constructor() {
+ this.peerStatus = new Map();
+ this.headless = false;
+ }
+ setMessageHTML(html) {
+ let statusBarElement = document.getElementById('status_bar');
+ if (!statusBarElement) {
+ return;
+ }
+ statusBarElement.innerHTML = html;
+ }
+ setHeadless(headless) {
+ this.headless = headless;
+ }
+ updatePeerMessage(peerID, message) {
+ this.peerStatus.set(peerID, { message, data: this.peerStatus.get(peerID)?.data });
+ this.render();
+ }
+ updatePeerData(peerID, data) {
+ this.peerStatus.set(peerID, { message: this.peerStatus.get(peerID)?.message, data: data });
+ }
+ updatePeerStatus(peerID, message = "", data = {}) {
+ this.peerStatus.set(peerID, { message, data });
+ this.render();
+ }
+ getPeerData(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 {
constructor() {
this.username = '';
@@ -37,9 +83,10 @@ export class App {
this.firstRun = false;
this.peerManager = null;
this.sync = new Sync();
- this.renderTimer = 0;
+ this.renderTimer = null;
this.syncQueues = new Map();
this.syncing = new Set();
+ this.statusBar = new StatusBar();
this.time = 0;
this.animals = ['shrew', 'jerboa', 'lemur', 'weasel', 'possum', 'possum', 'marmoset', 'planigale', 'mole', 'narwhal'];
this.adjectives = ['snazzy', 'whimsical', 'jazzy', 'bonkers', 'wobbly', 'spiffy', 'chirpy', 'zesty', 'bubbly', 'perky', 'sassy'];
@@ -56,6 +103,24 @@ export class App {
mediaID: ''
};
}
+ // updateStatusBar() {
+ // let statusBarElement = document.getElementById('status_bar');
+ // if (!statusBarElement) {
+ // return;
+ // }
+ // let newStatusBar = "";
+ // 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;
+ // }
async processSyncQueue(userID) {
if (this.syncing.has(userID)) {
return;
@@ -72,13 +137,16 @@ export class App {
let neededPostIDs = await this.sync.checkPostIds(userID, peerID, postIDs);
if (neededPostIDs.length > 0) {
console.log.apply(null, log(`[app] Need (${neededPostIDs.length}) posts for user ${logID(userID)} from peer ${logID(peerID)}`));
+ 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);
- // console.log(neededPosts);
}
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)})`);
}
}
+ // this.updateStatusBar();
this.syncing.delete(userID);
}
addPostIDsToSyncQueue(userID, peerID, postIDs) {
@@ -100,6 +168,7 @@ export class App {
return;
}
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);
@@ -108,7 +177,10 @@ export class App {
continue;
}
console.log.apply(null, log(`[app] calling getPostIDsForUser for user [${logID(userID)}] on peer [${logID(sendingPeerID)}]`));
+ this.statusBar.updatePeerStatus(sendingPeerID, `getPostIDs(${logID(userID)})⬆️`);
+
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);
}
@@ -155,8 +227,11 @@ export class App {
});
this.peerManager.registerRPC('getPostsForUser', async (requestingPeerID, userID, postIDs) => {
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);
}
return true;
@@ -168,8 +243,16 @@ 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);
}
@@ -177,9 +260,11 @@ export class App {
return true;
// }
});
+ 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) {
return;
}
@@ -486,19 +571,25 @@ export class App {
let second = listTwo[two % listTwo.length];
return { first, second };
}
+ getUserFunkyName(userID) {
+ let { first: adjective, second: animal } = this.funkyName(userID, this.adjectives, this.animals);
+ return `${adjective}_${animal}`;
+ }
+ getPeerFunkyName(peerID) {
+ let { first: adjective, second: snake } = this.funkyName(peerID, this.adjectives, this.snakes);
+ return `${adjective}_${snake}`;
+ }
getUsername() {
let username = localStorage.getItem("dandelion_username");
if (username && username !== "not_set") {
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;
}
setFont(fontName, fontSize) {
@@ -792,6 +883,7 @@ export class App {
this.isArchivePeer = urlParams.has('archive');
this.isBootstrapPeer = urlParams.has("bootstrap");
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);