git ssb

2+

mixmix / ticktack



Commit 2f8b5a42a327baeb86c4cc6af56c65848948d0ec

Merge pull request #83 from ticktackim/subscriptions

Subscriptions
mix irving authored on 2/6/2018, 10:23:41 AM
GitHub committed on 2/6/2018, 10:23:41 AM
Parent: e2fb4d766af3a45d510a0558e410b04dd3366e13
Parent: 235b36e740aa5e415143769f66b42154fb4365d2

Files changed

.gitignorechanged
app/html/channelCard.jschanged
app/html/sideNav/sideNavDiscovery.jschanged
app/page/channelShow.jschanged
app/page/channelSubscriptions.jschanged
channel/index.jschanged
channel/sync.jsdeleted
channel/obs.jsadded
translations/en.jschanged
.gitignoreView
@@ -1,2 +1,3 @@
11 node_modules
22 package-lock.json
3+.idea
app/html/channelCard.jsView
@@ -1,12 +1,8 @@
1-var nest = require('depnest')
2-const { h, map, when, Value } = require('mutant')
3-var isString= require('lodash/isString')
4-var maxBy= require('lodash/maxBy')
5-var markdown = require('ssb-markdown')
6-var ref = require('ssb-ref')
7-var htmlEscape = require('html-escape')
1+const nest = require('depnest')
2+const { h, when } = require('mutant')
83
4+
95 exports.gives = nest('app.html.channelCard')
106
117 exports.needs = nest({
128 'keys.sync.id': 'first',
@@ -14,46 +10,34 @@
1410 'translations.sync.strings': 'first',
1511 'channel.obs.subscribed': 'first',
1612 'channel.async.subscribe': 'first',
1713 'channel.async.unsubscribe': 'first',
18- 'channel.sync.isSubscribedTo': 'first',
14+ 'channel.obs.isSubscribedTo': 'first',
1915 })
2016
2117 exports.create = function (api) {
2218
2319 return nest('app.html.channelCard', (channel) => {
24- var strings = api.translations.sync.strings()
25-
20+ const strings = api.translations.sync.strings()
2621 const myId = api.keys.sync.id()
27- const { subscribed } = api.channel.obs
2822 const { subscribe, unsubscribe } = api.channel.async
29- const { isSubscribedTo } = api.channel.sync
30- const myChannels = subscribed(myId)
31- let cs = myChannels().values()
32- const youSubscribe = Value(isSubscribedTo(channel, myId))
33-
34- let cb = () => {
35- youSubscribe.set(isSubscribedTo(channel, myId))
36- }
23+ const { isSubscribedTo } = api.channel.obs
24+ const youSubscribe = isSubscribedTo(channel, myId)
3725
38- const goToChannel = (e, channel) => {
39- e.stopPropagation()
40-
26+ const goToChannel = () => {
4127 api.history.sync.push({ page: 'channelShow', channel: channel })
4228 }
4329
44- var b = h('ChannelCard', [
30+ return h('ChannelCard', [
4531 h('div.content', [
4632 h('div.text', [
47- h('h2', {'ev-click': ev => goToChannel(ev, channel)}, channel),
33+ h('h2', {'ev-click': goToChannel}, channel),
4834 when(youSubscribe,
49- h('Button', { 'ev-click': () => unsubscribe(channel, cb) }, strings.channelShow.action.unsubscribe),
50- h('Button', { 'ev-click': () => subscribe(channel, cb) }, strings.channelShow.action.subscribe)
35+ h('Button', { 'ev-click': () => unsubscribe(channel) }, strings.channelShow.action.unsubscribe),
36+ h('Button', { 'ev-click': () => subscribe(channel) }, strings.channelShow.action.subscribe)
5137 ),
5238 ])
5339 ])
5440 ])
55-
56- return b
5741 })
5842 }
5943
app/html/sideNav/sideNavDiscovery.jsView
@@ -45,8 +45,9 @@
4545 if (location.page) {
4646 if (location.page.match(/^blog/)) return true
4747 if (location.page.match(/^thread/)) return true
4848 if (location.page.match(/^user/)) return true
49+ if (location.page.match(/^channel/)) return true
4950 }
5051 if (location.key) {
5152 return true
5253 }
@@ -136,9 +137,9 @@
136137 Option({
137138 imageEl: h('i', [
138139 h('img', { src: path.join(__dirname, '../../../assets', 'discover.png') })
139140 ]),
140- label: "My subscriptions",
141+ label: strings.subscriptions.user,
141142 selected: location.page === 'channelSubscriptions' && !location.scope,
142143 location: { page: 'channelSubscriptions', scope: 'user' },
143144 }),
144145
@@ -146,9 +147,9 @@
146147 Option({
147148 imageEl: h('i', [
148149 h('img', { src: path.join(__dirname, '../../../assets', 'discover.png') })
149150 ]),
150- label: "Friends subscriptions",
151+ label: strings.subscriptions.friends,
151152 selected: location.page === 'channelSubscriptions' && location.scope === 'friends',
152153 location: { page: 'channelSubscriptions', scope: 'friends' },
153154 })
154155 ]
app/page/channelShow.jsView
@@ -10,18 +10,15 @@
1010 'app.html.scroller': 'first',
1111 'app.html.blogCard': 'first',
1212 'channel.obs.recent': 'first',
1313 'feed.pull.channel': 'first',
14- 'feed.pull.public': 'first',
1514 'history.sync.push': 'first',
1615 'keys.sync.id': 'first',
17- 'message.html.channel': 'first',
1816 'translations.sync.strings': 'first',
19- 'unread.sync.isUnread': 'first',
2017 'channel.obs.subscribed': 'first',
2118 'channel.async.subscribe': 'first',
2219 'channel.async.unsubscribe': 'first',
23- 'channel.sync.isSubscribedTo': 'first'
20+ 'channel.obs.isSubscribedTo': 'first'
2421 })
2522
2623 exports.create = (api) => {
2724 return nest('app.page.channelShow', channelShow)
@@ -31,23 +28,12 @@
3128 var strings = api.translations.sync.strings()
3229 const myId = api.keys.sync.id()
3330 const { subscribed } = api.channel.obs
3431 const { subscribe, unsubscribe } = api.channel.async
35- const { isSubscribedTo } = api.channel.sync
36- const myChannels = subscribed(myId)
37- let cs = myChannels().values()
38- const youSubscribe = Value(isSubscribedTo(location.channel, myId))
32+ const { isSubscribedTo } = api.channel.obs
33+ const youSubscribe = isSubscribedTo(location.channel, myId)
3934
40- let cb = () => {
41- youSubscribe.set(isSubscribedTo(location.channel, myId))
42- }
43-
4435 var searchVal = resolve(location.channel)
45- var searchResults = computed([api.channel.obs.recent(), searchVal], (channels, val) => {
46- if (val.length < 2) return []
47-
48- return channels.filter(c => c.toLowerCase().indexOf(val.toLowerCase()) > -1)
49- })
5036
5137
5238
5339 createStream = api.feed.pull.channel(location.channel)
@@ -58,10 +44,10 @@
5844 h('section.about', [
5945 h('h1', location.channel),
6046 h('div.actions', [
6147 when(youSubscribe,
62- h('Button', { 'ev-click': () => subscribe(location.channel, cb) }, strings.channelShow.action.unsubscribe),
63- h('Button', { 'ev-click': () => unsubscribe(location.channel, cb) }, strings.channelShow.action.subscribe)
48+ h('Button', { 'ev-click': () => subscribe(location.channel) }, strings.channelShow.action.unsubscribe),
49+ h('Button', { 'ev-click': () => unsubscribe(location.channel) }, strings.channelShow.action.subscribe)
6450 )
6551 ])
6652 ]),
6753 ]
app/page/channelSubscriptions.jsView
@@ -1,11 +1,8 @@
11 const nest = require('depnest')
2-const { h, watch, when, computed, Value, Set: MutantSet } = require('mutant')
3-const pull = require('pull-stream')
4-const Pushable = require('pull-pushable')
5-const ref = require('ssb-ref')
6-const throttle = require('mutant/throttle')
7-const MutantPullReduce = require('mutant-pull-reduce')
2+const { h, when, Value, onceTrue, computed, map: mutantMap } = require('mutant')
3+const sortBy = require('lodash/sortBy')
4+const map = require("lodash/map")
85
96
107 exports.gives = nest('app.page.channelSubscriptions')
118
@@ -13,16 +10,17 @@
1310 'app.html.sideNav': 'first',
1411 'app.html.topNav': 'first',
1512 'app.html.scroller': 'first',
1613 'app.html.channelCard': 'first',
17-
1814 'history.sync.push': 'first',
1915 'keys.sync.id': 'first',
2016 'channel.obs.subscribed': 'first',
17+ 'channel.obs.recent':'first',
2118 'channel.html.link': 'first',
2219 'translations.sync.strings': 'first',
2320 'sbot.async.friendsGet': 'first',
24- 'sbot.pull.userFeed': 'first'
21+ 'sbot.pull.userFeed': 'first',
22+ 'sbot.obs.connection': 'first'
2523 })
2624
2725 exports.create = (api) => {
2826 return nest('app.page.channelSubscriptions', function (location) {
@@ -32,54 +30,56 @@
3230 let myChannels, displaySubscriptions
3331
3432 if (location.scope === "user") {
3533 myChannels = subscribed(myId)
36- displaySubscriptions = () => [...myChannels().values()].map(c => api.app.html.channelCard(c))
34+
35+ const mySubscriptions = computed(myChannels, myChannels => [...myChannels.values()])
3736
3837 return h('Page -channelSubscriptions', { title: strings.home }, [
3938 api.app.html.sideNav(location),
4039 h('div.content', [
4140 //api.app.html.topNav(location),
42- when(myChannels, displaySubscriptions, h("p", "Loading..."))
41+ when(myChannels,
42+ myChannels().size === 0
43+ ? strings.subscriptions.state.noSubscriptions
44+ :''
45+ ),
46+ when(myChannels,
47+ mutantMap(mySubscriptions, api.app.html.channelCard),
48+ h("p", strings.loading)
49+ )
4350 ])
4451 ])
4552
4653 }
4754
4855 if (location.scope === "friends") {
4956
50- function createStream() {
51- var p = Pushable(true) // optionally pass `onDone` after it
57+ myChannels = Value(false)
5258
53- api.sbot.async.friendsGet({ dest: myId }, (err, friends) => {
54- for (f in friends) {
55- var s = subscribed(f)
56- s(c => [...c].map(x => p.push(x)))
57- }
58- })
59+ onceTrue(
60+ api.sbot.obs.connection,
61+ sbot => {
62+ sbot.channel.get((err, c) => {
63+ if (err) throw err
64+ let b = map(c, (v,k) => {return {channel: k, users: v}})
65+ b = sortBy(b, o => o.users.length)
66+ let res = b.reverse().slice(0,100)
5967
60- return p.source
61- }
68+ myChannels.set(res.map(c => c.channel))
69+ })
70+ }
71+ )
6272
63- var stream = createStream()
64- var opts = {
65- startValue: new Set(),
66- nextTick: true
67- }
6873
69- var channelList = api.app.html.scroller({
70- classList: ['content'],
71- stream: createStream,
72- render
73- })
74-
75- function render(channel) {
76- return api.app.html.channelCard(channel)
77- }
78-
79- return h('Page -channelSubscriptions', { title: strings.home }, [
74+ return h('Page -channelSubscriptions', { title: strings.home }, [
8075 api.app.html.sideNav(location),
81- channelList
76+ h('div.content', [
77+ when(myChannels,
78+ mutantMap(myChannels, api.app.html.channelCard),
79+ h("p", strings.loading)
80+ )
81+ ])
8282 ])
8383 }
8484 })
8585 }
channel/index.jsView
@@ -1,6 +1,6 @@
11 module.exports = {
22 async: require('./async'),
3- sync: require('./sync')
3+ obs: require('./obs')
44 }
55
66
channel/sync.jsView
@@ -1,24 +1,0 @@
1-var nest = require('depnest')
2-var ref = require('ssb-ref')
3-
4-exports.needs = nest({
5- 'keys.sync.id': 'first',
6- 'channel.obs.subscribed': 'first',
7-})
8-
9-exports.gives = nest('channel.sync.isSubscribedTo')
10-
11-exports.create = function (api) {
12- return nest('channel.sync.isSubscribedTo', isSubscribedTo)
13-
14- function isSubscribedTo (channel, id) {
15- if (!ref.isFeed(id)) {
16- id = api.keys.sync.id()
17- }
18-
19- const { subscribed } = api.channel.obs
20- const myChannels = subscribed(id)
21- let v = myChannels().values()
22- return [...v].includes(channel)
23- }
24-}
channel/obs.jsView
@@ -1,0 +1,24 @@
1+const nest = require('depnest')
2+const ref = require('ssb-ref')
3+const computed = require('mutant/computed')
4+
5+exports.needs = nest({
6+ 'keys.sync.id': 'first',
7+ 'channel.obs.subscribed': 'first',
8+})
9+
10+exports.gives = nest('channel.obs.isSubscribedTo')
11+
12+exports.create = function (api) {
13+ return nest('channel.obs.isSubscribedTo', isSubscribedTo)
14+
15+ function isSubscribedTo (channel, id) {
16+ if (!ref.isFeed(id)) {
17+ id = api.keys.sync.id()
18+ }
19+
20+ const { subscribed } = api.channel.obs
21+ const myChannels = subscribed(id)
22+ return computed([myChannels], (v) => v.has(channel))
23+ }
24+}
translations/en.jsView
@@ -137,8 +137,15 @@
137137 subscribe: 'Subscribe',
138138 unsubscribe: 'Unsubscribe'
139139 }
140140 },
141+ subscriptions: {
142+ user: "My subscriptions",
143+ friends: "Friends subscriptions",
144+ state: {
145+ noSubscriptions: 'You have no subscriptions yet'
146+ }
147+ },
141148 languages: {
142149 en: 'English',
143150 zh: '中文'
144151 }

Built with git-ssb-web