From afadb23f89e3dcaf3ce35de2619172c741704542 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 21 Dec 2015 10:46:32 +0000 Subject: [PATCH 1/5] Fix bug with date separator flashing up on scrollback Refactor the event-tile generation loop to go forwards rather than backwards, which makes it easier to figure out whether we are displaying a continuation of the previous event, and whether we need a date separator. Also only display the date separator at the top of the room if there's no more scrollback to be shown. This fixes vector-im/vector-web#431 --- src/components/structures/RoomView.js | 61 +++++++++++++++------------ 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index e7b97021df..aafc9b8906 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -399,6 +399,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() { var eventsToResend = this._getUnsentMessages(this.state.room); eventsToResend.forEach(function(event) { @@ -681,7 +687,10 @@ module.exports = React.createClass({ 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]; if (!EventTile.haveTileForEvent(mxEv)) { @@ -694,49 +703,45 @@ module.exports = React.createClass({ } } + // is this a continuation of the previous message? var continuation = false; - var last = false; - var dateSeparator = null; - if (i == this.state.room.timeline.length - 1) { - last = true; - } - 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()) + if (prevEvent !== null) { + if (mxEv.sender && + prevEvent.sender && + (mxEv.sender.userId === prevEvent.sender.userId) && + (mxEv.getType() == prevEvent.getType()) ) { 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 =
  • ; - 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 - var ts1 = this.state.room.timeline[i].getTs(); - dateSeparator =
  • ; + // do we need a date separator since the last event? + var ts1 = mxEv.getTs(); + if ((prevEvent == null && !this._canPaginate()) || + (prevEvent != null && + new Date(prevEvent.getTs()).toDateString() !== new Date(ts1).toDateString())) { + var dateSeparator =
  • ; + ret.push(dateSeparator); 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(); - ret.unshift( + ret.push(
  • ); - if (dateSeparator) { - ret.unshift(dateSeparator); - } - ++count; + + prevEvent = mxEv; } + return ret; }, From 765e5bdeb163b2be848b03a7112fa7c479e6cd8b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 21 Dec 2015 12:39:10 +0000 Subject: [PATCH 2/5] Add a 'top-of-search' marker Ugly as hell, pending better suggestions. This fixes https://github.com/vector-im/vector-web/issues/547 --- src/components/structures/RoomView.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index e7b97021df..3f79e1afe0 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -521,6 +521,7 @@ module.exports = React.createClass({ searchResults: [], searchHighlights: [], searchCount: null, + searchCanPaginate: null, }); this.savedSearchScrollState = {atBottom: true}; @@ -579,6 +580,7 @@ module.exports = React.createClass({ searchHighlights: highlights, searchResults: events, searchCount: results.count, + searchCanPaginate: !!(results.next_batch), }); self.nextSearchBatch = results.next_batch; }, function(error) { @@ -639,6 +641,13 @@ module.exports = React.createClass({ var lastRoomId; + if (this.state.searchCanPaginate === false) { + ret.push(
  • +

    End of search results

    +
  • + ); + } + for (var i = this.state.searchResults.length - 1; i >= 0; i--) { var result = this.state.searchResults[i]; var mxEv = new Matrix.MatrixEvent(result.result); From 7c285f9ad0ea62f629bb49cc378bbea277341a94 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 21 Dec 2015 13:46:27 +0000 Subject: [PATCH 3/5] Add a 'No results' marker when there are no search results at all. Also reword the 'no more results' marker. --- src/components/structures/RoomView.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 3f79e1afe0..d7d3d5988c 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -642,10 +642,17 @@ module.exports = React.createClass({ var lastRoomId; if (this.state.searchCanPaginate === false) { - ret.push(
  • -

    End of search results

    -
  • - ); + if (this.state.searchResults.length == 0) { + ret.push(
  • +

    No results

    +
  • + ); + } else { + ret.push(
  • +

    No more results

    +
  • + ); + } } for (var i = this.state.searchResults.length - 1; i >= 0; i--) { From ea2405ab3a18954c3be35002938f2513d4c16120 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 22 Dec 2015 00:57:57 +0000 Subject: [PATCH 4/5] escape double-slash commands --- src/components/views/rooms/MessageComposer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 7c228b5c9d..67fb37d530 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -319,6 +319,9 @@ module.exports = React.createClass({ if (isEmote) { contentText = contentText.substring(4); } + else if (contentText[0] === '/') { + contentText = contentText.substring(1); + } var htmlText; if (this.markdownEnabled && (htmlText = mdownToHtml(contentText)) !== contentText) { From 360806a8f1958f52eb92dfdf96829e34d5212a05 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 22 Dec 2015 11:04:39 +0000 Subject: [PATCH 5/5] RoomView: add whitespace for disambiguation --- src/components/structures/RoomView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index aafc9b8906..0f02085638 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -689,7 +689,7 @@ module.exports = React.createClass({ var prevEvent = null; // the last event we showed - var startIdx = Math.max(0, this.state.room.timeline.length-this.state.messageCap); + 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];