git ssb

16+

Dominic / patchbay



Tree: 37e60d1deaaf54e61e2ecd58ec79b7d4ee7dc6e1

Files: 37e60d1deaaf54e61e2ecd58ec79b7d4ee7dc6e1 / contact / html / relationships.js

4815 bytesRaw
1const nest = require('depnest')
2const { h, map, computed, when, Value } = require('mutant')
3
4exports.gives = nest('contact.html.relationships')
5
6exports.needs = nest({
7 // 'about.html.image': 'first',
8 'about.html.avatar': 'first',
9 // 'about.obs.name': 'first',
10 'contact.async.follow': 'first',
11 'contact.async.unfollow': 'first',
12 'contact.async.block': 'first',
13 'contact.async.unblock': 'first',
14 'contact.obs.followers': 'first',
15 'contact.obs.following': 'first',
16 'contact.obs.blockers': 'first',
17 'contact.obs.blocking': 'first',
18 'keys.sync.id': 'first'
19})
20
21exports.create = function (api) {
22 return nest({
23 'contact.html.relationships': relationships
24 })
25
26 function relationships (feedId) {
27 const rawFollowing = api.contact.obs.following(feedId)
28 const rawFollowers = api.contact.obs.followers(feedId)
29
30 // mix: TODO rework this
31 const friends = computed([rawFollowing, rawFollowers], (following, followers) => {
32 return [...following].filter(follow => followers.includes(follow))
33 })
34 const following = computed([rawFollowing, friends], (following, friends) => {
35 return [...following].filter(follow => !friends.includes(follow))
36 })
37 const followers = computed([rawFollowers, friends], (followers, friends) => {
38 return [...followers].filter(follower => !friends.includes(follower))
39 })
40 const blockers = api.contact.obs.blockers(feedId)
41 const blocking = api.contact.obs.blocking(feedId)
42
43 const modes = [
44 { label: 'Friends', data: friends },
45 { label: 'Follows', data: following },
46 { label: 'Followers', data: followers },
47 { label: 'Blocked by', data: blockers, hideEmpty: true },
48 { label: 'Blocking', data: blocking, hideEmpty: true }
49 ]
50 const mode = Value(0)
51 const setMode = (i) => {
52 if (mode() === i) mode.set()
53 else mode.set(i)
54 }
55
56 const avatar = api.about.html.avatar
57
58 return h('Relationships', [
59 h('header', 'Relationships'),
60 RelationshipStatus({ feedId, rawFollowing, blockers, api }),
61
62 h('div.groups', [
63 h('div.tabs', modes.map(({ label, data, hideEmpty }, i) => {
64 return computed([data, mode], (d, mode) => {
65 if (hideEmpty && !d.length) return
66
67 return h('div.tab',
68 {
69 className: mode === i ? '-active' : '',
70 'ev-click': () => setMode(i)
71 },
72 [
73 h('div.label', label),
74 h('div.count', d.length > 50 ? '50+' : d.length)
75 ]
76 )
77 })
78 })),
79 h('div.group', computed(mode, i => {
80 if (i === null) return
81
82 const { data } = modes[i]
83 return map(data, avatar)
84 }))
85 ])
86 ])
87 }
88}
89
90function RelationshipStatus ({ feedId, rawFollowing, blockers, api }) {
91 const myId = api.keys.sync.id()
92 if (feedId === myId) return
93
94 // mix: TODO oh lord this is ugly, refactor it !
95 const ImFollowing = api.contact.obs.following(myId)
96 const IFollowThem = computed([ImFollowing], ImFollowing => ImFollowing.includes(feedId))
97 const theyFollowMe = computed([rawFollowing], following => following.includes(myId))
98 const ImBlockingThem = computed(blockers, blockers => blockers.includes(myId))
99
100 const relationshipStatus = computed([IFollowThem, theyFollowMe], (IFollowThem, theyFollowMe) => {
101 return IFollowThem && theyFollowMe ? '- you are friends'
102 : IFollowThem ? '- you follow them'
103 : theyFollowMe ? '- they follow you'
104 : ''
105 })
106 const { unfollow, follow, block, unblock } = api.contact.async
107
108 return h('div.relationship-status', [
109 h('section -friendship', [
110 when(ImFollowing.sync,
111 when(IFollowThem,
112 h('button', { 'ev-click': () => unfollow(feedId) }, 'Unfollow'),
113 h('button', { 'ev-click': () => follow(feedId) }, 'Follow')
114 ),
115 h('button', { disabled: 'disabled' }, 'Loading...')
116 ),
117 when(ImFollowing.sync, h('div.relationship-status', relationshipStatus))
118 ]),
119 h('section -blocking', [
120 when(ImBlockingThem,
121 h('button -subtle', { 'ev-click': () => unblock(feedId, console.log) }, [ h('i.fa.fa-ban'), 'unblock' ]),
122 h('button -subtle', { 'ev-click': () => block(feedId, console.log) }, [ h('i.fa.fa-ban'), 'BLOCK' ])
123 ),
124 h('div.explainer', [
125 "Blocking tells everyone you don't want to communicate with a person.",
126 h('ul', [
127 h('li', 'You will no longer receive messages from this person'),
128 h('li', "This person won't get any new information about you (including this block)"),
129 h('li', "Your followers will see you have blocked this person - their apps need to know so that they don't pass your information on.")
130 ])
131 ])
132 ])
133 ])
134}
135

Built with git-ssb-web