Switch to instead use SVG format for content body

This commit is contained in:
N-Pex 2024-10-25 12:46:41 +02:00
parent 1d33657569
commit 1de3cc148e
2 changed files with 33 additions and 58 deletions

View file

@ -1,10 +1,9 @@
<template> <template>
<canvas ref="waveform"> <div v-html="content" class="waveform">
</canvas> </div>
</template> </template>
<script> <script>
// import util from "../../plugins/utils";
export default { export default {
props: { props: {
@ -15,65 +14,32 @@ export default {
}, },
}, },
}, },
data() { computed: {
return { content() {
}; return this.$sanitize(
}, this.event ? this.event.getContent().formatted_body : "",
mounted() { {
this.drawWaveform(this.event); allowedTags: ["svg", "path"],
}, allowedAttributes: {
methods: { 'svg': ["viewbox", "fill", "preserveaspectratio", "xmlns"],
drawWaveform(event) { 'path': ["d", "style"]
const canvas = this.$refs.waveform;
if (canvas) {
const dpr = window.devicePixelRatio || 1;
canvas.width = canvas.offsetWidth * dpr;
canvas.height = (canvas.offsetHeight) * dpr;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
const base64content = event ? event.getContent().formatted_body : undefined;
if (base64content) {
const data = atob(base64content).split('').map(function (c) { return c.charCodeAt(0); });
const drawLineSegment = (ctx, x, y0, data) => {
ctx.lineWidth = 1; // how thick the line is
ctx.strokeStyle = "#000"; // what color our line is
ctx.beginPath();
ctx.moveTo(x, y0 - data);
ctx.lineTo(x, y0 + data);
ctx.stroke();
};
console.log("W", canvas.width, canvas.height, canvas.offsetWidth, canvas.offsetHeight);
const width = canvas.width;
const height = canvas.height;
const samples = data.length;
for (let i = 0; i < width; i++) {
if (i % 4 == 2 || i % 4 == 3) continue;
const iSample = Math.floor(width == 0 ? 0 :(1000 * i) / width);
const sample = iSample < samples ? data[iSample] : 0;
drawLineSegment(ctx, i, height/2, (sample / 255) * height / 2);
} }
} }
} );
} }
}, },
watch: {
event: {
immediate: false,
handler(event) {
this.drawWaveform(event);
}
}
}
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import "@/assets/css/chat.scss"; @import "@/assets/css/chat.scss";
.waveform svg {
width: 100%;
height: 100%;
path {
stroke: black !important;
}
}
</style> </style>

View file

@ -526,10 +526,19 @@ class Util {
// Integerize // Integerize
filteredData = filteredData.map(n => parseInt((n * 255).toFixed())); filteredData = filteredData.map(n => parseInt((n * 255).toFixed()));
const base64 = Buffer.from(filteredData).toString('base64'); //.replace(/=/g, '')
console.log("BASE64", base64); // Generate SVG of waveform
let svg = `<svg viewBox="0 0 ${samples} 255" fill="none" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">`;
svg += `<path d="`;
filteredData.forEach((d, i) => {
const delta = d / 2;
svg += `M${i} ${128 - delta}V${128 + delta}`;
});
svg += `" style="fill:none;stroke:green;stroke-width:1" />`;
svg += "</svg>";
messageContent.format = "org.matrix.custom.html"; messageContent.format = "org.matrix.custom.html";
messageContent.formatted_body = base64; messageContent.formatted_body = svg;
}) })
} }
} }