From 4aea2caefce63b824f95fbc46d43e02df1f4c06e Mon Sep 17 00:00:00 2001 From: wmwragg Date: Thu, 11 Aug 2016 16:45:19 +0100 Subject: [PATCH 01/20] Initial pass at creating a direct message section --- src/components/views/rooms/RoomList.js | 65 +++++++++++++++----------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 52e0ffb083..ffb3b366e8 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -188,6 +188,7 @@ module.exports = React.createClass({ s.lists["im.vector.fake.invite"] = []; s.lists["m.favourite"] = []; s.lists["im.vector.fake.recent"] = []; + s.lists["im.vector.fake.direct"] = []; s.lists["m.lowpriority"] = []; s.lists["im.vector.fake.archived"] = []; @@ -206,36 +207,36 @@ module.exports = React.createClass({ else if (me.membership == "join" || me.membership === "ban" || (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { - var shouldShowRoom = true; + // Used to split rooms via tags + var tagNames = Object.keys(room.tags); + // Used for 1:1 direct chats + var joinedMembers = room.getJoinedMembers(); - // hiding conf rooms only ever toggles shouldShowRoom to false - if (HIDE_CONFERENCE_CHANS) { - // we want to hide the 1:1 conf<->user room and not the group chat - var joinedMembers = room.getJoinedMembers(); - if (joinedMembers.length === 2) { - var otherMember = joinedMembers.filter(function(m) { - return m.userId !== me.userId - })[0]; - var ConfHandler = self.props.ConferenceHandler; - if (ConfHandler && ConfHandler.isConferenceUser(otherMember.userId)) { - // console.log("Hiding conference 1:1 room %s", room.roomId); - shouldShowRoom = false; + // Show 1:1 chats in seperate "Direct Messages" section as long as they haven't + // been moved to a different tag section + if (joinedMembers.length === 2 && !tagNames.length) { + var otherMember = joinedMembers.filter(function(m) { + return m.userId !== me.userId + })[0]; + + var ConfHandler = self.props.ConferenceHandler; + if (ConfHandler && ConfHandler.isConferenceUser(otherMember.userId)) { + // console.log("Hiding conference 1:1 room %s", room.roomId); + if (!HIDE_CONFERENCE_CHANS) { + s.lists["im.vector.fake.direct"].push(room); } + } else { + s.lists["im.vector.fake.direct"].push(room); + } + } else if (tagNames.length) { + for (var i = 0; i < tagNames.length; i++) { + var tagName = tagNames[i]; + s.lists[tagName] = s.lists[tagName] || []; + s.lists[tagNames[i]].push(room); } } - - if (shouldShowRoom) { - var tagNames = Object.keys(room.tags); - if (tagNames.length) { - for (var i = 0; i < tagNames.length; i++) { - var tagName = tagNames[i]; - s.lists[tagName] = s.lists[tagName] || []; - s.lists[tagNames[i]].push(room); - } - } - else { - s.lists["im.vector.fake.recent"].push(room); - } + else { + s.lists["im.vector.fake.recent"].push(room); } } else if (me.membership === "leave") { @@ -364,8 +365,18 @@ module.exports = React.createClass({ searchFilter={ self.props.searchFilter } onShowMoreRooms={ self.onShowMoreRooms } /> + + { Object.keys(self.state.lists).map(function(tagName) { - if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|archived))$/)) { + if (!tagName.match(/^(m\.(favourite|lowpriority)|im\.vector\.fake\.(invite|recent|direct|archived))$/)) { return Date: Thu, 11 Aug 2016 17:32:39 +0100 Subject: [PATCH 02/20] refactoring out the direct message section --- src/MatrixTools.js | 30 ++++++++++++++++++++++++++ src/components/views/rooms/RoomList.js | 25 ++++++--------------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/MatrixTools.js b/src/MatrixTools.js index b003d8d2d7..3bc7f28e20 100644 --- a/src/MatrixTools.js +++ b/src/MatrixTools.js @@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +var CallHandler = require('./CallHandler'); module.exports = { /** @@ -24,5 +25,34 @@ module.exports = { getDisplayAliasForRoom: function(room) { return room.getCanonicalAlias() || room.getAliases()[0]; }, + + isDirectMessageRoom: function(room, me, ConferenceHandler, hideConferenceChans) { + if (me.membership == "join" || me.membership === "ban" || + (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) + { + // Used to split rooms via tags + var tagNames = Object.keys(room.tags); + // Used for 1:1 direct chats + var joinedMembers = room.getJoinedMembers(); + + // Show 1:1 chats in seperate "Direct Messages" section as long as they haven't + // been moved to a different tag section + if (joinedMembers.length === 2 && !tagNames.length) { + var otherMember = joinedMembers.filter(function(m) { + return m.userId !== me.userId + })[0]; + + if (ConferenceHandler && ConferenceHandler.isConferenceUser(otherMember.userId)) { + // console.log("Hiding conference 1:1 room %s", room.roomId); + if (!hideConferenceChans) { + return true; + } + } else { + return true; + } + } + } + return false; + }, } diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index ffb3b366e8..ce3e3a0cf7 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -25,6 +25,7 @@ var Unread = require('../../../Unread'); var dis = require("../../../dispatcher"); var sdk = require('../../../index'); var rate_limited_func = require('../../../ratelimitedfunc'); +var MatrixTools = require('../../../MatrixTools'); var HIDE_CONFERENCE_CHANS = true; @@ -204,31 +205,17 @@ module.exports = React.createClass({ if (me.membership == "invite") { s.lists["im.vector.fake.invite"].push(room); } + else if (MatrixTools.isDirectMessageRoom(room, me, self.props.ConferenceHandler, HIDE_CONFERENCE_CHANS)) { + // "Direct Message" rooms + s.lists["im.vector.fake.direct"].push(room); + } else if (me.membership == "join" || me.membership === "ban" || (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { // Used to split rooms via tags var tagNames = Object.keys(room.tags); - // Used for 1:1 direct chats - var joinedMembers = room.getJoinedMembers(); - // Show 1:1 chats in seperate "Direct Messages" section as long as they haven't - // been moved to a different tag section - if (joinedMembers.length === 2 && !tagNames.length) { - var otherMember = joinedMembers.filter(function(m) { - return m.userId !== me.userId - })[0]; - - var ConfHandler = self.props.ConferenceHandler; - if (ConfHandler && ConfHandler.isConferenceUser(otherMember.userId)) { - // console.log("Hiding conference 1:1 room %s", room.roomId); - if (!HIDE_CONFERENCE_CHANS) { - s.lists["im.vector.fake.direct"].push(room); - } - } else { - s.lists["im.vector.fake.direct"].push(room); - } - } else if (tagNames.length) { + if (tagNames.length) { for (var i = 0; i < tagNames.length; i++) { var tagName = tagNames[i]; s.lists[tagName] = s.lists[tagName] || []; From 434115ccda8ab00eb9792ae9c31227cab555e926 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Thu, 11 Aug 2016 17:34:05 +0100 Subject: [PATCH 03/20] Bugifx: 'background-color' in react should be 'backgroundColor' --- src/components/structures/ContextualMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ContextualMenu.js b/src/components/structures/ContextualMenu.js index ab557e77d7..fecb2a1841 100644 --- a/src/components/structures/ContextualMenu.js +++ b/src/components/structures/ContextualMenu.js @@ -108,7 +108,7 @@ module.exports = { } if (props.menuColour) { - menuStyle["background-color"] = props.menuColour; + menuStyle["backgroundColor"] = props.menuColour; } // FIXME: If a menu uses getDefaultProps it clobbers the onFinished From edb7301b37da508a1f35e9165a6967e5169cdb72 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Mon, 22 Aug 2016 14:10:51 +0100 Subject: [PATCH 04/20] Moving the drirect messages above rooms --- src/components/views/rooms/RoomList.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index ce3e3a0cf7..b382a3f362 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -341,10 +341,9 @@ module.exports = React.createClass({ searchFilter={ self.props.searchFilter } onShowMoreRooms={ self.onShowMoreRooms } /> - - Date: Tue, 23 Aug 2016 12:40:28 +0100 Subject: [PATCH 05/20] Added updating of count when room tile notification state changed --- src/components/views/rooms/RoomTile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/views/rooms/RoomTile.js b/src/components/views/rooms/RoomTile.js index dd1ca125aa..b646b12e76 100644 --- a/src/components/views/rooms/RoomTile.js +++ b/src/components/views/rooms/RoomTile.js @@ -40,6 +40,7 @@ module.exports = React.createClass({ highlight: React.PropTypes.bool.isRequired, isInvite: React.PropTypes.bool.isRequired, roomSubList: React.PropTypes.object.isRequired, + refreshSubList: React.PropTypes.func.isRequired, incomingCall: React.PropTypes.object, }, @@ -132,6 +133,7 @@ module.exports = React.createClass({ room: this.props.room, onFinished: function() { self.setState({ notificationTagMenu: false }); + self.props.refreshSubList(); } }); this.setState({ notificationTagMenu: true }); From 7fcdd0f77a2f801415fa1f060170b92118b63361 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Thu, 25 Aug 2016 19:46:01 +0100 Subject: [PATCH 06/20] Initial pass at sticky headers for the LHS panel section labels --- src/components/views/rooms/RoomList.js | 100 ++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b382a3f362..b55802746e 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -66,6 +66,11 @@ module.exports = React.createClass({ this.dispatcherRef = dis.register(this.onAction); }, + componentDidUpdate: function() { + // Reinitilaise the stickyHeaders when the component is created or updated + this._updateStickyHeaders(undefined, true); + }, + onAction: function(payload) { switch (payload.action) { case 'view_tooltip': @@ -252,9 +257,10 @@ module.exports = React.createClass({ } }, - _repositionTooltips: function(e) { + _whenScrolling: function(e) { this._repositionTooltip(e); this._repositionIncomingCallBox(e, false); + this._updateStickyHeaders(e, false); }, _repositionTooltip: function(e) { @@ -305,6 +311,96 @@ module.exports = React.createClass({ } }, + _initAndPositionStickyHeaders: function(e, firstTime) { + // Do the sticky header stuf here, both the initilaisation (firstTime === true) + // and the updating when scrolling (firstTime === false) + // use direct DOM access as done in _repositionIncomingCallBox + + var self = this; + + var stickies = document.getElementsByClassName("mx_RoomSubList_stickyContainer"); + var scrollArea = self._getScrollNode(); + var scrollAreaHeight = scrollArea.getBoundingClientRect().height; + +// console.log(scrollArea); +// console.log("scrollAreaHeight: " + scrollAreaHeight); + + if (firstTime) { + if (typeof stickies === "object" && stickies.length > 0) { + // Initialise the sticky headers + self.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { + sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; + var originalHeight = sticky.getBoundingClientRect().height; + sticky.dataset.originalHeight = originalHeight; + sticky.style.height = originalHeight; + + return sticky; + }); + } + } + + Array.prototype.forEach.call(self.stickyWrappers, function(sticky, i, stickyWrappers) { + var stickyPosition = sticky.dataset.originalPosition; + var stickyHeight = sticky.dataset.originalHeight; + var stickyHeader = sticky.childNodes[0]; + var topStuckHeight = stickyHeight * i; + var bottomStuckHeight = stickyHeight * (stickyWrappers.length - i) + +// console.log("i: " + i); +// console.log("scrollArea.scrollTop: " + scrollArea.scrollTop); +// console.log("scrollArea.offsetTop: " + scrollArea.offsetTop); +// console.log("stickyPosition: " + stickyPosition); +// console.log("stickyHeight: " + stickyHeight); + //console.log(stickyHeader); +// console.log("topStuckHeight: " + topStuckHeight); +// console.log("bottomStuckHeight: " + bottomStuckHeight); + + if (stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { + // Top stickies + // console.log("Top stickies"); + stickyHeader.classList.add("mx_RoomSubList_fixed"); + //sticky.style.height = stickyHeight + "px"; + stickyHeader.style.top = scrollArea.offsetTop + topStuckHeight + "px"; + } else if (stickyPosition >= ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { + /// Bottom stickies + //console.log("Bottom stickies"); + stickyHeader.classList.add("mx_RoomSubList_fixed"); + //sticky.style.height = stickyHeight + "px"; + stickyHeader.style.top = (scrollArea.offsetTop + scrollAreaHeight) - bottomStuckHeight + "px"; + } else { + // Not sticky + //console.log("Not sticky"); + stickyHeader.classList.remove("mx_RoomSubList_fixed"); + //sticky.style.height = null; + stickyHeader.style.top = null; + } + }); + }, + + _stickyWrappers: [], + + _updateStickyHeaders: function(e, firstTime) { + // Do the sticky header stuff here, both the initilaisation (firstTime === true) + // and the updating when scrolling (firstTime === false) + // use direct DOM access as done in _repositionIncomingCallBox + + var self = this; + + if (firstTime) { + // Useing requestAnimationFrame to ensure that the code is run after the painting + // of the newly rendered object + window.requestAnimationFrame(function() { + //console.log("### D E B U G requestAnimationFrame S T A R T ###"); + self._initAndPositionStickyHeaders(e, firstTime); + //console.log("### D E B U G requestAnimationFrame F I N I S H ###"); + }); + } else { + //console.log("### D E B U G S T A R T ###"); + this._initAndPositionStickyHeaders(e, firstTime); + //console.log("### D E B U G F I N I S H ###"); + } + }, + onShowMoreRooms: function() { // kick gemini in the balls to get it to wake up // XXX: uuuuuuugh. @@ -317,7 +413,7 @@ module.exports = React.createClass({ return ( + autoshow={true} onScroll={ self._whenScrolling } ref="gemscroll">
Date: Fri, 26 Aug 2016 09:56:07 +0100 Subject: [PATCH 07/20] Re-calculate sticky header positions when sublist header is clicked --- src/components/views/rooms/RoomList.js | 33 +++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index b55802746e..bbcef5286d 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -134,6 +134,11 @@ module.exports = React.createClass({ } }, + onSubListHeaderClick: function(isHidden) { + // The scroll area has expanded or contracted, so re-calculate sticky headers positions + this._updateStickyHeaders(undefined, true); + }, + onRoomTimeline: function(ev, room, toStartOfTimeline) { if (toStartOfTimeline) return; this._delayedRefreshRoomList(); @@ -311,21 +316,21 @@ module.exports = React.createClass({ } }, - _initAndPositionStickyHeaders: function(e, firstTime) { - // Do the sticky header stuf here, both the initilaisation (firstTime === true) - // and the updating when scrolling (firstTime === false) + _initAndPositionStickyHeaders: function(e, initialise) { + // Do the sticky header stuf here, both the initilaisation (initialise === true) + // and the updating when scrolling (initialise === false) // use direct DOM access as done in _repositionIncomingCallBox var self = this; - var stickies = document.getElementsByClassName("mx_RoomSubList_stickyContainer"); var scrollArea = self._getScrollNode(); var scrollAreaHeight = scrollArea.getBoundingClientRect().height; // console.log(scrollArea); // console.log("scrollAreaHeight: " + scrollAreaHeight); - if (firstTime) { + if (initialise) { + var stickies = document.getElementsByClassName("mx_RoomSubList_labelContainer"); if (typeof stickies === "object" && stickies.length > 0) { // Initialise the sticky headers self.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { @@ -379,24 +384,24 @@ module.exports = React.createClass({ _stickyWrappers: [], - _updateStickyHeaders: function(e, firstTime) { - // Do the sticky header stuff here, both the initilaisation (firstTime === true) - // and the updating when scrolling (firstTime === false) + _updateStickyHeaders: function(e, initialise) { + // Do the sticky header stuff here, both the initilaisation (initialise === true) + // and the updating when scrolling (initialise === false) // use direct DOM access as done in _repositionIncomingCallBox var self = this; - if (firstTime) { + if (initialise) { // Useing requestAnimationFrame to ensure that the code is run after the painting // of the newly rendered object window.requestAnimationFrame(function() { //console.log("### D E B U G requestAnimationFrame S T A R T ###"); - self._initAndPositionStickyHeaders(e, firstTime); + self._initAndPositionStickyHeaders(e, initialise); //console.log("### D E B U G requestAnimationFrame F I N I S H ###"); }); } else { //console.log("### D E B U G S T A R T ###"); - this._initAndPositionStickyHeaders(e, firstTime); + this._initAndPositionStickyHeaders(e, initialise); //console.log("### D E B U G F I N I S H ###"); } }, @@ -423,6 +428,7 @@ module.exports = React.createClass({ incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } searchFilter={ self.props.searchFilter } + onHeaderClick={ self.onSubListHeaderClick } onShowMoreRooms={ self.onShowMoreRooms } /> { Object.keys(self.state.lists).map(function(tagName) { @@ -471,6 +480,7 @@ module.exports = React.createClass({ incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } searchFilter={ self.props.searchFilter } + onHeaderClick={ self.onSubListHeaderClick } onShowMoreRooms={ self.onShowMoreRooms } /> } @@ -486,6 +496,7 @@ module.exports = React.createClass({ incomingCall={ self.state.incomingCall } collapsed={ self.props.collapsed } searchFilter={ self.props.searchFilter } + onHeaderClick={ self.onSubListHeaderClick } onShowMoreRooms={ self.onShowMoreRooms } /> Date: Fri, 26 Aug 2016 11:01:04 +0100 Subject: [PATCH 08/20] Added some logic to turn off sticky headers when the scroll area isn't large enough to support them --- src/components/views/rooms/RoomList.js | 77 +++++++++----------------- 1 file changed, 26 insertions(+), 51 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index bbcef5286d..dcaf9f9ac4 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -64,10 +64,12 @@ module.exports = React.createClass({ componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); + // Initilaise the stickyHeaders when the component is created + this._updateStickyHeaders(undefined, true); }, componentDidUpdate: function() { - // Reinitilaise the stickyHeaders when the component is created or updated + // Reinitilaise the stickyHeaders when the component is updated this._updateStickyHeaders(undefined, true); }, @@ -317,92 +319,65 @@ module.exports = React.createClass({ }, _initAndPositionStickyHeaders: function(e, initialise) { - // Do the sticky header stuf here, both the initilaisation (initialise === true) - // and the updating when scrolling (initialise === false) - // use direct DOM access as done in _repositionIncomingCallBox - - var self = this; - - var scrollArea = self._getScrollNode(); + var scrollArea = this._getScrollNode(); var scrollAreaHeight = scrollArea.getBoundingClientRect().height; -// console.log(scrollArea); -// console.log("scrollAreaHeight: " + scrollAreaHeight); - if (initialise) { var stickies = document.getElementsByClassName("mx_RoomSubList_labelContainer"); - if (typeof stickies === "object" && stickies.length > 0) { - // Initialise the sticky headers - self.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { - sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; - var originalHeight = sticky.getBoundingClientRect().height; - sticky.dataset.originalHeight = originalHeight; - sticky.style.height = originalHeight; - return sticky; - }); + this.scrollAreaSufficient = (120 + (stickies[0].getBoundingClientRect().height * stickies.length)) < scrollAreaHeight; + + if (this.scrollAreaSufficient) { + if (typeof stickies === "object" && stickies.length > 0) { + // Initialise the sticky headers + this.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { + sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; + var originalHeight = sticky.getBoundingClientRect().height; + sticky.dataset.originalHeight = originalHeight; + sticky.style.height = originalHeight; + + return sticky; + }); + } } } - Array.prototype.forEach.call(self.stickyWrappers, function(sticky, i, stickyWrappers) { + var self = this; + Array.prototype.forEach.call(this.stickyWrappers, function(sticky, i, stickyWrappers) { var stickyPosition = sticky.dataset.originalPosition; var stickyHeight = sticky.dataset.originalHeight; var stickyHeader = sticky.childNodes[0]; var topStuckHeight = stickyHeight * i; var bottomStuckHeight = stickyHeight * (stickyWrappers.length - i) -// console.log("i: " + i); -// console.log("scrollArea.scrollTop: " + scrollArea.scrollTop); -// console.log("scrollArea.offsetTop: " + scrollArea.offsetTop); -// console.log("stickyPosition: " + stickyPosition); -// console.log("stickyHeight: " + stickyHeight); - //console.log(stickyHeader); -// console.log("topStuckHeight: " + topStuckHeight); -// console.log("bottomStuckHeight: " + bottomStuckHeight); - - if (stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { + if (self.scrollAreaSufficient && stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { // Top stickies - // console.log("Top stickies"); stickyHeader.classList.add("mx_RoomSubList_fixed"); - //sticky.style.height = stickyHeight + "px"; stickyHeader.style.top = scrollArea.offsetTop + topStuckHeight + "px"; - } else if (stickyPosition >= ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { + } else if (self.scrollAreaSufficient && stickyPosition >= ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { /// Bottom stickies - //console.log("Bottom stickies"); stickyHeader.classList.add("mx_RoomSubList_fixed"); - //sticky.style.height = stickyHeight + "px"; stickyHeader.style.top = (scrollArea.offsetTop + scrollAreaHeight) - bottomStuckHeight + "px"; } else { // Not sticky - //console.log("Not sticky"); stickyHeader.classList.remove("mx_RoomSubList_fixed"); - //sticky.style.height = null; stickyHeader.style.top = null; } }); }, - _stickyWrappers: [], - _updateStickyHeaders: function(e, initialise) { - // Do the sticky header stuff here, both the initilaisation (initialise === true) - // and the updating when scrolling (initialise === false) - // use direct DOM access as done in _repositionIncomingCallBox - var self = this; if (initialise) { - // Useing requestAnimationFrame to ensure that the code is run after the painting - // of the newly rendered object - window.requestAnimationFrame(function() { - //console.log("### D E B U G requestAnimationFrame S T A R T ###"); + // Useing setTimeout to ensure that the code is run after the painting + // of the newly rendered object as using requestAnimationFrame caused + // artefacts to appear on screen briefly + window.setTimeout(function() { self._initAndPositionStickyHeaders(e, initialise); - //console.log("### D E B U G requestAnimationFrame F I N I S H ###"); }); } else { - //console.log("### D E B U G S T A R T ###"); this._initAndPositionStickyHeaders(e, initialise); - //console.log("### D E B U G F I N I S H ###"); } }, From 71e829fd324cd5c06c31684d0a5375cda9657709 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Fri, 26 Aug 2016 14:36:39 +0100 Subject: [PATCH 09/20] Getting click to not collapse expand when header is stuck --- src/components/views/rooms/RoomList.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index dcaf9f9ac4..7aacb7c00e 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -121,7 +121,7 @@ module.exports = React.createClass({ this._delayedRefreshRoomList(); }, - onArchivedHeaderClick: function(isHidden) { + onArchivedHeaderClick: function(ev, isHidden) { if (!isHidden) { var self = this; this.setState({ isLoadingLeftRooms: true }); @@ -136,9 +136,9 @@ module.exports = React.createClass({ } }, - onSubListHeaderClick: function(isHidden) { + onSubListHeaderClick: function(ev, isHidden) { // The scroll area has expanded or contracted, so re-calculate sticky headers positions - this._updateStickyHeaders(undefined, true); + this._updateStickyHeaders(ev, true); }, onRoomTimeline: function(ev, room, toStartOfTimeline) { @@ -343,6 +343,14 @@ module.exports = React.createClass({ } var self = this; + if (e !== undefined && e.type === "click") { + console.log("### D E B U G ###"); +// var clickedElement = e.target; +// console.log(clickedElement.offsetTop); +// scrollArea.scrollTop = clickedElement.offsetTop; + //e.target.scrollIntoView(); + //scrollArea.scrollTop = e.target.parentNode.dataset.originalPosition; + } Array.prototype.forEach.call(this.stickyWrappers, function(sticky, i, stickyWrappers) { var stickyPosition = sticky.dataset.originalPosition; var stickyHeight = sticky.dataset.originalHeight; @@ -352,14 +360,17 @@ module.exports = React.createClass({ if (self.scrollAreaSufficient && stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { // Top stickies + sticky.dataset.stuck = "top"; stickyHeader.classList.add("mx_RoomSubList_fixed"); stickyHeader.style.top = scrollArea.offsetTop + topStuckHeight + "px"; } else if (self.scrollAreaSufficient && stickyPosition >= ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { /// Bottom stickies + sticky.dataset.stuck = "bottom"; stickyHeader.classList.add("mx_RoomSubList_fixed"); stickyHeader.style.top = (scrollArea.offsetTop + scrollAreaHeight) - bottomStuckHeight + "px"; } else { // Not sticky + sticky.dataset.stuck = "none"; stickyHeader.classList.remove("mx_RoomSubList_fixed"); stickyHeader.style.top = null; } From b9e95865af2c7f29e132e59fcd187472083c6ff9 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Fri, 26 Aug 2016 15:09:13 +0100 Subject: [PATCH 10/20] Click on stuck header scrolls to that header, collapses expands for none stuck header --- src/components/views/rooms/RoomList.js | 38 ++++++++++++++------------ 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 7aacb7c00e..a020a168d8 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -65,12 +65,12 @@ module.exports = React.createClass({ componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); // Initilaise the stickyHeaders when the component is created - this._updateStickyHeaders(undefined, true); + this._updateStickyHeaders(true); }, componentDidUpdate: function() { // Reinitilaise the stickyHeaders when the component is updated - this._updateStickyHeaders(undefined, true); + this._updateStickyHeaders(true); }, onAction: function(payload) { @@ -121,7 +121,7 @@ module.exports = React.createClass({ this._delayedRefreshRoomList(); }, - onArchivedHeaderClick: function(ev, isHidden) { + onArchivedHeaderClick: function(isHidden) { if (!isHidden) { var self = this; this.setState({ isLoadingLeftRooms: true }); @@ -136,9 +136,9 @@ module.exports = React.createClass({ } }, - onSubListHeaderClick: function(ev, isHidden) { + onSubListHeaderClick: function(isHidden, scrollToPosition) { // The scroll area has expanded or contracted, so re-calculate sticky headers positions - this._updateStickyHeaders(ev, true); + this._updateStickyHeaders(true, scrollToPosition); }, onRoomTimeline: function(ev, room, toStartOfTimeline) { @@ -267,7 +267,7 @@ module.exports = React.createClass({ _whenScrolling: function(e) { this._repositionTooltip(e); this._repositionIncomingCallBox(e, false); - this._updateStickyHeaders(e, false); + this._updateStickyHeaders(false); }, _repositionTooltip: function(e) { @@ -318,7 +318,7 @@ module.exports = React.createClass({ } }, - _initAndPositionStickyHeaders: function(e, initialise) { + _initAndPositionStickyHeaders: function(initialise, scrollToPosition) { var scrollArea = this._getScrollNode(); var scrollAreaHeight = scrollArea.getBoundingClientRect().height; @@ -343,13 +343,9 @@ module.exports = React.createClass({ } var self = this; - if (e !== undefined && e.type === "click") { - console.log("### D E B U G ###"); -// var clickedElement = e.target; -// console.log(clickedElement.offsetTop); -// scrollArea.scrollTop = clickedElement.offsetTop; - //e.target.scrollIntoView(); - //scrollArea.scrollTop = e.target.parentNode.dataset.originalPosition; + var scrollStuckOffset = 0; + if (scrollToPosition !== undefined) { + scrollArea.scrollTop = scrollToPosition; } Array.prototype.forEach.call(this.stickyWrappers, function(sticky, i, stickyWrappers) { var stickyPosition = sticky.dataset.originalPosition; @@ -358,6 +354,10 @@ module.exports = React.createClass({ var topStuckHeight = stickyHeight * i; var bottomStuckHeight = stickyHeight * (stickyWrappers.length - i) + if (scrollToPosition !== undefined && stickyPosition === scrollToPosition) { + scrollStuckOffset = topStuckHeight; + } + if (self.scrollAreaSufficient && stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { // Top stickies sticky.dataset.stuck = "top"; @@ -375,9 +375,13 @@ module.exports = React.createClass({ stickyHeader.style.top = null; } }); + // Adjust the scroll to take account of stuck headers + if (scrollToPosition !== undefined) { + scrollArea.scrollTop -= scrollStuckOffset; + } }, - _updateStickyHeaders: function(e, initialise) { + _updateStickyHeaders: function(initialise, scrollToPosition) { var self = this; if (initialise) { @@ -385,10 +389,10 @@ module.exports = React.createClass({ // of the newly rendered object as using requestAnimationFrame caused // artefacts to appear on screen briefly window.setTimeout(function() { - self._initAndPositionStickyHeaders(e, initialise); + self._initAndPositionStickyHeaders(initialise, scrollToPosition); }); } else { - this._initAndPositionStickyHeaders(e, initialise); + this._initAndPositionStickyHeaders(initialise, scrollToPosition); } }, From 5f9c794f0cb4d41b8b98120a2edda2ee16d25ea5 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Fri, 26 Aug 2016 15:36:16 +0100 Subject: [PATCH 11/20] Tweaking autoscroll to only adjust if header stuck at top and not at bottom --- src/components/views/rooms/RoomList.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index a020a168d8..1c507e6629 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -354,15 +354,14 @@ module.exports = React.createClass({ var topStuckHeight = stickyHeight * i; var bottomStuckHeight = stickyHeight * (stickyWrappers.length - i) - if (scrollToPosition !== undefined && stickyPosition === scrollToPosition) { - scrollStuckOffset = topStuckHeight; - } - if (self.scrollAreaSufficient && stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { // Top stickies sticky.dataset.stuck = "top"; stickyHeader.classList.add("mx_RoomSubList_fixed"); stickyHeader.style.top = scrollArea.offsetTop + topStuckHeight + "px"; + if (scrollToPosition !== undefined && stickyPosition === scrollToPosition) { + scrollStuckOffset = topStuckHeight; + } } else if (self.scrollAreaSufficient && stickyPosition >= ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { /// Bottom stickies sticky.dataset.stuck = "bottom"; From 8ccb1d482a1cc58a18301ffe5b2a128f56a83a8f Mon Sep 17 00:00:00 2001 From: wmwragg Date: Fri, 26 Aug 2016 15:52:57 +0100 Subject: [PATCH 12/20] Better comments, and adjusted the top sticky logic, so that the very top header isn't allways stuck --- src/components/views/rooms/RoomList.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 1c507e6629..48f4b4084f 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -323,10 +323,13 @@ module.exports = React.createClass({ var scrollAreaHeight = scrollArea.getBoundingClientRect().height; if (initialise) { + // Get a collection of sticky header containers var stickies = document.getElementsByClassName("mx_RoomSubList_labelContainer"); + // Make sure there is sufficient space to do sticky headers this.scrollAreaSufficient = (120 + (stickies[0].getBoundingClientRect().height * stickies.length)) < scrollAreaHeight; + // Initialise the sticky headers if (this.scrollAreaSufficient) { if (typeof stickies === "object" && stickies.length > 0) { // Initialise the sticky headers @@ -344,9 +347,11 @@ module.exports = React.createClass({ var self = this; var scrollStuckOffset = 0; + // Scroll to the passed in position if (scrollToPosition !== undefined) { scrollArea.scrollTop = scrollToPosition; } + // Stick headers to top and bottom, or free them Array.prototype.forEach.call(this.stickyWrappers, function(sticky, i, stickyWrappers) { var stickyPosition = sticky.dataset.originalPosition; var stickyHeight = sticky.dataset.originalHeight; @@ -354,11 +359,12 @@ module.exports = React.createClass({ var topStuckHeight = stickyHeight * i; var bottomStuckHeight = stickyHeight * (stickyWrappers.length - i) - if (self.scrollAreaSufficient && stickyPosition <= (scrollArea.scrollTop + topStuckHeight)) { + if (self.scrollAreaSufficient && stickyPosition < (scrollArea.scrollTop + topStuckHeight)) { // Top stickies sticky.dataset.stuck = "top"; stickyHeader.classList.add("mx_RoomSubList_fixed"); stickyHeader.style.top = scrollArea.offsetTop + topStuckHeight + "px"; + // If stuck at top adjust the scroll back down to take account of all the stuck headers if (scrollToPosition !== undefined && stickyPosition === scrollToPosition) { scrollStuckOffset = topStuckHeight; } @@ -374,7 +380,7 @@ module.exports = React.createClass({ stickyHeader.style.top = null; } }); - // Adjust the scroll to take account of stuck headers + // Adjust the scroll to take account of top stuck headers if (scrollToPosition !== undefined) { scrollArea.scrollTop -= scrollStuckOffset; } From 73dd05b01d7cc2981882e940442fa3da34b7d296 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Fri, 26 Aug 2016 18:31:02 +0100 Subject: [PATCH 13/20] Corrected incorrect offset from top of window for the scrollArea --- src/components/views/rooms/RoomList.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 48f4b4084f..78f0587d1c 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -320,6 +320,7 @@ module.exports = React.createClass({ _initAndPositionStickyHeaders: function(initialise, scrollToPosition) { var scrollArea = this._getScrollNode(); + var scrollAreaOffset = scrollArea.getBoundingClientRect().top; var scrollAreaHeight = scrollArea.getBoundingClientRect().height; if (initialise) { @@ -334,7 +335,7 @@ module.exports = React.createClass({ if (typeof stickies === "object" && stickies.length > 0) { // Initialise the sticky headers this.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { - sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; + sticky.dataset.originalPosition = sticky.offsetTop - scrollAreaOffset; var originalHeight = sticky.getBoundingClientRect().height; sticky.dataset.originalHeight = originalHeight; sticky.style.height = originalHeight; @@ -363,7 +364,7 @@ module.exports = React.createClass({ // Top stickies sticky.dataset.stuck = "top"; stickyHeader.classList.add("mx_RoomSubList_fixed"); - stickyHeader.style.top = scrollArea.offsetTop + topStuckHeight + "px"; + stickyHeader.style.top = scrollAreaOffset + topStuckHeight + "px"; // If stuck at top adjust the scroll back down to take account of all the stuck headers if (scrollToPosition !== undefined && stickyPosition === scrollToPosition) { scrollStuckOffset = topStuckHeight; @@ -372,7 +373,7 @@ module.exports = React.createClass({ /// Bottom stickies sticky.dataset.stuck = "bottom"; stickyHeader.classList.add("mx_RoomSubList_fixed"); - stickyHeader.style.top = (scrollArea.offsetTop + scrollAreaHeight) - bottomStuckHeight + "px"; + stickyHeader.style.top = (scrollAreaOffset + scrollAreaHeight) - bottomStuckHeight + "px"; } else { // Not sticky sticky.dataset.stuck = "none"; From 7631539584a963793501011bd3489838047f2758 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Sun, 28 Aug 2016 11:39:47 +0100 Subject: [PATCH 14/20] Fixed incorrect init calculation of originalPosition attribute --- src/components/views/rooms/RoomList.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 78f0587d1c..9f10d51d82 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -320,6 +320,8 @@ module.exports = React.createClass({ _initAndPositionStickyHeaders: function(initialise, scrollToPosition) { var scrollArea = this._getScrollNode(); + // Use the offset of the top of the scroll area from the window + // as this is used to calculate the CSS fixed top position for the stickies var scrollAreaOffset = scrollArea.getBoundingClientRect().top; var scrollAreaHeight = scrollArea.getBoundingClientRect().height; @@ -335,7 +337,11 @@ module.exports = React.createClass({ if (typeof stickies === "object" && stickies.length > 0) { // Initialise the sticky headers this.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { - sticky.dataset.originalPosition = sticky.offsetTop - scrollAreaOffset; + // Save the positions of all the stickies within scroll area. + // These positions are relative to the LHS Panel top + sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; + + // Save and set the sticky heights var originalHeight = sticky.getBoundingClientRect().height; sticky.dataset.originalHeight = originalHeight; sticky.style.height = originalHeight; From 8f7d3394e668e8e51617e3e1627883508ec00f8a Mon Sep 17 00:00:00 2001 From: wmwragg Date: Sun, 28 Aug 2016 12:02:20 +0100 Subject: [PATCH 15/20] Always setup stickies, even if we aren't going to use them so that the following map can fire --- src/components/views/rooms/RoomList.js | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 9f10d51d82..96db9dd853 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -333,22 +333,20 @@ module.exports = React.createClass({ this.scrollAreaSufficient = (120 + (stickies[0].getBoundingClientRect().height * stickies.length)) < scrollAreaHeight; // Initialise the sticky headers - if (this.scrollAreaSufficient) { - if (typeof stickies === "object" && stickies.length > 0) { - // Initialise the sticky headers - this.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { - // Save the positions of all the stickies within scroll area. - // These positions are relative to the LHS Panel top - sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; + if (typeof stickies === "object" && stickies.length > 0) { + // Initialise the sticky headers + this.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { + // Save the positions of all the stickies within scroll area. + // These positions are relative to the LHS Panel top + sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; - // Save and set the sticky heights - var originalHeight = sticky.getBoundingClientRect().height; - sticky.dataset.originalHeight = originalHeight; - sticky.style.height = originalHeight; + // Save and set the sticky heights + var originalHeight = sticky.getBoundingClientRect().height; + sticky.dataset.originalHeight = originalHeight; + sticky.style.height = originalHeight; - return sticky; - }); - } + return sticky; + }); } } From 123d9b56c8a01e2818d088142c05910c220175a4 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Sun, 28 Aug 2016 16:25:20 +0100 Subject: [PATCH 16/20] calculating the scrollAreaHeight correctly taking into account the different scroll methods available on macOSX, i.e. System Preferences>General>Show Scroll Bars --- src/components/views/rooms/RoomList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 96db9dd853..f386cd1e6b 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -323,7 +323,7 @@ module.exports = React.createClass({ // Use the offset of the top of the scroll area from the window // as this is used to calculate the CSS fixed top position for the stickies var scrollAreaOffset = scrollArea.getBoundingClientRect().top; - var scrollAreaHeight = scrollArea.getBoundingClientRect().height; + var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height; if (initialise) { // Get a collection of sticky header containers From 2b1ed707c4009d9d52bdf04d4a076791da9e80b3 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Sun, 28 Aug 2016 19:18:41 +0100 Subject: [PATCH 17/20] Better comments, and correct bottom header sticky calc to allow clicking --- src/components/views/rooms/RoomList.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index f386cd1e6b..7fce16bc54 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -323,6 +323,8 @@ module.exports = React.createClass({ // Use the offset of the top of the scroll area from the window // as this is used to calculate the CSS fixed top position for the stickies var scrollAreaOffset = scrollArea.getBoundingClientRect().top; + // Use the offset of the top of the componet from the window + // as this is used to calculate the CSS fixed top position for the stickies var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height; if (initialise) { @@ -352,7 +354,8 @@ module.exports = React.createClass({ var self = this; var scrollStuckOffset = 0; - // Scroll to the passed in position + // Scroll to the passed in position, i.e. a header was clicked and in a scroll to state + // rather than a collapsable one (see RoomSubList.isCollapsableOnClick method for details) if (scrollToPosition !== undefined) { scrollArea.scrollTop = scrollToPosition; } @@ -373,7 +376,7 @@ module.exports = React.createClass({ if (scrollToPosition !== undefined && stickyPosition === scrollToPosition) { scrollStuckOffset = topStuckHeight; } - } else if (self.scrollAreaSufficient && stickyPosition >= ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { + } else if (self.scrollAreaSufficient && stickyPosition > ((scrollArea.scrollTop + scrollAreaHeight) - bottomStuckHeight)) { /// Bottom stickies sticky.dataset.stuck = "bottom"; stickyHeader.classList.add("mx_RoomSubList_fixed"); From 83c4fd4b2f1f1bfd0f370418eee8d2c4fcf2abf6 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Tue, 30 Aug 2016 10:45:17 +0100 Subject: [PATCH 18/20] Code clean up, and better comments --- src/components/views/rooms/RoomList.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 7fce16bc54..abb785fcc9 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -318,6 +318,8 @@ module.exports = React.createClass({ } }, + // Doing the stckiy headers as raw DOM, for speed, as it gets very stuttery if done + // properly through React _initAndPositionStickyHeaders: function(initialise, scrollToPosition) { var scrollArea = this._getScrollNode(); // Use the offset of the top of the scroll area from the window @@ -328,16 +330,16 @@ module.exports = React.createClass({ var scrollAreaHeight = ReactDOM.findDOMNode(this).getBoundingClientRect().height; if (initialise) { - // Get a collection of sticky header containers - var stickies = document.getElementsByClassName("mx_RoomSubList_labelContainer"); + // Get a collection of sticky header containers references + this.stickies = document.getElementsByClassName("mx_RoomSubList_labelContainer"); // Make sure there is sufficient space to do sticky headers - this.scrollAreaSufficient = (120 + (stickies[0].getBoundingClientRect().height * stickies.length)) < scrollAreaHeight; + this.scrollAreaSufficient = (120 + (this.stickies[0].getBoundingClientRect().height * this.stickies.length)) < scrollAreaHeight; // Initialise the sticky headers - if (typeof stickies === "object" && stickies.length > 0) { + if (typeof this.stickies === "object" && this.stickies.length > 0) { // Initialise the sticky headers - this.stickyWrappers = Array.prototype.map.call(stickies, function(sticky, i) { + Array.prototype.forEach.call(this.stickies, function(sticky, i) { // Save the positions of all the stickies within scroll area. // These positions are relative to the LHS Panel top sticky.dataset.originalPosition = sticky.offsetTop - scrollArea.offsetTop; @@ -360,7 +362,7 @@ module.exports = React.createClass({ scrollArea.scrollTop = scrollToPosition; } // Stick headers to top and bottom, or free them - Array.prototype.forEach.call(this.stickyWrappers, function(sticky, i, stickyWrappers) { + Array.prototype.forEach.call(this.stickies, function(sticky, i, stickyWrappers) { var stickyPosition = sticky.dataset.originalPosition; var stickyHeight = sticky.dataset.originalHeight; var stickyHeader = sticky.childNodes[0]; From 8061a2f279fcedad7956c6d9332e64494edf28d9 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Tue, 30 Aug 2016 11:55:51 +0100 Subject: [PATCH 19/20] Fixed historical scetion not scrolling up when clicked if not hidden and stuck --- src/components/views/rooms/RoomList.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index abb785fcc9..09d430de5e 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -121,10 +121,14 @@ module.exports = React.createClass({ this._delayedRefreshRoomList(); }, - onArchivedHeaderClick: function(isHidden) { + onArchivedHeaderClick: function(isHidden, scrollToPosition) { if (!isHidden) { var self = this; this.setState({ isLoadingLeftRooms: true }); + + // Try scrolling to position + this._updateStickyHeaders(true, scrollToPosition); + // we don't care about the response since it comes down via "Room" // events. MatrixClientPeg.get().syncLeftRooms().catch(function(err) { From c30ff57c6288a0251b63207f49500c6b68522b70 Mon Sep 17 00:00:00 2001 From: wmwragg Date: Tue, 30 Aug 2016 12:29:25 +0100 Subject: [PATCH 20/20] Better comments --- src/components/views/rooms/RoomList.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 09d430de5e..8bde9f2ace 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -64,12 +64,12 @@ module.exports = React.createClass({ componentDidMount: function() { this.dispatcherRef = dis.register(this.onAction); - // Initilaise the stickyHeaders when the component is created + // Initialise the stickyHeaders when the component is created this._updateStickyHeaders(true); }, componentDidUpdate: function() { - // Reinitilaise the stickyHeaders when the component is updated + // Reinitialise the stickyHeaders when the component is updated this._updateStickyHeaders(true); }, @@ -322,7 +322,7 @@ module.exports = React.createClass({ } }, - // Doing the stckiy headers as raw DOM, for speed, as it gets very stuttery if done + // Doing the sticky headers as raw DOM, for speed, as it gets very stuttery if done // properly through React _initAndPositionStickyHeaders: function(initialise, scrollToPosition) { var scrollArea = this._getScrollNode(); @@ -337,7 +337,7 @@ module.exports = React.createClass({ // Get a collection of sticky header containers references this.stickies = document.getElementsByClassName("mx_RoomSubList_labelContainer"); - // Make sure there is sufficient space to do sticky headers + // Make sure there is sufficient space to do sticky headers: 120px plus all the sticky headers this.scrollAreaSufficient = (120 + (this.stickies[0].getBoundingClientRect().height * this.stickies.length)) < scrollAreaHeight; // Initialise the sticky headers