70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
package isphere
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type Contact struct {
|
|
ContactID string
|
|
DisplayName string
|
|
Account string
|
|
Source string
|
|
Confidence float64
|
|
RawRef string
|
|
}
|
|
|
|
type SearchContactsQuery struct {
|
|
Query string
|
|
Limit int
|
|
}
|
|
|
|
type SearchContactsResult struct {
|
|
Contacts []Contact
|
|
}
|
|
|
|
func SearchContactsFromMessages(messages []Message, query SearchContactsQuery) SearchContactsResult {
|
|
unique := map[string]Contact{}
|
|
for _, message := range messages {
|
|
addMessageContact(unique, message.SenderID)
|
|
addMessageContact(unique, message.ReceiverID)
|
|
}
|
|
|
|
queryText := strings.ToLower(strings.TrimSpace(query.Query))
|
|
ids := make([]string, 0, len(unique))
|
|
for id := range unique {
|
|
if queryText == "" || strings.Contains(strings.ToLower(id), queryText) || strings.Contains(strings.ToLower(unique[id].DisplayName), queryText) {
|
|
ids = append(ids, id)
|
|
}
|
|
}
|
|
sort.Strings(ids)
|
|
|
|
limit := query.Limit
|
|
if limit <= 0 || limit > len(ids) {
|
|
limit = len(ids)
|
|
}
|
|
contacts := make([]Contact, 0, limit)
|
|
for _, id := range ids[:limit] {
|
|
contacts = append(contacts, unique[id])
|
|
}
|
|
return SearchContactsResult{Contacts: contacts}
|
|
}
|
|
|
|
func addMessageContact(unique map[string]Contact, id string) {
|
|
trimmed := strings.TrimSpace(id)
|
|
if trimmed == "" {
|
|
return
|
|
}
|
|
if _, exists := unique[trimmed]; exists {
|
|
return
|
|
}
|
|
unique[trimmed] = Contact{
|
|
ContactID: trimmed,
|
|
DisplayName: trimmed,
|
|
Account: trimmed,
|
|
Source: "local_readonly",
|
|
Confidence: 0.6,
|
|
RawRef: "message_jid",
|
|
}
|
|
}
|