Merge branch 'develop' into kegan/tab-complete

This commit is contained in:
Kegan Dougal 2015-12-22 15:16:39 +00:00
commit a20cabb06f
2 changed files with 52 additions and 28 deletions

View file

@ -412,6 +412,12 @@ module.exports = React.createClass({
} }
}, },
// return true if there's more messages in the backlog which we aren't displaying
_canPaginate: function() {
return (this.state.messageCap < this.state.room.timeline.length) ||
this.state.room.oldState.paginationToken;
},
onResendAllClick: function() { onResendAllClick: function() {
var eventsToResend = this._getUnsentMessages(this.state.room); var eventsToResend = this._getUnsentMessages(this.state.room);
eventsToResend.forEach(function(event) { eventsToResend.forEach(function(event) {
@ -534,6 +540,7 @@ module.exports = React.createClass({
searchResults: [], searchResults: [],
searchHighlights: [], searchHighlights: [],
searchCount: null, searchCount: null,
searchCanPaginate: null,
}); });
this.savedSearchScrollState = {atBottom: true}; this.savedSearchScrollState = {atBottom: true};
@ -592,6 +599,7 @@ module.exports = React.createClass({
searchHighlights: highlights, searchHighlights: highlights,
searchResults: events, searchResults: events,
searchCount: results.count, searchCount: results.count,
searchCanPaginate: !!(results.next_batch),
}); });
self.nextSearchBatch = results.next_batch; self.nextSearchBatch = results.next_batch;
}, function(error) { }, function(error) {
@ -652,6 +660,20 @@ module.exports = React.createClass({
var lastRoomId; var lastRoomId;
if (this.state.searchCanPaginate === false) {
if (this.state.searchResults.length == 0) {
ret.push(<li key="search-top-marker">
<h2 className="mx_RoomView_topMarker">No results</h2>
</li>
);
} else {
ret.push(<li key="search-top-marker">
<h2 className="mx_RoomView_topMarker">No more results</h2>
</li>
);
}
}
for (var i = this.state.searchResults.length - 1; i >= 0; i--) { for (var i = this.state.searchResults.length - 1; i >= 0; i--) {
var result = this.state.searchResults[i]; var result = this.state.searchResults[i];
var mxEv = new Matrix.MatrixEvent(result.result); var mxEv = new Matrix.MatrixEvent(result.result);
@ -694,7 +716,10 @@ module.exports = React.createClass({
return ret; return ret;
} }
for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) {
var prevEvent = null; // the last event we showed
var startIdx = Math.max(0, this.state.room.timeline.length - this.state.messageCap);
for (var i = startIdx; i < this.state.room.timeline.length; i++) {
var mxEv = this.state.room.timeline[i]; var mxEv = this.state.room.timeline[i];
if (!EventTile.haveTileForEvent(mxEv)) { if (!EventTile.haveTileForEvent(mxEv)) {
@ -707,49 +732,45 @@ module.exports = React.createClass({
} }
} }
// is this a continuation of the previous message?
var continuation = false; var continuation = false;
var last = false; if (prevEvent !== null) {
var dateSeparator = null; if (mxEv.sender &&
if (i == this.state.room.timeline.length - 1) { prevEvent.sender &&
last = true; (mxEv.sender.userId === prevEvent.sender.userId) &&
} (mxEv.getType() == prevEvent.getType())
if (i > 0 && count < this.state.messageCap - 1) {
if (this.state.room.timeline[i].sender &&
this.state.room.timeline[i - 1].sender &&
(this.state.room.timeline[i].sender.userId ===
this.state.room.timeline[i - 1].sender.userId) &&
(this.state.room.timeline[i].getType() ==
this.state.room.timeline[i - 1].getType())
) )
{ {
continuation = true; continuation = true;
} }
var ts0 = this.state.room.timeline[i - 1].getTs();
var ts1 = this.state.room.timeline[i].getTs();
if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
dateSeparator = <li key={ts1}><DateSeparator key={ts1} ts={ts1}/></li>;
continuation = false;
}
} }
if (i === 1) { // n.b. 1, not 0, as the 0th event is an m.room.create and so doesn't show on the timeline // do we need a date separator since the last event?
var ts1 = this.state.room.timeline[i].getTs(); var ts1 = mxEv.getTs();
dateSeparator = <li key={ts1}><DateSeparator ts={ts1}/></li>; if ((prevEvent == null && !this._canPaginate()) ||
(prevEvent != null &&
new Date(prevEvent.getTs()).toDateString() !== new Date(ts1).toDateString())) {
var dateSeparator = <li key={ts1}><DateSeparator key={ts1} ts={ts1}/></li>;
ret.push(dateSeparator);
continuation = false; continuation = false;
} }
var last = false;
if (i == this.state.room.timeline.length - 1) {
// XXX: we might not show a tile for the last event.
last = true;
}
var eventId = mxEv.getId(); var eventId = mxEv.getId();
ret.unshift( ret.push(
<li key={eventId} ref={this._collectEventNode.bind(this, eventId)} data-scroll-token={eventId}> <li key={eventId} ref={this._collectEventNode.bind(this, eventId)} data-scroll-token={eventId}>
<EventTile mxEvent={mxEv} continuation={continuation} last={last}/> <EventTile mxEvent={mxEv} continuation={continuation} last={last}/>
</li> </li>
); );
if (dateSeparator) {
ret.unshift(dateSeparator); prevEvent = mxEv;
}
++count;
} }
return ret; return ret;
}, },

View file

@ -348,6 +348,9 @@ module.exports = React.createClass({
if (isEmote) { if (isEmote) {
contentText = contentText.substring(4); contentText = contentText.substring(4);
} }
else if (contentText[0] === '/') {
contentText = contentText.substring(1);
}
var htmlText; var htmlText;
if (this.markdownEnabled && (htmlText = mdownToHtml(contentText)) !== contentText) { if (this.markdownEnabled && (htmlText = mdownToHtml(contentText)) !== contentText) {