feat: MSC4260 Report User, Bug #6 mutual exclusion, TDS toast compliance
- Add ReportUserModal.tsx — category dropdown + reason input, calls
POST /_matrix/client/v3/users/{userId}/report via mx.http.authedRequest,
inline success/error feedback, auto-closes 1500ms after success
- Wire Report User button into UserRoomProfile.tsx between UserModeration
and UserDeviceSessions (hidden for own profile)
- Bug #6: enforce mutual exclusion between chat backgrounds and seasonal
themes — ChatBgGrid clears seasonal→'off' on non-'none' pick;
SeasonalBgGrid clears chatBackground→'none' on real theme pick;
SeasonalEffect guards against legacy persisted state at render time
- TDS: strip all hardcoded hex/rgba fallbacks from LotusToastContainer.tsx
(var(--lt-bg-card), --lt-accent-orange, --lt-text-primary/secondary,
--lt-accent-orange-dim/border, --lt-box-glow-orange)
- Mark Bug #6 FIXED, MSC4260 DONE, toast TDS FIXED in LOTUS_BUGS.md and
LOTUS_TODO.md; note EventReaders + CallControls already compliant
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -797,5 +797,9 @@ export function SeasonalEffect() {
|
||||
}, [settings.seasonalThemeOverride]);
|
||||
|
||||
if (!theme) return null;
|
||||
// Suppress seasonal overlay when a chat background is active — both running simultaneously
|
||||
// wastes GPU and looks cluttered. The settings UI enforces mutual exclusion on write;
|
||||
// this guard covers any legacy state already persisted.
|
||||
if (settings.chatBackground !== 'none') return null;
|
||||
return <SeasonalOverlay theme={theme} reduced={reduced} />;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import { Membership } from '../../../types/matrix/room';
|
||||
import { useRoomCreators } from '../../hooks/useRoomCreators';
|
||||
import { useRoomPermissions } from '../../hooks/useRoomPermissions';
|
||||
import { useMemberPowerCompare } from '../../hooks/useMemberPowerCompare';
|
||||
import { ReportUserModal } from '../../features/room/ReportUserModal';
|
||||
import { CreatorChip } from './CreatorChip';
|
||||
import { getDirectCreatePath, withSearchParam } from '../../pages/pathUtils';
|
||||
import { DirectCreateSearchParams } from '../../pages/paths';
|
||||
@@ -272,6 +273,7 @@ type UserRoomProfileProps = {
|
||||
};
|
||||
export function UserRoomProfile({ userId }: UserRoomProfileProps) {
|
||||
const mx = useMatrixClient();
|
||||
const [reportUserOpen, setReportUserOpen] = useState(false);
|
||||
const crossSigningActive = useCrossSigningActive();
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
const navigate = useNavigate();
|
||||
@@ -390,8 +392,25 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
|
||||
canKick={canKickUser && membership === Membership.Join}
|
||||
canBan={canBanUser && membership !== Membership.Ban}
|
||||
/>
|
||||
{userId !== myUserId && (
|
||||
<Box style={{ padding: `0 ${config.space.S400} ${config.space.S200}` }}>
|
||||
<Button
|
||||
variant="Critical"
|
||||
fill="None"
|
||||
size="300"
|
||||
radii="300"
|
||||
before={<Icon size="50" src={Icons.Warning} />}
|
||||
onClick={() => setReportUserOpen(true)}
|
||||
>
|
||||
<Text size="B300">Report User</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
{showEncryption && userId !== myUserId && <UserDeviceSessions userId={userId} />}
|
||||
{userId !== myUserId && <UserPrivateNotes userId={userId} />}
|
||||
{reportUserOpen && (
|
||||
<ReportUserModal userId={userId} onClose={() => setReportUserOpen(false)} />
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user