diff --git a/app.js b/app.js
index 531ba01..53b6162 100644
--- a/app.js
+++ b/app.js
@@ -3,6 +3,7 @@ const React = require('react')
const ReactDOM = require('react-dom')
const create = require('create-react-class')
const Promise = require('bluebird')
+const urllib = require('url')
const Matrix = require('./backends/matrix.js')
@@ -18,37 +19,87 @@ const Input = require('./components/input.js')
// incoming/outgoing message alignment (split)
-let backend = new Matrix("user", "pass", "https://lain.haus")
-backend.sync()
let App = create({
displayName: "App",
getInitialState: function() {
- return this.checkBackend()
+ return {rooms: {}, events: {}}
},
checkBackend: function() {
- let returnValue = null
- if(backend.hasUpdates()) {
- returnValue = {
- rooms: backend.getRooms(),
- events: backend.getEvents()
- }
+ if(this.state.backend.hasUpdates()) {
+ console.log("RECEIVING UPDATES FROM BACKEND")
+ this.setState({
+ rooms: this.state.backend.getRooms(),
+ events: this.state.backend.getEvents()
+ })
}
setTimeout(() => {
- this.setState(this.checkBackend())
+ this.checkBackend()
}, 100)
- return returnValue
+ },
+
+ login: function() {
+ let user = document.getElementById("user").value
+ let pass = document.getElementById("pass").value
+ let hs = document.getElementById("hs").value
+ hs = urllib.parse(hs)
+
+ let data = {
+ user: user,
+ password: pass,
+ type: "m.login.password",
+ initial_device_display_name: "Neo v4",
+ };
+
+ let url = urllib.format(Object.assign(hs, {
+ pathname: "/_matrix/client/r0/login"
+ }));
+
+ fetch(url, {
+ body: JSON.stringify(data),
+ headers: {
+ 'content-type': 'application/json'
+ },
+ method: 'POST',
+ }).then((response) => response.json())
+ .then((responseJson) => {
+ this.setState({json: responseJson});
+ if(responseJson.access_token != undefined) {
+ let backend = new Matrix(responseJson.user_id, responseJson.access_token, "https://"+responseJson.home_server)
+ this.setState({
+ backend: backend
+ })
+ this.checkBackend()
+ }
+ })
+ .catch((error) => {
+ console.error(error);
+ });
},
render: function() {
+ if (this.state.backend == undefined) {
+ //Login screen
+ return (
+
+ )
+ }
return (
<>
-
+ {this.setState({roomId: roomId})}}/>
-
+
>
diff --git a/backends/matrix.js b/backends/matrix.js
index 9fd1d3c..7253abb 100644
--- a/backends/matrix.js
+++ b/backends/matrix.js
@@ -2,83 +2,53 @@
const React = require('react')
const ReactDOM = require('react-dom')
const defaultValue = require('default-value')
+const sdk = require('matrix-js-sdk')
class Matrix {
- constructor(user, password, homeserver) {
+ constructor(user, token, homeserver) {
this.user = user;
- this.password = password;
this.homeserver = homeserver;
- this.a = 0
- this.events = {
- "roomId": [
- {
- type: "m.room.message",
- sender: "@f0x:lain.haus",
- content: {
- body: "Image caption",
- info: {
- size: 1331429,
- mimetype: "image/png",
- thumbnail_info: {
- w: 600,
- h: 600,
- mimetype: "image/png",
- size: 151911
- },
- w: 2000,
- h: 2000,
- thumbnail_url: "mxc://lain.haus/PnptnVmLprDNICfhCqIIurHZ"
- },
- msgtype: "m.image",
- url: "mxc://lain.haus/MXtCRwxheuSEVsIyHfyUGJNz"
- },
- event_id: "$155317808164309EPnWP:lain.haus",
- origin_server_ts: 1553178081145,
- unsigned: {
- age: 587,
- transaction_id: "m1553178080798.12"
- },
- room_id: "!bghqZrxFTiDyEUzunK:disroot.org"
- }
- ]
- }
+ this.client = sdk.createClient({
+ baseUrl: homeserver,
+ accessToken: token,
+ userId: user
+ });
- //this.rooms = ["Neo", "version 4", "Codename", "Iris", "Let's All Love Lain", "Very long room name abcdefghijklmnopqrstuvwxyz"]
- this.rooms = {
- "room0": {
- name: "Neo",
- lastEvent: 10
- },
- "room1": {
- name: "v4: iris",
- lastEvent: 10
- },
- "room2": {
- name: "groups",
- lastEvent: 10
- },
- "room3": {
- name: "GUI Demo",
- lastEvent: 0
- }
- }
+ this.events = {}
+ this.rooms = {}
+ this.startClient()
this.updates = true
}
+ startClient() {
+ this.client.on("Room.timeline", (event, room, toStartOfTimeline) => {
+ if (toStartOfTimeline) {
+ return
+ }
+ if (this.events[room.roomId] == undefined) {
+ this.events[room.roomId] = []
+ this.rooms[room.roomId] = {
+ name: room.name,
+ lastEvent: 0
+ }
+ }
+ this.events[room.roomId].push(event.event)
+ this.updates = true
+ console.log("NEW EVENTS")
+ })
+ this.client.startClient()
+ }
+
getHS() {
return this.homeserver
}
getEvents(roomId) {
- return this.events["roomId"]
+ return this.events
}
getRooms() {
- let orderList = Object.keys(this.rooms)
- orderList.sort((a, b) => {
- return this.rooms[b].lastEvent - this.rooms[a].lastEvent
- })
- return {rooms: this.rooms, order: orderList}
+ return this.rooms
}
hasUpdates() {
@@ -89,36 +59,33 @@ class Matrix {
return false
}
- addEvent(event) {
- this.events["roomId"].push(event)
- }
-
sync() {
- let rand = this.lastRand
- while(rand == this.lastRand) {
- rand = Math.floor(Math.random()*Object.keys(this.rooms).length)
- }
- this.lastRand = rand
- let roomId = `room${rand}`
- let now = new Date().getMilliseconds()
- this.rooms[roomId].lastEvent = now
- this.updates = true
+ // let rand = this.lastRand
+ // while(rand == this.lastRand) {
+ // rand = Math.floor(Math.random()*Object.keys(this.rooms).length)
+ // }
+ // this.lastRand = rand
+ // let roomId = `room${rand}`
+ // let now = new Date().getMilliseconds()
+ // this.rooms[roomId].lastEvent = now
+ // this.updates = true
+
+ // let event = {
+ // content: {
+ // body: "New m.text
Event",
+ // msgtype: "m.text"
+ // },
+ // event_id: this.fakeEventId(),
+ // origin_server_ts: 1432735824653,
+ // room_id: "!jEsUZKDJdhlrceRyVU:domain.com",
+ // sender: "@example:domain.com",
+ // type: "m.room.message",
+ // unsigned: {
+ // age: 1234
+ // }
+ // }
+ // this.events["roomId"].push(event)
- let event = {
- content: {
- body: "Testing m.text",
- msgtype: "m.text"
- },
- event_id: this.fakeEventId(),
- origin_server_ts: 1432735824653,
- room_id: "!jEsUZKDJdhlrceRyVU:domain.com",
- sender: "@example:domain.com",
- type: "m.room.message",
- unsigned: {
- age: 1234
- }
- }
- this.events["roomId"].push(event)
setTimeout(() => {this.sync()}, 2000)
}
diff --git a/components/chat.js b/components/chat.js
index 92ccdfa..7d7e100 100644
--- a/components/chat.js
+++ b/components/chat.js
@@ -27,8 +27,15 @@ jdenticon.config = {
let chat = create({
displayName: "Chat",
+ getInitialState: function() {
+ return {
+ ref: null
+ }
+ },
+
getSnapshotBeforeUpdate: function(oldProps, oldState) {
let ref = this.state.ref
+ if (ref == null) {return}
if ((ref.scrollHeight - ref.offsetHeight) - ref.scrollTop < 100) { // Less than 100px from bottom
return true
}
@@ -37,6 +44,7 @@ let chat = create({
componentDidUpdate(prevProps, prevState, snapshot) {
let ref = this.state.ref
+ if (ref == null) {return}
if (snapshot) { // scroll to bottom
ref.scrollTop = (ref.scrollHeight - ref.offsetHeight)
}
@@ -49,6 +57,14 @@ let chat = create({
},
render: function() {
+ if (this.props.roomId == undefined || this.props.events[this.props.roomId] == undefined) {
+ //empty screen
+ return
+ }
+
let messageGroups = {
current: [],
groups: [],
@@ -58,7 +74,7 @@ let chat = create({
// if the sender is the same, add it to the 'current' messageGroup, if not,
// push the old one to 'groups' and start with a new array.
- this.props.events.forEach((event, id) => {
+ this.props.events[this.props.roomId].forEach((event, id) => {
if (event.sender != messageGroups.sender) {
messageGroups.sender = event.sender
if (messageGroups.current.length != 0) {
@@ -115,7 +131,7 @@ let EventGroup = create({
function getRenderedEvent(event, id, backend) {
if (event.type == "m.room.message") {
let msgtype = event.content.msgtype;
- return React.createElement(elements[defaultValue(msgtype, "m.text")], {event: event, key: id, backend: backend})
+ return React.createElement(defaultValue(elements[msgtype], elements["m.text"]), {event: event, key: id, backend: backend})
}
}
diff --git a/components/filterList.js b/components/filterList.js
index 0584c28..0e8f680 100644
--- a/components/filterList.js
+++ b/components/filterList.js
@@ -17,7 +17,7 @@ let FilterList = create({
select: function(id) {
this.setState({selection: id})
- //this.props.callback(id)
+ this.props.callback(id)
},
inputRef: function(ref) {
@@ -37,9 +37,9 @@ let FilterList = create({
},
render: function() {
- let items = Object.keys(this.props.items).map((itemKey, id) => {
+ let keys = Object.keys(this.props.items)
+ let items = keys.map((itemKey, id) => {
let item = this.props.items[itemKey]
-
let props = {
selected: this.state.selection == itemKey,
filter: this.state.filter,
diff --git a/components/sidebar.js b/components/sidebar.js
index 36f81fa..acef70f 100644
--- a/components/sidebar.js
+++ b/components/sidebar.js
@@ -4,6 +4,7 @@ const ReactDOM = require('react-dom')
const create = require('create-react-class')
const Promise = require('bluebird')
const debounce = require('debounce')
+const jdenticon = require('jdenticon')
const FilterList = require('./filterList.js')
@@ -17,6 +18,10 @@ let RoomListItem = create({
}
},
+ componentDidMount() {
+ jdenticon.update("svg")
+ },
+
setRef: function(ref) {
if (ref == null) {
return
@@ -61,7 +66,7 @@ let Sidebar = create({
render: function() {
return
-
+ {this.props.selectRoom(roomId)}}/>
}
})
diff --git a/package.json b/package.json
index d805745..b3929ce 100644
--- a/package.json
+++ b/package.json
@@ -35,9 +35,11 @@
"gulp-util": "^3.0.8",
"jdenticon": "^2.1.1",
"livereactload": "^4.0.0-beta.2",
+ "matrix-js-sdk": "^1.0.2",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"sanitize-html": "^1.20.0",
+ "sourceify": "^0.1.0",
"vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0",
"webpack": "^4.27.1"
diff --git a/public/scss/style.scss b/public/scss/style.scss
index cd050e8..a5a5304 100644
--- a/public/scss/style.scss
+++ b/public/scss/style.scss
@@ -48,6 +48,53 @@ body {
height: 100vh;
width: 100vw;
display: flex;
+ justify-content: center;
+}
+
+.loginwrapper {
+ margin-top: -15rem;
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+
+ img {
+ height: 15rem;
+ width: 15rem;
+ text-align: center;
+ align-self: center;
+ }
+}
+
+.login {
+ align-self: center;
+ display: inline-grid;
+ grid-template-columns: 1fr 1fr;
+
+ $blue: #5294e2;
+
+ label, input, button {
+ margin: 0.3rem;
+ padding: 0.3rem;
+ }
+
+ label {
+ background: $blue;
+ justify-self: left;
+ }
+
+ input {
+ border: 0.1rem solid $blue;
+ background: transparent;
+ color: white;
+ }
+
+ button {
+ grid-column-start: 2;
+ background: $blue;
+ color: white;
+ justify-self: right;
+ border: none;
+ }
}
.main {
diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml
index 3ed9d2a..cc5aeca 100644
--- a/shrinkwrap.yaml
+++ b/shrinkwrap.yaml
@@ -25,9 +25,11 @@ dependencies:
gulp-util: 3.0.8
jdenticon: 2.1.1
livereactload: 4.0.0-beta.2
+ matrix-js-sdk: 1.0.2
react: 16.6.3
react-dom: 16.6.3
sanitize-html: 1.20.0
+ sourceify: 0.1.0
vinyl-buffer: 1.0.1
vinyl-source-stream: 2.0.0
webpack: 4.27.1
@@ -989,6 +991,15 @@ packages:
ajv: ^6.0.0
resolution:
integrity: sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=
+ /ajv/6.10.0:
+ dependencies:
+ fast-deep-equal: 2.0.1
+ fast-json-stable-stringify: 2.0.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.2.2
+ dev: false
+ resolution:
+ integrity: sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
/ajv/6.6.2:
dependencies:
fast-deep-equal: 2.0.1
@@ -1004,6 +1015,10 @@ packages:
node: '>=0.4.2'
resolution:
integrity: sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
+ /another-json/0.2.0:
+ dev: false
+ resolution:
+ integrity: sha1-tfQBnJc7bdXGUGotk0acttMq7tw=
/ansi-colors/1.1.0:
dependencies:
ansi-wrap: 0.1.0
@@ -1393,6 +1408,13 @@ packages:
dev: false
resolution:
integrity: sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
+ /babel-runtime/6.26.0:
+ dependencies:
+ core-js: 2.6.5
+ regenerator-runtime: 0.11.1
+ dev: false
+ resolution:
+ integrity: sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
/babelify/10.0.0:
dev: false
engines:
@@ -1421,6 +1443,18 @@ packages:
dev: false
resolution:
integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
+ /base-x/3.0.4:
+ dependencies:
+ safe-buffer: 5.1.2
+ dev: false
+ resolution:
+ integrity: sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==
+ /base-x/3.0.5:
+ dependencies:
+ safe-buffer: 5.1.2
+ dev: false
+ resolution:
+ integrity: sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==
/base/0.11.2:
dependencies:
cache-base: 1.0.1
@@ -1620,6 +1654,12 @@ packages:
hasBin: true
resolution:
integrity: sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==
+ /browser-request/0.3.3:
+ dev: false
+ engines:
+ '0': node
+ resolution:
+ integrity: sha1-ns5bWsqJopkyJC4Yv5M975h2zBc=
/browser-resolve/1.11.3:
dependencies:
resolve: 1.1.7
@@ -1819,6 +1859,12 @@ packages:
hasBin: true
resolution:
integrity: sha512-kMGKs4BTzRWviZ8yru18xBpx+CyHG9eqgRbj9XbE3IMgtczf4aiA0Y1YCpVdvUieKGZ03kolSPXqTcscBCb9qw==
+ /bs58/4.0.1:
+ dependencies:
+ base-x: 3.0.5
+ dev: false
+ resolution:
+ integrity: sha1-vhYedsNU9veIrkBx9j806MTwpCo=
/budo/11.5.0:
dependencies:
bole: 2.0.0
@@ -2405,6 +2451,12 @@ packages:
optional: true
resolution:
integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
+ /content-type/1.0.4:
+ dev: false
+ engines:
+ node: '>= 0.6'
+ resolution:
+ integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
/convert-source-map/0.3.5:
dev: false
resolution:
@@ -2451,6 +2503,10 @@ packages:
resolution:
integrity: sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
tarball: 'http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz'
+ /core-js/2.6.5:
+ dev: false
+ resolution:
+ integrity: sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==
/core-util-is/1.0.2:
resolution:
integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
@@ -3839,7 +3895,7 @@ packages:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.7
- mime-types: 2.1.21
+ mime-types: 2.1.22
dev: false
engines:
node: '>= 0.12'
@@ -4491,7 +4547,7 @@ packages:
integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
/har-validator/5.1.3:
dependencies:
- ajv: 6.6.2
+ ajv: 6.10.0
har-schema: 2.0.0
dev: false
engines:
@@ -4675,7 +4731,7 @@ packages:
dependencies:
assert-plus: 1.0.0
jsprim: 1.4.1
- sshpk: 1.16.0
+ sshpk: 1.16.1
dev: false
engines:
node: '>=0.8'
@@ -5832,6 +5888,12 @@ packages:
optional: true
resolution:
integrity: sha1-X46MkNME7fElMJUaVVSruMXj9VI=
+ /loglevel/1.6.1:
+ dev: false
+ engines:
+ node: '>= 0.6.0'
+ resolution:
+ integrity: sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
/longest/1.0.1:
dev: false
engines:
@@ -5953,6 +6015,22 @@ packages:
/math-random/1.0.1:
resolution:
integrity: sha1-izqsWIuKZuSXXjzepn97sylgH6w=
+ /matrix-js-sdk/1.0.2:
+ dependencies:
+ another-json: 0.2.0
+ babel-runtime: 6.26.0
+ base-x: 3.0.4
+ bluebird: 3.5.3
+ browser-request: 0.3.3
+ bs58: 4.0.1
+ content-type: 1.0.4
+ loglevel: 1.6.1
+ qs: 6.6.0
+ request: 2.88.0
+ unhomoglyph: 1.0.2
+ dev: false
+ resolution:
+ integrity: sha512-4WCBJFSoOLelHi7IUAcVxPQF+gTc/i9NUKZ77qwUfcZVED8VKTIyWZnwpeLgocK5gAOJV9fkAyO5mny9SkZaGg==
/md5.js/1.3.5:
dependencies:
hash-base: 3.0.4
@@ -6085,16 +6163,23 @@ packages:
dev: false
engines:
node: '>= 0.6'
+ optional: true
resolution:
integrity: sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
- /mime-types/2.1.21:
+ /mime-db/1.38.0:
+ dev: false
+ engines:
+ node: '>= 0.6'
+ resolution:
+ integrity: sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
+ /mime-types/2.1.22:
dependencies:
- mime-db: 1.37.0
+ mime-db: 1.38.0
dev: false
engines:
node: '>= 0.6'
resolution:
- integrity: sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
+ integrity: sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
/mime/1.4.1:
dev: false
hasBin: true
@@ -7321,6 +7406,12 @@ packages:
node: '>=0.6'
resolution:
integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
+ /qs/6.6.0:
+ dev: false
+ engines:
+ node: '>=0.6'
+ resolution:
+ integrity: sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA==
/query-string/4.3.4:
dependencies:
object-assign: 4.1.1
@@ -7521,6 +7612,10 @@ packages:
dev: false
resolution:
integrity: sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
+ /regenerator-runtime/0.11.1:
+ dev: false
+ resolution:
+ integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
/regenerator-runtime/0.12.1:
dev: false
resolution:
@@ -7650,7 +7745,7 @@ packages:
is-typedarray: 1.0.0
isstream: 0.1.2
json-stringify-safe: 5.0.1
- mime-types: 2.1.21
+ mime-types: 2.1.22
oauth-sign: 0.9.0
performance-now: 2.1.0
qs: 6.5.2
@@ -8161,6 +8256,13 @@ packages:
node: '>=0.10.0'
resolution:
integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+ /sourceify/0.1.0:
+ dependencies:
+ convert-source-map: 1.6.0
+ through2: 2.0.5
+ dev: false
+ resolution:
+ integrity: sha1-C1b+V/lFc1DZJliBCq/afA9EA0w=
/sparkles/1.0.1:
dev: false
engines:
@@ -8228,7 +8330,7 @@ packages:
node: '>=0.10.0'
resolution:
integrity: sha1-pWad4StC87HV6D7QPHEEb8SPQe8=
- /sshpk/1.16.0:
+ /sshpk/1.16.1:
dependencies:
asn1: 0.2.4
assert-plus: 1.0.0
@@ -8244,7 +8346,7 @@ packages:
node: '>=0.10.0'
hasBin: true
resolution:
- integrity: sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==
+ integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
/ssri/6.0.1:
dependencies:
figgy-pudding: 3.5.1
@@ -8987,6 +9089,10 @@ packages:
node: '>= 0.10'
resolution:
integrity: sha1-M52kZGJS0ILcN45wgGcpl1DhG0k=
+ /unhomoglyph/1.0.2:
+ dev: false
+ resolution:
+ integrity: sha1-1p5fWmocayEZQaCIm4HrqGWVwlM=
/unicode-canonical-property-names-ecmascript/1.0.4:
dev: false
engines:
@@ -9546,9 +9652,11 @@ specifiers:
gulp-watch: ^5.0.1
jdenticon: ^2.1.1
livereactload: ^4.0.0-beta.2
+ matrix-js-sdk: ^1.0.2
react: ^16.6.3
react-dom: ^16.6.3
sanitize-html: ^1.20.0
+ sourceify: ^0.1.0
vinyl-buffer: ^1.0.1
vinyl-source-stream: ^2.0.0
webpack: ^4.27.1