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.
This commit is contained in:
Richard van der Hoff 2016-02-01 16:31:12 +00:00
parent f0cf5c0aff
commit d9e13780b8
4 changed files with 354 additions and 93 deletions

View file

@ -313,7 +313,7 @@ module.exports = React.createClass({
// by default we autoPeek rooms, unless we were called explicitly with
// autoPeek=false by something like RoomDirectory who has already peeked
this.setState({ autoPeek : payload.auto_peek === false ? false : true });
this._viewRoom(payload.room_id, payload.show_settings);
this._viewRoom(payload.room_id, payload.show_settings, payload.event_id);
break;
case 'view_prev_room':
roomIndexDelta = -1;
@ -348,7 +348,8 @@ module.exports = React.createClass({
if (foundRoom) {
dis.dispatch({
action: 'view_room',
room_id: foundRoom.roomId
room_id: foundRoom.roomId,
event_id: payload.event_id,
});
return;
}
@ -357,7 +358,8 @@ module.exports = React.createClass({
function(result) {
dis.dispatch({
action: 'view_room',
room_id: result.room_id
room_id: result.room_id,
event_id: payload.event_id,
});
});
break;
@ -429,15 +431,34 @@ module.exports = React.createClass({
});
},
_viewRoom: function(roomId, showSettings) {
// switch view to the given room
//
// eventId is optional and will cause a switch to the context of that
// particular event.
_viewRoom: function(roomId, showSettings, eventId) {
// before we switch room, record the scroll state of the current room
this._updateScrollMap();
this.focusComposer = true;
var newState = {
currentRoom: roomId,
initialEventId: eventId,
highlightedEventId: eventId,
initialEventPixelOffset: undefined,
page_type: this.PageTypes.RoomView,
};
// if we aren't given an explicit event id, look for one in the
// scrollStateMap.
if (!eventId) {
var scrollState = this.scrollStateMap[roomId];
if (scrollState) {
newState.initialEventId = scrollState.focussedEvent;
newState.initialEventPixelOffset = scrollState.pixelOffset;
}
}
if (this.sdkReady) {
// if the SDK is not ready yet, remember what room
// we're supposed to be on but don't notify about
@ -459,15 +480,14 @@ module.exports = React.createClass({
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
}
if (eventId) {
presentedId += "/"+eventId;
}
this.notifyNewScreen('room/'+presentedId);
newState.ready = true;
}
this.setState(newState);
/*
if (this.scrollStateMap[roomId]) {
var scrollState = this.scrollStateMap[roomId];
this.refs.roomView.restoreScrollState(scrollState);
}*/
if (this.refs.roomView && showSettings) {
this.refs.roomView.showSettings(true);
}
@ -515,9 +535,11 @@ module.exports = React.createClass({
if (self.starting_room_alias) {
dis.dispatch({
action: 'view_room_alias',
room_alias: self.starting_room_alias
room_alias: self.starting_room_alias,
event_id: self.starting_event_id,
});
delete self.starting_room_alias;
delete self.starting_event_id;
} else if (!self.state.page_type) {
if (!self.state.currentRoom) {
var firstRoom = null;
@ -635,23 +657,35 @@ module.exports = React.createClass({
action: 'start_post_registration',
});
} else if (screen.indexOf('room/') == 0) {
var roomString = screen.split('/')[1];
var roomString = screen.substring(5);
var eventId;
// extract event id, if one is given
var idx = roomString.indexOf('/');
if (idx >= 0) {
eventId = roomString.substring(idx+1);
roomString = roomString.substring(0, idx);
}
if (roomString[0] == '#') {
if (this.state.logged_in) {
dis.dispatch({
action: 'view_room_alias',
room_alias: roomString
room_alias: roomString,
event_id: eventId,
});
} else {
// Okay, we'll take you here soon...
this.starting_room_alias = roomString;
this.starting_event_id = eventId;
// ...but you're still going to have to log in.
this.notifyNewScreen('login');
}
} else {
dis.dispatch({
action: 'view_room',
room_id: roomString
room_id: roomString,
event_id: eventId,
});
}
}
@ -828,6 +862,9 @@ module.exports = React.createClass({
<RoomView
ref="roomView"
roomId={this.state.currentRoom}
eventId={this.state.initialEventId}
highlightedEventId={this.state.highlightedEventId}
eventPixelOffset={this.state.initialEventPixelOffset}
autoPeek={this.state.autoPeek}
key={this.state.currentRoom}
ConferenceHandler={this.props.ConferenceHandler} />