Commit graph

136 commits

Author SHA1 Message Date
Bruno Windels
c920dd2e8a check top of node instead of bottom, since coming in from last
as we're approaching from the last node, if we're scrolled up,
the first node we encounter would be below the bottom of the viewport

change the logic to stop at the first node that has its top
above the viewport bottom.

When completely scrolled up, this was causing nodes way below
the viewport to be selected as the reference for the pixelOffset,
and when pagination came in, it would immediately try to apply
the big negative pixelOffset, scrolling to a negative scrollTop,
thus going to the top again, and triggering another pagination,
entering in an infinite pagination loop until you scrolled down.
2019-02-26 16:26:24 +01:00
Bruno Windels
ba5f16358f fall back to InteractionObserver for detecting timeline resizes
this is not nearly as smooth as using ResizeObserver, as the
callback rate is a lot lower, but seems to be quite a bit better
than what we have right now, without the 7% cpu hog that
the requestAnimationFrame polling fallback has.
2019-02-26 10:49:03 +01:00
Bruno Windels
3823642863 some cleanup 2019-02-26 10:49:03 +01:00
Bruno Windels
41ae618d0e only clear min-height on scroll & adding items (componentDidUpdate)
before we would clear it as soon as you were 1px away from
the bottom of the timeline, which would still create jumping as
the whitespace would around 36px. To play it safe, we only clear it
after moving 200px from the bottom.

Also include "local echo" scroll events, caused by setting scrollTop
2019-02-26 10:49:03 +01:00
Bruno Windels
03784e586c replace getBoundingClientRect() with offset/scrollTop & clientHeight
as they are an order of magnitude faster in most browsers,
getBoundingClientRect() tends to cause relayout.
2019-02-26 10:49:03 +01:00
Bruno Windels
ecb074862e remove fix for old chrome bug 2019-02-26 10:49:03 +01:00
Bruno Windels
b3e6cbfddd restore scroll state when timeline resizes using ResizeObserver
(only where supported, polyfill doesn't give good results)
2019-02-26 10:49:03 +01:00
Bruno Windels
9e260ad96b make sure we're at the bottom, although that seems to always be the case in this branch? 2019-02-14 16:19:58 +01:00
Bruno Windels
790e752b7a clear min-height on scroll 2019-02-14 16:11:38 +01:00
Bruno Windels
3d393b654b clear min-height on ScrollPanel::componentDidUpdate to catch all cases 2019-02-04 18:27:22 +00:00
Bruno Windels
5d45d5dfac formatting 2019-01-22 11:37:09 +01:00
Bruno Windels
018f3d2a5c use box-sizing: border-box to make clientHeight === actual height 2019-01-21 17:30:02 +01:00
Bruno Windels
c9d5c4903b set min-height of messagelist to current height when showing typing bar
this ensures the timeline never shrinks, and avoids jumpiness when
typing bar disappears again.
2019-01-18 18:53:54 +01:00
Luke Barnard
39e9d52c04 Make sure to proxy special prop ref 2018-03-27 13:04:26 +01:00
Luke Barnard
b80568b1c5 Wrap GeminiScrollbar in a component, enabled forceGemini
Fixes https://github.com/vector-im/riot-web/issues/6294
2018-03-27 13:04:26 +01:00
Aidan Gauland
35780f5ae0 Remove use of deprecated React.PropTypes
Replace all uses of React.PropTypes with PropTypes and importing PropTypes from
'prop-types'.
2017-12-26 14:03:18 +13:00
Luke Barnard
ddd0e161c0 Fix broken imports 2017-12-01 10:41:56 +00:00
Luke Barnard
dad797d4a2 Run linting --fix 2017-11-16 13:19:36 +00:00
Luke Barnard
77418f535e Modify GroupView UI
- Remove featured users/rooms
 - Add "Rooms" section to show all rooms in the group in a room-directory-esque list. This has a "+" button in "edit" mode.
 - Make the group view body scrollable
2017-10-13 16:46:33 +01:00
Luke Barnard
d3f9a3aeb5 Run eslint --fix
Fixing 1000s of lint issues. Some rules cannot be `--fix`ed but this goes some way to linting the entire codebase.
2017-10-11 17:56:17 +01:00
David Baker
78a2e49705 Don't always paginate when mounting a ScrollPanel
Calling just checkFill on DidMount did not initially set the
scrollTop which meant that one back pagination request is always
performed regardless. This meant we would end up rending the
first batch of events, then paginating and re-rendering again
after the pagination got another batch, causing unnecessary render
churn.
2017-09-08 15:41:19 +01:00
David Baker
609d61d53c Revert "Implement sticky date separators" 2017-09-06 17:40:58 +01:00
Luke Barnard
c9c0771355 Spelling 2017-08-31 16:29:45 +01:00
Luke Barnard
cdb28f956e Add comment for StickyContainer extension 2017-08-31 16:29:31 +01:00
Luke Barnard
d516906b36 Implement sticky date separators
Use `react-sticky` to implement sticky date separators. This will pin a date separator to the top of the timeline panel when the separator scrolls out of the top of the view.

A known issue of this is that the spinner, which is in line with event tiles in the timeline, will appear to push the stuck date separator down. In reality the first date separator after the spinner is in line with event tiles and is not stuck because the spinner forces the timeline to be scrolled slightly further down than it would be otherwise. But also, date separators in the timeline (not "stuck") have a greater height.

Ideally the date separator would be suppressed whilst back paginating, but this will cause the stuck separator to flicker on and off. This is why the suppression has been removed.
2017-08-30 13:52:46 +01:00
Richard van der Hoff
33f330d434 Manual fixup for remaining q incantaions
* don't try to use `finally` as a static method
* work around absence of `allSettled`
2017-07-12 18:05:40 +01:00
Richard van der Hoff
0254d2b3a2 q(...) -> Promise.resolve
```
find src test -name '*.js' | xargs perl -i -pe 's/\b[qQ]\(/Promise.resolve(/'
```
2017-07-12 18:05:08 +01:00
Richard van der Hoff
a06bd84213 replace imports of q with bluebird
update `package.json`

```
find src test -name '*.js' |
   xargs perl -i -pe 'if (/require\(.[qQ].\)/) { $_ = "import Promise from '\''bluebird'\'';\n"; }'

find src test -name '*.js' |
   xargs perl -i -pe 'if (/import [qQ]/) { $_ = "import Promise from '\''bluebird'\'';\n"; }'
```
2017-07-12 18:05:08 +01:00
Luke Barnard
57f01b83be Revert "Save scroll state immediately before updating"
This reverts commit 4124a8dcff from PR https://github.com/matrix-org/matrix-react-sdk/pull/1076
2017-06-19 13:19:17 +01:00
Luke Barnard
513a585a3e Merge pull request #1076 from ollieh/issues/reduce-save-restore-window
Reduce save-restore window in ScrollPanel to reduce scrolling jumps
2017-06-19 11:23:10 +01:00
Oliver Hunt
4124a8dcff Save scroll state immediately before updating
Signed-off-by: Oliver Hunt <oliver@hunt.bz>
2017-06-12 06:19:12 +01:00
Oliver Hunt
3d59d72aaa Fixed pagination infinite loop caused by long messages
Signed-off-by: Oliver Hunt <oliver@hunt.bz>
2017-06-07 04:49:41 +01:00
Luke Barnard
6d9a1f047d Typo 2017-05-04 13:03:04 +01:00
Luke Barnard
bfa3123f9b Combine data-scroll-token and -contained-scroll-tokens
- Instead of using one attribute, use one that might just contain one token
 - Use the first token when tracking a child
 - Mandate that no commas can be in individual tokens
2017-05-04 10:00:13 +01:00
Luke Barnard
4febc63aee Add comment to _scrollToToken 2017-05-02 17:41:09 +01:00
Luke Barnard
fe83a99ab7 Update ScrollPanel docs 2017-05-02 17:36:59 +01:00
Luke Barnard
3f25928380 Fix jumping to an unread event when in MELS
This adds the `data-contained-scroll-tokens` API to elements in `ScrollPanel` which allows arbitrary containers of elements with scroll tokens to declare their contained scroll tokens. When jumping to a scroll token inside a container, the `ScrollPanel` will act as if it is scrolling to the container itself, not the child.

MELS has been modified such that it exposes the scroll tokens of all events that exist within it.This means "Jump to unread message" will work if the unread event is within a MELS (which is any member event, because even individual member events surrounded by other events are put inside a MELS).
2017-05-02 16:34:39 +01:00
Matthew Hodgson
fa033e6116 limit our keyboard shortcut modifiers correctly
fixes https://github.com/vector-im/riot-web/issues/3614
2017-04-23 00:49:14 +01:00
Luke Barnard
d218f90cde Fix infinite pagination/glitches with pagination
I think this was being caused by a bug introduced in 47f29b that meant that `backwards` was actually being used as `forwards`.
2017-04-07 11:34:31 +01:00
Luke Barnard
423babdb17 Remove fairly redundant condition
Making sure that a node is intersected by the bottom of the wrapper is a bit overkill, given that we iterate from the bottom. This also prevents the scenario of having no nodes that are not precisely intersected, but possibly straddling the bottom of the wrapper.
2017-04-05 17:51:07 +01:00
Luke Barnard
47f29b9454 Simplify simulated unfill 2017-04-05 17:48:24 +01:00
Luke Barnard
5737994957 Clarify and simplfiy unpagination logic 2017-04-04 13:28:26 +01:00
Luke Barnard
94fe9999db Reimplement _saveScrollState
The actual fix to https://github.com/vector-im/riot-web/issues/3175 is this change to `_saveScrollState`, which is to pick the trackedScrollToken based on which node is intersected by the bottom of the scroll panel. This is opposed to the previous logic that picked based on which node was the first from the bottom to be above the bottom of the viewport.

In the case where the viewport bottom does not intersect any events, the topmost event is used.
2017-04-04 11:55:53 +01:00
Luke Barnard
d8a30aa848 Double UNPAGINATION_PADDING again 2017-03-13 13:48:15 +00:00
Matthew Hodgson
2cf24c17e2 double scrollback window on roomview 2017-02-02 18:27:21 +00:00
Richard van der Hoff
cd1cf09dc9 Make tests pass on Chrome again
It seems that a number of the tests had started failing when run in
Chrome. They were fine under PhantomJS, but the MegolmExport tests only work
under Chrome, and I need them to work...

Mostly the problems were timing-related, where assumptions made about how
quickly the `then` handler on a promise would be called were no longer
valid. Possibly Chrome 55 has made some changes to the relative priorities of
setTimeout and sendMessage calls.

One of the TimelinePanel tests was failing because it was expecting the contents
of a div to take up more room than they actually were. It's possible this is
something very environment-specific; hopefully the new value will work on a
wider range of machines.

Also some logging tweaks.
2017-01-31 22:40:53 +00:00
David Baker
18d4d3392a Fix a bunch of linting errors
eslint --fix and a few manual ones
2017-01-20 14:22:27 +00:00
David Baker
9e3c94edf4 Fix exception when clearing room dir search
Needed more isMounted checks after promises return.
2016-12-06 14:59:10 +00:00
Luke Barnard
42fc7b1b66 Use UNFILL_REQUEST_DEBOUNCE_MS constant, reset unfillDebouncer timeout reference. 2016-11-22 17:23:06 +00:00
Luke Barnard
d1a5d94916 Make the unpagination process less aggressive
This increases `UNPAGINATION_PADDING` (see the ASCII on ScrollPanel.js, `_getExcessHeight`), and also debounces unfilling requests made for 200ms. This forces unfilling requests not to be sent unless the next 200ms has no scrolling, effectively.
2016-11-22 16:47:56 +00:00
Luke Barnard
b718f1542c Fix infinite loop when there are a lot of invisible events (#554)
Instead of using a window of a fixed number of events, unpaginate based on the distance of the viewport from the end of the scroll range.

The ScrollPanel uses the scrollTokens to convey to its parent (the TimelinePanel, in this case) the point to unpaginate up to. The TimelinePanel then takes a chunk of events off the front or back of `this.state.events` using `timelineWindow.unpaginate`.

Fixes https://github.com/vector-im/vector-web/issues/2020
2016-11-16 14:25:52 +00:00
David Baker
d0fd6e985f Document paranoia on the startAtBottom param 2016-09-16 17:48:08 +01:00
David Baker
806ef11fde Add 'startAtBottom' flag
Controls whether a scrollPanel starts off at the bottom.

This may not be necessary and could either be derived from stickyBottom, but
this means I can be sure that the behaviour of ScrollPanel is completely
unchanged for all other uses to avoid breaking any other uses of
ScrollPanel.
2016-09-16 17:18:58 +01:00
Richard van der Hoff
c8df9148b3 Remove relayoutOnUpdate prop on gemini-scrollbar
The latest gemini-scrollbar makes relayoutOnUpdate redundant, so update to it
and remove the properties.
2016-07-27 11:35:48 +01:00
Matthew Hodgson
7879be1704 implement basic local echo for resetting unread message count when opening a room without a scroll offset. hopefully largely fixes https://github.com/vector-im/vector-web/issues/967 2016-05-17 20:28:11 +01:00
Richard van der Hoff
d953ac4e6b Don't relayout scrollpanels every time something changes
Gemini's habit of reflowing everything everytime anything changes at all makes
for an unresponsive app. Turn it off everywhere we use gemini.
2016-04-20 12:25:19 +01:00
Richard van der Hoff
8b8ee21765 Catch pageup/down and ctrl-home/end at the top level
Make the scroll keys work when the focus is outside the message panel.
2016-04-05 13:40:36 +01:00
Richard van der Hoff
51fe77122b Fix an issue where the scroll stopped working.
Under certain conditions, it was possible to get stuck in a state where any
user-initiated scroll would be met with "Working around
vector-im/vector-web#528" and overridden. Fix this by removing the duplication
between _lastSetScroll and recentEventScroll, and using _lastSetScroll which is
more reliable.
2016-04-05 10:41:32 +01:00
Matthew Hodgson
5bd0303dda make it work, seemingly 2016-03-24 01:12:51 +00:00
Matthew Hodgson
151a9994ba WIP fix for image load popping 2016-03-24 00:13:32 +00:00
Richard van der Hoff
9f05249d9c Disable scrollpanel debug
... so that I can (re-)release
2016-03-23 14:53:38 +00:00
Richard van der Hoff
422a1f01a4 Limit check on scrollNode.scrollTop to keep firefox happy
Turns out that Firefox ignores attempts to set scrollTop to
Number.MAX_VALUE. Clip it to scrollHeight.
2016-03-23 10:51:07 +00:00
Richard van der Hoff
4fd49976ae Another go at fixing the jumpy scroll
The most recent problem was that we were setting _lastSetScroll whenever we
wrote to scrollTop (and ignoring the next scroll event which matched that
offset), but if there was no change to scrollTop, we wouldn't actually get a
scroll event, so would ignore some future scroll event instead.

Make sure that we only set _lastSetScroll if there's a change to scrollTop.

(Fixes https://github.com/vector-im/vector-web/issues/1162, more)
2016-03-22 19:33:02 +00:00
Richard van der Hoff
c1101d978e Turn on scroll debug again 2016-03-22 15:37:08 +00:00
Richard van der Hoff
b9d3047a93 Disable scrollpanel debug
... now that https://github.com/vector-im/vector-web/issues/1162 is hopefully
fixed
2016-03-22 11:58:17 +00:00
Richard van der Hoff
c89906e571 Only ignore scroll echoes once
When the user scrolls up, and scrolls back to where they were, we want to save
the final scroll state. We were ignoring it because it looked the same as the
last autoscroll.

Fixes https://github.com/vector-im/vector-web/issues/1162
2016-03-21 14:48:17 +00:00
Richard van der Hoff
7712582c29 Renable debug in ScrollPanel
... after matthew disabled it by accident
2016-03-19 20:42:30 +00:00
Matthew Hodgson
bfbb7a661e special case to include kicked rooms as per https://github.com/vector-im/vector-web/issues/308 2016-03-18 19:45:04 +00:00
Richard van der Hoff
d1dbce8adf Enable debug in ScrollPanel for now
... in an attempt to debug some of the recent scroll problems
2016-03-17 17:48:19 +00:00
Matthew Hodgson
2bedece9a1 argh, remove debugging 2016-03-15 22:15:04 +00:00
Matthew Hodgson
f66dd69710 oops, revert - do this on the right branch... 2016-03-15 18:40:03 +00:00
Richard van der Hoff
61cd66304e Adjust the scroll position when the gemini panel is resized
Make sure we restore the scroll state of the message panel when it is resized
2016-03-14 15:29:29 +00:00
Richard van der Hoff
3fd066c2d4 Put direct-linked events and search clickthroughs in the middle
We need two modes of operation for ScrollPanel.scrollToToken:

For jump-to-read-marker, we want it 1/3 of the way down the screen.
For search clickthrough, and hyperlinked events, we want put the event in the
*middle* of the screen.

Fixes https://github.com/vector-im/vector-web/issues/1032
2016-03-10 17:27:46 +00:00
Richard van der Hoff
10b55036f9 Merge branch 'rav/roomview_works' into develop
Implementation of new read-marker semantics (PR #160).
2016-02-24 17:26:46 +00:00
Richard van der Hoff
99d2392b6f Update the scroll offset when images load
In order to deal with image-loading reshaping the DOM, wire up
ScrollPanel.checkScroll to the image load events.

Fixes https://github.com/vector-im/vector-web/issues/984
2016-02-22 17:43:33 +00:00
Richard van der Hoff
c82b364ca8 Address review comments
Mostly renaming things and adding comments.
2016-02-03 08:03:10 +00:00
Richard van der Hoff
d9e13780b8 Implement direct-to-event linking.
This adds support for links to particular event ids: add /<eventId> to the URL
for a room.

This commit also ensures that we scroll to the 'read marker' when switching to
a room which has no previous scroll state, as well as preventing that marker
from going past the middle of the screen.

This also reinstates the preservation of scroll state when switching rooms,
which was disabled previously.
2016-02-01 16:31:12 +00:00
Richard van der Hoff
c30aeac315 Set our own booleans instead of using isMounted 2016-01-11 11:38:04 +00:00
Richard van der Hoff
62cf34b58c Fix some races due to promises completing after we've switched rooms
Add a few isMounted() checks to promise handlers so that we don't end up
throwing NPEs.
2016-01-08 12:03:45 +00:00
Matthew Hodgson
0772f50fab update copyright for 2016 2016-01-07 04:06:52 +00:00
Richard van der Hoff
355cabb7ee Merge pull request #70 from matrix-org/rav/scrollpanel_promises
Make ScrollPanel keep track of when fill requests are happening
2016-01-05 13:52:04 +00:00
Richard van der Hoff
2b169b06f5 Make ScrollPanel.isAtBottom more reliable
Given we want to use isAtBottom to figure out whether to show 'unread messages'
counts, we ought to return the current scroll state, rather than the saved one.

This fixes vector-im/vector-web#576
2016-01-05 11:02:18 +00:00
Richard van der Hoff
b5eae891b4 Address review comments
Make onFillRequest always return a promise
2016-01-04 16:28:32 +00:00
Richard van der Hoff
93e7f90ae4 ScrollPanel: implement forward-fill 2015-12-24 14:30:49 +00:00
Richard van der Hoff
f2a24521dc Make ScrollPanel keep track of when fill requests are happening
The dance to avoid doing repeated fill requests on every update is common, so
add it to ScrollPanel. Let onFillRequest return a promise, which prevents any
updates until it completes.
2015-12-24 14:15:50 +00:00
Richard van der Hoff
cdd539c3cd Factor out a separate 'ScrollPanel'
Create an intelligent scrolling list, which doesn't care what it contains, to
try and clean up some of the logic in RoomView.
2015-12-22 15:18:50 +00:00