apply stripDiacritics to QueryMatcher instead of individually

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2018-06-23 02:20:41 +01:00
parent 7cdc91856b
commit 6a84a7ab32
No known key found for this signature in database
GPG key ID: 3F879DA5AD802A5E
4 changed files with 18 additions and 32 deletions

View file

@ -43,10 +43,6 @@ export type Completion = {
href: ?string, href: ?string,
}; };
export function stripDiacritics(str: string): string {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
const PROVIDERS = [ const PROVIDERS = [
UserProvider, UserProvider,
RoomProvider, RoomProvider,

View file

@ -1,6 +1,7 @@
//@flow //@flow
/* /*
Copyright 2017 Aviral Dasgupta Copyright 2017 Aviral Dasgupta
Copyright 2018 Michael Telatynski <7t3chguy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -27,6 +28,10 @@ class KeyMap {
priorityMap = new Map(); priorityMap = new Map();
} }
function stripDiacritics(str: string): string {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
export default class QueryMatcher { export default class QueryMatcher {
/** /**
* @param {object[]} objects the objects to perform a match on * @param {object[]} objects the objects to perform a match on
@ -46,10 +51,11 @@ export default class QueryMatcher {
objects.forEach((object, i) => { objects.forEach((object, i) => {
const keyValues = _at(object, keys); const keyValues = _at(object, keys);
for (const keyValue of keyValues) { for (const keyValue of keyValues) {
if (!map.hasOwnProperty(keyValue)) { const key = stripDiacritics(keyValue).toLowerCase();
map[keyValue] = []; if (!map.hasOwnProperty(key)) {
map[key] = [];
} }
map[keyValue].push(object); map[key].push(object);
} }
keyMap.priorityMap.set(object, i); keyMap.priorityMap.set(object, i);
}); });
@ -82,7 +88,7 @@ export default class QueryMatcher {
} }
match(query: String): Array<Object> { match(query: String): Array<Object> {
query = query.toLowerCase(); query = stripDiacritics(query).toLowerCase();
if (this.options.shouldMatchWordsOnly) { if (this.options.shouldMatchWordsOnly) {
query = query.replace(/[^\w]/g, ''); query = query.replace(/[^\w]/g, '');
} }
@ -91,7 +97,7 @@ export default class QueryMatcher {
} }
const results = []; const results = [];
this.keyMap.keys.forEach((key) => { this.keyMap.keys.forEach((key) => {
let resultKey = key.toLowerCase(); let resultKey = key;
if (this.options.shouldMatchWordsOnly) { if (this.options.shouldMatchWordsOnly) {
resultKey = resultKey.replace(/[^\w]/g, ''); resultKey = resultKey.replace(/[^\w]/g, '');
} }

View file

@ -2,7 +2,6 @@
Copyright 2016 Aviral Dasgupta Copyright 2016 Aviral Dasgupta
Copyright 2017 Vector Creations Ltd Copyright 2017 Vector Creations Ltd
Copyright 2017, 2018 New Vector Ltd Copyright 2017, 2018 New Vector Ltd
Copyright 2018 Michael Telatynski <7t3chguy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -28,7 +27,6 @@ import sdk from '../index';
import _sortBy from 'lodash/sortBy'; import _sortBy from 'lodash/sortBy';
import {makeRoomPermalink} from "../matrix-to"; import {makeRoomPermalink} from "../matrix-to";
import type {Completion, SelectionRange} from "./Autocompleter"; import type {Completion, SelectionRange} from "./Autocompleter";
import {stripDiacritics} from "./Autocompleter";
const ROOM_REGEX = /(?=#)(\S*)/g; const ROOM_REGEX = /(?=#)(\S*)/g;
@ -45,7 +43,7 @@ export default class RoomProvider extends AutocompleteProvider {
constructor() { constructor() {
super(ROOM_REGEX); super(ROOM_REGEX);
this.matcher = new FuzzyMatcher([], { this.matcher = new FuzzyMatcher([], {
keys: ['displayedAlias', '_name'], keys: ['displayedAlias', 'name'],
}); });
} }
@ -69,12 +67,11 @@ export default class RoomProvider extends AutocompleteProvider {
return { return {
room: room, room: room,
name: room.name, name: room.name,
_name: stripDiacritics(room.name),
displayedAlias: getDisplayAliasForRoom(room), displayedAlias: getDisplayAliasForRoom(room),
}; };
})); }));
const matchedString = command[0]; const matchedString = command[0];
completions = this.matcher.match(stripDiacritics(matchedString)); completions = this.matcher.match(matchedString);
completions = _sortBy(completions, [ completions = _sortBy(completions, [
(c) => score(matchedString, c.displayedAlias), (c) => score(matchedString, c.displayedAlias),
(c) => c.displayedAlias.length, (c) => c.displayedAlias.length,

View file

@ -30,7 +30,6 @@ import MatrixClientPeg from '../MatrixClientPeg';
import type {MatrixEvent, Room, RoomMember, RoomState} from 'matrix-js-sdk'; import type {MatrixEvent, Room, RoomMember, RoomState} from 'matrix-js-sdk';
import {makeUserPermalink} from "../matrix-to"; import {makeUserPermalink} from "../matrix-to";
import type {Completion, SelectionRange} from "./Autocompleter"; import type {Completion, SelectionRange} from "./Autocompleter";
import {stripDiacritics} from "./Autocompleter";
const USER_REGEX = /@\S*/g; const USER_REGEX = /@\S*/g;
@ -40,11 +39,11 @@ export default class UserProvider extends AutocompleteProvider {
constructor(room: Room) { constructor(room: Room) {
super(USER_REGEX, { super(USER_REGEX, {
keys: ['_name'], keys: ['name'],
}); });
this.room = room; this.room = room;
this.matcher = new FuzzyMatcher([], { this.matcher = new FuzzyMatcher([], {
keys: ['_name', 'userId'], keys: ['name', 'userId'],
shouldMatchPrefix: true, shouldMatchPrefix: true,
shouldMatchWordsOnly: false, shouldMatchWordsOnly: false,
}); });
@ -109,7 +108,7 @@ export default class UserProvider extends AutocompleteProvider {
const fullMatch = command[0]; const fullMatch = command[0];
// Don't search if the query is a single "@" // Don't search if the query is a single "@"
if (fullMatch && fullMatch !== '@') { if (fullMatch && fullMatch !== '@') {
completions = this.matcher.match(stripDiacritics(fullMatch)).map((user) => { completions = this.matcher.match(fullMatch).map((user) => {
const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done const displayName = (user.name || user.userId || '').replace(' (IRC)', ''); // FIXME when groups are done
return { return {
// Length of completion should equal length of text in decorator. draft-js // Length of completion should equal length of text in decorator. draft-js
@ -143,21 +142,9 @@ export default class UserProvider extends AutocompleteProvider {
} }
const currentUserId = MatrixClientPeg.get().credentials.userId; const currentUserId = MatrixClientPeg.get().credentials.userId;
this.users = this.room.getJoinedMembers().filter(({userId}) => userId !== currentUserId);
this.users = []; this.users = _sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20);
this.room.getJoinedMembers().forEach(({userId, name, ...rest}) => {
if (userId === currentUserId) return; // skip self
this.users.push({
userId,
name,
_name: stripDiacritics(name),
...rest,
});
});
this.users = _sortBy(this.users, (member) =>
1E20 - lastSpoken[member.userId] || 1E20,
);
this.matcher.setObjects(this.users); this.matcher.setObjects(this.users);
} }