Files: 9b14c2770a1b327ee389c1c27a56ae36412130c0 / modules / page / html / render / profile.js
3921 bytesRaw
1 | var nest = require('depnest') |
2 | var ref = require('ssb-ref') |
3 | var {Value, h, when, computed, map, send} = require('mutant') |
4 | var extend = require('xtend') |
5 | |
6 | exports.needs = nest({ |
7 | 'about.obs.name': 'first', |
8 | 'about.html.image': 'first', |
9 | 'feed.html.rollup': 'first', |
10 | 'sbot.pull.userFeed': 'first', |
11 | 'sbot.async.publish': 'first', |
12 | 'keys.sync.id': 'first', |
13 | 'profile.obs': { |
14 | followers: 'first', |
15 | following: 'first' |
16 | } |
17 | }) |
18 | exports.gives = nest('page.html.render') |
19 | |
20 | exports.create = function (api) { |
21 | return nest('page.html.render', function profile (id) { |
22 | if (!ref.isFeed(id)) return |
23 | |
24 | var name = api.about.obs.name(id) |
25 | var yourId = api.keys.sync.id() |
26 | var yourFollows = api.profile.obs.following(yourId) |
27 | var rawFollowers = api.profile.obs.followers(id) |
28 | var rawFollowing = api.profile.obs.following(id) |
29 | var doneWaiting = Value(false) |
30 | setTimeout(() => doneWaiting.set(true), 1e3) |
31 | var friendsLoaded = computed([rawFollowers, rawFollowing, doneWaiting], (...x) => x.every(Boolean)) |
32 | |
33 | var friends = computed([rawFollowing, rawFollowers], (following, followers) => { |
34 | return Array.from(following).filter(follow => followers.has(follow)) |
35 | }) |
36 | |
37 | var following = computed([rawFollowing, friends], (following, friends) => { |
38 | return Array.from(following).filter(follow => !friends.includes(follow)) |
39 | }) |
40 | |
41 | var followers = computed([rawFollowers, friends], (followers, friends) => { |
42 | return Array.from(followers).filter(follower => !friends.includes(follower)) |
43 | }) |
44 | |
45 | var isFriends = computed([friends], function (friends) { |
46 | return friends.includes(yourId) |
47 | }) |
48 | |
49 | var followsYou = computed([following], function (followsYou) { |
50 | return followsYou.includes(yourId) |
51 | }) |
52 | |
53 | var youFollow = computed([yourFollows], function (youFollow) { |
54 | return youFollow.has(id) |
55 | }) |
56 | |
57 | var prepend = h('header', {className: 'ProfileHeader'}, [ |
58 | h('div.image', api.about.html.image(id)), |
59 | h('div.title', [ |
60 | h('h1', ['@', name]) |
61 | ]), |
62 | h('div.meta', [ |
63 | when(id === yourId, [ |
64 | h('a.-disabled', 'This is you!') |
65 | ], [ |
66 | when(youFollow, |
67 | h('a.ToggleButton.-unsubscribe', { |
68 | 'href': '#', |
69 | 'title': 'Click to unfollow', |
70 | 'ev-click': send(unfollow, id) |
71 | }, when(isFriends, 'Friends', 'Following')), |
72 | h('a.ToggleButton.-subscribe', { |
73 | 'href': '#', |
74 | 'ev-click': send(follow, id) |
75 | }, when(followsYou, 'Follow Back', 'Follow')) |
76 | ) |
77 | ]) |
78 | |
79 | ]) |
80 | ]) |
81 | |
82 | return h('div', {className: 'SplitView'}, [ |
83 | h('div.main', [ |
84 | api.feed.html.rollup((opts) => { |
85 | return api.sbot.pull.userFeed(extend(opts, {id})) |
86 | }, { prepend }) |
87 | ]), |
88 | h('div.side.-right', [ |
89 | when(friendsLoaded, |
90 | h('div', [ |
91 | renderContactBlock('Friends', friends), |
92 | renderContactBlock('Followers', followers), |
93 | renderContactBlock('Following', following) |
94 | ]), |
95 | h('div', {className: 'Loading'}) |
96 | ) |
97 | ]) |
98 | ]) |
99 | }) |
100 | |
101 | function renderContactBlock (title, profiles) { |
102 | return [ |
103 | when(computed(profiles, x => x.length), h('h2', title)), |
104 | h('div', { |
105 | classList: 'ProfileList' |
106 | }, [ |
107 | map(profiles, (id) => { |
108 | return h('a.profile', { |
109 | href: id |
110 | }, [ |
111 | h('div.avatar', [api.about.html.image(id)]), |
112 | h('div.main', [ |
113 | h('div.name', [ api.about.obs.name(id) ]) |
114 | ]) |
115 | ]) |
116 | }, { |
117 | idle: true |
118 | }) |
119 | ]) |
120 | ] |
121 | } |
122 | |
123 | function follow (id) { |
124 | api.sbot.async.publish({ |
125 | type: 'contact', |
126 | contact: id, |
127 | following: true |
128 | }) |
129 | } |
130 | |
131 | function unfollow (id) { |
132 | api.sbot.async.publish({ |
133 | type: 'contact', |
134 | contact: id, |
135 | following: false |
136 | }) |
137 | } |
138 | } |
139 |
Built with git-ssb-web