Browse Source

Add better support for being embeded as a widget in Matrix

Jonas Herzig 5 years ago
parent
commit
0a68f28c38
4 changed files with 76 additions and 5 deletions
  1. 2 0
      app/index.html
  2. 6 0
      app/index.js
  3. 60 0
      app/matrix.js
  4. 8 5
      webpack.config.js

+ 2 - 0
app/index.html

@@ -14,6 +14,8 @@
     <meta name="theme-color" content="#ffffff">
 
     <link rel="stylesheet" type="text/css" href="/loading.css">
+
+    <script src="matrix.js"></script>
   </head>
   <body>
     <div class="loading-container" data-bind="css: { loaded: true }">

+ 6 - 0
app/index.js

@@ -225,6 +225,9 @@ class GlobalBindings {
           this.resetClient()
         })
 
+        // Make sure we stay open if we're running as Matrix widget
+        window.matrixWidget.setAlwaysOnScreen(true)
+
         // Register all channels, recursively
         const registerChannel = channel => {
           this._newChannel(channel)
@@ -620,6 +623,9 @@ window.mumbleUi = ui
 window.onload = function () {
   var queryParams = url.parse(document.location.href, true).query
   var useJoinDialog = queryParams.joinDialog
+  if (queryParams.matrix) {
+    useJoinDialog = true
+  }
   if (queryParams.address) {
     ui.connectDialog.address(queryParams.address)
   } else {

+ 60 - 0
app/matrix.js

@@ -0,0 +1,60 @@
+// Handle messages coming from [Matrix] client if embedded as a [Widget] in some room.
+// [Matrix]: https://matrix.org/
+// [Widget]: https://docs.google.com/document/d/1uPF7XWY_dXTKVKV7jZQ2KmsI19wn9-kFRgQ1tFQP7wQ/edit
+
+class MatrixWidget {
+  constructor () {
+    this.widgetId = null
+    window.addEventListener('message', this.onMessage.bind(this))
+  }
+
+  onMessage (event) {
+    this.widgetId = this.widgetId || event.data.widgetId
+
+    switch (event.data.api) {
+      case 'fromWidget':
+        break
+      case 'toWidget':
+        switch (event.data.action) {
+          case 'capabilities':
+            this.sendResponse(event, {
+              capabilities: ['m.always_on_screen']
+            })
+            break
+        }
+        break
+      default:
+        break
+    }
+  }
+
+  sendContentLoaded () {
+    this.sendMessage({
+      action: 'content_loaded'
+    })
+  }
+
+  setAlwaysOnScreen (value) {
+    // Extension of main spec, see https://github.com/matrix-org/matrix-doc/issues/1354
+    this.sendMessage({
+      action: 'set_always_on_screen',
+      value: value, // once for spec compliance
+      data: { value: value } // and once for Riot
+    })
+  }
+
+  sendMessage (message) {
+    if (!this.widgetId) return
+    message.api = message.api || 'fromWidget'
+    message.widgetId = message.widgetId || this.widgetId
+    message.requestId = message.requestId || Math.random().toString(36)
+    window.parent.postMessage(message, '*')
+  }
+
+  sendResponse (event, response) {
+    event.data.response = response
+    event.source.postMessage(event.data, event.origin)
+  }
+}
+
+window.matrixWidget = new MatrixWidget()

+ 8 - 5
webpack.config.js

@@ -3,12 +3,15 @@ var theme = 'MetroMumbleLight'
 var path = require('path')
 
 module.exports = {
-  entry: [
-    './app/index.js',
-    './app/index.html'
-  ],
+  entry: {
+    index: [
+      './app/index.js',
+      './app/index.html'
+    ],
+    matrix: './app/matrix.js'
+  },
   output: {
-    filename: 'index.js',
+    filename: '[name].js',
     path: './dist'
   },
   module: {