git ssb

10+

Matt McKegg / patchwork



Tree: 0860eec08ace9e3fda8b85223b0bf924740870ec

Files: 0860eec08ace9e3fda8b85223b0bf924740870ec / modules / profile / async / suggest.js

2957 bytesRaw
1var nest = require('depnest')
2var {Struct, map, computed, watch} = require('mutant')
3
4exports.needs = nest({
5 'profile.obs.recentlyUpdated': 'first',
6 'contact.obs.following': 'first',
7 'about.obs.name': 'first',
8 'about.obs.imageUrl': 'first',
9 'intl.sync.startsWith': 'first',
10 'keys.sync.id': 'first'
11})
12
13exports.gives = nest('profile.async.suggest')
14
15exports.create = function (api) {
16 var suggestions = null
17 var recentSuggestions = null
18 var following = null
19 var matches = api.intl.sync.startsWith
20
21 return nest('profile.async.suggest', function () {
22 loadSuggestions()
23 return function (word, defaultItems) {
24 var defaultSuggestions = Array.isArray(defaultItems) && defaultItems.length ? suggestions().filter((item) => {
25 return matches(item.title, word) && defaultItems.includes(item.id)
26 }) : null
27
28 if (!word) {
29 return defaultSuggestions || recentSuggestions()
30 } else {
31 var result = defaultSuggestions || []
32
33 // prioritize people you follow
34 suggestions().forEach((item) => {
35 if (following().includes(item.id) && matches(item.title, word) && !result.some(v => v.id === item.id)) {
36 result.push(item)
37 }
38 })
39
40 // next most recently active profiles
41 recentSuggestions().forEach((item) => {
42 if (matches(item.title, word) && !result.some(v => v.id === item.id)) {
43 result.push(item)
44 }
45 })
46
47 // fallback to everyone
48 suggestions().forEach((item) => {
49 if (matches(item.title, word) && !result.some(v => v.id === item.id)) {
50 result.push(item)
51 }
52 })
53 return result
54 }
55 }
56 })
57
58 function loadSuggestions () {
59 if (!suggestions) {
60 var id = api.keys.sync.id()
61 following = api.contact.obs.following(id)
62 var recentlyUpdated = api.profile.obs.recentlyUpdated()
63 var contacts = computed([following, recentlyUpdated], function (a, b) {
64 var result = Array.from(a)
65 b.forEach((item, i) => {
66 if (!result.includes(item)) {
67 result.push(item)
68 }
69 })
70 return result
71 })
72
73 recentSuggestions = map(computed(recentlyUpdated, (items) => Array.from(items).slice(0, 40)), suggestion, {idle: true})
74 suggestions = map(contacts, suggestion, {idle: true})
75 watch(recentSuggestions)
76 watch(suggestions)
77 }
78 }
79
80 function suggestion (id) {
81 var name = api.about.obs.name(id)
82 return Struct({
83 title: name,
84 id,
85 subtitle: id.substring(0, 10),
86 value: computed([name, id], mention, {idle: true}),
87 cls: computed([id, following], followingClass, {idle: true}),
88 image: api.about.obs.imageUrl(id),
89 showBoth: true
90 })
91 }
92}
93
94function mention (name, id) {
95 return `[@${name}](${id})`
96}
97
98function followingClass (id, following) {
99 if (following.includes(id)) {
100 return 'following'
101 }
102}
103

Built with git-ssb-web