Send progress in main view

This commit is contained in:
N-Pex 2025-08-20 15:12:04 +02:00
parent 41232fbd90
commit e9accdebf1
11 changed files with 465 additions and 86 deletions

13
src/plugins/touch.js Normal file
View file

@ -0,0 +1,13 @@
import Hammer from "hammerjs";
export function singleOrDoubleTapRecognizer(element) {
// reference: https://codepen.io/jtangelder/pen/xxYyJQ
const hm = new Hammer.Manager(element);
hm.add(new Hammer.Tap({ event: "doubletap", taps: 2 }));
hm.add(new Hammer.Tap({ event: "singletap" }));
hm.get("doubletap").recognizeWith("singletap");
hm.get("singletap").requireFailure("doubletap");
return hm;
}

View file

@ -4,7 +4,6 @@ import imageResize from "image-resize";
import { AutoDiscovery, Method } from "matrix-js-sdk";
import User from "../models/user";
import prettyBytes from "pretty-bytes";
import Hammer from "hammerjs";
import { Thread } from "matrix-js-sdk/lib/models/thread";
import { imageSize } from "image-size";
import dayjs from "dayjs";
@ -144,13 +143,29 @@ class Util {
var file = null;
let decrypt = true;
if (!!content.info && !!content.info.thumbnail_url) {
url = matrixClient.mxcUrlToHttp(content.info.thumbnail_url, undefined, undefined, undefined, undefined, undefined, useAuthedMedia);
url = matrixClient.mxcUrlToHttp(
content.info.thumbnail_url,
undefined,
undefined,
undefined,
undefined,
undefined,
useAuthedMedia
);
decrypt = false;
if (content.info.thumbnail_info) {
mime = content.info.thumbnail_info.mimetype;
}
} else if (content.url != null) {
url = matrixClient.mxcUrlToHttp(content.url, undefined, undefined, undefined, undefined, undefined, useAuthedMedia);
url = matrixClient.mxcUrlToHttp(
content.url,
undefined,
undefined,
undefined,
undefined,
undefined,
useAuthedMedia
);
decrypt = false;
if (content.info) {
mime = content.info.mimetype;
@ -175,13 +190,17 @@ class Util {
throw new Error("No url found!");
}
const response = await axios
.get(url, useAuthedMedia ? {
responseType: "arraybuffer",
headers: {
Authorization: `Bearer ${matrixClient.getAccessToken()}`,
},
} : { responseType: "arraybuffer" });
const response = await axios.get(
url,
useAuthedMedia
? {
responseType: "arraybuffer",
headers: {
Authorization: `Bearer ${matrixClient.getAccessToken()}`,
},
}
: { responseType: "arraybuffer" }
);
const bytes = decrypt ? await this.decryptIfNeeded(file, response) : { buffer: response.data };
return URL.createObjectURL(new Blob([bytes.buffer], { type: mime }));
}
@ -217,7 +236,7 @@ class Util {
});
}
sendTextMessage(matrixClient, roomId, text, editedEvent, replyToEvent) {
sendTextMessage(matrixClient, roomId, text, editedEvent, replyToEvent, txnId) {
var content = ContentHelpers.makeTextMessage(text);
if (editedEvent) {
content["m.relates_to"] = {
@ -248,7 +267,7 @@ class Util {
.join("\n");
content.body = prefix + "\n\n" + content.body;
}
return this.sendMessage(matrixClient, roomId, "m.room.message", content);
return this.sendMessage(matrixClient, roomId, "m.room.message", content, txnId);
}
sendQuickReaction(matrixClient, roomId, emoji, event, extraData = {}) {
@ -306,10 +325,10 @@ class Util {
return this.sendMessage(matrixClient, roomId, "org.matrix.msc3381.poll.response", content);
}
sendMessage(matrixClient, roomId, eventType, content) {
sendMessage(matrixClient, roomId, eventType, content, txnId) {
return new Promise((resolve, reject) => {
matrixClient
.sendEvent(roomId, eventType, content, undefined, undefined)
.sendEvent(roomId, eventType, content, txnId, undefined)
.then((result) => {
console.log("Message sent: ", result);
resolve(result.event_id);
@ -419,7 +438,7 @@ class Util {
var description = file.name;
var msgtype = "m.file";
if (thumbnail) {
thumbnailData = thumbnail.data;
thumbnailInfo = {
@ -428,8 +447,8 @@ class Util {
w: thumbnail.w,
h: thumbnail.h,
};
}
}
if (file.type.startsWith("image/")) {
msgtype = "m.image";
@ -446,7 +465,9 @@ class Util {
width: newWidth,
height: newHeight,
outputType: "blob",
}).catch(() => {return Promise.resolve(undefined)});
}).catch(() => {
return Promise.resolve(undefined);
});
if (scaled && file.size > scaled.size) {
thumbnailData = new Uint8Array(await scaled.arrayBuffer());
thumbnailInfo = {
@ -483,12 +504,19 @@ class Util {
messageContent.filename = file.name;
}
let totalBytes = 0;
let thumbBytes = 0;
const useEncryption = matrixClient.isRoomEncrypted(roomId);
const dataUploadOpts = {
type: useEncryption ? "application/octet-stream" : file.type,
name: description,
progressHandler: onUploadProgress,
progressHandler: ({ loaded, total }) => {
if (onUploadProgress) {
onUploadProgress({ loaded: loaded + thumbBytes, total: totalBytes });
}
},
onlyContentUri: false,
};
@ -498,6 +526,8 @@ class Util {
data = encryptedBytes;
}
totalBytes = data.length;
if (thumbnailData) {
messageContent.thumbnail_info = thumbnailInfo;
if (useEncryption) {
@ -505,10 +535,16 @@ class Util {
messageContent.info.thumbnail_file = encryptedFile;
thumbnailData = encryptedBytes;
}
thumbBytes = thumbnailData.length;
totalBytes += thumbnailData.length;
const thumbnailUploadOpts = {
type: useEncryption ? "application/octet-stream" : file.type,
name: "thumb:" + description,
progressHandler: onUploadProgress,
progressHandler: ({ loaded, total }) => {
if (onUploadProgress) {
onUploadProgress({ loaded: loaded, total: totalBytes });
}
},
onlyContentUri: false,
};
const thumbUploadPromise = matrixClient.uploadContent(thumbnailData, thumbnailUploadOpts);
@ -1162,18 +1198,6 @@ class Util {
return mobileTabletPattern.test(userAgent);
}
singleOrDoubleTabRecognizer(element) {
// reference: https://codepen.io/jtangelder/pen/xxYyJQ
const hm = new Hammer.Manager(element);
hm.add(new Hammer.Tap({ event: "doubletap", taps: 2 }));
hm.add(new Hammer.Tap({ event: "singletap" }));
hm.get("doubletap").recognizeWith("singletap");
hm.get("singletap").requireFailure("doubletap");
return hm;
}
/**
* Possibly convert numerals to local representation (currently only for "bo" locale)
* @param str String in which to convert numerals [0-9]