added auto complete

This commit is contained in:
NanoAim
2025-07-10 11:04:05 +08:00
parent 252d33f001
commit 7f098d059d
3 changed files with 72 additions and 35 deletions

View File

@@ -174,7 +174,7 @@ export function useAutoComplete(
(x) => x._id !== "00000000000000000000000000", (x) => x._id !== "00000000000000000000000000",
); );
const matches = ( let matches = (
search.length > 0 search.length > 0
? users.filter((user) => ? users.filter((user) =>
user.username.toLowerCase().match(regex), user.username.toLowerCase().match(regex),
@@ -184,6 +184,13 @@ export function useAutoComplete(
.splice(0, 5) .splice(0, 5)
.filter((x) => typeof x !== "undefined"); .filter((x) => typeof x !== "undefined");
// Add @everyone if it matches the search and we're in a channel context
if (searchClues.users.type === "channel" &&
(search.length === 0 || "everyone".match(regex))) {
// Add a special "everyone" entry at the beginning
matches = [{ _id: "@everyone", username: "everyone" } as any, ...matches].slice(0, 5);
}
if (matches.length > 0) { if (matches.length > 0) {
const currentPosition = const currentPosition =
state.type !== "none" ? state.selected : 0; state.type !== "none" ? state.selected : 0;
@@ -256,6 +263,14 @@ export function useAutoComplete(
); );
} else if (state.type === "user") { } else if (state.type === "user") {
const selectedUser = state.matches[state.selected]; const selectedUser = state.matches[state.selected];
// Handle @everyone special case
if (selectedUser._id === "@everyone") {
content.splice(
index,
search.length + 1,
"@everyone ",
);
} else {
content.splice( content.splice(
index, index,
search.length + 1, search.length + 1,
@@ -263,6 +278,7 @@ export function useAutoComplete(
selectedUser.username, selectedUser.username,
" ", " ",
); );
}
} else { } else {
content.splice( content.splice(
index, index,
@@ -492,7 +508,7 @@ export default function AutoComplete({
{state.type === "user" && {state.type === "user" &&
state.matches.map((match, i) => ( state.matches.map((match, i) => (
<button <button
key={match} key={match._id || match}
className={i === state.selected ? "active" : ""} className={i === state.selected ? "active" : ""}
onMouseEnter={() => onMouseEnter={() =>
(i !== state.selected || !state.within) && (i !== state.selected || !state.within) &&
@@ -510,8 +526,28 @@ export default function AutoComplete({
}) })
} }
onClick={onClick}> onClick={onClick}>
{match._id === "@everyone" ? (
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
<span style={{
width: "24px",
height: "24px",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: "14px",
background: "var(--accent)",
color: "var(--accent-contrast)",
borderRadius: "50%",
fontWeight: "600"
}}>@</span>
<span>everyone</span>
</div>
) : (
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
<UserIcon size={24} target={match} status={true} /> <UserIcon size={24} target={match} status={true} />
{match.username} <span>{match.username}</span>
</div>
)}
</button> </button>
))} ))}
{state.type === "channel" && {state.type === "channel" &&

View File

@@ -48,12 +48,12 @@ export function RenderMention({ match }: CustomComponentProps) {
} }
const EveryoneMention = styled.span` const EveryoneMention = styled.span`
padding: 0 4px; padding: 0 6px;
flex-shrink: 0; flex-shrink: 0;
font-weight: 600; font-weight: 600;
cursor: default; cursor: pointer;
color: var(--foreground); color: var(--accent);
background: var(--secondary-background); background: var(--secondary-background);
border-radius: calc(var(--border-radius) * 2); border-radius: calc(var(--border-radius) * 2);

View File

@@ -109,6 +109,7 @@ export default observer(({ channel }: Props) => {
"UploadFiles", "UploadFiles",
"Masquerade", "Masquerade",
"React", "React",
"MentionEveryone",
"ManageChannel", "ManageChannel",
"ManagePermissions", "ManagePermissions",
]} ]}