diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss
index 61da3a360b..3a33b73ec9 100644
--- a/res/css/views/rooms/_AppsDrawer.scss
+++ b/res/css/views/rooms/_AppsDrawer.scss
@@ -16,9 +16,10 @@ limitations under the License.
*/
/*
- Minimum size for usual AppTiles and fixed size for mini-tiles.
+ Size settings
*/
-$AppTileMinHeight: 300px;
+$AppsDrawerMinHeight: 50px;
+$AppsDrawerDefaultHeight: 300px;
$MiniAppTileHeight: 114px;
.mx_AppsDrawer {
@@ -35,6 +36,13 @@ $MiniAppTileHeight: 114px;
flex-direction: row;
align-items: stretch;
justify-content: center;
+ min-height: $AppsDrawerMinHeight;
+ height: $AppsDrawerDefaultHeight;
+}
+
+.mx_AppsDrawer_minimised .mx_AppsContainer {
+ min-height: inherit;
+ height: inherit;
}
.mx_AddWidget_button {
@@ -67,7 +75,6 @@ $MiniAppTileHeight: 114px;
border-radius: 4px;
display: flex;
flex-direction: column;
- min-height: $AppTileMinHeight;
}
.mx_AppTile:last-child {
@@ -83,7 +90,6 @@ $MiniAppTileHeight: 114px;
border-radius: 4px;
display: flex;
flex-direction: column;
- min-height: $AppTileMinHeight;
}
.mx_AppTile_mini {
@@ -378,3 +384,27 @@ form.mx_Custom_Widget_Form div {
.mx_AppLoading iframe {
display: none;
}
+
+/* Hidden resize handle (Apptile bottom serves as indicator) */
+.mx_AppsDrawer .mx_ResizeHandle > div {
+ background: inherit;
+}
+
+.mx_AppsDrawer_fullWidth .mx_ResizeHandle {
+ max-width: 960px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.mx_AppsDrawer_minimised .mx_ResizeHandle {
+ display: none;
+}
+
+/* Avoid apptile iframes capturing mouse event focus when resizing */
+.mx_AppsDrawer_resizing iframe {
+ pointer-events: none;
+}
+
+.mx_AppsDrawer_resizing .mx_AppTile_persistedWrapper {
+ z-index: 1;
+}
diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js
index b64eb33435..842b93170f 100644
--- a/src/components/views/rooms/AppsDrawer.js
+++ b/src/components/views/rooms/AppsDrawer.js
@@ -30,6 +30,9 @@ import WidgetEchoStore from "../../../stores/WidgetEchoStore";
import AccessibleButton from '../elements/AccessibleButton';
import {IntegrationManagers} from "../../../integrations/IntegrationManagers";
import SettingsStore from "../../../settings/SettingsStore";
+import classNames from 'classnames';
+import ResizeHandle from '../elements/ResizeHandle';
+import {Resizer, FixedDistributor} from '../../../resizer';
// The maximum number of widgets that can be added in a room
const MAX_WIDGETS = 2;
@@ -60,6 +63,7 @@ export default createReactClass({
MatrixClientPeg.get().on('RoomState.events', this.onRoomStateEvents);
WidgetEchoStore.on('update', this._updateApps);
this.dispatcherRef = dis.register(this.onAction);
+ this._createResizer();
},
componentWillUnmount: function() {
@@ -69,6 +73,10 @@ export default createReactClass({
}
WidgetEchoStore.removeListener('update', this._updateApps);
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
+ if (this.resizer) {
+ this.resizer.detach();
+ this.resizer = null;
+ }
},
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
@@ -154,6 +162,30 @@ export default createReactClass({
this._launchManageIntegrations();
},
+ _createResizer: function() {
+ if (!this.resizeContainer) {
+ return;
+ }
+
+ const classNames = {
+ handle: "mx_ResizeHandle",
+ vertical: "mx_ResizeHandle_vertical",
+ resizing: "mx_AppsDrawer_resizing",
+ };
+ const resizer = new Resizer(
+ this.resizeContainer,
+ FixedDistributor,
+ {},
+ );
+ resizer.setClassNames(classNames);
+ resizer.attach();
+ this.resizer = resizer;
+ },
+
+ _setResizeContainerRef: function(div) {
+ this.resizeContainer = div;
+ },
+
render: function() {
const apps = this.state.apps.map((app, index, arr) => {
const capWhitelist = WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, this.props.room.roomId);
@@ -191,6 +223,13 @@ export default createReactClass({
;
}
+ const containerStyle = {
+ maxHeight: Math.max(this.props.maxHeight - 50, 300),
+ };
+ if (!this.props.showApps && this.resizer) {
+ this.resizer.forHandleAt(0).item.clearSize();
+ }
+
let spinner;
if (
apps.length === 0 && WidgetEchoStore.roomHasPendingWidgets(
@@ -202,12 +241,20 @@ export default createReactClass({
spinner =