Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 888e741f94 | |||
| 1f0686ddaf | |||
| 19c47fe88e | |||
| 60c2c97ba6 |
Generated
+847
-551
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@ export function ImagePackView({ address, requestClose }: ImagePackViewProps) {
|
||||
</Chip>
|
||||
</Box>
|
||||
<Box shrink="No">
|
||||
<IconButton onClick={requestClose} variant="Surface">
|
||||
<IconButton onClick={requestClose} variant="Surface" aria-label="Close">
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
||||
@@ -56,7 +56,7 @@ export function LeaveRoomPrompt({ roomId, onDone, onCancel }: LeaveRoomPromptPro
|
||||
escapeDeactivates: stopPropagation,
|
||||
}}
|
||||
>
|
||||
<Dialog variant="Surface">
|
||||
<Dialog variant="Surface" aria-labelledby="leave-room-dialog-title">
|
||||
<Header
|
||||
style={{
|
||||
padding: `0 ${config.space.S200} 0 ${config.space.S400}`,
|
||||
@@ -66,9 +66,9 @@ export function LeaveRoomPrompt({ roomId, onDone, onCancel }: LeaveRoomPromptPro
|
||||
size="500"
|
||||
>
|
||||
<Box grow="Yes">
|
||||
<Text size="H4">Leave Room</Text>
|
||||
<Text size="H4" id="leave-room-dialog-title">Leave Room</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={onCancel} radii="300">
|
||||
<IconButton size="300" onClick={onCancel} radii="300" aria-label="Cancel">
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
|
||||
@@ -48,6 +48,7 @@ export function FileDownloadButton({ filename, url, mimeType, encInfo }: FileDow
|
||||
variant={hasError ? 'Critical' : 'SurfaceVariant'}
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label={downloading ? 'Downloading...' : hasError ? 'Download failed, click to retry' : 'Download file'}
|
||||
>
|
||||
{downloading ? (
|
||||
<Spinner size="100" variant={hasError ? 'Critical' : 'Secondary'} />
|
||||
|
||||
@@ -173,6 +173,7 @@ export function AudioContent({
|
||||
size="300"
|
||||
radii="Pill"
|
||||
onClick={() => setMute(!mute)}
|
||||
aria-label={mute ? 'Unmute' : 'Mute'}
|
||||
aria-pressed={mute}
|
||||
>
|
||||
<Icon src={mute ? Icons.VolumeMute : Icons.VolumeHigh} size="50" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Box, Text } from 'folds';
|
||||
import { RelationsEvent } from 'matrix-js-sdk/lib/models/relations';
|
||||
import { RoomEvent } from 'matrix-js-sdk';
|
||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||
|
||||
type PollTextValue = Array<{ body: string }> | string;
|
||||
@@ -142,6 +143,21 @@ export function PollContent({
|
||||
unstableRels?.on(RelationsEvent.Add, refresh);
|
||||
unstableRels?.on(RelationsEvent.Remove, refresh);
|
||||
unstableRels?.on(RelationsEvent.Redaction, refresh);
|
||||
// Also listen at room level: if no votes exist yet, the Relations object is null
|
||||
// and the listeners above are no-ops. The room timeline event catches the first vote.
|
||||
const onTimeline = (ev: any) => {
|
||||
const type = ev.getType?.();
|
||||
const relatesTo = ev.getContent?.()?.['m.relates_to'];
|
||||
if (
|
||||
(type === 'm.poll.response' || type === 'org.matrix.msc3381.poll.response') &&
|
||||
relatesTo?.event_id === eventId
|
||||
) {
|
||||
refresh();
|
||||
}
|
||||
};
|
||||
const room2 = mx.getRoom(roomId);
|
||||
room2?.on(RoomEvent.Timeline, onTimeline);
|
||||
|
||||
return () => {
|
||||
stableRels?.off(RelationsEvent.Add, refresh);
|
||||
stableRels?.off(RelationsEvent.Remove, refresh);
|
||||
@@ -149,6 +165,7 @@ export function PollContent({
|
||||
unstableRels?.off(RelationsEvent.Add, refresh);
|
||||
unstableRels?.off(RelationsEvent.Remove, refresh);
|
||||
unstableRels?.off(RelationsEvent.Redaction, refresh);
|
||||
room2?.off(RoomEvent.Timeline, onTimeline);
|
||||
};
|
||||
}, [mx, roomId, eventId, refresh]);
|
||||
|
||||
|
||||
@@ -17,16 +17,17 @@ export const RoomTopicViewer = as<
|
||||
size="300"
|
||||
flexHeight
|
||||
className={classNames(css.ModalFlex, className)}
|
||||
aria-labelledby="room-topic-title"
|
||||
{...props}
|
||||
ref={ref}
|
||||
>
|
||||
<Header className={css.ModalHeader} variant="Surface" size="500">
|
||||
<Box grow="Yes">
|
||||
<Text size="H4" truncate>
|
||||
<Text size="H4" truncate id="room-topic-title">
|
||||
{name}
|
||||
</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={requestClose} radii="300">
|
||||
<IconButton size="300" onClick={requestClose} radii="300" aria-label="Close">
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
|
||||
@@ -245,7 +245,7 @@ type RoomNavItemProps = {
|
||||
showAvatar?: boolean;
|
||||
direct?: boolean;
|
||||
};
|
||||
export function RoomNavItem({
|
||||
function RoomNavItem_({
|
||||
room,
|
||||
selected,
|
||||
showAvatar,
|
||||
@@ -440,3 +440,4 @@ export function RoomNavItem({
|
||||
</NavItem>
|
||||
);
|
||||
}
|
||||
export const RoomNavItem = React.memo(RoomNavItem_);
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
} from 'folds';
|
||||
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { GifPicker } from '../../components/GifPicker';
|
||||
const GifPicker = React.lazy(() => import('../../components/GifPicker').then((m) => ({ default: m.GifPicker })));
|
||||
import { useClientConfig } from '../../hooks/useClientConfig';
|
||||
import {
|
||||
CustomEditor,
|
||||
@@ -56,7 +56,8 @@ import {
|
||||
trimCommand,
|
||||
getMentions,
|
||||
} from '../../components/editor';
|
||||
import { EmojiBoard, EmojiBoardTab } from '../../components/emoji-board';
|
||||
import { EmojiBoardTab } from '../../components/emoji-board/types';
|
||||
const EmojiBoard = React.lazy(() => import('../../components/emoji-board').then((m) => ({ default: m.EmojiBoard })));
|
||||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import {
|
||||
TUploadContent,
|
||||
@@ -94,6 +95,7 @@ import { getImageUrlBlob, loadImageElement } from '../../utils/dom';
|
||||
import { safeFile } from '../../utils/mimeTypes';
|
||||
import { fulfilledPromiseSettledResult } from '../../utils/common';
|
||||
import { useSetting } from '../../state/hooks/settings';
|
||||
import { useAlive } from '../../hooks/useAlive';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
import {
|
||||
getAudioMsgContent,
|
||||
@@ -141,6 +143,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
const powerLevels = usePowerLevelsContext();
|
||||
const creators = useRoomCreators(room);
|
||||
|
||||
const alive = useAlive();
|
||||
const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId));
|
||||
const [replyDraft, setReplyDraft] = useAtom(roomIdToReplyDraftAtomFamily(roomId));
|
||||
const replyUserID = replyDraft?.userId;
|
||||
@@ -250,9 +253,14 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
useCallback((width) => setHideStickerBtn(width < 500), [])
|
||||
);
|
||||
|
||||
const didRestoreDraft = React.useRef(false);
|
||||
useEffect(() => {
|
||||
if (didRestoreDraft.current) return;
|
||||
didRestoreDraft.current = true;
|
||||
if (msgDraft.length > 0) {
|
||||
Transforms.insertFragment(editor, msgDraft);
|
||||
}, [editor, msgDraft]);
|
||||
}
|
||||
}, [editor]);
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
@@ -490,6 +498,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('GIF send failed', e);
|
||||
if (!alive()) return;
|
||||
setGifError('Failed to send GIF. Please try again.');
|
||||
setTimeout(() => setGifError(null), 4000);
|
||||
}
|
||||
@@ -682,7 +691,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
: emojiBtnRef.current?.getBoundingClientRect() ?? undefined
|
||||
}
|
||||
content={
|
||||
<EmojiBoard
|
||||
<React.Suspense fallback={null}><EmojiBoard
|
||||
tab={emojiBoardTab}
|
||||
onTabChange={setEmojiBoardTab}
|
||||
imagePackRooms={imagePackRooms}
|
||||
@@ -699,7 +708,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
return t;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
/></React.Suspense>
|
||||
}
|
||||
>
|
||||
{!hideStickerBtn && (
|
||||
@@ -750,11 +759,11 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
: undefined
|
||||
}
|
||||
content={
|
||||
<GifPicker
|
||||
<React.Suspense fallback={null}><GifPicker
|
||||
apiKey={gifApiKey}
|
||||
onSelect={handleGifSelect}
|
||||
requestClose={() => setGifOpen(false)}
|
||||
/>
|
||||
/></React.Suspense>
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
|
||||
@@ -543,6 +543,8 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
const [timeline, setTimeline] = useState<Timeline>(() =>
|
||||
eventId ? getEmptyTimeline() : getInitialTimeline(room)
|
||||
);
|
||||
const timelineRef = React.useRef(timeline);
|
||||
timelineRef.current = timeline;
|
||||
const eventsLength = getTimelinesEventsCount(timeline.linkedTimelines);
|
||||
const liveTimelineLinked =
|
||||
timeline.linkedTimelines[timeline.linkedTimelines.length - 1] === getLiveTimeline(room);
|
||||
@@ -659,7 +661,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
) => {
|
||||
const evtTimeline = getEventTimeline(room, evtId);
|
||||
const absoluteIndex =
|
||||
evtTimeline && getEventIdAbsoluteIndex(timeline.linkedTimelines, evtTimeline, evtId);
|
||||
evtTimeline && getEventIdAbsoluteIndex(timelineRef.current.linkedTimelines, evtTimeline, evtId);
|
||||
|
||||
if (typeof absoluteIndex === 'number') {
|
||||
const scrolled = scrollToItem(absoluteIndex, {
|
||||
@@ -678,7 +680,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
loadEventTimeline(evtId);
|
||||
}
|
||||
},
|
||||
[room, timeline, scrollToItem, loadEventTimeline]
|
||||
[room, scrollToItem, loadEventTimeline]
|
||||
);
|
||||
|
||||
useLiveTimelineRefresh(
|
||||
@@ -847,13 +849,14 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
const timer = setTimeout(() => {
|
||||
if (!alive()) return;
|
||||
setFocusItem((currentItem) => {
|
||||
if (currentItem === focusItem) return undefined;
|
||||
return currentItem;
|
||||
});
|
||||
}, 2000);
|
||||
return () => clearTimeout(timer);
|
||||
}, [alive, focusItem, scrollToItem]);
|
||||
|
||||
// scroll to bottom of timeline
|
||||
|
||||
@@ -532,7 +532,7 @@ export function RoomViewHeader({ callView }: { callView?: boolean }) {
|
||||
}
|
||||
>
|
||||
{(triggerRef) => (
|
||||
<IconButton fill="None" ref={triggerRef} onClick={handleSearchClick}>
|
||||
<IconButton fill="None" ref={triggerRef} onClick={handleSearchClick} aria-label="Search">
|
||||
<Icon size="400" src={Icons.Search} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -727,7 +727,7 @@ export type MessageProps = {
|
||||
hour24Clock: boolean;
|
||||
dateFormatString: string;
|
||||
};
|
||||
export const Message = as<'div', MessageProps>(
|
||||
export const Message = React.memo(as<'div', MessageProps>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
@@ -984,6 +984,7 @@ export const Message = as<'div', MessageProps>(
|
||||
variant="SurfaceVariant"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Add reaction"
|
||||
aria-pressed={!!emojiBoardAnchor}
|
||||
>
|
||||
<Icon src={Icons.SmilePlus} size="100" />
|
||||
@@ -996,6 +997,7 @@ export const Message = as<'div', MessageProps>(
|
||||
variant="SurfaceVariant"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Reply"
|
||||
>
|
||||
<Icon src={Icons.ReplyArrow} size="100" />
|
||||
</IconButton>
|
||||
@@ -1006,6 +1008,7 @@ export const Message = as<'div', MessageProps>(
|
||||
variant="SurfaceVariant"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Reply in thread"
|
||||
>
|
||||
<Icon src={Icons.ThreadPlus} size="100" />
|
||||
</IconButton>
|
||||
@@ -1016,6 +1019,7 @@ export const Message = as<'div', MessageProps>(
|
||||
variant="SurfaceVariant"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Edit message"
|
||||
>
|
||||
<Icon src={Icons.Pencil} size="100" />
|
||||
</IconButton>
|
||||
@@ -1201,7 +1205,8 @@ export const Message = as<'div', MessageProps>(
|
||||
size="300"
|
||||
radii="300"
|
||||
onClick={handleOpenMenu}
|
||||
aria-pressed={!!menuAnchor}
|
||||
aria-expanded={!!menuAnchor}
|
||||
aria-haspopup="menu"
|
||||
>
|
||||
<Icon src={Icons.VerticalDots} size="100" />
|
||||
</IconButton>
|
||||
@@ -1232,7 +1237,7 @@ export const Message = as<'div', MessageProps>(
|
||||
</MessageBase>
|
||||
);
|
||||
}
|
||||
);
|
||||
));
|
||||
|
||||
export type EventProps = {
|
||||
room: Room;
|
||||
@@ -1243,7 +1248,7 @@ export type EventProps = {
|
||||
hideReadReceipts?: boolean;
|
||||
showDeveloperTools?: boolean;
|
||||
};
|
||||
export const Event = as<'div', EventProps>(
|
||||
export const Event = React.memo(as<'div', EventProps>(
|
||||
(
|
||||
{
|
||||
className,
|
||||
@@ -1370,7 +1375,8 @@ export const Event = as<'div', EventProps>(
|
||||
size="300"
|
||||
radii="300"
|
||||
onClick={handleOpenMenu}
|
||||
aria-pressed={!!menuAnchor}
|
||||
aria-expanded={!!menuAnchor}
|
||||
aria-haspopup="menu"
|
||||
>
|
||||
<Icon src={Icons.VerticalDots} size="100" />
|
||||
</IconButton>
|
||||
@@ -1383,4 +1389,4 @@ export const Event = as<'div', EventProps>(
|
||||
</MessageBase>
|
||||
);
|
||||
}
|
||||
);
|
||||
));
|
||||
|
||||
@@ -552,23 +552,23 @@ function DateHint({ hasChanges, handleReset }: DateHintProps) {
|
||||
>
|
||||
{hasChanges ? (
|
||||
<IconButton
|
||||
tabIndex={-1}
|
||||
onClick={handleReset}
|
||||
type="reset"
|
||||
variant="Secondary"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Reset to default"
|
||||
>
|
||||
<Icon src={Icons.Cross} size="100" />
|
||||
</IconButton>
|
||||
) : (
|
||||
<IconButton
|
||||
tabIndex={-1}
|
||||
onClick={handleOpenMenu}
|
||||
type="button"
|
||||
variant="Secondary"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Setting info"
|
||||
aria-pressed={!!anchor}
|
||||
>
|
||||
<Icon style={{ opacity: config.opacity.P300 }} size="100" src={Icons.Info} />
|
||||
|
||||
@@ -6,6 +6,7 @@ type TypingStatusUpdater = (typing: boolean) => void;
|
||||
|
||||
export const useTypingStatusUpdater = (mx: MatrixClient, roomId: string): TypingStatusUpdater => {
|
||||
const statusSentTsRef = useRef<number>(0);
|
||||
const typingTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const sendTypingStatus: TypingStatusUpdater = useMemo(() => {
|
||||
statusSentTsRef.current = 0;
|
||||
@@ -19,9 +20,10 @@ export const useTypingStatusUpdater = (mx: MatrixClient, roomId: string): Typing
|
||||
const sentTs = Date.now();
|
||||
statusSentTsRef.current = sentTs;
|
||||
|
||||
// Don't believe server will timeout typing status;
|
||||
// Clear typing status after timeout if already not;
|
||||
setTimeout(() => {
|
||||
// Cancel any previous pending timeout before scheduling a new one
|
||||
if (typingTimerRef.current !== undefined) clearTimeout(typingTimerRef.current);
|
||||
typingTimerRef.current = setTimeout(() => {
|
||||
typingTimerRef.current = undefined;
|
||||
if (statusSentTsRef.current === sentTs) {
|
||||
mx.sendTyping(roomId, false, TYPING_TIMEOUT_MS);
|
||||
statusSentTsRef.current = 0;
|
||||
|
||||
@@ -92,12 +92,12 @@ function UsernameHint({ server }: { server: string }) {
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
tabIndex={-1}
|
||||
onClick={handleOpenMenu}
|
||||
type="button"
|
||||
variant="Background"
|
||||
size="300"
|
||||
radii="300"
|
||||
aria-label="Username format hint"
|
||||
aria-pressed={!!anchor}
|
||||
>
|
||||
<Icon style={{ opacity: config.opacity.P300 }} size="100" src={Icons.Info} />
|
||||
@@ -206,6 +206,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog
|
||||
defaultValue={defaultUsername ?? defaultEmail}
|
||||
style={{ paddingRight: config.space.S300 }}
|
||||
name="usernameInput"
|
||||
aria-label="Username or email"
|
||||
variant="Background"
|
||||
size="500"
|
||||
required
|
||||
@@ -227,7 +228,7 @@ export function PasswordLoginForm({ defaultUsername, defaultEmail }: PasswordLog
|
||||
<Text as="label" size="L400" priority="300">
|
||||
Password
|
||||
</Text>
|
||||
<PasswordInput name="passwordInput" variant="Background" size="500" outlined required />
|
||||
<PasswordInput name="passwordInput" aria-label="Password" variant="Background" size="500" outlined required />
|
||||
<Box alignItems="Start" justifyContent="SpaceBetween" gap="200">
|
||||
{loginState.status === AsyncStatus.Error && (
|
||||
<>
|
||||
|
||||
@@ -7,9 +7,29 @@ type ClientLayoutProps = {
|
||||
};
|
||||
export function ClientLayout({ nav, children }: ClientLayoutProps) {
|
||||
return (
|
||||
<>
|
||||
<a
|
||||
href="#main-content"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-40px',
|
||||
left: 0,
|
||||
padding: '8px 16px',
|
||||
background: '#000',
|
||||
color: '#fff',
|
||||
zIndex: 9999,
|
||||
borderRadius: '0 0 4px 0',
|
||||
transition: 'top 0.1s',
|
||||
}}
|
||||
onFocus={(e) => { (e.currentTarget as HTMLElement).style.top = '0'; }}
|
||||
onBlur={(e) => { (e.currentTarget as HTMLElement).style.top = '-40px'; }}
|
||||
>
|
||||
Skip to main content
|
||||
</a>
|
||||
<Box grow="Yes">
|
||||
<Box shrink="No">{nav}</Box>
|
||||
<Box grow="Yes">{children}</Box>
|
||||
<Box shrink="No" as="nav" aria-label="Room navigation">{nav}</Box>
|
||||
<Box grow="Yes" as="main" id="main-content">{children}</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ function ClientRootOptions({ mx }: { mx?: MatrixClient }) {
|
||||
variant="Background"
|
||||
fill="None"
|
||||
onClick={handleToggle}
|
||||
aria-label="Account options"
|
||||
>
|
||||
<Icon size="200" src={Icons.VerticalDots} />
|
||||
<PopOut
|
||||
|
||||
@@ -107,7 +107,7 @@ function DirectHeader() {
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu}>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu} aria-label="Direct messages options">
|
||||
<Icon src={Icons.VerticalDots} size="200" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
||||
@@ -44,7 +44,7 @@ export function DirectCreate() {
|
||||
<Box grow="Yes" alignItems="Center" gap="200">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -96,7 +96,7 @@ export function AddServer() {
|
||||
<Box grow="Yes">
|
||||
<Text size="H4">Add Server</Text>
|
||||
</Box>
|
||||
<IconButton size="300" onClick={() => setDialog(false)} radii="300">
|
||||
<IconButton size="300" onClick={() => setDialog(false)} radii="300" aria-label="Close">
|
||||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
|
||||
@@ -33,7 +33,7 @@ export function FeaturedRooms() {
|
||||
<Box shrink="No">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -499,7 +499,7 @@ export function PublicRooms() {
|
||||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -25,7 +25,7 @@ export function HomeCreateRoom() {
|
||||
<Box grow="Yes" alignItems="Center" gap="200">
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -121,7 +121,7 @@ function HomeHeader() {
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu}>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu} aria-label="Home options">
|
||||
<Icon src={Icons.VerticalDots} size="200" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
||||
@@ -19,7 +19,7 @@ export function HomeSearch() {
|
||||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -753,7 +753,7 @@ export function Invites() {
|
||||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -642,7 +642,7 @@ export function Notifications() {
|
||||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -522,7 +522,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}>
|
||||
<IconButton data-id={folder.id} size="300" variant="Background" onClick={onClose} aria-label="Close folder">
|
||||
<Icon size="400" src={Icons.ChevronTop} filled />
|
||||
</IconButton>
|
||||
</SidebarAvatar>
|
||||
|
||||
@@ -34,7 +34,7 @@ export function SpaceSearch() {
|
||||
{screenSize === ScreenSize.Mobile && (
|
||||
<BackRouteHandler>
|
||||
{(onBack) => (
|
||||
<IconButton onClick={onBack}>
|
||||
<IconButton onClick={onBack} aria-label="Back">
|
||||
<Icon src={Icons.ArrowLeft} />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
@@ -273,7 +273,7 @@ function SpaceHeader() {
|
||||
{joinRules?.join_rule !== JoinRule.Public && <Icon src={Icons.Lock} size="50" />}
|
||||
</Box>
|
||||
<Box shrink="No">
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu}>
|
||||
<IconButton aria-pressed={!!menuAnchor} variant="Background" onClick={handleOpenMenu} aria-label="Space options">
|
||||
<Icon src={Icons.VerticalDots} size="200" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user