mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-19 19:46:50 +00:00
more flexible user search for mentions.
This commit is contained in:
parent
bec63b1c09
commit
bc88fe979c
@ -338,22 +338,75 @@ impl People {
|
||||
|
||||
/// This lets you start typing a name, and autocomplete the results for tagging
|
||||
/// someone in a post. It returns maximum 10 results.
|
||||
pub fn get_ids_from_prefix(&self, mut prefix: &str) -> Vec<(String, PublicKeyHex)> {
|
||||
pub fn search_people_to_tag(&self, mut text: &str) -> Vec<(String, PublicKeyHex)> {
|
||||
// work with or without the @ symbol:
|
||||
if prefix.starts_with('@') {
|
||||
prefix = &prefix[1..]
|
||||
if text.starts_with('@') {
|
||||
text = &text[1..]
|
||||
}
|
||||
self.people
|
||||
// normalize case
|
||||
let search = String::from(text).to_lowercase();
|
||||
|
||||
// grab all results then sort by score
|
||||
let mut results: Vec<(u16, String, PublicKeyHex)> = self
|
||||
.people
|
||||
.iter()
|
||||
.filter_map(|person| {
|
||||
if let Some(name) = &person.name {
|
||||
if name.starts_with(prefix) {
|
||||
return Some((name.clone(), person.pubkey.clone()));
|
||||
let mut score = 0u16;
|
||||
let mut result_name = String::from("");
|
||||
|
||||
// search for users by name
|
||||
if let Some(name) = &person.name.as_ref() {
|
||||
let matchable = name.to_lowercase();
|
||||
if matchable.starts_with(&search) {
|
||||
score = 300;
|
||||
result_name = name.to_string();
|
||||
}
|
||||
if matchable.contains(&search) {
|
||||
score = 200;
|
||||
result_name = name.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
// search for users by nip05 id
|
||||
if score == 0 && person.dns_id_valid > 0 {
|
||||
if let Some(dns_id) = &person.dns_id.as_ref().map(|n| n.to_lowercase()) {
|
||||
if dns_id.starts_with(&search) {
|
||||
score = 400;
|
||||
result_name = dns_id.to_string();
|
||||
}
|
||||
if dns_id.contains(&search) {
|
||||
score = 100;
|
||||
result_name = dns_id.to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if score > 0 {
|
||||
// if there is not a name, fallback to showing the initial chars of the pubkey,
|
||||
// but this is probably unnecessary and will never happen
|
||||
if result_name == "" {
|
||||
result_name = person.pubkey.to_string();
|
||||
}
|
||||
|
||||
// bigger names have a higher match chance, but they should be scored lower
|
||||
score = score - result_name.len() as u16;
|
||||
|
||||
return Some((score, result_name, person.pubkey.clone()));
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
.take(10)
|
||||
.collect();
|
||||
|
||||
results.sort_by(|a, b| a.0.cmp(&b.0).reverse());
|
||||
let max = if results.len() > 10 {
|
||||
10
|
||||
} else {
|
||||
results.len()
|
||||
};
|
||||
results[0..max]
|
||||
.into_iter()
|
||||
.map(|r| (r.1.to_owned(), r.2.clone()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ fn real_posting_area(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram
|
||||
.hint_text("@username"),
|
||||
);
|
||||
if !app.tag_someone.is_empty() {
|
||||
let pairs = GLOBALS.people.get_ids_from_prefix(&app.tag_someone);
|
||||
let pairs = GLOBALS.people.search_people_to_tag(&app.tag_someone);
|
||||
if !pairs.is_empty() {
|
||||
ui.menu_button("@", |ui| {
|
||||
for pair in pairs {
|
||||
|
Loading…
Reference in New Issue
Block a user