mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-18 06:35:35 +08:00
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
This commit is contained in:
parent
7660276b54
commit
3fd066c2d4
@ -141,13 +141,17 @@ module.exports = React.createClass({
|
||||
|
||||
/* jump to the given event id.
|
||||
*
|
||||
* pixelOffset gives the number of pixels between the bottom of the node
|
||||
* and the bottom of the container. If undefined, it will put the node
|
||||
* 1/3 of the way down of the container.
|
||||
* offsetBase gives the reference point for the pixelOffset. 0 means the
|
||||
* top of the container, 1 means the bottom, and fractional values mean
|
||||
* somewhere in the middle. If omitted, it defaults to 0.
|
||||
*
|
||||
* pixelOffset gives the number of pixels *above* the offsetBase that the
|
||||
* node (specifically, the bottom of it) will be positioned. If omitted, it
|
||||
* defaults to 0.
|
||||
*/
|
||||
scrollToEvent: function(eventId, pixelOffset) {
|
||||
scrollToEvent: function(eventId, pixelOffset, offsetBase) {
|
||||
if (this.refs.scrollPanel) {
|
||||
this.refs.scrollPanel.scrollToToken(eventId, pixelOffset);
|
||||
this.refs.scrollPanel.scrollToToken(eventId, pixelOffset, offsetBase);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -326,16 +326,24 @@ module.exports = React.createClass({
|
||||
this._saveScrollState();
|
||||
},
|
||||
|
||||
// pixelOffset gives the number of pixels between the bottom of the node
|
||||
// and the bottom of the container. If undefined, it will put the node
|
||||
// 1/3 of the way down the container.
|
||||
scrollToToken: function(scrollToken, pixelOffset) {
|
||||
var scrollNode = this._getScrollNode();
|
||||
/* Scroll the panel to bring the DOM node with the scroll token
|
||||
* `scrollToken` into view.
|
||||
*
|
||||
* offsetBase gives the reference point for the pixelOffset. 0 means the
|
||||
* top of the container, 1 means the bottom, and fractional values mean
|
||||
* somewhere in the middle. If omitted, it defaults to 0.
|
||||
*
|
||||
* pixelOffset gives the number of pixels *above* the offsetBase that the
|
||||
* node (specifically, the bottom of it) will be positioned. If omitted, it
|
||||
* defaults to 0.
|
||||
*/
|
||||
scrollToToken: function(scrollToken, pixelOffset, offsetBase) {
|
||||
pixelOffset = pixelOffset || 0;
|
||||
offsetBase = offsetBase || 0;
|
||||
|
||||
// default to 1/3 of the way down
|
||||
if (pixelOffset === undefined) {
|
||||
pixelOffset = (scrollNode.clientHeight * 2)/ 3;
|
||||
}
|
||||
// convert pixelOffset so that it is based on the bottom of the
|
||||
// container.
|
||||
pixelOffset += this._getScrollNode().clientHeight * (1-offsetBase);
|
||||
|
||||
// save the desired scroll state. It's important we do this here rather
|
||||
// than as a result of the scroll event, because (a) we might not *get*
|
||||
|
@ -70,7 +70,7 @@ var TimelinePanel = React.createClass({
|
||||
|
||||
// where to position the event given by eventId, in pixels from the
|
||||
// bottom of the viewport. If not given, will try to put the event
|
||||
// 1/3 of the way down the viewport.
|
||||
// half way down the viewport.
|
||||
eventPixelOffset: React.PropTypes.number,
|
||||
|
||||
// callback which is called when the panel is scrolled.
|
||||
@ -413,7 +413,8 @@ var TimelinePanel = React.createClass({
|
||||
}
|
||||
},
|
||||
|
||||
/* scroll to show the read-up-to marker
|
||||
/* scroll to show the read-up-to marker. We put it 1/3 of the way down
|
||||
* the container.
|
||||
*/
|
||||
jumpToReadMarker: function() {
|
||||
if (!this.refs.messagePanel)
|
||||
@ -432,13 +433,14 @@ var TimelinePanel = React.createClass({
|
||||
if (ret !== null) {
|
||||
// The messagepanel knows where the RM is, so we must have loaded
|
||||
// the relevant event.
|
||||
this.refs.messagePanel.scrollToEvent(this.state.readMarkerEventId);
|
||||
this.refs.messagePanel.scrollToEvent(this.state.readMarkerEventId,
|
||||
0, 1/3);
|
||||
}
|
||||
|
||||
// Looks like we haven't loaded the event corresponding to the read-marker.
|
||||
// As with jumpToLiveTimeline, we want to reload the timeline around the
|
||||
// read-marker.
|
||||
this._loadTimeline(this.state.readMarkerEventId);
|
||||
this._loadTimeline(this.state.readMarkerEventId, 0, 1/3);
|
||||
},
|
||||
|
||||
|
||||
@ -518,7 +520,15 @@ var TimelinePanel = React.createClass({
|
||||
_initTimeline: function(props) {
|
||||
var initialEvent = props.eventId;
|
||||
var pixelOffset = props.eventPixelOffset;
|
||||
return this._loadTimeline(initialEvent, pixelOffset);
|
||||
|
||||
// if a pixelOffset is given, it is relative to the bottom of the
|
||||
// container. If not, put the event in the middle of the container.
|
||||
var offsetBase = 1;
|
||||
if (pixelOffset == null) {
|
||||
offsetBase = 0.5;
|
||||
}
|
||||
|
||||
return this._loadTimeline(initialEvent, pixelOffset, offsetBase);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -529,12 +539,15 @@ var TimelinePanel = React.createClass({
|
||||
* scroll to the bottom of the room.
|
||||
*
|
||||
* @param {number?} pixelOffset offset to position the given event at
|
||||
* (pixels from the bottom of the view). If undefined, will put the
|
||||
* event 1/3 of the way down the view.
|
||||
* (pixels from the offsetBase). If omitted, defaults to 0.
|
||||
*
|
||||
* @param {number?} offsetBase the reference point for the pixelOffset. 0
|
||||
* means the top of the container, 1 means the bottom, and fractional
|
||||
* values mean somewhere in the middle. If omitted, it defaults to 0.
|
||||
*
|
||||
* returns a promise which will resolve when the load completes.
|
||||
*/
|
||||
_loadTimeline: function(eventId, pixelOffset) {
|
||||
_loadTimeline: function(eventId, pixelOffset, offsetBase) {
|
||||
this._timelineWindow = new Matrix.TimelineWindow(
|
||||
MatrixClientPeg.get(), this.props.room,
|
||||
{windowLimit: TIMELINE_CAP});
|
||||
@ -567,7 +580,8 @@ var TimelinePanel = React.createClass({
|
||||
return;
|
||||
}
|
||||
if (eventId) {
|
||||
this.refs.messagePanel.scrollToEvent(eventId, pixelOffset);
|
||||
this.refs.messagePanel.scrollToEvent(eventId, pixelOffset,
|
||||
offsetBase);
|
||||
} else {
|
||||
this.refs.messagePanel.scrollToBottom();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user