git ssb

3+

ev / decent



Commit 02f1d746a759d2cd6c1df4f041d77781e6476103

fix pull-scroll in decent too

Ev Bogue committed on 4/13/2017, 9:06:03 PM
Parent: 44c55621a7eaeae2d584e97f32151bd6cc2b8225

Files changed

build/index.htmlchanged
client/modules/channel.jschanged
client/modules/feed.jschanged
client/modules/identify.jschanged
client/modules/key.jschanged
client/modules/notifications.jschanged
client/modules/private.jschanged
client/modules/profile-edit.jschanged
client/modules/public.jschanged
client/modules/search.jschanged
client/modules/thread.jschanged
client/pull-scroll/.npmignoreadded
client/pull-scroll/LICENSEadded
client/pull-scroll/README.mdadded
client/pull-scroll/examples/README.mdadded
client/pull-scroll/examples/columns.jsadded
client/pull-scroll/examples/simple.jsadded
client/pull-scroll/index.jsadded
client/pull-scroll/package.jsonadded
client/pull-scroll/utils.jsadded
build/index.htmlView
The diff is too large to show. Use a local git client to view these changes.
Old file size: 737351 bytes
New file size: 737402 bytes
client/modules/channel.jsView
@@ -1,8 +1,8 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
4 +var Scroller = require('../pull-scroll')
55 var mfr = require('map-filter-reduce')
66
77 exports.needs = {
88 message_render: 'first',
client/modules/feed.jsView
@@ -1,6 +1,6 @@
11 var ref = require('ssb-ref')
2-var Scroller = require('pull-scroll')
2 +var Scroller = require('../pull-scroll')
33 var h = require('hyperscript')
44 var pull = require('pull-stream')
55 var u = require('../util')
66
client/modules/identify.jsView
@@ -1,8 +1,8 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
4 +var Scroller = require('../pull-scroll')
55 var id = require('../keys').id
66
77 exports.needs = {
88 publish: 'first'
client/modules/key.jsView
@@ -1,8 +1,8 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
4 +var Scroller = require('../pull-scroll')
55
66 exports.gives = {
77 screen_view: true
88 }
client/modules/notifications.jsView
@@ -1,9 +1,9 @@
11 'use strict'
22 var h = require('hyperscript')
33 var u = require('../util')
44 var pull = require('pull-stream')
5-var Scroller = require('pull-scroll')
5 +var Scroller = require('../pull-scroll')
66 var paramap = require('pull-paramap')
77 var plugs = require('../plugs')
88 var cont = require('cont')
99 var ref = require('ssb-ref')
client/modules/private.jsView
@@ -1,9 +1,9 @@
11 'use strict'
22 var h = require('hyperscript')
33 var u = require('../util')
44 var pull = require('pull-stream')
5-var Scroller = require('pull-scroll')
5 +var Scroller = require('../pull-scroll')
66 var ref = require('ssb-ref')
77
88 function map(ary, iter) {
99 if(Array.isArray(ary)) return ary.map(iter)
client/modules/profile-edit.jsView
@@ -1,8 +1,8 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
4 +var Scroller = require('../pull-scroll')
55 var id = require('../keys').id
66
77 exports.needs = {
88 publish: 'first',
client/modules/public.jsView
@@ -1,8 +1,8 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
4 +var Scroller = require('../pull-scroll')
55
66 exports.needs = {
77 message_render: 'first',
88 message_compose: 'first',
client/modules/search.jsView
@@ -1,8 +1,8 @@
11 var h = require('hyperscript')
22 var u = require('../util')
33 var pull = require('pull-stream')
4-var Scroller = require('pull-scroll')
4 +var Scroller = require('../pull-scroll')
55 var TextNodeSearcher = require('text-node-searcher')
66
77 exports.needs = {
88 message_render: 'first',
client/modules/thread.jsView
@@ -3,9 +3,9 @@
33 var sort = require('ssb-sort')
44 var ref = require('ssb-ref')
55 var h = require('hyperscript')
66 var u = require('../util')
7-var Scroller = require('pull-scroll')
7 +var Scroller = require('../pull-scroll')
88 var self_id = require('../keys').id
99
1010 function once (cont) {
1111 var ended = false
client/pull-scroll/.npmignoreView
@@ -1,0 +1,1 @@
1 +node_modules
client/pull-scroll/LICENSEView
@@ -1,0 +1,22 @@
1 +Copyright (c) 2016 Dominic Tarr
2 +
3 +Permission is hereby granted, free of charge,
4 +to any person obtaining a copy of this software and
5 +associated documentation files (the "Software"), to
6 +deal in the Software without restriction, including
7 +without limitation the rights to use, copy, modify,
8 +merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom
10 +the Software is furnished to do so,
11 +subject to the following conditions:
12 +
13 +The above copyright notice and this permission notice
14 +shall be included in all copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
20 +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
client/pull-scroll/README.mdView
@@ -1,0 +1,93 @@
1 +# pull-scroll
2 +
3 +pull-stream to a infinite scrolling web pane.
4 +
5 +streams are for programatically dealing with data that
6 +arrives or is processed over time. Many applications
7 +also have features they call "streams", or views
8 +that may contain a large number of items,
9 +if you just keep scrolling down?
10 +
11 +pull-scroll is the simplest way to join these concepts,
12 +you can take a pull-stream of content, attach it to a
13 +scrolling element, and the scroller sets the back pressure.
14 +
15 +when the element is filled, back pressure kicks in,
16 +and when you scroll to the end, it is released, and more data flows in.
17 +
18 +pull-scroll can be used for both double and single ended content streams.
19 +
20 +## example
21 +
22 +``` js
23 +var Scroller = require('pull-scroll')
24 +var pull = require('pull-stream')
25 +var h = require('hyperscript')
26 +
27 +var content = h('div')
28 +var scroller = h('div', {
29 + style: {
30 + //must set overflow-y to scroll for this to work.
31 + 'overflow-y': 'scroll',
32 + //and cause this element to not stretch.
33 + //this can also be achived using flexbox column.
34 + position: 'fixed', bottom:'0px', top: '0px',
35 + width: '600px'
36 + }
37 + }, content)
38 +
39 + //provide a render function that returns an html element.
40 + function render (n) {
41 + return h('h1', n.toString())
42 + }
43 +
44 + pull(
45 + pull.infinite(),
46 + Scroller(scroller, content, render)
47 + )
48 +
49 +document.body.appendChild(scroller)
50 +```
51 +
52 +you can have attach two Scrollers to an element, one for scrolling up
53 +and one for scrolling down. (thus, a two way infinite scroller)
54 +
55 +see [example here](https://github.com/dominictarr/patchbay/blob/master/modules/public.js#L24-L32)
56 +
57 +## api
58 +
59 +### Scroller(scrollable, container, render, isPrepend, isSticky, cb) => Sink
60 +
61 +Create a pull-stream sink where the back pressure is controlled by the scrolling of the element.
62 +`scrollable` needs to be an element which can scroll, and `container`
63 +is an optional child (otherwise elements will be added directly to `scrollable`)
64 +
65 +`render` is a function that takes stream items and returns an html element.
66 +
67 +If `isPrepend` is true, elements will be added before the first child of container,
68 +if it is false, they will be appended.
69 +
70 +If `isSticky` is true, `scrollable` will be scrolled into position after adding an element.
71 +this will make more elements come automatically, untill you scroll away.
72 +If `isSticky` is false, new elements will extend the container, but not be scrolled into positon,
73 +this means the scroll will only be adjusted as the user scrolls.
74 +
75 +If the user is scrolling to read old data (i.e. scrolling down on twitter, or up in the terminal)
76 +then use `isSticky=false`. If the user is scrolled to the end to get new data,
77 +(i.e. scrolling to the top on twitter, or the bottom in the terminal)
78 +then use `isSticky=true`.
79 +
80 +`cb` is an optional callback used only for error handling.
81 +This defaults to
82 +```js
83 +function (err) { if(err) console.error(err) }
84 +```
85 +
86 +## License
87 +
88 +MIT
89 +
90 +
91 +
92 +
93 +
client/pull-scroll/examples/README.mdView
@@ -1,0 +1,19 @@
1 +
2 +# run examples in electron
3 +
4 +```
5 +npm install electron-prebuilt electro -g
6 +electro examples/simple.js
7 +```
8 +[electro](https://github.com/dominictarr/electro) is my electron wrapper
9 +that lets you just run a single js file and pipe to it via stdio.
10 +
11 +
12 +# run examples in a browser via browserify
13 +
14 +```
15 +npm install browserify indexhtmlify -g
16 +
17 +browserify examples/simple.js | indexhtmlify > index.html
18 +```
19 +then open that in your prefured web browser!
client/pull-scroll/examples/columns.jsView
@@ -1,0 +1,85 @@
1 +var h = require('hyperscript')
2 +var o = require('observable')
3 +var pull = require('pull-stream')
4 +var Pause = require('pull-pause')
5 +
6 +var Scroller = require('../')
7 +
8 +var c = o.value()
9 +var v = o.value()
10 +
11 +var check = h('input', {type: 'checkbox'})
12 +var sticky = o.input(check, 'checked')
13 +var panel
14 +document.body.appendChild(
15 + panel = h('div.screen', {
16 + style: {
17 + top: '0px', bottom: '0px',
18 + position: 'absolute',
19 + display: 'flex',
20 + 'flex-direction': 'row'
21 + }
22 + },
23 + h('div', {style: {position: 'fixed', right: '20px', top: '20px'}},
24 + c, '-', v, check,
25 + h('a', 'Create!', {href: '#', onclick: function () {
26 + panel.appendChild(createScroller())
27 + }})
28 + )
29 + )
30 +)
31 +
32 +//load below the screen bottom, so that normal reading is jankless.
33 +
34 +//user provided source stream
35 +function createSource (top) {
36 + return pull(
37 + pull.infinite(),
38 + pull.map(function (e) {
39 + c((c()||0)+1)
40 + return {random: e, count: c(), top: top}
41 + }),
42 + pull.asyncMap(function (e, cb) {
43 + var delay = 100 + 200*Math.random()
44 + setTimeout(function () {
45 + e.delay = delay
46 + cb(null, e)
47 + }, delay)
48 + })
49 + )
50 +}
51 +
52 +function render (e) {
53 + return h('h3', {
54 + style: {background: 'hsl('+Math.round(Math.random()*360) + ',100%,50%)'
55 + }
56 + }, h('pre', JSON.stringify(e, null, 2)))
57 +}
58 +
59 +function createScroller () {
60 + var scroller = SCROLLER = h('ol', {
61 + style: {
62 + 'flex-bias': 0,
63 + overflowY: 'scroll',
64 + overflow: 'auto',
65 + display: 'inline-block'
66 + }
67 + })
68 +
69 + pull(
70 + createSource(true),
71 + Scroller(scroller, render, true, false)
72 + )
73 +
74 + pull(
75 + createSource(false),
76 + Scroller(scroller, render, false, false)
77 + )
78 +
79 + return h('div', {style: {
80 + display: 'flex', 'flex-bias': 0,
81 + 'flex-direction': 'column'
82 + }}, h('h1', 'scroller') , scroller)
83 +}
84 +
85 +
client/pull-scroll/examples/simple.jsView
@@ -1,0 +1,37 @@
1 +var Scroller = require('../')
2 +var pull = require('pull-stream')
3 +var h = require('hyperscript')
4 +
5 +var content = h('div')
6 +var scroller = h('div', {
7 + style: {
8 + //must set overflow-y to scroll for this to work.
9 + 'overflow-y': 'scroll',
10 + //and cause this element to not stretch.
11 + //this can also be achived using flexbox column.
12 + position: 'fixed', bottom:'0px', top: '0px',
13 + 'margin-left': 'auto',
14 + 'margin-right': 'auto',
15 + width: '600px'
16 + }
17 + }, content)
18 +
19 + //provide a render function that returns an html element.
20 + function render (n) {
21 + return h('h1', n.toString())
22 + }
23 +
24 + pull(
25 + pull.infinite(),
26 + Scroller(scroller, content, render)
27 + )
28 +
29 +document.body.appendChild(scroller)
30 +
31 +
32 +
33 +
34 +
35 +
36 +
37 +
client/pull-scroll/index.jsView
@@ -1,0 +1,100 @@
1 +var pull = require('pull-stream')
2 +var Pause = require('pull-pause')
3 +
4 +var next = 'undefined' === typeof setImmediate ? setTimeout : setImmediate
5 +var buffer = Math.max(window.innerHeight * 2, 1000)
6 +
7 +var u = require('./utils'),
8 + assertScrollable = u.assertScrollable,
9 + isEnd = u.isEnd,
10 + isFilled = u.isFilled,
11 + isVisible = u.isVisible,
12 + isScroll = u.isScroll
13 +
14 +module.exports = Scroller
15 +
16 +function Scroller(scroller, content, render, isPrepend, isSticky, cb) {
17 + assertScrollable(scroller)
18 +
19 + //if second argument is a function,
20 + //it means the scroller and content elements are the same.
21 + if('function' === typeof content) {
22 + cb = isSticky
23 + isPrepend = render
24 + render = content
25 + content = scroller
26 + }
27 +
28 + if(!cb) cb = function (err) { if(err) throw err }
29 +
30 + scroller.addEventListener('scroll', scroll)
31 + var pause = Pause(function () {})
32 + var queue = []
33 +
34 + //apply some changes to the dom, but ensure that
35 + //`element` is at the same place on screen afterwards.
36 +
37 + function add () {
38 + if(queue.length) {
39 + var m = queue.shift()
40 + var r = render(m)
41 + append(scroller, content, r, isPrepend, isSticky)
42 + }
43 + }
44 +
45 + function scroll (ev) {
46 + if(isEnd(scroller, buffer, isPrepend) || !isFilled(content)) {
47 + pause.resume()
48 + add()
49 + }
50 + }
51 +
52 + pause.pause()
53 +
54 + //wait until the scroller has been added to the document
55 + next(function next () {
56 + if(scroller.parentElement) pause.resume()
57 + else setTimeout(next, 100)
58 + })
59 +
60 + var stream = pull(
61 + pause,
62 + pull.drain(function (e) {
63 + queue.push(e)
64 + //we don't know the scroll bar positions if it's display none
65 + //so we have to wait until it becomes visible again.
66 + if(!isVisible(content)) {
67 + if(content.children.length < 15) add()
68 + }
69 + else if(!isScroll(scroller)) add()
70 + else if(isEnd(scroller, buffer, isPrepend)) add()
71 +
72 + if(queue.length > 5) pause.pause()
73 + }, function (err) {
74 + if(err) console.error(err)
75 + cb ? cb(err) : console.error(err)
76 + })
77 + )
78 +
79 + stream.visible = add
80 + return stream
81 +}
82 +
83 +
84 +function append(scroller, list, el, isPrepend, isSticky) {
85 + if(!el) return
86 + var s = scroller.scrollHeight
87 + if(isPrepend && list.firstChild)
88 + list.insertBefore(el, list.firstChild)
89 + else
90 + list.appendChild(el)
91 +
92 + //scroll down by the height of the thing added.
93 + //if it added to the top (in non-sticky mode)
94 + //or added it to the bottom (in sticky mode)
95 + if(isPrepend !== isSticky) {
96 + var d = (scroller.scrollHeight - s) + 1
97 + scroller.scrollTop = scroller.scrollTop + d
98 + }
99 +}
100 +
client/pull-scroll/package.jsonView
@@ -1,0 +1,23 @@
1 +{
2 + "name": "pull-scroll",
3 + "description": "",
4 + "version": "0.3.4",
5 + "homepage": "https://github.com/dominictarr/pull-scroll",
6 + "repository": {
7 + "type": "git",
8 + "url": "git://github.com/dominictarr/pull-scroll.git"
9 + },
10 + "dependencies": {
11 + "pull-pause": "0.0.0",
12 + "pull-stream": "^3.0.1"
13 + },
14 + "devDependencies": {
15 + "hyperscript": "^2.0.2",
16 + "observable": "^2.1.4"
17 + },
18 + "scripts": {
19 + "test": "set -e; for t in test/*.js; do node $t; done"
20 + },
21 + "author": "Dominic Tarr <dominic.tarr@gmail.com> (http://dominictarr.com)",
22 + "license": "MIT"
23 +}
client/pull-scroll/utils.jsView
@@ -1,0 +1,66 @@
1 +
2 +function assertScrollable(scroller) {
3 + var f = overflow(scroller)
4 + if(!/auto|scroll/.test(f))
5 + throw new Error('scroller.style.overflowY must be scroll or auto, was:' + f + '!')
6 +}
7 +
8 +function isEnd(scroller, buffer, isPrepend) {
9 + //if the element is display none, don't read anything into it.
10 + return (isPrepend ? isTop : isBottom)(scroller, buffer)
11 +}
12 +
13 +function isFilled(content) {
14 + return (
15 + !isVisible(content)
16 + //check if the scroller is not visible.
17 + // && content.getBoundingClientRect().height == 0
18 + //and has children. if there are no children,
19 + //it might be size zero because it hasn't started yet.
20 + && content.children.length > 10
21 + //&& !isVisible(scroller)
22 + )
23 +}
24 +
25 +function isVisible (el) {
26 + var style = getComputedStyle(el)
27 + return style.display === 'none' || style.visibility === 'hidden'
28 +}
29 +
30 +//test wether element has an active scroll bar.
31 +//(element needs to be visible for this to work)
32 +
33 +function isScroll (el) {
34 + return el.scrollHeight != el.clientHeight
35 +}
36 +
37 +
38 +module.exports = {
39 + assertScrollable: assertScrollable,
40 + isEnd: isEnd,
41 + isFilled: isFilled,
42 + isVisible: isVisible,
43 + isScroll: isScroll
44 +}
45 +
46 +
47 +// 'private' functions
48 +
49 +function overflow (el) {
50 + return el.style.overflowY || el.style.overflow || (function () {
51 + var style = getComputedStyle(el)
52 + return style.overflowY || el.style.overflow
53 + })()
54 +}
55 +
56 +function isTop (scroller, buffer) {
57 + return scroller.scrollTop <= (buffer || 0)
58 +}
59 +
60 +function isBottom (scroller, buffer) {
61 + var rect = scroller.getBoundingClientRect()
62 + var topmax = scroller.scrollTopMax || (scroller.scrollHeight - rect.height)
63 + return scroller.scrollTop >=
64 + + ((topmax) - (buffer || 0))
65 +}
66 +

Built with git-ssb-web