-
-
-
-
-
-
-
-
-
-
+
+ {/*
+
+
*/}
+
+
-
+
+
+
+
+
);
}
diff --git a/src/app/templates/client/Client.scss b/src/app/templates/client/Client.scss
index cdb8fcc9..bad5fc93 100644
--- a/src/app/templates/client/Client.scss
+++ b/src/app/templates/client/Client.scss
@@ -3,11 +3,12 @@
.client-container {
display: flex;
height: 100%;
+ flex-grow: 1;
}
.navigation__wrapper {
width: var(--navigation-width);
-
+
@include screen.smallerThan(mobileBreakpoint) {
width: 100%;
}
diff --git a/src/app/templates/client/ClientContent.jsx b/src/app/templates/client/ClientContent.jsx
index ada7008e..cebe012c 100644
--- a/src/app/templates/client/ClientContent.jsx
+++ b/src/app/templates/client/ClientContent.jsx
@@ -6,7 +6,7 @@ import navigation from '../../../client/state/navigation';
import { openNavigation } from '../../../client/action/navigation';
import Welcome from '../../organisms/welcome/Welcome';
-import { RoomBaseView } from '../../organisms/room/Room';
+import { RoomBaseView } from '../../features/room/Room';
export function ClientContent() {
const [roomInfo, setRoomInfo] = useState({
diff --git a/src/app/utils/ASCIILexicalTable.ts b/src/app/utils/ASCIILexicalTable.ts
new file mode 100644
index 00000000..61b2481a
--- /dev/null
+++ b/src/app/utils/ASCIILexicalTable.ts
@@ -0,0 +1,393 @@
+export class ASCIILexicalTable {
+ readonly startCode: number;
+
+ readonly endCode: number;
+
+ readonly maxStrWidth: number;
+
+ private readonly widthToSize: number[];
+
+ private readonly rangeCount: (i: number, j: number) => number;
+
+ constructor(startCode: number, endCode: number, maxStrWidth: number) {
+ if (startCode > endCode) {
+ throw new Error('Invalid ASCII code! startCode is greater than endCode.');
+ }
+ if (startCode < 0 || endCode > 128) {
+ throw new Error('Invalid ASCII code range!');
+ }
+
+ if (maxStrWidth <= 0) {
+ throw new Error('Invalid max string width!');
+ }
+
+ this.maxStrWidth = maxStrWidth;
+ this.startCode = startCode;
+ this.endCode = endCode;
+
+ /**
+ * @param i smaller - inclusive
+ * @param j larger - inclusive
+ * @returns number
+ */
+ this.rangeCount = (i: number, j: number): number => j - i + 1;
+
+ this.widthToSize = [];
+ this.populateWidthToSize();
+
+ if (this.size() > Number.MAX_SAFE_INTEGER) {
+ console.warn(
+ `[!] Warning: ASCIILexicalTable size is larger than the Number.MAX_SAFE_INTEGER: ${this.size()} > ${
+ Number.MAX_SAFE_INTEGER
+ }`
+ );
+ }
+ }
+
+ private populateWidthToSize() {
+ const chars = this.rangeCount(this.startCode, this.endCode);
+ for (let i = 0, count = 0; i < this.maxStrWidth; i += 1) {
+ count = count * chars + chars;
+ this.widthToSize[i] = count;
+ }
+ }
+
+ private getWidthToSize(width: number): number {
+ return this.widthToSize[width - 1];
+ }
+
+ first(): string {
+ return String.fromCharCode(this.startCode);
+ }
+
+ last(): string {
+ let str = '';
+ for (let i = 0; i < this.maxStrWidth; i += 1) {
+ str += String.fromCharCode(this.endCode);
+ }
+ return str;
+ }
+
+ hasIndex(index: number): boolean {
+ return index >= 0 && index < this.size();
+ }
+
+ has(str: string): boolean {
+ if (str.length === 0 || str.length > this.maxStrWidth) {
+ return false;
+ }
+
+ let charCode: number;
+ for (let i = 0; i < str.length; i += 1) {
+ charCode = str.charCodeAt(i);
+ if (charCode < this.startCode || charCode > this.endCode) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ size(): number {
+ return this.getWidthToSize(this.maxStrWidth);
+ }
+
+ index(str: string): number {
+ if (!this.has(str)) {
+ return -1;
+ }
+
+ let index = 0;
+ const chars = this.rangeCount(this.startCode, this.endCode);
+
+ for (let i = 0; i < this.maxStrWidth; i += 1) {
+ const code = str.charCodeAt(i);
+
+ if (Number.isNaN(code)) {
+ return index;
+ }
+
+ const opStrWidth = this.maxStrWidth - i;
+ const opStrTableSize = this.getWidthToSize(opStrWidth);
+
+ const segmentSize = opStrTableSize / chars;
+
+ const codeIndex = code - this.startCode;
+ const emptyCount = i === 0 ? 0 : 1;
+
+ index += segmentSize * codeIndex + emptyCount;
+ }
+
+ return index;
+ }
+
+ get(index: number): string | undefined {
+ if (!this.hasIndex(index)) {
+ return undefined;
+ }
+
+ let str = '';
+ const chars = this.rangeCount(this.startCode, this.endCode);
+
+ for (let toIndex = index, i = 0; i < this.maxStrWidth; i += 1) {
+ const opStrWidth = this.maxStrWidth - i;
+ const opStrTableSize = this.getWidthToSize(opStrWidth);
+
+ const segmentSize = opStrTableSize / chars;
+
+ const segmentIndex = Math.floor(toIndex / segmentSize);
+ str += String.fromCharCode(this.startCode + segmentIndex);
+
+ toIndex -= segmentIndex * segmentSize;
+ if (toIndex === 0) {
+ break;
+ }
+ toIndex -= 1;
+ }
+
+ return str;
+ }
+
+ previous(str: string): string | undefined {
+ if (!this.has(str)) return undefined;
+ let prev = str;
+ const lastCode = prev.charCodeAt(prev.length - 1);
+ prev = prev.slice(0, prev.length - 1);
+
+ if (lastCode === this.startCode) {
+ if (prev.length === 0) return undefined;
+ return prev;
+ }
+
+ prev += String.fromCharCode(lastCode - 1);
+ while (prev.length < this.maxStrWidth) {
+ prev += String.fromCharCode(this.endCode);
+ }
+ return prev;
+ }
+
+ next(str: string): string | undefined {
+ if (!this.has(str)) return undefined;
+ let next = str;
+
+ if (next.length < this.maxStrWidth) {
+ next += String.fromCharCode(this.startCode);
+ return next;
+ }
+
+ for (let i = next.length - 1; i >= 0; i -= 1) {
+ const lastCode = next.charCodeAt(i);
+ if (lastCode !== this.endCode) {
+ next = next.slice(0, i) + String.fromCharCode(lastCode + 1);
+ return next;
+ }
+ next = next.slice(0, i);
+ }
+ return undefined;
+ }
+
+ between(a: string, b: string): string | undefined {
+ if (!this.has(a) || !this.has(b)) {
+ return undefined;
+ }
+
+ const centerIndex = Math.floor((this.index(a) + this.index(b)) / 2);
+
+ const str = this.get(centerIndex);
+ if (str === a || str === b) return undefined;
+ return str;
+ }
+
+ nBetween(n: number, a: string, b: string): string[] | undefined {
+ if (n <= 0 || !this.has(a) || !this.has(b)) {
+ return undefined;
+ }
+
+ const indexA = this.index(a);
+ const indexB = this.index(b);
+
+ const nBetween = Math.max(indexA, indexB) - Math.min(indexA, indexB);
+ if (nBetween < n) {
+ return undefined;
+ }
+ const segmentSize = Math.floor(nBetween / (n + 1));
+ if (segmentSize === 0) return undefined;
+
+ const items: string[] = [];
+
+ for (
+ let segmentIndex = indexA + segmentSize;
+ segmentIndex < indexB;
+ segmentIndex += segmentSize
+ ) {
+ if (items.length === n) break;
+
+ const str = this.get(segmentIndex);
+
+ if (!str) break;
+ items.push(str);
+ }
+
+ if (items.length < n) {
+ return undefined;
+ }
+
+ return items;
+ }
+}
+
+// const printLex = (lex: ASCIILexicalTable) => {
+// const padRight = (s: string, maxWidth: number, padding: string): string => {
+// let ns = s;
+// for (let i = s.length; i < maxWidth; i += 1) {
+// ns += padding;
+// }
+// return ns;
+// };
+
+// const formattedLine = (n: number, item: string): string =>
+// `|${padRight(n.toString(), lex.size().toString().length, ' ')}|${item}|`;
+
+// const hr = `|${padRight('-', lex.size().toString().length, '-')}|${padRight(
+// '-',
+// lex.maxStrWidth,
+// '-'
+// )}|`;
+
+// console.log(`All lexicographic string combination in order.`);
+// console.log(`Start ASCII code: "${lex.startCode}"`);
+// console.log(`End ASCII code: "${lex.endCode}"`);
+// console.log(`Max string width: ${lex.maxStrWidth}`);
+// console.log(`Total String Combination Count: ${lex.size()}\n`);
+// console.log('Table:');
+// console.log(hr);
+// for (let i = 0; i < lex.size(); i += 1) {
+// const str = lex.get(i);
+// if (str) {
+// console.log(formattedLine(i, padRight(str, lex.maxStrWidth, '_')));
+// }
+// }
+// console.log(hr);
+// };
+
+// console.log('\n');
+
+// const lex = new ASCIILexicalTable('a'.charCodeAt(0), 'c'.charCodeAt(0), 3);
+// printLex(lex);
+// console.log(lex.size());
+// console.log(lex.nBetween(8, ' ', '~~~~~'));
+// console.log(lex.between('a', 'ccc'));
+// console.log(lex.get(11));
+// console.log(lex.get(11) === 'aaac');
+
+// const lex4 = new ASCIILexicalTable(' '.charCodeAt(0), '~'.charCodeAt(0), 5);
+// console.log('Size: ', lex4.size());
+// console.log('Between: ', lex4.between('7g7g5', 'caccc'));
+// printLex(lex4);
+
+// console.log('\n');
+
+// const perf = () => {
+// const loopLength = 99999;
+// const lexT = new ASCIILexicalTable('a'.charCodeAt(0), 'z'.charCodeAt(0), 9);
+// console.log(lexT.size());
+// const str = 'bcbba';
+// const strI = lexT.index(str);
+// console.log('================');
+// console.time('index');
+// console.log(lexT.index(str));
+// for (let i = 0; i < loopLength; i += 1) {
+// lexT.index(str);
+// }
+// console.timeEnd('index');
+// console.log('================');
+// console.time('get');
+// console.log(lexT.get(strI));
+// for (let i = 0; i < loopLength; i += 1) {
+// lexT.get(strI);
+// }
+// console.timeEnd('get');
+// console.log('================');
+// console.time('previous');
+// console.log(lexT.previous(str));
+// for (let i = 0; i < loopLength; i += 1) {
+// lexT.previous(str);
+// }
+// console.timeEnd('previous');
+// console.log('================');
+// console.time('next');
+// console.log(lexT.next(str));
+// for (let i = 0; i < loopLength; i += 1) {
+// lexT.next(str);
+// }
+// console.timeEnd('next');
+// console.log('================');
+// console.time('between');
+// console.log(lexT.between(str, 'cbbca'));
+// for (let i = 0; i < loopLength; i += 1) {
+// lexT.between(str, 'cbbca');
+// }
+// console.timeEnd('between');
+// };
+
+// perf();
+
+const findNextFilledKey = (
+ fromIndex: number,
+ keys: Array
+): [number, string] | [-1, undefined] => {
+ for (let j = fromIndex; j < keys.length; j += 1) {
+ const key = keys[j];
+ if (typeof key === 'string') {
+ return [j, key];
+ }
+ }
+
+ return [-1, undefined];
+};
+
+export const orderKeys = (
+ lex: ASCIILexicalTable,
+ keys: Array
+): Array | undefined => {
+ const newKeys: string[] = [];
+
+ for (let i = 0; i < keys.length; ) {
+ const key = keys[i];
+ const collectedKeys: string[] = [];
+ const [nextKeyIndex, nextKey] = findNextFilledKey(i + 1, keys);
+ const isKey = typeof key === 'string';
+
+ if (isKey) {
+ collectedKeys.push(key);
+ }
+
+ const keyToGenerateCount =
+ (nextKeyIndex === -1 ? keys.length : nextKeyIndex) - (key ? i + 1 : i + 0);
+
+ if (keyToGenerateCount > 0) {
+ const generatedKeys = lex.nBetween(
+ keyToGenerateCount,
+ key ?? lex.first(),
+ nextKey ?? lex.last()
+ );
+ if (generatedKeys) {
+ collectedKeys.push(...generatedKeys);
+ } else {
+ return lex.nBetween(keys?.length, lex.first(), lex.last());
+ }
+ }
+
+ newKeys.push(...collectedKeys);
+ i += collectedKeys.length;
+ }
+
+ if (newKeys.length !== keys.length) {
+ return undefined;
+ }
+
+ return newKeys;
+};
+
+// const lex = new ASCIILexicalTable('a'.charCodeAt(0), 'b'.charCodeAt(0), 2);
+// const keys = [undefined, undefined];
+// console.log(orderKeys(lex, keys));
diff --git a/src/app/utils/common.ts b/src/app/utils/common.ts
index 5cbe3806..6d7b69c1 100644
--- a/src/app/utils/common.ts
+++ b/src/app/utils/common.ts
@@ -95,3 +95,20 @@ export const trimLeadingSlash = (str: string): string => str.replace(START_SLASH
export const trimTrailingSlash = (str: string): string => str.replace(END_SLASHES_REG, '');
export const trimSlash = (str: string): string => trimLeadingSlash(trimTrailingSlash(str));
+
+export const nameInitials = (str: string | undefined | null, len = 1): string => {
+ if (!str) return '�';
+ return [...str].slice(0, len).join('') || '�';
+};
+
+export const randomStr = (len = 12): string => {
+ let str = '';
+ const minCode = 'A'.charCodeAt(0);
+ const maxCode = 'Z'.charCodeAt(0);
+
+ for (let i = 0; i < len; i += 1) {
+ const code = Math.floor(Math.random() * (maxCode - minCode + 1) + minCode);
+ str += String.fromCharCode(code);
+ }
+ return str;
+};
diff --git a/src/app/utils/keyboard.ts b/src/app/utils/keyboard.ts
index 78aa2521..8ec435d3 100644
--- a/src/app/utils/keyboard.ts
+++ b/src/app/utils/keyboard.ts
@@ -23,3 +23,10 @@ export const preventScrollWithArrowKey: KeyboardEventHandler = (evt) => {
evt.preventDefault();
}
};
+
+export const onEnterOrSpace = (callback: () => void) => (evt: KeyboardEventLike) => {
+ if (isKeyHotkey('enter', evt) || isKeyHotkey('space', evt)) {
+ evt.preventDefault();
+ callback();
+ }
+};
diff --git a/src/app/utils/matrix.ts b/src/app/utils/matrix.ts
index 9303c9ac..55e16a95 100644
--- a/src/app/utils/matrix.ts
+++ b/src/app/utils/matrix.ts
@@ -8,10 +8,12 @@ import {
MatrixError,
MatrixEvent,
Room,
+ RoomMember,
UploadProgress,
UploadResponse,
} from 'matrix-js-sdk';
import { IImageInfo, IThumbnailContent, IVideoInfo } from '../../types/matrix/common';
+import { AccountDataEvent } from '../../types/matrix/accountData';
export const matchMxId = (id: string): RegExpMatchArray | null =>
id.match(/^([@!$+#])(\S+):(\S+)$/);
@@ -37,8 +39,11 @@ export const parseMatrixToUrl = (url: string): [string | undefined, string | und
return [g1AsMxId, g3AsVia];
};
-export const getRoomWithCanonicalAlias = (mx: MatrixClient, alias: string): Room | undefined =>
- mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias);
+export const getCanonicalAliasRoomId = (mx: MatrixClient, alias: string): string | undefined =>
+ mx.getRooms()?.find((room) => room.getCanonicalAlias() === alias)?.roomId;
+
+export const getCanonicalAliasOrRoomId = (mx: MatrixClient, roomId: string): string =>
+ mx.getRoom(roomId)?.getCanonicalAlias() || roomId;
export const getImageInfo = (img: HTMLImageElement, fileOrBlob: File | Blob): IImageInfo => {
const info: IImageInfo = {};
@@ -162,10 +167,86 @@ export const factoryEventSentBy = (senderId: string) => (ev: MatrixEvent) =>
export const eventWithShortcode = (ev: MatrixEvent) =>
typeof ev.getContent().shortcode === 'string';
-export function hasDMWith(mx: MatrixClient, userId: string) {
+export const getDMRoomFor = (mx: MatrixClient, userId: string): Room | undefined => {
const dmLikeRooms = mx
.getRooms()
.filter((room) => mx.isRoomEncrypted(room.roomId) && room.getMembers().length <= 2);
return dmLikeRooms.find((room) => room.getMember(userId));
-}
+};
+
+export const guessDmRoomUserId = (room: Room, myUserId: string): string => {
+ const getOldestMember = (members: RoomMember[]): RoomMember | undefined => {
+ let oldestMemberTs: number | undefined;
+ let oldestMember: RoomMember | undefined;
+
+ const pickOldestMember = (member: RoomMember) => {
+ if (member.userId === myUserId) return;
+
+ if (
+ oldestMemberTs === undefined ||
+ (member.events.member && member.events.member.getTs() < oldestMemberTs)
+ ) {
+ oldestMember = member;
+ oldestMemberTs = member.events.member?.getTs();
+ }
+ };
+
+ members.forEach(pickOldestMember);
+
+ return oldestMember;
+ };
+
+ // Pick the joined user who's been here longest (and isn't us),
+ const member = getOldestMember(room.getJoinedMembers());
+ if (member) return member.userId;
+
+ // if there are no joined members other than us, use the oldest member
+ const member1 = getOldestMember(room.currentState.getMembers());
+ return member1?.userId ?? myUserId;
+};
+
+export const addRoomIdToMDirect = async (
+ mx: MatrixClient,
+ roomId: string,
+ userId: string
+): Promise => {
+ const mDirectsEvent = mx.getAccountData(AccountDataEvent.Direct);
+ const userIdToRoomIds: Record = mDirectsEvent?.getContent() ?? {};
+
+ // remove it from the lists of any others users
+ // (it can only be a DM room for one person)
+ Object.keys(userIdToRoomIds).forEach((targetUserId) => {
+ const roomIds = userIdToRoomIds[targetUserId];
+
+ if (targetUserId !== userId) {
+ const indexOfRoomId = roomIds.indexOf(roomId);
+ if (indexOfRoomId > -1) {
+ roomIds.splice(indexOfRoomId, 1);
+ }
+ }
+ });
+
+ const roomIds = userIdToRoomIds[userId] || [];
+ if (roomIds.indexOf(roomId) === -1) {
+ roomIds.push(roomId);
+ }
+ userIdToRoomIds[userId] = roomIds;
+
+ await mx.setAccountData(AccountDataEvent.Direct, userIdToRoomIds);
+};
+
+export const removeRoomIdFromMDirect = async (mx: MatrixClient, roomId: string): Promise => {
+ const mDirectsEvent = mx.getAccountData(AccountDataEvent.Direct);
+ const userIdToRoomIds: Record = mDirectsEvent?.getContent() ?? {};
+
+ Object.keys(userIdToRoomIds).forEach((targetUserId) => {
+ const roomIds = userIdToRoomIds[targetUserId];
+ const indexOfRoomId = roomIds.indexOf(roomId);
+ if (indexOfRoomId > -1) {
+ roomIds.splice(indexOfRoomId, 1);
+ }
+ });
+
+ await mx.setAccountData(AccountDataEvent.Direct, userIdToRoomIds);
+};
diff --git a/src/app/utils/regex.ts b/src/app/utils/regex.ts
index 281f1200..d7169062 100644
--- a/src/app/utils/regex.ts
+++ b/src/app/utils/regex.ts
@@ -1,5 +1,7 @@
export const HTTP_URL_PATTERN = `https?:\\/\\/(?:www\\.)?(?:[^\\s)]*)(?()[\]\\.,;:\s@\\"]+(\.[^<>()[\]\\.,;:\s@\\"]+)*)|(\\".+\\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
@@ -10,3 +12,9 @@ export const VARIATION_SELECTOR_PATTERN = '[\uFE00-\uFE0F]';
// https://github.com/mathiasbynens/emoji-regex
export const EMOJI_PATTERN = `[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)`;
+
+// Thumbs up emoji found to have Variation Selector 16 at the end
+// so included variation selector pattern in regex
+export const JUMBO_EMOJI_REG = new RegExp(
+ `^(((${EMOJI_PATTERN})|(:.+?:))(${VARIATION_SELECTOR_PATTERN}|\\s)*){1,10}$`
+);
diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts
index a2cb3a9f..750dd6ca 100644
--- a/src/app/utils/room.ts
+++ b/src/app/utils/room.ts
@@ -76,8 +76,8 @@ export const isSpace = (room: Room | null): boolean => {
export const isRoom = (room: Room | null): boolean => {
if (!room) return false;
const event = getStateEvent(room, StateEvent.RoomCreate);
- if (!event) return false;
- return event.getContent().type === undefined;
+ if (!event) return true;
+ return event.getContent().type !== RoomType.Space;
};
export const isUnsupportedRoom = (room: Room | null): boolean => {
@@ -88,7 +88,10 @@ export const isUnsupportedRoom = (room: Room | null): boolean => {
};
export function isValidChild(mEvent: MatrixEvent): boolean {
- return mEvent.getType() === StateEvent.SpaceChild && Object.keys(mEvent.getContent()).length > 0;
+ return (
+ mEvent.getType() === StateEvent.SpaceChild &&
+ Array.isArray(mEvent.getContent<{ via: string[] }>().via)
+ );
}
export const getAllParents = (roomToParents: RoomToParents, roomId: string): Set => {
@@ -141,6 +144,15 @@ export const getRoomToParents = (mx: MatrixClient): RoomToParents => {
return map;
};
+export const getOrphanParents = (roomToParents: RoomToParents, roomId: string): string[] => {
+ const parents = getAllParents(roomToParents, roomId);
+ const orphanParents = Array.from(parents).filter(
+ (parentRoomId) => !roomToParents.has(parentRoomId)
+ );
+
+ return orphanParents;
+};
+
export const isMutedRule = (rule: IPushRule) =>
rule.actions[0] === 'dont_notify' && rule.conditions?.[0]?.kind === 'event_match';
@@ -167,14 +179,18 @@ export const getNotificationType = (mx: MatrixClient, roomId: string): Notificat
return NotificationType.MentionsAndKeywords;
};
+const NOTIFICATION_EVENT_TYPES = [
+ 'm.room.create',
+ 'm.room.message',
+ 'm.room.encrypted',
+ 'm.room.member',
+ 'm.sticker',
+];
export const isNotificationEvent = (mEvent: MatrixEvent) => {
const eType = mEvent.getType();
- if (
- ['m.room.create', 'm.room.message', 'm.room.encrypted', 'm.room.member', 'm.sticker'].find(
- (type) => type === eType
- )
- )
+ if (!NOTIFICATION_EVENT_TYPES.includes(eType)) {
return false;
+ }
if (eType === 'm.room.member') return false;
if (mEvent.isRedacted()) return false;
@@ -183,6 +199,13 @@ export const isNotificationEvent = (mEvent: MatrixEvent) => {
return true;
};
+export const roomHaveNotification = (room: Room): boolean => {
+ const total = room.getUnreadNotificationCount(NotificationCountType.Total);
+ const highlight = room.getUnreadNotificationCount(NotificationCountType.Highlight);
+
+ return total > 0 || highlight > 0;
+};
+
export const roomHaveUnread = (mx: MatrixClient, room: Room) => {
const userId = mx.getUserId();
if (!userId) return false;
@@ -218,7 +241,7 @@ export const getUnreadInfos = (mx: MatrixClient): UnreadInfo[] => {
if (room.getMyMembership() !== 'join') return unread;
if (getNotificationType(mx, room.roomId) === NotificationType.Mute) return unread;
- if (roomHaveUnread(mx, room)) {
+ if (roomHaveNotification(room) || roomHaveUnread(mx, room)) {
unread.push(getUnreadInfo(room));
}
@@ -247,13 +270,19 @@ export const joinRuleToIconSrc = (
return undefined;
};
-export const getRoomAvatarUrl = (mx: MatrixClient, room: Room): string | undefined => {
- const url =
- room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, 32, 32, 'crop', undefined, false) ??
- undefined;
- if (url) return url;
- return room.getAvatarUrl(mx.baseUrl, 32, 32, 'crop') ?? undefined;
-};
+export const getRoomAvatarUrl = (
+ mx: MatrixClient,
+ room: Room,
+ size: 32 | 96 = 32
+): string | undefined => room.getAvatarUrl(mx.baseUrl, size, size, 'crop') ?? undefined;
+
+export const getDirectRoomAvatarUrl = (
+ mx: MatrixClient,
+ room: Room,
+ size: 32 | 96 = 32
+): string | undefined =>
+ room.getAvatarFallbackMember()?.getAvatarUrl(mx.baseUrl, size, size, 'crop', undefined, false) ??
+ undefined;
export const trimReplyFromBody = (body: string): string => {
const match = body.match(/^> <.+?> .+\n(>.*\n)*?\n/m);
diff --git a/src/app/utils/sort.ts b/src/app/utils/sort.ts
new file mode 100644
index 00000000..512c1998
--- /dev/null
+++ b/src/app/utils/sort.ts
@@ -0,0 +1,59 @@
+import { MatrixClient } from 'matrix-js-sdk';
+
+export type SortFunc = (a: T, b: T) => number;
+
+export const factoryRoomIdByActivity =
+ (mx: MatrixClient): SortFunc =>
+ (a, b) => {
+ const room1 = mx.getRoom(a);
+ const room2 = mx.getRoom(b);
+
+ return (
+ (room2?.getLastActiveTimestamp() ?? Number.MIN_SAFE_INTEGER) -
+ (room1?.getLastActiveTimestamp() ?? Number.MIN_SAFE_INTEGER)
+ );
+ };
+
+export const factoryRoomIdByAtoZ =
+ (mx: MatrixClient): SortFunc =>
+ (a, b) => {
+ let aName = mx.getRoom(a)?.name ?? '';
+ let bName = mx.getRoom(b)?.name ?? '';
+
+ // remove "#" from the room name
+ // To ignore it in sorting
+ aName = aName.replace(/#/g, '');
+ bName = bName.replace(/#/g, '');
+
+ if (aName.toLowerCase() < bName.toLowerCase()) {
+ return -1;
+ }
+ if (aName.toLowerCase() > bName.toLowerCase()) {
+ return 1;
+ }
+ return 0;
+ };
+
+export const factoryRoomIdByUnreadCount =
+ (getUnreadCount: (roomId: string) => number): SortFunc =>
+ (a, b) => {
+ const aT = getUnreadCount(a) ?? 0;
+ const bT = getUnreadCount(b) ?? 0;
+ return bT - aT;
+ };
+
+export const byTsOldToNew: SortFunc = (a, b) => a - b;
+
+export const byOrderKey: SortFunc = (a, b) => {
+ if (!a && !b) {
+ return 0;
+ }
+
+ if (!b) return -1;
+ if (!a) return 1;
+
+ if (a < b) {
+ return -1;
+ }
+ return 1;
+};
diff --git a/src/client/action/navigation.js b/src/client/action/navigation.js
index 4ee78a63..e48e839b 100644
--- a/src/client/action/navigation.js
+++ b/src/client/action/navigation.js
@@ -45,17 +45,19 @@ export function openSpaceManage(roomId) {
});
}
-export function openSpaceAddExisting(roomId) {
+export function openSpaceAddExisting(roomId, spaces = false) {
appDispatcher.dispatch({
type: cons.actions.navigation.OPEN_SPACE_ADDEXISTING,
roomId,
+ spaces,
});
}
-export function toggleRoomSettings(tabText) {
+export function toggleRoomSettings(roomId, tabText) {
appDispatcher.dispatch({
type: cons.actions.navigation.TOGGLE_ROOM_SETTINGS,
- tabText,
+ roomId,
+ tabText
});
}
diff --git a/src/client/event/hotkeys.js b/src/client/event/hotkeys.js
index e59ce3d7..076d3794 100644
--- a/src/client/event/hotkeys.js
+++ b/src/client/event/hotkeys.js
@@ -1,4 +1,4 @@
-import { openSearch, toggleRoomSettings } from '../action/navigation';
+import { openSearch } from '../action/navigation';
import navigation from '../state/navigation';
import { markAsRead } from '../action/notifications';
@@ -53,10 +53,6 @@ function listenKeyboard(event) {
if (navigation.isRawModalVisible) return;
if (event.key === 'Escape') {
- if (navigation.isRoomSettings) {
- toggleRoomSettings();
- return;
- }
if (navigation.selectedRoomId) {
markAsRead(navigation.selectedRoomId);
return;
diff --git a/src/client/initMatrix.js b/src/client/initMatrix.js
index 211cf114..835982f8 100644
--- a/src/client/initMatrix.js
+++ b/src/client/initMatrix.js
@@ -1,7 +1,7 @@
import EventEmitter from 'events';
import * as sdk from 'matrix-js-sdk';
import Olm from '@matrix-org/olm';
-// import { logger } from 'matrix-js-sdk/lib/logger';
+import { logger } from 'matrix-js-sdk/lib/logger';
import { getSecret } from './state/auth';
import RoomList from './state/RoomList';
@@ -13,7 +13,9 @@ import navigation from './state/navigation';
global.Olm = Olm;
-// logger.disableAll();
+if (import.meta.env.PROD) {
+ logger.disableAll();
+}
class InitMatrix extends EventEmitter {
constructor() {
@@ -23,14 +25,20 @@ class InitMatrix extends EventEmitter {
}
async init() {
- if (this.matrixClient) {
+ if (this.matrixClient || this.initializing) {
console.warn('Client is already initialized!')
return;
}
+ this.initializing = true;
- await this.startClient();
- this.setupSync();
- this.listenEvents();
+ try {
+ await this.startClient();
+ this.setupSync();
+ this.listenEvents();
+ this.initializing = false;
+ } catch {
+ this.initializing = false;
+ }
}
async startClient() {
@@ -62,6 +70,7 @@ class InitMatrix extends EventEmitter {
lazyLoadMembers: true,
});
this.matrixClient.setGlobalErrorOnUnknownDevices(false);
+ this.matrixClient.setMaxListeners(50);
}
setupSync() {
diff --git a/src/client/state/navigation.js b/src/client/state/navigation.js
index 07231cd4..ddac4dda 100644
--- a/src/client/state/navigation.js
+++ b/src/client/state/navigation.js
@@ -13,7 +13,6 @@ class Navigation extends EventEmitter {
this.selectedSpacePath = [cons.tabs.HOME];
this.selectedRoomId = null;
- this.isRoomSettings = false;
this.recentRooms = [];
this.spaceToRoom = new Map();
@@ -85,10 +84,6 @@ class Navigation extends EventEmitter {
this.removeRecentRoom(prevSelectedRoomId);
this.addRecentRoom(prevSelectedRoomId);
this.removeRecentRoom(this.selectedRoomId);
- if (this.isRoomSettings && typeof this.selectedRoomId === 'string') {
- this.isRoomSettings = !this.isRoomSettings;
- this.emit(cons.events.navigation.ROOM_SETTINGS_TOGGLED, this.isRoomSettings);
- }
this.emit(
cons.events.navigation.ROOM_SELECTED,
this.selectedRoomId,
@@ -305,14 +300,13 @@ class Navigation extends EventEmitter {
this.emit(cons.events.navigation.SPACE_MANAGE_OPENED, action.roomId);
},
[cons.actions.navigation.OPEN_SPACE_ADDEXISTING]: () => {
- this.emit(cons.events.navigation.SPACE_ADDEXISTING_OPENED, action.roomId);
+ this.emit(cons.events.navigation.SPACE_ADDEXISTING_OPENED, action.roomId, action.spaces);
},
[cons.actions.navigation.TOGGLE_ROOM_SETTINGS]: () => {
- this.isRoomSettings = !this.isRoomSettings;
this.emit(
cons.events.navigation.ROOM_SETTINGS_TOGGLED,
- this.isRoomSettings,
- action.tabText,
+ action.roomId,
+ action.tabText
);
},
[cons.actions.navigation.OPEN_SHORTCUT_SPACES]: () => {
diff --git a/src/index.scss b/src/index.scss
index 9dc5b4c3..5290035b 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -68,7 +68,7 @@
--tc-danger-low: rgba(240, 71, 71, 60%);
--tc-code: #e62498;
- --tc-link: hsl(213deg 76% 56%);
+ --tc-link: hsl(213deg 100% 45%);
--tc-tooltip: white;
--tc-badge: white;
@@ -86,14 +86,14 @@
--ic-danger-normal: rgba(240, 71, 71, 0.7);
/* user mxid colors */
- --mx-uc-1: hsl(208, 66%, 53%);
- --mx-uc-2: hsl(302, 49%, 45%);
- --mx-uc-3: hsl(163, 97%, 36%);
- --mx-uc-4: hsl(343, 75%, 61%);
- --mx-uc-5: hsl(24, 100%, 59%);
- --mx-uc-6: hsl(181, 63%, 47%);
- --mx-uc-7: hsl(242, 89%, 65%);
- --mx-uc-8: hsl(94, 65%, 50%);
+ --mx-uc-1: hsl(208, 100%, 45%);
+ --mx-uc-2: hsl(302, 100%, 30%);
+ --mx-uc-3: hsl(163, 100%, 30%);
+ --mx-uc-4: hsl(343, 100%, 45%);
+ --mx-uc-5: hsl(24, 100%, 45%);
+ --mx-uc-6: hsl(181, 100%, 30%);
+ --mx-uc-7: hsl(242, 100%, 45%);
+ --mx-uc-8: hsl(94, 100%, 35%);
/* system icon size | -ic-[size]: value */
--ic-large: 38px;
@@ -242,7 +242,7 @@
--tc-primary-low: rgba(255, 255, 255, 0.4);
--tc-code: #e565b1;
- --tc-link: hsl(213deg 94% 73%);
+ --tc-link: hsl(213deg 100% 80%);
--tc-badge: black;
/* system icons | --ic-[background type]-[priority]: value */
@@ -251,17 +251,14 @@
--ic-surface-low: rgba(255, 255, 255, 64%);
--ic-primary-normal: #ffffff;
- & .text {
- /* override user mxid colors for texts */
- --mx-uc-1: hsl(208, 100%, 58%);
- --mx-uc-2: hsl(301, 80%, 70%);
- --mx-uc-3: hsl(163, 93%, 41%);
- --mx-uc-4: hsl(343, 91%, 66%);
- --mx-uc-5: hsl(24, 90%, 67%);
- --mx-uc-6: hsl(181, 90%, 50%);
- --mx-uc-7: hsl(243, 100%, 74%);
- --mx-uc-8: hsl(94, 66%, 50%);
- }
+ --mx-uc-1: hsl(208, 100%, 75%);
+ --mx-uc-2: hsl(301, 100%, 80%);
+ --mx-uc-3: hsl(163, 100%, 70%);
+ --mx-uc-4: hsl(343, 100%, 75%);
+ --mx-uc-5: hsl(24, 100%, 70%);
+ --mx-uc-6: hsl(181, 100%, 60%);
+ --mx-uc-7: hsl(243, 100%, 80%);
+ --mx-uc-8: hsl(94, 100%, 80%);
/* shadow and overlay */
--bg-overlay: rgba(0, 0, 0, 60%);
@@ -402,6 +399,7 @@ textarea {
margin: 0;
padding: 0;
background-color: transparent;
+ color: inherit;
font-family: inherit;
font-size: inherit;
font-weight: inherit;
diff --git a/src/types/matrix/room.ts b/src/types/matrix/room.ts
index 33419ce5..c468309d 100644
--- a/src/types/matrix/room.ts
+++ b/src/types/matrix/room.ts
@@ -49,6 +49,12 @@ export enum RoomType {
Space = 'm.space',
}
+export type MSpaceChildContent = {
+ via: string[];
+ suggested?: boolean;
+ order?: string;
+};
+
export enum NotificationType {
Default = 'default',
AllMessages = 'all_messages',
@@ -67,15 +73,15 @@ export type IRoomCreateContent = {
};
};
+export type GetContentCallback = () => T;
+
export type RoomToParents = Map>;
-export type RoomToUnread = Map<
- string,
- {
- total: number;
- highlight: number;
- from: Set | null;
- }
->;
+export type Unread = {
+ total: number;
+ highlight: number;
+ from: Set | null;
+};
+export type RoomToUnread = Map;
export type UnreadInfo = {
roomId: string;
total: number;
diff --git a/vite.config.js b/vite.config.js
index 97f40500..1255f81c 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -45,6 +45,12 @@ export default defineConfig({
server: {
port: 8080,
host: true,
+ proxy: {
+ "^\\/.*?\\/olm\\.wasm$": {
+ target: 'http://localhost:8080',
+ rewrite: () => '/olm.wasm'
+ }
+ }
},
plugins: [
topLevelAwait({
From 6987332ba8142f6b9d25a5017fd7b3c3f0b55af4 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 4 Jun 2024 14:25:07 +1000
Subject: [PATCH 36/73] Bump nginx from 1.26.0-alpine to 1.27.0-alpine (#1759)
Bumps nginx from 1.26.0-alpine to 1.27.0-alpine.
---
updated-dependencies:
- dependency-name: nginx
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index f843fbf1..d6fffeed 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,7 +11,7 @@ RUN npm run build
## App
-FROM nginx:1.26.0-alpine
+FROM nginx:1.27.0-alpine
COPY --from=builder /src/dist /app
From 9db4b3a9c2f05138612172b7c8a1d5536f67b15e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 4 Jun 2024 14:26:21 +1000
Subject: [PATCH 37/73] Bump docker/login-action from 3.1.0 to 3.2.0 (#1758)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3.1.0...v3.2.0)
---
updated-dependencies:
- dependency-name: docker/login-action
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/prod-deploy.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml
index a203ea34..76ccb7e9 100644
--- a/.github/workflows/prod-deploy.yml
+++ b/.github/workflows/prod-deploy.yml
@@ -72,12 +72,12 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.3.0
- name: Login to Docker Hub
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.2.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to the Container registry
- uses: docker/login-action@v3.1.0
+ uses: docker/login-action@v3.2.0
with:
registry: ghcr.io
username: ${{ github.actor }}
From 09a0a2d7daa12d1e68f04042fbdeb2c5aa279f25 Mon Sep 17 00:00:00 2001
From: Kimiblock Moe
Date: Wed, 5 Jun 2024 20:43:19 +0800
Subject: [PATCH 38/73] Prevent Safari iOS from auto zooming (#1756)
Thanks @pixlxip:beeper.com
---
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/index.html b/index.html
index 48f8e69e..af2952d3 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
-
+
Cinny
From b6157707dbb5064f114bb41e6373cdb1c21189e6 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 15 Jun 2024 23:28:03 +1000
Subject: [PATCH 39/73] Bump docker/build-push-action from 5.3.0 to 5.4.0
(#1766)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.3.0 to 5.4.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5.3.0...v5.4.0)
---
updated-dependencies:
- dependency-name: docker/build-push-action
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/docker-pr.yml | 2 +-
.github/workflows/prod-deploy.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml
index de29ff35..aa5d1a2b 100644
--- a/.github/workflows/docker-pr.yml
+++ b/.github/workflows/docker-pr.yml
@@ -13,7 +13,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4.1.6
- name: Build Docker image
- uses: docker/build-push-action@v5.3.0
+ uses: docker/build-push-action@v5.4.0
with:
context: .
push: false
diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml
index 76ccb7e9..5afac942 100644
--- a/.github/workflows/prod-deploy.yml
+++ b/.github/workflows/prod-deploy.yml
@@ -90,7 +90,7 @@ jobs:
${{ secrets.DOCKER_USERNAME }}/cinny
ghcr.io/${{ github.repository }}
- name: Build and push Docker image
- uses: docker/build-push-action@v5.3.0
+ uses: docker/build-push-action@v5.4.0
with:
context: .
platforms: linux/amd64,linux/arm64
From c4615bd2560e247947a977c14b05e59502d0fe55 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 19 Jun 2024 13:55:34 +1000
Subject: [PATCH 40/73] Bump dawidd6/action-download-artifact from 3.1.4 to 6
(#1776)
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 3.1.4 to 6.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](https://github.com/dawidd6/action-download-artifact/compare/09f2f74827fd3a8607589e5ad7f9398816f540fe...bf251b5aa9c2f7eeb574a96ee720e24f801b7c11)
---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/deploy-pull-request.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/deploy-pull-request.yml b/.github/workflows/deploy-pull-request.yml
index 66e648b0..72ffed87 100644
--- a/.github/workflows/deploy-pull-request.yml
+++ b/.github/workflows/deploy-pull-request.yml
@@ -15,7 +15,7 @@ jobs:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Download pr number
- uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe
+ uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11
with:
workflow: ${{ github.event.workflow.id }}
run_id: ${{ github.event.workflow_run.id }}
@@ -24,7 +24,7 @@ jobs:
id: pr
run: echo "id=$(> $GITHUB_OUTPUT
- name: Download artifact
- uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe
+ uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11
with:
workflow: ${{ github.event.workflow.id }}
run_id: ${{ github.event.workflow_run.id }}
From 7a3e8dba924d122b5fbd4c375bf4ba1d039dbb95 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 19 Jun 2024 14:00:11 +1000
Subject: [PATCH 41/73] Bump docker/build-push-action from 5.4.0 to 6.0.0
(#1777)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.4.0 to 6.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5.4.0...v6.0.0)
---
updated-dependencies:
- dependency-name: docker/build-push-action
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/docker-pr.yml | 2 +-
.github/workflows/prod-deploy.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml
index aa5d1a2b..3dda9f7b 100644
--- a/.github/workflows/docker-pr.yml
+++ b/.github/workflows/docker-pr.yml
@@ -13,7 +13,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4.1.6
- name: Build Docker image
- uses: docker/build-push-action@v5.4.0
+ uses: docker/build-push-action@v6.0.0
with:
context: .
push: false
diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml
index 5afac942..61451f79 100644
--- a/.github/workflows/prod-deploy.yml
+++ b/.github/workflows/prod-deploy.yml
@@ -90,7 +90,7 @@ jobs:
${{ secrets.DOCKER_USERNAME }}/cinny
ghcr.io/${{ github.repository }}
- name: Build and push Docker image
- uses: docker/build-push-action@v5.4.0
+ uses: docker/build-push-action@v6.0.0
with:
context: .
platforms: linux/amd64,linux/arm64
From 60e022035f3bbfc09b2b5aee52f83e2aadf054e7 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 19 Jun 2024 14:02:12 +1000
Subject: [PATCH 42/73] Bump actions/checkout from 4.1.6 to 4.1.7 (#1775)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.6 to 4.1.7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4.1.6...v4.1.7)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/build-pull-request.yml | 2 +-
.github/workflows/docker-pr.yml | 2 +-
.github/workflows/lockfile.yml | 2 +-
.github/workflows/netlify-dev.yml | 2 +-
.github/workflows/prod-deploy.yml | 4 ++--
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/build-pull-request.yml b/.github/workflows/build-pull-request.yml
index 133729f7..95a9e8ef 100644
--- a/.github/workflows/build-pull-request.yml
+++ b/.github/workflows/build-pull-request.yml
@@ -12,7 +12,7 @@ jobs:
PR_NUMBER: ${{github.event.number}}
steps:
- name: Checkout repository
- uses: actions/checkout@v4.1.6
+ uses: actions/checkout@v4.1.7
- name: Setup node
uses: actions/setup-node@v4.0.2
with:
diff --git a/.github/workflows/docker-pr.yml b/.github/workflows/docker-pr.yml
index 3dda9f7b..a45917ba 100644
--- a/.github/workflows/docker-pr.yml
+++ b/.github/workflows/docker-pr.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v4.1.6
+ uses: actions/checkout@v4.1.7
- name: Build Docker image
uses: docker/build-push-action@v6.0.0
with:
diff --git a/.github/workflows/lockfile.yml b/.github/workflows/lockfile.yml
index af91698e..410d2f59 100644
--- a/.github/workflows/lockfile.yml
+++ b/.github/workflows/lockfile.yml
@@ -14,7 +14,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout
- uses: actions/checkout@v4.1.6
+ uses: actions/checkout@v4.1.7
- name: NPM Lockfile Changes
uses: codepunkt/npm-lockfile-changes@b40543471c36394409466fdb277a73a0856d7891
with:
diff --git a/.github/workflows/netlify-dev.yml b/.github/workflows/netlify-dev.yml
index 9252e3e4..5a0ecbca 100644
--- a/.github/workflows/netlify-dev.yml
+++ b/.github/workflows/netlify-dev.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v4.1.6
+ uses: actions/checkout@v4.1.7
- name: Setup node
uses: actions/setup-node@v4.0.2
with:
diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml
index 61451f79..227b96c7 100644
--- a/.github/workflows/prod-deploy.yml
+++ b/.github/workflows/prod-deploy.yml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v4.1.6
+ uses: actions/checkout@v4.1.7
- name: Setup node
uses: actions/setup-node@v4.0.2
with:
@@ -66,7 +66,7 @@ jobs:
packages: write
steps:
- name: Checkout repository
- uses: actions/checkout@v4.1.6
+ uses: actions/checkout@v4.1.7
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.0.0
- name: Set up Docker Buildx
From 4f09e6bbb5a633715937a3b89307dd685229606c Mon Sep 17 00:00:00 2001
From: Ajay Bura <32841439+ajbura@users.noreply.github.com>
Date: Mon, 8 Jul 2024 16:57:10 +0530
Subject: [PATCH 43/73] (chore) remove outdated code (#1765)
* optimize room typing members hook
* remove unused code - WIP
* remove old code from initMatrix
* remove twemojify function
* remove old sanitize util
* delete old markdown util
* delete Math atom component
* uninstall unused dependencies
* remove old notification system
* decrypt message in inbox notification center and fix refresh in background
* improve notification
---------
Co-authored-by: Krishan <33421343+kfiven@users.noreply.github.com>
---
index.html | 6 -
package-lock.json | 188 +---
package.json | 6 -
src/app/atoms/avatar/Avatar.jsx | 62 +-
src/app/atoms/math/Math.jsx | 33 -
src/app/atoms/math/Math.scss | 3 -
src/app/features/room/RoomInput.tsx | 10 +-
src/app/features/room/RoomTimeline.tsx | 30 +-
src/app/hooks/useCategorizedSpaces.js | 25 -
src/app/hooks/useCommands.ts | 4 +-
src/app/hooks/usePreviousValue.ts | 11 +
src/app/hooks/useRoomTypingMembers.ts | 24 +-
src/app/hooks/useSelectedSpace.js | 21 -
src/app/hooks/useSelectedTab.js | 21 -
src/app/hooks/useSpaceShortcut.js | 25 -
src/app/molecules/dialog/Dialog.jsx | 29 +-
.../following-members/FollowingMembers.jsx | 61 --
.../following-members/FollowingMembers.scss | 31 -
.../image-lightbox/ImageLightbox.jsx | 47 -
.../image-lightbox/ImageLightbox.scss | 50 -
src/app/molecules/media/Media.jsx | 366 --------
src/app/molecules/media/Media.scss | 90 --
src/app/molecules/message/Message.jsx | 853 ------------------
src/app/molecules/message/Message.scss | 479 ----------
src/app/molecules/message/TimelineChange.jsx | 78 --
src/app/molecules/message/TimelineChange.scss | 37 -
.../people-selector/PeopleSelector.jsx | 16 +-
.../molecules/popup-window/PopupWindow.jsx | 66 +-
.../room-notification/RoomNotification.jsx | 146 +--
.../molecules/room-options/RoomOptions.jsx | 73 --
.../molecules/room-profile/RoomProfile.jsx | 93 +-
src/app/molecules/room-search/RoomSearch.jsx | 201 -----
src/app/molecules/room-search/RoomSearch.scss | 62 --
.../molecules/room-selector/RoomSelector.jsx | 41 +-
src/app/molecules/room-tile/RoomTile.jsx | 48 +-
.../sidebar-avatar/SidebarAvatar.jsx | 55 --
.../sidebar-avatar/SidebarAvatar.scss | 64 --
.../space-add-existing/SpaceAddExisting.jsx | 15 +-
.../molecules/space-options/SpaceOptions.jsx | 128 ---
src/app/molecules/sso-buttons/SSOButtons.jsx | 41 -
src/app/molecules/sso-buttons/SSOButtons.scss | 25 -
src/app/organisms/create-room/CreateRoom.jsx | 154 ++--
src/app/organisms/emoji-board/EmojiBoard.jsx | 356 --------
src/app/organisms/emoji-board/EmojiBoard.scss | 137 ---
.../emoji-board/EmojiBoardOpener.jsx | 78 --
src/app/organisms/emoji-board/custom-emoji.js | 127 +--
src/app/organisms/emoji-board/emoji.js | 69 --
src/app/organisms/emoji-board/recent.js | 36 -
.../emoji-verification/EmojiVerification.jsx | 48 +-
src/app/organisms/invite-list/InviteList.jsx | 145 ---
src/app/organisms/invite-list/InviteList.scss | 26 -
src/app/organisms/invite-user/InviteUser.jsx | 128 +--
src/app/organisms/join-alias/JoinAlias.jsx | 69 +-
src/app/organisms/navigation/Directs.jsx | 71 --
src/app/organisms/navigation/Drawer.jsx | 93 --
src/app/organisms/navigation/Drawer.scss | 56 --
.../organisms/navigation/DrawerBreadcrumb.jsx | 142 ---
.../navigation/DrawerBreadcrumb.scss | 66 --
src/app/organisms/navigation/DrawerHeader.jsx | 159 ----
.../organisms/navigation/DrawerHeader.scss | 28 -
src/app/organisms/navigation/Home.jsx | 112 ---
src/app/organisms/navigation/Navigation.jsx | 16 -
src/app/organisms/navigation/Navigation.scss | 7 -
.../organisms/navigation/RoomsCategory.jsx | 92 --
.../organisms/navigation/RoomsCategory.scss | 54 --
src/app/organisms/navigation/Selector.jsx | 93 --
src/app/organisms/navigation/SideBar.jsx | 390 --------
src/app/organisms/navigation/SideBar.scss | 75 --
.../profile-editor/ProfileEditor.jsx | 24 +-
.../profile-viewer/ProfileViewer.jsx | 165 ++--
.../organisms/public-rooms/PublicRooms.jsx | 295 ------
.../organisms/public-rooms/PublicRooms.scss | 85 --
src/app/organisms/pw/Dialogs.jsx | 6 -
src/app/organisms/pw/Windows.jsx | 28 -
.../organisms/read-receipts/ReadReceipts.jsx | 76 --
src/app/organisms/room/EventLimit.js | 35 -
src/app/organisms/room/PeopleDrawer.jsx | 215 -----
src/app/organisms/room/PeopleDrawer.scss | 93 --
src/app/organisms/room/Room.scss | 20 -
src/app/organisms/room/RoomSettings.jsx | 3 +-
src/app/organisms/room/RoomView.scss | 46 -
src/app/organisms/room/RoomViewCmdBar.jsx | 297 ------
src/app/organisms/room/RoomViewCmdBar.scss | 57 --
src/app/organisms/room/RoomViewContent.jsx | 644 -------------
src/app/organisms/room/RoomViewContent.scss | 30 -
src/app/organisms/room/RoomViewFloating.jsx | 125 ---
src/app/organisms/room/RoomViewFloating.scss | 125 ---
src/app/organisms/room/RoomViewHeader.jsx | 132 ---
src/app/organisms/room/RoomViewHeader.scss | 47 -
src/app/organisms/room/RoomViewInput.jsx | 491 ----------
src/app/organisms/room/RoomViewInput.scss | 108 ---
src/app/organisms/room/TimelineScroll.js | 136 ---
src/app/organisms/room/commands.jsx | 220 -----
src/app/organisms/room/commands.scss | 10 -
src/app/organisms/room/common.jsx | 222 -----
src/app/organisms/search/Search.jsx | 31 +-
src/app/organisms/settings/CrossSigning.jsx | 109 ++-
src/app/organisms/settings/KeyBackup.jsx | 93 +-
.../shortcut-spaces/ShortcutSpaces.jsx | 169 ----
.../shortcut-spaces/ShortcutSpaces.scss | 52 --
.../organisms/space-manage/SpaceManage.jsx | 433 ---------
.../organisms/space-manage/SpaceManage.scss | 168 ----
.../space-settings/SpaceSettings.jsx | 9 +-
.../organisms/sticker-board/StickerBoard.jsx | 115 ---
.../organisms/sticker-board/StickerBoard.scss | 74 --
src/app/organisms/view-source/ViewSource.jsx | 73 --
src/app/organisms/view-source/ViewSource.scss | 19 -
src/app/organisms/welcome/Welcome.jsx | 20 -
src/app/organisms/welcome/Welcome.scss | 23 -
src/app/pages/Router.tsx | 21 +-
src/app/pages/client/ClientNonUIFeatures.tsx | 231 +++++
src/app/pages/client/ClientRoot.tsx | 2 -
src/app/pages/client/inbox/Notifications.tsx | 88 +-
src/app/state/room/roomToUnread.ts | 2 +-
src/app/state/typingMembers.ts | 6 -
src/app/templates/auth/Auth.jsx | 684 --------------
src/app/templates/auth/Auth.scss | 173 ----
src/app/templates/client/Client.jsx | 68 --
src/app/templates/client/Client.scss | 57 --
src/app/templates/client/ClientContent.jsx | 49 -
src/app/utils/disposable.ts | 20 +-
src/app/utils/dom.ts | 6 +
src/client/action/accountData.js | 41 -
src/client/action/auth.js | 104 ---
src/client/action/auth.ts | 13 +
src/client/action/navigation.js | 87 --
src/client/action/notifications.js | 1 -
src/client/action/room.js | 32 +-
src/client/action/roomTimeline.js | 34 -
src/client/event/hotkeys.js | 59 --
src/client/event/roomList.js | 38 -
src/client/initMatrix.js | 19 -
src/client/state/AccountData.js | 144 ---
src/client/state/Notifications.js | 412 ---------
src/client/state/RoomList.js | 383 --------
src/client/state/RoomTimeline.js | 407 ---------
src/client/state/RoomsHierarchy.js | 49 -
src/client/state/RoomsInput.js | 423 ---------
src/client/state/cons.js | 71 --
src/client/state/navigation.js | 318 -------
src/util/Postie.js | 97 --
src/util/colorMXID.js | 2 +-
src/util/markdown.js | 515 -----------
src/util/matrixUtil.js | 14 -
src/util/mimetypes.js | 39 -
src/util/sanitize.js | 140 ---
src/util/twemojify.jsx | 31 -
147 files changed, 1164 insertions(+), 15330 deletions(-)
delete mode 100644 src/app/atoms/math/Math.jsx
delete mode 100644 src/app/atoms/math/Math.scss
delete mode 100644 src/app/hooks/useCategorizedSpaces.js
create mode 100644 src/app/hooks/usePreviousValue.ts
delete mode 100644 src/app/hooks/useSelectedSpace.js
delete mode 100644 src/app/hooks/useSelectedTab.js
delete mode 100644 src/app/hooks/useSpaceShortcut.js
delete mode 100644 src/app/molecules/following-members/FollowingMembers.jsx
delete mode 100644 src/app/molecules/following-members/FollowingMembers.scss
delete mode 100644 src/app/molecules/image-lightbox/ImageLightbox.jsx
delete mode 100644 src/app/molecules/image-lightbox/ImageLightbox.scss
delete mode 100644 src/app/molecules/media/Media.jsx
delete mode 100644 src/app/molecules/media/Media.scss
delete mode 100644 src/app/molecules/message/Message.jsx
delete mode 100644 src/app/molecules/message/Message.scss
delete mode 100644 src/app/molecules/message/TimelineChange.jsx
delete mode 100644 src/app/molecules/message/TimelineChange.scss
delete mode 100644 src/app/molecules/room-options/RoomOptions.jsx
delete mode 100644 src/app/molecules/room-search/RoomSearch.jsx
delete mode 100644 src/app/molecules/room-search/RoomSearch.scss
delete mode 100644 src/app/molecules/sidebar-avatar/SidebarAvatar.jsx
delete mode 100644 src/app/molecules/sidebar-avatar/SidebarAvatar.scss
delete mode 100644 src/app/molecules/space-options/SpaceOptions.jsx
delete mode 100644 src/app/molecules/sso-buttons/SSOButtons.jsx
delete mode 100644 src/app/molecules/sso-buttons/SSOButtons.scss
delete mode 100644 src/app/organisms/emoji-board/EmojiBoard.jsx
delete mode 100644 src/app/organisms/emoji-board/EmojiBoard.scss
delete mode 100644 src/app/organisms/emoji-board/EmojiBoardOpener.jsx
delete mode 100644 src/app/organisms/emoji-board/emoji.js
delete mode 100644 src/app/organisms/emoji-board/recent.js
delete mode 100644 src/app/organisms/invite-list/InviteList.jsx
delete mode 100644 src/app/organisms/invite-list/InviteList.scss
delete mode 100644 src/app/organisms/navigation/Directs.jsx
delete mode 100644 src/app/organisms/navigation/Drawer.jsx
delete mode 100644 src/app/organisms/navigation/Drawer.scss
delete mode 100644 src/app/organisms/navigation/DrawerBreadcrumb.jsx
delete mode 100644 src/app/organisms/navigation/DrawerBreadcrumb.scss
delete mode 100644 src/app/organisms/navigation/DrawerHeader.jsx
delete mode 100644 src/app/organisms/navigation/DrawerHeader.scss
delete mode 100644 src/app/organisms/navigation/Home.jsx
delete mode 100644 src/app/organisms/navigation/Navigation.jsx
delete mode 100644 src/app/organisms/navigation/Navigation.scss
delete mode 100644 src/app/organisms/navigation/RoomsCategory.jsx
delete mode 100644 src/app/organisms/navigation/RoomsCategory.scss
delete mode 100644 src/app/organisms/navigation/Selector.jsx
delete mode 100644 src/app/organisms/navigation/SideBar.jsx
delete mode 100644 src/app/organisms/navigation/SideBar.scss
delete mode 100644 src/app/organisms/public-rooms/PublicRooms.jsx
delete mode 100644 src/app/organisms/public-rooms/PublicRooms.scss
delete mode 100644 src/app/organisms/read-receipts/ReadReceipts.jsx
delete mode 100644 src/app/organisms/room/EventLimit.js
delete mode 100644 src/app/organisms/room/PeopleDrawer.jsx
delete mode 100644 src/app/organisms/room/PeopleDrawer.scss
delete mode 100644 src/app/organisms/room/Room.scss
delete mode 100644 src/app/organisms/room/RoomView.scss
delete mode 100644 src/app/organisms/room/RoomViewCmdBar.jsx
delete mode 100644 src/app/organisms/room/RoomViewCmdBar.scss
delete mode 100644 src/app/organisms/room/RoomViewContent.jsx
delete mode 100644 src/app/organisms/room/RoomViewContent.scss
delete mode 100644 src/app/organisms/room/RoomViewFloating.jsx
delete mode 100644 src/app/organisms/room/RoomViewFloating.scss
delete mode 100644 src/app/organisms/room/RoomViewHeader.jsx
delete mode 100644 src/app/organisms/room/RoomViewHeader.scss
delete mode 100644 src/app/organisms/room/RoomViewInput.jsx
delete mode 100644 src/app/organisms/room/RoomViewInput.scss
delete mode 100644 src/app/organisms/room/TimelineScroll.js
delete mode 100644 src/app/organisms/room/commands.jsx
delete mode 100644 src/app/organisms/room/commands.scss
delete mode 100644 src/app/organisms/room/common.jsx
delete mode 100644 src/app/organisms/shortcut-spaces/ShortcutSpaces.jsx
delete mode 100644 src/app/organisms/shortcut-spaces/ShortcutSpaces.scss
delete mode 100644 src/app/organisms/space-manage/SpaceManage.jsx
delete mode 100644 src/app/organisms/space-manage/SpaceManage.scss
delete mode 100644 src/app/organisms/sticker-board/StickerBoard.jsx
delete mode 100644 src/app/organisms/sticker-board/StickerBoard.scss
delete mode 100644 src/app/organisms/view-source/ViewSource.jsx
delete mode 100644 src/app/organisms/view-source/ViewSource.scss
delete mode 100644 src/app/organisms/welcome/Welcome.jsx
delete mode 100644 src/app/organisms/welcome/Welcome.scss
create mode 100644 src/app/pages/client/ClientNonUIFeatures.tsx
delete mode 100644 src/app/templates/auth/Auth.jsx
delete mode 100644 src/app/templates/auth/Auth.scss
delete mode 100644 src/app/templates/client/Client.jsx
delete mode 100644 src/app/templates/client/Client.scss
delete mode 100644 src/app/templates/client/ClientContent.jsx
delete mode 100644 src/client/action/accountData.js
delete mode 100644 src/client/action/auth.js
create mode 100644 src/client/action/auth.ts
delete mode 100644 src/client/action/roomTimeline.js
delete mode 100644 src/client/event/roomList.js
delete mode 100644 src/client/state/AccountData.js
delete mode 100644 src/client/state/Notifications.js
delete mode 100644 src/client/state/RoomList.js
delete mode 100644 src/client/state/RoomTimeline.js
delete mode 100644 src/client/state/RoomsHierarchy.js
delete mode 100644 src/client/state/RoomsInput.js
delete mode 100644 src/util/Postie.js
delete mode 100644 src/util/markdown.js
delete mode 100644 src/util/mimetypes.js
delete mode 100644 src/util/sanitize.js
delete mode 100644 src/util/twemojify.jsx
diff --git a/index.html b/index.html
index af2952d3..9196cf3d 100644
--- a/index.html
+++ b/index.html
@@ -90,12 +90,6 @@
window.global ||= window;
-
-