Commit b54653fc52f7f7d05a4fc1e294bb6151561bff09
Merge pull request #98 from ticktackim/more_subscriptions
"more subscriptions" button, minor caching, "subscribe" buttonmix irving authored on 2/12/2018, 2:34:16 AM
GitHub committed on 2/12/2018, 2:34:16 AM
Parent: 6cedff7c896fdc49a0f8be9b4f479c7704797374
Parent: bf250c5c301cdcd83a84b88c89dd0d55db5fb8d7
Files changed
app/html/channelCard.js | changed |
app/page/channelShow.js | changed |
app/page/channelSubscriptions.js | changed |
app/page/channelSubscriptions.mcss | changed |
app/page/page.mcss | changed |
channel/index.js | changed |
channel/obs.js | changed |
channel/html/subscribe.js | added |
package.json | changed |
app/html/channelCard.js | ||
---|---|---|
@@ -1,43 +1,40 @@ | ||
1 | 1 | const nest = require('depnest') |
2 | 2 | const { h, when } = require('mutant') |
3 | 3 | |
4 | - | |
5 | 4 | exports.gives = nest('app.html.channelCard') |
6 | 5 | |
7 | 6 | exports.needs = nest({ |
8 | - 'keys.sync.id': 'first', | |
9 | - 'history.sync.push': 'first', | |
10 | - 'translations.sync.strings': 'first', | |
11 | - 'channel.obs.subscribed': 'first', | |
12 | - 'channel.async.subscribe': 'first', | |
13 | - 'channel.async.unsubscribe': 'first', | |
14 | - 'channel.obs.isSubscribedTo': 'first', | |
7 | + 'keys.sync.id': 'first', | |
8 | + 'history.sync.push': 'first', | |
9 | + 'translations.sync.strings': 'first', | |
10 | + 'channel.obs.subscribed': 'first', | |
11 | + 'channel.obs.isSubscribedTo': 'first', | |
12 | + 'channel.async.subscribe': 'first', | |
13 | + 'channel.async.unsubscribe': 'first', | |
14 | + 'channel.html.subscribe': 'first', | |
15 | 15 | }) |
16 | 16 | |
17 | 17 | exports.create = function (api) { |
18 | 18 | |
19 | - return nest('app.html.channelCard', (channel) => { | |
20 | - const strings = api.translations.sync.strings() | |
21 | - const myId = api.keys.sync.id() | |
22 | - const { subscribe, unsubscribe } = api.channel.async | |
23 | - const { isSubscribedTo } = api.channel.obs | |
24 | - const youSubscribe = isSubscribedTo(channel, myId) | |
25 | - | |
26 | - const goToChannel = () => { | |
27 | - api.history.sync.push({ page: 'channelShow', channel: channel }) | |
28 | - } | |
29 | - | |
30 | - return h('ChannelCard', [ | |
31 | - h('div.content', [ | |
32 | - h('div.text', [ | |
33 | - h('h2', {'ev-click': goToChannel}, channel), | |
34 | - when(youSubscribe, | |
35 | - h('Button', { 'ev-click': () => unsubscribe(channel) }, strings.channelShow.action.unsubscribe), | |
36 | - h('Button', { 'ev-click': () => subscribe(channel) }, strings.channelShow.action.subscribe) | |
37 | - ), | |
38 | - ]) | |
39 | - ]) | |
19 | + return nest('app.html.channelCard', (channel) => { | |
20 | + const strings = api.translations.sync.strings() | |
21 | + const myId = api.keys.sync.id() | |
22 | + const { subscribe, unsubscribe } = api.channel.async | |
23 | + const { isSubscribedTo } = api.channel.obs | |
24 | + const youSubscribe = isSubscribedTo(channel, myId) | |
25 | + | |
26 | + const goToChannel = () => { | |
27 | + api.history.sync.push({ page: 'channelShow', channel: channel }) | |
28 | + } | |
29 | + | |
30 | + return h('ChannelCard', [ | |
31 | + h('div.content', [ | |
32 | + h('div.text', [ | |
33 | + h('h2', {'ev-click': goToChannel}, channel), | |
34 | + api.channel.html.subscribe(channel) | |
40 | 35 | ]) |
41 | - }) | |
36 | + ]) | |
37 | + ]) | |
38 | + }) | |
42 | 39 | } |
43 | 40 |
app/page/channelShow.js | ||
---|---|---|
@@ -8,47 +8,31 @@ | ||
8 | 8 | 'app.html.sideNav': 'first', |
9 | 9 | 'app.html.topNav': 'first', |
10 | 10 | 'app.html.scroller': 'first', |
11 | 11 | 'app.html.blogCard': 'first', |
12 | - 'channel.obs.recent': 'first', | |
13 | 12 | 'feed.pull.channel': 'first', |
14 | 13 | 'history.sync.push': 'first', |
15 | - 'keys.sync.id': 'first', | |
16 | 14 | 'translations.sync.strings': 'first', |
17 | - 'channel.obs.subscribed': 'first', | |
18 | - 'channel.async.subscribe': 'first', | |
19 | - 'channel.async.unsubscribe': 'first', | |
20 | - 'channel.obs.isSubscribedTo': 'first' | |
15 | + 'channel.obs.recent': 'first', | |
16 | + 'channel.html.subscribe': 'first' | |
21 | 17 | }) |
22 | 18 | |
23 | 19 | exports.create = (api) => { |
24 | 20 | return nest('app.page.channelShow', channelShow) |
25 | 21 | |
26 | 22 | function channelShow(location) { |
27 | - | |
28 | 23 | var strings = api.translations.sync.strings() |
29 | - const myId = api.keys.sync.id() | |
30 | - const { subscribed } = api.channel.obs | |
31 | - const { subscribe, unsubscribe } = api.channel.async | |
32 | - const { isSubscribedTo } = api.channel.obs | |
33 | - const youSubscribe = isSubscribedTo(location.channel, myId) | |
34 | 24 | |
35 | 25 | var searchVal = resolve(location.channel) |
36 | 26 | |
37 | - | |
38 | - | |
39 | 27 | createStream = api.feed.pull.channel(location.channel) |
40 | - | |
41 | 28 | |
42 | 29 | const prepend = [ |
43 | 30 | api.app.html.topNav(location), |
44 | 31 | h('section.about', [ |
45 | 32 | h('h1', location.channel), |
46 | 33 | h('div.actions', [ |
47 | - when(youSubscribe, | |
48 | - h('Button', { 'ev-click': () => subscribe(location.channel) }, strings.channelShow.action.unsubscribe), | |
49 | - h('Button', { 'ev-click': () => unsubscribe(location.channel) }, strings.channelShow.action.subscribe) | |
50 | - ) | |
34 | + api.channel.html.subscribe(location.channel) | |
51 | 35 | ]) |
52 | 36 | ]), |
53 | 37 | ] |
54 | 38 |
app/page/channelSubscriptions.js | ||
---|---|---|
@@ -1,10 +1,10 @@ | ||
1 | 1 | const nest = require('depnest') |
2 | -const { h, when, Value, onceTrue, computed, map: mutantMap } = require('mutant') | |
2 | +const { h, when, Value, Array: MutantArray, onceTrue, computed, map: mutantMap } = require('mutant') | |
3 | 3 | const sortBy = require('lodash/sortBy') |
4 | -const map = require("lodash/map") | |
4 | +const map = require('lodash/map') | |
5 | +const difference = require('lodash/difference') | |
5 | 6 | |
6 | - | |
7 | 7 | exports.gives = nest('app.page.channelSubscriptions') |
8 | 8 | |
9 | 9 | exports.needs = nest({ |
10 | 10 | 'app.html.sideNav': 'first', |
@@ -22,68 +22,70 @@ | ||
22 | 22 | 'sbot.obs.connection': 'first' |
23 | 23 | }) |
24 | 24 | |
25 | 25 | exports.create = (api) => { |
26 | + const otherChannels = MutantArray () | |
27 | + | |
26 | 28 | return nest('app.page.channelSubscriptions', function (location) { |
27 | 29 | const strings = api.translations.sync.strings() |
28 | 30 | const myId = api.keys.sync.id() |
29 | - const { subscribed } = api.channel.obs | |
30 | - let myChannels, displaySubscriptions | |
31 | 31 | |
32 | + const rawSubs = api.channel.obs.subscribed(myId) | |
33 | + const mySubs = computed(rawSubs, myChannels => [...myChannels.values()].reverse() ) | |
34 | + | |
32 | 35 | if (location.scope === "user") { |
33 | - myChannels = subscribed(myId) | |
34 | - | |
35 | - const mySubscriptions = computed(myChannels, myChannels => [...myChannels.values()]) | |
36 | 36 | |
37 | 37 | return h('Page -channelSubscriptions', { title: strings.home }, [ |
38 | 38 | api.app.html.sideNav(location), |
39 | 39 | h('div.content', [ |
40 | - //api.app.html.topNav(location), | |
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) | |
40 | + when(rawSubs.sync, | |
41 | + [ | |
42 | + computed(mySubs, mys => mys.length === 0 ? strings.subscriptions.state.noSubscriptions : ''), | |
43 | + mutantMap(mySubs, api.app.html.channelCard), | |
44 | + ], | |
45 | + h('p', strings.loading) | |
49 | 46 | ) |
50 | 47 | ]) |
51 | 48 | ]) |
52 | - | |
53 | 49 | } |
54 | 50 | |
55 | 51 | if (location.scope === "friends") { |
56 | - | |
57 | - myChannels = Value(false) | |
58 | - | |
52 | + // update list of other all channels | |
59 | 53 | onceTrue( |
60 | 54 | api.sbot.obs.connection, |
61 | 55 | sbot => { |
62 | - sbot.channel.get((err, c) => { | |
56 | + sbot.channel.subscriptions((err, c) => { | |
63 | 57 | if (err) throw err |
64 | 58 | let b = map(c, (v,k) => {return {channel: k, users: v}}) |
65 | 59 | b = sortBy(b, o => o.users.length) |
66 | - let res = b.reverse().slice(0,100) | |
60 | + let res = b.reverse() | |
67 | 61 | |
68 | - myChannels.set(res.map(c => c.channel)) | |
62 | + otherChannels.set(res.map(c => c.channel)) | |
69 | 63 | }) |
70 | 64 | } |
71 | 65 | ) |
72 | 66 | |
67 | + const showMoreCounter = Value(1) | |
68 | + const newChannels = computed([otherChannels, mySubs, showMoreCounter], (other, mine, more) => { | |
69 | + return difference(other, mine) | |
70 | + .slice(0, 10*more) | |
71 | + }) | |
73 | 72 | |
74 | - return h('Page -channelSubscriptions', { title: strings.home }, [ | |
73 | + return h('Page -channelSubscriptions', { title: strings.home }, [ | |
75 | 74 | api.app.html.sideNav(location), |
76 | 75 | h('div.content', [ |
77 | - when(myChannels, | |
78 | - mutantMap(myChannels, api.app.html.channelCard), | |
79 | - h("p", strings.loading) | |
80 | - ) | |
76 | + when(otherChannels, | |
77 | + [ | |
78 | + mutantMap(newChannels, api.app.html.channelCard), | |
79 | + h('Button', { 'ev-click': () => showMoreCounter.set(showMoreCounter()+1) }, | |
80 | + strings.showMore | |
81 | + ) | |
82 | + ], | |
83 | + h('p', strings.loading) | |
84 | + ) | |
81 | 85 | ]) |
82 | 86 | ]) |
83 | 87 | } |
84 | 88 | }) |
85 | 89 | } |
86 | 90 | |
87 | 91 | |
88 | - | |
89 | - |
app/page/channelSubscriptions.mcss | ||
---|---|---|
@@ -8,13 +8,12 @@ | ||
8 | 8 | div.ChannelCard { |
9 | 9 | border-bottom: 1px solid rgba(0,0,0, .1) |
10 | 10 | } |
11 | 11 | |
12 | - div { | |
13 | - :last-child { | |
14 | - padding-bottom: 2rem !important | |
15 | - /* TODO fix - eww gross */ | |
16 | - } | |
12 | + div.Button { | |
13 | + max-width: 20rem | |
14 | + | |
15 | + margin: 2rem auto 12rem | |
17 | 16 | } |
18 | 17 | } |
19 | 18 | } |
20 | 19 |
app/page/page.mcss | ||
---|---|---|
@@ -22,9 +22,9 @@ | ||
22 | 22 | margin: 0 auto |
23 | 23 | |
24 | 24 | div, section { |
25 | 25 | :last-child { |
26 | - padding-bottom: 6rem !important | |
26 | + /* padding-bottom: 6rem !important */ | |
27 | 27 | } |
28 | 28 | } |
29 | 29 | } |
30 | 30 | } |
channel/index.js | ||
---|---|---|
@@ -1,6 +1,9 @@ | ||
1 | 1 | module.exports = { |
2 | 2 | async: require('./async'), |
3 | - obs: require('./obs') | |
3 | + obs: require('./obs'), | |
4 | + html: { | |
5 | + subscribe: require('./html/subscribe') | |
6 | + } | |
4 | 7 | } |
5 | 8 | |
6 | - | |
9 | + |
channel/obs.js | ||
---|---|---|
@@ -9,16 +9,30 @@ | ||
9 | 9 | |
10 | 10 | exports.gives = nest('channel.obs.isSubscribedTo') |
11 | 11 | |
12 | 12 | exports.create = function (api) { |
13 | + var subscriptions = {} | |
14 | + var myId | |
15 | + | |
13 | 16 | return nest('channel.obs.isSubscribedTo', isSubscribedTo) |
14 | 17 | |
15 | 18 | function isSubscribedTo (channel, id) { |
16 | 19 | if (!ref.isFeed(id)) { |
17 | - id = api.keys.sync.id() | |
20 | + id = getMyId() | |
18 | 21 | } |
19 | 22 | |
20 | - const { subscribed } = api.channel.obs | |
21 | - const myChannels = subscribed(id) | |
22 | - return computed([myChannels], (v) => v.has(channel)) | |
23 | + return computed(getSubscriptions(id), (v) => v.has(channel)) | |
23 | 24 | } |
25 | + | |
26 | + //cache getters | |
27 | + | |
28 | + function getMyId () { | |
29 | + if (!myId) myId = api.keys.sync.id() | |
30 | + return myId | |
31 | + } | |
32 | + | |
33 | + function getSubscriptions (id) { | |
34 | + if (!subscriptions[id]) subscriptions[id] = api.channel.obs.subscribed(id) | |
35 | + return subscriptions[id] | |
36 | + } | |
24 | 37 | } |
38 | + |
channel/html/subscribe.js | ||
---|---|---|
@@ -1,0 +1,27 @@ | ||
1 | +const nest = require('depnest') | |
2 | +const { h, when } = require('mutant') | |
3 | + | |
4 | +exports.gives = nest('channel.html.subscribe') | |
5 | + | |
6 | +exports.needs = nest({ | |
7 | + 'keys.sync.id': 'first', | |
8 | + 'translations.sync.strings': 'first', | |
9 | + 'channel.obs.isSubscribedTo': 'first', | |
10 | + 'channel.async.subscribe': 'first', | |
11 | + 'channel.async.unsubscribe': 'first', | |
12 | +}) | |
13 | + | |
14 | +exports.create = function (api) { | |
15 | + | |
16 | + return nest('channel.html.subscribe', (channel) => { | |
17 | + const strings = api.translations.sync.strings() | |
18 | + const myId = api.keys.sync.id() | |
19 | + const { subscribe, unsubscribe } = api.channel.async | |
20 | + | |
21 | + return when(api.channel.obs.isSubscribedTo(channel, myId), | |
22 | + h('Button', { 'ev-click': () => unsubscribe(channel) }, strings.channelShow.action.unsubscribe), | |
23 | + h('Button -primary', { 'ev-click': () => subscribe(channel) }, strings.channelShow.action.subscribe) | |
24 | + ) | |
25 | + }) | |
26 | +} | |
27 | + |
Built with git-ssb-web