Skip to content

Sort mention list by relations to current user #3330

@last-partizan

Description

@last-partizan

When typing @username Elk displays a list of possible users to mention.

Would be great to sort this list by user relations with those accounts, e.q.: display followed accounts first.

I'm familiar with vue, and I can implement this, but I need some input first.

My first draft looks like this:
diff --git a/app/composables/tiptap/suggestion.ts b/app/composables/tiptap/suggestion.ts
index fdaa24cd..b66c7d73 100644
--- a/app/composables/tiptap/suggestion.ts
+++ b/app/composables/tiptap/suggestion.ts
@@ -23,16 +23,33 @@ export const TiptapMentionSuggestion: Partial<SuggestionOptions> = import.meta.s
   : {
       pluginKey: new PluginKey('mention'),
       char: '@',
-      async items({ query }) {
+      async items({ query }): Promise<mastodon.v1.Account[]> {
         if (query.length === 0)
           return []
-
-        const paginator = useMastoClient().v2.search.list({ q: query, type: 'accounts', limit: 25, resolve: true })
-        return (await paginator.next()).value?.accounts ?? []
+        const client = useMastoClient()
+        const searchParams = { q: query, type: 'accounts' as const, limit: 5 }
+        const following = client.v2.search.list({ ...searchParams, following: true })
+        const other = client.v2.search.list({ ...searchParams, following: false })
+        const results = await Promise.all([following.next(), other.next()])
+        return uniqueBy(results.flatMap(result => result.value?.accounts ?? []), 'acct')
       },
       render: createSuggestionRenderer(TiptapMentionList),
     }
 
+function uniqueBy<T extends object>(items: T[], by: keyof T) {
+  const seen = new Set()
+  return items.filter((v) => {
+    const identity = v[by]
+    if (seen.has(identity)) {
+      return false
+    }
+    else {
+      seen.add(identity)
+      return true
+    }
+  })
+}
+
 export const TiptapHashtagSuggestion: Partial<SuggestionOptions> = {
   pluginKey: new PluginKey('hashtag'),
   char: '#',

I'm not entirely happy with this version, because of mastodon/mastodon#28238 this bug, which prevents partial username search. So, maybe we should go other way, and do something like this:

  • Fetch list of following accounts (once)
  • Filter list of following on the fly, without API request. If it has some data, display it. Trigger API search only if no matches found.

What do you think?

I created similar issue in Mastodon, to see if they're open to do this sort server-side mastodon/mastodon#35342

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions