Merge pull request #2440 from matrix-org/bwindels/smarterresizer
Improve room sublist resizing
This commit is contained in:
commit
0229453482
11 changed files with 407 additions and 229 deletions
|
@ -33,13 +33,25 @@ limitations under the License.
|
|||
|
||||
.mx_RoomSubList {
|
||||
min-height: 31px;
|
||||
flex: 0 100000000 auto;
|
||||
flex: 0 10000 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.mx_RoomSubList.resized-sized {
|
||||
/*
|
||||
flex-basis to 0 so sublists
|
||||
are not shrinking/growing relative
|
||||
to their content (as would be the case with auto),
|
||||
as this intervenes with sizing an item exactly
|
||||
when not available space is available
|
||||
in the flex container
|
||||
*/
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_nonEmpty {
|
||||
min-height: 70px;
|
||||
min-height: 74px;
|
||||
|
||||
.mx_AutoHideScrollbar_offset {
|
||||
padding-bottom: 4px;
|
||||
|
@ -50,17 +62,6 @@ limitations under the License.
|
|||
flex: none !important;
|
||||
}
|
||||
|
||||
.mx_RoomSubList.resized-all {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.mx_RoomSubList.resized-sized {
|
||||
/* resizer set max-height on resized-sized,
|
||||
so that limits the height and hence
|
||||
needs a very small flex-shrink */
|
||||
flex: 0 10000 auto;
|
||||
}
|
||||
|
||||
.mx_RoomSubList_labelContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
|
@ -36,7 +36,7 @@ import GroupStore from '../../../stores/GroupStore';
|
|||
import RoomSubList from '../../structures/RoomSubList';
|
||||
import ResizeHandle from '../elements/ResizeHandle';
|
||||
|
||||
import {Resizer, RoomDistributor, RoomSizer} from '../../../resizer'
|
||||
import {Resizer, RoomSubListDistributor} from '../../../resizer'
|
||||
const HIDE_CONFERENCE_CHANS = true;
|
||||
const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority|server_notice)|im\.vector\.fake\.(invite|recent|direct|archived))$/;
|
||||
|
||||
|
@ -153,7 +153,11 @@ module.exports = React.createClass({
|
|||
if (typeof newSize === "string") {
|
||||
newSize = Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
this.subListSizes[id] = newSize;
|
||||
if (newSize === null) {
|
||||
delete this.subListSizes[id];
|
||||
} else {
|
||||
this.subListSizes[id] = newSize;
|
||||
}
|
||||
window.localStorage.setItem("mx_roomlist_sizes", JSON.stringify(this.subListSizes));
|
||||
// update overflow indicators
|
||||
this._checkSubListsOverflow();
|
||||
|
@ -164,7 +168,7 @@ module.exports = React.createClass({
|
|||
const cfg = {
|
||||
onResized: this._onSubListResize,
|
||||
};
|
||||
this.resizer = new Resizer(this.resizeContainer, RoomDistributor, cfg, RoomSizer);
|
||||
this.resizer = new Resizer(this.resizeContainer, RoomSubListDistributor, cfg);
|
||||
this.resizer.setClassNames({
|
||||
handle: "mx_ResizeHandle",
|
||||
vertical: "mx_ResizeHandle_vertical",
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
distributors translate a moving cursor into
|
||||
CSS/DOM changes by calling the sizer
|
||||
|
||||
they have two methods:
|
||||
`resize` receives then new item size
|
||||
`resizeFromContainerOffset` receives resize handle location
|
||||
within the container bounding box. For internal use.
|
||||
This method usually ends up calling `resize` once the start offset is subtracted.
|
||||
the offset from the container edge of where
|
||||
the mouse cursor is.
|
||||
*/
|
||||
class FixedDistributor {
|
||||
constructor(sizer, item, id, config) {
|
||||
this.sizer = sizer;
|
||||
this.item = item;
|
||||
this.id = id;
|
||||
this.beforeOffset = sizer.getItemOffset(this.item);
|
||||
this.onResized = config && config.onResized;
|
||||
}
|
||||
|
||||
resize(itemSize) {
|
||||
this.sizer.setItemSize(this.item, itemSize);
|
||||
if (this.onResized) {
|
||||
this.onResized(itemSize, this.id, this.item);
|
||||
}
|
||||
return itemSize;
|
||||
}
|
||||
|
||||
resizeFromContainerOffset(offset) {
|
||||
this.resize(offset - this.beforeOffset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CollapseDistributor extends FixedDistributor {
|
||||
constructor(sizer, item, id, config) {
|
||||
super(sizer, item, id, config);
|
||||
this.toggleSize = config && config.toggleSize;
|
||||
this.onCollapsed = config && config.onCollapsed;
|
||||
this.isCollapsed = false;
|
||||
}
|
||||
|
||||
resize(newSize) {
|
||||
const isCollapsedSize = newSize < this.toggleSize;
|
||||
if (isCollapsedSize && !this.isCollapsed) {
|
||||
this.isCollapsed = true;
|
||||
if (this.onCollapsed) {
|
||||
this.onCollapsed(true, this.item);
|
||||
}
|
||||
} else if (!isCollapsedSize && this.isCollapsed) {
|
||||
if (this.onCollapsed) {
|
||||
this.onCollapsed(false, this.item);
|
||||
}
|
||||
this.isCollapsed = false;
|
||||
}
|
||||
if (!isCollapsedSize) {
|
||||
super.resize(newSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
FixedDistributor,
|
||||
CollapseDistributor,
|
||||
};
|
53
src/resizer/distributors/collapse.js
Normal file
53
src/resizer/distributors/collapse.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
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";
|
||||
import ResizeItem from "../item";
|
||||
|
||||
class CollapseItem extends ResizeItem {
|
||||
notifyCollapsed(collapsed) {
|
||||
const callback = this.resizer.config.onCollapsed;
|
||||
if (callback) {
|
||||
callback(collapsed, this.id, this.domNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class CollapseDistributor extends FixedDistributor {
|
||||
static createItem(resizeHandle, resizer, sizer) {
|
||||
return new CollapseItem(resizeHandle, resizer, sizer);
|
||||
}
|
||||
|
||||
constructor(item, config) {
|
||||
super(item);
|
||||
this.toggleSize = config && config.toggleSize;
|
||||
this.isCollapsed = false;
|
||||
}
|
||||
|
||||
resize(newSize) {
|
||||
const isCollapsedSize = newSize < this.toggleSize;
|
||||
if (isCollapsedSize && !this.isCollapsed) {
|
||||
this.isCollapsed = true;
|
||||
this.item.notifyCollapsed(true);
|
||||
} else if (!isCollapsedSize && this.isCollapsed) {
|
||||
this.item.notifyCollapsed(false);
|
||||
this.isCollapsed = false;
|
||||
}
|
||||
if (!isCollapsedSize) {
|
||||
super.resize(newSize);
|
||||
}
|
||||
}
|
||||
}
|
55
src/resizer/distributors/fixed.js
Normal file
55
src/resizer/distributors/fixed.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 ResizeItem from "../item";
|
||||
import Sizer from "../sizer";
|
||||
|
||||
/**
|
||||
distributors translate a moving cursor into
|
||||
CSS/DOM changes by calling the sizer
|
||||
|
||||
they have two methods:
|
||||
`resize` receives then new item size
|
||||
`resizeFromContainerOffset` receives resize handle location
|
||||
within the container bounding box. For internal use.
|
||||
This method usually ends up calling `resize` once the start offset is subtracted.
|
||||
*/
|
||||
export default class FixedDistributor {
|
||||
static createItem(resizeHandle, resizer, sizer) {
|
||||
return new ResizeItem(resizeHandle, resizer, sizer);
|
||||
}
|
||||
|
||||
static createSizer(containerElement, vertical, reverse) {
|
||||
return new Sizer(containerElement, vertical, reverse);
|
||||
}
|
||||
|
||||
constructor(item) {
|
||||
this.item = item;
|
||||
this.beforeOffset = item.offset();
|
||||
}
|
||||
|
||||
resize(size) {
|
||||
this.item.setSize(size);
|
||||
}
|
||||
|
||||
resizeFromContainerOffset(offset) {
|
||||
this.resize(offset - this.beforeOffset);
|
||||
}
|
||||
|
||||
start() {}
|
||||
|
||||
finish() {}
|
||||
}
|
132
src/resizer/distributors/roomsublist.js
Normal file
132
src/resizer/distributors/roomsublist.js
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
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() {
|
||||
}
|
||||
}
|
|
@ -14,17 +14,14 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {Sizer, FlexSizer} from "./sizer";
|
||||
import {FixedDistributor, CollapseDistributor} from "./distributors";
|
||||
import {Resizer} from "./resizer";
|
||||
import {RoomSizer, RoomDistributor} from "./room";
|
||||
import FixedDistributor from "./distributors/fixed";
|
||||
import CollapseDistributor from "./distributors/collapse";
|
||||
import RoomSubListDistributor from "./distributors/roomsublist";
|
||||
import Resizer from "./resizer";
|
||||
|
||||
module.exports = {
|
||||
Resizer,
|
||||
Sizer,
|
||||
FlexSizer,
|
||||
FixedDistributor,
|
||||
CollapseDistributor,
|
||||
RoomSizer,
|
||||
RoomDistributor,
|
||||
RoomSubListDistributor,
|
||||
};
|
||||
|
|
107
src/resizer/item.js
Normal file
107
src/resizer/item.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
export default class ResizeItem {
|
||||
constructor(handle, resizer, sizer) {
|
||||
const id = handle.getAttribute("data-id");
|
||||
const reverse = resizer.isReverseResizeHandle(handle);
|
||||
const domNode = reverse ? handle.nextElementSibling : handle.previousElementSibling;
|
||||
|
||||
this.domNode = domNode;
|
||||
this.id = id;
|
||||
this.reverse = reverse;
|
||||
this.resizer = resizer;
|
||||
this.sizer = sizer;
|
||||
}
|
||||
|
||||
_copyWith(handle, resizer, sizer) {
|
||||
const Ctor = this.constructor;
|
||||
return new Ctor(handle, resizer, sizer);
|
||||
}
|
||||
|
||||
_advance(forwards) {
|
||||
// opposite direction from fromResizeHandle to get back to handle
|
||||
let handle = this.reverse ?
|
||||
this.domNode.previousElementSibling :
|
||||
this.domNode.nextElementSibling;
|
||||
const moveNext = forwards !== this.reverse; // xor
|
||||
// iterate at least once to avoid infinite loop
|
||||
do {
|
||||
if (moveNext) {
|
||||
handle = handle.nextElementSibling;
|
||||
} else {
|
||||
handle = handle.previousElementSibling;
|
||||
}
|
||||
} while (handle && !this.resizer.isResizeHandle(handle));
|
||||
|
||||
if (handle) {
|
||||
const nextHandle = this._copyWith(handle, this.resizer, this.sizer);
|
||||
nextHandle.reverse = this.reverse;
|
||||
return nextHandle;
|
||||
}
|
||||
}
|
||||
|
||||
next() {
|
||||
return this._advance(true);
|
||||
}
|
||||
|
||||
previous() {
|
||||
return this._advance(false);
|
||||
}
|
||||
|
||||
size() {
|
||||
return this.sizer.getItemSize(this.domNode);
|
||||
}
|
||||
|
||||
offset() {
|
||||
return this.sizer.getItemOffset(this.domNode);
|
||||
}
|
||||
|
||||
setSize(size) {
|
||||
this.sizer.setItemSize(this.domNode, size);
|
||||
const callback = this.resizer.config.onResized;
|
||||
if (callback) {
|
||||
callback(size, this.id, this.domNode);
|
||||
}
|
||||
}
|
||||
|
||||
clearSize() {
|
||||
this.sizer.clearItemSize(this.domNode);
|
||||
const callback = this.resizer.config.onResized;
|
||||
if (callback) {
|
||||
callback(null, this.id, this.domNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
first() {
|
||||
const firstHandle = Array.from(this.domNode.parentElement.children).find(el => {
|
||||
return this.resizer.isResizeHandle(el);
|
||||
});
|
||||
if (firstHandle) {
|
||||
return this._copyWith(firstHandle, this.resizer, this.sizer);
|
||||
}
|
||||
}
|
||||
|
||||
last() {
|
||||
const lastHandle = Array.from(this.domNode.parentElement.children).reverse().find(el => {
|
||||
return this.resizer.isResizeHandle(el);
|
||||
});
|
||||
if (lastHandle) {
|
||||
return this._copyWith(lastHandle, this.resizer, this.sizer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,8 +14,6 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import {Sizer} from "./sizer";
|
||||
|
||||
/*
|
||||
classNames:
|
||||
// class on resize-handle
|
||||
|
@ -28,12 +26,14 @@ classNames:
|
|||
resizing: string
|
||||
*/
|
||||
|
||||
export class Resizer {
|
||||
constructor(container, distributorCtor, distributorCfg, sizerCtor = Sizer) {
|
||||
|
||||
export default class Resizer {
|
||||
// TODO move vertical/horizontal to config option/container class
|
||||
// as it doesn't make sense to mix them within one container/Resizer
|
||||
constructor(container, distributorCtor, config) {
|
||||
this.container = container;
|
||||
this.distributorCtor = distributorCtor;
|
||||
this.distributorCfg = distributorCfg;
|
||||
this.sizerCtor = sizerCtor;
|
||||
this.config = config;
|
||||
this.classNames = {
|
||||
handle: "resizer-handle",
|
||||
reverse: "resizer-reverse",
|
||||
|
@ -79,7 +79,11 @@ export class Resizer {
|
|||
}
|
||||
}
|
||||
|
||||
_isResizeHandle(el) {
|
||||
isReverseResizeHandle(el) {
|
||||
return el && el.classList.contains(this.classNames.reverse);
|
||||
}
|
||||
|
||||
isResizeHandle(el) {
|
||||
return el && el.classList.contains(this.classNames.handle);
|
||||
}
|
||||
|
||||
|
@ -99,6 +103,7 @@ export class Resizer {
|
|||
}
|
||||
|
||||
const {sizer, distributor} = this._createSizerAndDistributor(resizeHandle);
|
||||
distributor.start();
|
||||
|
||||
const onMouseMove = (event) => {
|
||||
const offset = sizer.offsetFromEvent(event);
|
||||
|
@ -106,48 +111,33 @@ export class Resizer {
|
|||
};
|
||||
|
||||
const body = document.body;
|
||||
const onMouseUp = (event) => {
|
||||
const finishResize = () => {
|
||||
if (this.classNames.resizing) {
|
||||
this.container.classList.remove(this.classNames.resizing);
|
||||
}
|
||||
body.removeEventListener("mouseup", onMouseUp, false);
|
||||
distributor.finish();
|
||||
body.removeEventListener("mouseup", finishResize, false);
|
||||
document.removeEventListener("mouseleave", finishResize, false);
|
||||
body.removeEventListener("mousemove", onMouseMove, false);
|
||||
};
|
||||
body.addEventListener("mouseup", onMouseUp, false);
|
||||
body.addEventListener("mouseup", finishResize, false);
|
||||
document.addEventListener("mouseleave", finishResize, false);
|
||||
body.addEventListener("mousemove", onMouseMove, false);
|
||||
}
|
||||
|
||||
_createSizerAndDistributor(resizeHandle) {
|
||||
const vertical = resizeHandle.classList.contains(this.classNames.vertical);
|
||||
const reverse = resizeHandle.classList.contains(this.classNames.reverse);
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
const sizer = new this.sizerCtor(this.container, vertical, reverse);
|
||||
|
||||
const items = this._getResizableItems();
|
||||
const prevItem = resizeHandle.previousElementSibling;
|
||||
// if reverse, resize the item after the handle instead of before, so + 1
|
||||
const itemIndex = items.indexOf(prevItem) + (reverse ? 1 : 0);
|
||||
const item = items[itemIndex];
|
||||
const id = resizeHandle.getAttribute("data-id");
|
||||
// eslint-disable-next-line new-cap
|
||||
const distributor = new this.distributorCtor(
|
||||
sizer, item, id, this.distributorCfg,
|
||||
items, this.container);
|
||||
const reverse = this.isReverseResizeHandle(resizeHandle);
|
||||
const Distributor = this.distributorCtor;
|
||||
const sizer = Distributor.createSizer(this.container, vertical, reverse);
|
||||
const item = Distributor.createItem(resizeHandle, this, sizer);
|
||||
const distributor = new Distributor(item, this.config);
|
||||
return {sizer, distributor};
|
||||
}
|
||||
|
||||
_getResizableItems() {
|
||||
return Array.from(this.container.children).filter(el => {
|
||||
return !this._isResizeHandle(el) && (
|
||||
this._isResizeHandle(el.previousElementSibling) ||
|
||||
this._isResizeHandle(el.nextElementSibling));
|
||||
});
|
||||
}
|
||||
|
||||
_getResizeHandles() {
|
||||
return Array.from(this.container.children).filter(el => {
|
||||
return this._isResizeHandle(el);
|
||||
return this.isResizeHandle(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 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 {FixedDistributor} from "./distributors";
|
||||
|
||||
class RoomSizer extends Sizer {
|
||||
setItemSize(item, size) {
|
||||
const isString = typeof size === "string";
|
||||
const cl = item.classList;
|
||||
if (isString) {
|
||||
if (size === "resized-all") {
|
||||
cl.add("resized-all");
|
||||
cl.remove("resized-sized");
|
||||
item.style.maxHeight = null;
|
||||
}
|
||||
} else {
|
||||
cl.add("resized-sized");
|
||||
cl.remove("resized-all");
|
||||
item.style.maxHeight = `${Math.round(size)}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RoomDistributor extends FixedDistributor {
|
||||
resize(itemSize) {
|
||||
const scrollItem = this.item.querySelector(".mx_RoomSubList_scroll");
|
||||
if (!scrollItem) {
|
||||
return; //FIXME: happens when starting the page on a community url, taking the safe way out for now
|
||||
}
|
||||
const fixedHeight = this.item.offsetHeight - scrollItem.offsetHeight;
|
||||
if (itemSize > (fixedHeight + scrollItem.scrollHeight)) {
|
||||
super.resize("resized-all");
|
||||
} else {
|
||||
super.resize(itemSize);
|
||||
}
|
||||
}
|
||||
|
||||
resizeFromContainerOffset(offset) {
|
||||
return this.resize(offset - this.sizer.getItemOffset(this.item));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
RoomSizer,
|
||||
RoomDistributor,
|
||||
};
|
|
@ -18,31 +18,13 @@ limitations under the License.
|
|||
implements DOM/CSS operations for resizing.
|
||||
The sizer determines what CSS mechanism is used for sizing items, like flexbox, ...
|
||||
*/
|
||||
class Sizer {
|
||||
export default class Sizer {
|
||||
constructor(container, vertical, reverse) {
|
||||
this.container = container;
|
||||
this.reverse = reverse;
|
||||
this.vertical = vertical;
|
||||
}
|
||||
|
||||
getItemPercentage(item) {
|
||||
/*
|
||||
const flexGrow = window.getComputedStyle(item).flexGrow;
|
||||
if (flexGrow === "") {
|
||||
return null;
|
||||
}
|
||||
return parseInt(flexGrow) / 1000;
|
||||
*/
|
||||
const style = window.getComputedStyle(item);
|
||||
const sizeStr = this.vertical ? style.height : style.width;
|
||||
const size = parseInt(sizeStr, 10);
|
||||
return size / this.getTotalSize();
|
||||
}
|
||||
|
||||
setItemPercentage(item, percent) {
|
||||
item.style.flexGrow = Math.round(percent * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
@param {Element} item the dom element being resized
|
||||
@return {number} how far the edge of the item is from the edge of the container
|
||||
|
@ -82,6 +64,14 @@ class Sizer {
|
|||
}
|
||||
}
|
||||
|
||||
clearItemSize(item) {
|
||||
if (this.vertical) {
|
||||
item.style.height = null;
|
||||
} else {
|
||||
item.style.width = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@param {MouseEvent} event the mouse event
|
||||
@return {number} the distance between the cursor and the edge of the container,
|
||||
|
@ -96,12 +86,3 @@ class Sizer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FlexSizer extends Sizer {
|
||||
setItemSize(item, size) {
|
||||
item.style.flexGrow = `0`;
|
||||
item.style.flexBasis = `${Math.round(size)}px`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {Sizer, FlexSizer};
|
||||
|
|
Loading…
Reference in a new issue