Improve auto-complete performance, include nicks

Previously, user auto-completion would only use the user IDs- now user
names are completed for also.
This commit is contained in:
Jaidyn Ann 2021-08-11 12:07:11 -05:00
parent 6b8823d213
commit f5ba403e55
2 changed files with 60 additions and 44 deletions

View File

@ -17,7 +17,7 @@
SendTextView::SendTextView(const char* name, ConversationView* convView) SendTextView::SendTextView(const char* name, ConversationView* convView)
: :
BTextView(name), BTextView(name),
fConversationView(convView), fChatView(convView),
fCurrentIndex(0), fCurrentIndex(0),
fHistoryIndex(0) fHistoryIndex(0)
{ {
@ -50,7 +50,7 @@ SendTextView::KeyDown(const char* bytes, int32 numBytes)
Insert("\n"); Insert("\n");
else if ((bytes[0] == B_ENTER) && (modifiers == 0)) { else if ((bytes[0] == B_ENTER) && (modifiers == 0)) {
_AppendHistory(); _AppendHistory();
fConversationView->MessageReceived(new BMessage(APP_CHAT)); fChatView->MessageReceived(new BMessage(APP_CHAT));
} }
else else
BTextView::KeyDown(bytes, numBytes); BTextView::KeyDown(bytes, numBytes);
@ -60,7 +60,7 @@ SendTextView::KeyDown(const char* bytes, int32 numBytes)
void void
SendTextView::_AutoComplete() SendTextView::_AutoComplete()
{ {
if (fConversationView == NULL || fConversationView->GetConversation() == NULL) if (fChatView == NULL || fChatView->GetConversation() == NULL)
return; return;
BStringList words; BStringList words;
@ -74,64 +74,77 @@ SendTextView::_AutoComplete()
fCurrentWord = lastWord; fCurrentWord = lastWord;
// Now to find the substitutes // Now to find the substitutes
const char* substitution = NULL; BString substitution;
if (fCurrentWord.StartsWith("/") == true) if (fCurrentWord.StartsWith("/") == true) {
substitution = _CommandAutoComplete(); substitution = _NextMatch(_CommandNames(), fCurrentWord.RemoveFirst("/"));
if (substitution.IsEmpty() == true)
substitution.Prepend("/");
}
else else
substitution = _UserAutoComplete(); substitution = _NextMatch(_UserNames(), fCurrentWord);
if (substitution == NULL) // Apply the substitution
if (substitution.IsEmpty() == true)
fCurrentIndex = 0; fCurrentIndex = 0;
else { else {
text.ReplaceLast(lastWord.String(), substitution); int32 index = text.FindLast(lastWord);
SetText(text.String()); int32 newindex = index + substitution.Length();
Select(TextLength(), TextLength());
Delete(index, lastWord.CountChars());
Insert(index, substitution, substitution.Length());
Select(newindex, newindex);
} }
} }
const char* BString
SendTextView::_CommandAutoComplete() SendTextView::_NextMatch(BStringList list, BString current)
{ {
int64 instance = BString match;
fConversationView->GetConversation()->GetProtocolLooper()->GetInstance(); for (int i = 0, j = 0; i < list.CountStrings(); i++)
CommandMap commands = if (list.StringAt(i).StartsWith(current)) {
((TheApp*)be_app)->GetMainWindow()->GetServer()->Commands(instance);
BString command;
BString cmdWord = BString(fCurrentWord).Remove(0, 1);
for (int i, j = 0; i < commands.CountItems(); i++)
if (commands.KeyAt(i).StartsWith(cmdWord)) {
if (j == fCurrentIndex) { if (j == fCurrentIndex) {
command = commands.KeyAt(i); match = list.StringAt(i);
fCurrentIndex++; fCurrentIndex++;
break; break;
} }
j++; j++;
} }
if (command.IsEmpty() == true) return match;
return NULL;
return command.Prepend("/").String();
} }
const char* BStringList
SendTextView::_UserAutoComplete() SendTextView::_CommandNames()
{ {
BString user; if (fCurrentIndex == 0) {
UserMap users = fConversationView->GetConversation()->Users(); int64 instance = fChatView->GetConversation()->GetProtocolLooper()->GetInstance();
for (int i, j = 0; i < users.CountItems(); i++) BStringList cmdNames;
if (users.KeyAt(i).StartsWith(fCurrentWord)) { CommandMap cmds =
if (j == fCurrentIndex) { ((TheApp*)be_app)->GetMainWindow()->GetServer()->Commands(instance);
user = users.KeyAt(i);
fCurrentIndex++; for (int i = 0; i < cmds.CountItems(); i++)
break; cmdNames.Add(cmds.KeyAt(i));
} fCurrentList = cmdNames;
j++; }
return fCurrentList;
}
BStringList
SendTextView::_UserNames()
{
if (fCurrentIndex == 0) {
BStringList nameAndId;
UserMap users = fChatView->GetConversation()->Users();
for (int i = 0; i < users.CountItems(); i++) {
nameAndId.Add(users.KeyAt(i));
nameAndId.Add(users.ValueAt(i)->GetName());
} }
if (user.IsEmpty() == true) fCurrentList = nameAndId;
return NULL; }
return user.String(); return fCurrentList;
} }

View File

@ -19,18 +19,21 @@ public:
private: private:
void _AutoComplete(); void _AutoComplete();
const char* _CommandAutoComplete(); BString _NextMatch(BStringList list, BString current);
const char* _UserAutoComplete();
BStringList _CommandNames();
BStringList _UserNames();
void _AppendHistory(); void _AppendHistory();
void _UpHistory(); void _UpHistory();
void _DownHistory(); void _DownHistory();
ConversationView* fConversationView; ConversationView* fChatView;
// Used for auto-completion // Used for auto-completion
int32 fCurrentIndex; int32 fCurrentIndex;
BString fCurrentWord; BString fCurrentWord;
BStringList fCurrentList;
// Used for history // Used for history
BStringList fHistory; BStringList fHistory;