Browse Source

add untracked files, whoops

master
f0x 5 months ago
parent
commit
8e76d8277e
5 changed files with 189 additions and 2 deletions
  1. 2
    2
      components/events/image.js
  2. 41
    0
      components/events/video.js
  3. 56
    0
      lib/media.js
  4. 1
    0
      public/icons/file.svg
  5. 89
    0
      tests/lib/media.js

+ 2
- 2
components/events/image.js View File

@@ -34,9 +34,9 @@ let Event = create({
34 34
     return (
35 35
       <div className="body">
36 36
         <a href={this.state.full} target="_blank">
37
-          <img src={this.state.thumb} style={{height: this.state.size.h, width: this.state.size.w}}/>
37
+          <img src={this.state.thumb} style={{maxHeight: this.state.size.h, maxWidth: this.state.size.w}}/>
38 38
         </a>
39
-        <Text event={this.props.event} nested={true}/>
39
+        {/*<Text event={this.props.event} nested={true}/>*/}
40 40
       </div>
41 41
     )
42 42
   }

+ 41
- 0
components/events/video.js View File

@@ -0,0 +1,41 @@
1
+'use strict'
2
+const React = require('react')
3
+const ReactDOM = require('react-dom')
4
+const create = require('create-react-class')
5
+const Promise = require('bluebird')
6
+const defaultValue = require('default-value')
7
+
8
+const mediaLib = require('../../lib/media.js')
9
+
10
+const Text = require('./text.js')
11
+
12
+let Event = create({
13
+  displayName: "m.video",
14
+
15
+  getInitialState: function() {
16
+    let event = this.props.event
17
+    if (event.content.url == undefined) {
18
+      return null
19
+    }
20
+    return mediaLib.parseEvent(this.props.client, event, 1000, 1000)
21
+  },
22
+
23
+  render: function() {
24
+    let event = this.props.event
25
+
26
+    if (this.state == null) {
27
+      return "malformed video event: " + event.content.body
28
+    }
29
+
30
+    return (
31
+      <div className="body">
32
+        <video controls poster={this.state.thumb} style={{maxHeight: this.state.size.h, maxWidth: this.state.size.w}}>
33
+          <source src={this.state.full}></source>
34
+        </video>
35
+        {/*<Text body={event.body} nested={true}/>*/}
36
+      </div>
37
+    )
38
+  }
39
+})
40
+
41
+module.exports = Event;

+ 56
- 0
lib/media.js View File

@@ -0,0 +1,56 @@
1
+// should be able to handle images, stickers, and video
2
+
3
+module.exports = {
4
+  parseEvent: function(client, event, maxHeight, maxWidth) {
5
+    if (event.content.msgtype == "m.image") {
6
+      let h = maxHeight
7
+      let w = maxWidth
8
+
9
+      let media_url = client.mxcUrlToHttp(event.content.url)
10
+      let thumb_url = event.content.url
11
+
12
+      if (event.content.info != null) {
13
+        if (event.content.info.thumbnail_url != null) {
14
+          thumb_url = event.content.info.thumbnail_url
15
+        }
16
+
17
+        if (event.content.info.thumbnail_info != null) {
18
+          h = (event.content.info.thumbnail_info.h < maxHeight) ? event.content.info.thumbnail_info.h : h
19
+          w = (event.content.info.thumbnail_info.w < maxWidth)  ? event.content.info.thumbnail_info.w : w
20
+        } else {
21
+          h = (event.content.info.h < maxHeight) ? event.content.info.h : h
22
+          w = (event.content.info.w < maxWidth)  ? event.content.info.w : w
23
+        }
24
+      }
25
+
26
+      thumb_url = client.mxcUrlToHttp(thumb_url, w, h, 'scale', false)
27
+
28
+      return {
29
+        full: media_url,
30
+        thumb: thumb_url,
31
+        size: {h, w}
32
+      }
33
+    }
34
+    if (event.content.msgtype == "m.video") {
35
+      let thumb = null
36
+      let h = maxHeight
37
+      let w = maxWidth
38
+
39
+      if (event.content.info != null) {
40
+        if (event.content.info.thumbnail_url != null) {
41
+          if (event.content.info.thumbnail_info != null) {
42
+            h = (event.content.info.thumbnail_info.h < maxHeight) ? event.content.info.thumbnail_info.h : h
43
+            w = (event.content.info.thumbnail_info.w < maxWidth)  ? event.content.info.thumbnail_info.w : w
44
+          }
45
+
46
+          thumb = client.mxcUrlToHttp(event.content.thumbnail, w, h, 'scale', false)
47
+        }
48
+      }
49
+      return {
50
+        full: client.mxcUrlToHttp(event.content.url),
51
+        thumb: thumb,
52
+        size: {h, w}
53
+      }
54
+    }
55
+  }
56
+}

+ 1
- 0
public/icons/file.svg View File

@@ -0,0 +1 @@
1
+<?xml version="1.0" ?><svg height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg"><path fill="#dedede" d="M33 12v23c0 4.42-3.58 8-8 8s-8-3.58-8-8v-25c0-2.76 2.24-5 5-5s5 2.24 5 5v21c0 1.1-.89 2-2 2-1.11 0-2-.9-2-2v-19h-3v19c0 2.76 2.24 5 5 5s5-2.24 5-5v-21c0-4.42-3.58-8-8-8s-8 3.58-8 8v25c0 6.08 4.93 11 11 11s11-4.92 11-11v-23h-3z"/><path d="M0 0h48v48h-48z" fill="none"/></svg>

+ 89
- 0
tests/lib/media.js View File

@@ -0,0 +1,89 @@
1
+let assert = require('assert')
2
+let urllib = require('url')
3
+let querystring = require('querystring')
4
+
5
+let mediaLib = require('../../lib/media.js')
6
+
7
+let client = {
8
+  mxcUrlToHttp: function(url, w, h, method, allowDirectLinks) {
9
+    let hs = "https://chat.privacytools.io"
10
+    let mxc = url.slice(6)
11
+    if (w) {
12
+      return `${hs}/_matrix/media/v1/thumbnail/${mxc}?w=${w}&h=${h}&method=${method}`
13
+    } else {
14
+      return `${hs}/_matrix/media/v1/download/${mxc}`
15
+    }
16
+  }
17
+}
18
+
19
+let mockEventTemplate = {
20
+  type: "m.room.message",
21
+  sender: "@f0x:privacytools.io",
22
+  content: {
23
+    body: "image.png",
24
+    info: {
25
+      size: 16692,
26
+      mimetype: "image/png",
27
+      thumbnail_info: {
28
+        w: 268,
29
+        h: 141,
30
+        mimetype: "image/png",
31
+        size: 16896
32
+      },
33
+      w: 268,
34
+      h: 141,
35
+      thumbnail_url: "mxc://privacytools.io/zBSerdKMhaXSIxfjzCmOnhXH"
36
+    },
37
+    msgtype: "m.image",
38
+    url: "mxc://privacytools.io/khPaFfeRyNdzlSttZraeAUre"
39
+  },
40
+  event_id: "$aaa:matrix.org",
41
+  origin_server_ts: 1558470168199,
42
+  unsigned: {
43
+    age: 143237861
44
+  },
45
+  room_id: "!aaa:matrix.org"
46
+}
47
+
48
+describe('media', function() {
49
+  describe('#parseEvent()', function() {
50
+    it('event without info', function() {
51
+      let mockEvent = JSON.parse(JSON.stringify(mockEventTemplate))
52
+      mockEvent.content.info = null
53
+
54
+      checkParsedEvent(mockEvent, {
55
+        w: 1000,
56
+        h: 1000,
57
+        method: 'scale'
58
+      })
59
+    }),
60
+    it('event without thumbnail', function() {
61
+      let mockEvent = JSON.parse(JSON.stringify(mockEventTemplate))
62
+      mockEvent.content.info.thumbnail_url = null
63
+      mockEvent.content.info.thumbnail_info = null
64
+      checkParsedEvent(mockEvent, {
65
+        w: 268,
66
+        h: 141,
67
+        method: 'scale'
68
+      })
69
+    })
70
+    it('event without thumbnail_info', function() {
71
+      let mockEvent = JSON.parse(JSON.stringify(mockEventTemplate))
72
+      mockEvent.content.info.thumbnail_url = null
73
+      checkParsedEvent(mockEvent, {
74
+        w: 268,
75
+        h: 141,
76
+        method: 'scale'
77
+      })
78
+    })
79
+  })
80
+})
81
+
82
+function checkParsedEvent(mockEvent, expected) {
83
+  let media = mediaLib.parseEvent(client, mockEvent, 1000, 1000)
84
+  let params = querystring.decode(urllib.parse(media.thumb).query)
85
+
86
+  Object.keys(params).forEach((key) => {
87
+    assert.equal(expected[key], params[key])
88
+  })
89
+}

Loading…
Cancel
Save