diff --git a/deno/ddln_server.ts b/deno/ddln_server.ts index c2b1038..85f199d 100644 --- a/deno/ddln_server.ts +++ b/deno/ddln_server.ts @@ -7,6 +7,8 @@ // import { serveDir } from "jsr:@std/http/file-server" +import { brotli } from "jsr:@deno-library/compress"; + const memoryCache = true; const filepathResponseCache: Map = new Map(); @@ -30,9 +32,15 @@ async function serveFile(filename: string) { const file = await Deno.readFile("../" + filename); - const newResponse = new Response(file); + + const compressed = await brotli.compress(file); + + const newResponse = await new Response(compressed); + // const newResponse = await new Response(file); newResponse.headers.set('Cache-Control', 'no-transform'); + newResponse.headers.set('Content-Encoding', 'br'); + if (filename.endsWith('.js')) { newResponse.headers.set('content-type', 'application/javascript') @@ -89,6 +97,15 @@ interface HelloMessage { known_users: string[] } +interface Hello2Message { + type: string + user_id: string + user_name: string + peer_id: string + peer_name: string + is_bootstrap_peer: boolean + // peer_description:RTCSessionDescription +} // interface PeerState { // socket:WebSocket; @@ -96,6 +113,7 @@ interface HelloMessage { // } // const peerStates:Map = new Map(); +const bootstrapPeers: Set = new Set(); const userPeers: Map> = new Map(); const peerSockets: Map = new Map(); const socketPeers: Map = new Map(); @@ -104,6 +122,31 @@ const socketPeers: Map = new Map(); // } +function hello2Handler(m:Hello2Message, socket:WebSocket) { + // bootstrapPeers.add(m.) + console.log(`[>hello2]: peer ${colorID(m.peer_id)}:${m.peer_name}, user ${colorID(m.user_id)}:${m.user_name}`); + + if (m.is_bootstrap_peer) { + bootstrapPeers.add(m.peer_id); + console.log(`This is a bootstrap peer. bootstrap peers:${[...bootstrapPeers.values()]}`); + } + + if (!userPeers.has(m.user_id)) { + userPeers.set(m.user_id, new Set()); + } + userPeers.get(m.user_id)?.add(m.peer_id); + peerSockets.set(m.peer_id, socket); // TODO:MAYBEBUG - what happens with multiple windows each with their own websocket? + socketPeers.set(socket, m.peer_id); + + if (!m.is_bootstrap_peer) { + + return JSON.stringify({ type: 'hello2', bootstrapPeers: [...bootstrapPeers.values()] }); + } + + return JSON.stringify({type:'hello2', message:'hello2 bootstrap peer!'}); + +} + function helloHandler(m: HelloMessage, socket: WebSocket) { console.log(`Received hello from peer ${colorID(m.peer_id)}:${m.peer_name}, user ${colorID(m.user_id)}:${m.user_name}`); @@ -233,7 +276,8 @@ function connectWebsocket(request: Request) { return; } console.log("Websocket close:", colorID(peerID), `code:${event.code} reason:${event.reason} wasClean: ${event.wasClean}`); - + + bootstrapPeers.delete(peerID); peerSockets.delete(peerID); deletePeerFromUserPeers(peerID); }); @@ -303,6 +347,7 @@ async function main() { messageDispatch.set('ping', pingHandler); messageDispatch.set('hello', helloHandler); + messageDispatch.set('hello2', hello2Handler); messageDispatch.set('peer_message', peerMessageHandler); Deno.serve({ diff --git a/src/IDUtils.ts b/src/IDUtils.ts new file mode 100644 index 0000000..9d6fde4 --- /dev/null +++ b/src/IDUtils.ts @@ -0,0 +1,13 @@ +function uuidv4() { + return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c: any) => + (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) + ); +} + +export function generateID() { + if (self.crypto.hasOwnProperty("randomUUID")) { + return self.crypto.randomUUID(); + } + + return uuidv4(); +} \ No newline at end of file diff --git a/src/PeerManager.ts b/src/PeerManager.ts new file mode 100644 index 0000000..0fc9cc5 --- /dev/null +++ b/src/PeerManager.ts @@ -0,0 +1,544 @@ +// connect to WS server, send info, connecto to bootstrap peer +// once connected to bootstrap peer, + +// Goal, connect to bootstrap peer, ask bootstrap peer for peers that have posts from users that we care about. get peers, connect to those peers, sync. +// how? do "perfect negotiation" with bootstrap peer. All logic here moves to BP. + +import { generateID } from "IDUtils"; + +// Use a broadcast channel to only have one peer manager for multiple tabs, +// then we won't need to have a session ID as all queries for a peerID will be coming from the same peer manager + +export class PeerManager { + routingTable: Map; + + private peers: Map; + private signaler: Signaler; + searchQueryFunctions: Map = new Map(); + RPC_remote: Map = new Map(); + rpc: { [key: string]: Function } = {}; + isBootstrapPeer: boolean = false; + bootstrapPeerConnection: PeerConnection | null = null; + + async onConnected(bootstrapPeerID: string) { + this.bootstrapPeerConnection = await this.connect(bootstrapPeerID); + } + + constructor(userID: string, peerID: string, isBootstrapPeer: boolean) { + this.isBootstrapPeer = isBootstrapPeer; + this.peers = new Map(); + this.routingTable = new Map(); + + + this.signaler = new Signaler(userID, peerID, isBootstrapPeer, this.onConnected.bind(this)); + + // Testing + let dummyPeer = new PeerConnection(this, "dummy_peer", this.signaler); + this.peers.set("dummy_peer", dummyPeer); + } + + async connect(remotePeerID: string) { + // Connect to the peer that has the peer id peerID + let peerConnection = new PeerConnection(this, remotePeerID, this.signaler); + await peerConnection.connect(); + this.peers.set(remotePeerID, peerConnection); + return peerConnection; + } + + async disconnect(remotePeerID: string) { + let peer = this.peers.get(remotePeerID); + + if (!peer) { + console.log(`PeerManager.disconnect: couln't find peer ${remotePeerID}`); + return; + } + + await peer.disconnect(); + this.peers.delete(remotePeerID); + } + + async call(peerID: string, functionName: string, args: any) { + let peer = this.peers.get(peerID); + + if (!peer) { + console.log(`Can't find peer ${peerID}`); + return; + } + + return await peer.call(functionName, args); + } + + callFromRemote(functionName: string, args: any) { + let func = this.RPC_remote.get(functionName); + + if (!func) { + throw new Error(); + } + + return func(args); + } + + registerRPC(functionName: string, func: Function) { + this.rpc[functionName] = (peerID: string, args: any) => { + return this.call(peerID, functionName, args); + }; + this.RPC_remote.set(functionName, func); + } + + registerSearchQuery(searchType: string, queryFunction: Function) { + this.searchQueryFunctions.set(searchType, queryFunction); + } + + async search(type: string, message: any) { + let promises = []; + for (let peer of this.peers.values()) { + promises.push(peer.call(type, message)); + } + + return await Promise.allSettled(promises); + } + + onMessage(remotePeerID: string, message: any) { + console.log(remotePeerID, message); + } +} + +function log(...args: any[]): void { + for (let arg of args) { + console.log("[LOG]", arg); + } +} + +interface Message { + type: string; + from_peer: string; + to_peer: string; + from_username: string; + from_peername: string; + peer_message: any; +} + +// Initially this wil be the bootstrap peer, We'll keep a connection to it and it will keep a list of all connected peers. +// Eventually we will replace this with connecting via other peers. +class Signaler { + websocket: WebSocket; + + sessionID: string; + userID: string; + peerID: string; + bootstrapPeerID: string = ""; + private isBootstrapPeer: boolean = false; + private onConnected: Function; + + constructor(userID: string, peerID: string, isBootstrapPeer: boolean, onConnected: Function) { + this.onConnected = onConnected; + this.isBootstrapPeer = isBootstrapPeer; + this.sessionID = generateID(); + this.userID = userID; + this.peerID = peerID; + + + try { + this.websocket = new WebSocket( + `wss://${window.location.hostname}:${window.location.port}/ws`, + ); + } catch (error: any) { + throw new Error(error.message); + } + + this.websocket.onopen = async (event) => { + log("signaler:ws:onopen"); + await this.sendHello2(); + }; + + this.websocket.onmessage = this.onMessage.bind(this); + } + + sendPeerMessage(remotePeerID: string, peerMessage: { type: string; description: RTCSessionDescription; }) { + this.send({ + type: "peer_message", + from: this.peerID, + to: remotePeerID, + from_username: "blah user", + from_peername: "blah peer", + message: peerMessage + }) + + // let responseMessage = { type: "peer_message", + // from: app.peerID, + // to: data.from, + // from_username: app.username, + // from_peername: app.peername, + // message: { type: "get_posts_for_user", post_ids: postIds, user_id: message.user_id } } + + } + + + async sendHello2() { + this.send({ + type: "hello2", + user_id: this.userID, + // user_name: app.username, + peer_id: this.peerID, + session_id: this.sessionID, + // peer_name: app.peername, + is_bootstrap_peer: this.isBootstrapPeer, + // peer_description: this.rtcPeerDescription + }); + } + + connect() { + } + + onMessage(event: MessageEvent) { + let messageJSON = event.data; + let message: any = null; + + try { + message = JSON.parse(messageJSON); + } catch (e) { + console.log(e); + throw new Error(); + } + + console.log("->signaler:", message); + + if (message.type === "hello2") { + + if (!this.isBootstrapPeer) { + this.bootstrapPeerID = message.bootstrapPeers[0]; + } + + this.onConnected(this.bootstrapPeerID); + } + } + + send(message: any) { + let messageJSON = ""; + + try { + messageJSON = JSON.stringify(message); + } catch (e) { + console.log(e); + return; + } + + console.log("<-signaler:", message); + + this.websocket.send(messageJSON); + } + + // sendPeerMessage +} + +class PeerConnection { + private remotePeerID: string; + private signaler: Signaler; + private peerManager: PeerManager; + private dataChannel: RTCDataChannel | null = null; + private messageHandlers: Map = new Map(); + + // private makingOffer:boolean = false; + // private ignoreOffer:boolean = false; + + rtcPeer: RTCPeerConnection | null = null; + + static config = { + iceServers: [ + { 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 return 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" }, + ], + }; + + pendingRPCs: Map< + string, + { resolve: Function; reject: Function; functionName: string } + > = new Map(); + messageSuperlog: boolean = true; + + async RPCHandler(message: any) { + } + + constructor( + peerManager: PeerManager, + remotePeerID: string, + signaler: Signaler, + ) { + this.peerManager = peerManager; + this.remotePeerID = remotePeerID; + this.signaler = signaler; + } + + async connect() { + this.rtcPeer = new RTCPeerConnection(PeerConnection.config); + this.dataChannel = this.rtcPeer.createDataChannel("ddln_main"); + + if (this.rtcPeer === null) { + return; + } + + // this.rtcPeer.onicecandidate = ({ candidate }) => this.signaler.send(JSON.stringify({ candidate })); + this.rtcPeer.onicecandidate = ({ candidate }) => console.log(candidate); + + + this.rtcPeer.onnegotiationneeded = async (event) => { + log("on negotiation needed fired"); + + if (!this.rtcPeer) { + throw new Error(); + } + + let makingOffer = false; + + try { + makingOffer = true; + await this.rtcPeer.setLocalDescription(); + + if (!this.rtcPeer.localDescription) { + return; + } + + this.signaler.sendPeerMessage(this.remotePeerID, { type: "rtcDescription", description: this.rtcPeer.localDescription }); + } catch (err) { + console.error(err); + } finally { + makingOffer = false; + } + }; + } + + async disconnect() { + } + + send(message: any) { + this.messageSuperlog && console.log("<-", message.type, message); + + let messageJSON = JSON.stringify(message); + // this.dataChannel?.send(); + + this.onMessage(messageJSON); + } + + call(functionName: string, args: any) { + let transactionID = generateID(); // make this faster as we will only ever have a small number of in-flight queries on a peer + // Think about a timeout here to auto reject it after a while. + let promise = new Promise((resolve, reject) => { + this.pendingRPCs.set(transactionID, { resolve, reject, functionName }); + // setTimeout(() => reject("bad"), 1000); + }); + + let message = { + type: "rpc_call", + transaction_id: transactionID, + function_name: functionName, + args: args, + }; + + this.send(message); + + return promise; + } + + onMessage(messageJSON: any) { + + let message: any = {}; + try { + message = JSON.parse(messageJSON); + } catch (e) { + console.log("PeerConnection.onMessage:", e); + } + + this.messageSuperlog && console.log("->", message.type, message); + let type = message.type; + + if (type === "rpc_response") { + let pendingRPC = this.pendingRPCs.get(message.transaction_id); + + if (!pendingRPC) { + throw new Error(); + } + + pendingRPC.resolve(message.response); + } + + if (type === "rpc_call") { + + let response = this.peerManager.callFromRemote(message.function_name, message.args); + + let responseMessage = { type: 'rpc_response', transaction_id: message.transaction_id, response: response }; + + this.send(responseMessage); + + } + + // this.peerManger.onMessage(this.remotePeerID, message); + } +} + +// export class PeerConnection2 { + +// id: string; + +// private makingOffer:boolean = false; +// private ignoreOffer:boolean = false; + +// rtcPeer: RTCPeerConnection; + +// signaler:WebSocket; + +// static config = { +// iceServers: [ +// { urls: "stun:stun.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" }, +// ], +// }; + +// constructor(remotePeerID: string, signaler:WebSocket) { +// this.id = remotePeerID; + +// this.rtcPeer = new RTCPeerConnection(PeerConnection2.config); + +// this.signaler = signaler;; + +// this.rtcPeer.onnegotiationneeded = async () => { +// try { +// this.makingOffer = true; +// await this.rtcPeer.setLocalDescription(); +// signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); +// } catch (err) { +// console.error(err); +// } finally { +// this.makingOffer = false; +// } +// }; + +// this.rtcPeer.onicecandidate = ({ candidate }) => signaler.send(JSON.stringify({ candidate })); + +// this.ignoreOffer = false; +// } + +// onSignallerMessage = async ({ data: { description, candidate } }: MessageEvent) => { +// try { +// if (description) { +// // const offerCollision = +// // description.type === "offer" && +// // (this.makingOffer || this.rtcPeer.signalingState !== "stable"); + +// // this.ignoreOffer = !polite && offerCollision; +// if (this.ignoreOffer) { +// return; +// } + +// await this.rtcPeer.setRemoteDescription(description); +// if (description.type === "offer") { +// await this.rtcPeer.setLocalDescription(); +// this.signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); +// } +// } else if (candidate) { +// try { +// await this.rtcPeer.addIceCandidate(candidate); +// } catch (err) { +// if (!this.ignoreOffer) { +// throw err; +// } +// } +// } +// } catch (err) { +// console.error(err); +// } +// }; + +// } + +// // const config = { +// // iceServers: [{ urls: "stun:stun.mystunserver.tld" }], +// // }; + +// // let polite = true; + +// // const signaler = new SignalingChannel(); +// // const signaler: any = {} +// // const rtcPeer = new RTCPeerConnection(config); + +// // // const constraints = { audio: true, video: true }; +// // const selfVideo = document.querySelector("video.selfview"); +// // const remoteVideo = document.querySelector("video.remoteview"); + +// // async function start() { +// // try { +// // const stream = await navigator.mediaDevices.getUserMedia(constraints); + +// // for (const track of stream.getTracks()) { +// // pc.addTrack(track, stream); +// // } +// // selfVideo.srcObject = stream; +// // } catch (err) { +// // console.error(err); +// // } +// // } + +// // rtcPeer.ontrack = ({ track, streams }) => { +// // track.onunmute = () => { +// // if (remoteVideo.srcObject) { +// // return; +// // } +// // remoteVideo.srcObject = streams[0]; +// // }; +// // }; + +// // makingOffer = false; + +// // rtcPeer.onnegotiationneeded = async () => { +// // try { +// // // makingOffer = true; +// // await rtcPeer.setLocalDescription(); +// // signaler.send({ description: rtcPeer.localDescription }); +// // } catch (err) { +// // console.error(err); +// // } finally { +// // makingOffer = false; +// // } +// // }; + +// // rtcPeer.onicecandidate = ({ candidate }) => signaler.send({ candidate }); + +// // let ignoreOffer = false; + +// // signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => { +// // try { +// // if (description) { +// // const offerCollision = +// // description.type === "offer" && +// // // (makingOffer || rtcPeer.signalingState !== "stable"); + +// // ignoreOffer = !polite && offerCollision; +// // if (ignoreOffer) { +// // return; +// // } + +// // await rtcPeer.setRemoteDescription(description); +// // if (description.type === "offer") { +// // await rtcPeer.setLocalDescription(); +// // signaler.send({ description: rtcPeer.localDescription }); +// // } +// // } else if (candidate) { +// // try { +// // await rtcPeer.addIceCandidate(candidate); +// // } catch (err) { +// // if (!ignoreOffer) { +// // throw err; +// // } +// // } +// // } +// // } catch (err) { +// // console.error(err); +// // } +// // }; diff --git a/src/log.ts b/src/log.ts new file mode 100644 index 0000000..da68cb6 --- /dev/null +++ b/src/log.ts @@ -0,0 +1,28 @@ +let logLines: string[] = []; +let logLength = 30; +let logVisible = false; + +export function setLogVisibility(visible:boolean) { + logVisible = visible; +} + +export function renderLog() { + if (!logVisible) { + return; + } + + let log = document.getElementById("log"); + if (!log) { + throw new Error(); + } + log.innerText = logLines.join("\n"); +} +export function log(message: string) { + console.log(message); + logLines.push(`${new Date().toLocaleTimeString()}: ${message}`); + if (logLines.length > logLength) { + logLines = logLines.slice(logLines.length - logLength); + } + + renderLog(); +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 4164d28..173ef01 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,6 +33,7 @@ Restruucture the app around the data. App/WS split is messy. Clean it up. // import * as ForceGraph3D from "3d-force-graph"; import { openDatabase, getData, addData, addDataArray, clearData, deleteData, mergeDataArray, getAllData, checkPostIds, getAllIds, getPostsByIds } from "db"; +// import {PeerConnection} from "webRTC"; // declare let WebTorrent: any; @@ -279,6 +280,88 @@ interface PeerMessage { message: any; } +// class Signaler { +// websocket: WebSocket | null = null; + +// websocketPingInterval: number = 0; + + + +// connect() { +// if (this.websocket?.readyState === WebSocket.OPEN) { +// return; +// } + +// window.clearInterval(this.websocketPingInterval); +// if (this.websocket) { this.websocket.close() }; + +// try { +// this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); +// } catch (error: any) { +// console.log(error.message); +// return; +// } + +// this.websocket.onopen = async (event) => { +// log("ws:connected"); +// await this.sendHello(); + +// // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. +// let helloRefreshIntervalPeriod = 120; +// if (app.isHeadless) { +// console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) +// this.helloRefreshInterval = window.setInterval(() => { +// console.log("wsConnection: Hello refresh.") + +// if (!navigator.onLine) { +// return; +// } +// this.sendHello(); +// }, helloRefreshIntervalPeriod * 1000); +// } + +// this.websocketPingInterval = window.setInterval(() => { +// if (!navigator.onLine) { +// return; +// } +// this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); +// }, 10_000) +// }; + +// this.websocket.onclose = (event) => { +// log("ws:disconnected"); +// // this.retry *= 2; +// log(`Retrying in ${this.retry} seconds`); +// window.setTimeout(() => { this.connect(); }, this.retry * 1000); +// }; + +// this.websocket.onmessage = (event) => { +// // log('ws:<-' + event.data.slice(0, 240)); +// let data = JSON.parse(event.data); + +// let { type } = data; + +// let handler = this.messageHandlers.get(type); +// if (!handler) { +// console.warn(`Got a message we can't handle:`, type); +// return; +// } + +// handler(data); + +// }; + +// this.websocket.onerror = (event) => { +// log('ws:error: ' + event); +// }; +// } +// } + +// disconnect() { +// this.websocket?.close(); +// } +// } + class wsConnection { websocket: WebSocket | null = null; userID = ""; @@ -304,12 +387,19 @@ class wsConnection { this.messageHandlers.set('pong', this.pongHandler); this.messageHandlers.set('peer_message', this.peerMessageHandler.bind(this)); + + // this.peerMessageHandlers.set('get_post_ids_for_user', this.getPostIdsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_post_ids_for_user_response', this.getPostIdsForUserResponseHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user', this.getPostsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user_response', this.getPostsForUserReponseHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer', this.sendWebRTCOfferHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer_response', this.getPostIdsForUserResponseHandler.bind(this)); + + + window.addEventListener('beforeunload', () => this.disconnect()); this.connect(); @@ -340,6 +430,10 @@ class wsConnection { pongHandler(data: any) { } + async sendWebRTCOfferHandler(data:any) { + + } + async getPostIdsForUserResponseHandler(data: any) { // log(`getPostsForUserResponse: ${data}`) @@ -1020,6 +1114,8 @@ class App { this.render(); } + + // What happens with multiple tabs/connections from the same peer ID? I don't think this works, we also need a session ID for each connection getPeerID() { let id = localStorage.getItem("peer_id"); @@ -1540,7 +1636,36 @@ class App { } async main() { + let urlParams = (new URL(window.location.href)).searchParams; + if (urlParams.has('log')) { + this.showInfo(); + } + let peer:RTCPeerConnection|null = null; +// if (window.RTCPeerConnection) { + peer = new RTCPeerConnection({ + iceServers: [ + { 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 return 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" }, + ] + }); + + peer.createDataChannel('boop'); + + peer.onicecandidate = ({ candidate }) => {log(`WRTC:${candidate?.address} ${candidate?.protocol} ${candidate?.type} ${(candidate as any)?.url}`)}; + peer.onnegotiationneeded = (event) => {console.log("on negotiation needed: ", event)} + + peer.createOffer().then((description)=>{ + peer.setLocalDescription(description) + log("RTC: " + description.sdp + description.type); + }); + + // } // await this.exportPostsForUser('b38b623c-c3fa-4351-9cab-50233c99fa4e'); @@ -1579,11 +1704,6 @@ class App { document.getElementById('connectURL')!.innerHTML = `connect`; - let urlParams = (new URL(window.location.href)).searchParams; - if (urlParams.has('log')) { - this.showInfo(); - } - if (urlParams.has('headless')) { this.isHeadless = true; } diff --git a/src/main2.ts b/src/main2.ts new file mode 100644 index 0000000..211c4b5 --- /dev/null +++ b/src/main2.ts @@ -0,0 +1,2114 @@ +// TODO: virtual list, only rerender what's needed so things can keep playing. + + + +/* +Problems + 1. Can't delete, very annoying + Tombstones. Send all IDs and all Tombstones. Ask only for posts that we don't get a tombstone for. Don't send posts we have a tombstone for? + + Posts don't propagate, you need to refresh to see new posts. + Broadcast when we post to all peers we know about. + + 3. Posting is slow because too long to render + 2. Can't follow people + 4. Can't like or reply to posts + +user + posts + media + tombstones + following + profile + name + description + profile pic + + +Restruucture the app around the data. App/WS split is messy. Clean it up. + +*/ + + +// import * as ForceGraph3D from "3d-force-graph"; +import { openDatabase, getData, addData, addDataArray, clearData, deleteData, mergeDataArray, getAllData, checkPostIds, getAllIds, getPostsByIds } from "db"; +import { generateID } from "IDUtils"; +import { PeerManager } from "PeerManager"; + +// import {PeerConnection} from "webRTC"; + +// declare let WebTorrent: any; + +// declare let ForceGraph3D: any; +declare let marked: any; +declare let QRCode: any; +// let posts:any; +// let keyBase = "dandelion_posts_v1_" +// let key:string = ""; + +// interface PostTimestamp { +// year: number, +// month: number, +// day: number, +// hour: number, +// minute: number, +// second: number, +// } + +function waitMs(durationMs: number) { + return new Promise(resolve => setTimeout(resolve, durationMs)); +} + +function uuidToBytes(uuid: string): Uint8Array { + return new Uint8Array(uuid.match(/[a-fA-F0-9]{2}/g)!.map((hex) => parseInt(hex, 16))); +} + +// Base58 character set +const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; +// Base58 encoding +// Base58 encoding +function encodeBase58(buffer: Uint8Array): string { + let carry; + const digits = [0]; + + for (const byte of buffer) { + carry = byte; + for (let i = 0; i < digits.length; i++) { + carry += digits[i] << 8; + digits[i] = carry % 58; + carry = Math.floor(carry / 58); + } + while (carry > 0) { + digits.push(carry % 58); + carry = Math.floor(carry / 58); + } + } + + let result = ''; + for (const digit of digits.reverse()) { + result += BASE58_ALPHABET[digit]; + } + + // Handle leading zero bytes + for (const byte of buffer) { + if (byte === 0x00) { + result = BASE58_ALPHABET[0] + result; + } else { + break; + } + } + + return result; +} + +// Convert UUID v4 to Base58 +function uuidToBase58(uuid: string): string { + const bytes = uuidToBytes(uuid); + return encodeBase58(bytes); +} + + +function logID(ID: string) { + return ID.substring(0, 5); +} + + +// function log(message:string) { +// console.log(message); +// let log = document.getElementById("log"); +// let newlog = document.createElement('span'); +// newlog.innerHTML = `
${message}
`; +// log?.appendChild(newlog); + +// } + +let logLines: string[] = []; +let logLength = 30; +let logVisible = false; +function renderLog() { + if (!logVisible) { + return; + } + + let log = document.getElementById("log"); + if (!log) { + throw new Error(); + } + log.innerText = logLines.join("\n"); +} +function log(message: string) { + console.log(message); + logLines.push(`${new Date().toLocaleTimeString()}: ${message}`); + if (logLines.length > logLength) { + logLines = logLines.slice(logLines.length - logLength); + } + + renderLog(); +} + + + +interface StoragePost { + data: Post; +} + +class Post { + post_timestamp: Date; + post_id: string; + author: string; + author_id: string; + text: string; + image_data: ArrayBuffer | null; + + + importedFrom: "twitter" | null; + importSource: any; + + constructor( + author: string, + author_id: string, + text: string, + post_timestamp: Date, + imageData: ArrayBuffer | null = null, + importedFrom: "twitter" | null = null, + importSource: any = null) { + + this.post_timestamp = post_timestamp; + this.post_id = generateID(); + + this.author = author; + this.author_id = author_id; + this.text = text; + this.image_data = imageData; + + this.importedFrom = importedFrom; + this.importSource = importSource; + } +} + +window.addEventListener('scroll', () => { + // Total height of the document + const totalPageHeight = document.body.scrollHeight; + + // Current scroll position + const scrollPoint = window.scrollY + window.innerHeight; + + // Check if scrolled to bottom + if (scrollPoint >= totalPageHeight) { + console.log('Scrolled to the bottom!'); + console.log(scrollPoint, totalPageHeight); + } + +}); + + + +// let peer = await new PeerConnection(peer_id); + +// let connectionReply = await wsConnection.send('hello'); +// for (let peer of connectionReply) { +// let peerConnection = await wsConnection.send('connect', peer.id); +// if (peerConnection) { +// this.peers.push(peerConnection); +// let postIDs = await peerConnection.getPostIDs(); +// let postsWeDontHave = this.diffPostIDs(postIDs); + +// let newPosts = await peerConnection.getPosts(postsWeDontHave); + +// this.addPosts(newPosts); + +// } +// } + +async function bytesToBase64DataUrl(bytes: Uint8Array, type = "application/octet-stream") { + return await new Promise((resolve, reject) => { + const reader = Object.assign(new FileReader(), { + onload: () => resolve(reader.result), + onerror: () => reject(reader.error), + }); + reader.readAsDataURL(new File([bytes], "", { type })); + }); +} + +async function arrayBufferToBase64(buffer: ArrayBuffer) { + var bytes = new Uint8Array(buffer); + return (await bytesToBase64DataUrl(bytes) as string).replace("data:application/octet-stream;base64,", ""); +} + +async function base64ToArrayBuffer(base64String: string) { + let response = await fetch("data:application/octet-stream;base64," + base64String); + let arrayBuffer = await response.arrayBuffer(); + return arrayBuffer; +} + +async function compressString(input: string) { + // Convert the string to a Uint8Array + const textEncoder = new TextEncoder(); + const inputArray = textEncoder.encode(input); + + // Create a CompressionStream + const compressionStream = new CompressionStream('gzip'); + const writer = compressionStream.writable.getWriter(); + + // Write the data and close the stream + writer.write(inputArray); + writer.close(); + + // Read the compressed data from the stream + const compressedArray = await new Response(compressionStream.readable).arrayBuffer(); + + // Convert the compressed data to a Uint8Array + return new Uint8Array(compressedArray); +} + +interface PeerMessage { + type: string; + from: string; + to: string; + from_peername: string; + from_username: string; + message: any; +} + +// class Signaler { +// websocket: WebSocket | null = null; + +// websocketPingInterval: number = 0; + + + +// connect() { +// if (this.websocket?.readyState === WebSocket.OPEN) { +// return; +// } + +// window.clearInterval(this.websocketPingInterval); +// if (this.websocket) { this.websocket.close() }; + +// try { +// this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); +// } catch (error: any) { +// console.log(error.message); +// return; +// } + +// this.websocket.onopen = async (event) => { +// log("ws:connected"); +// await this.sendHello(); + +// // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. +// let helloRefreshIntervalPeriod = 120; +// if (app.isHeadless) { +// console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) +// this.helloRefreshInterval = window.setInterval(() => { +// console.log("wsConnection: Hello refresh.") + +// if (!navigator.onLine) { +// return; +// } +// this.sendHello(); +// }, helloRefreshIntervalPeriod * 1000); +// } + +// this.websocketPingInterval = window.setInterval(() => { +// if (!navigator.onLine) { +// return; +// } +// this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); +// }, 10_000) +// }; + +// this.websocket.onclose = (event) => { +// log("ws:disconnected"); +// // this.retry *= 2; +// log(`Retrying in ${this.retry} seconds`); +// window.setTimeout(() => { this.connect(); }, this.retry * 1000); +// }; + +// this.websocket.onmessage = (event) => { +// // log('ws:<-' + event.data.slice(0, 240)); +// let data = JSON.parse(event.data); + +// let { type } = data; + +// let handler = this.messageHandlers.get(type); +// if (!handler) { +// console.warn(`Got a message we can't handle:`, type); +// return; +// } + +// handler(data); + +// }; + +// this.websocket.onerror = (event) => { +// log('ws:error: ' + event); +// }; +// } +// } + +// disconnect() { +// this.websocket?.close(); +// } +// } + + +// Connect websocket +// send hello +// get bootstrap peer ID +// WebRTC connect to bootstrap peer +// ask Bootstrap peer for peers that have users we care about. +// for now, bootstrap peer will connect to all peers and will tell us about them, moving all logic from the server to the BSP +// WebRTC Connect to peers that might have posts we need +// query those peers and do existing logic. + +class wsConnection { + websocket: WebSocket | null = null; + sessionID = ""; + userID = ""; + peerID = ""; + rtcPeerDescription: RTCSessionDescription | null = null; + UserIDsToSync: Set; + websocketPingInterval: number = 0; + helloRefreshInterval: number = 0; + retry = 10; + state = 'disconnected'; + // peers: Map = new Map(); + + messageHandlers: Map void> = new Map(); + peerMessageHandlers: Map void> = new Map(); + seenPeers: Map = new Map(); + + + constructor(userID: string, peerID: string, IDsToSync: Set, rtcPeerDescription: RTCSessionDescription) { + this.rtcPeerDescription = rtcPeerDescription; + this.sessionID = generateID(); + this.userID = userID; + this.peerID = peerID; + this.UserIDsToSync = new Set(IDsToSync); + + this.messageHandlers.set('hello', this.helloResponseHandler.bind(this)); + this.messageHandlers.set('hello2', this.hello2ResponseHandler.bind(this)); + this.messageHandlers.set('pong', this.pongHandler); + this.messageHandlers.set('peer_message', this.peerMessageHandler.bind(this)); + + + // + this.peerMessageHandlers.set('get_post_ids_for_user', this.getPostIdsForUserHandler.bind(this)); + this.peerMessageHandlers.set('get_post_ids_for_user_response', this.getPostIdsForUserResponseHandler.bind(this)); + + this.peerMessageHandlers.set('get_posts_for_user', this.getPostsForUserHandler.bind(this)); + this.peerMessageHandlers.set('get_posts_for_user_response', this.getPostsForUserReponseHandler.bind(this)); + + // this.peerMessageHandlers.set('send_webrtc_offer', this.sendWebRTCOfferHandler.bind(this)); + // this.peerMessageHandlers.set('send_webrtc_offer_response', this.getPostIdsForUserResponseHandler.bind(this)); + + + + window.addEventListener('beforeunload', () => this.disconnect()); + + this.connect(); + } + + // So we don't need custom logic everywhere we use this, I just wrapped it. + shouldSyncUserID(userID: string) { + if (app.isHeadless) { + return true; + } + + return this.UserIDsToSync.has(userID); + } + + async send(message: any) { + let json = "" + try { + json = JSON.stringify(message); + // console.log("*******", (await compressString(json)).byteLength, json.length); + } catch (e) { + console.log(e, "wsConnection send: Couldn't serialize message", message); + } + // log(`ws->${json.slice(0, 240)}`) + this.websocket!.send(json); + + } + + pongHandler(data: any) { + } + + + async sendWebRTCDescription(description: RTCSessionDescription | null) { + + console.log("description:", description); + this.send({ type: "rtc_session_description", description: description }); + } + + async getPostIdsForUserResponseHandler(data: any) { + // log(`getPostsForUserResponse: ${data}`) + + let message = data.message; + log(`Net: got ${message.post_ids.length} post IDs for user ${logID(message.user_id)} from peer ${logID(data.from)}`); + + + let startTime = app.timerStart(); + let postIds = await checkPostIds(message.user_id, message.post_ids); + log(`ID Check for user ${logID(message.user_id)} took ${app.timerDelta().toFixed(2)}ms`); + log(`Need ${postIds.length} posts for user ${logID(message.user_id)} from peer ${logID(data.from)}`); + + if (postIds.length === 0) { + return; + } + + log(`Net: Req ${postIds.length} posts for user ${logID(message.user_id)} from peer ${logID(data.from)}`) + let responseMessage = { type: "peer_message", from: app.peerID, to: data.from, from_username: app.username, from_peername: app.peername, message: { type: "get_posts_for_user", post_ids: postIds, user_id: message.user_id } } + + this.send(responseMessage); + } + + + + // static async compressArrayBuffer(data: ArrayBuffer): Promise { + // const compressionStream = new CompressionStream('gzip'); // You can also use 'deflate', 'deflate-raw', etc. + + // const compressedStream = new Response( + // new Blob([data]).stream().pipeThrough(compressionStream) + // ); + + // const compressedArrayBuffer = await compressedStream.arrayBuffer(); + + // return compressedArrayBuffer; + // } + postBlockList = new Set([ + '1c71f53c-c467-48e4-bc8c-39005b37c0d5', + '64203497-f77b-40d6-9e76-34d17372e72a', + '243130d8-4a41-471e-8898-5075f1bd7aec', + 'e01eff89-5100-4b35-af4c-1c1bcb007dd0', + '194696a2-d850-4bb0-98f7-47416b3d1662', + 'f6b21eb1-a0ff-435b-8efc-6a3dd70c0dca', + 'dd1d92aa-aa24-4166-a925-94ba072a9048' + ]); + + async getPostIdsForUserHandler(data: any) { + let message = data.message; + let postIds = await getAllIds(message.user_id) ?? []; + postIds = postIds.filter((postID: string) => !this.postBlockList.has(postID)); + if (postIds.length === 0) { + log(`Net: I know about user ${logID(message.user_id)} but I have 0 posts, so I'm not sending any to to peer ${logID(data.from)}`); + return; + } + log(`Net: Sending ${postIds.length} post Ids for user ${logID(message.user_id)} to peer ${logID(data.from)}`) + + let responseMessage = { type: "peer_message", from: app.peerID, to: data.from, from_username: app.username, from_peername: app.peername, message: { type: "get_post_ids_for_user_response", post_ids: postIds, user_id: message.user_id } } + this.send(responseMessage); + } + + async broadcastNewPost(userID: string, post: any) { + + let newPost = { ...post } + if (post.image_data) { + newPost.image_data = await arrayBufferToBase64(post.image_data); + } + + for (let [peerID, peerInfo] of this.seenPeers.entries()) { + log(`broadcastNewPost: sending new post to ${logID(peerID)}:${peerInfo.peerName}:${peerInfo.userName}`); + + this.sendPostsForUser(peerID, app.userID, [newPost]) + } + } + + + async sendPostsForUser(toPeerID: string, userID: string, posts: any) { + let responseMessage = { + type: "peer_message", + from: app.peerID, + to: toPeerID, + from_username: app.username, + from_peername: app.peername, + message: { + type: "get_posts_for_user_response", + posts: posts, + user_id: userID + } + } + + return this.send(responseMessage); + + } + + // Send posts to peer + async getPostsForUserHandler(data: any) { + let message = data.message; + let posts = await getPostsByIds(message.user_id, message.post_ids) ?? []; + + log(`Net: Sending ${posts.length} posts for user ${logID(message.user_id)} to peer ${logID(data.from)}`); + + app.timerStart(); + let output = []; + + console.log("Serializing images"); + for (let post of posts) { + let newPost = (post as any).data; + + if (newPost.image_data) { + // let compressedData = await wsConnection.compressArrayBuffer(newPost.image_data); + // console.log((newPost.image_data.byteLength - compressedData.byteLength) / 1024 / 1024); + + // TODO don't do this, use Blobs direclty! + // https://developer.chrome.com/blog/blob-support-for-Indexeddb-landed-on-chrome-dev + + newPost.image_data = await arrayBufferToBase64(newPost.image_data); + + } + + // let megs = JSON.stringify(newPost).length/1024/1024; + // console.log(`getPostsForUserHandler id:${newPost.post_id} post length:${megs}`); + output.push(newPost); + } + + let responseMessage = { type: "peer_message", from: app.peerID, to: data.from, from_username: app.username, from_peername: app.peername, message: { type: "get_posts_for_user_response", posts: output, user_id: message.user_id } } + + console.log("Sending posts"); + await this.sendPostsForUser(data.from, message.user_id, output); + let sendTime = app.timerDelta(); + log(`getPostsForUserHandler send took: ${sendTime.toFixed(2)}ms`); + + } + + + + // Got posts from peer + async getPostsForUserReponseHandler(data: any) { + app.timerStart(); + let message = data.message; + console.log(`Net: got ${message.posts.length} posts for user ${logID(message.user_id)} from peer ${logID(data.from)}`); + for (let post of message.posts) { + + // HACK: Some posts have insanely large images, so I'm gonna skip them. + // Once we support delete then we we could delete these posts in a sensible way. + if (this.postBlockList.has(post.post_id)) { + log(`Skipping blocked post: ${post.post_id}`); + continue; + } + + // HACK - some posts had the wrong author ID + if (message.user_id === app.userID) { + post.author_id = app.userID; + } + + post.post_timestamp = new Date(post.post_timestamp); + if (post.image_data) { + post.image_data = await base64ToArrayBuffer(post.image_data); + } + } + console.log(`Merging same user peer posts...`) + await mergeDataArray(message.user_id, data.message.posts); + + let receiveTime = app.timerDelta(); + + log(`getPostsForUserReponseHandler receive took: ${receiveTime.toFixed(2)}ms`); + + + if (message.user_id === app.getPreferentialUserID() || app.following.has(message.user_id)) { + app.render(); + } + } + + + + + async peerMessageHandler(data: PeerMessage) { + // log(`peerMessageHandler ${JSON.stringify(data)}`) + + this.seenPeers.set(data.from, { peerName: data.from_peername, userName: data.from_username }); + + let peerMessageType = data.message.type; + + let handler = this.peerMessageHandlers.get(peerMessageType); + + if (!handler) { + console.error(`got peer message type we don't have a handler for: ${peerMessageType}`); + return; + } + + handler(data); + } + + userBlockList = new Set([ + '5d63f0b2-a842-41bf-bf06-e0e4f6369271', + '5f1b85c4-b14c-454c-8df1-2cacc93f8a77', + // 'bba3ad24-9181-4e22-90c8-c265c80873ea' + ]) + + + // Hello2 + // Goal, connect to bootstrap peer, ask bootstrap peer for peers that have posts from users that we care about. get peers, connect to those peers, sync. + // how? do "perfect negotiation" with bootstrap peer. All logic here moves to BP. + + async sendHello2() { + this.send({ + type: "hello2", + user_id: this.userID, + user_name: app.username, + peer_id: this.peerID, + session_id: this.sessionID, + peer_name: app.peername, + is_bootstrap_peer: app.isBootstrapPeer, + peer_description: this.rtcPeerDescription + }); + } + + async sendHello() { + // TODO only get users you're following here. ✅ + let knownUsers = [...(await indexedDB.databases())].map(db => db.name?.replace('user_', '')).filter(userID => userID !== undefined); + knownUsers = knownUsers + .filter(userID => this.shouldSyncUserID(userID)) + .filter(userID => !this.userBlockList.has(userID)) + .filter(async userID => (await getAllIds(userID)).length > 0); // TODO:EASYOPT getting all the IDs is unecessary, replace it with a test to get a single ID. + + console.log('Net: Sending known users', knownUsers.map(userID => logID(userID ?? ""))); + return await this.send({ type: "hello", user_id: this.userID, user_name: app.username, peer_id: this.peerID, peer_name: app.peername, known_users: knownUsers }); + } + + hello2ResponseHandler(data: any) { + + } + + helloResponseHandler(data: any) { + + let users = []; + let receivedUsers = Object.entries(data.userPeers); + log(`Net: got ${receivedUsers.length} users from bootstrap peer.`) + + try { + let preferentialUserID = app.getPreferentialUserID(); + let currentUserPeers = data.userPeers[preferentialUserID]; + users.push([preferentialUserID, currentUserPeers]); + delete data.userPeers[preferentialUserID]; + } catch (e) { + console.log('helloResponseHandler', e); + } + + let getAllUsers = app.router.route !== App.Route.USER + if (getAllUsers) { + users = [...users, ...Object.entries(data.userPeers).filter(userID => this.shouldSyncUserID(userID[0]))]; + } + + // log(`Net: got ${users.length} users from bootstrap peer. \n${users.map((user)=>user[0]).join('\n')}`) + + for (let [userID, peerIDs] of users) { + if (this.userBlockList.has(userID)) { + console.log("Skipping user on blocklist:", userID) + continue; + } + + // this.peers.set(userID, [...peerIDs]); + + for (let peerID of [...peerIDs]) { + if (peerID === this.peerID) { + continue; + } + + log(`Net: Req post IDs for user ${logID(userID)} from peer ${logID(peerID)}`); + this.send({ + type: "peer_message", + from: this.peerID, + from_username: app.username, + from_peername: app.peername, + to: peerID, + message: { type: "get_post_ids_for_user", user_id: userID } + }) + } + } + } + + connect(): void { + if (this.websocket?.readyState === WebSocket.OPEN) { + return; + } + + window.clearInterval(this.websocketPingInterval); + if (this.websocket) { this.websocket.close() }; + + try { + this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); + } catch (error: any) { + console.log(error.message); + return; + } + + this.websocket.onopen = async (event) => { + log("ws:connected"); + await this.sendHello2(); + + // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. + // let helloRefreshIntervalPeriod = 120; + // if (app.isHeadless) { + // console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) + // this.helloRefreshInterval = window.setInterval(() => { + // console.log("wsConnection: Hello refresh.") + + // if (!navigator.onLine) { + // return; + // } + // this.sendHello(); + // }, helloRefreshIntervalPeriod * 1000); + // } + + this.websocketPingInterval = window.setInterval(() => { + if (!navigator.onLine) { + return; + } + this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); + }, 10_000) + }; + + // this.websocket.onopen = async (event) => { + // log("ws:connected"); + // await this.sendHello(); + + // // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. + // let helloRefreshIntervalPeriod = 120; + // if (app.isHeadless) { + // console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) + // this.helloRefreshInterval = window.setInterval(() => { + // console.log("wsConnection: Hello refresh.") + + // if (!navigator.onLine) { + // return; + // } + // this.sendHello(); + // }, helloRefreshIntervalPeriod * 1000); + // } + + // this.websocketPingInterval = window.setInterval(() => { + // if (!navigator.onLine) { + // return; + // } + // this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); + // }, 10_000) + // }; + + this.websocket.onclose = (event) => { + log("ws:disconnected"); + // this.retry *= 2; + log(`Retrying in ${this.retry} seconds`); + window.setTimeout(() => { this.connect(); }, this.retry * 1000); + }; + + this.websocket.onmessage = (event) => { + // log('ws:<-' + event.data.slice(0, 240)); + let data = JSON.parse(event.data); + + let { type } = data; + + let handler = this.messageHandlers.get(type); + if (!handler) { + console.warn(`Got a message we can't handle:`, type); + return; + } + + handler(data); + + }; + + this.websocket.onerror = (event) => { + log('ws:error: ' + event); + }; + } + + disconnect() { + this.websocket?.close(); + } +} + +class App { + username: string = ''; + peername: string = ''; + userID: string = ''; + peerID: string = ''; + following: Set = new Set(); + posts: StoragePost[] = []; + isHeadless: boolean = false; + isBootstrapPeer: boolean = false; + showLog: boolean = false; + markedAvailable = false; + limitPosts = 50; + websocket: wsConnection | null = null; + // vizGraph: any | null = null; + qrcode: any = null; + connectURL: string = ""; + firstRun = false; + peerManager: PeerManager | null = null; + + getPreferentialUserID() { + return this.router.userID.length !== 0 ? this.router.userID : this.userID; + } + + initMarkdown() { + if (typeof marked === "undefined") { + return; + } + + const renderer = new marked.Renderer(); + renderer.link = (href: any, title: string, text: string) => { + return `${text}`; + }; + marked.setOptions({ renderer: renderer }); + + this.markedAvailable = true; + } + + // arrayBufferToBase64(buffer: ArrayBuffer) { + // return new Promise((resolve, reject) => { + // const blob = new Blob([buffer], { type: 'application/octet-stream' }); + // const reader = new FileReader(); + + // reader.onloadend = () => { + // const dataUrl = reader.result as string; + // if (!dataUrl) { + // resolve(null); + // return; + // } + // const base64 = dataUrl.split(',')[1]; + // resolve(base64); + // }; + + // reader.onerror = (error) => { + // reject(error); + // }; + + // reader.readAsDataURL(blob); + // }); + // } + + async createTestData() { + let postsTestData = await (await fetch("./postsTestData.json")).json(); + + return postsTestData; + } + + time = 0; + + timerStart() { + this.time = performance.now(); + } + + timerDelta() { + return performance.now() - this.time; + } + + getFixedTweetText(entry: any) { + + + let fullText = entry.tweet.full_text; + + let linkMarkdown = ""; + for (const url of entry.tweet.entities.urls) { + linkMarkdown = `[${url.display_url}](${url.expanded_url})`; + fullText = fullText.replace(url.url, linkMarkdown); + } + + return fullText + } + + downloadBinary(data: ArrayBuffer, filename: string, mimeType: string = 'application/octet-stream') { + // Create a blob from the ArrayBuffer with the specified MIME type + const blob = new Blob([data], { type: mimeType }); + + // Create object URL from the blob + const url = window.URL.createObjectURL(blob); + + // Create temporary link element + const link = document.createElement('a'); + link.href = url; + link.download = filename; + + // Append link to body, click it, and remove it + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // Clean up the object URL + window.URL.revokeObjectURL(url); + } + + downloadJson(data: any, filename = 'data.json') { + const jsonString = JSON.stringify(data); + const blob = new Blob([jsonString], { type: 'application/json' }); + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = filename; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + } + + async importPostsForUser(userID: string, posts: string) { + + } + + async exportPostsForUser(userID: string) { + + let posts = await getAllData(userID); + + let output = []; + + console.log("Serializing images"); + for (let post of posts) { + let newPost = (post as any).data; + + if (newPost.image_data) { + newPost.image_data = await arrayBufferToBase64(newPost.image_data); + } + + output.push(newPost); + } + + let compressedData = await compressString(JSON.stringify(output)); + + const d = new Date(); + const timestamp = `${d.getFullYear() + }_${String(d.getMonth() + 1).padStart(2, '0') + }_${String(d.getDate()).padStart(2, '0') + }_${String(d.getHours()).padStart(2, '0') + }_${String(d.getMinutes()).padStart(2, '0') + }_${String(d.getSeconds()).padStart(2, '0')}`; + + + this.downloadBinary(compressedData, `ddln_${this.username}_export_${timestamp}.json.gz`); + } + + async importTweetArchive(userID: string, tweetArchive: any[]) { + log("Importing tweet archive") + let postsTestData: any[] = []; + + // let response = await fetch("./tweets.js"); + // let tweetsText = await response.text(); + // tweetsText = tweetsText.replace("window.YTD.tweets.part0", "window.tweetData"); + + // new Function(tweetsText)(); + + + // let tweets = JSON.parse(tweetJSON); + let count = 0; + + for (let entry of tweetArchive) { + // if (entry.tweet.hasOwnProperty("in_reply_to_screen_name") || entry.tweet.retweeted || entry.tweet.full_text.startsWith("RT")) { + // continue; + // } + + let mediaURL: string = entry.tweet?.entities?.media?.[0]?.media_url_https; + let isImage = false; + if (mediaURL) { + isImage = mediaURL.includes('jpg'); + } + + let imageData = null; + // if (isImage) { + // try { + // let response = await fetch(mediaURL); + // await waitMs(100); + // if (response.status === 200) { + // imageData = await response.arrayBuffer(); + // } + // console.log(imageData); + // } catch (e) { + // console.log(e); + // } + + // } + + let timeStamp = new Date(entry.tweet.created_at); + let tweetText = this.getFixedTweetText(entry); + let newPost = new Post('bobbydigitales', userID, tweetText, timeStamp, imageData, 'twitter', entry); + + postsTestData.push(newPost); + + count++; + if (count % 100 === 0) { + log(`Imported ${count} posts...`); + // render(postsTestData); + } + + // if (count == 100-1) { + // break; + // } + + } + return postsTestData; + } + + async createTestData3(userID: string) { + let posts = await (await (fetch('./posts.json'))).json(); + + return posts; + } + + async registerServiceWorker() { + if (!("serviceWorker" in navigator)) { + return; + } + + let registrations = await navigator.serviceWorker.getRegistrations(); + if (registrations.length > 0) { + console.log("Service worker already registered."); + return registrations[0]; + } + + navigator.serviceWorker + .register("/sw.js") + .then((registration) => { + console.log("Service Worker registered with scope:", registration.scope); + return registration; + }) + .catch((error) => { + console.error("Service Worker registration failed:", error); + }); + } + + async compressImage(imageData: ArrayBuffer, mimeType: string, quality = 0.5): Promise { + let uncompressedByteLength = imageData.byteLength; + log(`compressImage input:${mimeType} size:${(uncompressedByteLength / 1024).toFixed(2)}KBi quality:${quality}`); + + try { + // Convert ArrayBuffer to Blob + const blob = new Blob([imageData], { type: mimeType }); + + const bitmap = await createImageBitmap(blob, { + imageOrientation: 'none', + + // resizeWidth: desiredWidth, + // resizeHeight: desiredHeight, + // resizeQuality: 'high', + }); + + // const bitmap = await createImageBitmap(bitmapTemp, { + // imageOrientation: 'none', + + // resizeWidth: 600, + // resizeHeight: 800, + // // resizeHeight: (bitmapTemp.height / bitmapTemp.width) * 600, + // resizeQuality: 'high', + // }) + + //drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) + + + // Create a canvas and draw the image onto it + // let scale = 1/32; + // let scaledWidth = bitmap.width*scale; + // let scaledHeight = bitmap.height*scale; + + // let scale = 1/32; + + let scaledWidth = bitmap.width; + let scaledHeight = bitmap.height; + + let resizeThreshold = 600; + if (scaledWidth > resizeThreshold) { + scaledWidth = resizeThreshold; + scaledHeight = (bitmap.height / bitmap.width) * resizeThreshold; + } + + const canvas = document.createElement('canvas'); + canvas.width = scaledWidth; + canvas.height = scaledHeight; + const ctx = canvas.getContext('2d'); + ctx!.imageSmoothingEnabled = true; + ctx!.imageSmoothingQuality = 'high'; + canvas!.getContext('2d')!.drawImage(bitmap, 0, 0, bitmap.width, bitmap.height, 0, 0, scaledWidth, scaledHeight); + + + // Compress the image and get the result as an ArrayBuffer + const compressedBlob = await new Promise((resolve, reject) => + canvas.toBlob( + (blob) => (blob ? resolve(blob as Blob) : reject(new Error('Compression failed.'))), + 'image/jpeg', + quality + ) + ); + + + // TODO: Don't need to do this as we'll be storing blobs directly. + let compressedArrayBuffer = await (compressedBlob as Blob).arrayBuffer(); + let compressedByteLength = compressedArrayBuffer.byteLength; + + let percent = (uncompressedByteLength / compressedByteLength) + log(`compressImage: compressedSize:${(compressedArrayBuffer.byteLength / 1024).toFixed(2)}KBi ${percent.toFixed(2)}:1 compression`); + return compressedArrayBuffer; + } catch (e) { + console.error(e); + return null; + } + } + + async createNewPost(userID: string, postText: string, mediaData?: ArrayBuffer, mimeType?: "image/png" | "image/gif" | "image/jpg" | "image/jpeg" | "video/mp4") { + if ((typeof postText !== "string") || postText.length === 0) { + log("Not posting an empty string...") + return; + } + + if (mediaData && + (mimeType === 'image/jpg' || mimeType === 'image/jpeg' || mimeType === 'image/png') && + (mediaData as ArrayBuffer).byteLength > 500 * 1024) { + let compressedImage = await this.compressImage(mediaData as ArrayBuffer, mimeType, 0.9); + if (compressedImage) { + mediaData = compressedImage as ArrayBuffer; + } + } + + let post = new Post(this.username, userID, postText, new Date(), mediaData); + // this.posts.push(post); + // localStorage.setItem(key, JSON.stringify(posts)); + addData(userID, post); + + this.websocket?.broadcastNewPost(userID, post); + + + this.render(); + } + + getPeerID() { + let id = localStorage.getItem("peer_id"); + + if (!id) { + log(`Didn't find a peer ID, generating one`); + id = generateID(); + localStorage.setItem("peer_id", id); + } + + return id; + } + + getUserID() { + let id = localStorage.getItem("dandelion_id"); + + if (!id) { + log(`Didn't find a user ID, generating one`); + id = generateID(); + localStorage.setItem("dandelion_id", id); + } + + return id; + } + + animals = ['shrew', 'jerboa', 'lemur', 'weasel', 'possum', 'possum', 'marmoset', 'planigale', 'mole', 'narwhal']; + adjectives = ['snazzy', 'whimsical', 'jazzy', 'bonkers', 'wobbly', 'spiffy', 'chirpy', 'zesty', 'bubbly', 'perky', 'sassy']; + snakes = ['mamba', 'cobra', 'python', 'viper', 'krait', 'sidewinder', 'constrictor', 'boa', 'asp', 'anaconda', 'krait'] + + hashIdToIndices(id: string) { + let indices = []; + for (let char of id) { + if (char !== '0' && char !== '-') { + indices.push(parseInt(char, 16)); + if (indices.length == 2) { + break; + } + } + } + return [indices[0], indices[1]]; + } + + funkyName(id: string, listOne: string[], listTwo: string[]) { + let [one, two] = this.hashIdToIndices(id); + let first = listOne[one % this.adjectives.length]; + let second = listTwo[two % this.animals.length]; + return { first, second } + } + + 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}` + 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}` + return peername; + } + + setFont(fontName: string, fontSize: string) { + + let content = document.getElementById('content'); + + if (!content) { + return; + } + + content.style.fontFamily = fontName; + content.style.fontSize = fontSize; + + let textArea = document.getElementById('textarea_post'); + if (!textArea) { + return; + } + + textArea.style.fontFamily = fontName; + textArea.style.fontSize = fontSize; + } + + initOffline(connection: wsConnection) { + // Event listener for going offline + window.addEventListener('offline', () => { + log("offline") + }); + + // Event listener for going online + window.addEventListener('online', async () => { + log("online") + connection.connect(); + this.render(); + }); + + log(`Online status: ${navigator.onLine ? "online" : "offline"}`) + + } + + selectFile(contentType: string): Promise { + return new Promise(resolve => { + let input = document.createElement('input'); + input.type = 'file'; + // input.multiple = multiple; + input.accept = contentType; + + input.onchange = () => { + if (input.files == null) { + resolve(null); + return; + } + + let files = Array.from(input.files); + + // if (multiple) + // resolve(files); + // else + resolve(files[0]); + }; + + input.click(); + }); + } + + readFile(file: File): Promise { + // Always return a Promise + return new Promise((resolve, reject) => { + let content = ''; + const reader = new FileReader(); + // Wait till complete + reader.onloadend = function (e: any) { + content = e.target.result; + resolve(content); + }; + // Make sure to handle error states + reader.onerror = function (e: any) { + reject(e); + }; + reader.readAsText(file); + }); + } + + async lazyCreateQRCode() { + if (this.qrcode != null) { + return; + } + this.qrcode = await new QRCode(document.getElementById('qrcode'), { + text: this.connectURL, + width: 150, + height: 150, + colorDark: "#000000", + colorLight: "#ffffff", + correctLevel: QRCode.CorrectLevel.H + }); + } + + showInfo() { + let infoElement = document.getElementById('info'); + + if (infoElement === null) { + return; + } + infoElement.style.display == 'none' ? infoElement.style.display = 'block' : infoElement.style.display = 'none'; + logVisible = infoElement.style.display == 'block'; + renderLog(); + this.lazyCreateQRCode(); + (document.querySelector('#qrcode > img') as HTMLImageElement).classList.add('qrcode_image'); + (document.querySelector('#qrcode > canvas') as HTMLImageElement).classList.add('qrcode_image'); + + this.showLog = true; + + + } + + button(elementName: string) { + return document.getElementById(elementName) as HTMLButtonElement; + } + + div(elementName: string) { + return document.getElementById(elementName) as HTMLDivElement; + } + + initButtons(userID: string, posts: StoragePost[], registration: ServiceWorkerRegistration | undefined) { + // let font1Button = document.getElementById("button_font1") as HTMLButtonElement; + // let font2Button = document.getElementById("button_font2") as HTMLButtonElement; + // let importTweetsButton = document.getElementById("import_tweets") as HTMLButtonElement; + // let toggleDark = document.getElementById('toggle_dark') as HTMLButtonElement; + // let clearPostsButton = document.getElementById("clear_posts") as HTMLButtonElement; + // let updateApp = document.getElementById("update_app") as HTMLButtonElement; + // let ddlnLogoButton = document.getElementById('ddln_logo_button') as HTMLDivElement; + // let addPic = document.getElementById('button_add_pic') as HTMLDivElement; + // toggleDark.addEventListener('click', () => { + // document.documentElement.style.setProperty('--main-bg-color', 'white'); + // document.documentElement.style.setProperty('--main-fg-color', 'black'); + // }) + + let homeButton = this.div('home-button'); + homeButton.addEventListener('click', e => window.location.href = `${window.location.origin}/`) + + let profileButton = this.div('profile-button'); + profileButton.addEventListener('click', e => window.location.href = `${window.location.origin}/user/${this.userID}`) + + let monitorButton = this.div('monitor_button'); + monitorButton.addEventListener('click', async () => { + navContainer.classList.toggle('active'); + this.showInfo() + }); + + let navContainer = this.div('nav-container'); + let burgerMenuButton = this.div('burger-menu-button'); + burgerMenuButton.addEventListener('click', e => navContainer.classList.toggle('active')); + + let exportButton = this.button("export-button"); + exportButton.addEventListener('click', async e => { + + await this.exportPostsForUser(this.userID) + }); + + let composeButton = this.div('compose-button'); + composeButton.addEventListener('click', e => { + document.getElementById('compose')!.style.display = 'block'; + document.getElementById('textarea_post')?.focus(); + }); + + + let filePicker = document.getElementById('file-input') as HTMLInputElement; + filePicker?.addEventListener('change', async (event: any) => { + for (let file of filePicker.files as any) { + let buffer = await file.arrayBuffer(); + await this.createNewPost(this.userID, 'image...', buffer, file.type); + } + + // Reset so that if they pick the same image again, we still get the change event. + filePicker.value = ''; + }); + + let filePickerLabel = document.getElementById('file-input-label'); + filePickerLabel?.addEventListener('click', () => { + console.log("Add pic...") + }) + + + let usernameField = document.getElementById('username'); + usernameField?.addEventListener('input', (event: any) => { + this.username = event.target.innerText; + localStorage.setItem("dandelion_username", this.username); + }) + + // importTweetsButton.addEventListener('click', async () => { + // let file = await this.selectFile('text/*'); + + // console.log(file); + // if (file == null) { + // return; + // } + + // let tweetData = await this.readFile(file); + // tweetData = tweetData.replace('window.YTD.tweets.part0 = ', ''); + // const tweets = JSON.parse(tweetData); + + // let imported_posts = await this.importTweetArchive(userID, tweets); + // clearData(userID); + // // posts = posts.reverse(); + // addDataArray(userID, imported_posts); + // this.render(); + + // }); + + // clearPostsButton.addEventListener('click', () => { clearData(userID); posts = []; this.render() }); + + + let postButton = document.getElementById("button_post") as HTMLButtonElement; + let postText = document.getElementById("textarea_post") as HTMLTextAreaElement; + + if (!(postButton && postText)) { + throw new Error(); + } + + postText.addEventListener('paste', async (e) => { + const dataTransfer = e.clipboardData + const file = dataTransfer!.files[0]; + let buffer = await file.arrayBuffer(); + await this.createNewPost(this.userID, 'image...', buffer, file.type as any); + }); + + postButton.addEventListener("click", () => { + this.createNewPost(userID, postText.value); + postText.value = ""; + document.getElementById('compose')!.style.display = 'none'; + }); + + // updateApp.addEventListener("click", () => { + // registration?.active?.postMessage({ type: "update_app" }); + // }); + + + // ddlnLogoButton.addEventListener('click', async () => { + // this.showInfo() + // }); + + } + + async getPostsForFeed() { + + // get N posts from each user and sort them by date. + // This isn't really going to work very well. + // Eventually we'll need a db that only has followed user posts so we can get them chronologically + // + let posts: StoragePost[] = []; + for (let followedID of this.following.keys()) { + posts = posts.concat(await getData(followedID, new Date(2022, 8), new Date())); + // console.log(followedID); + } + + // @ts-ignore + posts = posts.sort((a, b) => a.post_timestamp - b.post_timestamp); + + return posts; + } + + async loadFollowersFromStorage(userID: string): Promise { + + // Rob + if (userID === 'b38b623c-c3fa-4351-9cab-50233c99fa4e') { + return [ + 'b38b623c-c3fa-4351-9cab-50233c99fa4e', + '6d774268-16cd-4e86-8bbe-847a0328893d', // Sean + '05a495a0-0dd8-4186-94c3-b8309ba6fc4c', // Martin + 'a0e42390-08b5-4b07-bc2b-787f8e5f1297', // BMO + 'bba3ad24-9181-4e22-90c8-c265c80873ea', // Harry + '8f6802be-c3b6-46c1-969c-5f90cbe01479', // Fiona + ] + } + + // Martin + if (userID === '05a495a0-0dd8-4186-94c3-b8309ba6fc4c') { + return [ + 'b38b623c-c3fa-4351-9cab-50233c99fa4e', + 'a0e42390-08b5-4b07-bc2b-787f8e5f1297', // BMO + ] + } + + // Fiona + if (userID === '8f6802be-c3b6-46c1-969c-5f90cbe01479') { + return [ + 'b38b623c-c3fa-4351-9cab-50233c99fa4e', // Rob + 'a0e42390-08b5-4b07-bc2b-787f8e5f1297', // BMO + '05a495a0-0dd8-4186-94c3-b8309ba6fc4c', // Martin + ] + } + + return ['a0e42390-08b5-4b07-bc2b-787f8e5f1297']; // Follow BMO by default :) + } + + async loadPostsFromStorage(userID: string, postID?: string) { + + this.timerStart(); + let posts: StoragePost[] = []; + + // if (postID) { + // posts = await gePostForUser(userID, postID); + // } + + posts = await getData(userID, new Date(2022, 8), new Date()); + + if (posts.length > 0) { + log(`Loaded ${posts.length} posts in ${this.timerDelta().toFixed(2)}ms`); + return posts; + } + + // posts = await createTestData2(userID); + + // log("Adding test data..."); + // addDataArray(userID, posts); + // return await getData(userID, new Date(2022, 8), new Date()); + } + + async listUsers() { + let knownUsers = [...(await indexedDB.databases())].map((db) => db.name?.replace('user_', '')); + if (knownUsers.length === 0) { + return; + } + + let preferredId = app.getPreferentialUserID() + for (let userID of knownUsers as string[]) { + // if (userID === preferredId) { + // continue; + // } + + // let ids = await getAllIds(userID); + // if (ids.length === 0) { + // console.log(`Purging user ${userID}`); + // indexedDB.deleteDatabase(`user_${userID}`); + // continue; + // } + + console.log(`${document.location.origin}/user/${userID}`); + + // console.log(`https://ddln.app/${this.username}/${uuidToBase58(userID)}`, userID); + } + + } + + + async initDB() { + let db = await openDatabase(this.userID); + } + + query_findPeersForUser(message: any) { + let havePostsForUser = true; + if (havePostsForUser) { + return this.peerID; + } + + return false; + } + + async testPeerManager() { + if (!this.peerManager) { + throw new Error(); + } + + this.peerManager.registerRPC('getPostIDsForUser', (args: any) => { + return [1, 2, 3, 4, 5] + }); + + let postIDs = await this.peerManager.rpc.getPostIDsForUser("dummy_peer", "bloop"); + + console.log("peerManager.rpc.getPostIDsForUser", postIDs); + + // this.peerManager.registerSearchQuery('find_peers_for_user', this.query_findPeersForUser); + + // let peers = await this.peerManager.search('find_peers_for_user', { 'user_id': 'bloop' }); + + } + + async main() { + + // Do capability detection here and report in a simple way if things we need don't exist with guidance on how to resolve it. + + let urlParams = (new URL(window.location.href)).searchParams; + if (urlParams.has('log')) { + this.showInfo(); + } + + this.isHeadless = /\bHeadlessChrome\//.test(navigator.userAgent); + this.isBootstrapPeer = urlParams.has("bootstrap"); + if (this.isBootstrapPeer) { + log(`This is a bootstrap peer`); + } + + this.peerID = this.getPeerID(); + this.peername = this.getPeername(); + this.userID = this.getUserID(); + this.username = this.getUsername(); + + this.peerManager = new PeerManager(this.userID, this.peerID, this.isBootstrapPeer); + this.testPeerManager(); + + // let peer: RTCPeerConnection | null = null; + // // if (window.RTCPeerConnection) { + // peer = new RTCPeerConnection({ + // iceServers: [ + // { 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 return 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" }, + // ] + // }); + + // peer.createDataChannel('boop'); + + // peer.onicecandidate = ({ candidate }) => { log(`WRTC:${candidate?.address} ${candidate?.protocol} ${candidate?.type} ${(candidate as any)?.url}`) }; + // peer.onnegotiationneeded = async (event) => { + // log("on negotiation needed fired"); + + // let makingOffer = false; + + // try { + // makingOffer = true; + // await peer.setLocalDescription(); + + // let IDsToSync = this.following; + // if (this.router.route === App.Route.USER) { + // IDsToSync = new Set([this.router.userID]); + // } + + // if (!peer.localDescription) { + // return; + // } + + // // this.websocket = new wsConnection(this.userID, this.peerID, IDsToSync, peer.localDescription); + // // log(peer.localDescription.type + ":" + peer.localDescription.sdp); + // // this.initOffline(this.websocket); + + // // this.websocket?.sendWebRTCDescription(peer.localDescription); + // } catch (err) { + // console.error(err); + // } finally { + // makingOffer = false; + // } + + // } + + + + + // peer.createOffer().then((description)=>{ + // peer.setLocalDescription(description) + // log("RTC: " + description.sdp + description.type); + // }); + + // } + + // await this.exportPostsForUser('b38b623c-c3fa-4351-9cab-50233c99fa4e'); + + // Get initial state and route from URL and user agent etc + + // Set local state (userid etc) based on that. + + // Init libraries + + // Render + // Load all images async + // Start the process of figuring out what posts we need + // Download posts once all current images are loaded + + + // window.resizeTo(645, 900); + + // this.initLogo() + + + this.getRoute(); + + if (this.router.route === App.Route.CONNECT) { + console.log('connect', this.router.userID); + localStorage.setItem("dandelion_id", this.router.userID); + localStorage.removeItem("dandelion_username"); + } + + + await this.initDB(); + + this.connectURL = `${document.location.origin}/connect/${this.userID}`; + document.getElementById('connectURL')!.innerHTML = `connect`; + + + + this.isHeadless = urlParams.has('headless'); + + let limitPostsParam = urlParams.get('limitPosts'); + if (limitPostsParam) { + this.limitPosts = parseInt(limitPostsParam); + } + + let time = 0; + let delta = 0; + // let isPersisted = await navigator?.storage?.persisted(); + // if (!isPersisted) { + // debugger; + // const isPersisted = await navigator.storage.persist(); + // log(`Persisted storage granted: ${isPersisted}`); + // } + + // log(`Persisted: ${(await navigator?.storage?.persisted())?.toString()}`); + + this.initMarkdown(); + + // let main = await fetch("/main.js"); + // let code = await main.text(); + // console.log(code); + // registration.active.postMessage({type:"updateMain", code:code}); + + // this.posts = await this.loadPosts(userID) ?? []; + + // debugger; + + await this.render(); // , (postID:string)=>{this.deletePost(userID, postID)} + + if ((performance as any)?.memory) { + log(`memory used: ${((performance as any).memory.usedJSHeapSize / 1024 / 1024).toFixed(2)}Mb`) + } + + // if (navigator?.storage) { + // let storageUsed = (await navigator?.storage?.estimate())?.usage/1024/1024 + // } + + // if (urlParams.get("sw") === "true") { + let registration; + registration = await this.registerServiceWorker(); + // } + + document.getElementById('username')!.innerText = `${this.username}`; + document.getElementById('peername')!.innerText = `peername:${this.peername}`; + document.getElementById('user_id')!.innerText = `user_id:${this.userID}`; + document.getElementById('peer_id')!.innerText = `peer_id:${this.peerID}`; + + this.initButtons(this.userID, this.posts, registration); + + + + log(`username:${this.username} user:${this.userID} peername:${this.peername} peer:${this.peerID}`); + + // await this.purgeEmptyUsers(); + + + + // this.listUsers() + + + // this.createNetworkViz(); + + // const client = new WebTorrent() + + // // Sintel, a free, Creative Commons movie + // const torrentId = 'magnet:?xt=urn:btih:6091e199a8d9272a40dd9a25a621a5c355d6b0be&dn=WING+IT!+-+Blender+Open+Movie+1080p.mp4&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337'; + + // client.add(torrentId, function (torrent: any) { + // // Torrents can contain many files. Let's use the .mp4 file + // const file = torrent.files.find(function (file: any) { + // return file.name.endsWith('.mp4') + // }) + + // // Display the file by adding it to the DOM. + // // Supports video, audio, image files, and more! + // file.appendTo(document.getElementById('torrent-content')); + // }) + } + + renderWelcome(contentDiv: HTMLDivElement) { + contentDiv.innerHTML = `
+ Welcome to Dandelion v0.1!
+ Loading posts for the default feed... +
+ `; + } + + // keep a map of posts to dom nodes. + // on re-render + // posts that are not in our list that we need at add + // posts that are in our list that we need to remove + + private renderedPosts = new Map(); + + async render() { + if (this.isHeadless) { + console.log('Headless so skipping render...'); + return; + } + + performance.mark("render-start"); + this.timerStart(); + + + let existingPosts = this.posts; + + + + this.posts = []; + switch (this.router.route) { + case App.Route.HOME: + case App.Route.CONNECT: { + this.following = new Set(await this.loadFollowersFromStorage(this.userID) ?? []); + this.posts = await this.getPostsForFeed(); + // this.posts = await this.loadPostsFromStorage(this.userID) ?? []; + // let compose = document.getElementById('compose'); + // if (!compose) { + // break; + // } + // compose.style.display = "block"; + break; + } + case App.Route.USER: { + this.posts = await this.loadPostsFromStorage(this.router.userID) ?? []; + let compose = document.getElementById('compose'); + if (!compose) { + break; + } + + compose.style.display = "none"; + break; + } + case App.Route.POST: { + this.posts = await this.loadPostsFromStorage(this.router.userID, this.router.postID) ?? []; + let compose = document.getElementById('compose'); + if (!compose) { + break; + } + compose.style.display = "none"; + break; + } + default: { + console.log("Render: got a route I didn't understand. Rendering HOME:", this.router.route); + this.posts = await this.loadPostsFromStorage(this.userID) ?? []; + break; + } + } + let contentDiv = document.getElementById("content"); + if (!contentDiv) { + throw new Error(); + } + if (this.posts.length === 0) { + this.renderWelcome(contentDiv as HTMLDivElement); + return; + } + + + // let existingPostSet = new Set(existingPosts.map(post => post.post_id)); + // let incomingPostSet = new Set(this.posts.map(post => post.post_id)); + + // let addedPosts = []; + // for (let post of this.posts) { + // if (!existingPostSet.has(post.post_id)) { + // addedPosts.push(post); + // } + // } + + // let deletedPosts = []; + // for (let post of existingPosts) { + // if (!incomingPostSet.has(post.post_id)) { + // deletedPosts.push(post); + // } + // } + + // console.log("added:", addedPosts, "removed:", deletedPosts); + + const fragment = document.createDocumentFragment(); + + contentDiv.innerHTML = ""; + let count = 0; + + this.renderedPosts.clear(); + let first = true; + for (let i = this.posts.length - 1; i >= 0; i--) { + let postData = this.posts[i]; + // this.postsSet.add(postData); + // TODO return promises for all image loads and await those. + let post = this.renderPost(postData.data, first); + first = false; + // this.renderedPosts.set(postData.post_id, post); + if (post) { + fragment.appendChild(post); + count++; + } + if (count > this.limitPosts) { + break; + } + } + + + if (!contentDiv) { + throw new Error("Couldn't get content div!"); + } + + contentDiv.appendChild(fragment); + + let renderTime = this.timerDelta(); + + log(`render took: ${renderTime.toFixed(2)}ms`); + performance.mark("render-end"); + performance.measure('render-time', 'render-start', 'render-end'); + + + + // if ((performance as any)?.memory) { + // log(`memory used: ${((performance as any).memory.usedJSHeapSize / 1024 / 1024).toFixed(2)}Mb`) + // } + + } + + async deletePost(userID: string, postID: string) { + deleteData(userID, postID) + + this.render(); + } + + renderPost(post: Post, first: boolean) { + if (!(post.hasOwnProperty("text"))) { + throw new Error("Post is malformed!"); + } + let containerDiv = document.createElement("div"); + + let timestamp = `${post.post_timestamp.toLocaleTimeString()} · ${post.post_timestamp.toLocaleDateString()}`; + + let deleteButton = document.createElement('button'); deleteButton.innerText = 'delete'; + deleteButton.onclick = () => { this.deletePost(post.author_id, post.post_id) }; + + // let editButton = document.createElement('button'); editButton.innerText = 'edit'; + let shareButton = document.createElement('button'); shareButton.innerText = 'share'; + shareButton.onclick = async () => { + let shareUrl = `${document.location.origin}/user/${post.author_id}/post/${post.post_id}`; + + await navigator.clipboard.writeText(shareUrl) + }; + + let ownPost = post.author_id === this.userID; + + let markdown = post.text; + if (this.markedAvailable) { + markdown = marked.parse(post.text); + } + + // if (markdown.includes("${first ? '' : '
'} +
+ @${post.author} - + ${post.post_timestamp.toLocaleDateString()} + + ${ownPost ? `` : ''} + ${ownPost ? `` : ''} + +
+
${markdown}
+ ` + + containerDiv.innerHTML = postTemplate; + + + if (ownPost) { + containerDiv.querySelector('#deleteButton')?.appendChild(deleteButton); + // containerDiv.querySelector('#editButton')?.appendChild(editButton); + } + + + containerDiv.querySelector('#shareButton')?.appendChild(shareButton); + + + if (!("image_data" in post && post.image_data)) { + // containerDiv.appendChild(timestampDiv); + return containerDiv; + // return null; + } + + let image = document.createElement("img"); + image.title = `${(post.image_data.byteLength / 1024 / 1024).toFixed(2)}MBytes`; + // const blob = new Blob([post.image_data as ArrayBuffer], { type: 'image/png' }); + const blob = new Blob([post.image_data as ArrayBuffer]); + const url = URL.createObjectURL(blob); + image.onload = () => { + URL.revokeObjectURL(url); + }; + + image.src = url; + // image.src = image.src = "data:image/png;base64," + post.image; + image.className = "postImage"; + // image.onclick = () => { App.maximizeElement(image) }; + + containerDiv.appendChild(image); + // containerDiv.appendChild(timestampDiv); + + return containerDiv; + } + + static maximizeElement(element: HTMLImageElement) { + element.style.transform = "scale(2.0)" + } + + router = { + route: App.Route.HOME, + userID: '', + postID: '', + mediaID: '' + } + + getRoute() { + let path = document.location.pathname; + console.log(">>>>>>>>>>>>>>>>>>>>>>>>>", path); + + const regex = "(user/([a-zA-Z0-9\-]+)/?(post/([a-zA-Z0-9\-]+)?/?)?(media/([0-9]+)?)?)|(connect/([a-zA-Z0-9\-]+))"; + + const match = path.match(new RegExp(regex)); + + if (match) { + if (match[8]) { // Check for the connect route + this.router.userID = match[8]; + this.router.route = App.Route.CONNECT; + } else { + + this.router.userID = match[2]; + this.router.postID = match[4]; + this.router.mediaID = match[6]; + + if (this.router.mediaID) { + this.router.route = App.Route.MEDIA; + } else if (this.router.postID) { + this.router.route = App.Route.POST; + } else { + this.router.route = App.Route.USER; + } + } + } + + console.log(">>>>>>>>>>>>>>>>>>>>>>>>>", this.router.userID, this.router.postID, this.router.mediaID, App.Route[this.router.route]); + + // user = /user/ + // post = /user//post/ + // media = /user//post//media/ + // group = /group/ID/post/ + // hashtag = /hashtag/ -- maybe only hastags in groups + // home = / + + } + +} + +namespace App { + export enum Route { + USER, + POST, + MEDIA, + GROUP, + HOME, + CONNECT, + }; +} + + + +let app = new App(); + +window.addEventListener("load", app.main.bind(app)); diff --git a/src/sw.ts b/src/sw.ts index 6307850..b0f74b0 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -5,10 +5,12 @@ const cacheName = "dandelion_cache_v1"; const contentToCache = [ '/static/index.html', '/static/main.css', - '/static/main.js', + '/static/main2.js', '/static/lib/marked.min.js', '/static/lib/qrcode.min.js', '/static/db.js', + '/static/PeerManager.js', + '/static/IDUtils.js', '/static/favicon.ico' ]; diff --git a/src/webRTC.ts b/src/webRTC.ts deleted file mode 100644 index 96ab36c..0000000 --- a/src/webRTC.ts +++ /dev/null @@ -1,110 +0,0 @@ -class PeerManager { - connect(peerID: string) { - // Connect to the peer that has the peer id peerID - } - - disconnect(peerID: string) { - } -} - -class PeerConnection { - static config = { - iceServers: [ - { urls: "stun:stun.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" }, - ], - }; - - -} - - -const config = { - iceServers: [{ urls: "stun:stun.mystunserver.tld" }], -}; - -let polite = true; - -// const signaler = new SignalingChannel(); -const signaler: any = {} -const pc = new RTCPeerConnection(config); - - -const constraints = { audio: true, video: true }; -const selfVideo = document.querySelector("video.selfview"); -const remoteVideo = document.querySelector("video.remoteview"); - -async function start() { - try { - const stream = await navigator.mediaDevices.getUserMedia(constraints); - - for (const track of stream.getTracks()) { - pc.addTrack(track, stream); - } - // selfVideo.srcObject = stream; - } catch (err) { - console.error(err); - } -} - - -pc.ontrack = ({ track, streams }) => { - track.onunmute = () => { - // if (remoteVideo.srcObject) { - // return; - // } - // remoteVideo.srcObject = streams[0]; - }; -}; - -let makingOffer = false; - -pc.onnegotiationneeded = async () => { - try { - makingOffer = true; - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } catch (err) { - console.error(err); - } finally { - makingOffer = false; - } -}; - -pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); - -let ignoreOffer = false; - -signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => { - try { - if (description) { - const offerCollision = - description.type === "offer" && - (makingOffer || pc.signalingState !== "stable"); - - ignoreOffer = !polite && offerCollision; - if (ignoreOffer) { - return; - } - - await pc.setRemoteDescription(description); - if (description.type === "offer") { - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - } else if (candidate) { - try { - await pc.addIceCandidate(candidate); - } catch (err) { - if (!ignoreOffer) { - throw err; - } - } - } - } catch (err) { - console.error(err); - } -}; \ No newline at end of file diff --git a/static/index.html b/static/index.html index 8f860c3..bc83c5e 100644 --- a/static/index.html +++ b/static/index.html @@ -10,19 +10,21 @@ - + - + diff --git a/static/main.css b/static/main.css index 0cb1f2f..a74cb8d 100644 --- a/static/main.css +++ b/static/main.css @@ -98,7 +98,7 @@ hr { #log { font-family: monospace; - text-wrap: nowrap; + text-wrap: wrap; font-size: 10px; margin-bottom: 20px; width: 100%; diff --git a/static/main.js b/static/main.js index df06f63..53b4886 100644 --- a/static/main.js +++ b/static/main.js @@ -191,6 +191,69 @@ async function compressString(input) { // Convert the compressed data to a Uint8Array return new Uint8Array(compressedArray); } +// class Signaler { +// websocket: WebSocket | null = null; +// websocketPingInterval: number = 0; +// connect() { +// if (this.websocket?.readyState === WebSocket.OPEN) { +// return; +// } +// window.clearInterval(this.websocketPingInterval); +// if (this.websocket) { this.websocket.close() }; +// try { +// this.websocket = new WebSocket(`wss://${window.location.hostname}:${window.location.port}/ws`); +// } catch (error: any) { +// console.log(error.message); +// return; +// } +// this.websocket.onopen = async (event) => { +// log("ws:connected"); +// await this.sendHello(); +// // If we're running as a headless peer, send a hello message every N seconds to refresh the posts we have. +// let helloRefreshIntervalPeriod = 120; +// if (app.isHeadless) { +// console.log("wsConnection: Setting hello refresh interval to ", helloRefreshIntervalPeriod) +// this.helloRefreshInterval = window.setInterval(() => { +// console.log("wsConnection: Hello refresh.") +// if (!navigator.onLine) { +// return; +// } +// this.sendHello(); +// }, helloRefreshIntervalPeriod * 1000); +// } +// this.websocketPingInterval = window.setInterval(() => { +// if (!navigator.onLine) { +// return; +// } +// this.send({ type: "ping", peer_id: this.peerID, peer_name: app.peername, user_id: app.userID, user_name: app.username }); +// }, 10_000) +// }; +// this.websocket.onclose = (event) => { +// log("ws:disconnected"); +// // this.retry *= 2; +// log(`Retrying in ${this.retry} seconds`); +// window.setTimeout(() => { this.connect(); }, this.retry * 1000); +// }; +// this.websocket.onmessage = (event) => { +// // log('ws:<-' + event.data.slice(0, 240)); +// let data = JSON.parse(event.data); +// let { type } = data; +// let handler = this.messageHandlers.get(type); +// if (!handler) { +// console.warn(`Got a message we can't handle:`, type); +// return; +// } +// handler(data); +// }; +// this.websocket.onerror = (event) => { +// log('ws:error: ' + event); +// }; +// } +// } +// disconnect() { +// this.websocket?.close(); +// } +// } class wsConnection { constructor(userID, peerID, IDsToSync) { this.websocket = null; @@ -232,10 +295,13 @@ class wsConnection { this.messageHandlers.set('hello', this.helloResponseHandler.bind(this)); this.messageHandlers.set('pong', this.pongHandler); this.messageHandlers.set('peer_message', this.peerMessageHandler.bind(this)); + // this.peerMessageHandlers.set('get_post_ids_for_user', this.getPostIdsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_post_ids_for_user_response', this.getPostIdsForUserResponseHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user', this.getPostsForUserHandler.bind(this)); this.peerMessageHandlers.set('get_posts_for_user_response', this.getPostsForUserReponseHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer', this.sendWebRTCOfferHandler.bind(this)); + this.peerMessageHandlers.set('send_webrtc_offer_response', this.getPostIdsForUserResponseHandler.bind(this)); window.addEventListener('beforeunload', () => this.disconnect()); this.connect(); } @@ -260,6 +326,8 @@ class wsConnection { } pongHandler(data) { } + async sendWebRTCOfferHandler(data) { + } async getPostIdsForUserResponseHandler(data) { // log(`getPostsForUserResponse: ${data}`) let message = data.message; @@ -765,6 +833,7 @@ class App { this.websocket?.broadcastNewPost(userID, post); this.render(); } + // What happens with multiple tabs/connections from the same peer ID? I don't think this works, we also need a session ID for each connection getPeerID() { let id = localStorage.getItem("peer_id"); if (!id) { @@ -1167,6 +1236,31 @@ class App { let db = await openDatabase(this.userID); } async main() { + let urlParams = (new URL(window.location.href)).searchParams; + if (urlParams.has('log')) { + this.showInfo(); + } + let peer = null; + // if (window.RTCPeerConnection) { + peer = new RTCPeerConnection({ + iceServers: [ + { 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 return 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" }, + ] + }); + peer.createDataChannel('boop'); + peer.onicecandidate = ({ candidate }) => { log(`WRTC:${candidate?.address} ${candidate?.protocol} ${candidate?.type} ${candidate?.url}`); }; + peer.onnegotiationneeded = (event) => { console.log("on negotiation needed: ", event); }; + peer.createOffer().then((description) => { + peer.setLocalDescription(description); + log("RTC: " + description.sdp + description.type); + }); + // } // await this.exportPostsForUser('b38b623c-c3fa-4351-9cab-50233c99fa4e'); // Get initial state and route from URL and user agent etc // Set local state (userid etc) based on that. @@ -1191,10 +1285,6 @@ class App { await this.initDB(); this.connectURL = `${document.location.origin}/connect/${this.userID}`; document.getElementById('connectURL').innerHTML = `connect`; - let urlParams = (new URL(window.location.href)).searchParams; - if (urlParams.has('log')) { - this.showInfo(); - } if (urlParams.has('headless')) { this.isHeadless = true; } diff --git a/static/main.js.map b/static/main.js.map index 7329545..6bba0f7 100644 --- a/static/main.js.map +++ b/static/main.js.map @@ -1 +1 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/static/sw.js b/static/sw.js index 335f1d3..e14579b 100644 --- a/static/sw.js +++ b/static/sw.js @@ -5,10 +5,12 @@ const cacheName = "dandelion_cache_v1"; const contentToCache = [ '/static/index.html', '/static/main.css', - '/static/main.js', + '/static/main2.js', '/static/lib/marked.min.js', '/static/lib/qrcode.min.js', '/static/db.js', + '/static/PeerManager.js', + '/static/IDUtils.js', '/static/favicon.ico' ]; self.addEventListener("install", (e) => { diff --git a/static/sw.js.map b/static/sw.js.map index 4190338..dfa9bf8 100644 --- a/static/sw.js.map +++ b/static/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sourceRoot":"","sources":["../src/sw.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sourceRoot":"","sources":["../src/sw.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/static/webRTC.js b/static/webRTC.js index 02af802..ecfa6f7 100644 --- a/static/webRTC.js +++ b/static/webRTC.js @@ -1,12 +1,66 @@ -"use strict"; -class PeerManager { +// import { wsConnection } from "./main"; +export class PeerManager { connect(peerID) { // Connect to the peer that has the peer id peerID } disconnect(peerID) { } } -class PeerConnection { +export class PeerConnection { + constructor(remotePeerID, signaler) { + this.makingOffer = false; + this.ignoreOffer = false; + this.onSignallerMessage = async ({ data: { description, candidate } }) => { + try { + if (description) { + // const offerCollision = + // description.type === "offer" && + // (this.makingOffer || this.rtcPeer.signalingState !== "stable"); + // this.ignoreOffer = !polite && offerCollision; + if (this.ignoreOffer) { + return; + } + await this.rtcPeer.setRemoteDescription(description); + if (description.type === "offer") { + await this.rtcPeer.setLocalDescription(); + this.signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); + } + } + else if (candidate) { + try { + await this.rtcPeer.addIceCandidate(candidate); + } + catch (err) { + if (!this.ignoreOffer) { + throw err; + } + } + } + } + catch (err) { + console.error(err); + } + }; + this.id = remotePeerID; + this.rtcPeer = new RTCPeerConnection(PeerConnection.config); + this.signaler = signaler; + ; + this.rtcPeer.onnegotiationneeded = async () => { + try { + this.makingOffer = true; + await this.rtcPeer.setLocalDescription(); + signaler.send(JSON.stringify({ description: this.rtcPeer.localDescription })); + } + catch (err) { + console.error(err); + } + finally { + this.makingOffer = false; + } + }; + this.rtcPeer.onicecandidate = ({ candidate }) => signaler.send(JSON.stringify({ candidate })); + this.ignoreOffer = false; + } } PeerConnection.config = { iceServers: [ @@ -17,80 +71,75 @@ PeerConnection.config = { { urls: "stun:stun4.l.google.com" }, ], }; -const config = { - iceServers: [{ urls: "stun:stun.mystunserver.tld" }], -}; -let polite = true; +// const config = { +// iceServers: [{ urls: "stun:stun.mystunserver.tld" }], +// }; +// let polite = true; // const signaler = new SignalingChannel(); -const signaler = {}; -const pc = new RTCPeerConnection(config); -const constraints = { audio: true, video: true }; -const selfVideo = document.querySelector("video.selfview"); -const remoteVideo = document.querySelector("video.remoteview"); -async function start() { - try { - const stream = await navigator.mediaDevices.getUserMedia(constraints); - for (const track of stream.getTracks()) { - pc.addTrack(track, stream); - } - // selfVideo.srcObject = stream; - } - catch (err) { - console.error(err); - } -} -pc.ontrack = ({ track, streams }) => { - track.onunmute = () => { - // if (remoteVideo.srcObject) { - // return; - // } - // remoteVideo.srcObject = streams[0]; - }; -}; -let makingOffer = false; -pc.onnegotiationneeded = async () => { - try { - makingOffer = true; - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - catch (err) { - console.error(err); - } - finally { - makingOffer = false; - } -}; -pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); -let ignoreOffer = false; -signaler.onmessage = async ({ data: { description, candidate } }) => { - try { - if (description) { - const offerCollision = description.type === "offer" && - (makingOffer || pc.signalingState !== "stable"); - ignoreOffer = !polite && offerCollision; - if (ignoreOffer) { - return; - } - await pc.setRemoteDescription(description); - if (description.type === "offer") { - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - } - else if (candidate) { - try { - await pc.addIceCandidate(candidate); - } - catch (err) { - if (!ignoreOffer) { - throw err; - } - } - } - } - catch (err) { - console.error(err); - } -}; +// const signaler: any = {} +// const rtcPeer = new RTCPeerConnection(config); +// // const constraints = { audio: true, video: true }; +// const selfVideo = document.querySelector("video.selfview"); +// const remoteVideo = document.querySelector("video.remoteview"); +// async function start() { +// try { +// const stream = await navigator.mediaDevices.getUserMedia(constraints); +// for (const track of stream.getTracks()) { +// pc.addTrack(track, stream); +// } +// selfVideo.srcObject = stream; +// } catch (err) { +// console.error(err); +// } +// } +// rtcPeer.ontrack = ({ track, streams }) => { +// track.onunmute = () => { +// if (remoteVideo.srcObject) { +// return; +// } +// remoteVideo.srcObject = streams[0]; +// }; +// }; +// makingOffer = false; +// rtcPeer.onnegotiationneeded = async () => { +// try { +// // makingOffer = true; +// await rtcPeer.setLocalDescription(); +// signaler.send({ description: rtcPeer.localDescription }); +// } catch (err) { +// console.error(err); +// } finally { +// makingOffer = false; +// } +// }; +// rtcPeer.onicecandidate = ({ candidate }) => signaler.send({ candidate }); +// let ignoreOffer = false; +// signaler.onmessage = async ({ data: { description, candidate } }: MessageEvent) => { +// try { +// if (description) { +// const offerCollision = +// description.type === "offer" && +// // (makingOffer || rtcPeer.signalingState !== "stable"); +// ignoreOffer = !polite && offerCollision; +// if (ignoreOffer) { +// return; +// } +// await rtcPeer.setRemoteDescription(description); +// if (description.type === "offer") { +// await rtcPeer.setLocalDescription(); +// signaler.send({ description: rtcPeer.localDescription }); +// } +// } else if (candidate) { +// try { +// await rtcPeer.addIceCandidate(candidate); +// } catch (err) { +// if (!ignoreOffer) { +// throw err; +// } +// } +// } +// } catch (err) { +// console.error(err); +// } +// }; //# sourceMappingURL=webRTC.js.map \ No newline at end of file diff --git a/static/webRTC.js.map b/static/webRTC.js.map index af74ec8..9dece95 100644 --- a/static/webRTC.js.map +++ b/static/webRTC.js.map @@ -1 +1 @@ -{"version":3,"file":"webRTC.js","sourceRoot":"","sources":["../src/webRTC.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"webRTC.js","sourceRoot":"","sources":["../src/webRTC.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/webRTC.js b/webRTC.js index 02af802..9dec2b9 100644 --- a/webRTC.js +++ b/webRTC.js @@ -1,96 +1,83 @@ -"use strict"; -class PeerManager { - connect(peerID) { - // Connect to the peer that has the peer id peerID - } - disconnect(peerID) { +// https://web.dev/articles/webrtc-basics + +// handles JSON.stringify/parse + +class SignalingChannel { + send(message) { + console.log(message); } } -class PeerConnection { -} -PeerConnection.config = { - iceServers: [ - { urls: "stun:stun.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" }, - ], -}; -const config = { - iceServers: [{ urls: "stun:stun.mystunserver.tld" }], -}; -let polite = true; -// const signaler = new SignalingChannel(); -const signaler = {}; -const pc = new RTCPeerConnection(config); -const constraints = { audio: true, video: true }; -const selfVideo = document.querySelector("video.selfview"); -const remoteVideo = document.querySelector("video.remoteview"); -async function start() { - try { - const stream = await navigator.mediaDevices.getUserMedia(constraints); - for (const track of stream.getTracks()) { - pc.addTrack(track, stream); + + +function createPeerConnection(targetPeer) { + + const signaling = new SignalingChannel(); + + // const constraints = {audio: true, video: true}; + const configuration = { iceServers: [{ urls: 'stun:stunserver2024.stunprotocol.org' }] }; + const peerConnection = new RTCPeerConnection(configuration); + const sendChannel = peerConnection.createDataChannel('default'); + + + // Send any ice candidates to the other peer. + peerConnection.onicecandidate = ({ candidate }) => signaling.send({ candidate }); + + // Let the "negotiationneeded" event trigger offer generation. + peerConnection.onnegotiationneeded = async () => { + try { + await peerConnection.setLocalDescription(await peerConnection.createOffer()); + // Send the offer to the other peer. + signaling.send({ desc: peerConnection.localDescription }); + } catch (err) { + console.error(err); } - // selfVideo.srcObject = stream; - } - catch (err) { - console.error(err); - } -} -pc.ontrack = ({ track, streams }) => { - track.onunmute = () => { - // if (remoteVideo.srcObject) { - // return; - // } - // remoteVideo.srcObject = streams[0]; }; -}; -let makingOffer = false; -pc.onnegotiationneeded = async () => { - try { - makingOffer = true; - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); + + // // Once remote track media arrives, show it in remote video element. + // peerConnection.ontrack = (event) => { + // // Don't set srcObject again if it is already set. + // if (remoteView.srcObject) return; + // remoteView.srcObject = event.streams[0]; + // }; + + // Call start() to initiate. + async function start() { + // try { + // Get local stream, show it in self-view, and add it to be sent. + // const stream = + // await navigator.mediaDevices.getUserMedia(constraints); + // stream.getTracks().forEach((track) => + // peerConnection.addTrack(track, stream)); + // selfView.srcObject = stream; + // } catch (err) { + // console.error(err); + // } } - catch (err) { - console.error(err); - } - finally { - makingOffer = false; - } -}; -pc.onicecandidate = ({ candidate }) => signaler.send({ candidate }); -let ignoreOffer = false; -signaler.onmessage = async ({ data: { description, candidate } }) => { - try { - if (description) { - const offerCollision = description.type === "offer" && - (makingOffer || pc.signalingState !== "stable"); - ignoreOffer = !polite && offerCollision; - if (ignoreOffer) { - return; - } - await pc.setRemoteDescription(description); - if (description.type === "offer") { - await pc.setLocalDescription(); - signaler.send({ description: pc.localDescription }); - } - } - else if (candidate) { - try { - await pc.addIceCandidate(candidate); - } - catch (err) { - if (!ignoreOffer) { - throw err; + + signaling.onmessage = async ({ desc, candidate }) => { + try { + if (desc) { + // If you get an offer, you need to reply with an answer. + if (desc.type === 'offer') { + await peerConnection.setRemoteDescription(desc); + // const stream = + // await navigator.mediaDevices.getUserMedia(constraints); + // stream.getTracks().forEach((track) => + // peerConnection.addTrack(track, stream)); + await peerConnection.setLocalDescription(await peerConnection.createAnswer()); + signaling.send({ desc: peerConnection.localDescription }); + } else if (desc.type === 'answer') { + await peerConnection.setRemoteDescription(desc); + } else { + console.log('Unsupported SDP type.'); } + } else if (candidate) { + await peerConnection.addIceCandidate(candidate); } + } catch (err) { + console.error(err); } - } - catch (err) { - console.error(err); - } -}; -//# sourceMappingURL=webRTC.js.map \ No newline at end of file + }; + +} +