mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-01-29 01:28:29 +00:00
improve member search
This commit is contained in:
parent
49219d8ba8
commit
b517b94f1a
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, KeyboardEvent as ReactKeyboardEvent } from 'react';
|
||||
import { Editor } from 'slate';
|
||||
import { Avatar, AvatarFallback, AvatarImage, MenuItem, Text, color } from 'folds';
|
||||
import { MatrixClient, RoomMember } from 'matrix-js-sdk';
|
||||
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
|
||||
|
||||
import { AutocompleteQuery } from './autocompleteQuery';
|
||||
import { AutocompleteMenu } from './AutocompleteMenu';
|
||||
|
@ -16,6 +16,7 @@ import { onTabPress } from '../../../utils/keyboard';
|
|||
import { createMentionElement, moveCursor, replaceWithElement } from '../utils';
|
||||
import { useKeyDown } from '../../../hooks/useKeyDown';
|
||||
import { getMxIdLocalPart, getMxIdServer, validMxId } from '../../../utils/matrix';
|
||||
import { getMemberDisplayName, getMemberSearchStr } from '../../../utils/room';
|
||||
|
||||
type MentionAutoCompleteHandler = (userId: string, name: string) => void;
|
||||
|
||||
|
@ -64,7 +65,7 @@ function UnknownMentionItem({
|
|||
}
|
||||
|
||||
type UserMentionAutocompleteProps = {
|
||||
roomId: string;
|
||||
room: Room;
|
||||
editor: Editor;
|
||||
query: AutocompleteQuery<string>;
|
||||
requestClose: () => void;
|
||||
|
@ -77,21 +78,19 @@ const SEARCH_OPTIONS: UseAsyncSearchOptions = {
|
|||
},
|
||||
};
|
||||
|
||||
const getRoomMemberStr: SearchItemStrGetter<RoomMember> = (roomMember) => [
|
||||
roomMember.name,
|
||||
getMxIdLocalPart(roomMember.userId) ?? roomMember.userId,
|
||||
roomMember.userId,
|
||||
];
|
||||
const mxIdToName = (mxId: string) => getMxIdLocalPart(mxId) ?? mxId;
|
||||
const getRoomMemberStr: SearchItemStrGetter<RoomMember> = (m, query) =>
|
||||
getMemberSearchStr(m, query, mxIdToName);
|
||||
|
||||
export function UserMentionAutocomplete({
|
||||
roomId,
|
||||
room,
|
||||
editor,
|
||||
query,
|
||||
requestClose,
|
||||
}: UserMentionAutocompleteProps) {
|
||||
const mx = useMatrixClient();
|
||||
const room = mx.getRoom(roomId);
|
||||
const roomAliasOrId = room?.getCanonicalAlias() || roomId;
|
||||
const roomId: string = room.roomId!;
|
||||
const roomAliasOrId = room.getCanonicalAlias() || roomId;
|
||||
const members = useRoomMembers(mx, roomId);
|
||||
|
||||
const [result, search, resetSearch] = useAsyncSearch(members, getRoomMemberStr, SEARCH_OPTIONS);
|
||||
|
@ -129,6 +128,9 @@ export function UserMentionAutocomplete({
|
|||
});
|
||||
});
|
||||
|
||||
const getName = (member: RoomMember) =>
|
||||
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
|
||||
|
||||
return (
|
||||
<AutocompleteMenu headerContent={<Text size="L400">Mentions</Text>} requestClose={requestClose}>
|
||||
{query.text === 'room' && (
|
||||
|
@ -155,9 +157,9 @@ export function UserMentionAutocomplete({
|
|||
as="button"
|
||||
radii="300"
|
||||
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
||||
onTabPress(evt, () => handleAutocomplete(roomMember.userId, roomMember.name))
|
||||
onTabPress(evt, () => handleAutocomplete(roomMember.userId, getName(roomMember)))
|
||||
}
|
||||
onClick={() => handleAutocomplete(roomMember.userId, roomMember.name)}
|
||||
onClick={() => handleAutocomplete(roomMember.userId, getName(roomMember))}
|
||||
after={
|
||||
<Text size="T200" priority="300" truncate>
|
||||
{roomMember.userId}
|
||||
|
@ -166,7 +168,7 @@ export function UserMentionAutocomplete({
|
|||
before={
|
||||
<Avatar size="200">
|
||||
{avatarUrl ? (
|
||||
<AvatarImage src={avatarUrl} alt={roomMember.userId} />
|
||||
<AvatarImage src={avatarUrl} alt={getName(roomMember)} />
|
||||
) : (
|
||||
<AvatarFallback
|
||||
style={{
|
||||
|
@ -174,14 +176,14 @@ export function UserMentionAutocomplete({
|
|||
color: color.Secondary.OnContainer,
|
||||
}}
|
||||
>
|
||||
<Text size="H6">{roomMember.name[0] || roomMember.userId[1]}</Text>
|
||||
<Text size="H6">{getName(roomMember)[0]}</Text>
|
||||
</AvatarFallback>
|
||||
)}
|
||||
</Avatar>
|
||||
}
|
||||
>
|
||||
<Text style={{ flexGrow: 1 }} size="B400" truncate>
|
||||
{roomMember.name}
|
||||
{getName(roomMember)}
|
||||
</Text>
|
||||
</MenuItem>
|
||||
);
|
||||
|
|
|
@ -17,7 +17,8 @@ export type UseAsyncSearchOptions = AsyncSearchOption & {
|
|||
};
|
||||
|
||||
export type SearchItemStrGetter<TSearchItem extends object | string | number> = (
|
||||
searchItem: TSearchItem
|
||||
searchItem: TSearchItem,
|
||||
query: string
|
||||
) => string | string[];
|
||||
|
||||
export type UseAsyncSearchResult<TSearchItem extends object | string | number> = {
|
||||
|
@ -38,7 +39,7 @@ export const useAsyncSearch = <TSearchItem extends object | string | number>(
|
|||
setResult(undefined);
|
||||
|
||||
const handleMatch: MatchHandler<TSearchItem> = (item, query) => {
|
||||
const itemStr = getItemStr(item);
|
||||
const itemStr = getItemStr(item, query);
|
||||
if (Array.isArray(itemStr))
|
||||
return !!itemStr.find((i) =>
|
||||
matchQuery(normalize(i, options?.normalizeOptions), query, options?.matchOptions)
|
||||
|
|
|
@ -46,13 +46,17 @@ import {
|
|||
} from '../../hooks/useIntersectionObserver';
|
||||
import { Membership } from '../../../types/matrix/room';
|
||||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import { UseAsyncSearchOptions, useAsyncSearch } from '../../hooks/useAsyncSearch';
|
||||
import {
|
||||
SearchItemStrGetter,
|
||||
UseAsyncSearchOptions,
|
||||
useAsyncSearch,
|
||||
} from '../../hooks/useAsyncSearch';
|
||||
import { useDebounce } from '../../hooks/useDebounce';
|
||||
import colorMXID from '../../../util/colorMXID';
|
||||
import { usePowerLevelTags, PowerLevelTag } from '../../hooks/usePowerLevelTags';
|
||||
import { roomIdToTypingMembersAtom, selectRoomTypingMembersAtom } from '../../state/typingMembers';
|
||||
import { TypingIndicator } from '../../components/typing-indicator';
|
||||
import { getMemberDisplayName } from '../../utils/room';
|
||||
import { getMemberDisplayName, getMemberSearchStr } from '../../utils/room';
|
||||
import { getMxIdLocalPart } from '../../utils/matrix';
|
||||
import { useSetting } from '../../state/hooks/settings';
|
||||
import { settingsAtom } from '../../state/settings';
|
||||
|
@ -161,7 +165,10 @@ const SEARCH_OPTIONS: UseAsyncSearchOptions = {
|
|||
contain: true,
|
||||
},
|
||||
};
|
||||
const getMemberItemStr = (m: RoomMember) => [m.name, m.userId];
|
||||
|
||||
const mxIdToName = (mxId: string) => getMxIdLocalPart(mxId) ?? mxId;
|
||||
const getRoomMemberStr: SearchItemStrGetter<RoomMember> = (m, query) =>
|
||||
getMemberSearchStr(m, query, mxIdToName);
|
||||
|
||||
type MembersDrawerProps = {
|
||||
room: Room;
|
||||
|
@ -200,7 +207,7 @@ export function MembersDrawer({ room }: MembersDrawerProps) {
|
|||
|
||||
const [result, search, resetSearch] = useAsyncSearch(
|
||||
filteredMembers,
|
||||
getMemberItemStr,
|
||||
getRoomMemberStr,
|
||||
SEARCH_OPTIONS
|
||||
);
|
||||
if (!result && searchInputRef.current?.value) search(searchInputRef.current.value);
|
||||
|
|
|
@ -443,7 +443,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
|||
)}
|
||||
{autocompleteQuery?.prefix === AutocompletePrefix.UserMention && (
|
||||
<UserMentionAutocomplete
|
||||
roomId={roomId}
|
||||
room={room}
|
||||
editor={editor}
|
||||
query={autocompleteQuery}
|
||||
requestClose={handleCloseAutocomplete}
|
||||
|
|
|
@ -193,7 +193,7 @@ export const MessageEditor = as<'div', MessageEditorProps>(
|
|||
)}
|
||||
{autocompleteQuery?.prefix === AutocompletePrefix.UserMention && (
|
||||
<UserMentionAutocomplete
|
||||
roomId={roomId}
|
||||
room={room}
|
||||
editor={editor}
|
||||
query={autocompleteQuery}
|
||||
requestClose={handleCloseAutocomplete}
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
NotificationCountType,
|
||||
RelationType,
|
||||
Room,
|
||||
RoomMember,
|
||||
} from 'matrix-js-sdk';
|
||||
import { CryptoBackend } from 'matrix-js-sdk/lib/common-crypto/CryptoBackend';
|
||||
import { AccountDataEvent } from '../../types/matrix/accountData';
|
||||
|
@ -293,6 +294,15 @@ export const getMemberDisplayName = (room: Room, userId: string): string | undef
|
|||
return name;
|
||||
};
|
||||
|
||||
export const getMemberSearchStr = (
|
||||
member: RoomMember,
|
||||
query: string,
|
||||
mxIdToName: (mxId: string) => string
|
||||
): string[] => [
|
||||
member.rawDisplayName === member.userId ? mxIdToName(member.userId) : member.rawDisplayName,
|
||||
query.startsWith('@') || query.indexOf(':') > -1 ? member.userId : mxIdToName(member.userId),
|
||||
];
|
||||
|
||||
export const getMemberAvatarMxc = (room: Room, userId: string): string | undefined => {
|
||||
const member = room.getMember(userId);
|
||||
return member?.getMxcAvatarUrl();
|
||||
|
|
Loading…
Reference in a new issue