Files: e2d5bfd85bf6a1e43f4cf5d1f8b8980d5830ecba / about / async / suggest.js
2585 bytesRaw
1 | const nest = require('depnest') |
2 | const { Struct, map, concat, dictToCollection, computed, lookup, watch, keys, resolve } = require('mutant') |
3 | |
4 | exports.gives = nest('about.async.suggest') |
5 | |
6 | exports.needs = nest({ |
7 | 'about.obs.groupedValues': 'first', |
8 | 'about.obs.name': 'first', |
9 | 'about.obs.imageUrl': 'first', |
10 | 'contact.obs.following': 'first', |
11 | 'feed.obs.recent': 'first', |
12 | 'keys.sync.id': 'first' |
13 | }) |
14 | |
15 | exports.create = function (api) { |
16 | var suggestions = null |
17 | var recentSuggestions = null |
18 | |
19 | return nest('about.async.suggest', suggest) |
20 | |
21 | function suggest () { |
22 | loadSuggestions() |
23 | return function (word) { |
24 | if (!word) return recentSuggestions() |
25 | |
26 | return suggestions() |
27 | .filter((item) => { |
28 | return item.title.toLowerCase().startsWith(word.toLowerCase()) |
29 | }) |
30 | .reverse() |
31 | } |
32 | } |
33 | |
34 | function loadSuggestions () { |
35 | if (suggestions) return |
36 | |
37 | var id = api.keys.sync.id() |
38 | var following = api.contact.obs.following(id) |
39 | var recentlyUpdated = api.feed.obs.recent() |
40 | var contacts = computed([following, recentlyUpdated], (a, b) => { |
41 | var result = new Set (a) |
42 | b.forEach(item => result.add(item)) |
43 | |
44 | return Array.from(result) |
45 | }) |
46 | |
47 | recentSuggestions = map( |
48 | computed(recentlyUpdated, (items) => Array.from(items).slice(0, 10)), |
49 | suggestion, |
50 | {idle: true} |
51 | ) |
52 | |
53 | const suggestionsRecord = lookup(contacts, contact => { |
54 | return [contact, keys(api.about.obs.groupedValues(contact, 'name'))] |
55 | }) |
56 | |
57 | suggestions = concat( |
58 | map(dictToCollection(suggestionsRecord), pluralSuggestions, {idle: true}) |
59 | ) |
60 | |
61 | watch(recentSuggestions) |
62 | watch(suggestions) |
63 | } |
64 | |
65 | function pluralSuggestions (item) { |
66 | const id = resolve(item.key) |
67 | return map(item.value, name => { |
68 | return Struct({ |
69 | id, |
70 | title: name, |
71 | subtitle: subtitle(id, name), |
72 | value: computed([name, id], mention), |
73 | image: api.about.obs.imageUrl(id), |
74 | showBoth: true |
75 | }) |
76 | }) |
77 | } |
78 | |
79 | function suggestion (id) { |
80 | var name = api.about.obs.name(id) |
81 | return Struct({ |
82 | title: name, |
83 | id, |
84 | subtitle: id.substring(0, 10), |
85 | value: computed([name, id], mention), |
86 | image: api.about.obs.imageUrl(id), |
87 | showBoth: true |
88 | }) |
89 | } |
90 | |
91 | function subtitle (id, name) { |
92 | return computed([api.about.obs.name(id)], commonName => { |
93 | return name.toLowerCase() === commonName.toLowerCase() |
94 | ? id.substring(0, 10) |
95 | : `${commonName} ${id.substring(0, 10)}` |
96 | }) |
97 | } |
98 | } |
99 | |
100 | function mention (name, id) { |
101 | return `[@${name}](${id})` |
102 | } |
103 | |
104 |
Built with git-ssb-web