feat: extended profile fields, push rule editor, server ACL editor
P2-8: Pronouns (m.pronouns) and Timezone (m.tz) fields in Settings →
Account → Profile; saved via MSC4133 PUT /profile/{userId}/{field};
useExtendedProfile hook fetches both in parallel; UserHero displays
pronouns below display name and timezone string below username
P2-11: Full push rule editor in Settings → Notifications below keyword
rules; covers override/room/sender/underride rule kinds; enable/disable
toggle per rule, human-readable labels for built-in rules, delete button
for custom rules, add-rule form for room and sender rules
P2-12: Server ACL viewer/editor in room settings (Server ACL tab);
reads m.room.server_acl state event; allow/deny server lists with
wildcard validation; allow IP literals toggle; power-level gated
(edit requires sufficient PL, otherwise read-only view)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Method } from 'matrix-js-sdk';
|
||||
import { useMatrixClient } from './useMatrixClient';
|
||||
|
||||
export type ExtendedProfile = {
|
||||
pronouns?: string;
|
||||
timezone?: string;
|
||||
};
|
||||
|
||||
export const useExtendedProfile = (userId: string): ExtendedProfile => {
|
||||
const mx = useMatrixClient();
|
||||
const [extProfile, setExtProfile] = useState<ExtendedProfile>({});
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
const fetchField = async <T extends Record<string, string>>(
|
||||
field: string,
|
||||
): Promise<string | undefined> => {
|
||||
try {
|
||||
const res = await mx.http.authedRequest<T>(
|
||||
Method.Get,
|
||||
`/profile/${encodeURIComponent(userId)}/${field}`,
|
||||
);
|
||||
return res[field as keyof T] as string | undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
fetchField<{ 'm.pronouns': string }>('m.pronouns'),
|
||||
fetchField<{ 'm.tz': string }>('m.tz'),
|
||||
]).then(([pronouns, timezone]) => {
|
||||
if (!cancelled) {
|
||||
setExtProfile({ pronouns: pronouns || undefined, timezone: timezone || undefined });
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [mx, userId]);
|
||||
|
||||
return extProfile;
|
||||
};
|
||||
Reference in New Issue
Block a user