Files: 10e34b53d3a68d175823c7588d903463e08056ce / app / html / context.js
3719 bytesRaw
1 | const nest = require('depnest') |
2 | const { h, computed, map, when, Dict, dictToCollection, Array: MutantArray } = require('mutant') |
3 | const pull = require('pull-stream') |
4 | const next = require('pull-next-step') |
5 | const get = require('lodash/get') |
6 | |
7 | exports.gives = nest('app.html.context') |
8 | |
9 | exports.needs = nest({ |
10 | 'about.html.image': 'first', |
11 | 'about.obs.name': 'first', |
12 | 'app.html.link': 'first', |
13 | 'feed.pull.private': 'first', |
14 | 'feed.pull.rollup': 'first', |
15 | 'keys.sync.id': 'first', |
16 | 'message.html.subject': 'first', |
17 | 'translations.sync.strings': 'first', |
18 | }) |
19 | |
20 | |
21 | exports.create = (api) => { |
22 | return nest('app.html.context', (location) => { |
23 | |
24 | const strings = api.translations.sync.strings() |
25 | const myKey = api.keys.sync.id() |
26 | |
27 | const discover = { |
28 | notifications: Math.floor(Math.random()*5+1), |
29 | imageEl: h('i.fa.fa-binoculars'), |
30 | name: strings.blogIndex.title, |
31 | location: { page: 'blogIndex' }, |
32 | selected: ['blogIndex', 'home'].includes(location.page) |
33 | } |
34 | var nearby = [] |
35 | |
36 | var recentPeersContacted = Dict() |
37 | // TODO - extract as contact.obs.recentPrivate or something |
38 | |
39 | pull( |
40 | next(api.feed.pull.private, {reverse: true, limit: 100, live: false}, ['value', 'timestamp']), |
41 | pull.filter(msg => msg.value.content.recps), |
42 | pull.drain(msg => { |
43 | msg.value.content.recps |
44 | .map(recp => typeof recp === 'object' ? recp.link : recp) |
45 | .filter(recp => recp != myKey) |
46 | .forEach(recp => { |
47 | if (recentPeersContacted.has(recp)) return |
48 | |
49 | recentPeersContacted.put(recp, msg) |
50 | }) |
51 | }) |
52 | ) |
53 | |
54 | return h('Context -feed', [ |
55 | LevelOneContext(), |
56 | LevelTwoContext() |
57 | ]) |
58 | |
59 | function LevelOneContext () { |
60 | return h('div.level.-one', [ |
61 | Option(discover), |
62 | map(nearby, Option), // TODO |
63 | map(dictToCollection(recentPeersContacted), ({ key, value }) => { |
64 | const feedId = key() |
65 | const lastMsg = value() |
66 | return Option({ |
67 | notifications: Math.random() > 0.7 ? Math.floor(Math.random()*9+1) : 0, // TODO |
68 | imageEl: api.about.html.image(feedId), // TODO make avatar |
69 | name: api.about.obs.name(feedId), |
70 | location: Object.assign(lastMsg, { feed: feedId }), // QUESION : how should we pass the context, is stapling feed on like this horrible? |
71 | selected: location.feed === feedId |
72 | }) |
73 | }) |
74 | ]) |
75 | } |
76 | |
77 | function LevelTwoContext () { |
78 | const targetUser = location.feed |
79 | if (!targetUser) return |
80 | |
81 | var threads = MutantArray() |
82 | |
83 | pull( |
84 | next(api.feed.pull.private, {reverse: true, limit: 100, live: false}, ['value', 'timestamp']), |
85 | pull.filter(msg => msg.value.content.recps), |
86 | pull.filter(msg => { |
87 | return msg.value.content.recps |
88 | .map(recp => typeof recp === 'object' ? recp.link : recp) |
89 | .some(recp => recp === targetUser) |
90 | }), |
91 | api.feed.pull.rollup(), |
92 | pull.drain(thread => threads.push(thread)) |
93 | ) |
94 | |
95 | return h('div.level.-two', [ |
96 | h('Button', 'New Message'), // TODO -translate |
97 | map(threads, thread => { |
98 | return h('Option', [ |
99 | api.app.html.link( |
100 | Object.assign(thread, { feed: targetUser }), |
101 | api.message.html.subject(thread) |
102 | ) |
103 | ]) |
104 | }) |
105 | ]) |
106 | } |
107 | |
108 | function Option ({ notifications = 0, imageEl, name, location, selected }) { |
109 | return h('Option', { className: selected ? '-selected' : '' }, [ |
110 | h('div.circle', [ |
111 | when(notifications, h('div.alert', notifications)), |
112 | imageEl |
113 | ]), |
114 | api.app.html.link(location, name), |
115 | ]) |
116 | } |
117 | }) |
118 | } |
119 | |
120 |
Built with git-ssb-web