diff --git a/res/css/views/rooms/_RoomList.scss b/res/css/views/rooms/_RoomList.scss index 360966a952..886f10dc4c 100644 --- a/res/css/views/rooms/_RoomList.scss +++ b/res/css/views/rooms/_RoomList.scss @@ -19,9 +19,11 @@ limitations under the License. /* take up remaining space below TopLeftMenu */ flex: 1; min-height: 0; + overflow-y: hidden; } .mx_RoomList .mx_ResizeHandle { + // needed so the z-index takes effect position: relative; } diff --git a/src/resizer/distributors/roomsublist2.js b/src/resizer/distributors/roomsublist2.js index 5d291e1516..d6bf8d6c7a 100644 --- a/src/resizer/distributors/roomsublist2.js +++ b/src/resizer/distributors/roomsublist2.js @@ -19,11 +19,7 @@ import FixedDistributor from "./fixed"; // const allowWhitespace = true; const handleHeight = 1; -function log() { -} - function clamp(height, min, max) { - //log(`clamping ${height} between ${min} and ${max}`); if (height > max) return max; if (height < min) return min; return height; @@ -31,9 +27,15 @@ function clamp(height, min, max) { export class Layout { constructor(applyHeight, initialSizes, collapsedState) { + // callback to set height of section this._applyHeight = applyHeight; + // list of {id, count} objects, + // determines sections and order of them this._sections = []; + // stores collapsed by id this._collapsedState = Object.assign({}, collapsedState); + // total available height to the layout + // (including resize handles, ...) this._availableHeight = 0; // heights stored by section section id this._sectionHeights = Object.assign({}, initialSizes); @@ -58,28 +60,42 @@ export class Layout { this._applyNewSize(); } - // [{id, count}] update(sections, availableHeight) { - if (Number.isFinite(availableHeight)) { + let heightChanged = false; + + if (Number.isFinite(availableHeight) && availableHeight !== this._availableHeight) { + heightChanged = true; this._availableHeight = availableHeight; } + + const sectionsChanged = + sections.length !== this._sections.length || + sections.some((a, i) => { + const b = this._sections[i]; + return a.id !== b.id || a.count !== b.count; + }); + + if (!heightChanged && !sectionsChanged) { + return; + } + + this._sections = sections; const totalHeight = this._getAvailableHeight(); + const defaultHeight = Math.floor(totalHeight / this._sections.length); this._sections.forEach((section, i) => { - if (!this._sectionHeights.hasOwnProperty(section.id)) { + if (!this._sectionHeights[section.id]) { this._sectionHeights[section.id] = clamp( - totalHeight / this._sections.length, + defaultHeight, this._getMinHeight(i), this._getMaxHeight(i), ); } }); - this._sections = sections; this._applyNewSize(); } openHandle(id) { const index = this._getSectionIndex(id); - //log(`openHandle resolved ${id} to ${index}`); return new Handle(this, index, this._sectionHeights[id]); } @@ -128,12 +144,10 @@ export class Layout { const section = this._sections[i]; const collapsed = this._collapsedState[section.id]; const maxItems = collapsed ? 0 : 1; - // log("_getMinHeight", i, section); return this._sectionHeight(Math.min(section.count, maxItems)); } _applyOverflow(overflow, sections, blend) { - //log("applyOverflow", overflow, sections); // take the given overflow amount, and applies it to the given sections. // calls itself recursively until it has distributed all the overflow // or run out of unclamped sections. @@ -155,10 +169,7 @@ export class Layout { // 100 -= -100 // 200 overflow -= this._heights[i] - newHeight; - // console.log(`this._heights[${i}] (${this._heights[i]}) - newHeight (${newHeight}) = ${this._heights[i] - newHeight}`); - // console.log(`changing ${this._heights[i]} to ${newHeight}`); this._heights[i] = newHeight; - // console.log(`for section ${i} overflow is ${overflow}`); if (!blend) { overflowPerSection = overflow; if (Math.abs(overflow) < 1.0) break; @@ -167,18 +178,16 @@ export class Layout { if (Math.abs(overflow) > 1.0 && unclampedSections.length > 0) { // we weren't able to distribute all the overflow so recurse and try again - // log("recursing with", overflow, unclampedSections); overflow = this._applyOverflow(overflow, unclampedSections, blend); } return overflow; } - _rebalanceAbove(anchor, overflowAbove) { + _rebalanceAbove(sectionIndex, overflowAbove) { if (Math.abs(overflowAbove) > 1.0) { - // log(`trying to rebalance upstream with ${overflowAbove}`); const sections = []; - for (let i = anchor - 1; i >= 0; i--) { + for (let i = sectionIndex - 1; i >= 0; i--) { sections.push(i); } overflowAbove = this._applyOverflow(overflowAbove, sections); @@ -186,66 +195,58 @@ export class Layout { return overflowAbove; } - _rebalanceBelow(anchor, overflowBelow) { + _rebalanceBelow(sectionIndex, overflowBelow) { if (Math.abs(overflowBelow) > 1.0) { - // log(`trying to rebalance downstream with ${overflowBelow}`); const sections = []; - for (let i = anchor + 1; i < this._sections.length; i++) { + for (let i = sectionIndex + 1; i < this._sections.length; i++) { sections.push(i); } overflowBelow = this._applyOverflow(overflowBelow, sections); - //log(`rebalanced downstream with ${overflowBelow}`); } return overflowBelow; } - // @param offset the amount the anchor is moved from what is stored in _sectionHeights, positive if downwards - // if we're clamped, return the offset we should be clamped at. - _relayout(anchor = 0, offset = 0, clamped = false) { + // @param offset the amount the sectionIndex is moved from what is stored in _sectionHeights, positive if downwards + // if we're constrained, return the offset we should be constrained at. + _relayout(sectionIndex = 0, offset = 0, constrained = false) { this._heights = this._sections.map((section) => this._sectionHeights[section.id]); // are these the amounts the items above/below shrank/grew and need to be relayouted? let overflowAbove; let overflowBelow; - const maxHeight = this._getMaxHeight(anchor); - const minHeight = this._getMinHeight(anchor); + const maxHeight = this._getMaxHeight(sectionIndex); + const minHeight = this._getMinHeight(sectionIndex); // new height > max ? - if (this._heights[anchor] + offset > maxHeight) { - // we're pulling downwards and clamped - // overflowAbove = minus how much are we above max height? - overflowAbove = (maxHeight - this._heights[anchor]) - offset; + if (this._heights[sectionIndex] + offset > maxHeight) { + // we're pulling downwards and constrained + // overflowAbove = minus how much are we above max height + overflowAbove = (maxHeight - this._heights[sectionIndex]) - offset; overflowBelow = offset; - // log(`pulling downwards clamped at max: ${overflowAbove} ${overflowBelow}`); - } else if (this._heights[anchor] + offset < minHeight) { // new height < min? - // we're pulling upwards and clamped - // overflowAbove = ??? (offset is negative here, so - offset will add) - overflowAbove = (minHeight - this._heights[anchor]) - offset; + } else if (this._heights[sectionIndex] + offset < minHeight) { // new height < min? + // we're pulling upwards and constrained + overflowAbove = (minHeight - this._heights[sectionIndex]) - offset; overflowBelow = offset; - // log(`pulling upwards clamped at min: ${overflowAbove} ${overflowBelow}`); } else { overflowAbove = 0; overflowBelow = offset; - // log(`resizing the anchor: ${overflowAbove} ${overflowBelow}`); } - this._heights[anchor] = clamp(this._heights[anchor] + offset, minHeight, maxHeight); + this._heights[sectionIndex] = clamp(this._heights[sectionIndex] + offset, minHeight, maxHeight); // these are reassigned the amount of overflow that could not be rebalanced // meaning we dragged the handle too far and it can't follow the cursor anymore - overflowAbove = this._rebalanceAbove(anchor, overflowAbove); - overflowBelow = this._rebalanceBelow(anchor, overflowBelow); + overflowAbove = this._rebalanceAbove(sectionIndex, overflowAbove); + overflowBelow = this._rebalanceBelow(sectionIndex, overflowBelow); - if (!clamped) { // to avoid risk of infinite recursion + if (!constrained) { // to avoid risk of infinite recursion // clamp to avoid overflowing or underflowing the page if (Math.abs(overflowAbove) > 1.0) { - // log(`clamping with overflowAbove ${overflowAbove}`); // here we do the layout again with offset - the amount of space we took too much - this._relayout(anchor, offset + overflowAbove, true); + this._relayout(sectionIndex, offset + overflowAbove, true); return offset + overflowAbove; } if (Math.abs(overflowBelow) > 1.0) { // here we do the layout again with offset - the amount of space we took too much - // log(`clamping with overflowBelow ${overflowBelow}`); - this._relayout(anchor, offset - overflowBelow, true); + this._relayout(sectionIndex, offset - overflowBelow, true); return offset - overflowBelow; } } @@ -255,7 +256,6 @@ export class Layout { } _applyHeights() { - log("updating layout, heights are now", this._heights); // apply the heights for (let i = 0; i < this._sections.length; i++) { const section = this._sections[i]; @@ -271,14 +271,14 @@ export class Layout { } class Handle { - constructor(layout, anchor, height) { + constructor(layout, sectionIndex, height) { this._layout = layout; - this._anchor = anchor; + this._sectionIndex = sectionIndex; this._initialHeight = height; } setHeight(height) { - this._layout._relayout(this._anchor, height - this._initialHeight); + this._layout._relayout(this._sectionIndex, height - this._initialHeight); return this; }