window.matrix = (opts) => new Proxy({ el: null, // HTML element profile:{ type: 'network', name: '[Matrix]', description: 'a standardized decentralized privacy-friendly protocol', url: 'https://matrix.org', protocol: 'matrix://', video: false, audio: false, chat: true, scene: true }, useWebcam: false, useChat: false, useScene: false, channel: '#xrfragment-test:matrix.org', server: 'https://matrix.org', username:'', auth: 'via password', authkey: '', client: null, roomid: '', // Matrix-CRDT ydoc: null, yhref: null, html: { generic: (opts) => `
` }, init(){ frontend.plugin['matrix'] = this $connections.chatnetwork = $connections.chatnetwork.concat([this]) $connections.scene = $connections.scene.concat([this]) if( window.localStorage.getItem("username") ) this.username = window.localStorage.getItem("username") this.reactToConnectionHrefs() document.addEventListener('network.connect', (e) => this.connect(e.detail) ) document.addEventListener('network.init', () => { let meeting = network.getMeetingFromUrl(document.location.href) if( meeting.match(this.profile.protocol) ){ this.parseLink( meeting ) } }) }, connect(opts){ if( opts.selectedWebcam == this.profile.name ) this.useWebcam = true if( opts.selectedChatnetwork == this.profile.name ) this.useChat = true if( opts.selectedScene == this.profile.name ) this.useScene = true if( this.useWebcam || this.useScene || this.useChat ){ this.link = `matrix://r/${this.channel.replace(/^#/,'')}` this.createLink() // ensure link this.channel = document.querySelector("#matrix input#channel").value this.server = document.querySelector("#matrix input#server").value this.username = document.querySelector("#matrix input#username").value this.auth = document.querySelector("#matrix select#auth").value localStorage.setItem("matrix.username",this.username) let secret = document.querySelector("#matrix input#secret").value document.querySelector("#matrix input#secret").value = '' let clientOpts = { baseUrl: this.server.match(/^http/) ? this.server : `https://${this.server}`, lazyLoadMembers: true, } if( this.auth == 'via access token'){ clientOpts.accessToken = secret clientOpts.userId = this.username } this.client = Matrix.sdk.createClient(clientOpts) // auth if( this.auth == 'via password'){ //this.client.loginWithPassword(this.username, secret) this.client.login("m.login.password",{"user": this.username, password: secret}) .then( () => this.onMatrixConnect() ) .catch( () => { window.notify("authentication was not succesful 😞") }) }else { this.onMatrixConnect() //this.client.loginWithToken(clientOpts.accessToken) //.then( () => this.onMatrixConnect() ) //.catch( () => { // window.notify("authentication was not succesful 😞") //}) } } }, onMatrixConnect(){ // Extra configuration needed for certain matrix-js-sdk (we don't call start) // calls to work without calling sync start functions this.client.canSupportVoip = false; this.client.clientOpts = { lazyLoadMembers: true } //this.client.startClient({ initialSyncLimit: 4 }) // show last 4 messages? //.then( () => { //.catch( (e) => window.notify("could not start matrix client 😞")) console.log("onmatrix connect") // token: this.matrixclient.getAccessToken() frontend.emit('network.info',{message:'🛰 syncing with Matrix (might take a while)',plugin:this}) //this.client.once("sync", function (state, prevState, res) { }); frontend.emit('network.connected',{plugin:this,username: this.username}) // get roomId of channel this.client.getRoomIdForAlias(this.channel) .then( (o) => { console.log(`${this.channel} has id ${o.room_id}`) this.roomId = o.room_id // join room if we haven't already this.client.joinRoom(this.roomId) .then( () => this.setupListeners() ) .catch( () => this.setupListeners() ) }) .catch((e) => { console.error(e) frontend.emit('network.error',{plugin:this,message:`channel ${this.channel} cannot be joined: `+String(e)}) }) }, setupCRDT(){ // Create a new Y.Doc and connect the MatrixProvider var Buffer = window.Buffer = Matrix.Buffer // expose to MatrixProvider this.ydoc = new Matrix.Y.Doc(); const provider = new Matrix.MatrixProvider(this.ydoc, this.client, { type: "alias", alias: this.channel }); provider.initialize(); this.ydoc.scene = this.ydoc.getMap('scene') // observe changes of the sum this.ydoc.scene.observe(ymapEvent => { // Find out what changed: // Option 1: A set of keys that changed ymapEvent.keysChanged // => Set