Opened 3 years ago

Closed 15 months ago

Last modified 13 months ago

#70 closed defect

Nickname tab completion in group chats

Reported by: pulkomandy Owned by:
Priority: Milestone: 1.24
Version: Keywords: enhancement UX vision-feature-parity
Cc:

Description

When pressing the tab key, the message writing view should autocomplete nicknames. When this happens, it should also set the message to include a XEP-0372 reference to the highlighted user.

Nickname matching algorithm:

  • Find the start of nickname (first whitespace before cursor)
  • Find the end of nickname (first whitespace after cursor?)
  • Find all nicknames currently in the room starting with that string (case insensitive?)
  • Add the first matching one to the text view (define "first": priorize who talked last? what was used in previous tab completions? alphabetical order?)
  • Pressing tab again cycles through other possible matches

Change History (9)

comment:1 by pulkomandy, 3 years ago

Keywords: enhancement added

comment:2 by pulkomandy, 3 years ago

Keywords: UX added

comment:3 by pulkomandy, 3 years ago

Keywords: vision-feature-parity added

comment:4 by pulkomandy, 2 years ago

Discussions on jdev (things with checkboxes can be moved to follow up tickets):

  • Start of nickname is after last space (or newline or tab) before cursor. End of nickname is probably at cursor position
  • [x] If at start of input buffer or after a newline, append a ":" or "," after the completed nickname
  • [ ] When a nickname is tab completed, insert a XEP 00372 mention in the message to be sure that person is notified of it
  • [ ] Order completions by last-mentionned then last-spoke
  • [ ] Matching should be case insensitive but case preserving
  • [ ] Maybe ignore extra characters like [, `, _ or | at start of name (or maybe even in the middle of names)
  • [ ] What to do with people using emoji as nickname? Probably not completeable
  • [ ] If tab completing an empty string, just iterate over all nicknames in the last-mentionned then last-spoke order

Algorithm can be implemented in one of two ways:

1) keep a list of all nicknames in a room ordered by last-mentionned then last-spoke. Mentioning someone moves them up. Someone speaking moves them behind (recently?) mentionned people. Disable people leaving the room, but don't move them down just yet (when do we do it? does the list keep growing forever) in case they join back later. When tab completing, go through that list until finding the first match. If tab is pressed again, continue going down the list. What if someone with matching nickname speaks after the firs tab completion but before the second one?

2) use a trie or just go through the list of all nicknames in alphabetical order to find the matching ones. Then sort them by last-mentionned/last-spoken

comment:5 by pulkomandy, 15 months ago

  • In either case, this requires keeping track of recently mentionned nicknames. Does this mean only XEP-0372 mentions, or any occurence of the nick in message bodies? I don't think tracking the latter is very reliable, but not all other clients may use XEP-0372?
  • Should the mentionned nick be highlighted somehow in the send box to hint that this will be a mention? I guess it is a good idea to implement that in received messages as well (in addition to sending a BNotification). References may have begin/end markers, but that's optional, how do we handle references without markers, do we highlight the whole message?

comment:6 by pulkomandy, 15 months ago

API should be something like:

std::list<MUCParticipant> FindPossibleNicknameCompletions(std::string prefix)

Returning an ordered list (order as mentionned above: first the recently mentionned, then the recently talked, and finally the other users). Users not curently in the chat should be in the list, but marked as offline so they can be skipped. This "mark" should be connected to the core so that, if the user comes back online, this is updated, and they will be in the list at the next tab completion attempt.

The idea is that we will get this list once, when tab is pressed, and keep using the same list for the next presses on tab (until some other key is pressed, for example backspace or more text added).

In the chat input, we must remember what was inserted by the first tab completion to replace it with the next one if tab is pressed again. We could also display at any time what would be completed if tab was pressed, but maybe that's too disuptive? When completing and there are multiple options, should we display them in a popup menu?

comment:8 by pulkomandy, 15 months ago

Status: newclosed

comment:9 by pulkomandy, 13 months ago

Milestone: 1.24
Note: See TracTickets for help on using tickets.