Skip to content

Commit

Permalink
Merge branch 'private-autocompletes' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmz committed Dec 4, 2024
2 parents 799e020 + 3f71362 commit 2b7a393
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 21 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.137.0] - Not released
### Changed
- The autocomplete is now queries server during typing. It allows to show exact
matches of private users and groups.

## [1.136.0] - 2024-11-08
### Changed
Expand Down
33 changes: 20 additions & 13 deletions src/components/autocomplete/selector.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDispatch, useSelector, useStore } from 'react-redux';
import { Link } from 'react-router';
import cn from 'classnames';
import { useEffect, useMemo, useRef, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { useEvent } from 'react-use-event-hook';
import { faExternalLinkAlt, faUserFriends } from '@fortawesome/free-solid-svg-icons';
import { Finder } from '../../utils/sparse-match';
Expand All @@ -23,19 +23,8 @@ import {

export function Selector({ query, events, onSelect, context, localLinks = false }) {
query = query.toLowerCase();
const dispatch = useDispatch();
const [usernames, accountsMap, compare] = useAccountsMap({ context });

// Request all users/groups when query longer than 2 chars
const lastQuery = useRef('');
useEffect(() => {
const lc = lastQuery.current;
if (query.length < 2 || (lc && query.slice(0, lc.length) === lc)) {
return;
}
lastQuery.current = query;
dispatch(getMatchedUsers(query));
}, [dispatch, query]);
useUsersRequest(query);

const matches = useMemo(() => {
const compareWithExact = (a, b) => {
Expand Down Expand Up @@ -196,3 +185,21 @@ function useAccountsMap({ context }) {
return [[...accountsMap.keys()], accountsMap, compare];
}, [context, post, store, lastAutocompleteQuery]);
}

function useUsersRequest(query) {
const dispatch = useDispatch();

useEffect(() => {
if (query.length < 2) {
return;
}

const abortController = new AbortController();
const { signal } = abortController;

const t = setTimeout(() => dispatch(getMatchedUsers(query, { signal })), 500);
signal.addEventListener('abort', () => clearTimeout(t));

return () => abortController.abort();
}, [query, dispatch]);
}
3 changes: 2 additions & 1 deletion src/redux/action-creators.js
Original file line number Diff line number Diff line change
Expand Up @@ -1396,10 +1396,11 @@ export function unlockComment(id) {
};
}

export function getMatchedUsers(query) {
export function getMatchedUsers(query, fetchOptions) {
return {
type: ActionTypes.GET_MATCHED_USERS,
apiRequest: Api.getMatchedUsers,
payload: { query },
fetchOptions,
};
}
4 changes: 2 additions & 2 deletions src/redux/middlewares.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ export const apiMiddleware = (store) => (next) => async (action) => {

//dispatch request begin action
//clean apiRequest to not get caught by this middleware
store.dispatch({ ...action, type: request(action.type), apiRequest: null });
store.dispatch({ ...action, type: request(action.type), apiRequest: null, fetchOptions: null });
try {
const apiResponse = await action.apiRequest(action.payload);
const apiResponse = await action.apiRequest(action.payload, action.fetchOptions);
const obj = await apiResponse.json();

if (apiResponse.status >= 200 && apiResponse.status < 300) {
Expand Down
10 changes: 5 additions & 5 deletions src/services/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -841,9 +841,9 @@ export function notifyOfAllComments({ postId, enabled }) {
);
}

export function getMatchedUsers({ query }) {
return fetch(
`${apiPrefix}/users/sparseMatches?qs=${encodeURIComponent(query)}`,
getRequestOptions(),
);
export function getMatchedUsers({ query }, fetchOptions = {}) {
return fetch(`${apiPrefix}/users/sparseMatches?qs=${encodeURIComponent(query)}`, {
...getRequestOptions(),
...fetchOptions,
});
}

0 comments on commit 2b7a393

Please sign in to comment.