Compare commits
3
Commits
14b6849f6e
...
2e8244dc67
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e8244dc67 | ||
|
|
e9d419f84c | ||
|
|
e0b1c50155 |
@@ -23,7 +23,7 @@ install() {
|
||||
python3 -m venv --without-pip "$VENV"
|
||||
curl -sS https://bootstrap.pypa.io/get-pip.py -o "$DIR/get-pip.py"
|
||||
"$VENV/bin/python" "$DIR/get-pip.py" -q
|
||||
"$VENV/bin/pip" install -q matrix-synapse
|
||||
"$VENV/bin/pip" install -q "matrix-synapse[url-preview]"
|
||||
fi
|
||||
if [ ! -f "$CFG" ]; then
|
||||
(cd "$DIR" && "$VENV/bin/python" -m synapse.app.homeserver \
|
||||
@@ -43,6 +43,9 @@ rc_joins: { local: { per_second: 1000, burst_count: 10000 }, remote: { per_secon
|
||||
rc_presence: { per_user: { per_second: 1000, burst_count: 10000 } }
|
||||
max_upload_size: 50M
|
||||
suppress_key_server_warning: true
|
||||
# URL previews (embed facades use the homeserver's cached thumbnail)
|
||||
url_preview_enabled: true
|
||||
url_preview_ip_range_blacklist: ['127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '100.64.0.0/10', '169.254.0.0/16', '::1/128', 'fe80::/10', 'fc00::/7']
|
||||
# scheduled messages (MSC4140 delayed events)
|
||||
max_event_delay_duration: 24h
|
||||
experimental_features:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import React, { ReactNode, useEffect, useId, useRef } from 'react';
|
||||
import { Box, Text } from 'folds';
|
||||
import { BreakWord } from '../../styles/Text.css';
|
||||
|
||||
@@ -10,12 +10,35 @@ type SettingTileProps = {
|
||||
children?: ReactNode;
|
||||
};
|
||||
export function SettingTile({ title, description, before, after, children }: SettingTileProps) {
|
||||
const titleId = useId();
|
||||
const afterRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// [Gitea #185] The control in `after` is almost always an icon-only Switch
|
||||
// (or a bare select/input) whose only visible label is this tile's title.
|
||||
// Point it at the title so screen readers announce "Show Notifications,
|
||||
// switch, on" instead of "switch, on". Explicit labels are left alone.
|
||||
useEffect(() => {
|
||||
if (!title || !afterRef.current) return;
|
||||
afterRef.current
|
||||
.querySelectorAll<HTMLElement>('[role="switch"], input, select, textarea, [role="combobox"]')
|
||||
.forEach((el) => {
|
||||
if (el.hasAttribute('aria-label') || el.hasAttribute('aria-labelledby')) return;
|
||||
if (
|
||||
el.tagName === 'INPUT' &&
|
||||
el.id &&
|
||||
afterRef.current?.querySelector(`label[for="${el.id}"]`)
|
||||
)
|
||||
return;
|
||||
el.setAttribute('aria-labelledby', titleId);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<Box alignItems="Center" gap="300">
|
||||
{before && <Box shrink="No">{before}</Box>}
|
||||
<Box grow="Yes" direction="Column" gap="100">
|
||||
{title && (
|
||||
<Text className={BreakWord} size="T300">
|
||||
<Text id={titleId} className={BreakWord} size="T300">
|
||||
{title}
|
||||
</Text>
|
||||
)}
|
||||
@@ -26,7 +49,11 @@ export function SettingTile({ title, description, before, after, children }: Set
|
||||
)}
|
||||
{children}
|
||||
</Box>
|
||||
{after && <Box shrink="No">{after}</Box>}
|
||||
{after && (
|
||||
<Box shrink="No" ref={afterRef}>
|
||||
{after}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1015,6 +1015,7 @@ export const Message = React.memo(
|
||||
size="300"
|
||||
data-user-id={senderId}
|
||||
onClick={onUserClick}
|
||||
aria-label={`${senderDisplayName}, open profile`}
|
||||
>
|
||||
<UserAvatar
|
||||
userId={senderId}
|
||||
|
||||
@@ -13,7 +13,13 @@ export function BookmarksTab() {
|
||||
<SidebarItem active={opened}>
|
||||
<SidebarItemTooltip tooltip="Saved Messages">
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={toggle}>
|
||||
<SidebarAvatar
|
||||
as="button"
|
||||
ref={triggerRef}
|
||||
aria-label="Saved Messages"
|
||||
outlined
|
||||
onClick={toggle}
|
||||
>
|
||||
<Icon src={Icons.Star} filled={opened} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
|
||||
@@ -104,6 +104,7 @@ export function CreateTab() {
|
||||
<SidebarAvatar
|
||||
className={menuCords ? ContainerColor({ variant: 'Surface' }) : undefined}
|
||||
as="button"
|
||||
aria-label="Add Space"
|
||||
ref={triggerRef}
|
||||
outlined
|
||||
onClick={handleMenu}
|
||||
|
||||
@@ -97,6 +97,7 @@ export function DirectTab() {
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar
|
||||
as="button"
|
||||
aria-label="Direct Messages"
|
||||
ref={triggerRef}
|
||||
outlined
|
||||
onClick={handleDirectClick}
|
||||
|
||||
@@ -54,7 +54,13 @@ export function ExploreTab() {
|
||||
<SidebarItem active={exploreSelected}>
|
||||
<SidebarItemTooltip tooltip="Explore Community">
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleExploreClick}>
|
||||
<SidebarAvatar
|
||||
as="button"
|
||||
ref={triggerRef}
|
||||
aria-label="Explore Community"
|
||||
outlined
|
||||
onClick={handleExploreClick}
|
||||
>
|
||||
<Icon src={Icons.Explore} filled={exploreSelected} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
|
||||
@@ -99,6 +99,7 @@ export function HomeTab() {
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar
|
||||
as="button"
|
||||
aria-label="Home"
|
||||
ref={triggerRef}
|
||||
outlined
|
||||
onClick={handleHomeClick}
|
||||
|
||||
@@ -47,7 +47,13 @@ export function InboxTab() {
|
||||
<SidebarItem active={inboxSelected}>
|
||||
<SidebarItemTooltip tooltip="Inbox">
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleInboxClick}>
|
||||
<SidebarAvatar
|
||||
as="button"
|
||||
ref={triggerRef}
|
||||
aria-label="Inbox"
|
||||
outlined
|
||||
onClick={handleInboxClick}
|
||||
>
|
||||
<Icon src={Icons.Inbox} filled={inboxSelected} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
|
||||
@@ -13,7 +13,7 @@ export function SearchTab() {
|
||||
<SidebarItem active={opened}>
|
||||
<SidebarItemTooltip tooltip="Search">
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={open}>
|
||||
<SidebarAvatar as="button" ref={triggerRef} aria-label="Search" outlined onClick={open}>
|
||||
<Icon src={Icons.Search} filled={opened} />
|
||||
</SidebarAvatar>
|
||||
)}
|
||||
|
||||
@@ -184,7 +184,12 @@ export function SettingsTab() {
|
||||
<SidebarItem active={settingsOpen}>
|
||||
<SidebarItemTooltip tooltip="User Settings">
|
||||
{(triggerRef) => (
|
||||
<SidebarAvatar as="button" ref={triggerRef} onClick={() => setSettingsOpen(true)}>
|
||||
<SidebarAvatar
|
||||
as="button"
|
||||
ref={triggerRef}
|
||||
aria-label="User Settings"
|
||||
onClick={() => setSettingsOpen(true)}
|
||||
>
|
||||
<UserAvatar
|
||||
userId={userId}
|
||||
src={avatarUrl}
|
||||
|
||||
@@ -54,6 +54,11 @@ function UnverifiedIndicator() {
|
||||
<SidebarAvatar
|
||||
className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
|
||||
as="button"
|
||||
aria-label={
|
||||
unverified
|
||||
? 'Unverified device — open settings'
|
||||
: 'Other unverified devices — open settings'
|
||||
}
|
||||
ref={triggerRef}
|
||||
outlined
|
||||
onClick={() => setSettings(true)}
|
||||
|
||||
Reference in New Issue
Block a user