255 lines
7.2 KiB
JavaScript
255 lines
7.2 KiB
JavaScript
|
|
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
|
||
|
|
/*
|
||
|
|
Copyright 2018 - 2022 The Matrix.org Foundation C.I.C.
|
||
|
|
|
||
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
you may not use this file except in compliance with the License.
|
||
|
|
You may obtain a copy of the License at
|
||
|
|
|
||
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
|
||
|
|
Unless required by applicable law or agreed to in writing, software
|
||
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
See the License for the specific language governing permissions and
|
||
|
|
limitations under the License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { MsgType } from "./@types/event.js";
|
||
|
|
import { M_TEXT, REFERENCE_RELATION } from "./@types/extensible_events.js";
|
||
|
|
import { isProvided } from "./extensible_events_v1/utilities.js";
|
||
|
|
import { M_ASSET, LocationAssetType, M_LOCATION, M_TIMESTAMP } from "./@types/location.js";
|
||
|
|
import { M_TOPIC } from "./@types/topic.js";
|
||
|
|
/**
|
||
|
|
* Generates the content for a HTML Message event
|
||
|
|
* @param body - the plaintext body of the message
|
||
|
|
* @param htmlBody - the HTML representation of the message
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
export function makeHtmlMessage(body, htmlBody) {
|
||
|
|
return {
|
||
|
|
msgtype: MsgType.Text,
|
||
|
|
format: "org.matrix.custom.html",
|
||
|
|
body: body,
|
||
|
|
formatted_body: htmlBody
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates the content for a HTML Notice event
|
||
|
|
* @param body - the plaintext body of the notice
|
||
|
|
* @param htmlBody - the HTML representation of the notice
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
export function makeHtmlNotice(body, htmlBody) {
|
||
|
|
return {
|
||
|
|
msgtype: MsgType.Notice,
|
||
|
|
format: "org.matrix.custom.html",
|
||
|
|
body: body,
|
||
|
|
formatted_body: htmlBody
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates the content for a HTML Emote event
|
||
|
|
* @param body - the plaintext body of the emote
|
||
|
|
* @param htmlBody - the HTML representation of the emote
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
export function makeHtmlEmote(body, htmlBody) {
|
||
|
|
return {
|
||
|
|
msgtype: MsgType.Emote,
|
||
|
|
format: "org.matrix.custom.html",
|
||
|
|
body: body,
|
||
|
|
formatted_body: htmlBody
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates the content for a Plaintext Message event
|
||
|
|
* @param body - the plaintext body of the emote
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
export function makeTextMessage(body) {
|
||
|
|
return {
|
||
|
|
msgtype: MsgType.Text,
|
||
|
|
body: body
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates the content for a Plaintext Notice event
|
||
|
|
* @param body - the plaintext body of the notice
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
export function makeNotice(body) {
|
||
|
|
return {
|
||
|
|
msgtype: MsgType.Notice,
|
||
|
|
body: body
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates the content for a Plaintext Emote event
|
||
|
|
* @param body - the plaintext body of the emote
|
||
|
|
* @returns
|
||
|
|
*/
|
||
|
|
export function makeEmoteMessage(body) {
|
||
|
|
return {
|
||
|
|
msgtype: MsgType.Emote,
|
||
|
|
body: body
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Location content helpers */
|
||
|
|
|
||
|
|
export const getTextForLocationEvent = (uri, assetType, timestamp, description) => {
|
||
|
|
const date = `at ${new Date(timestamp).toISOString()}`;
|
||
|
|
const assetName = assetType === LocationAssetType.Self ? "User" : undefined;
|
||
|
|
const quotedDescription = description ? `"${description}"` : undefined;
|
||
|
|
return [assetName, "Location", quotedDescription, uri, date].filter(Boolean).join(" ");
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generates the content for a Location event
|
||
|
|
* @param uri - a geo:// uri for the location
|
||
|
|
* @param timestamp - the timestamp when the location was correct (milliseconds since the UNIX epoch)
|
||
|
|
* @param description - the (optional) label for this location on the map
|
||
|
|
* @param assetType - the (optional) asset type of this location e.g. "m.self"
|
||
|
|
* @param text - optional. A text for the location
|
||
|
|
*/
|
||
|
|
export const makeLocationContent = (text, uri, timestamp, description, assetType) => {
|
||
|
|
const defaultedText = text ?? getTextForLocationEvent(uri, assetType || LocationAssetType.Self, timestamp, description);
|
||
|
|
const timestampEvent = timestamp ? {
|
||
|
|
[M_TIMESTAMP.name]: timestamp
|
||
|
|
} : {};
|
||
|
|
return _objectSpread({
|
||
|
|
msgtype: MsgType.Location,
|
||
|
|
body: defaultedText,
|
||
|
|
geo_uri: uri,
|
||
|
|
[M_LOCATION.name]: {
|
||
|
|
description,
|
||
|
|
uri
|
||
|
|
},
|
||
|
|
[M_ASSET.name]: {
|
||
|
|
type: assetType || LocationAssetType.Self
|
||
|
|
},
|
||
|
|
[M_TEXT.name]: defaultedText
|
||
|
|
}, timestampEvent);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parse location event content and transform to
|
||
|
|
* a backwards compatible modern m.location event format
|
||
|
|
*/
|
||
|
|
export const parseLocationEvent = wireEventContent => {
|
||
|
|
const location = M_LOCATION.findIn(wireEventContent);
|
||
|
|
const asset = M_ASSET.findIn(wireEventContent);
|
||
|
|
const timestamp = M_TIMESTAMP.findIn(wireEventContent);
|
||
|
|
const text = M_TEXT.findIn(wireEventContent);
|
||
|
|
const geoUri = location?.uri ?? wireEventContent?.geo_uri;
|
||
|
|
const description = location?.description;
|
||
|
|
const assetType = asset?.type ?? LocationAssetType.Self;
|
||
|
|
const fallbackText = text ?? wireEventContent.body;
|
||
|
|
return makeLocationContent(fallbackText, geoUri, timestamp ?? undefined, description, assetType);
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Topic event helpers
|
||
|
|
*/
|
||
|
|
|
||
|
|
export const makeTopicContent = (topic, htmlTopic) => {
|
||
|
|
const renderings = [];
|
||
|
|
// Put HTML first because clients will render the first type in
|
||
|
|
// the array that they understand
|
||
|
|
if (isProvided(htmlTopic)) {
|
||
|
|
renderings.push({
|
||
|
|
body: htmlTopic,
|
||
|
|
mimetype: "text/html"
|
||
|
|
});
|
||
|
|
}
|
||
|
|
if (isProvided(topic)) {
|
||
|
|
renderings.push({
|
||
|
|
body: topic,
|
||
|
|
mimetype: "text/plain"
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return {
|
||
|
|
topic,
|
||
|
|
[M_TOPIC.name]: {
|
||
|
|
"m.text": renderings
|
||
|
|
}
|
||
|
|
};
|
||
|
|
};
|
||
|
|
export const parseTopicContent = content => {
|
||
|
|
const mtopicParent = M_TOPIC.findIn(content);
|
||
|
|
const mtopic = Array.isArray(mtopicParent) ? mtopicParent : mtopicParent?.["m.text"];
|
||
|
|
// TODO remove support for the old malformed m.topic arrays after a few releases (only allow array in m.text)
|
||
|
|
// https://github.com/matrix-org/matrix-js-sdk/pull/4984#pullrequestreview-3174251065
|
||
|
|
//const mtopic = M_TOPIC.findIn<MTopicContent>(content)?.["m.text"];
|
||
|
|
if (!Array.isArray(mtopic)) {
|
||
|
|
return {
|
||
|
|
text: content.topic ?? undefined
|
||
|
|
};
|
||
|
|
}
|
||
|
|
const text = mtopic?.find(r => !isProvided(r.mimetype) || r.mimetype === "text/plain")?.body ?? content.topic ?? undefined;
|
||
|
|
const html = mtopic?.find(r => r.mimetype === "text/html")?.body;
|
||
|
|
return {
|
||
|
|
text,
|
||
|
|
html
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Beacon event helpers
|
||
|
|
*/
|
||
|
|
|
||
|
|
export const makeBeaconInfoContent = (timeout, isLive, description, assetType, timestamp) => ({
|
||
|
|
description,
|
||
|
|
timeout,
|
||
|
|
live: isLive,
|
||
|
|
[M_TIMESTAMP.name]: timestamp || Date.now(),
|
||
|
|
[M_ASSET.name]: {
|
||
|
|
type: assetType ?? LocationAssetType.Self
|
||
|
|
}
|
||
|
|
});
|
||
|
|
/**
|
||
|
|
* Flatten beacon info event content
|
||
|
|
*/
|
||
|
|
export const parseBeaconInfoContent = content => {
|
||
|
|
const {
|
||
|
|
description,
|
||
|
|
timeout,
|
||
|
|
live
|
||
|
|
} = content;
|
||
|
|
const timestamp = M_TIMESTAMP.findIn(content) ?? undefined;
|
||
|
|
const asset = M_ASSET.findIn(content);
|
||
|
|
return {
|
||
|
|
description,
|
||
|
|
timeout,
|
||
|
|
live,
|
||
|
|
assetType: asset?.type,
|
||
|
|
timestamp
|
||
|
|
};
|
||
|
|
};
|
||
|
|
export const makeBeaconContent = (uri, timestamp, beaconInfoEventId, description) => ({
|
||
|
|
[M_LOCATION.name]: {
|
||
|
|
description,
|
||
|
|
uri
|
||
|
|
},
|
||
|
|
[M_TIMESTAMP.name]: timestamp,
|
||
|
|
"m.relates_to": {
|
||
|
|
rel_type: REFERENCE_RELATION.name,
|
||
|
|
event_id: beaconInfoEventId
|
||
|
|
}
|
||
|
|
});
|
||
|
|
export const parseBeaconContent = content => {
|
||
|
|
const location = M_LOCATION.findIn(content);
|
||
|
|
const timestamp = M_TIMESTAMP.findIn(content) ?? undefined;
|
||
|
|
return {
|
||
|
|
description: location?.description,
|
||
|
|
uri: location?.uri,
|
||
|
|
timestamp
|
||
|
|
};
|
||
|
|
};
|
||
|
|
//# sourceMappingURL=content-helpers.js.map
|