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() {