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: false }, 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]) this.reactToConnectionHrefs() this.nickname = localStorage.getItem("nickname") || `human${String(Math.random()).substr(5,4)}` 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(/^#/,'')}` console.log("connecting "+this.profile.name) 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 let secret = document.querySelector("#matrix input#secret").value document.querySelector("#matrix input#secret").value = '' let credentials = { baseUrl: this.server } if( this.auth == 'via access token'){ credentials.accessToken = secret credentials.userId = this.username } this.client = Matrix.sdk.createClient(credentials) // Extra configuration needed for certain matrix-js-sdk // calls to work without calling sync start functions this.client.canSupportVoip = false; this.client.clientOpts = { lazyLoadMembers: true, }; // auth if( this.auth == 'via password'){ this.client.login("m.login.password",{"user": this.username, password: secret}) .then( () => this.onMatrixConnect() ) .catch( () => window.notify("authentication was not succesful 😞")) }else this.onMatrixConnect() } }, onMatrixConnect(){ // token: this.matrixclient.getAccessToken() frontend.emit('network.info',{message:'🛰 syncing with Matrix (might take a while)',plugin:this}) frontend.emit('network.connected',{plugin:this,username: this.username}) this.client.startClient({ initialSyncLimit: 4 }) // show last 4 messages? // get roomId of channel this.client.getRoomIdForAlias(this.channel) .then( (o) => { this.roomId = o.room_id this.setupListeners() }) .catch((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 this.ydoc = new Matrix.Y.Doc(); const provider = new Matrix.MatrixProvider(this.ydoc, this.client, { type: "alias", alias: this.channel }); provider.initialize(); this.yhref = this.ydoc.getText('href') // observe changes of the sum this.yhref.observe((event) => { console.log("new yhref: " + yhref.toString ); }); debugger }, getNormalizedName(){ return this.channel.replace(/(^#|:.*)/,'') }, setupListeners(){ if( this.useChat ) this.setupChat() //if( this.useScene ) this.setupCRDT() /* throws weird errors, perhaps matrix-sdk-js is too new */ return this }, setupChat(){ // receive receivemessages this.client.on("Room.timeline", (event, room, toStartOfTimeline) => { if (event.getType() !== "m.room.message") return // only print messages if( room.roomId == this.roomId ){ $chat.send({message: event.getContent().body, from: event.getSender()}) } }); // send chatmessages document.addEventListener('network.send', (e) => { let {message} = e.detail let href = frontend.share({linkonly:true}) // get our meetinglink in there // convert to absolute links if( message.match(/href="#/) ){ message = message.replace(/href=['"]#.*?['"]/g, `href="${href}"`) }else{ let pos = [] if( network.posName ){ pos.push(`#${network.posName}`) } if( network.pos ){ pos.push(`#${`pos=${network.pos}`}`) } if( pos.length ) message += `