Merge branch 'develop' into travis/remove-skinning

This commit is contained in:
Travis Ralston 2022-03-31 19:25:43 -06:00
commit 97efdf7094
54 changed files with 1559 additions and 431 deletions

View file

@ -17,7 +17,8 @@
import { arrayHasDiff } from "./arrays";
export function mayBeAnimated(mimeType: string): boolean {
return ["image/gif", "image/webp", "image/png", "image/apng"].includes(mimeType);
// AVIF animation support at the time of writing is only available in Chrome hence not having `blobIsAnimated` check
return ["image/gif", "image/webp", "image/png", "image/apng", "image/avif"].includes(mimeType);
}
function arrayBufferRead(arr: ArrayBuffer, start: number, len: number): Uint8Array {

View file

@ -203,18 +203,32 @@ export default class MultiInviter {
logger.error(err);
let errorText;
const isSpace = this.roomId && this.matrixClient.getRoom(this.roomId)?.isSpaceRoom();
let errorText: string;
let fatal = false;
switch (err.errcode) {
case "M_FORBIDDEN":
errorText = _t('You do not have permission to invite people to this room.');
if (isSpace) {
errorText = _t('You do not have permission to invite people to this space.');
} else {
errorText = _t('You do not have permission to invite people to this room.');
}
fatal = true;
break;
case USER_ALREADY_INVITED:
errorText = _t("User %(userId)s is already invited to the room", { userId: address });
if (isSpace) {
errorText = _t("User is already invited to the space");
} else {
errorText = _t("User is already invited to the room");
}
break;
case USER_ALREADY_JOINED:
errorText = _t("User %(userId)s is already in the room", { userId: address });
if (isSpace) {
errorText = _t("User is already in the space");
} else {
errorText = _t("User is already in the room");
}
break;
case "M_LIMIT_EXCEEDED":
// we're being throttled so wait a bit & try again
@ -224,10 +238,10 @@ export default class MultiInviter {
return;
case "M_NOT_FOUND":
case "M_USER_NOT_FOUND":
errorText = _t("User %(user_id)s does not exist", { user_id: address });
errorText = _t("User does not exist");
break;
case "M_PROFILE_UNDISCLOSED":
errorText = _t("User %(user_id)s may or may not exist", { user_id: address });
errorText = _t("User may or may not exist");
break;
case "M_PROFILE_NOT_FOUND":
if (!ignoreProfile) {
@ -241,7 +255,11 @@ export default class MultiInviter {
errorText = _t("The user must be unbanned before they can be invited.");
break;
case "M_UNSUPPORTED_ROOM_VERSION":
errorText = _t("The user's homeserver does not support the version of the room.");
if (isSpace) {
errorText = _t("The user's homeserver does not support the version of the space.");
} else {
errorText = _t("The user's homeserver does not support the version of the room.");
}
break;
}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { IContent, MatrixEvent } from "matrix-js-sdk/src/models/event";
import { IContent, IEventRelation, MatrixEvent } from "matrix-js-sdk/src/models/event";
import sanitizeHtml from "sanitize-html";
import escapeHtml from "escape-html";
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
@ -22,7 +22,6 @@ import { MsgType } from "matrix-js-sdk/src/@types/event";
import { PERMITTED_URL_SCHEMES } from "../HtmlUtils";
import { makeUserPermalink, RoomPermalinkCreator } from "./permalinks/Permalinks";
import { RecursivePartial } from "../@types/common";
import SettingsStore from "../settings/SettingsStore";
export function getParentEventId(ev?: MatrixEvent): string | undefined {
@ -144,30 +143,17 @@ export function getNestedReplyText(
return { body, html };
}
export function makeReplyMixIn(ev?: MatrixEvent): RecursivePartial<IContent> {
export function makeReplyMixIn(ev?: MatrixEvent): IEventRelation {
if (!ev) return {};
const mixin: RecursivePartial<IContent> = {
'm.relates_to': {
'm.in_reply_to': {
'event_id': ev.getId(),
},
const mixin: IEventRelation = {
'm.in_reply_to': {
'event_id': ev.getId(),
},
};
/**
* If the event replied is part of a thread
* Add the `m.thread` relation so that clients
* that know how to handle that relation will
* be able to render them more accurately
*/
if (ev.isThreadRelation || ev.isThreadRoot) {
mixin['m.relates_to'] = {
...mixin['m.relates_to'],
is_falling_back: false,
rel_type: THREAD_RELATION_TYPE.name,
event_id: ev.threadRootId,
};
if (SettingsStore.getValue("feature_thread") && ev.threadRootId) {
mixin.is_falling_back = false;
}
return mixin;
@ -206,12 +192,13 @@ export function addReplyToMessageContent(
includeLegacyFallback: true,
},
): void {
const replyContent = makeReplyMixIn(replyToEvent);
Object.assign(content, replyContent);
content["m.relates_to"] = {
...(content["m.relates_to"] || {}),
...makeReplyMixIn(replyToEvent),
};
if (opts.includeLegacyFallback) {
// Part of Replies fallback support - prepend the text we're sending
// with the text we're replying to
// Part of Replies fallback support - prepend the text we're sending with the text we're replying to
const nestedReply = getNestedReplyText(replyToEvent, opts.permalinkCreator);
if (nestedReply) {
if (content.formatted_body) {

View file

@ -34,3 +34,7 @@ export const getBeaconExpiryTimestamp = (beacon: Beacon): number =>
export const sortBeaconsByLatestExpiry = (left: Beacon, right: Beacon): number =>
getBeaconExpiryTimestamp(right) - getBeaconExpiryTimestamp(left);
// aka sort by timestamp descending
export const sortBeaconsByLatestCreation = (left: Beacon, right: Beacon): number =>
right.beaconInfo.timestamp - left.beaconInfo.timestamp;

View file

@ -54,6 +54,7 @@ const ALLOWED_BLOB_MIMETYPES = [
'image/png',
'image/apng',
'image/webp',
'image/avif',
'video/mp4',
'video/webm',