diff options
author | Dessalines <tyhou13@gmx.com> | 2020-01-24 13:59:50 -0500 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2020-01-24 13:59:50 -0500 |
commit | 608856b6cdd42b83f35eee8cb556ac626e75727f (patch) | |
tree | ccb74ba0a840d24a69f8ba3f3e95e06b5b5cce26 /ui/src/utils.ts | |
parent | 353891a3d1af878a8ce8d5562f3deaa9be380144 (diff) |
Adding autocomplete to post, community, message, and site forms. Fixes #453
Diffstat (limited to 'ui/src/utils.ts')
-rw-r--r-- | ui/src/utils.ts | 127 |
1 files changed, 123 insertions, 4 deletions
diff --git a/ui/src/utils.ts b/ui/src/utils.ts index 0e4cd9d5..6a0ffdb3 100644 --- a/ui/src/utils.ts +++ b/ui/src/utils.ts @@ -18,13 +18,17 @@ import { SearchType, WebSocketResponse, WebSocketJsonResponse, + SearchForm, + SearchResponse, } from './interfaces'; -import { UserService } from './services/UserService'; +import { UserService, WebSocketService } from './services'; + +import Tribute from 'tributejs/src/Tribute.js'; import markdown_it from 'markdown-it'; import markdownitEmoji from 'markdown-it-emoji/light'; import markdown_it_container from 'markdown-it-container'; -import * as twemoji from 'twemoji'; -import * as emojiShortName from 'emoji-short-name'; +import twemoji from 'twemoji'; +import emojiShortName from 'emoji-short-name'; import Toastify from 'toastify-js'; export const repoUrl = 'https://github.com/dessalines/lemmy'; @@ -33,7 +37,7 @@ export const archiveUrl = 'https://archive.is'; export const postRefetchSeconds: number = 60 * 1000; export const fetchLimit: number = 20; -export const mentionDropdownFetchLimit = 6; +export const mentionDropdownFetchLimit = 10; export function randomStr() { return Math.random() @@ -380,3 +384,118 @@ export function toast(text: string, background: string = 'success') { backgroundColor: backgroundColor, }).showToast(); } + +export function setupTribute(): Tribute { + return new Tribute({ + collection: [ + // Emojis + { + trigger: ':', + menuItemTemplate: (item: any) => { + let emoji = `:${item.original.key}:`; + return `${item.original.val} ${emoji}`; + }, + selectTemplate: (item: any) => { + return `:${item.original.key}:`; + }, + values: Object.entries(emojiShortName).map(e => { + return { key: e[1], val: e[0] }; + }), + allowSpaces: false, + autocompleteMode: true, + menuItemLimit: mentionDropdownFetchLimit, + }, + // Users + { + trigger: '@', + selectTemplate: (item: any) => { + return `[/u/${item.original.key}](/u/${item.original.key})`; + }, + values: (text: string, cb: any) => { + userSearch(text, (users: any) => cb(users)); + }, + allowSpaces: false, + autocompleteMode: true, + menuItemLimit: mentionDropdownFetchLimit, + }, + + // Communities + { + trigger: '#', + selectTemplate: (item: any) => { + return `[/c/${item.original.key}](/c/${item.original.key})`; + }, + values: (text: string, cb: any) => { + communitySearch(text, (communities: any) => cb(communities)); + }, + allowSpaces: false, + autocompleteMode: true, + menuItemLimit: mentionDropdownFetchLimit, + }, + ], + }); +} + +function userSearch(text: string, cb: any) { + if (text) { + let form: SearchForm = { + q: text, + type_: SearchType[SearchType.Users], + sort: SortType[SortType.TopAll], + page: 1, + limit: mentionDropdownFetchLimit, + }; + + WebSocketService.Instance.search(form); + + this.userSub = WebSocketService.Instance.subject.subscribe( + msg => { + let res = wsJsonToRes(msg); + if (res.op == UserOperation.Search) { + let data = res.data as SearchResponse; + let users = data.users.map(u => { + return { key: u.name }; + }); + cb(users); + this.userSub.unsubscribe(); + } + }, + err => console.error(err), + () => console.log('complete') + ); + } else { + cb([]); + } +} + +function communitySearch(text: string, cb: any) { + if (text) { + let form: SearchForm = { + q: text, + type_: SearchType[SearchType.Communities], + sort: SortType[SortType.TopAll], + page: 1, + limit: mentionDropdownFetchLimit, + }; + + WebSocketService.Instance.search(form); + + this.communitySub = WebSocketService.Instance.subject.subscribe( + msg => { + let res = wsJsonToRes(msg); + if (res.op == UserOperation.Search) { + let data = res.data as SearchResponse; + let communities = data.communities.map(u => { + return { key: u.name }; + }); + cb(communities); + this.communitySub.unsubscribe(); + } + }, + err => console.error(err), + () => console.log('complete') + ); + } else { + cb([]); + } +} |