diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index be7bffff40..f47764133b 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -141,12 +141,6 @@ limitations under the License. box-sizing: border-box; min-width: 24px; // prevent flexbox crushing - .mx_AccessibleTooltipButton_container { - // TODO - position: absolute; - top: -50px; - } - &:hover { &::after { content: ''; diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index df064cdf40..bc8a2927c0 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -98,12 +98,16 @@ $MiniAppTileHeight: 200px; } } +// TODO this should be 300px but that's too large +$MinWidth: 240px; + .mx_AppsDrawer_has2 .mx_AppTile { width: 50%; &:nth-child(3) { flex-grow: 1; - width: 0; + width: 0 !important; + min-width: $MinWidth !important; } } .mx_AppsDrawer_has3 .mx_AppTile { @@ -111,13 +115,14 @@ $MiniAppTileHeight: 200px; &:nth-child(3) { flex-grow: 1; - width: 0; + width: 0 !important; + min-width: $MinWidth !important; } } .mx_AppTile { width: 50%; - min-width: 200px; + min-width: $MinWidth; border: 8px solid $widget-menu-bar-bg-color; border-left-width: 5px; border-right-width: 5px; diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 547432fcf6..13964f8592 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -1374,7 +1374,7 @@ export default class RoomView extends React.Component { private onAppsClick = () => { dis.dispatch({ - action: "appsDrawer", // TODO should this go into the RVS? + action: "appsDrawer", show: !this.state.showApps, }); }; diff --git a/src/components/views/context_menus/WidgetContextMenu.tsx b/src/components/views/context_menus/WidgetContextMenu.tsx index b77e91ed0b..44cdc5523e 100644 --- a/src/components/views/context_menus/WidgetContextMenu.tsx +++ b/src/components/views/context_menus/WidgetContextMenu.tsx @@ -56,6 +56,7 @@ const WidgetContextMenu: React.FC = ({ if (showUnpin) { const onUnpinClick = () => { WidgetStore.instance.unpinWidget(app.id); + onFinished(); }; unpinButton = ; @@ -65,9 +66,10 @@ const WidgetContextMenu: React.FC = ({ if (canModify && WidgetUtils.isManagedByManager(app)) { const onEditClick = () => { WidgetUtils.editWidget(room, app); + onFinished(); }; - editButton = + editButton = ; } let snapshotButton; @@ -128,13 +130,38 @@ const WidgetContextMenu: React.FC = ({ revokeButton = ; } + const pinnedWidgets = WidgetStore.instance.getPinnedApps(roomId); + const widgetIndex = pinnedWidgets.findIndex(widget => widget.id === app.id); + + let moveLeftButton; + if (showUnpin && widgetIndex > 0) { + const onClick = () => { + WidgetStore.instance.movePinnedWidget(app.id, -1); + onFinished(); + }; + + moveLeftButton = ; + } + + let moveRightButton; + if (showUnpin && widgetIndex < pinnedWidgets.length - 1) { + const onClick = () => { + WidgetStore.instance.movePinnedWidget(app.id, 1); + onFinished(); + }; + + moveRightButton = ; + } + return - { unpinButton } - { snapshotButton } { editButton } - { deleteButton } { revokeButton } + { deleteButton } + { snapshotButton } + { moveLeftButton } + { moveRightButton } + { unpinButton } ; }; diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index 3f2074e793..e5f02730c5 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -95,7 +95,7 @@ export default class AppsDrawer extends React.Component { // persist to localStorage console.log("@@ _saveResizerPreferences"); localStorage.setItem(this._getStorageKey(), JSON.stringify([ - this._getAppsHash(this.state.apps), + this.state.apps.map(app => app.id), ...this.state.apps.slice(1).map((_, i) => this.resizer.forHandleAt(i).size), ])); }, @@ -133,10 +133,9 @@ export default class AppsDrawer extends React.Component { _loadResizerPreferences = () => { console.log("@@ _loadResizerPreferences"); try { - const [idString, ...sizes] = JSON.parse(localStorage.getItem(this._getStorageKey())); - // format: [idString: string, ...percentages: string]; - // TODO determine the exact behaviour we want for layout changing when pinning/unpinning - if (this._getAppsHash() === idString || true) { + const [[...lastIds], ...sizes] = JSON.parse(localStorage.getItem(this._getStorageKey())); + // Every app was included in the last split, reuse the last sizes + if (this.state.apps.length <= lastIds.length && this.state.apps.every(app => lastIds.includes(app.id))) { sizes.forEach((size, i) => { const distributor = this.resizer.forHandleAt(i); if (distributor) { diff --git a/src/resizer/sizer.ts b/src/resizer/sizer.ts index ec3a8c113c..d5cc524320 100644 --- a/src/resizer/sizer.ts +++ b/src/resizer/sizer.ts @@ -92,10 +92,8 @@ export default class Sizer { } } - // TODO public start(item: HTMLElement) {} - // TODO public finish(item: HTMLElement) {} /** diff --git a/src/stores/WidgetStore.ts b/src/stores/WidgetStore.ts index 15886a7817..6bdea9f2f1 100644 --- a/src/stores/WidgetStore.ts +++ b/src/stores/WidgetStore.ts @@ -205,7 +205,38 @@ export default class WidgetStore extends AsyncStoreWithClient { this.emit(UPDATE_EVENT); } - public getPinnedApps(roomId): IApp[] { + public movePinnedWidget(widgetId: string, delta: 1 | -1) { + // TODO simplify this by changing the storage medium of pinned to an array once the Jitsi default-on goes away + const roomId = this.getRoomId(widgetId); + const roomInfo = this.getRoom(roomId); + if (!roomInfo || roomInfo.pinned[widgetId] === false) return; + + const pinnedApps = this.getPinnedApps(roomId).map(app => app.id); + const i = pinnedApps.findIndex(id => id === widgetId); + + if (delta > 0) { + pinnedApps.splice(i, 2, pinnedApps[i + 1], pinnedApps[i]); + } else { + pinnedApps.splice(i - 1, 2, pinnedApps[i], pinnedApps[i - 1]); + } + + const reorderedPinned: IRoomWidgets["pinned"] = {}; + pinnedApps.forEach(id => { + reorderedPinned[id] = true; + }); + Object.keys(roomInfo.pinned).forEach(id => { + if (reorderedPinned[id] === undefined) { + reorderedPinned[id] = roomInfo.pinned[id]; + } + }); + roomInfo.pinned = reorderedPinned; + + SettingsStore.setValue("Widgets.pinned", roomId, SettingLevel.ROOM_ACCOUNT, roomInfo.pinned); + this.emit(roomId); + this.emit(UPDATE_EVENT); + } + + public getPinnedApps(roomId: string): IApp[] { // returns the apps in the order they were pinned with, up to the maximum const roomInfo = this.getRoom(roomId); if (!roomInfo) return [];