git ssb

2+

mixmix / ticktack



Commit bece765b487127c47d7cd4da71eb2574d7218dde

get channel pages working!

Dominic Tarr committed on 8/14/2017, 5:19:15 AM
Parent: 1edfe7452d88b203db8a281861c9a4c05a70610e

Files changed

app/index.jschanged
app/page/home.jschanged
app/page/channel.jsadded
router/sync/routes.jschanged
state/obs.jschanged
app/index.jsView
@@ -9,8 +9,10 @@
99 threadCard: require('./html/thread-card')
1010 },
1111 page: {
1212 group: require('./page/group'),
13+ channel: require('./page/channel'),
1314 home: require('./page/home'),
1415 private: require('./page/private')
1516 }
1617 }
18+
app/page/home.jsView
@@ -111,27 +111,19 @@
111111 h('div.container', [
112112 //private section
113113 h('section.updates -directMessage', [
114114 h('div.threads',
115-// Object.keys(threads.roots)
116-// .map(function (id) {
117-// return threads.roots[id]
118-// })
119-// .filter(function (thread) {
120-// return filter(location.filter, thread)
121-// })
122115 groupedThreads
123116 .map(function (thread) {
124117 var el = api.app.html
125118 .threadCard(thread, opts)
126-//DISABLE: rethinking pages
127-// if(!location.filter && el)
128-// el.onclick = function () {
129-// if(!filterForThread(thread))
130-// api.history.sync.push({key: thread.key})
131-// else
132-// api.history.sync.push({page: 'home', filter: filterForThread(thread)})
133-// }
119+ if(thread.value.content.channel) {
120+ el.onclick = function (ev) {
121+ console.log('THTREAD CHANNEL', thread.value.content.channel)
122+ api.history.sync.push({channel: thread.value.content.channel})
123+ ev.preventDefault()
124+ }
125+ }
134126 return el
135127 })
136128 )
137129 ]),
@@ -149,14 +141,4 @@
149141 ])
150142 })
151143 }
152144
153-
154-
155-
156-
157-
158-
159-
160-
161-
162-
app/page/channel.jsView
@@ -1,0 +1,140 @@
1+const nest = require('depnest')
2+const { h, computed } = require('mutant')
3+const {threadReduce} = require('ssb-reduce-stream')
4+const pull = require('pull-stream')
5+const isObject = require('lodash/isObject')
6+const isString = require('lodash/isString')
7+const last = require('lodash/last')
8+const get = require('lodash/get')
9+const More = require('hypermore')
10+const morphdom = require('morphdom')
11+const Debounce = require('obv-debounce')
12+const PullObv = require('pull-obv')
13+
14+exports.gives = nest('app.page.channel')
15+
16+exports.needs = nest({
17+ 'app.html.nav': 'first',
18+ 'history.sync.push': 'first',
19+ 'keys.sync.id': 'first',
20+ 'translations.sync.strings': 'first',
21+ 'state.obs.threads': 'first',
22+ 'app.html.threadCard': 'first',
23+ 'feed.pull.channel': 'first'
24+})
25+
26+function toRecpGroup(msg) {
27+ //cannocialize
28+ return Array.isArray(msg.value.content.repcs) &&
29+ msg.value.content.recps.map(function (e) {
30+ return (isString(e) ? e : e.link)
31+ }).sort().map(function (id) {
32+ return id.substring(0, 10)
33+ }).join(',')
34+}
35+
36+exports.create = (api) => {
37+ return nest('app.page.channel', function (location) {
38+ // location here can expected to be: { page: 'home' }
39+ var strings = api.translations.sync.strings()
40+
41+ var container = h('div.container', [])
42+
43+ function filterForThread (thread) {
44+ if(thread.value.private)
45+ return {private: toRecpGroup(thread)}
46+ else if(thread.value.content.channel)
47+ return {channel: thread.value.content.channel}
48+ }
49+
50+ function filter (rule, thread) {
51+ if(!thread.value) return false
52+ if(!rule) return true
53+ if(rule.channel) {
54+ return rule.channel == thread.value.content.channel
55+ }
56+ else if(rule.group)
57+ return rule.group == thread.value.content.group
58+ else if(rule.private)
59+ return rule.private == toRecpGroup(thread)
60+ else return true
61+ }
62+
63+ var morePlease = false
64+ var threadsObs = api.state.obs.threads()
65+
66+ var createChannelStream = api.feed.pull.channel(location.channel)
67+
68+ var channelObs = PullObv(
69+ threadReduce,
70+ createChannelStream({reverse: true, limit: 1000})
71+ )
72+
73+// // DUCT TAPE: debounce the observable so it doesn't
74+// // update the dom more than 1/second
75+// threadsObs(function () {
76+// if(morePlease) threadsObs.more()
77+// })
78+// threadsObsDebounced = Debounce(threadsObs, 1000)
79+// threadsObsDebounced(function () {
80+// morePlease = false
81+// })
82+// threadsObsDebounced.more = function () {
83+// morePlease = true
84+// requestIdleCallback(threadsObs.more)
85+// }
86+
87+ var threadsHtmlObs = More(
88+// threadsObsDebounced,
89+ channelObs,
90+ function render (threads) {
91+
92+ var sorted = Object.keys(threads.roots)
93+ .map(function (id) {
94+ return threads.roots[id]
95+ })
96+ .sort(function (a, b) {
97+ return latestUpdate(b) - latestUpdate(a)
98+ })
99+
100+
101+ function latestUpdate(thread) {
102+ var m = thread.timestamp
103+ if(!thread.replies) return m
104+
105+ for(var i = 0; i < thread.replies.length; i++)
106+ m = Math.max(thread.replies[i].timestamp, m)
107+ return m
108+ }
109+
110+ morphdom(container,
111+ // LEGACY: some of these containers could be removed
112+ // but they are here to be compatible with the old MCSS.
113+ h('div.container', [
114+ //private section
115+ h('section.updates -directMessage', [
116+ h('div.threads',
117+ sorted
118+ .map(function (thread) {
119+ var el = api.app.html
120+ .threadCard(thread, opts)
121+ return el
122+ })
123+ )
124+ ]),
125+ ])
126+ )
127+ return container
128+ }
129+ )
130+
131+ return h('Page -home', [
132+ h('h1', location.channel),
133+ api.app.html.nav(),
134+ threadsHtmlObs,
135+ h('button', {'ev-click': threadsHtmlObs.more}, [strings.showMore])
136+ ])
137+ })
138+}
139+
140+
router/sync/routes.jsView
@@ -4,8 +4,9 @@
44
55 exports.needs = nest({
66 'app.page.home': 'first',
77 'app.page.group': 'first',
8+ 'app.page.channel': 'first',
89 'app.page.private': 'first'
910 })
1011
1112 exports.create = (api) => {
@@ -15,9 +16,9 @@
1516
1617 const routes = [
1718 [ location => location.page === 'home', pages.home ],
1819 [ location => location.type === 'group', pages.group ],
19- [ location => location.page === 'channel', pages.channel ],
20+ [ location => location.channel , pages.channel ],
2021 [ location => ref.isMsg(location.key), pages.private ]
2122 ]
2223
2324 return [...routes, ...sofar]
@@ -32,4 +33,5 @@
3233
3334
3435
3536
37+
state/obs.jsView
@@ -1,8 +1,8 @@
11 var PullObv = require('pull-obv')
22 var threadReduce = require('ssb-reduce-stream')
33 var pull = require('pull-stream')
4-const Next = require('pull-next')
4+var Next = require('pull-next')
55
66 var nest = require('depnest')
77
88 function isObject (o) {
@@ -10,12 +10,8 @@
1010 }
1111
1212 exports.gives = nest('state.obs.threads', true)
1313
14-//{
15-// state: {obs: {threads: true}}
16-//}
17-
1814 exports.needs = nest({
1915 'message.sync.unbox': 'first',
2016 'sbot.pull.log': 'first'
2117 })
@@ -67,29 +63,33 @@
6763 var timer
6864 //keep localStorage up to date
6965 threadsObs(function (threadsState) {
7066 if(timer) return
71- clearTimeout(timer)
7267 timer = setTimeout(function () {
7368 timer = null
7469 threadsState.last = lastTimestamp
70+ console.log('save state')
7571 localStorage.threadsState = JSON.stringify(threadsState)
7672 }, 1000)
7773 })
7874
7975 //stream live messages. this *should* work.
8076 //there is no back pressure on new events
8177 //only a show more on the top (currently)
8278
83- pull(
84- Next(function () {
85- return api.sbot.pull.log({reverse: true, limit: 500, gte: firstTimestamp})
86- }),
87- pull.drain(function (data) {
88- firstTimestamp = data.timestamp
89- threadsObs.set(threadReduce(threadsObs.value, data))
90- })
91- )
79+// pull(
80+// Next(function () {
81+// return api.sbot.pull.log({limit: 500, gte: firstTimestamp, live: true})
82+// }),
83+// pull.drain(function (data) {
84+// if(data.sync) return
85+// firstTimestamp = data.timestamp
86+// console.log("SET", data.timestamp, firstTimestamp)
87+// threadsObs.set(threadReduce(threadsObs.value, data))
88+// })
89+// )
90+
9291 return threadsObs
9392 })
9493 }
9594
95+

Built with git-ssb-web