apply stripDiacritics to QueryMatcher instead of individually
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
7cdc91856b
commit
6a84a7ab32
4 changed files with 18 additions and 32 deletions
|
@ -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,
|
||||||
|
|
|
@ -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, '');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue