mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-16 05:04:57 +08:00
Fix applying programmatically set height for "top" room layout (#9339)
* Fix applying programmatically set height for "top" room layout When applying a room layout automatically (e.g. via `io.element.widgets.layout` state event), in cases the layout mode container it set to "top", the height was previously not correctly updated. Signed-off-by: Oliver Sand <oliver.sand@nordeck.net> * Add cypress tests Signed-off-by: Oliver Sand <oliver.sand@nordeck.net>
This commit is contained in:
parent
f92f7beb47
commit
191b0a1517
121
cypress/e2e/widgets/layout.spec.ts
Normal file
121
cypress/e2e/widgets/layout.spec.ts
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 Oliver Sand
|
||||||
|
Copyright 2022 Nordeck IT + Consulting GmbH.
|
||||||
|
|
||||||
|
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 { IWidget } from "matrix-widget-api";
|
||||||
|
|
||||||
|
import { SynapseInstance } from "../../plugins/synapsedocker";
|
||||||
|
|
||||||
|
const ROOM_NAME = 'Test Room';
|
||||||
|
const WIDGET_ID = "fake-widget";
|
||||||
|
const WIDGET_HTML = `
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Fake Widget</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Hello World
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
describe('Widget Layout', () => {
|
||||||
|
let widgetUrl: string;
|
||||||
|
let synapse: SynapseInstance;
|
||||||
|
let roomId: string;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.startSynapse("default").then(data => {
|
||||||
|
synapse = data;
|
||||||
|
|
||||||
|
cy.initTestUser(synapse, "Sally");
|
||||||
|
});
|
||||||
|
cy.serveHtmlFile(WIDGET_HTML).then(url => {
|
||||||
|
widgetUrl = url;
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.createRoom({
|
||||||
|
name: ROOM_NAME,
|
||||||
|
}).then((id) => {
|
||||||
|
roomId = id;
|
||||||
|
|
||||||
|
// setup widget via state event
|
||||||
|
cy.getClient().then(async matrixClient => {
|
||||||
|
const content: IWidget = {
|
||||||
|
id: WIDGET_ID,
|
||||||
|
creatorUserId: 'somebody',
|
||||||
|
type: 'widget',
|
||||||
|
name: 'widget',
|
||||||
|
url: widgetUrl,
|
||||||
|
};
|
||||||
|
await matrixClient.sendStateEvent(roomId, 'im.vector.modular.widgets', content, WIDGET_ID);
|
||||||
|
}).as('widgetEventSent');
|
||||||
|
|
||||||
|
// set initial layout
|
||||||
|
cy.getClient().then(async matrixClient => {
|
||||||
|
const content = {
|
||||||
|
widgets: {
|
||||||
|
[WIDGET_ID]: {
|
||||||
|
container: 'top', index: 1, width: 100, height: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await matrixClient.sendStateEvent(roomId, 'io.element.widgets.layout', content, "");
|
||||||
|
}).as('layoutEventSent');
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.all([
|
||||||
|
cy.get<string>("@widgetEventSent"),
|
||||||
|
cy.get<string>("@layoutEventSent"),
|
||||||
|
]).then(() => {
|
||||||
|
// open the room
|
||||||
|
cy.viewRoomByName(ROOM_NAME);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
cy.stopSynapse(synapse);
|
||||||
|
cy.stopWebServers();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('manually resize the height of the top container layout', () => {
|
||||||
|
cy.get('iframe[title="widget"]').invoke('height').should('be.lessThan', 250);
|
||||||
|
|
||||||
|
cy.get('.mx_AppsContainer_resizerHandle')
|
||||||
|
.trigger('mousedown')
|
||||||
|
.trigger('mousemove', { clientX: 0, clientY: 550, force: true })
|
||||||
|
.trigger('mouseup', { clientX: 0, clientY: 550, force: true });
|
||||||
|
|
||||||
|
cy.get('iframe[title="widget"]').invoke('height').should('be.greaterThan', 400);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('programatically resize the height of the top container layout', () => {
|
||||||
|
cy.get('iframe[title="widget"]').invoke('height').should('be.lessThan', 250);
|
||||||
|
|
||||||
|
cy.getClient().then(async matrixClient => {
|
||||||
|
const content = {
|
||||||
|
widgets: {
|
||||||
|
[WIDGET_ID]: {
|
||||||
|
container: 'top', index: 1, width: 100, height: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await matrixClient.sendStateEvent(roomId, 'io.element.widgets.layout', content, "");
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('iframe[title="widget"]').invoke('height').should('be.greaterThan', 400);
|
||||||
|
});
|
||||||
|
});
|
@ -31,7 +31,6 @@ import Resizer from "../../../resizer/resizer";
|
|||||||
import PercentageDistributor from "../../../resizer/distributors/percentage";
|
import PercentageDistributor from "../../../resizer/distributors/percentage";
|
||||||
import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
|
||||||
import { clamp, percentageOf, percentageWithin } from "../../../utils/numbers";
|
import { clamp, percentageOf, percentageWithin } from "../../../utils/numbers";
|
||||||
import { useStateCallback } from "../../../hooks/useStateCallback";
|
|
||||||
import UIStore from "../../../stores/UIStore";
|
import UIStore from "../../../stores/UIStore";
|
||||||
import { IApp } from "../../../stores/WidgetStore";
|
import { IApp } from "../../../stores/WidgetStore";
|
||||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||||
@ -330,13 +329,8 @@ const PersistentVResizer: React.FC<IPersistentResizerProps> = ({
|
|||||||
defaultHeight = 280;
|
defaultHeight = 280;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [height, setHeight] = useStateCallback(defaultHeight, newHeight => {
|
|
||||||
newHeight = percentageOf(newHeight, minHeight, maxHeight) * 100;
|
|
||||||
WidgetLayoutStore.instance.setContainerHeight(room, Container.Top, newHeight);
|
|
||||||
});
|
|
||||||
|
|
||||||
return <Resizable
|
return <Resizable
|
||||||
size={{ height: Math.min(height, maxHeight), width: undefined }}
|
size={{ height: Math.min(defaultHeight, maxHeight), width: undefined }}
|
||||||
minHeight={minHeight}
|
minHeight={minHeight}
|
||||||
maxHeight={maxHeight}
|
maxHeight={maxHeight}
|
||||||
onResizeStart={() => {
|
onResizeStart={() => {
|
||||||
@ -346,7 +340,15 @@ const PersistentVResizer: React.FC<IPersistentResizerProps> = ({
|
|||||||
resizeNotifier.notifyTimelineHeightChanged();
|
resizeNotifier.notifyTimelineHeightChanged();
|
||||||
}}
|
}}
|
||||||
onResizeStop={(e, dir, ref, d) => {
|
onResizeStop={(e, dir, ref, d) => {
|
||||||
setHeight(height + d.height);
|
let newHeight = defaultHeight + d.height;
|
||||||
|
newHeight = percentageOf(newHeight, minHeight, maxHeight) * 100;
|
||||||
|
|
||||||
|
WidgetLayoutStore.instance.setContainerHeight(
|
||||||
|
room,
|
||||||
|
Container.Top,
|
||||||
|
newHeight,
|
||||||
|
);
|
||||||
|
|
||||||
resizeNotifier.stopResizing();
|
resizeNotifier.stopResizing();
|
||||||
}}
|
}}
|
||||||
handleWrapperClass={handleWrapperClass}
|
handleWrapperClass={handleWrapperClass}
|
||||||
|
Loading…
Reference in New Issue
Block a user