Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

accent insensitive autocomplete #2007

Merged
merged 5 commits into from
Jun 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/autocomplete/QueryMatcher.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//@flow
/*
Copyright 2017 Aviral Dasgupta
Copyright 2018 Michael Telatynski <7t3chguy@gmail.com>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -27,6 +28,10 @@ class KeyMap {
priorityMap = new Map();
}

function stripDiacritics(str: string): string {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}

export default class QueryMatcher {
/**
* @param {object[]} objects the objects to perform a match on
Expand All @@ -46,10 +51,11 @@ export default class QueryMatcher {
objects.forEach((object, i) => {
const keyValues = _at(object, keys);
for (const keyValue of keyValues) {
if (!map.hasOwnProperty(keyValue)) {
map[keyValue] = [];
const key = stripDiacritics(keyValue).toLowerCase();
if (!map.hasOwnProperty(key)) {
map[key] = [];
}
map[keyValue].push(object);
map[key].push(object);
}
keyMap.priorityMap.set(object, i);
});
Expand Down Expand Up @@ -82,7 +88,7 @@ export default class QueryMatcher {
}

match(query: String): Array<Object> {
query = query.toLowerCase();
query = stripDiacritics(query).toLowerCase();
if (this.options.shouldMatchWordsOnly) {
query = query.replace(/[^\w]/g, '');
}
Expand All @@ -91,7 +97,7 @@ export default class QueryMatcher {
}
const results = [];
this.keyMap.keys.forEach((key) => {
let resultKey = key.toLowerCase();
let resultKey = key;
if (this.options.shouldMatchWordsOnly) {
resultKey = resultKey.replace(/[^\w]/g, '');
}
Expand Down
23 changes: 10 additions & 13 deletions src/autocomplete/UserProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Copyright 2016 Aviral Dasgupta
Copyright 2017 Vector Creations Ltd
Copyright 2017, 2018 New Vector Ltd
Copyright 2018 Michael Telatynski <7t3chguy@gmail.com>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -26,9 +27,9 @@ import FuzzyMatcher from './FuzzyMatcher';
import _sortBy from 'lodash/sortBy';
import MatrixClientPeg from '../MatrixClientPeg';

import type {Room, RoomMember} from 'matrix-js-sdk';
import type {MatrixEvent, Room, RoomMember, RoomState} from 'matrix-js-sdk';
import {makeUserPermalink} from "../matrix-to";
import type {SelectionRange} from "./Autocompleter";
import type {Completion, SelectionRange} from "./Autocompleter";

const USER_REGEX = /@\S*/g;

Expand All @@ -44,7 +45,7 @@ export default class UserProvider extends AutocompleteProvider {
this.matcher = new FuzzyMatcher([], {
keys: ['name', 'userId'],
shouldMatchPrefix: true,
shouldMatchWordsOnly: false
shouldMatchWordsOnly: false,
});

this._onRoomTimelineBound = this._onRoomTimeline.bind(this);
Expand All @@ -61,7 +62,7 @@ export default class UserProvider extends AutocompleteProvider {
}
}

_onRoomTimeline(ev, room, toStartOfTimeline, removed, data) {
_onRoomTimeline(ev: MatrixEvent, room: Room, toStartOfTimeline: boolean, removed: boolean, data: Object) {
if (!room) return;
if (removed) return;
if (room.roomId !== this.room.roomId) return;
Expand All @@ -77,7 +78,7 @@ export default class UserProvider extends AutocompleteProvider {
this.onUserSpoke(ev.sender);
}

_onRoomStateMember(ev, state, member) {
_onRoomStateMember(ev: MatrixEvent, state: RoomState, member: RoomMember) {
// ignore members in other rooms
if (member.roomId !== this.room.roomId) {
return;
Expand All @@ -87,7 +88,7 @@ export default class UserProvider extends AutocompleteProvider {
this.users = null;
}

async getCompletions(query: string, selection: SelectionRange, force?: boolean = false) {
async getCompletions(query: string, selection: SelectionRange, force?: boolean = false): Array<Completion> {
const MemberAvatar = sdk.getComponent('views.avatars.MemberAvatar');

// Disable autocompletions when composing commands because of various issues
Expand Down Expand Up @@ -128,7 +129,7 @@ export default class UserProvider extends AutocompleteProvider {
return completions;
}

getName() {
getName(): string {
return '👥 ' + _t('Users');
}

Expand All @@ -141,13 +142,9 @@ export default class UserProvider extends AutocompleteProvider {
}

const currentUserId = MatrixClientPeg.get().credentials.userId;
this.users = this.room.getJoinedMembers().filter((member) => {
if (member.userId !== currentUserId) return true;
});
this.users = this.room.getJoinedMembers().filter(({userId}) => userId !== currentUserId);

this.users = _sortBy(this.users, (member) =>
1E20 - lastSpoken[member.userId] || 1E20,
);
this.users = _sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20);

this.matcher.setObjects(this.users);
}
Expand Down