mirror of
https://github.com/officialdakari/Extera.git
synced 2025-04-11 23:08:46 +02:00
use authenticated media everywhere (almost)
This commit is contained in:
parent
2e5507cf94
commit
659b7d5e12
39 changed files with 342 additions and 359 deletions
21
package-lock.json
generated
21
package-lock.json
generated
|
@ -37,6 +37,7 @@
|
|||
"domhandler": "5.0.3",
|
||||
"emojibase": "6.1.0",
|
||||
"emojibase-data": "7.0.1",
|
||||
"eruda": "3.4.1",
|
||||
"file-saver": "2.0.5",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
|
@ -46,7 +47,6 @@
|
|||
"html-dom-parser": "4.0.0",
|
||||
"html-react-parser": "4.2.0",
|
||||
"immer": "9.0.16",
|
||||
"is-hotkey": "0.2.0",
|
||||
"jotai": "2.6.0",
|
||||
"leaflet": "1.9.4",
|
||||
"linkify-react": "4.1.3",
|
||||
|
@ -87,6 +87,7 @@
|
|||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-wasm": "6.1.1",
|
||||
"@types/file-saver": "2.0.5",
|
||||
"@types/is-hotkey": "0.1.10",
|
||||
"@types/leaflet": "1.9.12",
|
||||
"@types/md5": "2.3.5",
|
||||
"@types/node": "18.11.18",
|
||||
|
@ -111,6 +112,7 @@
|
|||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.11",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"is-hotkey": "0.2.0",
|
||||
"prettier": "2.8.1",
|
||||
"sass": "1.56.2",
|
||||
"typescript": "4.9.4",
|
||||
|
@ -5580,6 +5582,13 @@
|
|||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/is-hotkey": {
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/is-hotkey/-/is-hotkey-0.1.10.tgz",
|
||||
"integrity": "sha512-RvC8KMw5BCac1NvRRyaHgMMEtBaZ6wh0pyPTBu7izn4Sj/AX9Y4aXU5c7rX8PnM/knsuUpC1IeoBkANtxBypsQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
|
||||
|
@ -7394,6 +7403,12 @@
|
|||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/eruda": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/eruda/-/eruda-3.4.1.tgz",
|
||||
"integrity": "sha512-RmaO5yD97URY/9Q0lye3cmmNPoXNKreeePIw7c/zllbscR92CjGFZFuQ70+0fLIvLcKW3Xha8DS8NFhmeNbEBQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
|
||||
|
@ -9165,7 +9180,9 @@
|
|||
"node_modules/is-hotkey": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.2.0.tgz",
|
||||
"integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw=="
|
||||
"integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
"domhandler": "5.0.3",
|
||||
"emojibase": "6.1.0",
|
||||
"emojibase-data": "7.0.1",
|
||||
"eruda": "3.4.1",
|
||||
"file-saver": "2.0.5",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
|
@ -57,7 +58,6 @@
|
|||
"html-dom-parser": "4.0.0",
|
||||
"html-react-parser": "4.2.0",
|
||||
"immer": "9.0.16",
|
||||
"is-hotkey": "0.2.0",
|
||||
"jotai": "2.6.0",
|
||||
"leaflet": "1.9.4",
|
||||
"linkify-react": "4.1.3",
|
||||
|
@ -98,6 +98,7 @@
|
|||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-wasm": "6.1.1",
|
||||
"@types/file-saver": "2.0.5",
|
||||
"@types/is-hotkey": "0.1.10",
|
||||
"@types/leaflet": "1.9.12",
|
||||
"@types/md5": "2.3.5",
|
||||
"@types/node": "18.11.18",
|
||||
|
@ -122,6 +123,7 @@
|
|||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.11",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"is-hotkey": "0.2.0",
|
||||
"prettier": "2.8.1",
|
||||
"sass": "1.56.2",
|
||||
"typescript": "4.9.4",
|
||||
|
|
|
@ -17,6 +17,7 @@ import { IEmoji, emojis } from '../../../plugins/emoji';
|
|||
import { ExtendedPackImage, PackUsage } from '../../../plugins/custom-emoji';
|
||||
import { useKeyDown } from '../../../hooks/useKeyDown';
|
||||
import { ListItemButton, ListItemIcon, ListItemText, Typography } from '@mui/material';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
type EmoticonCompleteHandler = (key: string, shortcode: string) => void;
|
||||
|
||||
|
@ -76,7 +77,7 @@ export function EmoticonAutocomplete({
|
|||
const ta = textAreaRef.current;
|
||||
if (!ta) return;
|
||||
const mxc = key.startsWith('mxc://');
|
||||
const src = mxc ? mx.mxcUrlToHttp(key) : key;
|
||||
const src = mxc ? mxcUrlToHttp(mx, key) : key;
|
||||
console.log(src, key, shortcode);
|
||||
|
||||
var v = ta.value;
|
||||
|
@ -127,7 +128,7 @@ export function EmoticonAutocomplete({
|
|||
<Box
|
||||
shrink="No"
|
||||
as="img"
|
||||
src={mx.mxcUrlToHttp(key) || key}
|
||||
src={mxcUrlToHttp(mx, key) || key}
|
||||
alt={emoticon.shortcode}
|
||||
style={{ width: toRem(24), height: toRem(24), objectFit: 'contain' }}
|
||||
/>
|
||||
|
|
|
@ -33,7 +33,7 @@ import { useRelevantImagePacks } from '../../hooks/useImagePacks';
|
|||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useRecentEmoji } from '../../hooks/useRecentEmoji';
|
||||
import { ExtendedPackImage, ImagePack, PackUsage } from '../../plugins/custom-emoji';
|
||||
import { isUserId } from '../../utils/matrix';
|
||||
import { isUserId, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { editableActiveElement, isIntersectingScrollView, targetFromEvent } from '../../utils/dom';
|
||||
import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearch';
|
||||
import { useDebounce } from '../../hooks/useDebounce';
|
||||
|
@ -41,11 +41,8 @@ import { useThrottle } from '../../hooks/useThrottle';
|
|||
import { addRecentEmoji } from '../../plugins/recent-emoji';
|
||||
import { mobileOrTablet } from '../../utils/user-agent';
|
||||
import { getText } from '../../../lang';
|
||||
import { useSetting } from '../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
import { openJoinAlias } from '../../../client/action/navigation';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiArrowRight, mdiHistory, mdiMagnify, mdiSticker, mdiStickerOutline } from '@mdi/js';
|
||||
import { mdiHistory, mdiStickerOutline } from '@mdi/js';
|
||||
import { Divider, IconButton, Tab, Tabs, Theme, Tooltip, useTheme } from '@mui/material';
|
||||
import { SearchContainer, SearchIcon, SearchIconWrapper, SearchInputBase } from '../../atoms/search/Search';
|
||||
import { MotionBox } from '../../atoms/motion/Animated';
|
||||
|
@ -367,7 +364,7 @@ function ImagePackSidebarStack({
|
|||
height: toRem(24),
|
||||
objectFit: 'contain',
|
||||
}}
|
||||
src={mx.mxcUrlToHttp(pack.getPackAvatarUrl(usage) ?? '') || pack.avatarUrl}
|
||||
src={mxcUrlToHttp(mx, pack.getPackAvatarUrl(usage) ?? '') || pack.avatarUrl}
|
||||
alt={label || getText('emojiboard.unknown_pack')}
|
||||
/>
|
||||
</SidebarBtn>
|
||||
|
|
|
@ -5,7 +5,7 @@ import { MatrixClient, MatrixEvent, Room } from 'matrix-js-sdk';
|
|||
import * as css from './Reaction.css';
|
||||
import { getHexcodeForEmoji, getShortcodeFor } from '../../plugins/emoji';
|
||||
import { getMemberDisplayName } from '../../utils/room';
|
||||
import { eventWithShortcode, getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { eventWithShortcode, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { getText } from '../../../lang';
|
||||
import { Typography, useTheme } from '@mui/material';
|
||||
|
||||
|
@ -32,7 +32,7 @@ export const Reaction = as<
|
|||
{reaction.startsWith('mxc://') ? (
|
||||
<img
|
||||
className={css.ReactionImg}
|
||||
src={mx.mxcUrlToHttp(reaction) ?? reaction}
|
||||
src={mxcUrlToHttp(mx, reaction) ?? reaction}
|
||||
alt={reaction}
|
||||
/>
|
||||
) : (
|
||||
|
|
|
@ -21,6 +21,7 @@ import Icon from '@mdi/react';
|
|||
import { mdiPause, mdiPlayOutline, mdiVolumeHigh, mdiVolumeMute } from '@mdi/js';
|
||||
import { CircularProgress, IconButton, Slider } from '@mui/material';
|
||||
import { AccessTime, Pause, PlayArrow } from '@mui/icons-material';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
const PLAY_TIME_THROTTLE_OPS = {
|
||||
wait: 500,
|
||||
|
@ -51,7 +52,7 @@ export function AudioContent({
|
|||
|
||||
const [srcState, loadSrc] = useAsyncCallback(
|
||||
useCallback(
|
||||
() => getFileSrcUrl(mx.mxcUrlToHttp(url, undefined, undefined, undefined, false, true, true) ?? '', mimeType, encInfo, mx, !('cordova' in window)),
|
||||
() => getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType, encInfo, mx, !('cordova' in window)),
|
||||
[mx, url, mimeType, encInfo]
|
||||
)
|
||||
);
|
||||
|
|
|
@ -24,6 +24,7 @@ import { LoadingButton } from '@mui/lab';
|
|||
import { BackButtonHandler } from '../../../hooks/useBackButton';
|
||||
import { useModals } from '../../../hooks/useModals';
|
||||
import { v4 } from 'uuid';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
const renderErrorButton = (retry: () => void, text: string) => (
|
||||
<Tooltip title={getText('msg.file.failed')}>
|
||||
|
@ -58,7 +59,7 @@ export function ReadTextFile({ body, mimeType, url, encInfo, renderViewer, forma
|
|||
const [textViewer, setTextViewer] = useState(false);
|
||||
|
||||
const loadSrc = useCallback(
|
||||
() => getFileSrcUrl(mx.mxcUrlToHttp(url, undefined, undefined, undefined, false, true, true) ?? '', mimeType, encInfo),
|
||||
() => getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType, encInfo),
|
||||
[mx, url, mimeType, encInfo]
|
||||
);
|
||||
|
||||
|
@ -132,7 +133,7 @@ export function ReadPdfFile({ body, mimeType, url, encInfo, renderViewer, format
|
|||
|
||||
const [pdfState, loadPdf] = useAsyncCallback(
|
||||
useCallback(async () => {
|
||||
const httpUrl = await getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo);
|
||||
const httpUrl = await getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType, encInfo);
|
||||
setPdfViewer(true);
|
||||
return httpUrl;
|
||||
}, [mx, url, mimeType, encInfo])
|
||||
|
@ -192,7 +193,7 @@ export function DownloadFile({ body, mimeType, url, info, encInfo, filename }: D
|
|||
|
||||
const [downloadState, download] = useAsyncCallback(
|
||||
useCallback(async () => {
|
||||
const httpUrl = await getFileSrcUrl(mx.mxcUrlToHttp(url, undefined, undefined, undefined, false, true, true) ?? '', mimeType, encInfo, mx);
|
||||
const httpUrl = await getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType, encInfo, mx);
|
||||
saveFile(httpUrl, filename ?? body);
|
||||
return httpUrl;
|
||||
}, [mx, url, mimeType, encInfo, body, filename])
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
} from 'folds';
|
||||
import classNames from 'classnames';
|
||||
import { BlurhashCanvas } from 'react-blurhash';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
|
||||
import { IImageInfo, MATRIX_BLUR_HASH_PROPERTY_NAME } from '../../../../types/matrix/common';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||
|
@ -14,13 +13,11 @@ import { getFileSrcUrl } from './util';
|
|||
import * as css from './style.css';
|
||||
import { bytesToSize } from '../../../utils/common';
|
||||
import { FALLBACK_MIMETYPE } from '../../../utils/mimeTypes';
|
||||
import { RenderBody } from '../RenderBody';
|
||||
import HTMLReactParser, { HTMLReactParserOptions } from 'html-react-parser';
|
||||
import { getReactCustomHtmlParser } from '../../../plugins/react-custom-html-parser';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiAlert, mdiImage } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
import { Button, CircularProgress, Dialog, DialogTitle, Tooltip } from '@mui/material';
|
||||
import { Button, CircularProgress, Dialog, Tooltip } from '@mui/material';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
type RenderViewerProps = {
|
||||
src: string;
|
||||
|
@ -77,7 +74,7 @@ export const ImageContent = as<'div', ImageContentProps>(
|
|||
|
||||
const [srcState, loadSrc] = useAsyncCallback(
|
||||
useCallback(
|
||||
() => getFileSrcUrl(mx.mxcUrlToHttp(url, undefined, undefined, undefined, false, true, true) ?? '', mimeType || FALLBACK_MIMETYPE, encInfo, mx),
|
||||
() => getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType || FALLBACK_MIMETYPE, encInfo, mx),
|
||||
[mx, url, mimeType, encInfo]
|
||||
)
|
||||
);
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|||
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||
import { getFileSrcUrl } from './util';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
export type ThumbnailContentProps = {
|
||||
info: IThumbnailContent;
|
||||
|
@ -20,7 +21,7 @@ export function ThumbnailContent({ info, renderImage }: ThumbnailContentProps) {
|
|||
throw new Error(getText('msg.thumbnail.failed'));
|
||||
}
|
||||
return getFileSrcUrl(
|
||||
mx.mxcUrlToHttp(thumbMxcUrl, undefined, undefined, undefined, false, true, true) ?? '',
|
||||
mxcUrlToHttp(mx, thumbMxcUrl) ?? '',
|
||||
thumbInfo.mimetype,
|
||||
info.thumbnail_file,
|
||||
mx
|
||||
|
|
|
@ -21,6 +21,7 @@ import { getText } from '../../../../lang';
|
|||
import Icon from '@mdi/react';
|
||||
import { mdiAlert, mdiPlay } from '@mdi/js';
|
||||
import { Button, Chip, CircularProgress, Fab, Tooltip, Typography } from '@mui/material';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
type RenderVideoProps = {
|
||||
title: string;
|
||||
|
@ -64,7 +65,7 @@ export const VideoContent = as<'div', VideoContentProps>(
|
|||
|
||||
const [srcState, loadSrc] = useAsyncCallback(
|
||||
useCallback(
|
||||
() => getFileSrcUrl(mx.mxcUrlToHttp(url, undefined, undefined, undefined, false, true, true) ?? '', mimeType, encInfo, mx, !('cordova' in window)),
|
||||
() => getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType, encInfo, mx, !('cordova' in window)),
|
||||
[mx, url, mimeType, encInfo]
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/* eslint-disable jsx-a11y/media-has-caption */
|
||||
import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Box, Text, toRem } from 'folds';
|
||||
import React, { ReactNode, useCallback, useRef, useState } from 'react';
|
||||
import { Box, Text } from 'folds';
|
||||
import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
|
||||
import { Range } from 'react-range';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||
import { getFileSrcUrl } from './util';
|
||||
|
@ -20,6 +19,7 @@ import { secondsToMinutesAndSeconds } from '../../../utils/common';
|
|||
import Icon from '@mdi/react';
|
||||
import { mdiPause, mdiPlay } from '@mdi/js';
|
||||
import { CircularProgress, IconButton, Slider, useTheme } from '@mui/material';
|
||||
import { mxcUrlToHttp } from '../../../utils/matrix';
|
||||
|
||||
const PLAY_TIME_THROTTLE_OPS = {
|
||||
wait: 500,
|
||||
|
@ -51,7 +51,7 @@ export function VoiceContent({
|
|||
|
||||
const [srcState, loadSrc] = useAsyncCallback(
|
||||
useCallback(
|
||||
() => getFileSrcUrl(mx.mxcUrlToHttp(url, undefined, undefined, undefined, false, true, true) ?? '', mimeType, encInfo, mx, !('cordova' in window)),
|
||||
() => getFileSrcUrl(mxcUrlToHttp(mx, url) ?? '', mimeType, encInfo, mx, !('cordova' in window)),
|
||||
[mx, url, mimeType, encInfo]
|
||||
)
|
||||
);
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
import classNames from 'classnames';
|
||||
import * as css from './style.css';
|
||||
import { RoomAvatar } from '../room-avatar';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { nameInitials } from '../../utils/common';
|
||||
import { millify } from '../../plugins/millify';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
|
@ -144,7 +144,7 @@ export const RoomCard = as<'div', RoomCardProps>(
|
|||
|
||||
const avatar = joinedRoom
|
||||
? getRoomAvatarUrl(mx, joinedRoom, 96)
|
||||
: avatarUrl && mx.mxcUrlToHttp(avatarUrl, 96, 96, 'crop');
|
||||
: avatarUrl && mxcUrlToHttp(mx, avatarUrl, 96, 96, 'crop');
|
||||
|
||||
const roomName = joinedRoom?.name || name || fallbackName;
|
||||
const roomTopic =
|
||||
|
|
|
@ -6,7 +6,7 @@ import { openInviteUser } from '../../../client/action/navigation';
|
|||
import { IRoomCreateContent, Membership, StateEvent } from '../../../types/matrix/room';
|
||||
import { getMemberDisplayName, getStateEvent } from '../../utils/room';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
import { timeDayMonthYear, timeHourMinute } from '../../utils/time';
|
||||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
||||
|
@ -32,7 +32,7 @@ export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) =>
|
|||
const avatarMxc = useRoomAvatar(room, mDirects.has(room.roomId));
|
||||
const name = useRoomName(room);
|
||||
const topic = useRoomTopic(room);
|
||||
const avatarHttpUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc) : undefined;
|
||||
const avatarHttpUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc) : undefined;
|
||||
|
||||
const createContent = createEvent?.getContent<IRoomCreateContent>();
|
||||
const ts = createEvent?.getTs();
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
import * as css from './UrlPreviewCard.css';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiArrowLeft, mdiArrowRight } from '@mdi/js';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
const linkStyles = { color: color.Success.Main };
|
||||
|
||||
|
@ -28,7 +29,7 @@ export const UrlPreviewCard = as<'div', { url: string; ts: number }>(
|
|||
if (previewStatus.status === AsyncStatus.Error) return null;
|
||||
|
||||
const renderContent = (prev: IPreviewUrlResponse) => {
|
||||
const imgUrl = mx.mxcUrlToHttp(prev['og:image'] || '', 256, 256, 'scale', false);
|
||||
const imgUrl = mxcUrlToHttp(mx, prev['og:image'] || '', 256, 256, 'scale');
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
import { style } from '@vanilla-extract/css';
|
||||
import { config } from 'folds';
|
||||
|
||||
export const Header = style({
|
||||
borderBottomColor: 'transparent',
|
||||
});
|
||||
export const HeaderTopic = style({
|
||||
':hover': {
|
||||
cursor: 'pointer',
|
||||
opacity: config.opacity.P500,
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
});
|
|
@ -2,31 +2,23 @@ import React, { MouseEventHandler, forwardRef, useState } from 'react';
|
|||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
RectCords,
|
||||
Text,
|
||||
config,
|
||||
toRem,
|
||||
} from 'folds';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { PageHeader } from '../../components/page';
|
||||
import { useSetSetting } from '../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
import { useRoomAvatar, useRoomName } from '../../hooks/useRoomMeta';
|
||||
import { useSpace } from '../../hooks/useSpace';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { RoomAvatar } from '../../components/room-avatar';
|
||||
import { nameInitials } from '../../utils/common';
|
||||
import * as css from './LobbyHeader.css';
|
||||
import { openInviteUser, openSpaceSettings } from '../../../client/action/navigation';
|
||||
import { IPowerLevels, usePowerLevelsAPI } from '../../hooks/usePowerLevels';
|
||||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import { LeaveSpacePrompt } from '../../components/leave-space-prompt';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAccount, mdiAccountPlus, mdiArrowLeft, mdiCog, mdiDotsVertical } from '@mdi/js';
|
||||
import { AppBar, Divider, IconButton, ListItemIcon, ListItemText, Menu, MenuItem, Toolbar, Tooltip } from '@mui/material';
|
||||
import { ArrowBack, MoreVert, Person, PersonAdd, Settings } from '@mui/icons-material';
|
||||
import { BackRouteHandler } from '../../components/BackRouteHandler';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
type LobbyMenuProps = {
|
||||
roomId: string;
|
||||
|
@ -115,7 +107,7 @@ export function LobbyHeader({ showProfile, powerLevels }: LobbyHeaderProps) {
|
|||
|
||||
const name = useRoomName(space);
|
||||
const avatarMxc = useRoomAvatar(space);
|
||||
const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined;
|
||||
const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, 96, 96, 'crop') ?? undefined : undefined;
|
||||
|
||||
const handleOpenMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
||||
setMenuAnchor(evt.currentTarget);
|
||||
|
|
|
@ -12,6 +12,7 @@ import { PageHero } from '../../components/page';
|
|||
import { onEnterOrSpace } from '../../utils/keyboard';
|
||||
import { Dialog } from '@mui/material';
|
||||
import { BackButtonHandler } from '../../hooks/useBackButton';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
export function LobbyHero() {
|
||||
const mx = useMatrixClient();
|
||||
|
@ -20,7 +21,7 @@ export function LobbyHero() {
|
|||
const name = useRoomName(space);
|
||||
const topic = useRoomTopic(space);
|
||||
const avatarMxc = useRoomAvatar(space);
|
||||
const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined;
|
||||
const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, 96, 96, 'crop') ?? undefined : undefined;
|
||||
|
||||
return (
|
||||
<PageHero
|
||||
|
|
|
@ -5,7 +5,6 @@ import {
|
|||
as,
|
||||
toRem,
|
||||
} from 'folds';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { JoinRule, MatrixError, Room } from 'matrix-js-sdk';
|
||||
import { RoomAvatar, RoomIcon } from '../../components/room-avatar';
|
||||
import { SequenceCard } from '../../components/sequence-card';
|
||||
|
@ -27,11 +26,10 @@ import { ErrorCode } from '../../cs-errorcode';
|
|||
import { getDirectRoomAvatarUrl, getRoomAvatarUrl } from '../../utils/room';
|
||||
import { ItemDraggableTarget, useDraggableItem } from './DnD';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlert, mdiArrowRight, mdiPlus } from '@mdi/js';
|
||||
import { Chip, Dialog, Divider, IconButton, Tooltip, Typography } from '@mui/material';
|
||||
import { ArrowForward, Warning } from '@mui/icons-material';
|
||||
import { BackButtonHandler } from '../../hooks/useBackButton';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
type RoomJoinButtonProps = {
|
||||
roomId: string;
|
||||
|
@ -352,7 +350,7 @@ export const RoomItemCard = as<'div', RoomItemCardProps>(
|
|||
topic={summaryState.data.topic}
|
||||
avatarUrl={
|
||||
summaryState.data?.avatar_url
|
||||
? mx.mxcUrlToHttp(summaryState.data.avatar_url, 96, 96, 'crop') ??
|
||||
? mxcUrlToHttp(mx, summaryState.data.avatar_url, 96, 96, 'crop') ??
|
||||
undefined
|
||||
: undefined
|
||||
}
|
||||
|
|
|
@ -4,12 +4,10 @@ import {
|
|||
Avatar,
|
||||
as,
|
||||
toRem,
|
||||
config,
|
||||
Chip,
|
||||
Text,
|
||||
Badge,
|
||||
} from 'folds';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import classNames from 'classnames';
|
||||
import { MatrixError, Room } from 'matrix-js-sdk';
|
||||
import { HierarchyItem } from '../../hooks/useSpaceHierarchy';
|
||||
|
@ -32,6 +30,7 @@ import { mdiChevronDown, mdiChevronRight, mdiPlus } from '@mdi/js';
|
|||
import Icon from '@mdi/react';
|
||||
import { Button, CircularProgress, ListItemText, Menu, MenuItem } from '@mui/material';
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
function SpaceProfileLoading() {
|
||||
return (
|
||||
|
@ -427,7 +426,7 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>(
|
|||
name={summaryState.data.name || summaryState.data.canonical_alias || roomId}
|
||||
avatarUrl={
|
||||
summaryState.data?.avatar_url
|
||||
? mx.mxcUrlToHttp(summaryState.data.avatar_url, 96, 96, 'crop') ??
|
||||
? mxcUrlToHttp(mx, summaryState.data.avatar_url, 96, 96, 'crop') ??
|
||||
undefined
|
||||
: undefined
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
getReactCustomHtmlParser,
|
||||
makeHighlightRegex,
|
||||
} from '../../plugins/react-custom-html-parser';
|
||||
import { getMxIdLocalPart, isRoomId, isUserId } from '../../utils/matrix';
|
||||
import { getMxIdLocalPart, isRoomId, isUserId, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { openJoinAlias, openProfileViewer } from '../../../client/action/navigation';
|
||||
import { useMatrixEventRenderer } from '../../hooks/useMatrixEventRenderer';
|
||||
import { GetContentCallback, MessageEvent, StateEvent } from '../../../types/matrix/room';
|
||||
|
@ -218,7 +218,7 @@ export function SearchResultGroup({
|
|||
userId={event.sender}
|
||||
src={
|
||||
senderAvatarMxc
|
||||
? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop') ?? undefined
|
||||
? mxcUrlToHttp(mx, senderAvatarMxc, 48, 48, 'crop') ?? undefined
|
||||
: undefined
|
||||
}
|
||||
alt={displayName}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { useVirtualizer } from "@tanstack/react-virtual";
|
|||
import { useRoomNavigate } from "../../hooks/useRoomNavigate";
|
||||
import { HTMLReactParserOptions } from "html-react-parser";
|
||||
import { getReactCustomHtmlParser } from "../../plugins/react-custom-html-parser";
|
||||
import { getMxIdLocalPart, isRoomId, isUserId } from "../../utils/matrix";
|
||||
import { getMxIdLocalPart, isRoomId, isUserId, mxcUrlToHttp } from "../../utils/matrix";
|
||||
import { openJoinAlias, openProfileViewer } from "../../../client/action/navigation";
|
||||
import { useSetting } from "../../state/hooks/settings";
|
||||
import { settingsAtom } from "../../state/settings";
|
||||
|
@ -108,7 +108,7 @@ function PinnedMessage({ room, eventId, renderContent, requestOpen, canUnpin }:
|
|||
userId={sender}
|
||||
src={
|
||||
senderAvatarMxc
|
||||
? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop', false, false, true) ??
|
||||
? mxcUrlToHttp(mx, senderAvatarMxc, 48, 48, 'crop') ??
|
||||
undefined
|
||||
: undefined
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { Avatar, Box, IconButton, Text } from "folds";
|
||||
import { CallEvent, Room, User } from "matrix-js-sdk";
|
||||
import { CallEvent, Room } from "matrix-js-sdk";
|
||||
|
||||
import * as css from './RoomCall.css';
|
||||
import { UserAvatar } from '../../components/user-avatar';
|
||||
|
@ -9,10 +9,10 @@ import { useMatrixClient } from '../../hooks/useMatrixClient';
|
|||
import { AvatarBase } from '../../components/message';
|
||||
import { CallErrorCode, CallState, MatrixCall } from 'matrix-js-sdk/lib/webrtc/call';
|
||||
import { CallFeed } from 'matrix-js-sdk/lib/webrtc/callFeed';
|
||||
import { SDPStreamMetadataPurpose } from 'matrix-js-sdk/lib/webrtc/callEventTypes';
|
||||
import Icon, { Icon as MDIcon } from '@mdi/react';
|
||||
import { mdiAccount, mdiCamera, mdiCameraOff, mdiMicrophone, mdiMicrophoneOff, mdiPhone, mdiPhoneHangup, mdiVideo, mdiVideoOff } from '@mdi/js';
|
||||
import { mdiAccount, mdiMicrophone, mdiMicrophoneOff, mdiPhone, mdiPhoneHangup, mdiVideo, mdiVideoOff } from '@mdi/js';
|
||||
import { translate } from '../../../lang';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
// TODO refactor
|
||||
const styles: Record<CallState | string, CSSProperties> = {
|
||||
|
@ -57,8 +57,6 @@ export function RoomCall({ room, call, onHangup, invitation, video }: RoomCallPr
|
|||
if (!recipient) return;
|
||||
|
||||
const audioRef = useRef<HTMLAudioElement>(null);
|
||||
|
||||
const [userStyle, setUserStyle] = useState<CSSProperties>();
|
||||
const [recipientStyle, setRecipientStyle] = useState<CSSProperties>();
|
||||
|
||||
const [recipientShowVideo, setRecipientShowVideo] = useState(false);
|
||||
|
@ -198,14 +196,11 @@ export function RoomCall({ room, call, onHangup, invitation, video }: RoomCallPr
|
|||
<video controls={false} autoPlay className={css.VideoFeed} style={{ display: localShowVideo ? 'block' : 'none' }} ref={localVideoRef} />
|
||||
{!localShowVideo && (
|
||||
<AvatarBase className={css.UserAvatar}>
|
||||
<Avatar
|
||||
style={userStyle}
|
||||
>
|
||||
<Avatar>
|
||||
<UserAvatar
|
||||
userId={user.userId}
|
||||
alt={user.displayName ?? user.userId}
|
||||
src={typeof user.avatarUrl === 'string' ? mx.mxcUrlToHttp(user.avatarUrl, 96, 96, 'scale', true) ?? undefined : undefined}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
src={typeof user.avatarUrl === 'string' ? mxcUrlToHttp(mx, user.avatarUrl, 96, 96, 'scale') ?? undefined : undefined}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
|
@ -221,8 +216,7 @@ export function RoomCall({ room, call, onHangup, invitation, video }: RoomCallPr
|
|||
<UserAvatar
|
||||
userId={recipient.userId}
|
||||
alt={recipient.displayName ?? recipient.userId}
|
||||
src={typeof recipient.avatarUrl === 'string' ? mx.mxcUrlToHttp(recipient.avatarUrl, 96, 96, 'scale', true) ?? undefined : undefined}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
src={typeof recipient.avatarUrl === 'string' ? mxcUrlToHttp(mx, recipient.avatarUrl, 96, 96, 'scale') ?? undefined : undefined}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import React, {
|
||||
Dispatch,
|
||||
KeyboardEventHandler,
|
||||
MouseEvent,
|
||||
MouseEventHandler,
|
||||
PointerEvent,
|
||||
RefObject,
|
||||
forwardRef,
|
||||
useCallback,
|
||||
|
@ -21,7 +18,6 @@ import {
|
|||
Overlay,
|
||||
OverlayBackdrop,
|
||||
OverlayCenter,
|
||||
PopOut,
|
||||
Scroll,
|
||||
Text,
|
||||
config,
|
||||
|
@ -41,7 +37,6 @@ import {
|
|||
RoomMentionAutocomplete,
|
||||
UserMentionAutocomplete,
|
||||
EmoticonAutocomplete,
|
||||
resetEditorHistory,
|
||||
customHtmlEqualsPlainText,
|
||||
trimCustomHtml,
|
||||
isEmptyEditor,
|
||||
|
@ -50,8 +45,7 @@ import {
|
|||
getMentions
|
||||
} from '../../components/editor';
|
||||
import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board';
|
||||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import { TUploadContent, encryptFile, getImageInfo, getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { TUploadContent, encryptFile, getImageInfo, getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { useTypingStatusUpdater } from '../../hooks/useTypingStatusUpdater';
|
||||
import { useFilePicker } from '../../hooks/useFilePicker';
|
||||
import { useFilePasteHandler } from '../../hooks/useFilePasteHandler';
|
||||
|
@ -100,15 +94,14 @@ import { sanitizeText } from '../../utils/sanitize';
|
|||
import { CommandAutocomplete } from './CommandAutocomplete';
|
||||
import { Command, SHRUG, LENNY, TABLEFLIP, UNFLIP, useCommands } from '../../hooks/useCommands';
|
||||
import { mobileOrTablet } from '../../utils/user-agent';
|
||||
import { useElementSizeObserver } from '../../hooks/useElementSizeObserver';
|
||||
import { ReplyLayout } from '../../components/message';
|
||||
import { markAsRead } from '../../../client/action/notifications';
|
||||
import { roomToParentsAtom } from '../../state/room/roomToParents';
|
||||
import { getText } from '../../../lang';
|
||||
import { openHiddenRooms, openReusableContextMenu } from '../../../client/action/navigation';
|
||||
import { openReusableContextMenu } from '../../../client/action/navigation';
|
||||
import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAt, mdiBell, mdiBellOff, mdiCheckAll, mdiClose, mdiEmoticon, mdiEmoticonOutline, mdiEye, mdiEyeOff, mdiFile, mdiMicrophone, mdiPlusCircle, mdiPlusCircleOutline, mdiSend, mdiSendOutline, mdiSticker, mdiStickerOutline } from '@mdi/js';
|
||||
import { mdiBell, mdiBellOff, mdiClose, mdiEmoticon, mdiEmoticonOutline, mdiEye, mdiEyeOff, mdiFile, mdiMicrophone, mdiPlusCircleOutline, mdiSendOutline, mdiSticker, mdiStickerOutline } from '@mdi/js';
|
||||
import { usePowerLevelsAPI, usePowerLevelsContext } from '../../hooks/usePowerLevels';
|
||||
import { useVoiceRecorder } from '../../hooks/useVoiceRecorder';
|
||||
import { getEventCords } from '../../../util/common';
|
||||
|
@ -525,7 +518,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
}, [textAreaRef]);
|
||||
|
||||
const handleStickerSelect = async (mxc: string, shortcode: string, label: string) => {
|
||||
const stickerUrl = mx.mxcUrlToHttp(mxc);
|
||||
const stickerUrl = mxcUrlToHttp(mx, mxc);
|
||||
if (!stickerUrl) return;
|
||||
|
||||
const info = await getImageInfo(
|
||||
|
|
|
@ -29,6 +29,7 @@ import { v4 } from 'uuid';
|
|||
import { generateConferenceID } from '../../../util/conferenceID';
|
||||
import { getIntegrationManagerURL } from '../../hooks/useIntegrationManager';
|
||||
import wallpaperDB from '../../utils/wallpaper';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
export function RoomView({ room, eventId }: { room: Room; eventId?: string; }) {
|
||||
const roomInputRef = useRef(null);
|
||||
|
@ -79,7 +80,7 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string; }) {
|
|||
matrix_user_id: myUserId,
|
||||
matrix_room_id: room.roomId,
|
||||
matrix_display_name: profile?.displayName ?? myUserId,
|
||||
matrix_avatar_url: profile?.avatarUrl && mx.mxcUrlToHttp(profile?.avatarUrl),
|
||||
matrix_avatar_url: profile?.avatarUrl && mxcUrlToHttp(mx, profile?.avatarUrl, undefined, undefined, undefined, true),
|
||||
...content.data
|
||||
};
|
||||
var url = `${content.url}`; // Should not be a reference
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
withOriginBaseUrl,
|
||||
withSearchParam,
|
||||
} from '../../pages/pathUtils';
|
||||
import { getCanonicalAliasOrRoomId, isRoomId, isUserId } from '../../utils/matrix';
|
||||
import { getCanonicalAliasOrRoomId, isRoomId, isUserId, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { _SearchPathSearchParams } from '../../pages/paths';
|
||||
import * as css from './RoomViewHeader.css';
|
||||
import { useRoomUnread } from '../../state/hooks/unread';
|
||||
|
@ -261,7 +261,7 @@ export function RoomViewHeader({
|
|||
const [showPinned, setShowPinned] = useState(false);
|
||||
const [showWidgets, setShowWidgets] = useState(false);
|
||||
const [widgets, setWidgets] = useState<ReactNode[]>([]);
|
||||
const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined : undefined;
|
||||
const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, 96, 96, 'crop') ?? undefined : undefined;
|
||||
const powerLevels = usePowerLevelsContext();
|
||||
const { getPowerLevel, canSendStateEvent, canDoAction } = usePowerLevelsAPI(powerLevels);
|
||||
const myUserId = mx.getUserId();
|
||||
|
|
|
@ -41,7 +41,7 @@ import {
|
|||
getMemberAvatarMxc,
|
||||
getMemberDisplayName,
|
||||
} from '../../../utils/room';
|
||||
import { getCanonicalAliasOrRoomId, getMxIdLocalPart, isRoomId, isUserId } from '../../../utils/matrix';
|
||||
import { getCanonicalAliasOrRoomId, getMxIdLocalPart, isRoomId, isUserId, mxcUrlToHttp } from '../../../utils/matrix';
|
||||
import { MessageLayout, MessageSpacing, settingsAtom } from '../../../state/settings';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { useRecentEmoji } from '../../../hooks/useRecentEmoji';
|
||||
|
@ -300,7 +300,7 @@ export const MessageFileDownloadItem = as<
|
|||
const mxc = url ?? content.file?.url;
|
||||
const fileInfo = content?.info;
|
||||
const handleClick = async () => {
|
||||
const httpUrl = mx.mxcUrlToHttp(mxc, undefined, undefined, undefined, false, true, true);
|
||||
const httpUrl = mxcUrlToHttp(mx, mxc);
|
||||
if (!httpUrl) return onClose?.();
|
||||
const Url = await getFileSrcUrl(
|
||||
httpUrl,
|
||||
|
@ -1265,7 +1265,7 @@ export const Message = as<'div', MessageProps>(
|
|||
userId={senderId}
|
||||
src={
|
||||
senderAvatarMxc
|
||||
? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop') ?? undefined
|
||||
? mxcUrlToHttp(mx, senderAvatarMxc, 48, 48, 'crop') ?? undefined
|
||||
: undefined
|
||||
}
|
||||
alt={senderDisplayName}
|
||||
|
|
|
@ -22,6 +22,7 @@ import ImagePackUpload from './ImagePackUpload';
|
|||
import { getText } from '../../../lang';
|
||||
import { Button, Checkbox, DialogActions, DialogContent, TextField } from '@mui/material';
|
||||
import { useForceUpdate } from '../../hooks/useForceUpdate';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
const renameImagePackItem = (shortcode) => new Promise((resolve) => {
|
||||
let isCompleted = false;
|
||||
|
@ -270,7 +271,7 @@ function ImagePack({ roomId, stateKey, handlePackDelete }) {
|
|||
return (
|
||||
<div className="image-pack">
|
||||
<ImagePackProfile
|
||||
avatarUrl={pack.avatarUrl ? mx.mxcUrlToHttp(pack.avatarUrl, 42, 42, 'crop') : null}
|
||||
avatarUrl={pack.avatarUrl ? mxcUrlToHttp(mx, pack.avatarUrl, 42, 42, 'crop') : null}
|
||||
displayName={pack.displayName ?? 'Unknown'}
|
||||
attribution={pack.attribution}
|
||||
usage={getUsage(pack.usage)}
|
||||
|
@ -291,7 +292,7 @@ function ImagePack({ roomId, stateKey, handlePackDelete }) {
|
|||
{images.map(([shortcode, image]) => (
|
||||
<ImagePackItem
|
||||
key={shortcode}
|
||||
url={mx.mxcUrlToHttp(image.mxc)}
|
||||
url={mxcUrlToHttp(mx, image.mxc)}
|
||||
shortcode={shortcode}
|
||||
usage={getUsage(image.usage)}
|
||||
onUsageChange={canChange ? handleUsageItem : undefined}
|
||||
|
@ -356,7 +357,7 @@ function ImagePackUser() {
|
|||
return (
|
||||
<div className="image-pack">
|
||||
<ImagePackProfile
|
||||
avatarUrl={pack.avatarUrl ? mx.mxcUrlToHttp(pack.avatarUrl, 42, 42, 'crop') : null}
|
||||
avatarUrl={pack.avatarUrl ? mxcUrlToHttp(mx, pack.avatarUrl, 42, 42, 'crop') : null}
|
||||
displayName={pack.displayName ?? getText('emojiboard.personal_pack')}
|
||||
attribution={pack.attribution}
|
||||
usage={getUsage(pack.usage)}
|
||||
|
@ -375,7 +376,7 @@ function ImagePackUser() {
|
|||
{images.map(([shortcode, image]) => (
|
||||
<ImagePackItem
|
||||
key={shortcode}
|
||||
url={mx.mxcUrlToHttp(image.mxc)}
|
||||
url={mxcUrlToHttp(mx, image.mxc)}
|
||||
shortcode={shortcode}
|
||||
usage={getUsage(image.usage)}
|
||||
onUsageChange={handleUsageItem}
|
||||
|
|
|
@ -10,7 +10,7 @@ import Text from '../../atoms/text/Text';
|
|||
import RoomTile from '../../molecules/room-tile/RoomTile';
|
||||
|
||||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
||||
import { getDMRoomFor, getRoomNameOrId } from '../../utils/matrix';
|
||||
import { getDMRoomFor, getRoomNameOrId, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { getText } from '../../../lang';
|
||||
import { BackButtonHandler, useBackButton } from '../../hooks/useBackButton';
|
||||
import { mdiAccount, mdiClose } from '@mdi/js';
|
||||
|
@ -219,7 +219,7 @@ function InviteUser({ isOpen, roomId, searchTerm, onRequestClose }) {
|
|||
key={userId}
|
||||
avatarSrc={
|
||||
typeof user.avatar_url === 'string'
|
||||
? mx.mxcUrlToHttp(user.avatar_url, 42, 42, 'crop')
|
||||
? mxcUrlToHttp(mx, user.avatar_url, 42, 42, 'crop')
|
||||
: null
|
||||
}
|
||||
name={name}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { useRef, useState } from 'react';
|
|||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import './Banner.scss';
|
||||
import initMatrix from '../../../client/initMatrix';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
export default function Banner({ url, noBorder, onUpload, emptyBanner }) {
|
||||
const mx = useMatrixClient();
|
||||
const uploadImageRef = useRef(null);
|
||||
|
@ -38,7 +39,7 @@ export default function Banner({ url, noBorder, onUpload, emptyBanner }) {
|
|||
<div onClick={handleClick} className={noBorder ? 'banner-container-nb' : 'banner-container'}>
|
||||
{
|
||||
!emptyBanner ?
|
||||
<img src={mx.mxcUrlToHttp(url)} className='profile-banner' /> :
|
||||
<img src={mxcUrlToHttp(mx, url)} className='profile-banner' /> :
|
||||
<div style={{ height: '150px', backgroundColor: emptyBanner }} />
|
||||
}
|
||||
<input type='file' accept='image/*' onChange={uploadImage} ref={uploadImageRef} style={{ display: 'none' }} />
|
||||
|
|
|
@ -18,6 +18,7 @@ import { Box } from 'folds';
|
|||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useAccountData } from '../../hooks/useAccountData';
|
||||
import { copyToClipboard } from '../../../util/common';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
|
||||
function ProfileEditor({ userId }) {
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
|
@ -26,7 +27,7 @@ function ProfileEditor({ userId }) {
|
|||
|
||||
const displayNameRef = useRef(null);
|
||||
const [avatarSrc, setAvatarSrc] = useState(
|
||||
user.avatarUrl ? mx.mxcUrlToHttp(user.avatarUrl, 80, 80, 'crop') : null
|
||||
user.avatarUrl ? mxcUrlToHttp(mx, user.avatarUrl, 80, 80, 'crop') : null
|
||||
);
|
||||
const [username, setUsername] = useState(user.displayName);
|
||||
const [disabled, setDisabled] = useState(true);
|
||||
|
@ -35,7 +36,7 @@ function ProfileEditor({ userId }) {
|
|||
let isMounted = true;
|
||||
mx.getProfileInfo(mx.getUserId()).then((info) => {
|
||||
if (!isMounted) return;
|
||||
setAvatarSrc(info.avatar_url ? mx.mxcUrlToHttp(info.avatar_url, 80, 80, 'crop') : null);
|
||||
setAvatarSrc(info.avatar_url ? mxcUrlToHttp(mx, info.avatar_url, 80, 80, 'crop') : null);
|
||||
setUsername(info.displayname);
|
||||
});
|
||||
return () => {
|
||||
|
@ -58,7 +59,7 @@ function ProfileEditor({ userId }) {
|
|||
return;
|
||||
}
|
||||
mx.setAvatarUrl(url);
|
||||
setAvatarSrc(mx.mxcUrlToHttp(url, 80, 80, 'crop'));
|
||||
setAvatarSrc(mxcUrlToHttp(mx, url, 80, 80, 'crop'));
|
||||
};
|
||||
|
||||
const saveDisplayName = () => {
|
||||
|
@ -186,7 +187,7 @@ function ProfileEditor({ userId }) {
|
|||
};
|
||||
|
||||
const bannerUrl = useMemo(() => {
|
||||
return mx.mxcUrlToHttp(bannerSrc, null, null, null, false, true, true);
|
||||
return mxcUrlToHttp(mx, bannerSrc);
|
||||
}, [mx, bannerSrc]);
|
||||
|
||||
const [snackbarOpen, setSnackbar] = useState(false);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import './ProfileViewer.scss';
|
||||
|
||||
|
@ -25,7 +25,7 @@ import PowerLevelSelector from '../../molecules/power-level-selector/PowerLevelS
|
|||
import { useForceUpdate } from '../../hooks/useForceUpdate';
|
||||
import { confirmDialog } from '../../molecules/confirm-dialog/ConfirmDialog';
|
||||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
||||
import { getDMRoomFor, getMxIdLocalPart, getMxIdServer } from '../../utils/matrix';
|
||||
import { getDMRoomFor, getMxIdLocalPart, getMxIdServer, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { EventTimeline } from 'matrix-js-sdk';
|
||||
import Banner from './Banner';
|
||||
import { getText, translate } from '../../../lang';
|
||||
|
@ -480,7 +480,7 @@ function ProfileViewer() {
|
|||
const username = roomMember ? getUsernameOfRoomMember(roomMember) : getUsername(userId);
|
||||
const avatarMxc = roomMember?.getMxcAvatarUrl?.() || mx.getUser(userId)?.avatarUrl;
|
||||
const avatarUrl =
|
||||
avatarMxc && avatarMxc !== 'null' ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null;
|
||||
avatarMxc && avatarMxc !== 'null' ? mxcUrlToHttp(mx, avatarMxc, 80, 80, 'crop') : null;
|
||||
|
||||
const powerLevel = roomMember?.powerLevel || 0;
|
||||
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0;
|
||||
|
@ -489,13 +489,13 @@ function ProfileViewer() {
|
|||
const membership = roomState.getStateEvents('m.room.member', userId);
|
||||
const membershipContent = membership?.getContent() ?? {};
|
||||
|
||||
var bannerUrl;
|
||||
|
||||
console.log(membershipContent);
|
||||
|
||||
if (typeof membershipContent[cons.EXTERA_BANNER_URL] === 'string' && membershipContent[cons.EXTERA_BANNER_URL].startsWith('mxc://')) {
|
||||
bannerUrl = mx.mxcUrlToHttp(membershipContent[cons.EXTERA_BANNER_URL], false, false, false, false, true, true);
|
||||
}
|
||||
const bannerUrl = useMemo(() => {
|
||||
if (typeof membershipContent[cons.EXTERA_BANNER_URL] === 'string' && membershipContent[cons.EXTERA_BANNER_URL].startsWith('mxc://')) {
|
||||
return mxcUrlToHttp(mx, membershipContent[cons.EXTERA_BANNER_URL]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [mx, membershipContent]);
|
||||
|
||||
const canChangeRole =
|
||||
room.currentState.maySendEvent('m.room.power_levels', mx.getUserId()) &&
|
||||
|
|
|
@ -185,7 +185,6 @@ function RoomMembersItem({ room, onClick }) {
|
|||
}
|
||||
|
||||
function RoomSettings() {
|
||||
const mx = useMatrixClient();
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
const [isEditing, setEditing] = useState(false);
|
||||
const [window, requestClose] = useWindowToggle(setSelectedTab);
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Close } from "@mui/icons-material";
|
|||
import { getText } from "../../../lang";
|
||||
import { Box } from "folds";
|
||||
import { useMatrixClient } from "../../hooks/useMatrixClient";
|
||||
import { mxcUrlToHttp } from "../../utils/matrix";
|
||||
|
||||
function Theme({ theme, onToggle, onRemove }) {
|
||||
return (
|
||||
|
@ -52,7 +53,7 @@ export default function Themes() {
|
|||
const onAdd = (evt) => {
|
||||
evt.preventDefault();
|
||||
const { name, url } = evt.target.elements;
|
||||
const cssUrl = mx.mxcUrlToHttp(url.value, false, false, false, true, true);
|
||||
const cssUrl = mxcUrlToHttp(mx, url.value);
|
||||
setThemes([
|
||||
...themes,
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
isNotificationEvent,
|
||||
} from '../../utils/room';
|
||||
import { NotificationType, UnreadInfo } from '../../../types/matrix/room';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
|
||||
import { useSelectedRoom } from '../../hooks/router/useSelectedRoom';
|
||||
import { useInboxNotificationsSelected } from '../../hooks/router/useInbox';
|
||||
import { enablePush } from '../../../push';
|
||||
|
@ -197,7 +197,7 @@ function MessageNotifications() {
|
|||
plugin.local.schedule({
|
||||
id,
|
||||
title: roomName,
|
||||
icon: roomAvatar ? mx.mxcUrlToHttp(roomAvatar, 96, 96, 'scale', true) : undefined,
|
||||
icon: roomAvatar ? mxcUrlToHttp(mx, roomAvatar, 96, 96, 'scale', true) : undefined,
|
||||
text,
|
||||
data: {
|
||||
roomId
|
||||
|
@ -266,7 +266,7 @@ function MessageNotifications() {
|
|||
notify({
|
||||
roomName: room.name ?? 'Unknown',
|
||||
roomAvatar: avatarMxc
|
||||
? mx.mxcUrlToHttp(avatarMxc, 96, 96, 'crop') ?? undefined
|
||||
? mxcUrlToHttp(mx, avatarMxc, 96, 96, 'crop') ?? undefined
|
||||
: undefined,
|
||||
username: getMemberDisplayName(room, sender) ?? getMxIdLocalPart(sender) ?? sender,
|
||||
roomId: room.roomId,
|
||||
|
|
|
@ -23,7 +23,7 @@ import { useVirtualizer } from '@tanstack/react-virtual';
|
|||
import { HTMLReactParserOptions } from 'html-react-parser';
|
||||
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { getMxIdLocalPart, isRoomId, isUserId } from '../../../utils/matrix';
|
||||
import { getMxIdLocalPart, isRoomId, isUserId, mxcUrlToHttp } from '../../../utils/matrix';
|
||||
import { InboxNotificationsPathSearchParams } from '../../paths';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
||||
import { SequenceCard } from '../../../components/sequence-card';
|
||||
|
@ -418,7 +418,7 @@ function RoomNotificationsGroupComp({
|
|||
userId={event.sender}
|
||||
src={
|
||||
senderAvatarMxc
|
||||
? mx.mxcUrlToHttp(senderAvatarMxc, 48, 48, 'crop') ?? undefined
|
||||
? mxcUrlToHttp(mx, senderAvatarMxc, 48, 48, 'crop') ?? undefined
|
||||
: undefined
|
||||
}
|
||||
alt={displayName}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ChangeEventHandler, EventHandler, KeyboardEventHandler, RefObject, SyntheticEvent, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import React, { KeyboardEventHandler, RefObject, SyntheticEvent, useEffect, useRef, useState } from 'react';
|
||||
import { PageNav, PageNavContent } from '../../../components/page';
|
||||
import { AppBar, Box, CircularProgress, IconButton, LinearProgress, Tab, Tabs, Toolbar, useTheme } from '@mui/material';
|
||||
import { useNavHidden } from '../../../hooks/useHideableNav';
|
||||
|
@ -6,15 +6,10 @@ import { MenuOpen, Menu as MenuIcon, Close, Message as MessageIcon } from '@mui/
|
|||
import SearchBar from '../SearchBar';
|
||||
import { getText } from '../../../../lang';
|
||||
import { MatrixEvent, Room } from 'matrix-js-sdk';
|
||||
import { Scroll } from 'folds';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { VirtualTile } from '../../../components/virtualizer';
|
||||
import { RoomNavItem } from '../../../features/room-nav';
|
||||
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||
import { getHomeRoomPath } from '../../pathUtils';
|
||||
import { getCanonicalAliasOrRoomId, getDMRoomFor, searchRoom } from '../../../utils/matrix';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { getDMRoomFor, mxcUrlToHttp, searchRoom } from '../../../utils/matrix';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { muteChangesAtom } from '../../../state/room-list/mutedRoomList';
|
||||
import { roomToUnreadAtom } from '../../../state/room/roomToUnread';
|
||||
import RoomSelector from '../../../molecules/room-selector/RoomSelector';
|
||||
|
@ -22,9 +17,6 @@ import RoomTile from '../../../molecules/room-tile/RoomTile';
|
|||
|
||||
import * as roomActions from '../../../../client/action/room';
|
||||
import { hasDevices } from '../../../../util/matrixUtil';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { MessageSearchParams, useMessageSearch } from '../../../features/message-search/useMessageSearch';
|
||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
import { MessageSearch } from '../../../features/message-search';
|
||||
import { useRooms } from '../../../state/hooks/roomList';
|
||||
import { mDirectAtom } from '../../../state/mDirectList';
|
||||
|
@ -130,7 +122,7 @@ function SearchUsers({ users }: { users: UserProfile[] }) {
|
|||
key={userId}
|
||||
avatarSrc={
|
||||
typeof user.avatar_url === 'string'
|
||||
? mx.mxcUrlToHttp(user.avatar_url, 42, 42, 'crop')
|
||||
? mxcUrlToHttp(mx, user.avatar_url, 42, 42, 'crop')
|
||||
: null
|
||||
}
|
||||
name={name}
|
||||
|
|
|
@ -8,280 +8,280 @@ import { StateEvent } from '../../types/matrix/room';
|
|||
export type PackEventIdToUnknown = Record<string, unknown>;
|
||||
export type EmoteRoomIdToPackEvents = Record<string, PackEventIdToUnknown>;
|
||||
export type EmoteRoomsContent = {
|
||||
rooms?: EmoteRoomIdToPackEvents;
|
||||
rooms?: EmoteRoomIdToPackEvents;
|
||||
};
|
||||
|
||||
export enum PackUsage {
|
||||
Emoticon = 'emoticon',
|
||||
Sticker = 'sticker',
|
||||
Emoticon = 'emoticon',
|
||||
Sticker = 'sticker',
|
||||
}
|
||||
|
||||
export type PackImage = {
|
||||
url: string;
|
||||
body?: string;
|
||||
usage?: PackUsage[];
|
||||
info?: IImageInfo;
|
||||
url: string;
|
||||
body?: string;
|
||||
usage?: PackUsage[];
|
||||
info?: IImageInfo;
|
||||
};
|
||||
|
||||
export type PackImages = Record<string, PackImage>;
|
||||
|
||||
export type PackMeta = {
|
||||
display_name?: string;
|
||||
avatar_url?: string;
|
||||
attribution?: string;
|
||||
usage?: PackUsage[];
|
||||
display_name?: string;
|
||||
avatar_url?: string;
|
||||
attribution?: string;
|
||||
usage?: PackUsage[];
|
||||
};
|
||||
|
||||
export type ExtendedPackImage = PackImage & {
|
||||
shortcode: string;
|
||||
shortcode: string;
|
||||
};
|
||||
|
||||
export type PackContent = {
|
||||
pack?: PackMeta;
|
||||
images?: PackImages;
|
||||
pack?: PackMeta;
|
||||
images?: PackImages;
|
||||
};
|
||||
|
||||
export class ImagePack {
|
||||
public id: string;
|
||||
public id: string;
|
||||
|
||||
public content: PackContent;
|
||||
public content: PackContent;
|
||||
|
||||
public displayName?: string;
|
||||
public displayName?: string;
|
||||
|
||||
public avatarUrl?: string;
|
||||
public avatarUrl?: string;
|
||||
|
||||
public usage?: PackUsage[];
|
||||
public usage?: PackUsage[];
|
||||
|
||||
public attribution?: string;
|
||||
public attribution?: string;
|
||||
|
||||
public images: Map<string, ExtendedPackImage>;
|
||||
public images: Map<string, ExtendedPackImage>;
|
||||
|
||||
public emoticons: ExtendedPackImage[];
|
||||
public emoticons: ExtendedPackImage[];
|
||||
|
||||
public stickers: ExtendedPackImage[];
|
||||
public stickers: ExtendedPackImage[];
|
||||
|
||||
static parsePack(eventId: string, packContent: PackContent) {
|
||||
if (!eventId || typeof packContent?.images !== 'object') {
|
||||
return undefined;
|
||||
static parsePack(eventId: string, packContent: PackContent) {
|
||||
if (!eventId || typeof packContent?.images !== 'object') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return new ImagePack(eventId, packContent);
|
||||
}
|
||||
|
||||
return new ImagePack(eventId, packContent);
|
||||
}
|
||||
constructor(eventId: string, content: PackContent) {
|
||||
this.id = eventId;
|
||||
this.content = JSON.parse(JSON.stringify(content));
|
||||
|
||||
constructor(eventId: string, content: PackContent) {
|
||||
this.id = eventId;
|
||||
this.content = JSON.parse(JSON.stringify(content));
|
||||
this.images = new Map();
|
||||
this.emoticons = [];
|
||||
this.stickers = [];
|
||||
|
||||
this.images = new Map();
|
||||
this.emoticons = [];
|
||||
this.stickers = [];
|
||||
|
||||
this.applyPackMeta(content);
|
||||
this.applyImages(content);
|
||||
}
|
||||
|
||||
applyPackMeta(content: PackContent) {
|
||||
const pack = content.pack ?? {};
|
||||
|
||||
this.displayName = pack.display_name;
|
||||
this.avatarUrl = pack.avatar_url;
|
||||
this.usage = pack.usage ?? [PackUsage.Emoticon, PackUsage.Sticker];
|
||||
this.attribution = pack.attribution;
|
||||
}
|
||||
|
||||
applyImages(content: PackContent) {
|
||||
this.images = new Map();
|
||||
this.emoticons = [];
|
||||
this.stickers = [];
|
||||
if (!content.images) return;
|
||||
|
||||
Object.entries(content.images).forEach(([shortcode, data]) => {
|
||||
const { url } = data;
|
||||
const body = data.body ?? shortcode;
|
||||
const usage = data.usage ?? this.usage;
|
||||
const { info } = data;
|
||||
|
||||
if (!url) return;
|
||||
const image: ExtendedPackImage = {
|
||||
shortcode,
|
||||
url,
|
||||
body,
|
||||
usage,
|
||||
info,
|
||||
};
|
||||
|
||||
this.images.set(shortcode, image);
|
||||
if (usage && usage.includes(PackUsage.Emoticon)) {
|
||||
this.emoticons.push(image);
|
||||
}
|
||||
if (usage && usage.includes(PackUsage.Sticker)) {
|
||||
this.stickers.push(image);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getImages() {
|
||||
return this.images;
|
||||
}
|
||||
|
||||
getEmojis() {
|
||||
return this.emoticons;
|
||||
}
|
||||
|
||||
getStickers() {
|
||||
return this.stickers;
|
||||
}
|
||||
|
||||
getImagesFor(usage: PackUsage) {
|
||||
if (usage === PackUsage.Emoticon) return this.getEmojis();
|
||||
if (usage === PackUsage.Sticker) return this.getStickers();
|
||||
return this.getEmojis();
|
||||
}
|
||||
|
||||
getContent() {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
getPackAvatarUrl(usage: PackUsage): string | undefined {
|
||||
return this.avatarUrl || this.getImagesFor(usage)[0].url;
|
||||
}
|
||||
|
||||
private updatePackProperty<K extends keyof PackMeta>(property: K, value: PackMeta[K]) {
|
||||
if (this.content.pack === undefined) {
|
||||
this.content.pack = {};
|
||||
this.applyPackMeta(content);
|
||||
this.applyImages(content);
|
||||
}
|
||||
this.content.pack[property] = value;
|
||||
this.applyPackMeta(this.content);
|
||||
}
|
||||
|
||||
setAvatarUrl(avatarUrl?: string) {
|
||||
this.updatePackProperty('avatar_url', avatarUrl);
|
||||
}
|
||||
applyPackMeta(content: PackContent) {
|
||||
const pack = content.pack ?? {};
|
||||
|
||||
setDisplayName(displayName?: string) {
|
||||
this.updatePackProperty('display_name', displayName);
|
||||
}
|
||||
this.displayName = pack.display_name;
|
||||
this.avatarUrl = pack.avatar_url;
|
||||
this.usage = pack.usage ?? [PackUsage.Emoticon, PackUsage.Sticker];
|
||||
this.attribution = pack.attribution;
|
||||
}
|
||||
|
||||
setAttribution(attribution?: string) {
|
||||
this.updatePackProperty('attribution', attribution);
|
||||
}
|
||||
applyImages(content: PackContent) {
|
||||
this.images = new Map();
|
||||
this.emoticons = [];
|
||||
this.stickers = [];
|
||||
if (!content.images) return;
|
||||
|
||||
setUsage(usage?: PackUsage[]) {
|
||||
this.updatePackProperty('usage', usage);
|
||||
}
|
||||
Object.entries(content.images).forEach(([shortcode, data]) => {
|
||||
const { url } = data;
|
||||
const body = data.body ?? shortcode;
|
||||
const usage = data.usage ?? this.usage;
|
||||
const { info } = data;
|
||||
|
||||
addImage(key: string, imgContent: PackImage) {
|
||||
this.content.images = {
|
||||
[key]: imgContent,
|
||||
...this.content.images,
|
||||
};
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
if (!url) return;
|
||||
const image: ExtendedPackImage = {
|
||||
shortcode,
|
||||
url,
|
||||
body,
|
||||
usage,
|
||||
info,
|
||||
};
|
||||
|
||||
removeImage(key: string) {
|
||||
if (!this.content.images) return;
|
||||
if (this.content.images[key] === undefined) return;
|
||||
delete this.content.images[key];
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
this.images.set(shortcode, image);
|
||||
if (usage && usage.includes(PackUsage.Emoticon)) {
|
||||
this.emoticons.push(image);
|
||||
}
|
||||
if (usage && usage.includes(PackUsage.Sticker)) {
|
||||
this.stickers.push(image);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateImageKey(key: string, newKey: string) {
|
||||
const { images } = this.content;
|
||||
if (!images) return;
|
||||
if (images[key] === undefined) return;
|
||||
const copyImages: PackImages = {};
|
||||
Object.keys(images).forEach((imgKey) => {
|
||||
copyImages[imgKey === key ? newKey : imgKey] = images[imgKey];
|
||||
});
|
||||
this.content.images = copyImages;
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
getImages() {
|
||||
return this.images;
|
||||
}
|
||||
|
||||
private updateImageProperty<K extends keyof PackImage>(
|
||||
key: string,
|
||||
property: K,
|
||||
value: PackImage[K]
|
||||
) {
|
||||
if (!this.content.images) return;
|
||||
if (this.content.images[key] === undefined) return;
|
||||
this.content.images[key][property] = value;
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
getEmojis() {
|
||||
return this.emoticons;
|
||||
}
|
||||
|
||||
setImageUrl(key: string, url: string) {
|
||||
this.updateImageProperty(key, 'url', url);
|
||||
}
|
||||
getStickers() {
|
||||
return this.stickers;
|
||||
}
|
||||
|
||||
setImageBody(key: string, body?: string) {
|
||||
this.updateImageProperty(key, 'body', body);
|
||||
}
|
||||
getImagesFor(usage: PackUsage) {
|
||||
if (usage === PackUsage.Emoticon) return this.getEmojis();
|
||||
if (usage === PackUsage.Sticker) return this.getStickers();
|
||||
return this.getEmojis();
|
||||
}
|
||||
|
||||
setImageInfo(key: string, info?: IImageInfo) {
|
||||
this.updateImageProperty(key, 'info', info);
|
||||
}
|
||||
getContent() {
|
||||
return this.content;
|
||||
}
|
||||
|
||||
setImageUsage(key: string, usage?: PackUsage[]) {
|
||||
this.updateImageProperty(key, 'usage', usage);
|
||||
}
|
||||
getPackAvatarUrl(usage: PackUsage): string | undefined {
|
||||
return this.avatarUrl || this.getImagesFor(usage)[0].url;
|
||||
}
|
||||
|
||||
private updatePackProperty<K extends keyof PackMeta>(property: K, value: PackMeta[K]) {
|
||||
if (this.content.pack === undefined) {
|
||||
this.content.pack = {};
|
||||
}
|
||||
this.content.pack[property] = value;
|
||||
this.applyPackMeta(this.content);
|
||||
}
|
||||
|
||||
setAvatarUrl(avatarUrl?: string) {
|
||||
this.updatePackProperty('avatar_url', avatarUrl);
|
||||
}
|
||||
|
||||
setDisplayName(displayName?: string) {
|
||||
this.updatePackProperty('display_name', displayName);
|
||||
}
|
||||
|
||||
setAttribution(attribution?: string) {
|
||||
this.updatePackProperty('attribution', attribution);
|
||||
}
|
||||
|
||||
setUsage(usage?: PackUsage[]) {
|
||||
this.updatePackProperty('usage', usage);
|
||||
}
|
||||
|
||||
addImage(key: string, imgContent: PackImage) {
|
||||
this.content.images = {
|
||||
[key]: imgContent,
|
||||
...this.content.images,
|
||||
};
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
|
||||
removeImage(key: string) {
|
||||
if (!this.content.images) return;
|
||||
if (this.content.images[key] === undefined) return;
|
||||
delete this.content.images[key];
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
|
||||
updateImageKey(key: string, newKey: string) {
|
||||
const { images } = this.content;
|
||||
if (!images) return;
|
||||
if (images[key] === undefined) return;
|
||||
const copyImages: PackImages = {};
|
||||
Object.keys(images).forEach((imgKey) => {
|
||||
copyImages[imgKey === key ? newKey : imgKey] = images[imgKey];
|
||||
});
|
||||
this.content.images = copyImages;
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
|
||||
private updateImageProperty<K extends keyof PackImage>(
|
||||
key: string,
|
||||
property: K,
|
||||
value: PackImage[K]
|
||||
) {
|
||||
if (!this.content.images) return;
|
||||
if (this.content.images[key] === undefined) return;
|
||||
this.content.images[key][property] = value;
|
||||
this.applyImages(this.content);
|
||||
}
|
||||
|
||||
setImageUrl(key: string, url: string) {
|
||||
this.updateImageProperty(key, 'url', url);
|
||||
}
|
||||
|
||||
setImageBody(key: string, body?: string) {
|
||||
this.updateImageProperty(key, 'body', body);
|
||||
}
|
||||
|
||||
setImageInfo(key: string, info?: IImageInfo) {
|
||||
this.updateImageProperty(key, 'info', info);
|
||||
}
|
||||
|
||||
setImageUsage(key: string, usage?: PackUsage[]) {
|
||||
this.updateImageProperty(key, 'usage', usage);
|
||||
}
|
||||
}
|
||||
|
||||
export function packEventsToImagePacks(packEvents: MatrixEvent[]): ImagePack[] {
|
||||
return packEvents.reduce<ImagePack[]>((imagePacks, packEvent) => {
|
||||
const packId = packEvent?.getId();
|
||||
const content = packEvent?.getContent() as PackContent | undefined;
|
||||
if (!packId || !content) return imagePacks;
|
||||
const pack = ImagePack.parsePack(packId, content);
|
||||
if (pack) {
|
||||
imagePacks.push(pack);
|
||||
}
|
||||
return imagePacks;
|
||||
}, []);
|
||||
return packEvents.reduce<ImagePack[]>((imagePacks, packEvent) => {
|
||||
const packId = packEvent?.getId();
|
||||
const content = packEvent?.getContent() as PackContent | undefined;
|
||||
if (!packId || !content) return imagePacks;
|
||||
const pack = ImagePack.parsePack(packId, content);
|
||||
if (pack) {
|
||||
imagePacks.push(pack);
|
||||
}
|
||||
return imagePacks;
|
||||
}, []);
|
||||
}
|
||||
|
||||
export function getRoomImagePacks(room: Room): ImagePack[] {
|
||||
const dataEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes);
|
||||
return packEventsToImagePacks(dataEvents);
|
||||
const dataEvents = getStateEvents(room, StateEvent.PoniesRoomEmotes);
|
||||
return packEventsToImagePacks(dataEvents);
|
||||
}
|
||||
|
||||
export function getGlobalImagePacks(mx: MatrixClient): ImagePack[] {
|
||||
const emoteRoomsContent = getAccountData(mx, AccountDataEvent.PoniesEmoteRooms)?.getContent() as
|
||||
| EmoteRoomsContent
|
||||
| undefined;
|
||||
if (typeof emoteRoomsContent !== 'object') return [];
|
||||
const emoteRoomsContent = getAccountData(mx, AccountDataEvent.PoniesEmoteRooms)?.getContent() as
|
||||
| EmoteRoomsContent
|
||||
| undefined;
|
||||
if (typeof emoteRoomsContent !== 'object') return [];
|
||||
|
||||
const { rooms } = emoteRoomsContent;
|
||||
if (typeof rooms !== 'object') return [];
|
||||
const { rooms } = emoteRoomsContent;
|
||||
if (typeof rooms !== 'object') return [];
|
||||
|
||||
const roomIds = Object.keys(rooms);
|
||||
const roomIds = Object.keys(rooms);
|
||||
|
||||
const packs = roomIds.flatMap((roomId) => {
|
||||
if (typeof rooms[roomId] !== 'object') return [];
|
||||
const room = mx.getRoom(roomId);
|
||||
if (!room) return [];
|
||||
const packEventIdToUnknown = rooms[roomId];
|
||||
const roomPacks = getStateEvents(room, StateEvent.PoniesRoomEmotes);
|
||||
const globalPacks = roomPacks.filter((mE) => {
|
||||
const packKey = mE.getStateKey();
|
||||
if (typeof packKey === 'string') return !!packEventIdToUnknown[packKey];
|
||||
return false;
|
||||
const packs = roomIds.flatMap((roomId) => {
|
||||
if (typeof rooms[roomId] !== 'object') return [];
|
||||
const room = mx.getRoom(roomId);
|
||||
if (!room) return [];
|
||||
const packEventIdToUnknown = rooms[roomId];
|
||||
const roomPacks = getStateEvents(room, StateEvent.PoniesRoomEmotes);
|
||||
const globalPacks = roomPacks.filter((mE) => {
|
||||
const packKey = mE.getStateKey();
|
||||
if (typeof packKey === 'string') return !!packEventIdToUnknown[packKey];
|
||||
return false;
|
||||
});
|
||||
return packEventsToImagePacks(globalPacks);
|
||||
});
|
||||
return packEventsToImagePacks(globalPacks);
|
||||
});
|
||||
|
||||
return packs;
|
||||
return packs;
|
||||
}
|
||||
|
||||
export function getUserImagePack(mx: MatrixClient): ImagePack | undefined {
|
||||
const userPackContent = getAccountData(mx, AccountDataEvent.PoniesUserEmotes)?.getContent() as
|
||||
| PackContent
|
||||
| undefined;
|
||||
const userId = mx.getUserId();
|
||||
if (!userPackContent || !userId) {
|
||||
return undefined;
|
||||
}
|
||||
const userPackContent = getAccountData(mx, AccountDataEvent.PoniesUserEmotes)?.getContent() as
|
||||
| PackContent
|
||||
| undefined;
|
||||
const userId = mx.getUserId();
|
||||
if (!userPackContent || !userId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const userImagePack = ImagePack.parsePack(userId, userPackContent);
|
||||
return userImagePack;
|
||||
const userImagePack = ImagePack.parsePack(userId, userPackContent);
|
||||
return userImagePack;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -290,14 +290,14 @@ export function getUserImagePack(mx: MatrixClient): ImagePack | undefined {
|
|||
* @returns {ImagePack[]} packs
|
||||
*/
|
||||
export function getRelevantPacks(mx?: MatrixClient, rooms?: Room[]): ImagePack[] {
|
||||
const userPack = mx && getUserImagePack(mx);
|
||||
const userPacks = userPack ? [userPack] : [];
|
||||
const globalPacks = mx ? getGlobalImagePacks(mx) : [];
|
||||
const globalPackIds = new Set(globalPacks.map((pack) => pack.id));
|
||||
const roomsPack = rooms?.flatMap(getRoomImagePacks) ?? [];
|
||||
const userPack = mx && getUserImagePack(mx);
|
||||
const userPacks = userPack ? [userPack] : [];
|
||||
const globalPacks = mx ? getGlobalImagePacks(mx) : [];
|
||||
const globalPackIds = new Set(globalPacks.map((pack) => pack.id));
|
||||
const roomsPack = rooms?.flatMap(getRoomImagePacks) ?? [];
|
||||
|
||||
return userPacks.concat(
|
||||
globalPacks,
|
||||
roomsPack.filter((pack) => !globalPackIds.has(pack.id))
|
||||
);
|
||||
return userPacks.concat(
|
||||
globalPacks,
|
||||
roomsPack.filter((pack) => !globalPackIds.has(pack.id))
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import { Opts as LinkifyOpts } from 'linkifyjs';
|
|||
import Linkify from 'linkify-react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import * as css from '../styles/CustomHtml.css';
|
||||
import { getMxIdLocalPart, getCanonicalAliasRoomId } from '../utils/matrix';
|
||||
import { getMxIdLocalPart, getCanonicalAliasRoomId, mxcUrlToHttp } from '../utils/matrix';
|
||||
import { getMemberDisplayName } from '../utils/room';
|
||||
import { EMOJI_PATTERN, URL_NEG_LB } from '../utils/regex';
|
||||
import { getHexcodeForEmoji, getShortcodeFor } from './emoji';
|
||||
|
@ -289,7 +289,7 @@ export const getReactCustomHtmlParser = (
|
|||
}
|
||||
|
||||
if (name === 'img') {
|
||||
const htmlSrc = mx.mxcUrlToHttp(props.src);
|
||||
const htmlSrc = mxcUrlToHttp(mx, props.src);
|
||||
if (htmlSrc && props.src.startsWith('mxc://') === false) {
|
||||
return (
|
||||
<a href={htmlSrc} target="_blank" rel="noreferrer noopener">
|
||||
|
|
|
@ -285,3 +285,7 @@ export const removeRoomIdFromMDirect = async (mx: MatrixClient, roomId: string):
|
|||
|
||||
await mx.setAccountData(AccountDataEvent.Direct, userIdToRoomIds);
|
||||
};
|
||||
|
||||
export const mxcUrlToHttp = (mx: MatrixClient, mxcUrl: string, width?: number, height?: number, resizeMethod?: 'crop' | 'scale', doNotAuthenticate?: boolean) => {
|
||||
return mx.mxcUrlToHttp(mxcUrl, width, height, resizeMethod, false, true, !doNotAuthenticate);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue