From 27dc997d70e9595b988be906ed48d3d092f15063 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Mon, 15 Jul 2019 02:51:08 +0200 Subject: [PATCH] Refactored EventGroup --- package.json | 2 + src/components/chat.js | 64 ++++++++++++++++--------------- src/lib/generate-thumbnail-url.js | 15 ++++++++ src/lib/parse-mxc.js | 16 ++++++++ src/lib/validate/is-mxc.js | 7 ++++ yarn.lock | 28 ++++++++++++++ 6 files changed, 102 insertions(+), 30 deletions(-) create mode 100644 src/lib/generate-thumbnail-url.js create mode 100644 src/lib/parse-mxc.js create mode 100644 src/lib/validate/is-mxc.js diff --git a/package.json b/package.json index 15ff907..2391eaa 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "budo": "^11.5.0", "color-convert": "^2.0.0", "create-react-class": "^15.6.3", + "dataprog": "^0.1.0", "debounce": "^1.2.0", "default-value": "^1.0.0", "del": "^3.0.0", @@ -40,6 +41,7 @@ "react-dom": "^16.6.3", "sanitize-html": "^1.20.0", "sourceify": "^0.1.0", + "validatem": "^0.2.0", "vinyl-buffer": "^1.0.1", "vinyl-source-stream": "^2.0.0", "webpack": "^4.27.1" diff --git a/src/components/chat.js b/src/components/chat.js index a11fbda..f4a471f 100644 --- a/src/components/chat.js +++ b/src/components/chat.js @@ -4,6 +4,7 @@ const Promise = require("bluebird"); const React = require("react"); const create = require("create-react-class"); const sanitize = require("sanitize-html"); +const { expression } = require("dataprog"); const Event = require("./events/Event.js"); const Info = require("./info.js"); @@ -12,7 +13,9 @@ const User = require("./events/user.js"); const Loading = require("./loading.js"); const generateJdenticon = require("../lib/generate-jdenticon"); +const generateThumbnailUrl = require("../lib/generate-thumbnail-url"); const groupEvents = require("../lib/group-events"); +const parseMXC = require("../lib/parse-mxc"); let eventFunctions = { plaintext: function() { @@ -159,42 +162,43 @@ let chat = create({ } }); -let EventGroup = create({ - displayName: "EventGroup", +function EventGroup({ events, room, client, onReplyClick }) { + let [ avatarRef, setAvatarRef ] = React.useState(); - getInitialState: function() { - let user = this.props.client.getUser(this.props.events[0].sender); - let avatar = ; - - if (user.avatarUrl != null) { - let hs = this.props.client.baseUrl; - let media_mxc = user.avatarUrl.slice(6); - let url = `${hs}/_matrix/media/v1/thumbnail/${media_mxc}?width=128&height=128&method=scale`; - avatar = ; + React.useEffect(() => { + if (avatarRef != null) { + generateJdenticon(user.userId).update(avatarRef); } + }, [ avatarRef ]); - return { - user: user, - avatar: avatar - }; - }, + let user = client.getUser(events[0].sender); - avatarRef: function(ref) { - generateJdenticon(this.state.user.userId).update(ref); - }, + let avatar = expression(() => { + if (user.avatarUrl != null) { + let url = generateThumbnailUrl({ + homeserver: client.baseUrl, + mxc: parseMXC(user.avatarUrl), + width: 128, + height: 128 + }); - render: function() { - let events = this.props.events.map((event, key) => { - return ; - }); - return
- {this.state.avatar} + return ; + } else { + return ; + } + }); + + return ( +
+ {avatar}
- - {events} + + {events.map((event, key) => { + return ; + })}
-
; - } -}); +
+ ); +} module.exports = chat; diff --git a/src/lib/generate-thumbnail-url.js b/src/lib/generate-thumbnail-url.js new file mode 100644 index 0000000..7dba6df --- /dev/null +++ b/src/lib/generate-thumbnail-url.js @@ -0,0 +1,15 @@ +"use strict"; + +const { validateOptions, required, isNumber, isString } = require("validatem"); +const isMXC = require("./validate/is-mxc"); + +module.exports = function generateThumbnailUrl({homeserver, mxc, width, height }) { + validateOptions(arguments, { + homeserver: [ required, isString ], + mxc: [ required, isMXC ], + width: [ required, isNumber ], + height: [ required, isNumber ] + }); + + return `${homeserver}/_matrix/media/v1/thumbnail/${mxc.homeserver}/${mxc.id}?width=${width}&height=${height}&method=scale`; +}; diff --git a/src/lib/parse-mxc.js b/src/lib/parse-mxc.js new file mode 100644 index 0000000..ed49b71 --- /dev/null +++ b/src/lib/parse-mxc.js @@ -0,0 +1,16 @@ +"use strict"; + +const urlLib = require("url"); + +module.exports = function parseMXC(uri) { + let parsed = urlLib.parse(uri); + + if (parsed.protocol === "mxc:" && parsed.slashes === true) { + return { + homeserver: parsed.host, + id: parsed.pathname.replace(/^\/+/, "") + }; + } else { + throw new Error("Specified URI is not an MXC URI"); + } +}; diff --git a/src/lib/validate/is-mxc.js b/src/lib/validate/is-mxc.js new file mode 100644 index 0000000..9f9f57a --- /dev/null +++ b/src/lib/validate/is-mxc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = function isMXC(value) { + if (value.homeserver == null || value.id == null) { + throw new Error("Must be an MXC object"); + } +}; diff --git a/yarn.lock b/yarn.lock index 84f21fc..cba98a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1359,6 +1359,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +assure-array@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assure-array/-/assure-array-1.0.0.tgz#4f4ad16a87659d6200a4fb7103462033d216ec1f" + integrity sha1-T0rRaodlnWIApPtxA0YgM9IW7B8= + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -2594,6 +2599,11 @@ create-ecdh@^4.0.0: bn.js "^4.1.0" elliptic "^6.0.0" +create-error@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/create-error/-/create-error-0.3.1.tgz#69810245a629e654432bf04377360003a5351a23" + integrity sha1-aYECRaYp5lRDK/BDdzYAA6U1GiM= + create-hash@^1.1.0, create-hash@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -2778,6 +2788,15 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +dataprog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/dataprog/-/dataprog-0.1.0.tgz#373c3708e4a1ebc03b066142921fdf663caa27bb" + integrity sha512-mG+VRq+cu9vOdEYj7LV0RrI4ocOx3r9jemlKuCxAxB8uHEa1yqaPlDIjNSwwY6yi7oh/VETqf9tm+qGreVRXjQ== + dependencies: + assure-array "^1.0.0" + bluebird "^3.5.5" + default-value "^1.0.0" + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" @@ -9810,6 +9829,15 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validatem@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/validatem/-/validatem-0.2.0.tgz#0cde815813f3c8a33615bf09370e88d511a65658" + integrity sha512-fSW8L19US3smdm/E5tw7zTR3WgC+yGiBf67zhxCgVJExujZui2t8gwVyX05u9tcIBu/90tzqsD9hfMR0VAGKUA== + dependencies: + assure-array "^1.0.0" + create-error "^0.3.1" + default-value "^1.0.0" + value-or-function@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813"