diff --git a/src/app/molecules/image-pack/ImagePack.jsx b/src/app/molecules/image-pack/ImagePack.jsx
index d66895ff..725291d1 100644
--- a/src/app/molecules/image-pack/ImagePack.jsx
+++ b/src/app/molecules/image-pack/ImagePack.jsx
@@ -1,5 +1,5 @@
import React, {
- useState, useMemo, useReducer,
+ useState, useMemo, useReducer, useEffect,
} from 'react';
import PropTypes from 'prop-types';
import './ImagePack.scss';
@@ -12,6 +12,7 @@ import Button from '../../atoms/button/Button';
import Text from '../../atoms/text/Text';
import Input from '../../atoms/input/Input';
import Checkbox from '../../atoms/button/Checkbox';
+import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
import { ImagePack as ImagePackBuilder } from '../../organisms/emoji-board/custom-emoji';
import { confirmDialog } from '../confirm-dialog/ConfirmDialog';
@@ -394,6 +395,75 @@ function ImagePackUser() {
);
}
+function useGlobalImagePack() {
+ const [, forceUpdate] = useReducer((count) => count + 1, 0);
+ const mx = initMatrix.matrixClient;
+
+ const roomIdToStateKeys = new Map();
+ const globalContent = mx.getAccountData('im.ponies.emote_rooms')?.getContent() ?? { rooms: {} };
+ const { rooms } = globalContent;
+
+ Object.keys(rooms).forEach((roomId) => {
+ if (typeof rooms[roomId] !== 'object') return;
+ const room = mx.getRoom(roomId);
+ const stateKeys = Object.keys(rooms[roomId]);
+ if (!room || stateKeys.length === 0) return;
+ roomIdToStateKeys.set(roomId, stateKeys);
+ });
+
+ useEffect(() => {
+ const handleEvent = (event) => {
+ if (event.getType() === 'im.ponies.emote_rooms') forceUpdate();
+ };
+ mx.addListener('accountData', handleEvent);
+ return () => {
+ mx.removeListener('accountData', handleEvent);
+ };
+ }, []);
+
+ return roomIdToStateKeys;
+}
+
+function ImagePackGlobal() {
+ const mx = initMatrix.matrixClient;
+ const roomIdToStateKeys = useGlobalImagePack();
+
+ const handleChange = (roomId, stateKey) => {
+ removeGlobalImagePack(mx, roomId, stateKey);
+ };
+
+ return (
+
+
Global packs
+
+ {
+ roomIdToStateKeys.size > 0
+ ? [...roomIdToStateKeys].map(([roomId, stateKeys]) => {
+ const room = mx.getRoom(roomId);
+ return (
+ stateKeys.map((stateKey) => {
+ const data = room.currentState.getStateEvents('im.ponies.room_emotes', stateKey);
+ const pack = ImagePackBuilder.parsePack(data?.getId(), data?.getContent());
+ if (!pack) return null;
+ return (
+
+
handleChange(roomId, stateKey)} isActive />
+
+ {pack.displayName ?? 'Unknown'}
+ {room.name}
+
+
+ );
+ })
+ );
+ })
+ :
No global packs
+ }
+
+
+ );
+}
+
export default ImagePack;
-export { ImagePackUser };
+export { ImagePackUser, ImagePackGlobal };
diff --git a/src/app/molecules/image-pack/ImagePack.scss b/src/app/molecules/image-pack/ImagePack.scss
index bd3538a0..91d6a185 100644
--- a/src/app/molecules/image-pack/ImagePack.scss
+++ b/src/app/molecules/image-pack/ImagePack.scss
@@ -31,3 +31,17 @@
gap: var(--sp-normal);
}
}
+
+.image-pack-global {
+ &__empty {
+ text-align: center;
+ padding: var(--sp-extra-loose) var(--sp-normal);
+ }
+ & .image-pack__global {
+ padding: 0 var(--sp-normal);
+ padding-bottom: var(--sp-normal);
+ &:first-child {
+ padding-top: var(--sp-normal);
+ }
+ }
+}
diff --git a/src/app/organisms/emoji-board/custom-emoji.js b/src/app/organisms/emoji-board/custom-emoji.js
index 996d8532..928c86c1 100644
--- a/src/app/organisms/emoji-board/custom-emoji.js
+++ b/src/app/organisms/emoji-board/custom-emoji.js
@@ -153,6 +153,7 @@ function getGlobalImagePacks(mx) {
const packs = roomIds.flatMap((roomId) => {
if (typeof rooms[roomId] !== 'object') return [];
const room = mx.getRoom(roomId);
+ if (!room) return [];
const stateKeys = Object.keys(rooms[roomId]);
return stateKeys.map((stateKey) => {
diff --git a/src/app/organisms/settings/Settings.jsx b/src/app/organisms/settings/Settings.jsx
index 618a4e72..b50c9926 100644
--- a/src/app/organisms/settings/Settings.jsx
+++ b/src/app/organisms/settings/Settings.jsx
@@ -24,7 +24,7 @@ import PopupWindow from '../../molecules/popup-window/PopupWindow';
import SettingTile from '../../molecules/setting-tile/SettingTile';
import ImportE2ERoomKeys from '../../molecules/import-export-e2e-room-keys/ImportE2ERoomKeys';
import ExportE2ERoomKeys from '../../molecules/import-export-e2e-room-keys/ExportE2ERoomKeys';
-import { ImagePackUser } from '../../molecules/image-pack/ImagePack';
+import { ImagePackUser, ImagePackGlobal } from '../../molecules/image-pack/ImagePack';
import ProfileEditor from '../profile-editor/ProfileEditor';
import CrossSigning from './CrossSigning';
@@ -172,7 +172,12 @@ function NotificationsSection() {
}
function EmojiSection() {
- return
;
+ return (
+ <>
+
+
+ >
+ );
}
function SecuritySection() {