Render call events in timeline
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Cadence Ember 2020-11-29 19:47:19 +13:00
parent 2e91ff8ff2
commit ea6ccc08ee
Signed by: cadence
GPG key ID: BC1C2C61CF521B17
10 changed files with 483 additions and 3 deletions

20
spec.js
View file

@ -54,6 +54,26 @@ module.exports = [
source: "/assets/icons/profile-event.svg", source: "/assets/icons/profile-event.svg",
target: "/static/profile-event.svg", target: "/static/profile-event.svg",
}, },
{
type: "file",
source: "/assets/icons/call-out.svg",
target: "/static/call-out.svg",
},
{
type: "file",
source: "/assets/icons/call-in.svg",
target: "/static/call-in.svg",
},
{
type: "file",
source: "/assets/icons/call-accepted.svg",
target: "/static/call-accepted.svg",
},
{
type: "file",
source: "/assets/icons/call-rejected.svg",
target: "/static/call-rejected.svg",
},
{ {
type: "sass", type: "sass",
source: "/sass/main.sass", source: "/sass/main.sass",

View file

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 20 20"
version="1.1"
id="svg1826"
sodipodi:docname="call-accepted.svg"
width="20"
height="20"
inkscape:export-filename="/home/cloud/Code/Carbon/src/assets/icons/call-out-accepted.svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata1830">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>free-icons-solid</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="879"
id="namedview1828"
showgrid="true"
inkscape:snap-global="true"
inkscape:snap-bbox="false"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="false"
inkscape:object-paths="false"
inkscape:snap-intersection-paths="true"
inkscape:snap-midpoints="false"
inkscape:snap-smooth-nodes="false"
showguides="true"
inkscape:zoom="32"
inkscape:cx="7.9954672"
inkscape:cy="9.9614234"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1826">
<inkscape:grid
type="xygrid"
id="grid2773"
originx="-158"
originy="-1412" />
</sodipodi:namedview>
<defs
id="defs4">
<style
id="style2">.a{fill:#757575;}.b{fill:#b4b4b4;}.c{fill:#767676;}</style>
</defs>
<title
id="title6">free-icons-solid</title>
<path
inkscape:connector-curvature="0"
class="a"
d="m 15,13 h -3 c -0.460994,-2.45e-4 -1.000244,0.539006 -1,1 l 0.0029,0.66952 C 7.75933,14.711832 4.2952877,11.24779 4.3376001,8.004177 L 5,8 C 5.4609939,8.000244 6.0002445,7.4609939 6,7 V 4 C 6.0002445,3.5390061 5.4609939,2.9997555 5,3 H 3 C 2.5390061,2.9997555 1.9997555,3.5390061 2,4 v 4 c -4.15e-5,5.069836 3.9301639,9.000041 9,9 h 4 c 0.460994,2.45e-4 1.000245,-0.539006 1,-1 v -2 c 2.45e-4,-0.460994 -0.539006,-1.000245 -1,-1 z"
id="path226"
style="fill:#73d216;fill-opacity:1;stroke:none;stroke-width:0.99999994"
sodipodi:nodetypes="ccccccccccccccccc" />
<path
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#73d216;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
d="m 9,7 c 2,0 3,1 3,3"
id="path3644"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3646"
d="m 9,4 c 4,0 6,2 6,6"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#73d216;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 20 20"
version="1.1"
id="svg1826"
sodipodi:docname="call-in.svg"
width="20"
height="20"
inkscape:export-filename="/home/cloud/Code/Carbon/src/assets/icons/call-out-accepted.svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata1830">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>free-icons-solid</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="879"
id="namedview1828"
showgrid="true"
inkscape:snap-global="true"
inkscape:snap-bbox="false"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="false"
inkscape:object-paths="false"
inkscape:snap-intersection-paths="true"
inkscape:snap-midpoints="false"
inkscape:snap-smooth-nodes="false"
showguides="true"
inkscape:zoom="16"
inkscape:cx="9.4645773"
inkscape:cy="12.891863"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1826">
<inkscape:grid
type="xygrid"
id="grid2773"
originx="-158"
originy="-1412" />
</sodipodi:namedview>
<defs
id="defs4">
<style
id="style2">.a{fill:#757575;}.b{fill:#b4b4b4;}.c{fill:#767676;}</style>
</defs>
<title
id="title6">free-icons-solid</title>
<path
inkscape:connector-curvature="0"
class="a"
d="m 15,15 h -3 c -0.460994,-2.45e-4 -1.000244,0.539006 -1,1 l 0.0029,0.66952 C 7.75933,16.711832 4.2952877,13.24779 4.3376001,10.004177 L 5,10 C 5.4609939,10.000244 6.0002445,9.4609939 6,9 V 6 C 6.0002445,5.5390061 5.4609939,4.9997555 5,5 H 3 C 2.5390061,4.9997555 1.9997555,5.5390061 2,6 v 4 c -4.15e-5,5.069836 3.9301639,9.000041 9,9 h 4 c 0.460994,2.45e-4 1.000245,-0.539006 1,-1 v -2 c 2.45e-4,-0.460994 -0.539006,-1.000245 -1,-1 z"
id="path226"
style="fill:#d591c6;fill-opacity:1;stroke:none;stroke-width:0.99999994"
sodipodi:nodetypes="ccccccccccccccccc" />
<g
id="g2813"
style="stroke:#d591c6;stroke-opacity:1"
transform="matrix(1,0,0,-1,0,13.004142)">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path2807"
d="M 13,11 V 2 l -3,3"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#d591c6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path2809"
d="m 13,2 3,3"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#d591c6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 20 20"
version="1.1"
id="svg1826"
sodipodi:docname="call-out.svg"
width="20"
height="20"
inkscape:export-filename="/home/cloud/Code/Carbon/src/assets/icons/call-out-accepted.svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata1830">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>free-icons-solid</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="879"
id="namedview1828"
showgrid="true"
inkscape:snap-global="true"
inkscape:snap-bbox="false"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="false"
inkscape:object-paths="false"
inkscape:snap-intersection-paths="true"
inkscape:snap-midpoints="false"
inkscape:snap-smooth-nodes="false"
showguides="true"
inkscape:zoom="16"
inkscape:cx="9.4645773"
inkscape:cy="12.891863"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1826">
<inkscape:grid
type="xygrid"
id="grid2773"
originx="-158"
originy="-1412" />
</sodipodi:namedview>
<defs
id="defs4">
<style
id="style2">.a{fill:#757575;}.b{fill:#b4b4b4;}.c{fill:#767676;}</style>
</defs>
<title
id="title6">free-icons-solid</title>
<path
inkscape:connector-curvature="0"
class="a"
d="m 15,15 h -3 c -0.460994,-2.45e-4 -1.000244,0.539006 -1,1 l 0.0029,0.66952 C 7.75933,16.711832 4.2952877,13.24779 4.3376001,10.004177 L 5,10 C 5.4609939,10.000244 6.0002445,9.4609939 6,9 V 6 C 6.0002445,5.5390061 5.4609939,4.9997555 5,5 H 3 C 2.5390061,4.9997555 1.9997555,5.5390061 2,6 v 4 c -4.15e-5,5.069836 3.9301639,9.000041 9,9 h 4 c 0.460994,2.45e-4 1.000245,-0.539006 1,-1 v -2 c 2.45e-4,-0.460994 -0.539006,-1.000245 -1,-1 z"
id="path226"
style="fill:#d591c6;fill-opacity:1;stroke:none;stroke-width:0.99999994"
sodipodi:nodetypes="ccccccccccccccccc" />
<g
id="g2813"
style="stroke:#d591c6;stroke-opacity:1">
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path2807"
d="M 13,11 V 2 l -3,3"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#d591c6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path2809"
d="m 13,2 3,3"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#d591c6;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 20 20"
version="1.1"
id="svg1826"
sodipodi:docname="call-rejected.svg"
width="20"
height="20"
inkscape:export-filename="/home/cloud/Code/Carbon/src/assets/icons/call-out-accepted.svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
<metadata
id="metadata1830">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>free-icons-solid</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="879"
id="namedview1828"
showgrid="true"
inkscape:snap-global="true"
inkscape:snap-bbox="false"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="false"
inkscape:object-paths="false"
inkscape:snap-intersection-paths="true"
inkscape:snap-midpoints="false"
inkscape:snap-smooth-nodes="false"
showguides="true"
inkscape:zoom="22.627417"
inkscape:cx="12.65156"
inkscape:cy="10.798274"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1826">
<inkscape:grid
type="xygrid"
id="grid2773"
originx="-158"
originy="-1412" />
</sodipodi:namedview>
<defs
id="defs4">
<style
id="style2">.a{fill:#757575;}.b{fill:#b4b4b4;}.c{fill:#767676;}</style>
</defs>
<title
id="title6">free-icons-solid</title>
<path
inkscape:connector-curvature="0"
class="a"
d="m 15,13 h -3 c -0.460994,-2.45e-4 -1.000244,0.539006 -1,1 l 0.0029,0.66952 C 7.75933,14.711832 4.2952877,11.24779 4.3376001,8.004177 L 5,8 C 5.4609939,8.000244 6.0002445,7.4609939 6,7 V 4 C 6.0002445,3.5390061 5.4609939,2.9997555 5,3 H 3 C 2.5390061,2.9997555 1.9997555,3.5390061 2,4 v 4 c -4.15e-5,5.069836 3.9301639,9.000041 9,9 h 4 c 0.460994,2.45e-4 1.000245,-0.539006 1,-1 v -2 c 2.45e-4,-0.460994 -0.539006,-1.000245 -1,-1 z"
id="path226"
style="fill:#f43f3f;fill-opacity:1;stroke:none;stroke-width:0.99999994"
sodipodi:nodetypes="ccccccccccccccccc" />
<g
id="g2927"
style="stroke:#f43f3f;stroke-opacity:1">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path2872"
d="M 11,8 16,3"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#f43f3f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" />
<path
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#f43f3f;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill"
d="M 16,8 11,3"
id="path2923"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

67
src/js/events/call.js Normal file
View file

@ -0,0 +1,67 @@
const {UngroupableEvent} = require("./event")
const {ejs} = require("../basic")
const lsm = require("../lsm")
const {extractDisplayName, resolveMxc, extractLocalpart} = require("../functions")
class CallEvent extends UngroupableEvent {
constructor(data) {
super(data)
this.class("c-message-event")
this.senderName = extractLocalpart(this.data.sender)
this.render()
}
renderInner(iconURL, elements) {
this.clearChildren()
this.child(
ejs("div").class("c-message-event__inner").child(
iconURL ? ejs("img").class("c-message-event__icon").attribute("width", "20").attribute("height", "20").attribute("src", iconURL) : "",
...elements
)
)
super.render()
}
}
class CallInviteEvent extends CallEvent {
static canRender(eventData) {
return eventData.type === "m.call.invite"
}
render() {
const icon = this.data.sender === lsm.get("mx_user_id") ? "static/call-out.svg" : "static/call-in.svg"
this.renderInner(icon, [
this.senderName,
" started a VOIP call, but Carbon doesn't support VOIP calls"
])
}
}
class CallAnswerEvent extends CallEvent {
static canRender(eventData) {
return eventData.type === "m.call.answer"
}
render() {
this.renderInner("static/call-accepted.svg", [
this.senderName,
" answered the call"
])
}
}
class CallHangupEvent extends CallEvent {
static canRender(eventData) {
return eventData.type === "m.call.hangup"
}
render() {
const reason = this.data.content.reason === "invite_timeout" ? "missed the call" : "hung up the call"
this.renderInner("static/call-rejected.svg", [
this.senderName,
" " + reason
])
}
}
module.exports = [CallInviteEvent, CallAnswerEvent, CallHangupEvent]

View file

@ -24,7 +24,7 @@ class Image extends GroupableEvent {
wrapper.class("c-media--spoiler") wrapper.class("c-media--spoiler")
const wall = ejs("div").class("c-media__spoiler").text("Spoiler") const wall = ejs("div").class("c-media__spoiler").text("Spoiler")
wrapper.child(wall) wrapper.child(wall)
function toggle() { const toggle = () => {
wrapper.element.classList.toggle("c-media--shown") wrapper.element.classList.toggle("c-media--shown")
} }
wrapper.on("click", toggle) wrapper.on("click", toggle)

View file

@ -3,12 +3,14 @@ const messageEvent = require("./message")
const encryptedEvent = require("./encrypted") const encryptedEvent = require("./encrypted")
const membershipEvent = require("./membership") const membershipEvent = require("./membership")
const unknownEvent = require("./unknown") const unknownEvent = require("./unknown")
const callEvent = require("./call")
const events = [ const events = [
...imageEvent, ...imageEvent,
...messageEvent, ...messageEvent,
...encryptedEvent, ...encryptedEvent,
...membershipEvent, ...membershipEvent,
...callEvent,
...unknownEvent, ...unknownEvent,
] ]

View file

@ -1,7 +1,9 @@
const lsm = require("./lsm.js") const lsm = require("./lsm.js")
function resolveMxc(url, size, method) { function resolveMxc(url, size, method) {
let [server, id] = url.match(/^mxc:\/\/([^/]+)\/(.*)/).slice(1) const match = url.match(/^mxc:\/\/([^/]+)\/(.*)/)
if (!match) return url
let [server, id] = match.slice(1)
id = id.replace(/#.*$/, "") id = id.replace(/#.*$/, "")
if (size && method) { if (size && method) {
return `${lsm.get("domain")}/_matrix/media/r0/thumbnail/${server}/${id}?width=${size}&height=${size}&method=${method}` return `${lsm.get("domain")}/_matrix/media/r0/thumbnail/${server}/${id}?width=${size}&height=${size}&method=${method}`

View file

@ -259,7 +259,7 @@ class Timeline extends Subscribable {
this.map.get(id).update(eventData) this.map.get(id).update(eventData)
} else { } else {
// skip displaying events that we don't know how to // skip displaying events that we don't know how to
if (eventData.type === "m.reaction") { if (["m.reaction", "m.call.candidates"].includes(eventData.type)) {
continue continue
} }
// skip redacted events // skip redacted events