mirror of
https://github.com/officialdakari/Extera.git
synced 2025-04-11 23:08:46 +02:00
More usage of MD Icons and video calls
This commit is contained in:
parent
7cb1c8ff3d
commit
a5773c3207
59 changed files with 663 additions and 550 deletions
|
@ -4,14 +4,14 @@
|
|||
"officialdakari.ru",
|
||||
"usesarchbtw.lol",
|
||||
"private.coffee",
|
||||
"catgirl.cloud",
|
||||
"secroot.xyz"
|
||||
"matrix.im"
|
||||
],
|
||||
"allowCustomHomeservers": true,
|
||||
"featuredCommunities": {
|
||||
"openAsDefault": false,
|
||||
"spaces": [],
|
||||
"rooms": [
|
||||
"#extera:officialdakari.ru",
|
||||
"#basement:officialdakari.ru"
|
||||
],
|
||||
"servers": [
|
||||
|
|
7
find.js
7
find.js
|
@ -6,13 +6,18 @@ const files = fs.readdirSync('src/', {
|
|||
|
||||
const q = process.argv[2];
|
||||
|
||||
var total = 0;
|
||||
|
||||
for (const f of files) {
|
||||
try {
|
||||
const b = fs.readFileSync(`src/${f}`, 'utf-8');
|
||||
if (b.includes(q) || f.includes(q)) {
|
||||
total ++;
|
||||
console.log(f);
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`${total} files in total`);
|
246
package.json
246
package.json
|
@ -1,124 +1,124 @@
|
|||
{
|
||||
"name": "cinny",
|
||||
"version": "3.2.0",
|
||||
"description": "Yet another matrix client",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "yarn check:eslint && yarn check:prettier",
|
||||
"check:eslint": "eslint src/*",
|
||||
"check:prettier": "prettier --check .",
|
||||
"fix:prettier": "prettier --write .",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Ajay Bura",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "1.1.6",
|
||||
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0",
|
||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3",
|
||||
"@fontsource/inter": "4.5.14",
|
||||
"@matrix-org/olm": "3.2.14",
|
||||
"@mdi/js": "7.4.47",
|
||||
"@mdi/react": "1.6.1",
|
||||
"@tanstack/react-query": "5.24.1",
|
||||
"@tanstack/react-query-devtools": "5.24.1",
|
||||
"@tanstack/react-virtual": "3.2.0",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
"@vanilla-extract/css": "1.9.3",
|
||||
"@vanilla-extract/recipes": "0.3.0",
|
||||
"@vanilla-extract/vite-plugin": "3.7.1",
|
||||
"anafanafo": "2.0.0",
|
||||
"await-to-js": "3.0.0",
|
||||
"badge-maker": "4.0.0",
|
||||
"blurhash": "2.0.4",
|
||||
"browser-encrypt-attachment": "0.3.0",
|
||||
"classnames": "2.3.2",
|
||||
"dateformat": "5.0.3",
|
||||
"dayjs": "1.11.10",
|
||||
"domhandler": "5.0.3",
|
||||
"emojibase": "6.1.0",
|
||||
"emojibase-data": "7.0.1",
|
||||
"file-saver": "2.0.5",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
"folds": "2.0.0",
|
||||
"formik": "2.4.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",
|
||||
"linkify-react": "4.1.3",
|
||||
"linkifyjs": "4.1.3",
|
||||
"marked": "13.0.2",
|
||||
"matrix-js-sdk": "29.1.0",
|
||||
"millify": "6.1.0",
|
||||
"pdfjs-dist": "4.2.67",
|
||||
"prismjs": "1.29.0",
|
||||
"prop-types": "15.8.1",
|
||||
"quill": "2.0.2",
|
||||
"quill-markdown-shortcuts": "0.0.10",
|
||||
"quilljs-markdown": "1.2.0",
|
||||
"react": "18.2.0",
|
||||
"react-aria": "3.29.1",
|
||||
"react-autosize-textarea": "7.1.0",
|
||||
"react-blurhash": "0.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-draggable": "4.4.6",
|
||||
"react-error-boundary": "4.0.13",
|
||||
"react-google-recaptcha": "2.1.0",
|
||||
"react-modal": "3.16.1",
|
||||
"react-quill": "2.0.0",
|
||||
"react-quilljs": "2.0.2",
|
||||
"react-range": "1.8.14",
|
||||
"react-router-dom": "6.20.0",
|
||||
"sanitize-html": "2.12.1",
|
||||
"showdown": "2.1.0",
|
||||
"slate": "0.94.1",
|
||||
"slate-history": "0.93.0",
|
||||
"slate-react": "0.98.4",
|
||||
"tippy.js": "6.3.7",
|
||||
"ua-parser-js": "1.0.35",
|
||||
"url": "0.11.3",
|
||||
"uuid": "10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
|
||||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-wasm": "6.1.1",
|
||||
"@types/file-saver": "2.0.5",
|
||||
"@types/node": "18.11.18",
|
||||
"@types/prismjs": "1.26.0",
|
||||
"@types/react": "18.2.39",
|
||||
"@types/react-dom": "18.2.17",
|
||||
"@types/react-google-recaptcha": "2.1.8",
|
||||
"@types/sanitize-html": "2.9.0",
|
||||
"@types/showdown": "2.0.6",
|
||||
"@types/ua-parser-js": "0.7.36",
|
||||
"@types/uuid": "10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.46.1",
|
||||
"@typescript-eslint/parser": "5.46.1",
|
||||
"@vitejs/plugin-react": "4.2.0",
|
||||
"buffer": "6.0.3",
|
||||
"eslint": "8.29.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.11",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"prettier": "2.8.1",
|
||||
"sass": "1.56.2",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "5.0.13",
|
||||
"vite-plugin-static-copy": "1.0.4",
|
||||
"vite-plugin-top-level-await": "1.4.1"
|
||||
}
|
||||
}
|
||||
"name": "extera",
|
||||
"version": "1.1.0",
|
||||
"description": "Fork of Cinny with new features and slightly different design",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"build": "vite build",
|
||||
"lint": "yarn check:eslint && yarn check:prettier",
|
||||
"check:eslint": "eslint src/*",
|
||||
"check:prettier": "prettier --check .",
|
||||
"fix:prettier": "prettier --write .",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "OfficialDakari",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "1.1.6",
|
||||
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "1.3.0",
|
||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "1.0.3",
|
||||
"@fontsource/inter": "4.5.14",
|
||||
"@matrix-org/olm": "3.2.14",
|
||||
"@mdi/js": "7.4.47",
|
||||
"@mdi/react": "1.6.1",
|
||||
"@tanstack/react-query": "5.24.1",
|
||||
"@tanstack/react-query-devtools": "5.24.1",
|
||||
"@tanstack/react-virtual": "3.2.0",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
"@vanilla-extract/css": "1.9.3",
|
||||
"@vanilla-extract/recipes": "0.3.0",
|
||||
"@vanilla-extract/vite-plugin": "3.7.1",
|
||||
"anafanafo": "2.0.0",
|
||||
"await-to-js": "3.0.0",
|
||||
"badge-maker": "4.0.0",
|
||||
"blurhash": "2.0.4",
|
||||
"browser-encrypt-attachment": "0.3.0",
|
||||
"classnames": "2.3.2",
|
||||
"dateformat": "5.0.3",
|
||||
"dayjs": "1.11.10",
|
||||
"domhandler": "5.0.3",
|
||||
"emojibase": "6.1.0",
|
||||
"emojibase-data": "7.0.1",
|
||||
"file-saver": "2.0.5",
|
||||
"flux": "4.0.3",
|
||||
"focus-trap-react": "10.0.2",
|
||||
"folds": "2.0.0",
|
||||
"formik": "2.4.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",
|
||||
"linkify-react": "4.1.3",
|
||||
"linkifyjs": "4.1.3",
|
||||
"marked": "13.0.2",
|
||||
"matrix-js-sdk": "29.1.0",
|
||||
"millify": "6.1.0",
|
||||
"pdfjs-dist": "4.2.67",
|
||||
"prismjs": "1.29.0",
|
||||
"prop-types": "15.8.1",
|
||||
"quill": "2.0.2",
|
||||
"quill-markdown-shortcuts": "0.0.10",
|
||||
"quilljs-markdown": "1.2.0",
|
||||
"react": "18.2.0",
|
||||
"react-aria": "3.29.1",
|
||||
"react-autosize-textarea": "7.1.0",
|
||||
"react-blurhash": "0.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-draggable": "4.4.6",
|
||||
"react-error-boundary": "4.0.13",
|
||||
"react-google-recaptcha": "2.1.0",
|
||||
"react-modal": "3.16.1",
|
||||
"react-quill": "2.0.0",
|
||||
"react-quilljs": "2.0.2",
|
||||
"react-range": "1.8.14",
|
||||
"react-router-dom": "6.20.0",
|
||||
"sanitize-html": "2.12.1",
|
||||
"showdown": "2.1.0",
|
||||
"slate": "0.94.1",
|
||||
"slate-history": "0.93.0",
|
||||
"slate-react": "0.98.4",
|
||||
"tippy.js": "6.3.7",
|
||||
"ua-parser-js": "1.0.35",
|
||||
"url": "0.11.3",
|
||||
"uuid": "10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
|
||||
"@rollup/plugin-inject": "5.0.3",
|
||||
"@rollup/plugin-wasm": "6.1.1",
|
||||
"@types/file-saver": "2.0.5",
|
||||
"@types/node": "18.11.18",
|
||||
"@types/prismjs": "1.26.0",
|
||||
"@types/react": "18.2.39",
|
||||
"@types/react-dom": "18.2.17",
|
||||
"@types/react-google-recaptcha": "2.1.8",
|
||||
"@types/sanitize-html": "2.9.0",
|
||||
"@types/showdown": "2.0.6",
|
||||
"@types/ua-parser-js": "0.7.36",
|
||||
"@types/uuid": "10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.46.1",
|
||||
"@typescript-eslint/parser": "5.46.1",
|
||||
"@vitejs/plugin-react": "4.2.0",
|
||||
"buffer": "6.0.3",
|
||||
"eslint": "8.29.0",
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-react": "7.31.11",
|
||||
"eslint-plugin-react-hooks": "4.6.0",
|
||||
"prettier": "2.8.1",
|
||||
"sass": "1.56.2",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "5.0.13",
|
||||
"vite-plugin-static-copy": "1.0.4",
|
||||
"vite-plugin-top-level-await": "1.4.1"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import React, { KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect } from 'react';
|
||||
import { Avatar, Icon, Icons, MenuItem, Text } from 'folds';
|
||||
import { Avatar, MenuItem, Text } from 'folds';
|
||||
import { JoinRule, MatrixClient } from 'matrix-js-sdk';
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
|
@ -15,6 +15,8 @@ import { mDirectAtom } from '../../../state/mDirectList';
|
|||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||
import { factoryRoomIdByActivity } from '../../../utils/sort';
|
||||
import { RoomAvatar, RoomIcon } from '../../room-avatar';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiPound } from '@mdi/js';
|
||||
|
||||
type MentionAutoCompleteHandler = (roomAliasOrId: string, name: string) => void;
|
||||
|
||||
|
@ -44,7 +46,7 @@ function UnknownRoomMentionItem({
|
|||
onMouseDown={(evt: any) => { evt.preventDefault() }}
|
||||
before={
|
||||
<Avatar size="200">
|
||||
<Icon src={Icons.Hash} size="100" />
|
||||
<Icon size={0.7} path={mdiPound} />
|
||||
</Avatar>
|
||||
}
|
||||
>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, KeyboardEvent as ReactKeyboardEvent } from 'react';
|
||||
import { Avatar, Icon, Icons, MenuItem, Text } from 'folds';
|
||||
import { Avatar, MenuItem, Text } from 'folds';
|
||||
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
|
||||
|
||||
import { AutocompleteQuery } from './autocompleteQuery';
|
||||
|
@ -16,6 +16,8 @@ import { useKeyDown } from '../../../hooks/useKeyDown';
|
|||
import { getMxIdLocalPart, getMxIdServer, validMxId } from '../../../utils/matrix';
|
||||
import { getMemberDisplayName, getMemberSearchStr } from '../../../utils/room';
|
||||
import { UserAvatar } from '../../user-avatar';
|
||||
import { mdiAccount } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
type MentionAutoCompleteHandler = (userId: string, name: string) => void;
|
||||
|
||||
|
@ -46,7 +48,7 @@ function UnknownMentionItem({
|
|||
<Avatar size="200">
|
||||
<UserAvatar
|
||||
userId={userId}
|
||||
renderFallback={() => <Icon size="50" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={0.7} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
}
|
||||
|
@ -170,7 +172,7 @@ export function UserMentionAutocomplete({
|
|||
userId={roomMember.userId}
|
||||
src={avatarUrl ?? undefined}
|
||||
alt={getName(roomMember)}
|
||||
renderFallback={() => <Icon size="50" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={0.7} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable jsx-a11y/media-has-caption */
|
||||
import React, { ReactNode, useCallback, useRef, useState } from 'react';
|
||||
import { Badge, Chip, Icon, IconButton, Icons, ProgressBar, Spinner, Text, toRem } from 'folds';
|
||||
import { Badge, Chip, IconButton, ProgressBar, Spinner, Text, toRem } from 'folds';
|
||||
import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment';
|
||||
import { Range } from 'react-range';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
|
@ -17,6 +17,8 @@ import {
|
|||
} from '../../../hooks/media';
|
||||
import { useThrottle } from '../../../hooks/useThrottle';
|
||||
import { secondsToMinutesAndSeconds } from '../../../utils/common';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiPause, mdiPlayOutline, mdiVolumeHigh, mdiVolumeMute } from '@mdi/js';
|
||||
|
||||
const PLAY_TIME_THROTTLE_OPS = {
|
||||
wait: 500,
|
||||
|
@ -130,7 +132,7 @@ export function AudioContent({
|
|||
srcState.status === AsyncStatus.Loading || loading ? (
|
||||
<Spinner variant="Secondary" size="50" />
|
||||
) : (
|
||||
<Icon src={playing ? Icons.Pause : Icons.Play} size="50" filled={playing} />
|
||||
<Icon size={0.8} path={playing ? mdiPause : mdiPlayOutline} />
|
||||
)
|
||||
}
|
||||
>
|
||||
|
@ -151,7 +153,7 @@ export function AudioContent({
|
|||
onClick={() => setMute(!mute)}
|
||||
aria-pressed={mute}
|
||||
>
|
||||
<Icon src={mute ? Icons.VolumeMute : Icons.VolumeHigh} size="50" />
|
||||
<Icon size={0.8} path={mute ? mdiVolumeMute : mdiVolumeHigh} />
|
||||
</IconButton>
|
||||
<Range
|
||||
step={0.1}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { Box, Icon, IconSrc } from 'folds';
|
||||
import { Box } from 'folds';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { CompactLayout, ModernLayout } from '..';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
export type EventContentProps = {
|
||||
messageLayout: number;
|
||||
time: ReactNode;
|
||||
iconSrc: IconSrc;
|
||||
iconSrc: string;
|
||||
content: ReactNode;
|
||||
};
|
||||
export function EventContent({ messageLayout, time, iconSrc, content }: EventContentProps) {
|
||||
|
@ -17,7 +18,7 @@ export function EventContent({ messageLayout, time, iconSrc, content }: EventCon
|
|||
alignItems="Center"
|
||||
justifyContent="Center"
|
||||
>
|
||||
<Icon style={{ opacity: 0.6 }} size="50" src={iconSrc} />
|
||||
<Icon style={{ opacity: 0.6 }} size={0.8} path={iconSrc} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { Box, Icon, Icons, Text, as, color, config } from 'folds';
|
||||
import { Box, Text, as, color, config } from 'folds';
|
||||
import React from 'react';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiAlert, mdiDelete, mdiLock, mdiLockAlert } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
const warningStyle = { color: color.Warning.Main, opacity: config.opacity.P300 };
|
||||
const criticalStyle = { color: color.Critical.Main, opacity: config.opacity.P300 };
|
||||
|
@ -8,7 +10,7 @@ const criticalStyle = { color: color.Critical.Main, opacity: config.opacity.P300
|
|||
export const MessageDeletedContent = as<'div', { children?: never; reason?: string }>(
|
||||
({ reason, ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={warningStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Delete} />
|
||||
<Icon size={0.85} path={mdiDelete} />
|
||||
{reason ? (
|
||||
<i>{getText('msg.redacted.reason', reason)}</i>
|
||||
) : (
|
||||
|
@ -20,42 +22,42 @@ export const MessageDeletedContent = as<'div', { children?: never; reason?: stri
|
|||
|
||||
export const MessageUnsupportedContent = as<'div', { children?: never }>(({ ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={criticalStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Warning} />
|
||||
<Icon size={0.85} path={mdiAlert} />
|
||||
<i>{getText('msg.unsupported')}</i>
|
||||
</Box>
|
||||
));
|
||||
|
||||
export const MessageFailedContent = as<'div', { children?: never }>(({ ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={criticalStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Warning} />
|
||||
<Icon size={0.85} path={mdiAlert} />
|
||||
<i>{getText('msg.failed.load')}</i>
|
||||
</Box>
|
||||
));
|
||||
|
||||
export const MessageBadEncryptedContent = as<'div', { children?: never }>(({ ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={warningStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Lock} />
|
||||
<Icon size={0.85} path={mdiLockAlert} />
|
||||
<i>{getText('msg.failed.decrypt')}</i>
|
||||
</Box>
|
||||
));
|
||||
|
||||
export const MessageNotDecryptedContent = as<'div', { children?: never }>(({ ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={warningStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Lock} />
|
||||
<Icon size={0.85} path={mdiLockAlert} />
|
||||
<i>{getText('msg.not_decrypted')}</i>
|
||||
</Box>
|
||||
));
|
||||
|
||||
export const MessageBrokenContent = as<'div', { children?: never }>(({ ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={criticalStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Warning} />
|
||||
<Icon size={0.85} path={mdiAlert} />
|
||||
<i>{getText('msg.broken')}</i>
|
||||
</Box>
|
||||
));
|
||||
|
||||
export const MessageEmptyContent = as<'div', { children?: never }>(({ ...props }, ref) => (
|
||||
<Box as="span" alignItems="Center" gap="100" style={criticalStyle} {...props} ref={ref}>
|
||||
<Icon size="50" src={Icons.Warning} />
|
||||
<Icon size={0.85} path={mdiAlert} />
|
||||
<i>{getText('msg.empty')}</i>
|
||||
</Box>
|
||||
));
|
||||
|
|
|
@ -2,8 +2,6 @@ import React, { ReactNode, useCallback, useState } from 'react';
|
|||
import {
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
Icons,
|
||||
Modal,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
|
@ -32,6 +30,8 @@ import * as css from './style.css';
|
|||
import { HTMLReactParserOptions } from 'html-react-parser';
|
||||
import { RenderBody } from '../RenderBody';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlert, mdiArrowDownBold, mdiArrowRight } from '@mdi/js';
|
||||
|
||||
const renderErrorButton = (retry: () => void, text: string) => (
|
||||
<TooltipProvider
|
||||
|
@ -52,7 +52,7 @@ const renderErrorButton = (retry: () => void, text: string) => (
|
|||
outlined
|
||||
radii="300"
|
||||
onClick={retry}
|
||||
before={<Icon size="100" src={Icons.Warning} filled />}
|
||||
before={<Icon size={1} path={mdiAlert} />}
|
||||
>
|
||||
<Text size="B400" truncate>
|
||||
{text}
|
||||
|
@ -143,7 +143,7 @@ export function ReadTextFile({ body, mimeType, url, encInfo, renderViewer, forma
|
|||
textState.status === AsyncStatus.Loading ? (
|
||||
<Spinner fill="Solid" size="100" variant="Secondary" />
|
||||
) : (
|
||||
<Icon size="100" src={Icons.ArrowRight} filled />
|
||||
<Icon size={1} path={mdiArrowRight} />
|
||||
)
|
||||
}
|
||||
>
|
||||
|
@ -224,7 +224,7 @@ export function ReadPdfFile({ body, mimeType, url, encInfo, renderViewer, format
|
|||
pdfState.status === AsyncStatus.Loading ? (
|
||||
<Spinner fill="Solid" size="100" variant="Secondary" />
|
||||
) : (
|
||||
<Icon size="100" src={Icons.ArrowRight} filled />
|
||||
<Icon size={1} path={mdiArrowRight} />
|
||||
)
|
||||
}
|
||||
>
|
||||
|
@ -278,7 +278,7 @@ export function DownloadFile({ body, mimeType, url, info, encInfo, filename, for
|
|||
downloadState.status === AsyncStatus.Loading ? (
|
||||
<Spinner fill="Soft" size="100" variant="Secondary" />
|
||||
) : (
|
||||
<Icon size="100" src={Icons.Download} filled />
|
||||
<Icon size={1} path={mdiArrowDownBold} />
|
||||
)
|
||||
}
|
||||
>
|
||||
|
|
|
@ -3,8 +3,6 @@ import {
|
|||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
Icons,
|
||||
Modal,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
|
@ -30,6 +28,8 @@ 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';
|
||||
|
||||
type RenderViewerProps = {
|
||||
src: string;
|
||||
|
@ -152,7 +152,7 @@ export const ImageContent = as<'div', ImageContentProps>(
|
|||
radii="300"
|
||||
size="300"
|
||||
onClick={loadSrc}
|
||||
before={<Icon size="Inherit" src={Icons.Photo} filled />}
|
||||
before={<Icon size={1} path={mdiImage} />}
|
||||
>
|
||||
<Text size="B300">{getText('btn.view')}</Text>
|
||||
</Button>
|
||||
|
@ -197,7 +197,7 @@ export const ImageContent = as<'div', ImageContentProps>(
|
|||
outlined
|
||||
radii="300"
|
||||
onClick={handleRetry}
|
||||
before={<Icon size="Inherit" src={Icons.Warning} filled />}
|
||||
before={<Icon size={1} path={mdiAlert} />}
|
||||
>
|
||||
<Text size="B300">{getText('btn.retry')}</Text>
|
||||
</Button>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Box, Icon, Icons, MenuItem, Text, as, color, config } from 'folds';
|
||||
import { Box, MenuItem, Text, as, color, config } from 'folds';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import * as css from './style.css';
|
||||
import ProgressBar from '../../progressbar';
|
||||
|
|
|
@ -3,8 +3,6 @@ import {
|
|||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
Icons,
|
||||
Spinner,
|
||||
Text,
|
||||
Tooltip,
|
||||
|
@ -26,6 +24,8 @@ import { getFileSrcUrl } from './util';
|
|||
import { bytesToSize } from '../../../../util/common';
|
||||
import { millisecondsToMinutesAndSeconds } from '../../../utils/common';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlert, mdiPlay } from '@mdi/js';
|
||||
|
||||
type RenderVideoProps = {
|
||||
title: string;
|
||||
|
@ -115,7 +115,7 @@ export const VideoContent = as<'div', VideoContentProps>(
|
|||
radii="300"
|
||||
size="300"
|
||||
onClick={loadSrc}
|
||||
before={<Icon size="Inherit" src={Icons.Play} filled />}
|
||||
before={<Icon size={1} path={mdiPlay} />}
|
||||
>
|
||||
<Text size="B300">{getText('btn.watch')}</Text>
|
||||
</Button>
|
||||
|
@ -159,7 +159,7 @@ export const VideoContent = as<'div', VideoContentProps>(
|
|||
outlined
|
||||
radii="300"
|
||||
onClick={handleRetry}
|
||||
before={<Icon size="Inherit" src={Icons.Warning} filled />}
|
||||
before={<Icon size={1} path={mdiAlert} />}
|
||||
>
|
||||
<Text size="B300">{getText('btn.retry')}</Text>
|
||||
</Button>
|
||||
|
|
|
@ -4,8 +4,6 @@ import {
|
|||
Badge,
|
||||
Box,
|
||||
Chip,
|
||||
Icon,
|
||||
Icons,
|
||||
Line,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
|
@ -40,6 +38,8 @@ 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';
|
||||
|
||||
type RoomJoinButtonProps = {
|
||||
roomId: string;
|
||||
|
@ -70,15 +70,14 @@ function RoomJoinButton({ roomId, via }: RoomJoinButtonProps) {
|
|||
}
|
||||
>
|
||||
{(triggerRef) => (
|
||||
<Icon
|
||||
ref={triggerRef}
|
||||
style={{ color: color.Critical.Main, cursor: 'pointer' }}
|
||||
src={Icons.Warning}
|
||||
size="400"
|
||||
filled
|
||||
tabIndex={0}
|
||||
aria-label={joinState.error.data?.error || joinState.error.message}
|
||||
/>
|
||||
<span ref={triggerRef}>
|
||||
<Icon
|
||||
style={{ color: color.Critical.Main, cursor: 'pointer' }}
|
||||
path={mdiAlert}
|
||||
size={1}
|
||||
aria-label={joinState.error.data?.error || joinState.error.message}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</TooltipProvider>
|
||||
)}
|
||||
|
@ -88,7 +87,7 @@ function RoomJoinButton({ roomId, via }: RoomJoinButtonProps) {
|
|||
size="400"
|
||||
radii="Pill"
|
||||
before={
|
||||
canJoin ? <Icon src={Icons.Plus} size="50" /> : <Spinner variant="Secondary" size="100" />
|
||||
canJoin ? <Icon size={0.8} path={mdiPlus} /> : <Spinner variant="Secondary" size="100" />
|
||||
}
|
||||
onClick={join}
|
||||
disabled={!canJoin}
|
||||
|
@ -381,7 +380,7 @@ export const RoomItemCard = as<'div', RoomItemCardProps>(
|
|||
radii="Pill"
|
||||
aria-label="Open Room"
|
||||
>
|
||||
<Icon size="50" src={Icons.ArrowRight} />
|
||||
<Icon size={0.8} path={mdiArrowRight} />
|
||||
</Chip>
|
||||
</Box>
|
||||
) : (
|
||||
|
|
|
@ -4,8 +4,6 @@ import {
|
|||
Avatar,
|
||||
Text,
|
||||
Chip,
|
||||
Icon,
|
||||
Icons,
|
||||
as,
|
||||
Badge,
|
||||
toRem,
|
||||
|
@ -35,6 +33,8 @@ import { ErrorCode } from '../../cs-errorcode';
|
|||
import { useDraggableItem } from './DnD';
|
||||
import { openCreateRoom, openSpaceAddExisting } from '../../../client/action/navigation';
|
||||
import { getText } from '../../../lang';
|
||||
import { mdiChevronDown, mdiChevronRight, mdiPlus } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
function SpaceProfileLoading() {
|
||||
return (
|
||||
|
@ -145,7 +145,7 @@ function UnknownSpaceProfile({
|
|||
</Avatar>
|
||||
}
|
||||
after={
|
||||
canJoin ? <Icon src={Icons.Plus} size="50" /> : <Spinner variant="Secondary" size="200" />
|
||||
canJoin ? <Icon size={0.8} path={mdiPlus} /> : <Spinner variant="Secondary" size="200" />
|
||||
}
|
||||
>
|
||||
<Box alignItems="Center" gap="200">
|
||||
|
@ -208,7 +208,7 @@ function SpaceProfile({
|
|||
/>
|
||||
</Avatar>
|
||||
}
|
||||
after={<Icon src={closed ? Icons.ChevronRight : Icons.ChevronBottom} size="50" />}
|
||||
after={<Icon size={0.8} path={closed ? mdiChevronRight : mdiChevronDown} />}
|
||||
>
|
||||
<Box alignItems="Center" gap="200">
|
||||
<Text size="H4" truncate>
|
||||
|
@ -237,7 +237,7 @@ function RootSpaceProfile({ closed, categoryId, handleClose }: RootSpaceProfileP
|
|||
className={css.HeaderChip}
|
||||
variant="Surface"
|
||||
size="500"
|
||||
after={<Icon src={closed ? Icons.ChevronRight : Icons.ChevronBottom} size="50" />}
|
||||
after={<Icon size={0.8} path={closed ? mdiChevronRight : mdiChevronDown} />}
|
||||
>
|
||||
<Box alignItems="Center" gap="200">
|
||||
<Text size="H4" truncate>
|
||||
|
@ -300,7 +300,7 @@ function AddRoomButton({ item }: { item: HierarchyItem }) {
|
|||
<Chip
|
||||
variant="Primary"
|
||||
radii="Pill"
|
||||
before={<Icon src={Icons.Plus} size="50" />}
|
||||
before={<Icon size={0.8} path={mdiPlus} />}
|
||||
onClick={handleAddRoom}
|
||||
aria-pressed={!!cords}
|
||||
>
|
||||
|
@ -361,7 +361,7 @@ function AddSpaceButton({ item }: { item: HierarchyItem }) {
|
|||
<Chip
|
||||
variant="SurfaceVariant"
|
||||
radii="Pill"
|
||||
before={<Icon src={Icons.Plus} size="50" />}
|
||||
before={<Icon size={0.8} path={mdiPlus} />}
|
||||
onClick={handleAddSpace}
|
||||
aria-pressed={!!cords}
|
||||
>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { RefObject, useEffect, useMemo, useRef } from 'react';
|
||||
import { Text, Box, Icon, Icons, config, Spinner, IconButton, Line, toRem } from 'folds';
|
||||
import { Text, Box, config, Spinner, IconButton, Line, toRem } from 'folds';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
|
@ -24,6 +24,8 @@ import { SearchInput } from './SearchInput';
|
|||
import { SearchFilters } from './SearchFilters';
|
||||
import { VirtualTile } from '../../components/virtualizer';
|
||||
import { getText, translate } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlertCircleOutline, mdiChevronUp, mdiMessageOutline } from '@mdi/js';
|
||||
|
||||
const useSearchPathSearchParams = (searchParams: URLSearchParams): _SearchPathSearchParams =>
|
||||
useMemo(
|
||||
|
@ -196,7 +198,7 @@ export function MessageSearch({
|
|||
size="300"
|
||||
aria-label={getText('aria.scroll_to_top')}
|
||||
>
|
||||
<Icon src={Icons.ChevronTop} size="300" />
|
||||
<Icon size={0.8} path={mdiChevronUp} />
|
||||
</IconButton>
|
||||
</ScrollTopContainer>
|
||||
<Box ref={scrollTopAnchorRef} direction="Column" gap="300">
|
||||
|
@ -235,7 +237,7 @@ export function MessageSearch({
|
|||
>
|
||||
<PageHeroSection>
|
||||
<PageHero
|
||||
icon={<Icon size="600" src={Icons.Message} />}
|
||||
icon={<Icon size={0.8} path={mdiMessageOutline} />}
|
||||
title={getText('msg_search.title.2')}
|
||||
subTitle={getText('msg_search.subtitle.2')}
|
||||
/>
|
||||
|
@ -250,7 +252,7 @@ export function MessageSearch({
|
|||
alignItems="Center"
|
||||
gap="200"
|
||||
>
|
||||
<Icon size="200" src={Icons.Info} />
|
||||
<Icon size={0.8} path={mdiAlertCircleOutline} />
|
||||
<Text>
|
||||
{translate('generic.no_results', <b>{`"${msgSearchParams.term}"`}</b>)}
|
||||
</Text>
|
||||
|
|
|
@ -10,8 +10,6 @@ import {
|
|||
Box,
|
||||
Chip,
|
||||
Text,
|
||||
Icon,
|
||||
Icons,
|
||||
Line,
|
||||
config,
|
||||
PopOut,
|
||||
|
@ -25,7 +23,7 @@ import {
|
|||
Badge,
|
||||
RectCords,
|
||||
} from 'folds';
|
||||
import { SearchOrderBy } from 'matrix-js-sdk';
|
||||
import { JoinRule, SearchOrderBy } from 'matrix-js-sdk';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
|
@ -39,6 +37,8 @@ import {
|
|||
import { DebounceOptions, useDebounce } from '../../hooks/useDebounce';
|
||||
import { VirtualTile } from '../../components/virtualizer';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiCheck, mdiClose, mdiMessageLockOutline, mdiMessageOutline, mdiPlusCircleOutline, mdiSort } from '@mdi/js';
|
||||
|
||||
type OrderButtonProps = {
|
||||
order?: string;
|
||||
|
@ -101,7 +101,7 @@ function OrderButton({ order, onChange }: OrderButtonProps) {
|
|||
<Chip
|
||||
variant="SurfaceVariant"
|
||||
radii="Pill"
|
||||
after={<Icon size="50" src={Icons.Sort} />}
|
||||
after={<Icon size={0.8} path={mdiSort} />}
|
||||
onClick={handleOpenMenu}
|
||||
>
|
||||
{<Text size="T200">{getText(rankOrder ? 'sort.relevance' : 'sort.recent')}</Text>}
|
||||
|
@ -271,9 +271,11 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto
|
|||
aria-pressed={selected}
|
||||
before={
|
||||
<Icon
|
||||
size="50"
|
||||
src={
|
||||
joinRuleToIconSrc(Icons, room.getJoinRule(), false) ?? Icons.Hash
|
||||
size={0.8}
|
||||
path={
|
||||
room.getJoinRule() !== JoinRule.Public ?
|
||||
mdiMessageLockOutline :
|
||||
mdiMessageOutline
|
||||
}
|
||||
/>
|
||||
}
|
||||
|
@ -317,7 +319,7 @@ function SelectRoomButton({ roomList, selectedRooms, onChange }: SelectRoomButto
|
|||
onClick={handleOpenMenu}
|
||||
variant="SurfaceVariant"
|
||||
radii="Pill"
|
||||
before={<Icon size="100" src={Icons.PlusCircle} />}
|
||||
before={<Icon size={0.8} path={mdiPlusCircleOutline} />}
|
||||
>
|
||||
<Text size="T200">{getText('search_filters.select_rooms')}</Text>
|
||||
</Chip>
|
||||
|
@ -356,7 +358,7 @@ export function SearchFilters({
|
|||
<Chip
|
||||
variant={!global ? 'Success' : 'Surface'}
|
||||
aria-pressed={!global}
|
||||
before={!global && <Icon size="100" src={Icons.Check} />}
|
||||
before={!global && <Icon size={0.8} path={mdiCheck} />}
|
||||
outlined
|
||||
onClick={() => onGlobalChange()}
|
||||
>
|
||||
|
@ -366,7 +368,7 @@ export function SearchFilters({
|
|||
<Chip
|
||||
variant={global ? 'Success' : 'Surface'}
|
||||
aria-pressed={global}
|
||||
before={global && <Icon size="100" src={Icons.Check} />}
|
||||
before={global && <Icon size={0.8} path={mdiCheck} />}
|
||||
outlined
|
||||
onClick={() => onGlobalChange(true)}
|
||||
>
|
||||
|
@ -391,11 +393,15 @@ export function SearchFilters({
|
|||
radii="Pill"
|
||||
before={
|
||||
<Icon
|
||||
size="50"
|
||||
src={joinRuleToIconSrc(Icons, room.getJoinRule(), false) ?? Icons.Hash}
|
||||
size={0.8}
|
||||
path={
|
||||
room.getJoinRule() !== JoinRule.Public ?
|
||||
mdiMessageLockOutline :
|
||||
mdiMessageOutline
|
||||
}
|
||||
/>
|
||||
}
|
||||
after={<Icon size="50" src={Icons.Cross} />}
|
||||
after={<Icon size={0.8} path={mdiClose} />}
|
||||
>
|
||||
<Text size="T200">{room.name}</Text>
|
||||
</Chip>
|
||||
|
|
|
@ -1,67 +1,69 @@
|
|||
import React, { FormEventHandler, RefObject } from 'react';
|
||||
import { Box, Text, Input, Icon, Icons, Spinner, Chip, config } from 'folds';
|
||||
import { Box, Text, Input, Spinner, Chip, config } from 'folds';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiClose, mdiMagnify } from '@mdi/js';
|
||||
|
||||
type SearchProps = {
|
||||
active?: boolean;
|
||||
loading?: boolean;
|
||||
searchInputRef: RefObject<HTMLInputElement>;
|
||||
onSearch: (term: string) => void;
|
||||
onReset: () => void;
|
||||
active?: boolean;
|
||||
loading?: boolean;
|
||||
searchInputRef: RefObject<HTMLInputElement>;
|
||||
onSearch: (term: string) => void;
|
||||
onReset: () => void;
|
||||
};
|
||||
export function SearchInput({ active, loading, searchInputRef, onSearch, onReset }: SearchProps) {
|
||||
const handleSearchSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
|
||||
evt.preventDefault();
|
||||
const { searchInput } = evt.target as HTMLFormElement & {
|
||||
searchInput: HTMLInputElement;
|
||||
const handleSearchSubmit: FormEventHandler<HTMLFormElement> = (evt) => {
|
||||
evt.preventDefault();
|
||||
const { searchInput } = evt.target as HTMLFormElement & {
|
||||
searchInput: HTMLInputElement;
|
||||
};
|
||||
|
||||
const searchTerm = searchInput.value.trim() || undefined;
|
||||
if (searchTerm) {
|
||||
onSearch(searchTerm);
|
||||
}
|
||||
};
|
||||
|
||||
const searchTerm = searchInput.value.trim() || undefined;
|
||||
if (searchTerm) {
|
||||
onSearch(searchTerm);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box as="form" direction="Column" gap="100" onSubmit={handleSearchSubmit}>
|
||||
<span data-spacing-node />
|
||||
<Text size="L400">{getText('search_input.header')}</Text>
|
||||
<Input
|
||||
ref={searchInputRef}
|
||||
style={{ paddingRight: config.space.S300 }}
|
||||
name="searchInput"
|
||||
size="500"
|
||||
variant="Background"
|
||||
placeholder={getText('placeholder.search_input')}
|
||||
autoComplete="off"
|
||||
before={
|
||||
active && loading ? (
|
||||
<Spinner variant="Secondary" size="200" />
|
||||
) : (
|
||||
<Icon size="200" src={Icons.Search} />
|
||||
)
|
||||
}
|
||||
after={
|
||||
active ? (
|
||||
<Chip
|
||||
key="resetButton"
|
||||
type="reset"
|
||||
variant="Secondary"
|
||||
size="400"
|
||||
radii="Pill"
|
||||
outlined
|
||||
after={<Icon size="50" src={Icons.Cross} />}
|
||||
onClick={onReset}
|
||||
>
|
||||
<Text size="B300">{getText('btn.search.clear')}</Text>
|
||||
</Chip>
|
||||
) : (
|
||||
<Chip type="submit" variant="Primary" size="400" radii="Pill" outlined>
|
||||
<Text size="B300">{getText('search_input.clear')}</Text>
|
||||
</Chip>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
return (
|
||||
<Box as="form" direction="Column" gap="100" onSubmit={handleSearchSubmit}>
|
||||
<span data-spacing-node />
|
||||
<Text size="L400">{getText('search_input.header')}</Text>
|
||||
<Input
|
||||
ref={searchInputRef}
|
||||
style={{ paddingRight: config.space.S300 }}
|
||||
name="searchInput"
|
||||
size="500"
|
||||
variant="Background"
|
||||
placeholder={getText('placeholder.search_input')}
|
||||
autoComplete="off"
|
||||
before={
|
||||
active && loading ? (
|
||||
<Spinner variant="Secondary" size="200" />
|
||||
) : (
|
||||
<Icon size={1} path={mdiMagnify} />
|
||||
)
|
||||
}
|
||||
after={
|
||||
active ? (
|
||||
<Chip
|
||||
key="resetButton"
|
||||
type="reset"
|
||||
variant="Secondary"
|
||||
size="400"
|
||||
radii="Pill"
|
||||
outlined
|
||||
after={<Icon size={1} path={mdiClose} />}
|
||||
onClick={onReset}
|
||||
>
|
||||
<Text size="B300">{getText('btn.search.clear')}</Text>
|
||||
</Chip>
|
||||
) : (
|
||||
<Chip type="submit" variant="Primary" size="400" radii="Pill" outlined>
|
||||
<Text size="B300">{getText('search_input.clear')}</Text>
|
||||
</Chip>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import React, { MouseEventHandler, useMemo } from 'react';
|
||||
import { IEventWithRoomId, JoinRule, RelationType, Room } from 'matrix-js-sdk';
|
||||
import { HTMLReactParserOptions } from 'html-react-parser';
|
||||
import { Avatar, Box, Chip, Header, Icon, Icons, Text, config } from 'folds';
|
||||
import { Avatar, Box, Chip, Header, Text, config } from 'folds';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import {
|
||||
getReactCustomHtmlParser,
|
||||
|
@ -34,6 +34,8 @@ import { SequenceCard } from '../../components/sequence-card';
|
|||
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
|
||||
import { UserAvatar } from '../../components/user-avatar';
|
||||
import { getText, translate } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAccount } from '@mdi/js';
|
||||
|
||||
type SearchResultGroupProps = {
|
||||
room: Room;
|
||||
|
@ -215,7 +217,7 @@ export function SearchResultGroup({
|
|||
: undefined
|
||||
}
|
||||
alt={displayName}
|
||||
renderFallback={() => <Icon size="200" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import React from 'react';
|
||||
import { as, Chip, Icon, Icons, Text } from 'folds';
|
||||
import { as, Chip, Text } from 'folds';
|
||||
import classNames from 'classnames';
|
||||
import * as css from './styles.css';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiChevronDown, mdiChevronRight } from '@mdi/js';
|
||||
|
||||
export const RoomNavCategoryButton = as<'button', { closed?: boolean }>(
|
||||
({ className, closed, children, ...props }, ref) => (
|
||||
|
@ -12,8 +14,8 @@ export const RoomNavCategoryButton = as<'button', { closed?: boolean }>(
|
|||
before={
|
||||
<Icon
|
||||
className={css.CategoryButtonIcon}
|
||||
size="50"
|
||||
src={closed ? Icons.ChevronRight : Icons.ChevronBottom}
|
||||
size={1}
|
||||
path={closed ? mdiChevronRight : mdiChevronDown}
|
||||
/>
|
||||
}
|
||||
{...props}
|
||||
|
|
|
@ -3,9 +3,7 @@ import { Room } from 'matrix-js-sdk';
|
|||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Text,
|
||||
Menu,
|
||||
MenuItem,
|
||||
|
@ -42,6 +40,8 @@ import { allRoomsAtom } from '../../state/room-list/roomList';
|
|||
import { useDirects } from '../../state/hooks/roomList';
|
||||
import { usePresences } from '../../hooks/usePresences';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAccountPlus, mdiArrowLeft, mdiBellCancel, mdiCheckAll, mdiCog, mdiDotsVertical, mdiLinkVariant } from '@mdi/js';
|
||||
|
||||
type RoomNavItemMenuProps = {
|
||||
room: Room;
|
||||
|
@ -83,7 +83,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<Icon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
disabled={!unread}
|
||||
>
|
||||
|
@ -99,7 +99,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
|||
variant="Primary"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.UserPlus} />}
|
||||
after={<Icon size={1} path={mdiAccountPlus} />}
|
||||
radii="300"
|
||||
disabled={!canInvite}
|
||||
>
|
||||
|
@ -110,7 +110,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleCopyLink}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Link} />}
|
||||
after={<Icon size={1} path={mdiLinkVariant} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -120,7 +120,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleRoomSettings}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Setting} />}
|
||||
after={<Icon size={1} path={mdiCog} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -138,7 +138,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
|||
variant="Critical"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.ArrowGoLeft} />}
|
||||
after={<Icon size={1} path={mdiArrowLeft} />}
|
||||
radii="300"
|
||||
aria-pressed={promptLeave}
|
||||
>
|
||||
|
@ -303,7 +303,7 @@ export function RoomNavItem({
|
|||
<UnreadBadge highlight={unread.highlight > 0} count={unread.total} />
|
||||
</UnreadBadgeCenter>
|
||||
)}
|
||||
{muted && !optionsVisible && <Icon size="50" src={Icons.BellMute} />}
|
||||
{muted && !optionsVisible && <Icon size={1} path={mdiBellCancel} />}
|
||||
</Box>
|
||||
</NavItemContent>
|
||||
</NavLink>
|
||||
|
@ -342,7 +342,7 @@ export function RoomNavItem({
|
|||
size="300"
|
||||
radii="300"
|
||||
>
|
||||
<Icon size="50" src={Icons.VerticalDots} />
|
||||
<Icon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
</NavItemOptions>
|
||||
|
|
|
@ -14,9 +14,7 @@ import {
|
|||
Chip,
|
||||
ContainerColor,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Input,
|
||||
Menu,
|
||||
MenuItem,
|
||||
|
@ -58,6 +56,8 @@ import { UserAvatar } from '../../components/user-avatar';
|
|||
import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers';
|
||||
import { usePresences } from '../../hooks/usePresences';
|
||||
import { getText } from '../../../lang';
|
||||
import { mdiAccount, mdiChevronUp, mdiClose, mdiFilterOutline, mdiMagnify, mdiSort } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
export const MembershipFilters = {
|
||||
filterJoined: (m: RoomMember) => m.membership === Membership.Join,
|
||||
|
@ -317,7 +317,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
variant="Background"
|
||||
onClick={() => setPeopleDrawer(false)}
|
||||
>
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
)}
|
||||
</TooltipProvider>
|
||||
|
@ -380,7 +380,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
variant={membershipFilter.color}
|
||||
size="400"
|
||||
radii="300"
|
||||
before={<Icon src={Icons.Filter} size="50" />}
|
||||
before={<Icon size={1} path={mdiFilterOutline} />}
|
||||
>
|
||||
<Text size="T200">{membershipFilter.name}</Text>
|
||||
</Chip>
|
||||
|
@ -434,7 +434,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
variant="Background"
|
||||
size="400"
|
||||
radii="300"
|
||||
after={<Icon src={Icons.Sort} size="50" />}
|
||||
after={<Icon size={1} path={mdiSort} />}
|
||||
>
|
||||
<Text size="T200">{sortFilter.name}</Text>
|
||||
</Chip>
|
||||
|
@ -451,7 +451,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
variant="Surface"
|
||||
size="400"
|
||||
radii="400"
|
||||
before={<Icon size="50" src={Icons.Search} />}
|
||||
before={<Icon size={1} path={mdiMagnify} />}
|
||||
after={
|
||||
result && (
|
||||
<Chip
|
||||
|
@ -466,7 +466,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
}
|
||||
resetSearch();
|
||||
}}
|
||||
after={<Icon size="50" src={Icons.Cross} />}
|
||||
after={<Icon size={1} path={mdiClose} />}
|
||||
>
|
||||
<Text size="B300">{result.items.length ? getText('generic.result_count', result.items.length) : getText('generic.no_results.2')}</Text>
|
||||
</Chip>
|
||||
|
@ -485,7 +485,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
size="300"
|
||||
aria-label={getText('aria.scroll_to_top')}
|
||||
>
|
||||
<Icon src={Icons.ChevronTop} size="300" />
|
||||
<Icon size={1} path={mdiChevronUp} />
|
||||
</IconButton>
|
||||
</ScrollTopContainer>
|
||||
|
||||
|
@ -552,7 +552,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
userId={member.userId}
|
||||
src={avatarUrl ?? undefined}
|
||||
alt={name}
|
||||
renderFallback={() => <Icon size="50" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
}
|
||||
|
|
|
@ -62,5 +62,6 @@ export const UserAvatar = style({
|
|||
|
||||
export const VideoFeed = style({
|
||||
maxWidth: '400px',
|
||||
maxHeight: '400px'
|
||||
maxHeight: '400px',
|
||||
borderRadius: config.radii.R300
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { Avatar, Box, Icon, IconButton, Icons, Text } from "folds";
|
||||
import { Avatar, Box, IconButton, Text } from "folds";
|
||||
import { CallEvent, Room, User } from "matrix-js-sdk";
|
||||
|
||||
import * as css from './RoomCall.css';
|
||||
|
@ -10,8 +10,8 @@ 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 as MDIIcon } from '@mdi/react';
|
||||
import { mdiMicrophone, mdiMicrophoneOff, mdiPhone, mdiPhoneHangup } from '@mdi/js';
|
||||
import Icon, { Icon as MDIcon } from '@mdi/react';
|
||||
import { mdiAccount, mdiCamera, mdiCameraOff, mdiMicrophone, mdiMicrophoneOff, mdiPhone, mdiPhoneHangup, mdiVideo, mdiVideoOff } from '@mdi/js';
|
||||
import { translate } from '../../../lang';
|
||||
|
||||
// TODO refactor
|
||||
|
@ -42,9 +42,10 @@ type RoomCallProps = {
|
|||
call: MatrixCall;
|
||||
onHangup: () => void;
|
||||
invitation?: boolean;
|
||||
video?: boolean;
|
||||
};
|
||||
|
||||
export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
||||
export function RoomCall({ room, call, onHangup, invitation, video }: RoomCallProps) {
|
||||
const mx = useMatrixClient();
|
||||
const mxId = mx.getUserId();
|
||||
if (typeof mxId !== 'string') return null;
|
||||
|
@ -63,9 +64,13 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
const [recipientShowVideo, setRecipientShowVideo] = useState(false);
|
||||
const recipientVideoRef = useRef<HTMLVideoElement>(null);
|
||||
|
||||
const [localShowVideo, setLocalShowVideo] = useState(false);
|
||||
const localVideoRef = useRef<HTMLVideoElement>(null);
|
||||
|
||||
const ringtoneRef = useRef<HTMLAudioElement>(null);
|
||||
|
||||
const [isMuted, setMuted] = useState(false);
|
||||
const [isVideoMuted, setVideoMuted] = useState(false);
|
||||
|
||||
const handleHang = useCallback(() => {
|
||||
console.debug(`hanging up`, call);
|
||||
|
@ -89,6 +94,18 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
setMuted(newState);
|
||||
}, []);
|
||||
|
||||
const handleVideoMute = useCallback(async () => {
|
||||
if (!call) {
|
||||
console.debug('No call, dont handling mute');
|
||||
return;
|
||||
}
|
||||
|
||||
const newState = !call.isLocalVideoMuted();
|
||||
|
||||
call.setLocalVideoMuted(newState);
|
||||
setVideoMuted(newState);
|
||||
}, []);
|
||||
|
||||
const handleReject = useCallback(async () => {
|
||||
if (!call) return;
|
||||
|
||||
|
@ -105,26 +122,50 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
if (!call) return;
|
||||
|
||||
await call.answer(true, false);
|
||||
if (video) {
|
||||
call.setLocalVideoMuted(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleVideoAccept = useCallback(async () => {
|
||||
if (!call) return;
|
||||
|
||||
await call.answer(true, true);
|
||||
}, []);
|
||||
|
||||
console.debug(`Rerendering RoomCall`);
|
||||
|
||||
call.on(CallEvent.FeedsChanged, (feeds: CallFeed[]) => {
|
||||
feeds.forEach(feed => {
|
||||
if (!feed.isLocal()) {
|
||||
const remoteStream = feed.stream;
|
||||
const remoteStream = feed.stream;
|
||||
if (feed.isLocal()) {
|
||||
if (!feed.isVideoMuted()) {
|
||||
setLocalShowVideo(true);
|
||||
setTimeout(() => {
|
||||
if (localVideoRef.current) {
|
||||
localVideoRef.current.srcObject = remoteStream;
|
||||
localVideoRef.current.play().catch(console.error);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
} else {
|
||||
console.debug(`REMOTE FEED!!!`, feed);
|
||||
if (feed.hasAudioTrack) {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.srcObject = remoteStream;
|
||||
audioRef.current.play().catch(console.error);
|
||||
}
|
||||
} else {
|
||||
if (recipientVideoRef.current) {
|
||||
recipientVideoRef.current.srcObject = remoteStream;
|
||||
recipientVideoRef.current.play().catch(console.error);
|
||||
setRecipientShowVideo(true);
|
||||
}
|
||||
}
|
||||
if (!feed.isVideoMuted()) {
|
||||
setRecipientShowVideo(true);
|
||||
setTimeout(() => {
|
||||
if (recipientVideoRef.current) {
|
||||
recipientVideoRef.current.srcObject = remoteStream;
|
||||
recipientVideoRef.current.play().catch(console.error);
|
||||
} else {
|
||||
console.error(`NO RECIPIENT VIDEO REF!!!!!!! CRITICAL ERROR`);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -162,23 +203,24 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
<Box grow='Yes' direction='Row'>
|
||||
<div className={css.UsersDiv}>
|
||||
<div className={css.UserAvatarBox}>
|
||||
<AvatarBase className={css.UserAvatar}>
|
||||
<Avatar
|
||||
style={userStyle}
|
||||
>
|
||||
<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="200" src={Icons.User} filled />}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
<video controls={false} autoPlay className={css.VideoFeed} style={{ display: localShowVideo ? 'block' : 'none' }} ref={localVideoRef} />
|
||||
{!localShowVideo && (
|
||||
<AvatarBase className={css.UserAvatar}>
|
||||
<Avatar
|
||||
style={userStyle}
|
||||
>
|
||||
<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} />}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
)}
|
||||
</div>
|
||||
<div className={css.UserAvatarBox}>
|
||||
{recipientShowVideo && (
|
||||
<video controls={false} autoPlay ref={recipientVideoRef} />
|
||||
)}
|
||||
<video controls={false} autoPlay className={css.VideoFeed} style={{ display: recipientShowVideo ? 'block' : 'none' }} ref={recipientVideoRef} />
|
||||
{!recipientShowVideo && (
|
||||
<AvatarBase className={css.UserAvatar}>
|
||||
<Avatar
|
||||
|
@ -188,7 +230,7 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
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="200" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
|
@ -197,17 +239,20 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
</div>
|
||||
</Box>
|
||||
<Box className={css.CallControlsContainer} grow='No' direction='Row'>
|
||||
<IconButton variant='SurfaceVariant' onClick={handleVideoMute} aria-pressed={isVideoMuted}>
|
||||
<MDIcon path={isVideoMuted ? mdiVideoOff : mdiVideo} size={1} />
|
||||
</IconButton>
|
||||
<IconButton variant='SurfaceVariant' onClick={handleMute} aria-pressed={isMuted}>
|
||||
<MDIIcon path={isMuted ? mdiMicrophoneOff : mdiMicrophone} size={1} />
|
||||
<MDIcon path={isMuted ? mdiMicrophoneOff : mdiMicrophone} size={1} />
|
||||
</IconButton>
|
||||
<IconButton variant='Critical' onClick={handleHang}>
|
||||
<MDIIcon path={mdiPhoneHangup} size={1} />
|
||||
<MDIcon path={mdiPhoneHangup} size={1} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
{
|
||||
[CallState.Ringing, CallState.InviteSent, CallState.Connecting].includes(call.state) &&
|
||||
[CallState.InviteSent, CallState.Connecting].includes(call.state) &&
|
||||
(
|
||||
<audio
|
||||
src='https://officialdakari.ru/_matrix/media/r0/download/officialdakari.ru/rAiqpTddZoUUhcBVjPQORWJb'
|
||||
|
@ -227,18 +272,30 @@ export function RoomCall({ room, call, onHangup, invitation }: RoomCallProps) {
|
|||
/>
|
||||
<div className={css.UsersDiv}>
|
||||
<Text priority='400' size='H3'>{translate(
|
||||
'title.incoming_call',
|
||||
video ? 'title.incoming_video_call' : 'title.incoming_call',
|
||||
<b>
|
||||
{recipient.displayName ?? recipient.userId}
|
||||
</b>
|
||||
)}</Text>
|
||||
</div>
|
||||
{video && (
|
||||
<div>
|
||||
<Text style={{ color: 'red' }}>
|
||||
<b>ATTENTION!</b> Due to a bug, recipient <i>will see your video feed</i> for less than a second, and then it will be <i>frozen picture</i> (Not blank screen, but a frozen picture!)
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
<Box className={css.CallControlsContainer} grow='No' direction='Row'>
|
||||
{video && (
|
||||
<IconButton variant='Success' onClick={handleVideoAccept}>
|
||||
<MDIcon path={mdiVideo} size={1} />
|
||||
</IconButton>
|
||||
)}
|
||||
<IconButton variant='Success' onClick={handleAccept}>
|
||||
<MDIIcon path={mdiPhone} size={1} />
|
||||
<MDIcon path={mdiPhone} size={1} />
|
||||
</IconButton>
|
||||
<IconButton variant='Critical' onClick={handleReject}>
|
||||
<MDIIcon path={mdiPhoneHangup} size={1} />
|
||||
<MDIcon path={mdiPhoneHangup} size={1} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</>
|
||||
|
|
|
@ -18,9 +18,7 @@ import { EventTimeline, EventType, IContent, MsgType, Room } from 'matrix-js-sdk
|
|||
import {
|
||||
Box,
|
||||
Dialog,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Line,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
|
@ -111,6 +109,8 @@ import { roomToParentsAtom } from '../../state/room/roomToParents';
|
|||
import { getText } from '../../../lang';
|
||||
import { openHiddenRooms } from '../../../client/action/navigation';
|
||||
import { ScreenSize, useScreenSize } from '../../hooks/useScreenSize';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiCheckAll, mdiClose, mdiEmoticon, mdiEmoticonOutline, mdiFile, mdiPlusCircle, mdiPlusCircleOutline, mdiSend, mdiSendOutline, mdiSticker, mdiStickerOutline } from '@mdi/js';
|
||||
|
||||
interface RoomInputProps {
|
||||
fileDropContainerRef: RefObject<HTMLElement>;
|
||||
|
@ -479,7 +479,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
gap="500"
|
||||
style={{ padding: toRem(60) }}
|
||||
>
|
||||
<Icon size="600" src={Icons.File} />
|
||||
<Icon size={1} path={mdiFile} />
|
||||
<Text size="H4" align="Center">
|
||||
{getText('room_input.drop_files', room?.name || getText('room_input.drop_files.this_room'))}
|
||||
</Text>
|
||||
|
@ -561,7 +561,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
size="300"
|
||||
radii="300"
|
||||
>
|
||||
<Icon src={Icons.Cross} size="50" />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</div>
|
||||
|
@ -574,13 +574,13 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
size="300"
|
||||
radii="300"
|
||||
>
|
||||
<Icon src={Icons.PlusCircle} />
|
||||
<Icon size={1} path={mdiPlusCircleOutline} />
|
||||
</IconButton>
|
||||
}
|
||||
after={
|
||||
<>
|
||||
<IconButton onMouseDown={dontHideKeyboard} onClick={readReceipt} variant="SurfaceVariant" size="300" radii="300">
|
||||
<Icon src={Icons.CheckTwice} />
|
||||
<Icon size={1} path={mdiCheckAll} />
|
||||
</IconButton>
|
||||
<UseStateProvider initial={undefined}>
|
||||
{(emojiBoardTab: EmojiBoardTab | undefined, setEmojiBoardTab) => (
|
||||
|
@ -623,8 +623,8 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
ref={emojiBtnRef}
|
||||
>
|
||||
<Icon
|
||||
src={showStickerButton ? Icons.Sticker : Icons.Smile}
|
||||
filled={!!emojiBoardTab}
|
||||
size={1}
|
||||
path={showStickerButton ? (!!emojiBoardTab ? mdiSticker : mdiStickerOutline) : (!!emojiBoardTab ? mdiEmoticon : mdiEmoticonOutline)}
|
||||
/>
|
||||
</IconButton>
|
||||
)}
|
||||
|
@ -633,7 +633,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
</UseStateProvider>
|
||||
{screenSize !== ScreenSize.Mobile && (
|
||||
<IconButton onMouseDown={dontHideKeyboard} onClick={submit} variant="SurfaceVariant" size="300" radii="300">
|
||||
<Icon src={Icons.Send} />
|
||||
<Icon size={1} path={mdiSendOutline} />
|
||||
</IconButton>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -34,8 +34,6 @@ import {
|
|||
Box,
|
||||
Chip,
|
||||
ContainerColor,
|
||||
Icon,
|
||||
Icons,
|
||||
Line,
|
||||
Scroll,
|
||||
Text,
|
||||
|
@ -118,6 +116,8 @@ import { useSwipeLeft } from '../../hooks/useSwipeLeft';
|
|||
import { clamp } from '../../utils/common';
|
||||
import { parse } from 'url';
|
||||
import { getText, translate } from '../../../lang';
|
||||
import { mdiCheckAll, mdiChevronDown, mdiCodeBraces, mdiCodeBracesBox, mdiImageEdit, mdiMessageAlert, mdiPencilBox } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
const TimelineFloat = as<'div', css.TimelineFloatVariants>(
|
||||
({ position, className, ...props }, ref) => (
|
||||
|
@ -1378,7 +1378,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
<EventContent
|
||||
messageLayout={messageLayout}
|
||||
time={timeJSX}
|
||||
iconSrc={Icons.Hash}
|
||||
iconSrc={mdiPencilBox}
|
||||
content={
|
||||
<Box grow="Yes" direction="Column">
|
||||
<Text size="T300" priority="300">
|
||||
|
@ -1411,7 +1411,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
<EventContent
|
||||
messageLayout={messageLayout}
|
||||
time={timeJSX}
|
||||
iconSrc={Icons.Hash}
|
||||
iconSrc={mdiPencilBox}
|
||||
content={
|
||||
<Box grow="Yes" direction="Column">
|
||||
<Text size="T300" priority="300">
|
||||
|
@ -1444,7 +1444,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
<EventContent
|
||||
messageLayout={messageLayout}
|
||||
time={timeJSX}
|
||||
iconSrc={Icons.Hash}
|
||||
iconSrc={mdiImageEdit}
|
||||
content={
|
||||
<Box grow="Yes" direction="Column">
|
||||
<Text size="T300" priority="300">
|
||||
|
@ -1479,7 +1479,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
<EventContent
|
||||
messageLayout={messageLayout}
|
||||
time={timeJSX}
|
||||
iconSrc={Icons.Code}
|
||||
iconSrc={mdiCodeBracesBox}
|
||||
content={
|
||||
<Box grow="Yes" direction="Column">
|
||||
<Text size="T300" priority="300">
|
||||
|
@ -1517,7 +1517,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
<EventContent
|
||||
messageLayout={messageLayout}
|
||||
time={timeJSX}
|
||||
iconSrc={Icons.Code}
|
||||
iconSrc={mdiCodeBracesBox}
|
||||
content={
|
||||
<Box grow="Yes" direction="Column">
|
||||
<Text size="T300" priority="300">
|
||||
|
@ -1626,7 +1626,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
variant="Primary"
|
||||
radii="Pill"
|
||||
outlined
|
||||
before={<Icon size="50" src={Icons.MessageUnread} />}
|
||||
before={<Icon size={0.7} path={mdiMessageAlert} />}
|
||||
onClick={handleJumpToUnread}
|
||||
>
|
||||
<Text size="L400">{getText('btn.timeline.jump_to_unread')}</Text>
|
||||
|
@ -1636,7 +1636,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
variant="SurfaceVariant"
|
||||
radii="Pill"
|
||||
outlined
|
||||
before={<Icon size="50" src={Icons.CheckTwice} />}
|
||||
before={<Icon size={0.7} path={mdiCheckAll} />}
|
||||
onClick={handleMarkAsRead}
|
||||
>
|
||||
<Text size="L400">{getText('btn.timeline.mark_as_read')}</Text>
|
||||
|
@ -1703,7 +1703,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, textAreaRef }: RoomT
|
|||
variant="SurfaceVariant"
|
||||
radii="Pill"
|
||||
outlined
|
||||
before={<Icon size="50" src={Icons.ArrowBottom} />}
|
||||
before={<Icon size={0.7} path={mdiChevronDown} />}
|
||||
onClick={handleJumpToLatest}
|
||||
>
|
||||
<Text size="L400">{getText('btn.timeline.jump_to_latest')}</Text>
|
||||
|
|
|
@ -57,7 +57,7 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||
const [callWindow, setCallWindow] = useRoomCall();
|
||||
|
||||
const handleCall = async () => {
|
||||
if (callWindow) return;
|
||||
if (callWindow) return console.error('A call is already going on');
|
||||
const newCall = mx.createCall(room.roomId);
|
||||
if (!newCall) return alert('Calls are not supported in your browser!');
|
||||
setMxCall(newCall);
|
||||
|
@ -93,6 +93,8 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||
if (i > 10) return clearInterval(interval);
|
||||
i++;
|
||||
|
||||
console.debug('Invited to a call!!!', content.offer);
|
||||
|
||||
const call = mx.callEventHandler?.calls.get(content.call_id);
|
||||
|
||||
if (!call) return console.debug('No call found', content.call_id, mx.callEventHandler?.calls);
|
||||
|
@ -105,9 +107,11 @@ export function RoomView({ room, eventId }: { room: Room; eventId?: string }) {
|
|||
return;
|
||||
}
|
||||
|
||||
console.debug(`Call offer!!!`, content.offer);
|
||||
|
||||
setMxCall(call);
|
||||
setCallWindow(
|
||||
<RoomCall room={room} call={call} onHangup={onHangup} invitation={true} />
|
||||
<RoomCall room={room} call={call} onHangup={onHangup} invitation={true} video={content.offer.sdp.includes('video')} />
|
||||
);
|
||||
}, 1000);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Icon,
|
||||
Icons,
|
||||
Modal,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
|
@ -23,6 +21,8 @@ import { useRoomLatestRenderedEvent } from '../../hooks/useRoomLatestRenderedEve
|
|||
import { useRoomEventReaders } from '../../hooks/useRoomEventReaders';
|
||||
import { EventReaders } from '../../components/event-readers';
|
||||
import { getText, translate } from '../../../lang';
|
||||
import { mdiCheckAll } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
export type RoomViewFollowingProps = {
|
||||
room: Room;
|
||||
|
@ -72,7 +72,7 @@ export const RoomViewFollowing = as<'div', RoomViewFollowingProps>(
|
|||
>
|
||||
{names.length > 0 && (
|
||||
<>
|
||||
<Icon style={{ opacity: config.opacity.P300 }} size="100" src={Icons.CheckTwice} />
|
||||
<Icon style={{ opacity: config.opacity.P300 }} size={0.7} path={mdiCheckAll} />
|
||||
<Text size="T300" truncate>
|
||||
{names.length === 1 && (
|
||||
<>
|
||||
|
|
|
@ -8,8 +8,6 @@ import {
|
|||
OverlayCenter,
|
||||
OverlayBackdrop,
|
||||
IconButton,
|
||||
Icon,
|
||||
Icons,
|
||||
Tooltip,
|
||||
TooltipProvider,
|
||||
Menu,
|
||||
|
@ -27,7 +25,7 @@ import {
|
|||
Button,
|
||||
} from 'folds';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { EventTimeline, JoinRule, MatrixCall, MatrixEvent, Room } from 'matrix-js-sdk';
|
||||
import { EventTimeline, JoinRule, MatrixEvent, Room } from 'matrix-js-sdk';
|
||||
import { useAtomValue } from 'jotai';
|
||||
|
||||
import { useStateEvent } from '../../hooks/useStateEvent';
|
||||
|
@ -73,6 +71,8 @@ import { getReactCustomHtmlParser } from '../../plugins/react-custom-html-parser
|
|||
import { HTMLReactParserOptions } from 'html-react-parser';
|
||||
import { Message } from './message';
|
||||
import { Image } from '../../components/media';
|
||||
import { mdiAccount, mdiAccountPlus, mdiArrowLeft, mdiCheckAll, mdiChevronLeft, mdiChevronRight, mdiClose, mdiCog, mdiDotsVertical, mdiLinkVariant, mdiMagnify, mdiPhone, mdiPin } from '@mdi/js';
|
||||
import Icon from '@mdi/react';
|
||||
|
||||
type RoomMenuProps = {
|
||||
room: Room;
|
||||
|
@ -114,7 +114,7 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<Icon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
disabled={!unread}
|
||||
>
|
||||
|
@ -130,7 +130,7 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(
|
|||
variant="Primary"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.UserPlus} />}
|
||||
after={<Icon size={1} path={mdiAccountPlus} />}
|
||||
radii="300"
|
||||
disabled={!canInvite}
|
||||
>
|
||||
|
@ -141,7 +141,7 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleCopyLink}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Link} />}
|
||||
after={<Icon size={1} path={mdiLinkVariant} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -151,7 +151,7 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleRoomSettings}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Setting} />}
|
||||
after={<Icon size={1} path={mdiCog} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -169,7 +169,7 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(
|
|||
variant="Critical"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.ArrowGoLeft} />}
|
||||
after={<Icon size={1} path={mdiArrowLeft} />}
|
||||
radii="300"
|
||||
aria-pressed={promptLeave}
|
||||
>
|
||||
|
@ -247,7 +247,7 @@ export function RoomViewHeader({
|
|||
const [messageSpacing] = useSetting(settingsAtom, 'messageSpacing');
|
||||
const { navigateRoom, navigateSpace } = useRoomNavigate();
|
||||
const [mediaAutoLoad] = useSetting(settingsAtom, 'mediaAutoLoad');
|
||||
|
||||
|
||||
const htmlReactParserOptions = useMemo<HTMLReactParserOptions>(
|
||||
() =>
|
||||
getReactCustomHtmlParser(mx, room, {
|
||||
|
@ -446,7 +446,7 @@ export function RoomViewHeader({
|
|||
<Text size="H4">{getText('pinned.title')}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={handlePinnedClose} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Box tabIndex={-1} direction='Column' style={{ height: 'inherit' }}>
|
||||
|
@ -461,7 +461,7 @@ export function RoomViewHeader({
|
|||
<Chip
|
||||
variant="Secondary"
|
||||
radii="300"
|
||||
before={<Icon size="50" src={Icons.ChevronLeft} />}
|
||||
before={<Icon size={1} path={mdiChevronLeft} />}
|
||||
onClick={handlePrevPage}
|
||||
aria-disabled={pageNo <= 1 || loadingPinList}
|
||||
>
|
||||
|
@ -522,7 +522,7 @@ export function RoomViewHeader({
|
|||
<Chip
|
||||
variant="Primary"
|
||||
radii="300"
|
||||
after={<Icon size="50" src={Icons.ChevronRight} />}
|
||||
after={<Icon size={1} path={mdiChevronRight} />}
|
||||
onClick={handleNextPage}
|
||||
aria-disabled={pageNo >= pinnedPages || loadingPinList}
|
||||
>
|
||||
|
@ -600,7 +600,7 @@ export function RoomViewHeader({
|
|||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton ref={triggerRef} onClick={handleSearchClick}>
|
||||
<Icon size="400" src={Icons.Search} />
|
||||
<Icon size={1} path={mdiMagnify} />
|
||||
</IconButton>
|
||||
)}
|
||||
</TooltipProvider>
|
||||
|
@ -616,7 +616,7 @@ export function RoomViewHeader({
|
|||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton ref={triggerRef} onClick={handlePinnedClick}>
|
||||
<Icon size="400" src={Icons.Pin} />
|
||||
<Icon size={1} path={mdiPin} />
|
||||
</IconButton>
|
||||
)}
|
||||
</TooltipProvider>
|
||||
|
@ -632,14 +632,14 @@ export function RoomViewHeader({
|
|||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton ref={triggerRef} onClick={() => setPeopleDrawer((drawer) => !drawer)}>
|
||||
<Icon size="400" src={Icons.User} />
|
||||
<Icon size={1} path={mdiAccount} />
|
||||
</IconButton>
|
||||
)}
|
||||
</TooltipProvider>
|
||||
)}
|
||||
{mDirects.has(room.roomId) && (
|
||||
<IconButton onClick={handleCall}>
|
||||
<Icon size="400" src={Icons.Phone} />
|
||||
<Icon size={1} path={mdiPhone} />
|
||||
</IconButton>
|
||||
)}
|
||||
<TooltipProvider
|
||||
|
@ -654,7 +654,7 @@ export function RoomViewHeader({
|
|||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton onClick={handleOpenMenu} ref={triggerRef} aria-pressed={!!menuAnchor}>
|
||||
<Icon size="400" src={Icons.VerticalDots} filled={!!menuAnchor} />
|
||||
<Icon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
)}
|
||||
</TooltipProvider>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Box, Icon, IconButton, Icons, Text, as } from 'folds';
|
||||
import { Box, Text, as } from 'folds';
|
||||
import { Room } from 'matrix-js-sdk';
|
||||
import classNames from 'classnames';
|
||||
import { useSetAtom } from 'jotai';
|
||||
|
|
|
@ -4,9 +4,7 @@ import {
|
|||
Button,
|
||||
Dialog,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Input,
|
||||
Line,
|
||||
Menu,
|
||||
|
@ -90,6 +88,8 @@ import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
|||
import { ImageViewer } from '../../../components/image-viewer';
|
||||
import { Image } from '../../../components/media';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAccount, mdiAlertCircleOutline, mdiCheck, mdiCheckAll, mdiClose, mdiCodeBraces, mdiDelete, mdiDotsVertical, mdiEmoticon, mdiEmoticonPlus, mdiLinkVariant, mdiPencil, mdiPin, mdiPinOff, mdiReply, mdiRestore } from '@mdi/js';
|
||||
|
||||
export type ReactionHandler = (keyOrMxc: string, shortcode: string) => void;
|
||||
|
||||
|
@ -178,7 +178,7 @@ export const MessageAllReactionItem = as<
|
|||
</Overlay>
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Smile} />}
|
||||
after={<Icon size={1} path={mdiEmoticon} />}
|
||||
radii="300"
|
||||
onClick={() => setOpen(true)}
|
||||
{...props}
|
||||
|
@ -227,7 +227,7 @@ export const MessageReadReceiptItem = as<
|
|||
</Overlay>
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<Icon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
onClick={() => setOpen(true)}
|
||||
{...props}
|
||||
|
@ -309,7 +309,7 @@ export const MessageSourceCodeItem = as<
|
|||
</Overlay>
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.BlockCode} />}
|
||||
after={<Icon size={1} path={mdiCodeBraces} />}
|
||||
radii="300"
|
||||
onClick={() => setOpen(true)}
|
||||
{...props}
|
||||
|
@ -366,7 +366,7 @@ export const MessagePinItem = as<
|
|||
return (
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Pin} />}
|
||||
after={<Icon size={1} path={isPinned ? mdiPin : mdiPinOff} />}
|
||||
radii="300"
|
||||
{...props}
|
||||
ref={ref}
|
||||
|
@ -545,7 +545,7 @@ export const MessageRecoverItem = as<
|
|||
<Text size="H4">{getText('recovered.title')}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={handleClose} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
{message}
|
||||
|
@ -555,7 +555,7 @@ export const MessageRecoverItem = as<
|
|||
</Overlay>
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Eye} />}
|
||||
after={<Icon size={1} path={mdiRestore} />}
|
||||
radii="300"
|
||||
onClick={handleClick}
|
||||
{...props}
|
||||
|
@ -588,7 +588,7 @@ export const MessageCopyLinkItem = as<
|
|||
return (
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Link} />}
|
||||
after={<Icon size={1} path={mdiLinkVariant} />}
|
||||
radii="300"
|
||||
onClick={handleCopy}
|
||||
{...props}
|
||||
|
@ -664,7 +664,7 @@ export const MessageDeleteItem = as<
|
|||
<Text size="H4">{getText('msg_redact.title')}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={handleClose} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Box
|
||||
|
@ -684,7 +684,7 @@ export const MessageDeleteItem = as<
|
|||
{getText('msg_redact.reason.2')}
|
||||
</Text>
|
||||
</Text>
|
||||
<Input name="reasonInput" variant="Background" />
|
||||
<Input name="reasonInput" variant="Background" autoComplete='off' />
|
||||
{deleteState.status === AsyncStatus.Error && (
|
||||
<Text style={{ color: color.Critical.Main }} size="T300">
|
||||
{getText('error.redact_msg')}
|
||||
|
@ -714,7 +714,7 @@ export const MessageDeleteItem = as<
|
|||
variant="Critical"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Delete} />}
|
||||
after={<Icon size={1} path={mdiDelete} />}
|
||||
radii="300"
|
||||
onClick={() => setOpen(true)}
|
||||
aria-pressed={open}
|
||||
|
@ -793,7 +793,7 @@ export const MessageReportItem = as<
|
|||
<Text size="H4">{getText('msg_report.title')}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={handleClose} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Box
|
||||
|
@ -846,7 +846,7 @@ export const MessageReportItem = as<
|
|||
variant="Critical"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Warning} />}
|
||||
after={<Icon size={1} path={mdiAlertCircleOutline} />}
|
||||
radii="300"
|
||||
onClick={() => setOpen(true)}
|
||||
aria-pressed={open}
|
||||
|
@ -1024,7 +1024,7 @@ export const Message = as<'div', MessageProps>(
|
|||
: undefined
|
||||
}
|
||||
alt={senderDisplayName}
|
||||
renderFallback={() => <Icon size="200" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
|
@ -1154,7 +1154,7 @@ export const Message = as<'div', MessageProps>(
|
|||
radii="300"
|
||||
aria-pressed={!!emojiBoardAnchor}
|
||||
>
|
||||
<Icon src={Icons.SmilePlus} size="100" />
|
||||
<Icon size={1} path={mdiEmoticonPlus} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
)}
|
||||
|
@ -1165,7 +1165,7 @@ export const Message = as<'div', MessageProps>(
|
|||
size="300"
|
||||
radii="300"
|
||||
>
|
||||
<Icon src={Icons.ReplyArrow} size="100" />
|
||||
<Icon size={1} path={mdiReply} />
|
||||
</IconButton>
|
||||
{canEditEvent(mx, mEvent) && onEditId && (
|
||||
<IconButton
|
||||
|
@ -1174,7 +1174,7 @@ export const Message = as<'div', MessageProps>(
|
|||
size="300"
|
||||
radii="300"
|
||||
>
|
||||
<Icon src={Icons.Pencil} size="100" />
|
||||
<Icon size={1} path={mdiPencil} />
|
||||
</IconButton>
|
||||
)}
|
||||
<PopOut
|
||||
|
@ -1205,7 +1205,7 @@ export const Message = as<'div', MessageProps>(
|
|||
{mEvent.getType() == 'org.matrix.msc3381.poll.start' && mEvent.sender?.userId == (mx.getUserId() ?? '') && (
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Check} />}
|
||||
after={<Icon size={1} path={mdiCheck} />}
|
||||
radii="300"
|
||||
onClick={handleEndPoll}
|
||||
>
|
||||
|
@ -1222,7 +1222,7 @@ export const Message = as<'div', MessageProps>(
|
|||
{canSendReaction && (
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.SmilePlus} />}
|
||||
after={<Icon size={1} path={mdiEmoticonPlus} />}
|
||||
radii="300"
|
||||
onClick={handleAddReactions}
|
||||
>
|
||||
|
@ -1245,7 +1245,7 @@ export const Message = as<'div', MessageProps>(
|
|||
)}
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.ReplyArrow} />}
|
||||
after={<Icon size={1} path={mdiReply} />}
|
||||
radii="300"
|
||||
data-event-id={mEvent.getId()}
|
||||
onClick={(evt: any) => {
|
||||
|
@ -1265,7 +1265,7 @@ export const Message = as<'div', MessageProps>(
|
|||
{canEditEvent(mx, mEvent) && onEditId && (
|
||||
<MenuItem
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Pencil} />}
|
||||
after={<Icon size={1} path={mdiPencil} />}
|
||||
radii="300"
|
||||
data-event-id={mEvent.getId()}
|
||||
onClick={() => {
|
||||
|
@ -1330,7 +1330,7 @@ export const Message = as<'div', MessageProps>(
|
|||
onClick={handleOpenMenu}
|
||||
aria-pressed={!!menuAnchor}
|
||||
>
|
||||
<Icon src={Icons.VerticalDots} size="100" />
|
||||
<Icon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
</Box>
|
||||
|
@ -1475,7 +1475,7 @@ export const Event = as<'div', EventProps>(
|
|||
onClick={handleOpenMenu}
|
||||
aria-pressed={!!menuAnchor}
|
||||
>
|
||||
<Icon src={Icons.VerticalDots} size="100" />
|
||||
<Icon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
</Box>
|
||||
|
|
|
@ -9,10 +9,7 @@ import React, {
|
|||
import {
|
||||
Box,
|
||||
Chip,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Line,
|
||||
PopOut,
|
||||
RectCords,
|
||||
Spinner,
|
||||
|
@ -49,6 +46,8 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|||
import { getEditedEvent, trimReplyFromFormattedBody } from '../../../utils/room';
|
||||
import { mobileOrTablet } from '../../../utils/user-agent';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiEmoticon, mdiEmoticonOutline } from '@mdi/js';
|
||||
|
||||
type MessageEditorProps = {
|
||||
roomId: string;
|
||||
|
@ -290,7 +289,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
|||
size="300"
|
||||
radii="300"
|
||||
>
|
||||
<Icon size="400" src={Icons.Smile} filled={anchor !== undefined} />
|
||||
<Icon size={1} path={anchor !== undefined ? mdiEmoticon : mdiEmoticonOutline} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
)}
|
||||
|
|
|
@ -4,9 +4,7 @@ import {
|
|||
Avatar,
|
||||
Box,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Line,
|
||||
MenuItem,
|
||||
Scroll,
|
||||
|
@ -26,6 +24,8 @@ import { Reaction } from '../../../components/message';
|
|||
import { getHexcodeForEmoji, getShortcodeFor } from '../../../plugins/emoji';
|
||||
import { UserAvatar } from '../../../components/user-avatar';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAccount, mdiClose } from '@mdi/js';
|
||||
|
||||
export type ReactionViewerProps = {
|
||||
room: Room;
|
||||
|
@ -95,7 +95,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>(
|
|||
<Text size="H3">{getText('reaction_viewer.reacted_with', selectedShortcode)}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={requestClose}>
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
|
||||
|
@ -132,7 +132,7 @@ export const ReactionViewer = as<'div', ReactionViewerProps>(
|
|||
userId={senderId}
|
||||
src={avatarUrl ?? undefined}
|
||||
alt={name}
|
||||
renderFallback={() => <Icon size="50" src={Icons.User} filled />}
|
||||
renderFallback={() => <Icon size={1} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import React, { ReactNode } from 'react';
|
||||
import { IconSrc, Icons } from 'folds';
|
||||
import { EventTimeline, MatrixEvent, Room } from 'matrix-js-sdk';
|
||||
import { IMemberContent, Membership } from '../../types/matrix/room';
|
||||
import { getMxIdLocalPart } from '../utils/matrix';
|
||||
import { isMembershipChanged } from '../utils/room';
|
||||
import { useMatrixClient } from './useMatrixClient';
|
||||
import { mdiAccount, mdiAccountLock, mdiAccountLockOpen, mdiAccountPlus, mdiAccountRemove, mdiArrowRight, mdiAt } from '@mdi/js';
|
||||
|
||||
/// TODO: TRANSLATE THIS!
|
||||
|
||||
export type ParsedResult = {
|
||||
icon: IconSrc;
|
||||
icon: string;
|
||||
body: ReactNode;
|
||||
};
|
||||
|
||||
|
@ -37,7 +39,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (!senderId || !userId)
|
||||
return {
|
||||
icon: Icons.User,
|
||||
icon: mdiAccount,
|
||||
body: 'Broken membership event',
|
||||
};
|
||||
|
||||
|
@ -48,7 +50,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
if (content.membership === Membership.Invite) {
|
||||
if (prevContent.membership === Membership.Knock) {
|
||||
return {
|
||||
icon: Icons.ArrowGoRightPlus,
|
||||
icon: mdiAccountPlus,
|
||||
body: (
|
||||
<>
|
||||
<b>{senderName}</b>
|
||||
|
@ -62,7 +64,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
}
|
||||
|
||||
return {
|
||||
icon: Icons.ArrowGoRightPlus,
|
||||
icon: mdiAccountPlus,
|
||||
body: (
|
||||
<>
|
||||
<b>{senderName}</b>
|
||||
|
@ -75,7 +77,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (content.membership === Membership.Knock) {
|
||||
return {
|
||||
icon: Icons.ArrowGoRightPlus,
|
||||
icon: mdiAccountPlus,
|
||||
body: (
|
||||
<>
|
||||
<b>{userName}</b>
|
||||
|
@ -88,7 +90,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (content.membership === Membership.Join) {
|
||||
return {
|
||||
icon: Icons.ArrowGoRight,
|
||||
icon: mdiAccountPlus,
|
||||
body: (
|
||||
<>
|
||||
<b>{userName}</b>
|
||||
|
@ -101,7 +103,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
if (content.membership === Membership.Leave) {
|
||||
if (prevContent.membership === Membership.Invite) {
|
||||
return {
|
||||
icon: Icons.ArrowGoRightCross,
|
||||
icon: mdiAccountRemove,
|
||||
body:
|
||||
senderId === userId ? (
|
||||
<>
|
||||
|
@ -123,7 +125,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (prevContent.membership === Membership.Knock) {
|
||||
return {
|
||||
icon: Icons.ArrowGoRightCross,
|
||||
icon: mdiAccountRemove,
|
||||
body:
|
||||
senderId === userId ? (
|
||||
<>
|
||||
|
@ -145,7 +147,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (prevContent.membership === Membership.Ban) {
|
||||
return {
|
||||
icon: Icons.ArrowGoLeft,
|
||||
icon: mdiAccountLockOpen,
|
||||
body: (
|
||||
<>
|
||||
<b>{senderName}</b>
|
||||
|
@ -157,7 +159,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
}
|
||||
|
||||
return {
|
||||
icon: Icons.ArrowGoLeft,
|
||||
icon: mdiAccountRemove,
|
||||
body:
|
||||
senderId === userId ? (
|
||||
<>
|
||||
|
@ -177,7 +179,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (content.membership === Membership.Ban) {
|
||||
return {
|
||||
icon: Icons.ArrowGoLeft,
|
||||
icon: mdiAccountLock,
|
||||
body: (
|
||||
<>
|
||||
<b>{senderName}</b>
|
||||
|
@ -193,7 +195,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
const prevUserName = prevContent.displayname || userId;
|
||||
|
||||
return {
|
||||
icon: Icons.Mention,
|
||||
icon: mdiAt,
|
||||
body: content.displayname ? (
|
||||
<>
|
||||
<b>{prevUserName}</b>
|
||||
|
@ -210,7 +212,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
}
|
||||
if (content.avatar_url !== prevContent.avatar_url) {
|
||||
return {
|
||||
icon: Icons.User,
|
||||
icon: mdiAccount,
|
||||
body: content.displayname ? (
|
||||
<>
|
||||
<b>{userName}</b>
|
||||
|
@ -227,7 +229,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
|
||||
if (content['ru.officialdakari.extera_banner'] !== prevContent['ru.officialdakari.extera_banner']) {
|
||||
return {
|
||||
icon: Icons.User,
|
||||
icon: mdiAccount,
|
||||
body: content['ru.officialdakari.extera_banner'] ? (
|
||||
<>
|
||||
<b>{userName}</b>
|
||||
|
@ -243,7 +245,7 @@ export const useMemberEventParser = (): MemberEventParser => {
|
|||
}
|
||||
|
||||
return {
|
||||
icon: Icons.User,
|
||||
icon: mdiAccount,
|
||||
body: 'Broken membership event',
|
||||
};
|
||||
};
|
||||
|
|
|
@ -53,7 +53,7 @@ import { settingsAtom } from '../../state/settings';
|
|||
import { isMacOS } from '../../utils/user-agent';
|
||||
import { KeySymbol } from '../../utils/key-symbol';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { Icons, Input } from 'folds';
|
||||
import { Input } from 'folds';
|
||||
import Banner from '../profile-editor/Banner';
|
||||
import { getText } from '../../../lang';
|
||||
import { useBackButton } from '../../hooks/useBackButton';
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import React from 'react';
|
||||
import { Box, Icon, Icons, color, Text } from 'folds';
|
||||
import { Box, color, Text } from 'folds';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlert } from '@mdi/js';
|
||||
|
||||
export function FieldError({ message }: { message: string }) {
|
||||
return (
|
||||
<Box style={{ color: color.Critical.Main }} alignItems="Center" gap="100">
|
||||
<Icon size="50" filled src={Icons.Warning} />
|
||||
<Icon size={1} path={mdiAlert} />
|
||||
<Text size="T200">
|
||||
<b>{message}</b>
|
||||
</Text>
|
||||
|
|
|
@ -8,9 +8,7 @@ import React, {
|
|||
} from 'react';
|
||||
import {
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Input,
|
||||
Menu,
|
||||
MenuItem,
|
||||
|
@ -23,6 +21,8 @@ import FocusTrap from 'focus-trap-react';
|
|||
|
||||
import { useDebounce } from '../../hooks/useDebounce';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiChevronDown } from '@mdi/js';
|
||||
|
||||
export function ServerPicker({
|
||||
server,
|
||||
|
@ -134,7 +134,7 @@ export function ServerPicker({
|
|||
aria-pressed={!!serverMenuAnchor}
|
||||
radii="300"
|
||||
>
|
||||
<Icon src={Icons.ChevronBottom} />
|
||||
<Icon size={1} path={mdiChevronDown} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
)
|
||||
|
|
|
@ -3,9 +3,7 @@ import {
|
|||
Box,
|
||||
Button,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Input,
|
||||
Menu,
|
||||
Overlay,
|
||||
|
@ -38,6 +36,8 @@ import { FieldError } from '../FiledError';
|
|||
import { getResetPasswordPath } from '../../pathUtils';
|
||||
import { getText } from '../../../../lang';
|
||||
import cons from '../../../../client/state/cons';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlertCircleOutline } from '@mdi/js';
|
||||
|
||||
function UsernameHint({ server }: { server: string }) {
|
||||
const [anchor, setAnchor] = useState<RectCords>();
|
||||
|
@ -100,7 +100,7 @@ function UsernameHint({ server }: { server: string }) {
|
|||
radii="300"
|
||||
aria-pressed={!!anchor}
|
||||
>
|
||||
<Icon style={{ opacity: config.opacity.P300 }} size="100" src={Icons.Info} />
|
||||
<Icon style={{ opacity: config.opacity.P300 }} size={1} path={mdiAlertCircleOutline} />
|
||||
</IconButton>
|
||||
</PopOut>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import {
|
||||
Box,
|
||||
Icon,
|
||||
Icons,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
OverlayCenter,
|
||||
|
@ -17,6 +15,8 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
|||
import { CustomLoginResponse, LoginError, login, useLoginComplete } from './loginUtil';
|
||||
import { getText } from '../../../../lang';
|
||||
import cons from '../../../../client/state/cons';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlert } from '@mdi/js';
|
||||
|
||||
function LoginTokenError({ message }: { message: string }) {
|
||||
return (
|
||||
|
@ -31,7 +31,7 @@ function LoginTokenError({ message }: { message: string }) {
|
|||
alignItems="Start"
|
||||
gap="300"
|
||||
>
|
||||
<Icon size="300" filled src={Icons.Warning} />
|
||||
<Icon size={1} path={mdiAlert} />
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Token Login</Text>
|
||||
<Text size="T300">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useRef } from 'react';
|
||||
import { Icon, Icons, Scroll } from 'folds';
|
||||
import { Scroll } from 'folds';
|
||||
|
||||
import {
|
||||
Sidebar,
|
||||
|
@ -13,6 +13,8 @@ import {
|
|||
import { DirectTab, HomeTab, SpaceTabs, InboxTab, ExploreTab, UserTab } from './sidebar';
|
||||
import { openCreateRoom, openSearch } from '../../../client/action/navigation';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiMagnify, mdiPlus } from '@mdi/js';
|
||||
|
||||
export function SidebarNav() {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
|
@ -39,7 +41,7 @@ export function SidebarNav() {
|
|||
outlined
|
||||
onClick={() => openCreateRoom(true)}
|
||||
>
|
||||
<Icon src={Icons.Plus} />
|
||||
<Icon size={1} path={mdiPlus} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
|
@ -60,7 +62,7 @@ export function SidebarNav() {
|
|||
outlined
|
||||
onClick={() => openSearch()}
|
||||
>
|
||||
<Icon src={Icons.Search} />
|
||||
<Icon size={1} path={mdiMagnify} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import React from 'react';
|
||||
import { Box, Button, Icon, Icons, Text, config, toRem } from 'folds';
|
||||
import { Box, Button, Text, config, toRem } from 'folds';
|
||||
import { Page, PageHero, PageHeroSection } from '../../components/page';
|
||||
import CinnySVG from '../../../../public/res/svg/cinny.svg';
|
||||
import cons from '../../../client/state/cons';
|
||||
import { getText } from '../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiCodeBraces, mdiHeart } from '@mdi/js';
|
||||
|
||||
export function WelcomePage() {
|
||||
return (
|
||||
|
@ -38,7 +40,7 @@ export function WelcomePage() {
|
|||
href="https://github.com/OfficialDakari/Extera"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
before={<Icon size="200" src={Icons.Code} />}
|
||||
before={<Icon size={1} path={mdiCodeBraces} />}
|
||||
>
|
||||
<Text as="span" size="B400">
|
||||
{getText('btn.source_code')}
|
||||
|
@ -50,7 +52,7 @@ export function WelcomePage() {
|
|||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
fill="Soft"
|
||||
before={<Icon size="200" src={Icons.Heart} />}
|
||||
before={<Icon size={1} path={mdiHeart} />}
|
||||
>
|
||||
<Text as="span" size="B400">
|
||||
{getText('btn.sponsor')}
|
||||
|
|
|
@ -4,9 +4,7 @@ import {
|
|||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Menu,
|
||||
MenuItem,
|
||||
PopOut,
|
||||
|
@ -46,6 +44,8 @@ import { useRoomsUnread } from '../../../state/hooks/unread';
|
|||
import { markAsRead } from '../../../../client/action/notifications';
|
||||
import { getText } from '../../../../lang';
|
||||
import { isHidden } from '../../../state/hooks/roomList';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAt, mdiCheckAll, mdiDotsVertical, mdiPlusCircleOutline } from '@mdi/js';
|
||||
|
||||
type DirectMenuProps = {
|
||||
requestClose: () => void;
|
||||
|
@ -66,7 +66,7 @@ const DirectMenu = forwardRef<HTMLDivElement, DirectMenuProps>(({ requestClose }
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<Icon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
aria-disabled={!unread}
|
||||
>
|
||||
|
@ -101,7 +101,7 @@ function DirectHeader() {
|
|||
</Box>
|
||||
<Box>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu}>
|
||||
<Icon src={Icons.VerticalDots} size="200" />
|
||||
<Icon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -134,7 +134,7 @@ function DirectEmpty() {
|
|||
return (
|
||||
<NavEmptyCenter>
|
||||
<NavEmptyLayout
|
||||
icon={<Icon size="600" src={Icons.Mention} />}
|
||||
icon={<Icon size={1} path={mdiAt} />}
|
||||
title={
|
||||
<Text size="H5" align="Center">
|
||||
{getText('direct_menu.empty')}
|
||||
|
@ -204,7 +204,7 @@ export function Direct() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Plus} size="100" />
|
||||
<Icon size={1} path={mdiPlusCircleOutline} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
|
|
|
@ -7,9 +7,7 @@ import {
|
|||
Button,
|
||||
Dialog,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Input,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
|
@ -37,6 +35,8 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
|||
import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper';
|
||||
import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiClose, mdiPlus, mdiServerNetwork, mdiServerNetworkOutline, mdiStar, mdiStarOutline } from '@mdi/js';
|
||||
|
||||
export function AddServer() {
|
||||
const mx = useMatrixClient();
|
||||
|
@ -96,7 +96,7 @@ export function AddServer() {
|
|||
<Text size="H4">{getText('explore.add_server')}</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={() => setDialog(false)} radii="300">
|
||||
<Icon src={Icons.Cross} />
|
||||
<Icon size={1} path={mdiClose} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Box
|
||||
|
@ -143,7 +143,7 @@ export function AddServer() {
|
|||
variant="Secondary"
|
||||
fill="Soft"
|
||||
size="300"
|
||||
before={<Icon size="100" src={Icons.Plus} />}
|
||||
before={<Icon size={1} path={mdiPlus} />}
|
||||
onClick={() => setDialog(true)}
|
||||
>
|
||||
<Text size="B300" truncate>
|
||||
|
@ -186,7 +186,7 @@ export function Explore() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Bulb} size="100" filled={featuredSelected} />
|
||||
<Icon size={1} path={featuredSelected ? mdiStar : mdiStarOutline} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
|
@ -208,9 +208,8 @@ export function Explore() {
|
|||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon
|
||||
src={Icons.Category}
|
||||
size="100"
|
||||
filled={selectedServer === userServer}
|
||||
path={selectedServer === userServer ? mdiServerNetwork : mdiServerNetworkOutline}
|
||||
size={1}
|
||||
/>
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
|
@ -243,9 +242,8 @@ export function Explore() {
|
|||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon
|
||||
src={Icons.Category}
|
||||
size="100"
|
||||
filled={server === selectedServer}
|
||||
path={mdiServerNetworkOutline}
|
||||
size={1}
|
||||
/>
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Box, Icon, Icons, Scroll, Text } from 'folds';
|
||||
import { Box, Scroll, Text } from 'folds';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useClientConfig } from '../../../hooks/useClientConfig';
|
||||
import { RoomCard, RoomCardGrid } from '../../../components/room-card';
|
||||
|
@ -16,6 +16,8 @@ import { RoomTopicViewer } from '../../../components/room-topic-viewer';
|
|||
import * as css from './style.css';
|
||||
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||
import { getText } from '../../../../lang';
|
||||
import Icon from '@mdi/react';
|
||||
import { mdiAlertCircleOutline, mdiStar, mdiStarCircleOutline } from '@mdi/js';
|
||||
|
||||
export function FeaturedRooms() {
|
||||
const { featuredCommunities } = useClientConfig();
|
||||
|
@ -32,7 +34,7 @@ export function FeaturedRooms() {
|
|||
<Box direction="Column" gap="200">
|
||||
<PageHeroSection>
|
||||
<PageHero
|
||||
icon={<Icon size="600" src={Icons.Bulb} />}
|
||||
icon={<Icon size={1} path={mdiStar} />}
|
||||
title={getText('explore.featured.title')}
|
||||
subTitle={getText('explore.featured.subtitle')}
|
||||
/>
|
||||
|
@ -105,7 +107,7 @@ export function FeaturedRooms() {
|
|||
alignItems="Center"
|
||||
gap="200"
|
||||
>
|
||||
<Icon size="400" src={Icons.Info} />
|
||||
<Icon size={1} path={mdiAlertCircleOutline} />
|
||||
<Text size="T300" align="Center">
|
||||
{getText('explore.no_featured')}
|
||||
</Text>
|
||||
|
|
|
@ -8,12 +8,11 @@ import React, {
|
|||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Chip,
|
||||
Icon,
|
||||
Icons,
|
||||
Input,
|
||||
Line,
|
||||
Menu,
|
||||
|
@ -42,6 +41,7 @@ import { allRoomsAtom } from '../../../state/room-list/roomList';
|
|||
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||
import { getMxIdServer } from '../../../utils/matrix';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiAlertCircleOutline, mdiArrowLeft, mdiCheck, mdiChevronDown, mdiClose, mdiMagnify, mdiServer, mdiServerNetwork, mdiShape } from '@mdi/js';
|
||||
|
||||
const useServerSearchParams = (searchParams: URLSearchParams): ExploreServerPathSearchParams =>
|
||||
useMemo(
|
||||
|
@ -115,7 +115,7 @@ function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchPr
|
|||
active && loading ? (
|
||||
<Spinner variant="Secondary" size="200" />
|
||||
) : (
|
||||
<Icon size="200" src={Icons.Search} />
|
||||
<MDIcon size={1} path={mdiMagnify} />
|
||||
)
|
||||
}
|
||||
after={
|
||||
|
@ -126,7 +126,7 @@ function Search({ active, loading, searchInputRef, onSearch, onReset }: SearchPr
|
|||
size="400"
|
||||
radii="Pill"
|
||||
outlined
|
||||
after={<Icon size="50" src={Icons.Cross} />}
|
||||
after={<MDIcon size={0.7} path={mdiClose} />}
|
||||
onClick={onReset}
|
||||
>
|
||||
<Text size="B300">{getText('btn.clear_search')}</Text>
|
||||
|
@ -233,7 +233,7 @@ function ThirdPartyProtocolsSelector({
|
|||
radii="Pill"
|
||||
size="400"
|
||||
variant={instanceId ? 'Success' : 'SurfaceVariant'}
|
||||
after={<Icon size="100" src={Icons.ChevronBottom} />}
|
||||
after={<MDIcon size={1} path={mdiChevronDown} />}
|
||||
>
|
||||
<Text size="T200" truncate>
|
||||
{selectedInstance?.desc ?? DEFAULT_INSTANCE_NAME}
|
||||
|
@ -327,7 +327,7 @@ function LimitButton({ limit, onLimitChange }: LimitButtonProps) {
|
|||
radii="Pill"
|
||||
size="400"
|
||||
variant="SurfaceVariant"
|
||||
after={<Icon size="100" src={Icons.ChevronBottom} />}
|
||||
after={<MDIcon size={1} path={mdiChevronDown} />}
|
||||
>
|
||||
<Text size="T200" truncate>{getText('count.page_limit', limit)}</Text>
|
||||
</Chip>
|
||||
|
@ -472,7 +472,7 @@ export function PublicRooms() {
|
|||
size="500"
|
||||
variant="Surface"
|
||||
radii="Pill"
|
||||
before={<Icon size="100" src={Icons.ArrowLeft} />}
|
||||
before={<MDIcon size={1} path={mdiArrowLeft} />}
|
||||
onClick={handleSearchClear}
|
||||
>
|
||||
<Text size="T300">{server}</Text>
|
||||
|
@ -480,7 +480,7 @@ export function PublicRooms() {
|
|||
</Box>
|
||||
|
||||
<Box grow="No" justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Icon size="400" src={Icons.Search} />
|
||||
<MDIcon size={1} path={mdiMagnify} />
|
||||
<Text size="H3" truncate>
|
||||
{getText('explore.server.search')}
|
||||
</Text>
|
||||
|
@ -489,7 +489,7 @@ export function PublicRooms() {
|
|||
</>
|
||||
) : (
|
||||
<Box grow="Yes" justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Icon size="400" src={Icons.Category} />
|
||||
<MDIcon size={1} path={mdiServerNetwork} />
|
||||
<Text size="H3" truncate>
|
||||
{server}
|
||||
</Text>
|
||||
|
@ -526,7 +526,7 @@ export function PublicRooms() {
|
|||
aria-pressed={filter.value === serverSearchParams.type}
|
||||
before={
|
||||
filter.value === serverSearchParams.type && (
|
||||
<Icon size="100" src={Icons.Check} />
|
||||
<MDIcon size={1} path={mdiCheck} />
|
||||
)
|
||||
}
|
||||
outlined
|
||||
|
@ -629,7 +629,7 @@ export function PublicRooms() {
|
|||
alignItems="Center"
|
||||
gap="200"
|
||||
>
|
||||
<Icon size="400" src={Icons.Info} />
|
||||
<MDIcon size={1} path={mdiAlertCircleOutline} />
|
||||
<Text size="T300" align="Center">
|
||||
{getText('explore.server.no_communities')}
|
||||
</Text>
|
||||
|
|
|
@ -4,9 +4,7 @@ import {
|
|||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Menu,
|
||||
MenuItem,
|
||||
PopOut,
|
||||
|
@ -15,6 +13,7 @@ import {
|
|||
config,
|
||||
toRem,
|
||||
} from 'folds';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
|
@ -49,6 +48,7 @@ import { markAsRead } from '../../../../client/action/notifications';
|
|||
import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCategories';
|
||||
import { getText } from '../../../../lang';
|
||||
import { isHidden } from '../../../state/hooks/roomList';
|
||||
import { mdiCheckAll, mdiDotsVertical, mdiLinkVariant, mdiMagnify, mdiPlus, mdiPlusCircle, mdiPlusCircleOutline, mdiPound } from '@mdi/js';
|
||||
|
||||
type HomeMenuProps = {
|
||||
requestClose: () => void;
|
||||
|
@ -69,7 +69,7 @@ const HomeMenu = forwardRef<HTMLDivElement, HomeMenuProps>(({ requestClose }, re
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<MDIcon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
aria-disabled={!unread}
|
||||
>
|
||||
|
@ -104,7 +104,7 @@ function HomeHeader() {
|
|||
</Box>
|
||||
<Box>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu}>
|
||||
<Icon src={Icons.VerticalDots} size="200" />
|
||||
<MDIcon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -139,7 +139,7 @@ function HomeEmpty() {
|
|||
return (
|
||||
<NavEmptyCenter>
|
||||
<NavEmptyLayout
|
||||
icon={<Icon size="600" src={Icons.Hash} />}
|
||||
icon={<MDIcon size={1} path={mdiPound} />}
|
||||
title={
|
||||
<Text size="H5" align="Center">
|
||||
{getText('home.empty')}
|
||||
|
@ -226,7 +226,7 @@ export function Home() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Plus} size="100" />
|
||||
<MDIcon size={1} path={mdiPlusCircleOutline} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit">
|
||||
|
@ -242,7 +242,7 @@ export function Home() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Link} size="100" />
|
||||
<MDIcon size={1} path={mdiLinkVariant} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit">
|
||||
|
@ -258,7 +258,7 @@ export function Home() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Search} size="100" filled={searchSelected} />
|
||||
<MDIcon size={1} path={mdiMagnify} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit">
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import React, { useRef } from 'react';
|
||||
import { Box, Icon, Icons, Text, Scroll } from 'folds';
|
||||
import { Box, Text, Scroll } from 'folds';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
|
||||
import { MessageSearch } from '../../../features/message-search';
|
||||
import { useHomeRooms } from './useHomeRooms';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiMagnify } from '@mdi/js';
|
||||
|
||||
export function HomeSearch() {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
|
@ -13,7 +15,7 @@ export function HomeSearch() {
|
|||
<Page>
|
||||
<PageHeader>
|
||||
<Box grow="Yes" justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Icon size="400" src={Icons.Search} />
|
||||
<MDIcon size={1} path={mdiMagnify} />
|
||||
<Text size="H3">
|
||||
{getText('msg_search.title')}
|
||||
</Text>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React from 'react';
|
||||
import { Avatar, Box, Icon, Icons, Text } from 'folds';
|
||||
import { Avatar, Box, Text } from 'folds';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { NavCategory, NavItem, NavItemContent, NavLink } from '../../../components/nav';
|
||||
import { getInboxInvitesPath, getInboxNotificationsPath } from '../../pathUtils';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import {
|
||||
useInboxInvitesSelected,
|
||||
useInboxNotificationsSelected,
|
||||
|
@ -12,6 +13,7 @@ import { allInvitesAtom } from '../../../state/room-list/inviteList';
|
|||
import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper';
|
||||
import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiEmail, mdiEmailOutline, mdiMail, mdiMailboxOutline, mdiMessageAlert, mdiMessageAlertOutline } from '@mdi/js';
|
||||
|
||||
function InvitesNavItem() {
|
||||
const invitesSelected = useInboxInvitesSelected();
|
||||
|
@ -29,7 +31,7 @@ function InvitesNavItem() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Mail} size="100" filled={invitesSelected} />
|
||||
<MDIcon size={1} path={invitesSelected ? mdiEmail : mdiEmailOutline} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
|
@ -68,7 +70,7 @@ export function Inbox() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.MessageUnread} size="100" filled={notificationsSelected} />
|
||||
<MDIcon size={1} path={notificationsSelected ? mdiMessageAlert : mdiMessageAlertOutline} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
|
|
|
@ -3,8 +3,6 @@ import {
|
|||
Avatar,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
Icons,
|
||||
Overlay,
|
||||
OverlayBackdrop,
|
||||
OverlayCenter,
|
||||
|
@ -15,6 +13,7 @@ import {
|
|||
config,
|
||||
} from 'folds';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { MatrixError, Room } from 'matrix-js-sdk';
|
||||
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
|
||||
|
@ -40,6 +39,7 @@ import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback';
|
|||
import { useRoomNavigate } from '../../../hooks/useRoomNavigate';
|
||||
import { useRoomTopic } from '../../../hooks/useRoomMeta';
|
||||
import { getText, translate } from '../../../../lang';
|
||||
import { mdiMail } from '@mdi/js';
|
||||
|
||||
const COMPACT_CARD_WIDTH = 548;
|
||||
|
||||
|
@ -227,7 +227,7 @@ export function Invites() {
|
|||
<Page>
|
||||
<PageHeader>
|
||||
<Box grow="Yes" justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Icon size="400" src={Icons.Mail} />
|
||||
<MDIcon size={1} path={mdiMail} />
|
||||
<Text size="H3">
|
||||
{getText('inbox.invites.title')}
|
||||
</Text>
|
||||
|
|
|
@ -5,15 +5,14 @@ import {
|
|||
Box,
|
||||
Chip,
|
||||
Header,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Scroll,
|
||||
Text,
|
||||
config,
|
||||
toRem,
|
||||
} from 'folds';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import {
|
||||
INotification,
|
||||
INotificationsResponse,
|
||||
|
@ -71,6 +70,7 @@ import { VirtualTile } from '../../../components/virtualizer';
|
|||
import { UserAvatar } from '../../../components/user-avatar';
|
||||
import { EncryptedContent } from '../../../features/room/message';
|
||||
import { getText, translate } from '../../../../lang';
|
||||
import { mdiAccount, mdiCheck, mdiCheckAll, mdiChevronUp, mdiMessage } from '@mdi/js';
|
||||
|
||||
type RoomNotificationsGroup = {
|
||||
roomId: string;
|
||||
|
@ -382,7 +382,7 @@ function RoomNotificationsGroupComp({
|
|||
variant="Primary"
|
||||
radii="Pill"
|
||||
onClick={handleMarkAsRead}
|
||||
before={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
before={<MDIcon size={0.6} path={mdiCheckAll} />}
|
||||
>
|
||||
<Text size="T200">{getText('notifications.mark_as_read')}</Text>
|
||||
</Chip>
|
||||
|
@ -421,7 +421,7 @@ function RoomNotificationsGroupComp({
|
|||
: undefined
|
||||
}
|
||||
alt={displayName}
|
||||
renderFallback={() => <Icon size="200" src={Icons.User} filled />}
|
||||
renderFallback={() => <MDIcon size={1} path={mdiAccount} />}
|
||||
/>
|
||||
</Avatar>
|
||||
</AvatarBase>
|
||||
|
@ -550,7 +550,7 @@ export function Notifications() {
|
|||
<Page>
|
||||
<PageHeader>
|
||||
<Box grow="Yes" justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Icon size="400" src={Icons.Message} />
|
||||
<MDIcon size={1} path={mdiMessage} />
|
||||
<Text size="H3">
|
||||
{getText('notifications.title')}
|
||||
</Text>
|
||||
|
@ -570,7 +570,7 @@ export function Notifications() {
|
|||
onClick={() => setOnlyHighlighted(false)}
|
||||
variant={!onlyHighlight ? 'Success' : 'Surface'}
|
||||
aria-pressed={!onlyHighlight}
|
||||
before={!onlyHighlight && <Icon size="100" src={Icons.Check} />}
|
||||
before={!onlyHighlight && <MDIcon size={0.7} path={mdiCheck} />}
|
||||
outlined
|
||||
>
|
||||
<Text size="T200">{getText('notifications.filter.all')}</Text>
|
||||
|
@ -579,7 +579,7 @@ export function Notifications() {
|
|||
onClick={() => setOnlyHighlighted(true)}
|
||||
variant={onlyHighlight ? 'Success' : 'Surface'}
|
||||
aria-pressed={onlyHighlight}
|
||||
before={onlyHighlight && <Icon size="100" src={Icons.Check} />}
|
||||
before={onlyHighlight && <MDIcon size={0.7} path={mdiCheck} />}
|
||||
outlined
|
||||
>
|
||||
<Text size="T200">{getText('notifications.filter.highlighted')}</Text>
|
||||
|
@ -599,7 +599,7 @@ export function Notifications() {
|
|||
size="300"
|
||||
aria-label={getText('scroll_to_top')}
|
||||
>
|
||||
<Icon src={Icons.ChevronTop} size="300" />
|
||||
<MDIcon size={1} path={mdiChevronUp} />
|
||||
</IconButton>
|
||||
</ScrollTopContainer>
|
||||
<div
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React, { MouseEventHandler, forwardRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds';
|
||||
import { Box, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { useDirects } from '../../../state/hooks/roomList';
|
||||
|
@ -23,6 +24,7 @@ import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
|
|||
import { useDirectRooms } from '../direct/useDirectRooms';
|
||||
import { markAsRead } from '../../../../client/action/notifications';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiAccount, mdiAccountOutline, mdiCheckAll } from '@mdi/js';
|
||||
|
||||
type DirectMenuProps = {
|
||||
requestClose: () => void;
|
||||
|
@ -43,7 +45,7 @@ const DirectMenu = forwardRef<HTMLDivElement, DirectMenuProps>(({ requestClose }
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<MDIcon path={mdiCheckAll} size={1} />}
|
||||
radii="300"
|
||||
aria-disabled={!unread}
|
||||
>
|
||||
|
@ -98,7 +100,7 @@ export function DirectTab() {
|
|||
onClick={handleDirectClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
>
|
||||
<Icon src={Icons.User} filled={directSelected} />
|
||||
<MDIcon size={1} path={directSelected ? mdiAccount : mdiAccountOutline} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
|
|
|
@ -2,13 +2,14 @@ import React from 'react';
|
|||
import { Icon, Icons } from 'folds';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { SidebarAvatar, SidebarItem, SidebarItemTooltip } from '../../../components/sidebar';
|
||||
import { useExploreSelected } from '../../../hooks/router/useExploreSelected';
|
||||
import {
|
||||
getExploreFeaturedPath,
|
||||
getExplorePath,
|
||||
getExploreServerPath,
|
||||
joinPathComponent,
|
||||
getExploreFeaturedPath,
|
||||
getExplorePath,
|
||||
getExploreServerPath,
|
||||
joinPathComponent,
|
||||
} from '../../pathUtils';
|
||||
import { useClientConfig } from '../../../hooks/useClientConfig';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
|
@ -16,50 +17,51 @@ import { getMxIdServer } from '../../../utils/matrix';
|
|||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiCompass, mdiCompassOutline } from '@mdi/js';
|
||||
|
||||
export function ExploreTab() {
|
||||
const mx = useMatrixClient();
|
||||
const screenSize = useScreenSizeContext();
|
||||
const clientConfig = useClientConfig();
|
||||
const navigate = useNavigate();
|
||||
const navToActivePath = useAtomValue(useNavToActivePathAtom());
|
||||
const mx = useMatrixClient();
|
||||
const screenSize = useScreenSizeContext();
|
||||
const clientConfig = useClientConfig();
|
||||
const navigate = useNavigate();
|
||||
const navToActivePath = useAtomValue(useNavToActivePathAtom());
|
||||
|
||||
const exploreSelected = useExploreSelected();
|
||||
const exploreSelected = useExploreSelected();
|
||||
|
||||
const handleExploreClick = () => {
|
||||
if (screenSize === ScreenSize.Mobile) {
|
||||
navigate(getExplorePath());
|
||||
return;
|
||||
}
|
||||
const handleExploreClick = () => {
|
||||
if (screenSize === ScreenSize.Mobile) {
|
||||
navigate(getExplorePath());
|
||||
return;
|
||||
}
|
||||
|
||||
const activePath = navToActivePath.get('explore');
|
||||
if (activePath) {
|
||||
navigate(joinPathComponent(activePath));
|
||||
return;
|
||||
}
|
||||
const activePath = navToActivePath.get('explore');
|
||||
if (activePath) {
|
||||
navigate(joinPathComponent(activePath));
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientConfig.featuredCommunities?.openAsDefault) {
|
||||
navigate(getExploreFeaturedPath());
|
||||
return;
|
||||
}
|
||||
const userId = mx.getUserId();
|
||||
const userServer = userId ? getMxIdServer(userId) : undefined;
|
||||
if (userServer) {
|
||||
navigate(getExploreServerPath(userServer));
|
||||
return;
|
||||
}
|
||||
navigate(getExplorePath());
|
||||
};
|
||||
if (clientConfig.featuredCommunities?.openAsDefault) {
|
||||
navigate(getExploreFeaturedPath());
|
||||
return;
|
||||
}
|
||||
const userId = mx.getUserId();
|
||||
const userServer = userId ? getMxIdServer(userId) : undefined;
|
||||
if (userServer) {
|
||||
navigate(getExploreServerPath(userServer));
|
||||
return;
|
||||
}
|
||||
navigate(getExplorePath());
|
||||
};
|
||||
|
||||
return (
|
||||
<SidebarItem active={exploreSelected}>
|
||||
<SidebarItemTooltip tooltip={getText('explore.title')}>
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleExploreClick}>
|
||||
<Icon src={Icons.Explore} filled={exploreSelected} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
</SidebarItem>
|
||||
);
|
||||
return (
|
||||
<SidebarItem active={exploreSelected}>
|
||||
<SidebarItemTooltip tooltip={getText('explore.title')}>
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleExploreClick}>
|
||||
<MDIcon size={1} path={exploreSelected ? mdiCompass : mdiCompassOutline} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
</SidebarItem>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { MouseEventHandler, forwardRef, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds';
|
||||
import { Box, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import { useOrphanRooms } from '../../../state/hooks/roomList';
|
||||
|
@ -8,6 +8,7 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
|||
import { mDirectAtom } from '../../../state/mDirectList';
|
||||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||
import Icon, { Icon as MDIcon } from '@mdi/react';
|
||||
import { roomToUnreadAtom } from '../../../state/room/roomToUnread';
|
||||
import { getHomePath, joinPathComponent } from '../../pathUtils';
|
||||
import { useRoomsUnread } from '../../../state/hooks/unread';
|
||||
|
@ -24,6 +25,7 @@ import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
|
|||
import { useHomeRooms } from '../home/useHomeRooms';
|
||||
import { markAsRead } from '../../../../client/action/notifications';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiCheckAll, mdiHome, mdiHomeOutline } from '@mdi/js';
|
||||
|
||||
type HomeMenuProps = {
|
||||
requestClose: () => void;
|
||||
|
@ -44,7 +46,7 @@ const HomeMenu = forwardRef<HTMLDivElement, HomeMenuProps>(({ requestClose }, re
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<Icon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
aria-disabled={!unread}
|
||||
>
|
||||
|
@ -100,7 +102,7 @@ export function HomeTab() {
|
|||
onClick={handleHomeClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
>
|
||||
<Icon src={Icons.Home} filled={homeSelected} />
|
||||
<MDIcon size={1} path={homeSelected ? mdiHome : mdiHomeOutline} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Icon, Icons } from 'folds';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import {
|
||||
SidebarAvatar,
|
||||
|
@ -20,6 +21,7 @@ import { UnreadBadge } from '../../../components/unread-badge';
|
|||
import { ScreenSize, useScreenSizeContext } from '../../../hooks/useScreenSize';
|
||||
import { useNavToActivePathAtom } from '../../../state/hooks/navToActivePath';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiInbox, mdiInboxOutline } from '@mdi/js';
|
||||
|
||||
export function InboxTab() {
|
||||
const screenSize = useScreenSizeContext();
|
||||
|
@ -49,7 +51,7 @@ export function InboxTab() {
|
|||
<SidebarItemTooltip tooltip={getText('inbox.title')}>
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleInboxClick}>
|
||||
<Icon src={Icons.Inbox} filled={inboxSelected} />
|
||||
<MDIcon path={inboxSelected ? mdiInbox : mdiInboxOutline} size={1} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
</SidebarItemTooltip>
|
||||
|
|
|
@ -12,9 +12,7 @@ import React, {
|
|||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Box,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Line,
|
||||
Menu,
|
||||
MenuItem,
|
||||
|
@ -24,6 +22,7 @@ import {
|
|||
config,
|
||||
toRem,
|
||||
} from 'folds';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { Room } from 'matrix-js-sdk';
|
||||
import {
|
||||
|
@ -91,6 +90,7 @@ import { markAsRead } from '../../../../client/action/notifications';
|
|||
import { copyToClipboard } from '../../../utils/dom';
|
||||
import { openInviteUser, openSpaceSettings } from '../../../../client/action/navigation';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiAccount, mdiAccountPlus, mdiCheckAll, mdiChevronUp, mdiCog, mdiLink, mdiLinkVariant, mdiPin, mdiPlus, mdiTune } from '@mdi/js';
|
||||
|
||||
type SpaceMenuProps = {
|
||||
room: Room;
|
||||
|
@ -145,7 +145,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<MDIcon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
disabled={!unread}
|
||||
>
|
||||
|
@ -158,7 +158,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(
|
|||
size="300"
|
||||
radii="300"
|
||||
onClick={handleUnpin}
|
||||
after={<Icon size="100" src={Icons.Pin} />}
|
||||
after={<MDIcon size={1} path={mdiPin} />}
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
{getText('btn.unpin')}
|
||||
|
@ -173,7 +173,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(
|
|||
variant="Primary"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.UserPlus} />}
|
||||
after={<MDIcon size={1} path={mdiAccountPlus} />}
|
||||
radii="300"
|
||||
disabled={!canInvite}
|
||||
>
|
||||
|
@ -184,7 +184,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleCopyLink}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Link} />}
|
||||
after={<MDIcon size={1} path={mdiLinkVariant} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -194,7 +194,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(
|
|||
<MenuItem
|
||||
onClick={handleRoomSettings}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Setting} />}
|
||||
after={<MDIcon size={1} path={mdiCog} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -504,7 +504,7 @@ function OpenedSpaceFolder({ folder, onClose, children }: OpenedSpaceFolderProps
|
|||
<SidebarFolderDropTarget ref={aboveTargetRef} position="Top" />
|
||||
<SidebarAvatar size="300">
|
||||
<IconButton data-id={folder.id} size="300" variant="Background" onClick={onClose}>
|
||||
<Icon size="400" src={Icons.ChevronTop} filled />
|
||||
<MDIcon size={1} path={mdiChevronUp} />
|
||||
</IconButton>
|
||||
</SidebarAvatar>
|
||||
{children}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useRef } from 'react';
|
||||
import { Box, Icon, Icons, Text, Scroll } from 'folds';
|
||||
import { Box, Text, Scroll } from 'folds';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { Page, PageContent, PageContentCenter, PageHeader } from '../../../components/page';
|
||||
import { MessageSearch } from '../../../features/message-search';
|
||||
|
@ -10,6 +10,8 @@ import { mDirectAtom } from '../../../state/mDirectList';
|
|||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
import { getText } from '../../../../lang';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { mdiMagnify } from '@mdi/js';
|
||||
|
||||
export function SpaceSearch() {
|
||||
const mx = useMatrixClient();
|
||||
|
@ -28,7 +30,7 @@ export function SpaceSearch() {
|
|||
<Page>
|
||||
<PageHeader>
|
||||
<Box grow="Yes" justifyContent="Center" alignItems="Center" gap="200">
|
||||
<Icon size="400" src={Icons.Search} />
|
||||
<MDIcon size={1} path={mdiMagnify} />
|
||||
<Text size="H3" truncate>
|
||||
{getText('home.search_messages')}
|
||||
</Text>
|
||||
|
|
|
@ -10,9 +10,7 @@ import { useAtom, useAtomValue } from 'jotai';
|
|||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
Icon,
|
||||
IconButton,
|
||||
Icons,
|
||||
Line,
|
||||
Menu,
|
||||
MenuItem,
|
||||
|
@ -22,6 +20,7 @@ import {
|
|||
config,
|
||||
toRem,
|
||||
} from 'folds';
|
||||
import { Icon as MDIcon } from '@mdi/react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { IJoinRuleEventContent, JoinRule, Room } from 'matrix-js-sdk';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
|
@ -74,6 +73,7 @@ import { useClosedNavCategoriesAtom } from '../../../state/hooks/closedNavCatego
|
|||
import { useStateEvent } from '../../../hooks/useStateEvent';
|
||||
import { StateEvent } from '../../../../types/matrix/room';
|
||||
import { getText } from '../../../../lang';
|
||||
import { mdiAccountPlus, mdiArrowLeft, mdiCheckAll, mdiCog, mdiDotsVertical, mdiFlag, mdiFlagOutline, mdiLink, mdiLock, mdiMagnify } from '@mdi/js';
|
||||
|
||||
type SpaceMenuProps = {
|
||||
room: Room;
|
||||
|
@ -121,7 +121,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
|||
<MenuItem
|
||||
onClick={handleMarkAsRead}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.CheckTwice} />}
|
||||
after={<MDIcon size={1} path={mdiCheckAll} />}
|
||||
radii="300"
|
||||
disabled={!unread}
|
||||
>
|
||||
|
@ -137,7 +137,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
|||
variant="Primary"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.UserPlus} />}
|
||||
after={<MDIcon size={1} path={mdiAccountPlus} />}
|
||||
radii="300"
|
||||
disabled={!canInvite}
|
||||
>
|
||||
|
@ -148,7 +148,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
|||
<MenuItem
|
||||
onClick={handleCopyLink}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Link} />}
|
||||
after={<MDIcon size={1} path={mdiLink} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -158,7 +158,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
|||
<MenuItem
|
||||
onClick={handleRoomSettings}
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.Setting} />}
|
||||
after={<MDIcon size={1} path={mdiCog} />}
|
||||
radii="300"
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} as="span" size="T300">
|
||||
|
@ -176,7 +176,7 @@ const SpaceMenu = forwardRef<HTMLDivElement, SpaceMenuProps>(({ room, requestClo
|
|||
variant="Critical"
|
||||
fill="None"
|
||||
size="300"
|
||||
after={<Icon size="100" src={Icons.ArrowGoLeft} />}
|
||||
after={<MDIcon size={1} path={mdiArrowLeft} />}
|
||||
radii="300"
|
||||
aria-pressed={promptLeave}
|
||||
>
|
||||
|
@ -222,14 +222,14 @@ function SpaceHeader() {
|
|||
<PageNavHeader>
|
||||
<Box alignItems="Center" grow="Yes" gap="300">
|
||||
<Box grow="Yes" alignItems="Center" gap="100">
|
||||
{joinRules?.join_rule !== JoinRule.Public && <MDIcon size={0.7} path={mdiLock} />}
|
||||
<Text size="H4" truncate>
|
||||
{spaceName}
|
||||
</Text>
|
||||
{joinRules?.join_rule !== JoinRule.Public && <Icon src={Icons.Lock} size="50" />}
|
||||
</Box>
|
||||
<Box>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu}>
|
||||
<Icon src={Icons.VerticalDots} size="200" />
|
||||
<MDIcon size={1} path={mdiDotsVertical} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -334,7 +334,7 @@ export function Space() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Flag} size="100" filled={lobbySelected} />
|
||||
<MDIcon size={1} path={lobbySelected ? mdiFlag : mdiFlagOutline} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
|
@ -350,7 +350,7 @@ export function Space() {
|
|||
<NavItemContent>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Search} size="100" filled={searchSelected} />
|
||||
<MDIcon size={1} path={mdiMagnify} />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
|
|
|
@ -863,5 +863,6 @@
|
|||
"settings.presence.title": "Presence status",
|
||||
"settings.new_design_input.title": "New input design",
|
||||
"settings.new_design_input.desc": "Apply new design for message composer.",
|
||||
"title.incoming_call": "Incoming call from {0}"
|
||||
"title.incoming_call": "Incoming call from {0}",
|
||||
"title.incoming_video_call": "Incoming video call from {0}"
|
||||
}
|
|
@ -21,5 +21,6 @@
|
|||
"login.forgot_password_link": "ふぉるごっとぱすをーど?",
|
||||
"login.login_button": "ろぎん",
|
||||
"error.register.invalid_request": "Failed to register.ようろれくべすとだたわずいんわりど。",
|
||||
"title.incoming_call": "インコメンがカール {0}"
|
||||
"title.incoming_call": "インコメンがカール {0}",
|
||||
"title.incoming_video_call": "インコメンがウィデオカール {0}"
|
||||
}
|
|
@ -863,5 +863,6 @@
|
|||
"settings.presence.title": "Статус",
|
||||
"settings.new_design_input.title": "Новый дизайн ввода сообщения",
|
||||
"settings.new_design_input.desc": "Использовать новый дизайн редактора сообщений.",
|
||||
"title.incoming_call": "Входящий звонок от {0}"
|
||||
"title.incoming_call": "Входящий звонок от {0}",
|
||||
"title.incoming_video_call": "Входящий видеозвонок от {0}"
|
||||
}
|
Loading…
Add table
Reference in a new issue