mirror of https://github.com/vector-im/riot-web
Remove legacy resizing code
parent
1cce6e2e32
commit
52219a8341
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
Copyright 2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
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.
|
||||
*/
|
||||
|
||||
import Sizer from "../sizer";
|
||||
import ResizeItem from "../item";
|
||||
|
||||
class RoomSizer extends Sizer {
|
||||
setItemSize(item, size) {
|
||||
item.style.maxHeight = `${Math.round(size)}px`;
|
||||
item.classList.add("resized-sized");
|
||||
}
|
||||
|
||||
clearItemSize(item) {
|
||||
item.style.maxHeight = null;
|
||||
item.classList.remove("resized-sized");
|
||||
}
|
||||
}
|
||||
|
||||
class RoomSubListItem extends ResizeItem {
|
||||
isCollapsed() {
|
||||
return this.domNode.classList.contains("mx_RoomSubList_hidden");
|
||||
}
|
||||
|
||||
maxSize() {
|
||||
const header = this.domNode.querySelector(".mx_RoomSubList_labelContainer");
|
||||
const scrollItem = this.domNode.querySelector(".mx_RoomSubList_scroll");
|
||||
const headerHeight = this.sizer.getItemSize(header);
|
||||
return headerHeight + (scrollItem ? scrollItem.scrollHeight : 0);
|
||||
}
|
||||
|
||||
minSize() {
|
||||
const isNotEmpty = this.domNode.classList.contains("mx_RoomSubList_nonEmpty");
|
||||
return isNotEmpty ? 74 : 31; //size of header + 1? room tile (see room sub list css)
|
||||
}
|
||||
|
||||
isSized() {
|
||||
return this.domNode.classList.contains("resized-sized");
|
||||
}
|
||||
}
|
||||
|
||||
export default class RoomSubListDistributor {
|
||||
static createItem(resizeHandle, resizer, sizer) {
|
||||
return new RoomSubListItem(resizeHandle, resizer, sizer);
|
||||
}
|
||||
|
||||
static createSizer(containerElement, vertical, reverse) {
|
||||
return new RoomSizer(containerElement, vertical, reverse);
|
||||
}
|
||||
|
||||
constructor(item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
_handleSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
resize(size) {
|
||||
//console.log("*** starting resize session with size", size);
|
||||
let item = this.item;
|
||||
while (item) {
|
||||
const minSize = item.minSize();
|
||||
if (item.isCollapsed()) {
|
||||
item = item.previous();
|
||||
} else if (size <= minSize) {
|
||||
//console.log(" - resizing", item.id, "to min size", minSize);
|
||||
item.setSize(minSize);
|
||||
const remainder = minSize - size;
|
||||
item = item.previous();
|
||||
if (item) {
|
||||
size = item.size() - remainder - this._handleSize();
|
||||
}
|
||||
} else {
|
||||
const maxSize = item.maxSize();
|
||||
if (size > maxSize) {
|
||||
// console.log(" - resizing", item.id, "to maxSize", maxSize);
|
||||
item.setSize(maxSize);
|
||||
const remainder = size - maxSize;
|
||||
item = item.previous();
|
||||
if (item) {
|
||||
size = item.size() + remainder; // todo: handle size here?
|
||||
}
|
||||
} else {
|
||||
//console.log(" - resizing", item.id, "to size", size);
|
||||
item.setSize(size);
|
||||
item = null;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log("*** ending resize session");
|
||||
}
|
||||
|
||||
resizeFromContainerOffset(containerOffset) {
|
||||
this.resize(containerOffset - this.item.offset());
|
||||
}
|
||||
|
||||
start() {
|
||||
// set all max-height props to the actual height.
|
||||
let item = this.item.first();
|
||||
const sizes = [];
|
||||
while (item) {
|
||||
if (!item.isCollapsed()) {
|
||||
sizes.push(item.size());
|
||||
} else {
|
||||
sizes.push(100);
|
||||
}
|
||||
item = item.next();
|
||||
}
|
||||
item = this.item.first();
|
||||
sizes.forEach((size) => {
|
||||
item.setSize(size);
|
||||
item = item.next();
|
||||
});
|
||||
}
|
||||
|
||||
finish() {
|
||||
}
|
||||
}
|
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
Copyright 2019 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
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.
|
||||
*/
|
||||
|
||||
import FixedDistributor from "./fixed";
|
||||
|
||||
function clamp(height, min, max) {
|
||||
if (height > max) return max;
|
||||
if (height < min) return min;
|
||||
return height;
|
||||
}
|
||||
|
||||
export class Layout {
|
||||
constructor(applyHeight, initialSizes, collapsedState, options) {
|
||||
// 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);
|
||||
// in-progress heights, while dragging. Committed on mouse-up.
|
||||
this._heights = [];
|
||||
// use while manually resizing to cancel
|
||||
// the resize for a given mouse position
|
||||
// when the previous resize made the layout
|
||||
// constrained
|
||||
this._clampedOffset = 0;
|
||||
// used while manually resizing, to clear
|
||||
// _clampedOffset when the direction of resizing changes
|
||||
this._lastOffset = 0;
|
||||
|
||||
this._allowWhitespace = options && options.allowWhitespace;
|
||||
this._handleHeight = (options && options.handleHeight) || 0;
|
||||
}
|
||||
|
||||
setAvailableHeight(newSize) {
|
||||
this._availableHeight = newSize;
|
||||
// needs more work
|
||||
this._applyNewSize();
|
||||
}
|
||||
|
||||
expandSection(id, height) {
|
||||
this._collapsedState[id] = false;
|
||||
this._applyNewSize();
|
||||
this.openHandle(id).setHeight(height).finish();
|
||||
}
|
||||
|
||||
collapseSection(id) {
|
||||
this._collapsedState[id] = true;
|
||||
this._applyNewSize();
|
||||
}
|
||||
|
||||
update(sections, availableHeight, force = false) {
|
||||
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 && !force) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._sections = sections;
|
||||
const totalHeight = this._getAvailableHeight();
|
||||
const defaultHeight = Math.floor(totalHeight / this._sections.length);
|
||||
this._sections.forEach((section, i) => {
|
||||
if (!this._sectionHeights[section.id]) {
|
||||
this._sectionHeights[section.id] = clamp(
|
||||
defaultHeight,
|
||||
this._getMinHeight(i),
|
||||
this._getMaxHeight(i),
|
||||
);
|
||||
}
|
||||
});
|
||||
this._applyNewSize();
|
||||
}
|
||||
|
||||
openHandle(id) {
|
||||
const index = this._getSectionIndex(id);
|
||||
return new Handle(this, index, this._sectionHeights[id]);
|
||||
}
|
||||
|
||||
_getAvailableHeight() {
|
||||
const nonCollapsedSectionCount = this._sections.reduce((count, section) => {
|
||||
const collapsed = this._collapsedState[section.id];
|
||||
return count + (collapsed ? 0 : 1);
|
||||
}, 0);
|
||||
return this._availableHeight - ((nonCollapsedSectionCount - 1) * this._handleHeight);
|
||||
}
|
||||
|
||||
_applyNewSize() {
|
||||
const newHeight = this._getAvailableHeight();
|
||||
const currHeight = this._sections.reduce((sum, section) => {
|
||||
return sum + this._sectionHeights[section.id];
|
||||
}, 0);
|
||||
const offset = newHeight - currHeight;
|
||||
this._heights = this._sections.map((section) => this._sectionHeights[section.id]);
|
||||
const sections = this._sections.map((_, i) => i);
|
||||
this._applyOverflow(-offset, sections, true);
|
||||
this._applyHeights();
|
||||
this._commitHeights();
|
||||
}
|
||||
|
||||
_getSectionIndex(id) {
|
||||
return this._sections.findIndex((s) => s.id === id);
|
||||
}
|
||||
|
||||
_getMaxHeight(i) {
|
||||
const section = this._sections[i];
|
||||
const collapsed = this._collapsedState[section.id];
|
||||
|
||||
if (collapsed) {
|
||||
return this._sectionHeight(0);
|
||||
} else if (!this._allowWhitespace) {
|
||||
return this._sectionHeight(section.count);
|
||||
} else {
|
||||
return 100000;
|
||||
}
|
||||
}
|
||||
|
||||
_sectionHeight(count) {
|
||||
return 36 + (count === 0 ? 0 : 4 + (count * 34));
|
||||
}
|
||||
|
||||
_getMinHeight(i) {
|
||||
const section = this._sections[i];
|
||||
const collapsed = this._collapsedState[section.id];
|
||||
const maxItems = collapsed ? 0 : 1;
|
||||
return this._sectionHeight(Math.min(section.count, maxItems));
|
||||
}
|
||||
|
||||
_applyOverflow(overflow, sections, blend) {
|
||||
// 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.
|
||||
|
||||
const unclampedSections = [];
|
||||
|
||||
let overflowPerSection = blend ? (overflow / sections.length) : overflow;
|
||||
for (const i of sections) {
|
||||
const newHeight = clamp(
|
||||
this._heights[i] - overflowPerSection,
|
||||
this._getMinHeight(i),
|
||||
this._getMaxHeight(i),
|
||||
);
|
||||
if (newHeight == this._heights[i] - overflowPerSection) {
|
||||
unclampedSections.push(i);
|
||||
}
|
||||
// when section is growing, overflow increases?
|
||||
// 100 -= 200 - 300
|
||||
// 100 -= -100
|
||||
// 200
|
||||
overflow -= this._heights[i] - newHeight;
|
||||
this._heights[i] = newHeight;
|
||||
if (!blend) {
|
||||
overflowPerSection = overflow;
|
||||
if (Math.abs(overflow) < 1.0) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Math.abs(overflow) > 1.0 && unclampedSections.length > 0) {
|
||||
// we weren't able to distribute all the overflow so recurse and try again
|
||||
overflow = this._applyOverflow(overflow, unclampedSections, blend);
|
||||
}
|
||||
|
||||
return overflow;
|
||||
}
|
||||
|
||||
_rebalanceAbove(sectionIndex, overflowAbove) {
|
||||
if (Math.abs(overflowAbove) > 1.0) {
|
||||
const sections = [];
|
||||
for (let i = sectionIndex - 1; i >= 0; i--) {
|
||||
sections.push(i);
|
||||
}
|
||||
overflowAbove = this._applyOverflow(overflowAbove, sections);
|
||||
}
|
||||
return overflowAbove;
|
||||
}
|
||||
|
||||
_rebalanceBelow(sectionIndex, overflowBelow) {
|
||||
if (Math.abs(overflowBelow) > 1.0) {
|
||||
const sections = [];
|
||||
for (let i = sectionIndex + 1; i < this._sections.length; i++) {
|
||||
sections.push(i);
|
||||
}
|
||||
overflowBelow = this._applyOverflow(overflowBelow, sections);
|
||||
}
|
||||
return overflowBelow;
|
||||
}
|
||||
|
||||
// @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(sectionIndex);
|
||||
const minHeight = this._getMinHeight(sectionIndex);
|
||||
// new height > max ?
|
||||
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;
|
||||
} else if (this._heights[sectionIndex] + offset < minHeight) { // new height < min?
|
||||
// we're pulling upwards and constrained
|
||||
overflowAbove = (minHeight - this._heights[sectionIndex]) - offset;
|
||||
overflowBelow = offset;
|
||||
} else {
|
||||
overflowAbove = 0;
|
||||
overflowBelow = offset;
|
||||
}
|
||||
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(sectionIndex, overflowAbove);
|
||||
overflowBelow = this._rebalanceBelow(sectionIndex, overflowBelow);
|
||||
|
||||
if (!constrained) { // to avoid risk of infinite recursion
|
||||
// clamp to avoid overflowing or underflowing the page
|
||||
if (Math.abs(overflowAbove) > 1.0) {
|
||||
// here we do the layout again with offset - the amount of space we took too much
|
||||
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
|
||||
this._relayout(sectionIndex, offset - overflowBelow, true);
|
||||
return offset - overflowBelow;
|
||||
}
|
||||
}
|
||||
|
||||
this._applyHeights();
|
||||
return undefined;
|
||||
}
|
||||
|
||||
_applyHeights() {
|
||||
// apply the heights
|
||||
for (let i = 0; i < this._sections.length; i++) {
|
||||
const section = this._sections[i];
|
||||
this._applyHeight(section.id, this._heights[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_commitHeights() {
|
||||
this._sections.forEach((section, i) => {
|
||||
this._sectionHeights[section.id] = this._heights[i];
|
||||
});
|
||||
}
|
||||
|
||||
_setUncommittedSectionHeight(sectionIndex, offset) {
|
||||
if (Math.sign(offset) != Math.sign(this._lastOffset)) {
|
||||
this._clampedOffset = undefined;
|
||||
}
|
||||
if (this._clampedOffset !== undefined) {
|
||||
if (offset < 0 && offset < this._clampedOffset) {
|
||||
return;
|
||||
}
|
||||
if (offset > 0 && offset > this._clampedOffset) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._clampedOffset = this._relayout(sectionIndex, offset);
|
||||
this._lastOffset = offset;
|
||||
}
|
||||
}
|
||||
|
||||
class Handle {
|
||||
constructor(layout, sectionIndex, height) {
|
||||
this._layout = layout;
|
||||
this._sectionIndex = sectionIndex;
|
||||
this._initialHeight = height;
|
||||
}
|
||||
|
||||
setHeight(height) {
|
||||
this._layout._setUncommittedSectionHeight(
|
||||
this._sectionIndex,
|
||||
height - this._initialHeight,
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
finish() {
|
||||
this._layout._commitHeights();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class Distributor extends FixedDistributor {
|
||||
constructor(item, cfg) {
|
||||
super(item);
|
||||
this._handle = cfg.getLayout().openHandle(item.id);
|
||||
}
|
||||
|
||||
finish() {
|
||||
this._handle.finish();
|
||||
}
|
||||
|
||||
resize(height) {
|
||||
this._handle.setHeight(height);
|
||||
}
|
||||
}
|
|
@ -17,5 +17,4 @@ limitations under the License.
|
|||
|
||||
export FixedDistributor from "./distributors/fixed";
|
||||
export CollapseDistributor from "./distributors/collapse";
|
||||
export RoomSubListDistributor from "./distributors/roomsublist";
|
||||
export Resizer from "./resizer";
|
||||
|
|
Loading…
Reference in New Issue