From 0a6c20cf77af78f24bd786809e7ca5449e3326a0 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 8 Nov 2021 19:19:59 +0100 Subject: [PATCH 01/70] add maximise widget functionality --- res/css/_components.scss | 1 + .../views/right_panel/_RoomSummaryCard.scss | 18 ++- res/css/views/rooms/_AppMaximisedDrawer.scss | 46 ++++++ res/css/views/rooms/_AppsDrawer.scss | 8 + .../element-icons/room/widgets/maximise.svg | 3 + .../element-icons/room/widgets/minimise.svg | 3 + src/components/structures/RoomView.tsx | 109 +++++++++---- src/components/views/elements/AppTile.tsx | 30 +++- .../views/right_panel/RoomSummaryCard.tsx | 14 ++ .../views/rooms/AppMaximisedDrawer.tsx | 143 ++++++++++++++++++ src/i18n/strings/en_EN.json | 2 + src/stores/widgets/WidgetLayoutStore.ts | 49 +++++- 12 files changed, 393 insertions(+), 33 deletions(-) create mode 100644 res/css/views/rooms/_AppMaximisedDrawer.scss create mode 100644 res/img/element-icons/room/widgets/maximise.svg create mode 100644 res/img/element-icons/room/widgets/minimise.svg create mode 100644 src/components/views/rooms/AppMaximisedDrawer.tsx diff --git a/res/css/_components.scss b/res/css/_components.scss index d4c383b1fe6..866b26d9acf 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -208,6 +208,7 @@ @import "./views/right_panel/_VerificationPanel.scss"; @import "./views/right_panel/_WidgetCard.scss"; @import "./views/room_settings/_AliasSettings.scss"; +@import "./views/rooms/_AppMaximisedDrawer.scss"; @import "./views/rooms/_AppsDrawer.scss"; @import "./views/rooms/_Autocomplete.scss"; @import "./views/rooms/_AuxPanel.scss"; diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index e08a11cd36a..a414619b2da 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -133,6 +133,8 @@ limitations under the License. } .mx_RoomSummaryCard_app_pinToggle, + .mx_RoomSummaryCard_app_maximise, + .mx_RoomSummaryCard_app_minimise, .mx_RoomSummaryCard_app_options { position: absolute; top: 0; @@ -174,9 +176,23 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/room/pin-upright.svg'); } } + .mx_RoomSummaryCard_app_maximise { + right: 48px; - .mx_RoomSummaryCard_app_options { + &::before { + mask-image: url('$(res)/img/element-icons/room/widgets/maximise.svg'); + } + } + .mx_RoomSummaryCard_app_minimise { right: 48px; + &::before { + background-color: $accent-color; + mask-image: url('$(res)/img/element-icons/room/widgets/minimise.svg'); + } + } + + .mx_RoomSummaryCard_app_options { + right: 72px; display: none; &::before { diff --git a/res/css/views/rooms/_AppMaximisedDrawer.scss b/res/css/views/rooms/_AppMaximisedDrawer.scss new file mode 100644 index 00000000000..7741afc8f99 --- /dev/null +++ b/res/css/views/rooms/_AppMaximisedDrawer.scss @@ -0,0 +1,46 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. + +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. +*/ + +.mx_AppMaximisedContainer { + display: flex; + flex-direction: row; + align-items: stretch; + justify-content: center; + height: 100%; + width: 100%; + flex: 1; + flex-grow: 1; + min-height: 0; + padding: 5px; + + .mx_AppTile:first-of-type { + border-left-width: 8px; + border-radius: 10px 0 0 10px; + } + .mx_AppTile:last-of-type { + border-right-width: 8px; + border-radius: 0 10px 10px 0; + } + + .mx_ResizeHandle_horizontal { + position: relative; + + > div { + width: 0; + } + } +} \ No newline at end of file diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 1276b13fdeb..d88c2166c94 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -227,6 +227,14 @@ $MinWidth: 240px; margin: 0 3px; } +.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_minWidget { + mask-image: url('$(res)/img/element-icons/room/widgets/minimise.svg'); +} + +.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_maxWidget { + mask-image: url('$(res)/img/element-icons/room/widgets/maximise.svg'); +} + .mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_popout { mask-image: url('$(res)/img/feather-customised/widget/external-link.svg'); } diff --git a/res/img/element-icons/room/widgets/maximise.svg b/res/img/element-icons/room/widgets/maximise.svg new file mode 100644 index 00000000000..ed6e021299c --- /dev/null +++ b/res/img/element-icons/room/widgets/maximise.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/room/widgets/minimise.svg b/res/img/element-icons/room/widgets/minimise.svg new file mode 100644 index 00000000000..58c62750c71 --- /dev/null +++ b/res/img/element-icons/room/widgets/minimise.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 03cca683aee..5bcf393bd4b 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -95,6 +95,7 @@ import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline'; import { dispatchShowThreadEvent } from '../../dispatcher/dispatch-actions/threads'; import { fetchInitialEvent } from "../../utils/EventUtils"; import { ComposerType } from "../../dispatcher/payloads/ComposerInsertPayload"; +import AppMaximisedDrawer from '../views/rooms/AppMaximisedDrawer'; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -119,6 +120,13 @@ interface IRoomProps extends MatrixClientProps { onRegistered?(credentials: IMatrixClientCreds): void; } +// This defines, the content of the mainSplit +// AND if the mainSplit does not contain the Timeline, the chat is shown in the right panel. +enum MainSplitContentType { + Timeline, + MaximisedWidget, + // Video +} export interface IRoomState { room?: Room; roomId?: string; @@ -188,6 +196,7 @@ export interface IRoomState { rejecting?: boolean; rejectError?: Error; hasPinnedWidgets?: boolean; + mainSplitContentType: MainSplitContentType; dragCounter: number; // whether or not a spaces context switch brought us here, // if it did we don't want the room to be marked as read as soon as it is loaded. @@ -254,6 +263,7 @@ export class RoomView extends React.Component { showAvatarChanges: true, showDisplaynameChanges: true, matrixClientIsReady: this.context && this.context.isInitialSyncComplete(), + mainSplitContentType: MainSplitContentType.Timeline, dragCounter: 0, timelineRenderingType: TimelineRenderingType.Room, liveTimeline: undefined, @@ -306,18 +316,35 @@ export class RoomView extends React.Component { } private onWidgetStoreUpdate = () => { - if (this.state.room) { - this.checkWidgets(this.state.room); - } + if (!this.state.room) return; + this.checkWidgets(this.state.room); + }; + + private onWidgetEchoStoreUpdate = () => { + if (!this.state.room) return; + this.checkWidgets(this.state.room); + }; + + private onWidgetLayoutChange = () => { + if (!this.state.room) return; + this.checkWidgets(this.state.room); // we cheat here by calling the thing that matters }; private checkWidgets = (room) => { this.setState({ - hasPinnedWidgets: WidgetLayoutStore.instance.getContainerWidgets(room, Container.Top).length > 0, - showApps: this.shouldShowApps(room), + hasPinnedWidgets: WidgetLayoutStore.instance.hasPinnedWidgets(this.state.room), + mainSplitContentType: this.getMainSplitContentType(), + showApps: this.shouldShowApps(this.state.room), }); }; + private getMainSplitContentType = () => { + // TODO-video check if video should be displayed in main panel + return (WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room)) + ? MainSplitContentType.MaximisedWidget + : MainSplitContentType.Timeline; + }; + private onReadReceiptsChange = () => { this.setState({ showReadReceipts: SettingsStore.getValue("showReadReceipts", this.state.roomId), @@ -504,18 +531,6 @@ export class RoomView extends React.Component { } } - private onWidgetEchoStoreUpdate = () => { - if (!this.state.room) return; - this.setState({ - hasPinnedWidgets: WidgetLayoutStore.instance.getContainerWidgets(this.state.room, Container.Top).length > 0, - showApps: this.shouldShowApps(this.state.room), - }); - }; - - private onWidgetLayoutChange = () => { - this.onWidgetEchoStoreUpdate(); // we cheat here by calling the thing that matters - }; - private setupRoom(room: Room, roomId: string, joining: boolean, shouldPeek: boolean) { // if this is an unknown room then we're in one of three states: // - This is a room we can peek into (search engine) (we can /peek) @@ -972,7 +987,7 @@ export class RoomView extends React.Component { if (this.unmounted) return; // Attach a widget store listener only when we get a room WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange); - this.onWidgetLayoutChange(); // provoke an update + // this.onWidgetLayoutChange(); // provoke an update // Done with checkwidget now TODO-maximise_widget remove comment after review this.calculatePeekRules(room); this.updatePreviewUrlVisibility(room); @@ -2098,6 +2113,52 @@ export class RoomView extends React.Component { const showChatEffects = SettingsStore.getValue('showChatEffects'); + // Decide what to show in the main split + let mainSplitBody; + if (SettingsStore.getValue("feature_maximised_widgets")) { + switch (this.state.mainSplitContentType) { + case MainSplitContentType.Timeline: + mainSplitBody = + { auxPanel } +
+ { fileDropTarget } + { topUnreadMessagesBar } + { jumpToBottom } + { messagePanel } + { searchResultsPanel } +
+ { statusBarArea } + { previewBar } + { messageComposer } +
; + break; + case MainSplitContentType.MaximisedWidget: + mainSplitBody = ; + break; + // TODO-video MainSplitContentType.Video: + // break; + } + } else { + mainSplitBody = + { auxPanel } +
+ { fileDropTarget } + { topUnreadMessagesBar } + { jumpToBottom } + { messagePanel } + { searchResultsPanel } +
+ { statusBarArea } + { previewBar } + { messageComposer } +
; + } + return (
@@ -2120,17 +2181,7 @@ export class RoomView extends React.Component { />
- { auxPanel } -
- { fileDropTarget } - { topUnreadMessagesBar } - { jumpToBottom } - { messagePanel } - { searchResultsPanel } -
- { statusBarArea } - { previewBar } - { messageComposer } + { mainSplitBody }
diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index dcb6e62649b..b125798a264 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -40,7 +40,7 @@ import WidgetAvatar from "../avatars/WidgetAvatar"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { Room } from "matrix-js-sdk/src/models/room"; import { IApp } from "../../../stores/WidgetStore"; - +import { WidgetLayoutStore, Container } from "../../../stores/widgets/WidgetLayoutStore"; interface IProps { app: IApp; // If room is not specified then it is an account level widget @@ -400,6 +400,16 @@ export default class AppTile extends React.Component { { target: '_blank', href: this.sgWidget.popoutUrl, rel: 'noreferrer noopener' }).click(); }; + private onMaxMinWidgetClick = (): void => { + // TODO-video make this not interfere with the new video conference design + + const targetContainer = + WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Center) + ? Container.Right + : Container.Center; + WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer); + }; + private onContextMenuClick = (): void => { this.setState({ menuDisplayed: true }); }; @@ -522,6 +532,23 @@ export default class AppTile extends React.Component { /> ); } + let maxMinButton; + if (SettingsStore.getValue("feature_maximised_widgets")) { + const widgetIsMaximised = WidgetLayoutStore.instance. + isInContainer(this.props.room, this.props.app, Container.Center); + maxMinButton = ; + } return
@@ -531,6 +558,7 @@ export default class AppTile extends React.Component { { this.props.showTitle && this.getTileTitle() } + { maxMinButton } { (this.props.showPopout && !this.state.requiresClient) && = ({ app, room }) => { mx_RoomSummaryCard_Button_pinned: isPinned, }); + const isMaximised = WidgetLayoutStore.instance.isInContainer(room, app, Container.Center); + const toggleMaximised = isMaximised + ? () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); } + : () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Center); }; + + const maximiseTitle = isMaximised ? _t("Minimise widget") : _t("Maximise widget"); + return
= ({ app, room }) => { disabled={cannotPin} yOffset={-24} /> + { SettingsStore.getValue("feature_maximised_widgets") && + } { contextMenu }
; diff --git a/src/components/views/rooms/AppMaximisedDrawer.tsx b/src/components/views/rooms/AppMaximisedDrawer.tsx new file mode 100644 index 00000000000..6de480ac34d --- /dev/null +++ b/src/components/views/rooms/AppMaximisedDrawer.tsx @@ -0,0 +1,143 @@ +/* +Copyright 2017 Vector Creations Ltd +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 React from 'react'; + +import AppTile from '../elements/AppTile'; +import dis from '../../../dispatcher/dispatcher'; +import * as sdk from '../../../index'; +import * as ScalarMessaging from '../../../ScalarMessaging'; +import WidgetUtils from '../../../utils/WidgetUtils'; +import WidgetEchoStore from "../../../stores/WidgetEchoStore"; +import ResizeNotifier from "../../../utils/ResizeNotifier"; +import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { Room } from "matrix-js-sdk/src/models/room"; +import { IApp } from "../../../stores/WidgetStore"; + +interface IProps { + userId: string; + room: Room; + resizeNotifier: ResizeNotifier; + showApps?: boolean; // Should apps be rendered + maxHeight: number; +} + +interface IState { + app: IApp; + resizing: boolean; +} + +@replaceableComponent("views.rooms.AppMaximisedDrawer") +export default class AppMaximisedDrawer extends React.Component { + private dispatcherRef: string; + public static defaultProps: Partial = { + showApps: true, + }; + + constructor(props: IProps) { + super(props); + + this.state = { + app: this.getApp(), + resizing: false, + }; + + this.props.resizeNotifier.on("isResizing", this.onIsResizing); + } + + public componentDidMount(): void { + ScalarMessaging.startListening(); + WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(this.props.room), this.updateApps); + } + + public componentWillUnmount(): void { + ScalarMessaging.stopListening(); + WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(this.props.room), this.updateApps); + if (this.dispatcherRef) dis.unregister(this.dispatcherRef); + this.props.resizeNotifier.off("isResizing", this.onIsResizing); + } + + private onIsResizing = (resizing: boolean): void => { + // This inoformation is needed to make sure the widget does not consume the pointer events for resizing. + this.setState({ resizing: resizing }); + }; + + public componentDidUpdate(prevProps: IProps, prevState: IState): void { + if (prevProps.userId !== this.props.userId || prevProps.room !== this.props.room) { + // Room has changed, update app + this.updateApps(); + } + } + + private getApp = (): IApp => { + if (WidgetLayoutStore.instance.hasMaximisedWidget(this.props.room)) { + return WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center)[0]; + } else { + console.error("Maximised widget container is shown although there is no app in the center container"); + return undefined; + } + }; + + private updateApps = (): void => { + this.setState({ + app: this.getApp(), + }); + }; + + public render(): JSX.Element { + // Should the showApps button also impct the maximied widget? TODO-maximise_widget Remove after review + // if (!this.props.showApps) return
; + + const app = ; + + if (!app) { + return
; + } + + let spinner; + if ( + !app && WidgetEchoStore.roomHasPendingWidgets( + this.props.room.roomId, + WidgetUtils.getRoomWidgets(this.props.room), + ) + ) { + const Loader = sdk.getComponent("elements.Spinner"); + spinner = ; + } + return ( + +
+ + { app } + +
+ { spinner } +
+ ); + } +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 86d77489cba..f34ba50cd02 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1853,6 +1853,8 @@ "Threads": "Threads", "Room Info": "Room Info", "You can only pin up to %(count)s widgets|other": "You can only pin up to %(count)s widgets", + "Minimise widget": "Minimise widget", + "Maximise widget": "Maximise widget", "Unpin a widget to view it in this panel": "Unpin a widget to view it in this panel", "Set my room layout for everyone": "Set my room layout for everyone", "Widgets": "Widgets", diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 7efc5fb195b..9ac3b542529 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -26,6 +26,7 @@ import { SettingLevel } from "../../settings/SettingLevel"; import { arrayFastClone } from "../../utils/arrays"; import { UPDATE_EVENT } from "../AsyncStore"; import { compare } from "../../utils/strings"; +import { some } from "lodash"; export const WIDGET_LAYOUT_EVENT_TYPE = "io.element.widgets.layout"; @@ -40,6 +41,7 @@ export enum Container { // ... more as needed. Note that most of this code assumes that there // are only two containers, and that only the top container is special. + Center = "center" } export interface IStoredLayout { @@ -201,12 +203,21 @@ export class WidgetLayoutStore extends ReadyWatchingStore { // function will go into the right container. const topWidgets: IApp[] = []; const rightWidgets: IApp[] = []; + const centerWidgets: IApp[] = []; for (const widget of widgets) { const stateContainer = roomLayout?.widgets?.[widget.id]?.container; const manualContainer = userLayout?.widgets?.[widget.id]?.container; const isLegacyPinned = !!legacyPinned?.[widget.id]; const defaultContainer = WidgetType.JITSI.matches(widget.type) ? Container.Top : Container.Right; - + if (stateContainer === Container.Center || manualContainer === Container.Center) { + if (centerWidgets.length) { + console.error("Tried to push a second Widget into the center container"); + } else { + centerWidgets.push(widget); + } + // The widget won't need to be put in any oter container. + continue; + } let targetContainer = defaultContainer; if (!!manualContainer || !!stateContainer) { targetContainer = (manualContainer) ? manualContainer : stateContainer; @@ -323,6 +334,11 @@ export class WidgetLayoutStore extends ReadyWatchingStore { ordered: rightWidgets, }; } + if (centerWidgets.length) { + this.byRoom[room.roomId][Container.Center] = { + ordered: centerWidgets, + }; + } const afterChanges = JSON.stringify(this.byRoom[room.roomId]); if (afterChanges !== beforeChanges) { @@ -339,7 +355,11 @@ export class WidgetLayoutStore extends ReadyWatchingStore { } public canAddToContainer(room: Room, container: Container): boolean { - return this.getContainerWidgets(room, container).length < MAX_PINNED; + switch (container) { + case Container.Top: return this.getContainerWidgets(room, container).length < MAX_PINNED; + case Container.Right: return this.getContainerWidgets(room, container).length < MAX_PINNED; + case Container.Center: return this.getContainerWidgets(room, container).length < 1; + } } public getResizerDistributions(room: Room, container: Container): string[] { // yes, string. @@ -426,6 +446,31 @@ export class WidgetLayoutStore extends ReadyWatchingStore { this.updateUserLayout(room, { [widget.id]: { container: toContainer }, }); + switch (toContainer) { + case Container.Center: + for (const w of this.getContainerWidgets(room, Container.Top)) { + this.moveToContainer(room, w, Container.Right); + } + for (const w of this.getContainerWidgets(room, Container.Top)) { + if (w !== widget) {this.moveToContainer(room, w, Container.Right);} + } + break; + case Container.Right: + break; + case Container.Top: + if (this.hasMaximisedWidget(room) && toContainer) { + this.moveToContainer(room, this.getContainerWidgets(room, Container.Center)[0], Container.Right); + } + break; + } + } + + public hasMaximisedWidget(room: Room) { + return this.getContainerWidgets(room, Container.Center).length > 0; + } + + public hasPinnedWidgets(room: Room) { + return this.getContainerWidgets(room, Container.Top).length > 0; } public canCopyLayoutToRoom(room: Room): boolean { From a9a2c41e04b12785230d33f4ca0cf74e991654c0 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 8 Nov 2021 19:41:04 +0100 Subject: [PATCH 02/70] fix linter issues --- src/components/structures/RoomView.tsx | 2 +- src/stores/widgets/WidgetLayoutStore.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 5bcf393bd4b..4590da83953 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -196,7 +196,7 @@ export interface IRoomState { rejecting?: boolean; rejectError?: Error; hasPinnedWidgets?: boolean; - mainSplitContentType: MainSplitContentType; + mainSplitContentType?: MainSplitContentType; dragCounter: number; // whether or not a spaces context switch brought us here, // if it did we don't want the room to be marked as read as soon as it is loaded. diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 9ac3b542529..6b0aa4928c1 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -26,7 +26,6 @@ import { SettingLevel } from "../../settings/SettingLevel"; import { arrayFastClone } from "../../utils/arrays"; import { UPDATE_EVENT } from "../AsyncStore"; import { compare } from "../../utils/strings"; -import { some } from "lodash"; export const WIDGET_LAYOUT_EVENT_TYPE = "io.element.widgets.layout"; From cb4ae5f72fcf74043d08dfb6ee45872642254e73 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 8 Nov 2021 19:44:56 +0100 Subject: [PATCH 03/70] fix style lint issues --- res/css/views/rooms/_AppMaximisedDrawer.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/rooms/_AppMaximisedDrawer.scss b/res/css/views/rooms/_AppMaximisedDrawer.scss index 7741afc8f99..af738750711 100644 --- a/res/css/views/rooms/_AppMaximisedDrawer.scss +++ b/res/css/views/rooms/_AppMaximisedDrawer.scss @@ -43,4 +43,4 @@ limitations under the License. width: 0; } } -} \ No newline at end of file +} From e68c8f154181ff17775e1ba9e6d3655aab6e3811 Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Tue, 9 Nov 2021 17:18:52 +0100 Subject: [PATCH 04/70] Update src/components/structures/RoomView.tsx Co-authored-by: J. Ryan Stinnett --- src/components/structures/RoomView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 4590da83953..46bafcb024e 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -327,7 +327,7 @@ export class RoomView extends React.Component { private onWidgetLayoutChange = () => { if (!this.state.room) return; - this.checkWidgets(this.state.room); // we cheat here by calling the thing that matters + this.checkWidgets(this.state.room); }; private checkWidgets = (room) => { From 8608c59f4fc0dbadbfe9e3262d8f80d6228ca001 Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Tue, 9 Nov 2021 17:31:41 +0100 Subject: [PATCH 05/70] fix typo Co-authored-by: J. Ryan Stinnett --- src/stores/widgets/WidgetLayoutStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 6b0aa4928c1..2c2c65edb49 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -214,7 +214,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore { } else { centerWidgets.push(widget); } - // The widget won't need to be put in any oter container. + // The widget won't need to be put in any other container. continue; } let targetContainer = defaultContainer; From bb543a2012fcb1c9bd224134126b194e09f8a401 Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Tue, 9 Nov 2021 17:33:43 +0100 Subject: [PATCH 06/70] typo Co-authored-by: J. Ryan Stinnett --- src/components/views/rooms/AppMaximisedDrawer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/AppMaximisedDrawer.tsx b/src/components/views/rooms/AppMaximisedDrawer.tsx index 6de480ac34d..a82a7f41af9 100644 --- a/src/components/views/rooms/AppMaximisedDrawer.tsx +++ b/src/components/views/rooms/AppMaximisedDrawer.tsx @@ -73,7 +73,7 @@ export default class AppMaximisedDrawer extends React.Component } private onIsResizing = (resizing: boolean): void => { - // This inoformation is needed to make sure the widget does not consume the pointer events for resizing. + // This information is needed to make sure the widget does not consume the pointer events for resizing. this.setState({ resizing: resizing }); }; From 4cc316db78fc185a6cc176f3d9aaa3971d891d99 Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Wed, 10 Nov 2021 13:02:32 +0100 Subject: [PATCH 07/70] Remove caps "AND " Co-authored-by: J. Ryan Stinnett --- src/components/structures/RoomView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 46bafcb024e..c9ed7b7f888 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -120,8 +120,8 @@ interface IRoomProps extends MatrixClientProps { onRegistered?(credentials: IMatrixClientCreds): void; } -// This defines, the content of the mainSplit -// AND if the mainSplit does not contain the Timeline, the chat is shown in the right panel. +// This defines the content of the mainSplit. +// If the mainSplit does not contain the Timeline, the chat is shown in the right panel. enum MainSplitContentType { Timeline, MaximisedWidget, From 4a3b48dc2c37ed5b276b004dff317f3078ddb3fe Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Wed, 10 Nov 2021 13:10:26 +0100 Subject: [PATCH 08/70] fix spelling Co-authored-by: J. Ryan Stinnett --- src/stores/widgets/WidgetLayoutStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 2c2c65edb49..e54e8a573d8 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -210,7 +210,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore { const defaultContainer = WidgetType.JITSI.matches(widget.type) ? Container.Top : Container.Right; if (stateContainer === Container.Center || manualContainer === Container.Center) { if (centerWidgets.length) { - console.error("Tried to push a second Widget into the center container"); + console.error("Tried to push a second widget into the center container"); } else { centerWidgets.push(widget); } From 5d14783bb4c01f11c7752d446cb1bcaa4028d454 Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Wed, 10 Nov 2021 13:11:31 +0100 Subject: [PATCH 09/70] improove readibility for continue in for Co-authored-by: J. Ryan Stinnett --- src/stores/widgets/WidgetLayoutStore.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index e54e8a573d8..e6a87c8eebf 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -451,7 +451,8 @@ export class WidgetLayoutStore extends ReadyWatchingStore { this.moveToContainer(room, w, Container.Right); } for (const w of this.getContainerWidgets(room, Container.Top)) { - if (w !== widget) {this.moveToContainer(room, w, Container.Right);} + if (w === widget) continue; + this.moveToContainer(room, w, Container.Right); } break; case Container.Right: From 74f9b934fff160411bcc3ff5fc6409da3e307a4a Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 14:20:47 +0100 Subject: [PATCH 10/70] review fixes --- res/css/views/rooms/_AppMaximisedDrawer.scss | 2 +- res/css/views/rooms/_AppsDrawer.scss | 4 +- src/components/structures/RoomView.tsx | 73 ++++++++----------- src/components/views/elements/AppTile.tsx | 2 - .../views/rooms/AppMaximisedDrawer.tsx | 2 +- 5 files changed, 33 insertions(+), 50 deletions(-) diff --git a/res/css/views/rooms/_AppMaximisedDrawer.scss b/res/css/views/rooms/_AppMaximisedDrawer.scss index af738750711..bda77f9487f 100644 --- a/res/css/views/rooms/_AppMaximisedDrawer.scss +++ b/res/css/views/rooms/_AppMaximisedDrawer.scss @@ -1,6 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd -Copyright 2019 The Matrix.org Foundation C.I.C. +Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index d88c2166c94..8d8af2d2218 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -228,11 +228,11 @@ $MinWidth: 240px; } .mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_minWidget { - mask-image: url('$(res)/img/element-icons/room/widgets/minimise.svg'); + mask-image: url('$(res)/img/feather-customised/minimise.svg'); } .mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_maxWidget { - mask-image: url('$(res)/img/element-icons/room/widgets/maximise.svg'); + mask-image: url('$(res)/img/feather-customised/maximise.svg'); } .mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_popout { diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index c9ed7b7f888..9658da3849d 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -987,7 +987,6 @@ export class RoomView extends React.Component { if (this.unmounted) return; // Attach a widget store listener only when we get a room WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(room), this.onWidgetLayoutChange); - // this.onWidgetLayoutChange(); // provoke an update // Done with checkwidget now TODO-maximise_widget remove comment after review this.calculatePeekRules(room); this.updatePreviewUrlVisibility(room); @@ -2114,49 +2113,35 @@ export class RoomView extends React.Component { const showChatEffects = SettingsStore.getValue('showChatEffects'); // Decide what to show in the main split - let mainSplitBody; - if (SettingsStore.getValue("feature_maximised_widgets")) { - switch (this.state.mainSplitContentType) { - case MainSplitContentType.Timeline: - mainSplitBody = - { auxPanel } -
- { fileDropTarget } - { topUnreadMessagesBar } - { jumpToBottom } - { messagePanel } - { searchResultsPanel } -
- { statusBarArea } - { previewBar } - { messageComposer } -
; - break; - case MainSplitContentType.MaximisedWidget: - mainSplitBody = ; - break; - // TODO-video MainSplitContentType.Video: - // break; - } - } else { - mainSplitBody = - { auxPanel } -
- { fileDropTarget } - { topUnreadMessagesBar } - { jumpToBottom } - { messagePanel } - { searchResultsPanel } -
- { statusBarArea } - { previewBar } - { messageComposer } -
; + let mainSplitBody = + { auxPanel } +
+ { fileDropTarget } + { topUnreadMessagesBar } + { jumpToBottom } + { messagePanel } + { searchResultsPanel } +
+ { statusBarArea } + { previewBar } + { messageComposer } +
; + + switch (this.state.mainSplitContentType) { + case MainSplitContentType.Timeline: + // keep the timeline in as the mainSplitBody + break; + case MainSplitContentType.MaximisedWidget: + if (!SettingsStore.getValue("feature_maximised_widgets")) {break;} + mainSplitBody = ; + break; + // TODO-video MainSplitContentType.Video: + // break; } return ( diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index b125798a264..54694dec3d4 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -401,8 +401,6 @@ export default class AppTile extends React.Component { }; private onMaxMinWidgetClick = (): void => { - // TODO-video make this not interfere with the new video conference design - const targetContainer = WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Center) ? Container.Right diff --git a/src/components/views/rooms/AppMaximisedDrawer.tsx b/src/components/views/rooms/AppMaximisedDrawer.tsx index a82a7f41af9..262d8a4575e 100644 --- a/src/components/views/rooms/AppMaximisedDrawer.tsx +++ b/src/components/views/rooms/AppMaximisedDrawer.tsx @@ -1,6 +1,6 @@ /* Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd +Copyright 2021 Matrix.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. From cfbdf405d5f8ade78fe45bc9de07fa27bc18d897 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 14:51:16 +0100 Subject: [PATCH 11/70] reuse already added icons --- res/css/views/right_panel/_RoomSummaryCard.scss | 5 +++-- res/img/element-icons/room/widgets/maximise.svg | 3 --- res/img/element-icons/room/widgets/minimise.svg | 3 --- src/stores/widgets/WidgetLayoutStore.ts | 7 +++---- 4 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 res/img/element-icons/room/widgets/maximise.svg delete mode 100644 res/img/element-icons/room/widgets/minimise.svg diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index a414619b2da..1b93b713bdc 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -180,14 +180,15 @@ limitations under the License. right: 48px; &::before { - mask-image: url('$(res)/img/element-icons/room/widgets/maximise.svg'); + background-color: $secondary-fg-color; + mask-image: url('$(res)/img/feather-customised/maximise.svg'); } } .mx_RoomSummaryCard_app_minimise { right: 48px; &::before { background-color: $accent-color; - mask-image: url('$(res)/img/element-icons/room/widgets/minimise.svg'); + mask-image: url('$(res)/img/feather-customised/minimise.svg'); } } diff --git a/res/img/element-icons/room/widgets/maximise.svg b/res/img/element-icons/room/widgets/maximise.svg deleted file mode 100644 index ed6e021299c..00000000000 --- a/res/img/element-icons/room/widgets/maximise.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/res/img/element-icons/room/widgets/minimise.svg b/res/img/element-icons/room/widgets/minimise.svg deleted file mode 100644 index 58c62750c71..00000000000 --- a/res/img/element-icons/room/widgets/minimise.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index e6a87c8eebf..8ca6b3c2714 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -196,10 +196,9 @@ export class WidgetLayoutStore extends ReadyWatchingStore { } const roomLayout: ILayoutStateEvent = layoutEv ? layoutEv.getContent() : null; - - // We essentially just need to find the top container's widgets because we - // only have two containers. Anything not in the top widget by the end of this - // function will go into the right container. + // We filter for the center container. + // (An error is raised, if there are multiple widgets marked for the center container) + // For the right and top container we allow multiple widgets. const topWidgets: IApp[] = []; const rightWidgets: IApp[] = []; const centerWidgets: IApp[] = []; From ffb0af8b69cf7c7209ae817d9263f6ab191829a6 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 14:55:41 +0100 Subject: [PATCH 12/70] more container comment fixes --- src/stores/widgets/WidgetLayoutStore.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 8ca6b3c2714..7567989e969 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -38,8 +38,6 @@ export enum Container { // changes needed", though this may change in the future. Right = "right", - // ... more as needed. Note that most of this code assumes that there - // are only two containers, and that only the top container is special. Center = "center" } @@ -196,9 +194,9 @@ export class WidgetLayoutStore extends ReadyWatchingStore { } const roomLayout: ILayoutStateEvent = layoutEv ? layoutEv.getContent() : null; - // We filter for the center container. + // We filter for the center container first. // (An error is raised, if there are multiple widgets marked for the center container) - // For the right and top container we allow multiple widgets. + // For the right and top container multiple widgets are allowed. const topWidgets: IApp[] = []; const rightWidgets: IApp[] = []; const centerWidgets: IApp[] = []; From 1155ae979313d4c528ec5a0d8fbad5155d516bc4 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 15:12:43 +0100 Subject: [PATCH 13/70] fix app options button the button was at the wrong position when feature flag is disabled --- res/css/views/right_panel/_RoomSummaryCard.scss | 3 +-- src/components/views/right_panel/RoomSummaryCard.tsx | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index 1b93b713bdc..ff1589dadfc 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -180,7 +180,6 @@ limitations under the License. right: 48px; &::before { - background-color: $secondary-fg-color; mask-image: url('$(res)/img/feather-customised/maximise.svg'); } } @@ -193,7 +192,7 @@ limitations under the License. } .mx_RoomSummaryCard_app_options { - right: 72px; + right: 48px; display: none; &::before { diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index 705483cbfe6..d23982ba711 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -167,6 +167,7 @@ const AppRow: React.FC = ({ app, room }) => { onClick={openMenu} title={_t("Options")} yOffset={-24} + style={{ right: SettingsStore.getValue("feature_maximised_widgets")?"72px":"" }} /> Date: Wed, 10 Nov 2021 15:34:43 +0100 Subject: [PATCH 14/70] remove error message --- .../views/rooms/AppMaximisedDrawer.tsx | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/components/views/rooms/AppMaximisedDrawer.tsx b/src/components/views/rooms/AppMaximisedDrawer.tsx index 262d8a4575e..4a997f6a935 100644 --- a/src/components/views/rooms/AppMaximisedDrawer.tsx +++ b/src/components/views/rooms/AppMaximisedDrawer.tsx @@ -85,12 +85,7 @@ export default class AppMaximisedDrawer extends React.Component } private getApp = (): IApp => { - if (WidgetLayoutStore.instance.hasMaximisedWidget(this.props.room)) { - return WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center)[0]; - } else { - console.error("Maximised widget container is shown although there is no app in the center container"); - return undefined; - } + return WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center)[0]; }; private updateApps = (): void => { @@ -100,9 +95,9 @@ export default class AppMaximisedDrawer extends React.Component }; public render(): JSX.Element { - // Should the showApps button also impct the maximied widget? TODO-maximise_widget Remove after review - // if (!this.props.showApps) return
; - + if (!this.state.app) { + return
; + } const app = pointerEvents={this.state.resizing ? 'none' : undefined} />; - if (!app) { - return
; - } - let spinner; if ( !app && WidgetEchoStore.roomHasPendingWidgets( From a76e7ec3caa24c1a05d3f43f146925fe6d01644f Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 15:35:55 +0100 Subject: [PATCH 15/70] fix issue not beeing able to maximise only widgets with a hight index in the list could be maximised if another widget was already maximised --- src/stores/widgets/WidgetLayoutStore.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 7567989e969..5fd9a7d46b5 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -439,27 +439,32 @@ export class WidgetLayoutStore extends ReadyWatchingStore { public moveToContainer(room: Room, widget: IApp, toContainer: Container) { const allWidgets = this.getAllWidgets(room); if (!allWidgets.some(([w]) => w.id === widget.id)) return; // invalid - this.updateUserLayout(room, { - [widget.id]: { container: toContainer }, - }); + // Prepare other containers (potentially move widgets to obay the following rules) switch (toContainer) { + case Container.Right: + // new "right" widget + break; case Container.Center: + // new "center" widget => all other widgets go into "right" for (const w of this.getContainerWidgets(room, Container.Top)) { this.moveToContainer(room, w, Container.Right); } - for (const w of this.getContainerWidgets(room, Container.Top)) { - if (w === widget) continue; + for (const w of this.getContainerWidgets(room, Container.Center)) { this.moveToContainer(room, w, Container.Right); } break; - case Container.Right: - break; case Container.Top: + // new "top" widget => the center widget moves into "right" if (this.hasMaximisedWidget(room) && toContainer) { this.moveToContainer(room, this.getContainerWidgets(room, Container.Center)[0], Container.Right); } break; } + + // move widgets into requested container. + this.updateUserLayout(room, { + [widget.id]: { container: toContainer }, + }); } public hasMaximisedWidget(room: Room) { From 04e0b42c29ec6e3536f05de10c0508752457844e Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 18:23:17 +0100 Subject: [PATCH 16/70] remove maxmimisedDrawer -> add the logic to the AppDrawer --- res/css/_components.scss | 1 - res/css/views/rooms/_AppMaximisedDrawer.scss | 46 ------ src/components/structures/RoomView.tsx | 4 +- .../views/rooms/AppMaximisedDrawer.tsx | 134 ------------------ src/components/views/rooms/AppsDrawer.tsx | 74 ++++++---- 5 files changed, 49 insertions(+), 210 deletions(-) delete mode 100644 res/css/views/rooms/_AppMaximisedDrawer.scss delete mode 100644 src/components/views/rooms/AppMaximisedDrawer.tsx diff --git a/res/css/_components.scss b/res/css/_components.scss index 866b26d9acf..d4c383b1fe6 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -208,7 +208,6 @@ @import "./views/right_panel/_VerificationPanel.scss"; @import "./views/right_panel/_WidgetCard.scss"; @import "./views/room_settings/_AliasSettings.scss"; -@import "./views/rooms/_AppMaximisedDrawer.scss"; @import "./views/rooms/_AppsDrawer.scss"; @import "./views/rooms/_Autocomplete.scss"; @import "./views/rooms/_AuxPanel.scss"; diff --git a/res/css/views/rooms/_AppMaximisedDrawer.scss b/res/css/views/rooms/_AppMaximisedDrawer.scss deleted file mode 100644 index bda77f9487f..00000000000 --- a/res/css/views/rooms/_AppMaximisedDrawer.scss +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2021 The Matrix.org Foundation C.I.C. - -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. -*/ - -.mx_AppMaximisedContainer { - display: flex; - flex-direction: row; - align-items: stretch; - justify-content: center; - height: 100%; - width: 100%; - flex: 1; - flex-grow: 1; - min-height: 0; - padding: 5px; - - .mx_AppTile:first-of-type { - border-left-width: 8px; - border-radius: 10px 0 0 10px; - } - .mx_AppTile:last-of-type { - border-right-width: 8px; - border-radius: 0 10px 10px 0; - } - - .mx_ResizeHandle_horizontal { - position: relative; - - > div { - width: 0; - } - } -} diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 9658da3849d..76ff6bb3e89 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -95,7 +95,7 @@ import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline'; import { dispatchShowThreadEvent } from '../../dispatcher/dispatch-actions/threads'; import { fetchInitialEvent } from "../../utils/EventUtils"; import { ComposerType } from "../../dispatcher/payloads/ComposerInsertPayload"; -import AppMaximisedDrawer from '../views/rooms/AppMaximisedDrawer'; +import AppsDrawer from '../views/rooms/AppsDrawer'; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -2133,7 +2133,7 @@ export class RoomView extends React.Component { break; case MainSplitContentType.MaximisedWidget: if (!SettingsStore.getValue("feature_maximised_widgets")) {break;} - mainSplitBody = { - private dispatcherRef: string; - public static defaultProps: Partial = { - showApps: true, - }; - - constructor(props: IProps) { - super(props); - - this.state = { - app: this.getApp(), - resizing: false, - }; - - this.props.resizeNotifier.on("isResizing", this.onIsResizing); - } - - public componentDidMount(): void { - ScalarMessaging.startListening(); - WidgetLayoutStore.instance.on(WidgetLayoutStore.emissionForRoom(this.props.room), this.updateApps); - } - - public componentWillUnmount(): void { - ScalarMessaging.stopListening(); - WidgetLayoutStore.instance.off(WidgetLayoutStore.emissionForRoom(this.props.room), this.updateApps); - if (this.dispatcherRef) dis.unregister(this.dispatcherRef); - this.props.resizeNotifier.off("isResizing", this.onIsResizing); - } - - private onIsResizing = (resizing: boolean): void => { - // This information is needed to make sure the widget does not consume the pointer events for resizing. - this.setState({ resizing: resizing }); - }; - - public componentDidUpdate(prevProps: IProps, prevState: IState): void { - if (prevProps.userId !== this.props.userId || prevProps.room !== this.props.room) { - // Room has changed, update app - this.updateApps(); - } - } - - private getApp = (): IApp => { - return WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center)[0]; - }; - - private updateApps = (): void => { - this.setState({ - app: this.getApp(), - }); - }; - - public render(): JSX.Element { - if (!this.state.app) { - return
; - } - const app = ; - - let spinner; - if ( - !app && WidgetEchoStore.roomHasPendingWidgets( - this.props.room.roomId, - WidgetUtils.getRoomWidgets(this.props.room), - ) - ) { - const Loader = sdk.getComponent("elements.Spinner"); - spinner = ; - } - return ( - -
- - { app } - -
- { spinner } -
- ); - } -} diff --git a/src/components/views/rooms/AppsDrawer.tsx b/src/components/views/rooms/AppsDrawer.tsx index e4bbd3a2886..358a3d1a8bb 100644 --- a/src/components/views/rooms/AppsDrawer.tsx +++ b/src/components/views/rooms/AppsDrawer.tsx @@ -47,7 +47,8 @@ interface IProps { } interface IState { - apps: IApp[]; + // @ts-ignore - TS wants a string key, but we know better + apps: {[id: Container]: IApp[]}; resizingVertical: boolean; // true when changing the height of the apps drawer resizingHorizontal: boolean; // true when chagning the distribution of the width between widgets resizing: boolean; @@ -118,7 +119,7 @@ export default class AppsDrawer extends React.Component { this.resizeContainer.classList.remove("mx_AppsDrawer_resizing"); WidgetLayoutStore.instance.setResizerDistributions( this.props.room, Container.Top, - this.state.apps.slice(1).map((_, i) => this.resizer.forHandleAt(i).size), + this.topApps().slice(1).map((_, i) => this.resizer.forHandleAt(i).size), ); this.setState({ resizingHorizontal: false }); }, @@ -148,7 +149,8 @@ export default class AppsDrawer extends React.Component { if (prevProps.userId !== this.props.userId || prevProps.room !== this.props.room) { // Room has changed, update apps this.updateApps(); - } else if (this.getAppsHash(this.state.apps) !== this.getAppsHash(prevState.apps)) { + } else if (this.getAppsHash(this.topApps()) + !== this.getAppsHash(prevState.apps[Container.Top])) { this.loadResizerPreferences(); } } @@ -163,7 +165,7 @@ export default class AppsDrawer extends React.Component { private loadResizerPreferences = (): void => { const distributions = WidgetLayoutStore.instance.getResizerDistributions(this.props.room, Container.Top); - if (this.state.apps && (this.state.apps.length - 1) === distributions.length) { + if (this.state.apps && (this.topApps().length - 1) === distributions.length) { distributions.forEach((size, i) => { const distributor = this.resizer.forHandleAt(i); if (distributor) { @@ -200,8 +202,16 @@ export default class AppsDrawer extends React.Component { break; } }; - - private getApps = (): IApp[] => WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Top); + // @ts-ignore - TS wants a string key, but we know better + private getApps = (): { [id: Container]: IApp[] } => { + // @ts-ignore + const appsDict: { [id: Container]: IApp[] } = {}; + appsDict[Container.Top] = WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Top); + appsDict[Container.Center] = WidgetLayoutStore.instance.getContainerWidgets(this.props.room, Container.Center); + return appsDict; + }; + private topApps = (): IApp[] => this.state.apps[Container.Top]; + private centerApps = (): IApp[] => this.state.apps[Container.Center]; private updateApps = (): void => { this.setState({ @@ -211,8 +221,9 @@ export default class AppsDrawer extends React.Component { public render(): JSX.Element { if (!this.props.showApps) return
; - - const apps = this.state.apps.map((app, index, arr) => { + const widgetIsMaxmised: boolean = this.centerApps().length > 0; + const appsToDisplay = widgetIsMaxmised ? this.centerApps() : this.topApps(); + const apps = appsToDisplay.map((app, index, arr) => { return ( { const classes = classNames({ mx_AppsDrawer: true, + mx_AppsDrawer_maximise: widgetIsMaxmised, mx_AppsDrawer_fullWidth: apps.length < 2, mx_AppsDrawer_resizing: this.state.resizing, mx_AppsDrawer_2apps: apps.length === 2, mx_AppsDrawer_3apps: apps.length === 3, }); + const appConatiners = +
+ { apps.map((app, i) => { + if (i < 1) return app; + return + apps.length / 2} /> + { app } + ; + }) } +
; + + let drawer; + if (widgetIsMaxmised) { + drawer = appConatiners; + } else { + drawer = + { appConatiners } + ; + } return (
- -
- { apps.map((app, i) => { - if (i < 1) return app; - return - apps.length / 2} /> - { app } - ; - }) } -
-
+ { drawer } { spinner }
); From 21b9549c7685d4c5b07022bc53f4c0db741c2343 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 18:24:53 +0100 Subject: [PATCH 17/70] fix centering and overflow of appDrawer if maximised and right panel closed --- res/css/structures/_MainSplit.scss | 6 +++--- res/css/views/elements/_ResizeHandle.scss | 4 ++-- res/css/views/rooms/_AppsDrawer.scss | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index 407a1c270cf..263ded74832 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -23,9 +23,9 @@ limitations under the License. } .mx_MainSplit > .mx_RightPanel_ResizeWrapper { - padding: 5px; - // margin left to not allow the handle to not encroach on the space for the scrollbar - margin-left: 8px; + // no padding on the left. The spacing is taken care of by the main split content. + padding: 5px 5px 5px 0px; + // margin-left: 0px; height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel &:hover .mx_RightPanel_ResizeHandle { diff --git a/res/css/views/elements/_ResizeHandle.scss b/res/css/views/elements/_ResizeHandle.scss index 63c5d978611..bf56888da09 100644 --- a/res/css/views/elements/_ResizeHandle.scss +++ b/res/css/views/elements/_ResizeHandle.scss @@ -33,8 +33,8 @@ limitations under the License. } .mx_MatrixChat > .mx_ResizeHandle.mx_ResizeHandle_horizontal { - margin: 0 -10px 0 0; - padding: 0 8px 0 0; + // margin: 0 0px 0 0; + // padding: 0 8px 0 0; } .mx_ResizeHandle.mx_ResizeHandle_horizontal > div { diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 8d8af2d2218..aca333e71cf 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -18,11 +18,12 @@ limitations under the License. $MiniAppTileHeight: 200px; .mx_AppsDrawer { - margin: 5px 5px 5px 18px; + margin: 5px 5px 5px 5px; position: relative; display: flex; flex-direction: column; overflow: hidden; + flex-grow: 1; .mx_AppsContainer_resizerHandleContainer { width: 100%; From 38f8cfee8e44abd4a68b55b22a9817fa76816ec2 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 11 Nov 2021 11:12:05 +0100 Subject: [PATCH 18/70] fix hover label "Minimise widget"->"Close" --- src/components/views/elements/AppTile.tsx | 2 +- src/components/views/right_panel/RoomSummaryCard.tsx | 2 +- src/i18n/strings/en_EN.json | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index 54694dec3d4..a1b2933125c 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -542,7 +542,7 @@ export default class AppTile extends React.Component { : " mx_AppTileMenuBar_iconButton_maxWidget") } title={ - widgetIsMaximised ? _t('Minimise widget'): _t('Maximise widget') + widgetIsMaximised ? _t('Close'): _t('Maximise widget') } onClick={this.onMaxMinWidgetClick} />; diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index d23982ba711..e27a658d9ae 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -144,7 +144,7 @@ const AppRow: React.FC = ({ app, room }) => { ? () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); } : () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Center); }; - const maximiseTitle = isMaximised ? _t("Minimise widget") : _t("Maximise widget"); + const maximiseTitle = isMaximised ? _t("Close") : _t("Maximise widget"); return
Date: Wed, 10 Nov 2021 20:00:08 +0100 Subject: [PATCH 19/70] right panel chat timeline --- res/css/_components.scss | 1 + res/css/structures/_RightPanel.scss | 7 + res/css/structures/_TimelineCard.scss | 66 +++++++ src/components/structures/MessagePanel.tsx | 3 + src/components/structures/RightPanel.tsx | 14 +- src/components/structures/ThreadView.tsx | 3 +- src/components/structures/TimelineCard.tsx | 171 ++++++++++++++++++ src/components/structures/TimelinePanel.tsx | 3 + .../views/right_panel/RoomHeaderButtons.tsx | 28 +++ src/components/views/rooms/EventTile.tsx | 19 +- .../AfterRightPanelPhaseChangePayload.ts | 1 + src/i18n/strings/en_EN.json | 2 + src/stores/RightPanelStore.ts | 1 + src/stores/RightPanelStorePhases.ts | 1 + 14 files changed, 312 insertions(+), 8 deletions(-) create mode 100644 res/css/structures/_TimelineCard.scss create mode 100644 src/components/structures/TimelineCard.tsx diff --git a/res/css/_components.scss b/res/css/_components.scss index d4c383b1fe6..410f08b69cc 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -33,6 +33,7 @@ @import "./structures/_SpacePanel.scss"; @import "./structures/_SpaceRoomView.scss"; @import "./structures/_TabbedView.scss"; +@import "./structures/_TimelineCard.scss"; @import "./structures/_ToastContainer.scss"; @import "./structures/_UploadBar.scss"; @import "./structures/_UserMenu.scss"; diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss index 51d7693cff8..ada35962406 100644 --- a/res/css/structures/_RightPanel.scss +++ b/res/css/structures/_RightPanel.scss @@ -144,6 +144,13 @@ $pulse-color: $notice-primary-color; } } +.mx_RightPanel_timelinePanelButton { + &::before { + mask-image: url('$(res)/img/element-icons/feedback.svg'); + mask-position: center; + } +} + @keyframes mx_RightPanel_indicator_pulse { 0% { transform: scale(0.95); diff --git a/res/css/structures/_TimelineCard.scss b/res/css/structures/_TimelineCard.scss new file mode 100644 index 00000000000..3113faa7c9e --- /dev/null +++ b/res/css/structures/_TimelineCard.scss @@ -0,0 +1,66 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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. +*/ + +.mx_TimelineCard { + display: flex; + flex-direction: column; + + padding-right: 0; + + + + .mx_TimelineCard__header { + width: calc(100% - 60px); + margin-left: 6px; + margin-bottom: 4px; + display: flex; + flex: 1; + justify-content: space-between; + align-items: center; + + span:first-of-type { + font-weight: 600; + font-size: 15px; + line-height: 18px; + color: $secondary-content; + } + } + + .mx_AutoHideScrollbar { + border-radius: 8px; + } + + .mx_RoomView_messageListWrapper { + background-color: $background; + padding: 8px; + border-radius: inherit; + } + + .mx_ScrollPanel { + .mx_RoomView_MessageList { + padding: 0; + } + } + + .mx_MessageComposer { + background-color: $background; + border-radius: 8px; + margin-top: 8px; + width: calc(100% - 8px); + padding: 0 8px; + box-sizing: border-box; + } +} diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 6a204775dc0..0f013791a42 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -50,6 +50,7 @@ import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; import EditorStateTransfer from "../../utils/EditorStateTransfer"; import { logger } from 'matrix-js-sdk/src/logger'; import { Action } from '../../dispatcher/actions'; +import { RightPanelPhases } from '../../stores/RightPanelStorePhases'; const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes const continuedTypes = [EventType.Sticker, EventType.RoomMessage]; @@ -179,6 +180,7 @@ interface IProps { getRelationsForEvent?(eventId: string, relationType: string, eventType: string): Relations; hideThreadedMessages?: boolean; + threadViewPreviousCard?: RightPanelPhases; } interface IState { @@ -789,6 +791,7 @@ export default class MessagePanel extends React.Component { callEventGrouper={callEventGrouper} hideSender={this.membersCount <= 2 && this.props.layout === Layout.Bubble} timelineRenderingType={this.context.timelineRenderingType} + threadViewPreviousCard={this.props.threadViewPreviousCard} /> , ); diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 16ef8918505..56f991d89b3 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -54,6 +54,7 @@ import SpaceStore from "../../stores/SpaceStore"; import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks'; import { E2EStatus } from '../../utils/ShieldUtils'; import { dispatchShowThreadsPanelEvent } from '../../dispatcher/dispatch-actions/threads'; +import TimelineCard from './TimelineCard'; interface IProps { room?: Room; // if showing panels for a given room, this is set @@ -66,6 +67,7 @@ interface IProps { interface IState { phase: RightPanelPhases; + previousPhase?: RightPanelPhases; isUserPrivilegedInGroup?: boolean; member?: RoomMember; verificationRequest?: VerificationRequest; @@ -219,6 +221,7 @@ export default class RightPanel extends React.Component { verificationRequestPromise: payload.verificationRequestPromise, widgetId: payload.widgetId, space: payload.space, + previousPhase: payload.previousPhase, }); } }; @@ -334,7 +337,13 @@ export default class RightPanel extends React.Component { panel = ; } break; - + case RightPanelPhases.TimelinePanel: + if (!SettingsStore.getValue("feature_maximised_widgets")) { break; } + panel = ; + break; case RightPanelPhases.FilePanel: panel = ; break; @@ -348,7 +357,8 @@ export default class RightPanel extends React.Component { initialEvent={this.state.initialEvent} initialEventHighlighted={this.state.initialEventHighlighted} permalinkCreator={this.props.permalinkCreator} - e2eStatus={this.props.e2eStatus} />; + e2eStatus={this.props.e2eStatus} + previousPhase={this.state.previousPhase} />; break; case RightPanelPhases.ThreadPanel: diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index 04c7ff576c6..caf604f583a 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -51,6 +51,7 @@ interface IProps { e2eStatus?: E2EStatus; initialEvent?: MatrixEvent; initialEventHighlighted?: boolean; + previousPhase?: RightPanelPhases; } interface IState { thread?: Thread; @@ -213,7 +214,7 @@ export default class ThreadView extends React.Component { diff --git a/src/components/structures/TimelineCard.tsx b/src/components/structures/TimelineCard.tsx new file mode 100644 index 00000000000..13d3c6b4d09 --- /dev/null +++ b/src/components/structures/TimelineCard.tsx @@ -0,0 +1,171 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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 React from 'react'; +import { MatrixEvent, Room } from 'matrix-js-sdk/src'; +import { Thread } from 'matrix-js-sdk/src/models/thread'; + +import BaseCard from "../views/right_panel/BaseCard"; +import { RightPanelPhases } from "../../stores/RightPanelStorePhases"; + +import ResizeNotifier from '../../utils/ResizeNotifier'; +import MessageComposer from '../views/rooms/MessageComposer'; +import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks'; +import { Layout } from '../../settings/Layout'; +import TimelinePanel from './TimelinePanel'; +import { E2EStatus } from '../../utils/ShieldUtils'; +import EditorStateTransfer from '../../utils/EditorStateTransfer'; +import RoomContext from '../../contexts/RoomContext'; + +import { _t } from '../../languageHandler'; +import { replaceableComponent } from '../../utils/replaceableComponent'; + +interface IProps { + room: Room; + onClose: () => void; + resizeNotifier: ResizeNotifier; + permalinkCreator?: RoomPermalinkCreator; + e2eStatus?: E2EStatus; + initialEvent?: MatrixEvent; + initialEventHighlighted?: boolean; +} +interface IState { + thread?: Thread; + editState?: EditorStateTransfer; + replyToEvent?: MatrixEvent; +} + +@replaceableComponent("structures.TimelineCard") +export default class TimelineCard extends React.Component { + static contextType = RoomContext; + + private messagePanel: TimelinePanel; + + constructor(props: IProps) { + super(props); + this.state = {}; + } + public componentDidMount(): void { + + } + + public componentWillUnmount(): void { + + } + + public componentDidUpdate(prevProps) { + + } + + private renderTimelineCardHeader = (): JSX.Element => { + return
+ { _t("Chat") } +
; + }; + + private gatherTimelinePanelRef = r => { + this.messagePanel = r; + }; + + private onMessageListScroll = ev => { + // if (this.messagePanel.isAtEndOfLiveTimeline()) { + // this.setState({ + // numUnreadMessages: 0, + // atEndOfLiveTimeline: true, + // }); + // } else { + // this.setState({ + // atEndOfLiveTimeline: false, + // }); + // } + // this.updateTopUnreadMessagesBar(); + }; + + private onUserScroll = () => { + // if (this.state.initialEventId && this.state.isInitialEventHighlighted) { + // dis.dispatch({ + // action: 'view_room', + // room_id: this.state.room.roomId, + // event_id: this.state.initialEventId, + // highlighted: false, + // replyingToEvent: this.state.replyToEvent, + // }); + // } + }; + + // decide whether or not the top 'unread messages' bar should be shown + private updateTopUnreadMessagesBar = () => { + if (!this.messagePanel) { + return; + } + + // const showBar = this.messagePanel.canJumpToReadMarker(); + // if (this.state.showTopUnreadMessagesBar != showBar) { + // this.setState({ showTopUnreadMessagesBar: showBar }); + // } + }; + + public render(): JSX.Element { + return ( + + + // + ); + } +} diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index 495d3c438ff..d75d8afda99 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -50,6 +50,7 @@ import ErrorDialog from '../views/dialogs/ErrorDialog'; import { debounce } from 'lodash'; import { logger } from "matrix-js-sdk/src/logger"; +import { RightPanelPhases } from '../../stores/RightPanelStorePhases'; const PAGINATE_SIZE = 20; const INITIAL_SIZE = 20; @@ -133,6 +134,7 @@ interface IProps { onPaginationRequest?(timelineWindow: TimelineWindow, direction: string, size: number): Promise; hideThreadedMessages?: boolean; + threadViewPreviousCard?: RightPanelPhases; } interface IState { @@ -1539,6 +1541,7 @@ class TimelinePanel extends React.Component { layout={this.props.layout} enableFlair={SettingsStore.getValue(UIFeature.Flair)} hideThreadedMessages={this.props.hideThreadedMessages} + threadViewPreviousCard={this.props.threadViewPreviousCard} /> ); } diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index fabe46c1154..77af874082d 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -66,6 +66,25 @@ const PinnedMessagesHeaderButton = ({ room, isHighlighted, onClick }) => { ; }; +const TimelinePanelHeaderButton = ({ room, isHighlighted, showNewMessage, onClick }) => { + if (!SettingsStore.getValue("feature_maximised_widgets")) return null; + + let unreadIndicator; + if (/*pinnedEvents.some(id => !readPinnedEvents.has(id)*/ showNewMessage) { + unreadIndicator =
; + } + + return + { unreadIndicator } + ; +}; + interface IProps { room?: Room; } @@ -116,6 +135,9 @@ export default class RoomHeaderButtons extends HeaderButtons { // This toggles for us, if needed this.setPhase(RightPanelPhases.PinnedMessages); }; + private onTimelinePanelClicked = () => { + this.setPhase(RightPanelPhases.TimelinePanel); + }; public renderButtons() { return <> @@ -124,6 +146,12 @@ export default class RoomHeaderButtons extends HeaderButtons { isHighlighted={this.isPhase(RightPanelPhases.PinnedMessages)} onClick={this.onPinnedMessagesClicked} /> + { SettingsStore.getValue("feature_thread") && {
{ - dispatchShowThreadEvent( - this.props.mxEvent, - ); + dispatchShowThreadEvent(this.props.mxEvent, + undefined, + undefined, + this.props.threadViewPreviousCard ); }} > @@ -1337,7 +1340,10 @@ export default class EventTile extends React.Component { "data-has-reply": !!replyChain, "onMouseEnter": () => this.setState({ hover: true }), "onMouseLeave": () => this.setState({ hover: false }), - "onClick": () => dispatchShowThreadEvent(this.props.mxEvent), + "onClick": () => dispatchShowThreadEvent(this.props.mxEvent, + undefined, + undefined, + this.props.threadViewPreviousCard ), }, <> { sender } { avatar } @@ -1363,7 +1369,10 @@ export default class EventTile extends React.Component { dispatchShowThreadEvent(this.props.mxEvent)} + onClick={() => dispatchShowThreadEvent(this.props.mxEvent, + undefined, + undefined, + this.props.threadViewPreviousCard )} key="thread" /> ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 5b284f4322f..99b634ba6f6 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1850,6 +1850,7 @@ "Nothing pinned, yet": "Nothing pinned, yet", "If you have permissions, open the menu on any message and select Pin to stick them here.": "If you have permissions, open the menu on any message and select Pin to stick them here.", "Pinned messages": "Pinned messages", + "Chat panel": "Chat panel", "Threads": "Threads", "Room Info": "Room Info", "You can only pin up to %(count)s widgets|other": "You can only pin up to %(count)s widgets", @@ -3013,6 +3014,7 @@ "All threads": "All threads", "Shows all threads from current room": "Shows all threads from current room", "Show:": "Show:", + "Chat": "Chat", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", diff --git a/src/stores/RightPanelStore.ts b/src/stores/RightPanelStore.ts index f9e0a578eb3..cc3451514e2 100644 --- a/src/stores/RightPanelStore.ts +++ b/src/stores/RightPanelStore.ts @@ -219,6 +219,7 @@ export default class RightPanelStore extends Store { dis.dispatch({ action: Action.AfterRightPanelPhaseChange, phase: targetPhase, + previousPhase: this.state.previousPhase, ...(refireParams || {}), }); break; diff --git a/src/stores/RightPanelStorePhases.ts b/src/stores/RightPanelStorePhases.ts index 96a585b6761..71aa24db6bd 100644 --- a/src/stores/RightPanelStorePhases.ts +++ b/src/stores/RightPanelStorePhases.ts @@ -25,6 +25,7 @@ export enum RightPanelPhases { RoomSummary = 'RoomSummary', Widget = 'Widget', PinnedMessages = "PinnedMessages", + TimelinePanel = "TimelinePanel", Room3pidMemberInfo = 'Room3pidMemberInfo', // Group stuff From 0df2b82cd8e8e7a0ff763efd1134f67aaa67b18e Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 20:49:35 +0100 Subject: [PATCH 20/70] automatically switch to TimelineCard on maximise --- src/stores/widgets/WidgetLayoutStore.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 5fd9a7d46b5..977269efacb 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -26,6 +26,10 @@ import { SettingLevel } from "../../settings/SettingLevel"; import { arrayFastClone } from "../../utils/arrays"; import { UPDATE_EVENT } from "../AsyncStore"; import { compare } from "../../utils/strings"; +import dis from '../../dispatcher/dispatcher'; +import { SetRightPanelPhasePayload } from "../../dispatcher/payloads/SetRightPanelPhasePayload"; +import { Action } from "../../dispatcher/actions"; +import { RightPanelPhases } from "../RightPanelStorePhases"; export const WIDGET_LAYOUT_EVENT_TYPE = "io.element.widgets.layout"; @@ -452,6 +456,11 @@ export class WidgetLayoutStore extends ReadyWatchingStore { for (const w of this.getContainerWidgets(room, Container.Center)) { this.moveToContainer(room, w, Container.Right); } + // Additionally change the right panel phase to chat: + dis.dispatch({ + action: Action.SetRightPanelPhase, + phase: RightPanelPhases.TimelinePanel, + }); break; case Container.Top: // new "top" widget => the center widget moves into "right" From bddb05f96620ddf2a62b90e9b1e04c9e78d3d136 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 10 Nov 2021 21:19:50 +0100 Subject: [PATCH 21/70] fix style and compile errors --- res/css/structures/_TimelineCard.scss | 4 +--- src/components/views/rooms/EventTile.tsx | 15 +++------------ 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/res/css/structures/_TimelineCard.scss b/res/css/structures/_TimelineCard.scss index 3113faa7c9e..35eadaa3670 100644 --- a/res/css/structures/_TimelineCard.scss +++ b/res/css/structures/_TimelineCard.scss @@ -20,8 +20,6 @@ limitations under the License. padding-right: 0; - - .mx_TimelineCard__header { width: calc(100% - 60px); margin-left: 6px; @@ -30,7 +28,7 @@ limitations under the License. flex: 1; justify-content: space-between; align-items: center; - + span:first-of-type { font-weight: 600; font-size: 15px; diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 57fc54d2290..0db17292c16 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -617,10 +617,7 @@ export default class EventTile extends React.Component {
{ - dispatchShowThreadEvent(this.props.mxEvent, - undefined, - undefined, - this.props.threadViewPreviousCard ); + dispatchShowThreadEvent(this.props.mxEvent); }} > @@ -1340,10 +1337,7 @@ export default class EventTile extends React.Component { "data-has-reply": !!replyChain, "onMouseEnter": () => this.setState({ hover: true }), "onMouseLeave": () => this.setState({ hover: false }), - "onClick": () => dispatchShowThreadEvent(this.props.mxEvent, - undefined, - undefined, - this.props.threadViewPreviousCard ), + "onClick": () => dispatchShowThreadEvent(this.props.mxEvent), }, <> { sender } { avatar } @@ -1369,10 +1363,7 @@ export default class EventTile extends React.Component { dispatchShowThreadEvent(this.props.mxEvent, - undefined, - undefined, - this.props.threadViewPreviousCard )} + onClick={() => dispatchShowThreadEvent(this.props.mxEvent)} key="thread" /> Date: Thu, 11 Nov 2021 11:07:03 +0100 Subject: [PATCH 22/70] fix highlighting and labels --- src/components/views/right_panel/RoomHeaderButtons.tsx | 4 ++-- src/components/views/rooms/EventTile.tsx | 3 +-- src/i18n/strings/en_EN.json | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index 77af874082d..5c1bbba0d12 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -76,7 +76,7 @@ const TimelinePanelHeaderButton = ({ room, isHighlighted, showNewMessage, onClic return { /> diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 0db17292c16..3686c893e4a 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -618,8 +618,7 @@ export default class EventTile extends React.Component { className="mx_ThreadInfo" onClick={() => { dispatchShowThreadEvent(this.props.mxEvent); - }} - > + }} > { _t("%(count)s reply", { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 99b634ba6f6..de15f8cc61a 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1850,7 +1850,7 @@ "Nothing pinned, yet": "Nothing pinned, yet", "If you have permissions, open the menu on any message and select Pin to stick them here.": "If you have permissions, open the menu on any message and select Pin to stick them here.", "Pinned messages": "Pinned messages", - "Chat panel": "Chat panel", + "Chat": "Chat", "Threads": "Threads", "Room Info": "Room Info", "You can only pin up to %(count)s widgets|other": "You can only pin up to %(count)s widgets", @@ -3014,7 +3014,6 @@ "All threads": "All threads", "Shows all threads from current room": "Shows all threads from current room", "Show:": "Show:", - "Chat": "Chat", "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.", "Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.", "Failed to load timeline position": "Failed to load timeline position", From c3a640975c4d3da649d36758a9a8397afb27a3b0 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 11 Nov 2021 11:46:56 +0100 Subject: [PATCH 23/70] rename timelinePanel-> timelineCard --- res/css/structures/_RightPanel.scss | 2 +- src/components/structures/RightPanel.tsx | 2 +- src/components/structures/TimelineCard.tsx | 2 +- .../views/right_panel/RoomHeaderButtons.tsx | 14 +++++++------- src/stores/RightPanelStorePhases.ts | 2 +- src/stores/widgets/WidgetLayoutStore.ts | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss index ada35962406..af0f0db0f51 100644 --- a/res/css/structures/_RightPanel.scss +++ b/res/css/structures/_RightPanel.scss @@ -144,7 +144,7 @@ $pulse-color: $notice-primary-color; } } -.mx_RightPanel_timelinePanelButton { +.mx_RightPanel_timelineCardButton { &::before { mask-image: url('$(res)/img/element-icons/feedback.svg'); mask-position: center; diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 56f991d89b3..5661ec83461 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -337,7 +337,7 @@ export default class RightPanel extends React.Component { panel = ; } break; - case RightPanelPhases.TimelinePanel: + case RightPanelPhases.TimelineCard: if (!SettingsStore.getValue("feature_maximised_widgets")) { break; } panel = { sendReadReceiptOnLoad={true} // No RR support in thread's MVP timelineSet={this.props.room.getUnfilteredTimelineSet()} showUrlPreview={true} - threadViewPreviousCard={RightPanelPhases.TimelinePanel} + threadViewPreviousCard={RightPanelPhases.TimelineCard} layout={Layout.Group} hideThreadedMessages={false} hidden={false} diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index 5c1bbba0d12..88427284b1a 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -66,7 +66,7 @@ const PinnedMessagesHeaderButton = ({ room, isHighlighted, onClick }) => { ; }; -const TimelinePanelHeaderButton = ({ room, isHighlighted, showNewMessage, onClick }) => { +const TimelineCardHeaderButton = ({ room, isHighlighted, showNewMessage, onClick }) => { if (!SettingsStore.getValue("feature_maximised_widgets")) return null; let unreadIndicator; @@ -75,7 +75,7 @@ const TimelinePanelHeaderButton = ({ room, isHighlighted, showNewMessage, onClic } return { // This toggles for us, if needed this.setPhase(RightPanelPhases.PinnedMessages); }; - private onTimelinePanelClicked = () => { - this.setPhase(RightPanelPhases.TimelinePanel); + private onTimelineCardClicked = () => { + this.setPhase(RightPanelPhases.TimelineCard); }; public renderButtons() { @@ -146,11 +146,11 @@ export default class RoomHeaderButtons extends HeaderButtons { isHighlighted={this.isPhase(RightPanelPhases.PinnedMessages)} onClick={this.onPinnedMessagesClicked} /> - { SettingsStore.getValue("feature_thread") && ({ action: Action.SetRightPanelPhase, - phase: RightPanelPhases.TimelinePanel, + phase: RightPanelPhases.TimelineCard, }); break; case Container.Top: From 6fb6e6d3908a17b710a0004b1a6d171851cea44c Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 11 Nov 2021 12:17:07 +0100 Subject: [PATCH 24/70] simplify previous phase access - the previous phase is stored inside the RightPanelStore.sharedinstace and does not need to be part of the RightPanel --- src/components/structures/RightPanel.tsx | 4 +--- src/dispatcher/payloads/AfterRightPanelPhaseChangePayload.ts | 1 - src/stores/RightPanelStore.ts | 1 - src/stores/RightPanelStorePhases.ts | 1 + 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 5661ec83461..9d7eebc9320 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -67,7 +67,6 @@ interface IProps { interface IState { phase: RightPanelPhases; - previousPhase?: RightPanelPhases; isUserPrivilegedInGroup?: boolean; member?: RoomMember; verificationRequest?: VerificationRequest; @@ -221,7 +220,6 @@ export default class RightPanel extends React.Component { verificationRequestPromise: payload.verificationRequestPromise, widgetId: payload.widgetId, space: payload.space, - previousPhase: payload.previousPhase, }); } }; @@ -358,7 +356,7 @@ export default class RightPanel extends React.Component { initialEventHighlighted={this.state.initialEventHighlighted} permalinkCreator={this.props.permalinkCreator} e2eStatus={this.props.e2eStatus} - previousPhase={this.state.previousPhase} />; + previousPhase={RightPanelStore.getSharedInstance().previousPhase} />; break; case RightPanelPhases.ThreadPanel: diff --git a/src/dispatcher/payloads/AfterRightPanelPhaseChangePayload.ts b/src/dispatcher/payloads/AfterRightPanelPhaseChangePayload.ts index bede512095b..cfd4a2d3cc6 100644 --- a/src/dispatcher/payloads/AfterRightPanelPhaseChangePayload.ts +++ b/src/dispatcher/payloads/AfterRightPanelPhaseChangePayload.ts @@ -23,7 +23,6 @@ import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/reque interface AfterRightPanelPhaseChangeAction extends ActionPayload { action: Action.AfterRightPanelPhaseChange; phase: RightPanelPhases; - previousPhase: RightPanelPhases; verificationRequestPromise?: Promise; } diff --git a/src/stores/RightPanelStore.ts b/src/stores/RightPanelStore.ts index cc3451514e2..f9e0a578eb3 100644 --- a/src/stores/RightPanelStore.ts +++ b/src/stores/RightPanelStore.ts @@ -219,7 +219,6 @@ export default class RightPanelStore extends Store { dis.dispatch({ action: Action.AfterRightPanelPhaseChange, phase: targetPhase, - previousPhase: this.state.previousPhase, ...(refireParams || {}), }); break; diff --git a/src/stores/RightPanelStorePhases.ts b/src/stores/RightPanelStorePhases.ts index ce33c791176..e67a841e90e 100644 --- a/src/stores/RightPanelStorePhases.ts +++ b/src/stores/RightPanelStorePhases.ts @@ -54,6 +54,7 @@ export const RIGHT_PANEL_PHASES_NO_ARGS = [ RightPanelPhases.RoomMemberList, RightPanelPhases.GroupMemberList, RightPanelPhases.GroupRoomList, + RightPanelPhases.TimelineCard, ]; // Subset of phases visible in the Space View From 98adc2119d427f36c4e688d28ded373ad13e9855 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 11 Nov 2021 12:17:37 +0100 Subject: [PATCH 25/70] close right panel chat if no widget is maximised --- src/components/views/elements/AppTile.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index a1b2933125c..6a408aca150 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -88,6 +88,9 @@ interface IState { } import { logger } from "matrix-js-sdk/src/logger"; +import { RightPanelPhases } from '../../../stores/RightPanelStorePhases'; +import { Action } from '../../../dispatcher/actions'; +import RightPanelStore from '../../../stores/RightPanelStore'; @replaceableComponent("views.elements.AppTile") export default class AppTile extends React.Component { @@ -406,6 +409,11 @@ export default class AppTile extends React.Component { ? Container.Right : Container.Center; WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer); + if (targetContainer === Container.Right + && RightPanelStore.getSharedInstance().visibleRoomPanelPhase === RightPanelPhases.TimelineCard) { + // If the widget gets closed also close the RightPanel chat. + dis.dispatch({ action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomSummary }); + } }; private onContextMenuClick = (): void => { From 7d8879f933a4ea3f1152055e62b0ca1f8ad61889 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 11 Nov 2021 12:53:19 +0100 Subject: [PATCH 26/70] fix linter --- src/components/views/rooms/EventTile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 3686c893e4a..f7db8e56c9b 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -618,7 +618,7 @@ export default class EventTile extends React.Component { className="mx_ThreadInfo" onClick={() => { dispatchShowThreadEvent(this.props.mxEvent); - }} > + }}> { _t("%(count)s reply", { From 0831b60dc45d8948ce9243229e24c63963ff1bf4 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 11 Nov 2021 15:31:29 +0100 Subject: [PATCH 27/70] review fixes --- res/css/structures/_MainSplit.scss | 1 - res/css/views/elements/_ResizeHandle.scss | 5 ----- res/css/views/right_panel/_RoomSummaryCard.scss | 3 +++ res/css/views/rooms/_AppsDrawer.scss | 2 +- src/components/structures/RoomView.tsx | 2 +- src/components/views/right_panel/RoomSummaryCard.tsx | 6 ++++-- src/components/views/rooms/AppsDrawer.tsx | 3 +-- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss index 263ded74832..8c30abe97da 100644 --- a/res/css/structures/_MainSplit.scss +++ b/res/css/structures/_MainSplit.scss @@ -25,7 +25,6 @@ limitations under the License. .mx_MainSplit > .mx_RightPanel_ResizeWrapper { // no padding on the left. The spacing is taken care of by the main split content. padding: 5px 5px 5px 0px; - // margin-left: 0px; height: calc(100vh - 51px); // height of .mx_RoomHeader.light-panel &:hover .mx_RightPanel_ResizeHandle { diff --git a/res/css/views/elements/_ResizeHandle.scss b/res/css/views/elements/_ResizeHandle.scss index bf56888da09..2af2880654e 100644 --- a/res/css/views/elements/_ResizeHandle.scss +++ b/res/css/views/elements/_ResizeHandle.scss @@ -32,11 +32,6 @@ limitations under the License. cursor: row-resize; } -.mx_MatrixChat > .mx_ResizeHandle.mx_ResizeHandle_horizontal { - // margin: 0 0px 0 0; - // padding: 0 8px 0 0; -} - .mx_ResizeHandle.mx_ResizeHandle_horizontal > div { width: 1px; height: 100%; diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index ff1589dadfc..a8fb028bf9c 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -198,6 +198,9 @@ limitations under the License. &::before { mask-image: url('$(res)/img/element-icons/room/ellipsis.svg'); } + &.mx_RoomSummaryCard_maximised_widget { + right: 72px; + } } &.mx_RoomSummaryCard_Button_pinned { diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index aca333e71cf..27b0053aec3 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -18,7 +18,7 @@ limitations under the License. $MiniAppTileHeight: 200px; .mx_AppsDrawer { - margin: 5px 5px 5px 5px; + margin: 5px; position: relative; display: flex; flex-direction: column; diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 76ff6bb3e89..e1e43639ba1 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2132,7 +2132,7 @@ export class RoomView extends React.Component { // keep the timeline in as the mainSplitBody break; case MainSplitContentType.MaximisedWidget: - if (!SettingsStore.getValue("feature_maximised_widgets")) {break;} + if (!SettingsStore.getValue("feature_maximised_widgets")) break; mainSplitBody = = ({ app, room }) => { { if (prevProps.userId !== this.props.userId || prevProps.room !== this.props.room) { // Room has changed, update apps this.updateApps(); - } else if (this.getAppsHash(this.topApps()) - !== this.getAppsHash(prevState.apps[Container.Top])) { + } else if (this.getAppsHash(this.topApps()) !== this.getAppsHash(prevState.apps[Container.Top])) { this.loadResizerPreferences(); } } From fdf7b9f3cafcd5ab393c78b924741c9abe88e5d7 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 12 Nov 2021 15:57:54 +0100 Subject: [PATCH 28/70] add jest test for WidgetLayoutStore --- src/stores/widgets/WidgetLayoutStore.ts | 4 +- test/stores/WidgetLayoutStore-test.ts | 125 ++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 test/stores/WidgetLayoutStore-test.ts diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 5fd9a7d46b5..b66a7a757a3 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -173,7 +173,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore { } }; - private recalculateRoom(room: Room) { + public recalculateRoom(room: Room) { const widgets = WidgetStore.instance.getApps(room.roomId); if (!widgets?.length) { this.byRoom[room.roomId] = {}; @@ -455,7 +455,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore { break; case Container.Top: // new "top" widget => the center widget moves into "right" - if (this.hasMaximisedWidget(room) && toContainer) { + if (this.hasMaximisedWidget(room)) { this.moveToContainer(room, this.getContainerWidgets(room, Container.Center)[0], Container.Right); } break; diff --git a/test/stores/WidgetLayoutStore-test.ts b/test/stores/WidgetLayoutStore-test.ts new file mode 100644 index 00000000000..61399862ab4 --- /dev/null +++ b/test/stores/WidgetLayoutStore-test.ts @@ -0,0 +1,125 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +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 "../skinned-sdk"; // Must be first for skinning to work +import WidgetStore, { IApp } from "../../src/stores/WidgetStore"; +import { Container, WidgetLayoutStore } from "../../src/stores/widgets/WidgetLayoutStore"; +import { Room } from "matrix-js-sdk"; +import { stubClient } from "../test-utils"; + +// setup test env values +const roomId = "!room:server"; +const mockRoom = { + roomId: roomId, + currentState: { + getStateEvents: (_l, _x) => { + return { + getId: ()=>"$layoutEventId", + getContent: () => null, + }; + }, + } }; + +const mockApps = [ + { roomId: roomId, id: "1" }, + { roomId: roomId, id: "2" }, + { roomId: roomId, id: "3" }, + { roomId: roomId, id: "4" }, +]; + +// fake the WidgetStore.instance to just return an object with `getApps` +jest.spyOn(WidgetStore, 'instance', 'get').mockReturnValue({ getApps: (_room) => mockApps }); + +describe("WidgetLayoutStore", () => { + // we need to init a client so it does not error, when asking for DeviceStorage handlers (SettingsStore.setValue("Widgets.layout")) + stubClient(); + + const store = WidgetLayoutStore.instance; + + it("all widgets should be in the right container by default", async () => { + store.recalculateRoom(mockRoom); + expect(store.getContainerWidgets(mockRoom, Container.Right).length).toStrictEqual(mockApps.length); + }); + it("add widget to top container", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Top); + expect(store.getContainerWidgets(mockRoom, Container.Top)).toStrictEqual([mockApps[0]]); + }); + it("add three widgets to top container", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Top); + store.moveToContainer(mockRoom, mockApps[1], Container.Top); + store.moveToContainer(mockRoom, mockApps[2], Container.Top); + expect(new Set(store.getContainerWidgets(mockRoom, Container.Top))) + .toEqual(new Set([mockApps[0], mockApps[1], mockApps[2]])); + }); + it("cannot add more than three widgets to top container", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Top); + store.moveToContainer(mockRoom, mockApps[1], Container.Top); + store.moveToContainer(mockRoom, mockApps[2], Container.Top); + expect(store.canAddToContainer(mockRoom, Container.Top)) + .toEqual(false); + }); + it("remove pins when maximising (other widget)", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Top); + store.moveToContainer(mockRoom, mockApps[1], Container.Top); + store.moveToContainer(mockRoom, mockApps[2], Container.Top); + store.moveToContainer(mockRoom, mockApps[3], Container.Center); + expect(store.getContainerWidgets(mockRoom, Container.Top)) + .toEqual([]); + expect(new Set(store.getContainerWidgets(mockRoom, Container.Right))) + .toEqual(new Set([mockApps[0], mockApps[1], mockApps[2]])); + expect(store.getContainerWidgets(mockRoom, Container.Center)) + .toEqual([mockApps[3]]); + }); + it("remove pins when maximising (one of the pinned widgets)", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Top); + store.moveToContainer(mockRoom, mockApps[1], Container.Top); + store.moveToContainer(mockRoom, mockApps[2], Container.Top); + store.moveToContainer(mockRoom, mockApps[0], Container.Center); + expect(store.getContainerWidgets(mockRoom, Container.Top)) + .toEqual([]); + expect(store.getContainerWidgets(mockRoom, Container.Center)) + .toEqual([mockApps[0]]); + expect(new Set(store.getContainerWidgets(mockRoom, Container.Right))) + .toEqual(new Set([mockApps[1], mockApps[2], mockApps[3]])); + }); + it("remove maximised when pinning (other widget)", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Center); + store.moveToContainer(mockRoom, mockApps[1], Container.Top); + expect(store.getContainerWidgets(mockRoom, Container.Top)) + .toEqual([mockApps[1]]); + expect(store.getContainerWidgets(mockRoom, Container.Center)) + .toEqual([]); + expect(new Set(store.getContainerWidgets(mockRoom, Container.Right))) + .toEqual(new Set([mockApps[2], mockApps[3], mockApps[0]])); + }); + it("remove maximised when pinning (same widget)", async () => { + store.recalculateRoom(mockRoom); + store.moveToContainer(mockRoom, mockApps[0], Container.Center); + store.moveToContainer(mockRoom, mockApps[0], Container.Top); + expect(store.getContainerWidgets(mockRoom, Container.Top)) + .toEqual([mockApps[0]]); + expect(store.getContainerWidgets(mockRoom, Container.Center)) + .toEqual([]); + expect(new Set(store.getContainerWidgets(mockRoom, Container.Right))) + .toEqual(new Set([mockApps[2], mockApps[3], mockApps[1]])); + }); +}); From b06490e772e4ec5f264b70d102c1892ebf222a79 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 12 Nov 2021 18:55:48 +0100 Subject: [PATCH 29/70] change accent-color maybe that fixes the github build --- res/css/views/right_panel/_RoomSummaryCard.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index a8fb028bf9c..0605ae6de48 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -186,8 +186,8 @@ limitations under the License. .mx_RoomSummaryCard_app_minimise { right: 48px; &::before { - background-color: $accent-color; mask-image: url('$(res)/img/feather-customised/minimise.svg'); + background-color: $accent-color-50pct; } } From b3c65261915628bc307da7b688803060a160a2d3 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 12 Nov 2021 19:01:22 +0100 Subject: [PATCH 30/70] another try --- res/css/views/right_panel/_RoomSummaryCard.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index 0605ae6de48..3fe1cbb0ba2 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -187,7 +187,7 @@ limitations under the License. right: 48px; &::before { mask-image: url('$(res)/img/feather-customised/minimise.svg'); - background-color: $accent-color-50pct; + background-color: $tertiary-content; } } From a23931b5759f69484d7bd32952ddac52bb99d55a Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 12 Nov 2021 19:07:58 +0100 Subject: [PATCH 31/70] I think I have it now...(accent related commit) --- res/css/views/right_panel/_RoomSummaryCard.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index b28a14429d0..a384f194aba 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -187,7 +187,7 @@ limitations under the License. right: 48px; &::before { mask-image: url('$(res)/img/feather-customised/minimise.svg'); - background-color: $tertiary-content; + background-color: $accent; } } From 0bcb881328c2df04a543d683140b47e58f3aea97 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 15:14:43 +0100 Subject: [PATCH 32/70] fix room state always overriding user settings (and causing various issues) --- src/stores/widgets/WidgetLayoutStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index b66a7a757a3..823dd450d22 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -205,7 +205,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore { const manualContainer = userLayout?.widgets?.[widget.id]?.container; const isLegacyPinned = !!legacyPinned?.[widget.id]; const defaultContainer = WidgetType.JITSI.matches(widget.type) ? Container.Top : Container.Right; - if (stateContainer === Container.Center || manualContainer === Container.Center) { + if ((manualContainer) ? manualContainer === Container.Center : stateContainer === Container.Center) { if (centerWidgets.length) { console.error("Tried to push a second widget into the center container"); } else { From b1ef33beca506bdeca3e7aff0afd63c930f91f0f Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 17:11:46 +0100 Subject: [PATCH 33/70] fix container border width --- res/css/views/right_panel/_WidgetCard.scss | 2 ++ res/css/views/rooms/_AppsDrawer.scss | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/res/css/views/right_panel/_WidgetCard.scss b/res/css/views/right_panel/_WidgetCard.scss index edf9ba7dd72..7213842c56b 100644 --- a/res/css/views/right_panel/_WidgetCard.scss +++ b/res/css/views/right_panel/_WidgetCard.scss @@ -20,6 +20,8 @@ limitations under the License. .mx_AppTileFullWidth { max-width: unset; + width: auto; + margin: 0px 8px 0px 8px; height: 100%; border: 0; } diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 30f969262fd..59800e9e976 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -155,7 +155,7 @@ $MinWidth: 240px; width: 100% !important; // to override the inline style set by the resizer margin: 0; padding: 0; - border: 5px solid $widget-menu-bar-bg-color; + border: 8px solid $widget-menu-bar-bg-color; border-radius: 8px; display: flex; flex-direction: column; From ba4d09c6715bd08b71345ad70edf4907e97c3a8c Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 18:15:38 +0100 Subject: [PATCH 34/70] change icons, change border width use the correct variable for the expan icon use a new variable for the container-border-width --- res/css/_common.scss | 2 + res/css/structures/_LeftPanelWidget.scss | 2 +- res/css/structures/_RightPanel.scss | 2 +- res/css/views/dialogs/_HostSignupDialog.scss | 4 +- res/css/views/messages/_ViewSourceEvent.scss | 6 +- .../views/right_panel/_RoomSummaryCard.scss | 7 +- res/css/views/rooms/_AppsDrawer.scss | 42 +++++++----- res/img/element-icons/maximise_expand.svg | 3 + res/img/element-icons/minimise_collapse.svg | 3 + res/img/feather-customised/maximise.svg | 63 ------------------ res/img/feather-customised/minimise.svg | 65 ------------------- .../legacy-light/css/_legacy-light.scss | 4 +- res/themes/light/css/_light.scss | 5 +- 13 files changed, 49 insertions(+), 159 deletions(-) create mode 100644 res/img/element-icons/maximise_expand.svg create mode 100644 res/img/element-icons/minimise_collapse.svg delete mode 100644 res/img/feather-customised/maximise.svg delete mode 100644 res/img/feather-customised/minimise.svg diff --git a/res/css/_common.scss b/res/css/_common.scss index d6d139d2bd4..3d8b6659b38 100644 --- a/res/css/_common.scss +++ b/res/css/_common.scss @@ -30,6 +30,8 @@ $MessageTimestamp_width_hover: calc($MessageTimestamp_width - 2 * $selected-mess $slider-dot-size: 1em; $slider-selection-dot-size: 2.4em; +$container-border-width: 8px; + :root { font-size: 10px; diff --git a/res/css/structures/_LeftPanelWidget.scss b/res/css/structures/_LeftPanelWidget.scss index bb04b856245..0ac340e2f01 100644 --- a/res/css/structures/_LeftPanelWidget.scss +++ b/res/css/structures/_LeftPanelWidget.scss @@ -134,7 +134,7 @@ limitations under the License. mask-position: center; mask-size: contain; mask-repeat: no-repeat; - mask-image: url('$(res)/img/feather-customised/maximise.svg'); + mask-image: url($expand-button-url); background: $muted-fg-color; } } diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss index 38a1fe9099a..1809626ed95 100644 --- a/res/css/structures/_RightPanel.scss +++ b/res/css/structures/_RightPanel.scss @@ -22,7 +22,7 @@ limitations under the License. display: flex; flex-direction: column; border-radius: 8px; - padding: 8px 0; + padding: $container-border-width 0; box-sizing: border-box; height: 100%; contain: strict; diff --git a/res/css/views/dialogs/_HostSignupDialog.scss b/res/css/views/dialogs/_HostSignupDialog.scss index d8a6652a397..d2d7b727da4 100644 --- a/res/css/views/dialogs/_HostSignupDialog.scss +++ b/res/css/views/dialogs/_HostSignupDialog.scss @@ -78,7 +78,7 @@ limitations under the License. } .mx_HostSignup_maximize_button { - mask: url('$(res)/img/feather-customised/maximise.svg'); + mask: url($expand-button-url); mask-repeat: no-repeat; mask-position: center; mask-size: cover; @@ -92,7 +92,7 @@ limitations under the License. } .mx_HostSignup_minimize_button { - mask: url('$(res)/img/feather-customised/minimise.svg'); + mask: url($collapse-button-url); mask-repeat: no-repeat; mask-position: center; mask-size: cover; diff --git a/res/css/views/messages/_ViewSourceEvent.scss b/res/css/views/messages/_ViewSourceEvent.scss index bdb036fe173..6fee17d3c17 100644 --- a/res/css/views/messages/_ViewSourceEvent.scss +++ b/res/css/views/messages/_ViewSourceEvent.scss @@ -35,13 +35,15 @@ limitations under the License. mask-size: auto 12px; visibility: hidden; background-color: $accent; - mask-image: url('$(res)/img/feather-customised/maximise.svg'); + mask-image: url($expand-button-url); } &.mx_ViewSourceEvent_expanded .mx_ViewSourceEvent_toggle { mask-position: 0 bottom; margin-bottom: 7px; - mask-image: url('$(res)/img/feather-customised/minimise.svg'); + width: 10px; + height: 10px; + mask-image: url($collapse-button-url); } } diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index a384f194aba..75c4d414960 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -180,13 +180,16 @@ limitations under the License. right: 48px; &::before { - mask-image: url('$(res)/img/feather-customised/maximise.svg'); + mask-size: 14px; + mask-image: url($expand-button-url); } } .mx_RoomSummaryCard_app_minimise { right: 48px; + &::before { - mask-image: url('$(res)/img/feather-customised/minimise.svg'); + mask-size: 14px; + mask-image: url($collapse-button-url); background-color: $accent; } } diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 947c6bbeb5e..d88979bcdb3 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -101,11 +101,11 @@ $MiniAppTileHeight: 200px; min-height: 0; .mx_AppTile:first-of-type { - border-left-width: 8px; + border-left-width: $container-border-width; border-radius: 10px 0 0 10px; } .mx_AppTile:last-of-type { - border-right-width: 8px; + border-right-width: $container-border-width; border-radius: 0 10px 10px 0; } @@ -143,7 +143,7 @@ $MinWidth: 240px; .mx_AppTile { width: 50%; min-width: $MinWidth; - border: 8px solid $widget-menu-bar-bg-color; + border: $container-border-width solid $widget-menu-bar-bg-color; border-left-width: 5px; border-right-width: 5px; display: flex; @@ -225,24 +225,30 @@ $MinWidth: 240px; mask-position: 0 center; mask-size: auto 12px; background-color: $topleftmenu-color; - margin: 0 3px; -} - -.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_minWidget { - mask-image: url('$(res)/img/feather-customised/minimise.svg'); -} - -.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_maxWidget { - mask-image: url('$(res)/img/feather-customised/maximise.svg'); -} + margin: 0 5px; -.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_popout { - mask-image: url('$(res)/img/feather-customised/widget/external-link.svg'); + &.mx_AppTileMenuBar_iconButton_minWidget { + width: 10px; + height: 12px; + mask-size: auto 10px; + mask-image: url($collapse-button-url); + } + + &.mx_AppTileMenuBar_iconButton_maxWidget { + width: 11px; + height: 11px; + mask-image: url($expand-button-url); + } + + &.mx_AppTileMenuBar_iconButton_popout { + mask-image: url('$(res)/img/feather-customised/widget/external-link.svg'); + } + + &.mx_AppTileMenuBar_iconButton_menu { + mask-image: url('$(res)/img/element-icons/room/ellipsis.svg'); + } } -.mx_AppTileMenuBar_iconButton.mx_AppTileMenuBar_iconButton_menu { - mask-image: url('$(res)/img/element-icons/room/ellipsis.svg'); -} .mx_AppTileBody { height: 100%; diff --git a/res/img/element-icons/maximise_expand.svg b/res/img/element-icons/maximise_expand.svg new file mode 100644 index 00000000000..06c44e2acdd --- /dev/null +++ b/res/img/element-icons/maximise_expand.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/minimise_collapse.svg b/res/img/element-icons/minimise_collapse.svg new file mode 100644 index 00000000000..e941d41276f --- /dev/null +++ b/res/img/element-icons/minimise_collapse.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/feather-customised/maximise.svg b/res/img/feather-customised/maximise.svg deleted file mode 100644 index 96185da1359..00000000000 --- a/res/img/feather-customised/maximise.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - diff --git a/res/img/feather-customised/minimise.svg b/res/img/feather-customised/minimise.svg deleted file mode 100644 index f05e9399600..00000000000 --- a/res/img/feather-customised/minimise.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss index 83255da36d9..0e9355b22be 100644 --- a/res/themes/legacy-light/css/_legacy-light.scss +++ b/res/themes/legacy-light/css/_legacy-light.scss @@ -207,8 +207,8 @@ $event-highlight-bg-color: $yellow-background; $event-timestamp-color: #acacac; $copy-button-url: "$(res)/img/feather-customised/clipboard.svg"; -$collapse-button-url: "$(res)/img/feather-customised/minimise.svg"; -$expand-button-url: "$(res)/img/feather-customised/maximise.svg"; +$collapse-button-url: "$(res)/img/element-icons/minimise_collapse.svg"; +$expand-button-url: "$(res)/img/element-icons/maximise_expand.svg"; // e2e $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 4e3da74bce8..83263af4802 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -198,9 +198,8 @@ $event-highlight-bg-color: $yellow-background; $event-timestamp-color: #acacac; $copy-button-url: "$(res)/img/feather-customised/clipboard.svg"; -$collapse-button-url: "$(res)/img/feather-customised/minimise.svg"; -$expand-button-url: "$(res)/img/feather-customised/maximise.svg"; - +$collapse-button-url: "$(res)/img/element-icons/minimise_collapse.svg"; +$expand-button-url: "$(res)/img/element-icons/maximise_expand.svg"; // e2e $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent $e2e-unknown-color: #e8bf37; From 2a8bba61d6772df9f66a1bea445e16977fc5ab1a Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 18:21:04 +0100 Subject: [PATCH 35/70] use $container-border-width where needed --- res/css/views/right_panel/_WidgetCard.scss | 2 +- res/css/views/rooms/_AppsDrawer.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/views/right_panel/_WidgetCard.scss b/res/css/views/right_panel/_WidgetCard.scss index 7213842c56b..934131e0010 100644 --- a/res/css/views/right_panel/_WidgetCard.scss +++ b/res/css/views/right_panel/_WidgetCard.scss @@ -21,7 +21,7 @@ limitations under the License. .mx_AppTileFullWidth { max-width: unset; width: auto; - margin: 0px 8px 0px 8px; + margin: 0px $container-border-width 0px $container-border-width; height: 100%; border: 0; } diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index eb44e98d7fb..aec98f4a7c8 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -156,7 +156,7 @@ $MinWidth: 240px; width: 100% !important; // to override the inline style set by the resizer margin: 0; padding: 0; - border: 8px solid $widget-menu-bar-bg-color; + border: $container-border-width solid $widget-menu-bar-bg-color; border-radius: 8px; display: flex; flex-direction: column; From 6f3a1c08e1b2303d4af9f0df0c6238a6c4b1a470 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 18:27:02 +0100 Subject: [PATCH 36/70] fix style lint --- res/css/views/right_panel/_RoomSummaryCard.scss | 2 -- res/css/views/rooms/_AppsDrawer.scss | 7 +++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index 75c4d414960..33f17cbfadc 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -178,7 +178,6 @@ limitations under the License. } .mx_RoomSummaryCard_app_maximise { right: 48px; - &::before { mask-size: 14px; mask-image: url($expand-button-url); @@ -186,7 +185,6 @@ limitations under the License. } .mx_RoomSummaryCard_app_minimise { right: 48px; - &::before { mask-size: 14px; mask-image: url($collapse-button-url); diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index aec98f4a7c8..1bf7536104d 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -233,23 +233,22 @@ $MinWidth: 240px; mask-size: auto 10px; mask-image: url($collapse-button-url); } - + &.mx_AppTileMenuBar_iconButton_maxWidget { width: 11px; height: 11px; mask-image: url($expand-button-url); } - + &.mx_AppTileMenuBar_iconButton_popout { mask-image: url('$(res)/img/feather-customised/widget/external-link.svg'); } - + &.mx_AppTileMenuBar_iconButton_menu { mask-image: url('$(res)/img/element-icons/room/ellipsis.svg'); } } - .mx_AppTileBody { height: 100%; width: 100%; From fa35b44df69c73d03409ef6a2491eae0d55c1afd Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 18:31:51 +0100 Subject: [PATCH 37/70] add !important for widget card AppTileFullWidth --- res/css/views/right_panel/_WidgetCard.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/right_panel/_WidgetCard.scss b/res/css/views/right_panel/_WidgetCard.scss index 934131e0010..812de3cfc83 100644 --- a/res/css/views/right_panel/_WidgetCard.scss +++ b/res/css/views/right_panel/_WidgetCard.scss @@ -20,7 +20,7 @@ limitations under the License. .mx_AppTileFullWidth { max-width: unset; - width: auto; + width: auto !important; margin: 0px $container-border-width 0px $container-border-width; height: 100%; border: 0; From 7f0c5d60eaa0d252669e30affd583b000cd39d8b Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 18:47:45 +0100 Subject: [PATCH 38/70] fix bug where a widget can be open twice It was possible to open the widget in the right card and also have it fullscreen which lead to an infint react loop, moving around the persistant iFrame. --- src/components/views/right_panel/RoomSummaryCard.tsx | 12 +++++++++--- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index f965e0516c1..22fd59fbca4 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -150,9 +150,15 @@ const AppRow: React.FC = ({ app, room }) => { className="mx_RoomSummaryCard_icon_app" onClick={onOpenWidgetClick} // only show a tooltip if the widget is pinned - title={isPinned ? _t("Unpin a widget to view it in this panel") : ""} - forceHide={!isPinned} - disabled={isPinned} + title={ + isPinned + ? _t("Unpin this widget to view it in this panel") + : isMaximised + ? _t("Close this widget to view it in this panel") : + "" + } + forceHide={!(isPinned || isMaximised)} + disabled={isPinned || isMaximised} yOffset={-48} > diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 27a1807b703..0a24545ba69 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1867,7 +1867,8 @@ "Room Info": "Room Info", "You can only pin up to %(count)s widgets|other": "You can only pin up to %(count)s widgets", "Maximise widget": "Maximise widget", - "Unpin a widget to view it in this panel": "Unpin a widget to view it in this panel", + "Unpin this widget to view it in this panel": "Unpin this widget to view it in this panel", + "Close this widget to view it in this panel": "Close this widget to view it in this panel", "Set my room layout for everyone": "Set my room layout for everyone", "Widgets": "Widgets", "Edit widgets, bridges & bots": "Edit widgets, bridges & bots", From a8d2e5e305b26aa91e017d51fbd3e638ddf9e720 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 19:01:58 +0100 Subject: [PATCH 39/70] review fixes ( file naming and remove image url variable) --- res/css/structures/_LeftPanelWidget.scss | 2 +- res/css/views/dialogs/_HostSignupDialog.scss | 4 ++-- res/css/views/messages/_ViewSourceEvent.scss | 4 ++-- res/css/views/right_panel/_RoomSummaryCard.scss | 4 ++-- res/css/views/rooms/_AppsDrawer.scss | 4 ++-- res/css/views/rooms/_EventTile.scss | 4 ++-- .../{maximise_expand.svg => maximise-expand.svg} | 0 .../{minimise_collapse.svg => minimise-collapse.svg} | 0 res/themes/legacy-light/css/_legacy-light.scss | 2 -- res/themes/light/css/_light.scss | 2 -- 10 files changed, 11 insertions(+), 15 deletions(-) rename res/img/element-icons/{maximise_expand.svg => maximise-expand.svg} (100%) rename res/img/element-icons/{minimise_collapse.svg => minimise-collapse.svg} (100%) diff --git a/res/css/structures/_LeftPanelWidget.scss b/res/css/structures/_LeftPanelWidget.scss index 0ac340e2f01..0a01a19b90a 100644 --- a/res/css/structures/_LeftPanelWidget.scss +++ b/res/css/structures/_LeftPanelWidget.scss @@ -134,7 +134,7 @@ limitations under the License. mask-position: center; mask-size: contain; mask-repeat: no-repeat; - mask-image: url($expand-button-url); + mask-image: url("$(res)/img/element-icons/maximise-expand.svg"); background: $muted-fg-color; } } diff --git a/res/css/views/dialogs/_HostSignupDialog.scss b/res/css/views/dialogs/_HostSignupDialog.scss index d2d7b727da4..56d71034045 100644 --- a/res/css/views/dialogs/_HostSignupDialog.scss +++ b/res/css/views/dialogs/_HostSignupDialog.scss @@ -78,7 +78,7 @@ limitations under the License. } .mx_HostSignup_maximize_button { - mask: url($expand-button-url); + mask: url("$(res)/img/element-icons/maximise-expand.svg"); mask-repeat: no-repeat; mask-position: center; mask-size: cover; @@ -92,7 +92,7 @@ limitations under the License. } .mx_HostSignup_minimize_button { - mask: url($collapse-button-url); + mask: url("$(res)/img/element-icons/minimise-collapse.svg"); mask-repeat: no-repeat; mask-position: center; mask-size: cover; diff --git a/res/css/views/messages/_ViewSourceEvent.scss b/res/css/views/messages/_ViewSourceEvent.scss index 6fee17d3c17..562c10c1b03 100644 --- a/res/css/views/messages/_ViewSourceEvent.scss +++ b/res/css/views/messages/_ViewSourceEvent.scss @@ -35,7 +35,7 @@ limitations under the License. mask-size: auto 12px; visibility: hidden; background-color: $accent; - mask-image: url($expand-button-url); + mask-image: url("$(res)/img/element-icons/maximise-expand.svg"); } &.mx_ViewSourceEvent_expanded .mx_ViewSourceEvent_toggle { @@ -43,7 +43,7 @@ limitations under the License. margin-bottom: 7px; width: 10px; height: 10px; - mask-image: url($collapse-button-url); + mask-image: url("$(res)/img/element-icons/minimise-collapse.svg"); } } diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index 33f17cbfadc..bb3638c475c 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -180,14 +180,14 @@ limitations under the License. right: 48px; &::before { mask-size: 14px; - mask-image: url($expand-button-url); + mask-image: url("$(res)/img/element-icons/maximise-expand.svg"); } } .mx_RoomSummaryCard_app_minimise { right: 48px; &::before { mask-size: 14px; - mask-image: url($collapse-button-url); + mask-image: url("$(res)/img/element-icons/minimise-collapse.svg"); background-color: $accent; } } diff --git a/res/css/views/rooms/_AppsDrawer.scss b/res/css/views/rooms/_AppsDrawer.scss index 1bf7536104d..3a62d728f63 100644 --- a/res/css/views/rooms/_AppsDrawer.scss +++ b/res/css/views/rooms/_AppsDrawer.scss @@ -231,13 +231,13 @@ $MinWidth: 240px; width: 10px; height: 12px; mask-size: auto 10px; - mask-image: url($collapse-button-url); + mask-image: url("$(res)/img/element-icons/minimise-collapse.svg"); } &.mx_AppTileMenuBar_iconButton_maxWidget { width: 11px; height: 11px; - mask-image: url($expand-button-url); + mask-image: url("$(res)/img/element-icons/maximise-expand.svg"); } &.mx_AppTileMenuBar_iconButton_popout { diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index f7b55709563..5a3e1a90a64 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -546,13 +546,13 @@ $left-gutter: 64px; mask-size: 75%; mask-position: center; mask-repeat: no-repeat; - mask-image: url($collapse-button-url); + mask-image: url("$(res)/img/element-icons/minimise-collapse.svg"); } .mx_EventTile_expandButton { mask-size: 75%; mask-position: center; mask-repeat: no-repeat; - mask-image: url($expand-button-url); + mask-image: url("$(res)/img/element-icons/maximise-expand.svg"); } .mx_EventTile_body .mx_EventTile_pre_container:focus-within .mx_EventTile_copyButton, diff --git a/res/img/element-icons/maximise_expand.svg b/res/img/element-icons/maximise-expand.svg similarity index 100% rename from res/img/element-icons/maximise_expand.svg rename to res/img/element-icons/maximise-expand.svg diff --git a/res/img/element-icons/minimise_collapse.svg b/res/img/element-icons/minimise-collapse.svg similarity index 100% rename from res/img/element-icons/minimise_collapse.svg rename to res/img/element-icons/minimise-collapse.svg diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss index 0e9355b22be..a50ebbb50d2 100644 --- a/res/themes/legacy-light/css/_legacy-light.scss +++ b/res/themes/legacy-light/css/_legacy-light.scss @@ -207,8 +207,6 @@ $event-highlight-bg-color: $yellow-background; $event-timestamp-color: #acacac; $copy-button-url: "$(res)/img/feather-customised/clipboard.svg"; -$collapse-button-url: "$(res)/img/element-icons/minimise_collapse.svg"; -$expand-button-url: "$(res)/img/element-icons/maximise_expand.svg"; // e2e $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 83263af4802..590830cb40f 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -198,8 +198,6 @@ $event-highlight-bg-color: $yellow-background; $event-timestamp-color: #acacac; $copy-button-url: "$(res)/img/feather-customised/clipboard.svg"; -$collapse-button-url: "$(res)/img/element-icons/minimise_collapse.svg"; -$expand-button-url: "$(res)/img/element-icons/maximise_expand.svg"; // e2e $e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent $e2e-unknown-color: #e8bf37; From 3743b7469da584de073bd0eb48248e1c8f72a5d2 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 15 Nov 2021 19:05:51 +0100 Subject: [PATCH 40/70] fix awkward ternary stack --- .../views/right_panel/RoomSummaryCard.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index 22fd59fbca4..4a2d662c78b 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -145,18 +145,19 @@ const AppRow: React.FC = ({ app, room }) => { const maximiseTitle = isMaximised ? _t("Close") : _t("Maximise widget"); + let openTitle = ""; + if (isPinned) { + openTitle = _t("Unpin this widget to view it in this panel"); + } else if (isMaximised) { + openTitle =_t("Close this widget to view it in this panel"); + } + return
Date: Mon, 15 Nov 2021 19:11:18 +0100 Subject: [PATCH 41/70] remove the now deprecated collapse button url after merge --- res/themes/light/css/_light.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index 8a884273357..54a8b692f89 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -302,8 +302,6 @@ $focus-brightness: 105%; // Icon URLs // ******************** $copy-button-url: "$(res)/img/feather-customised/clipboard.svg"; -$collapse-button-url: "$(res)/img/feather-customised/minimise.svg"; -$expand-button-url: "$(res)/img/feather-customised/maximise.svg"; // ******************** // Mixins From ad183fbaad05157ef859763ba9f3c081bf5c7eba Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 16 Nov 2021 13:36:41 +0100 Subject: [PATCH 42/70] fix styling and move TimelineCard to the views --- res/css/_components.scss | 2 +- .../right_panel}/_TimelineCard.scss | 30 ------------------- src/components/structures/RightPanel.tsx | 2 +- .../right_panel}/TimelineCard.tsx | 26 ++++++++-------- 4 files changed, 15 insertions(+), 45 deletions(-) rename res/css/{structures => views/right_panel}/_TimelineCard.scss (63%) rename src/components/{structures => views/right_panel}/TimelineCard.tsx (87%) diff --git a/res/css/_components.scss b/res/css/_components.scss index 75b6ef46535..03b46677d4f 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -33,7 +33,6 @@ @import "./structures/_SpacePanel.scss"; @import "./structures/_SpaceRoomView.scss"; @import "./structures/_TabbedView.scss"; -@import "./structures/_TimelineCard.scss"; @import "./structures/_ToastContainer.scss"; @import "./structures/_UploadBar.scss"; @import "./structures/_UserMenu.scss"; @@ -205,6 +204,7 @@ @import "./views/right_panel/_PinnedMessagesCard.scss"; @import "./views/right_panel/_RoomSummaryCard.scss"; @import "./views/right_panel/_ThreadPanel.scss"; +@import "./views/right_panel/_TimelineCard.scss"; @import "./views/right_panel/_UserInfo.scss"; @import "./views/right_panel/_VerificationPanel.scss"; @import "./views/right_panel/_WidgetCard.scss"; diff --git a/res/css/structures/_TimelineCard.scss b/res/css/views/right_panel/_TimelineCard.scss similarity index 63% rename from res/css/structures/_TimelineCard.scss rename to res/css/views/right_panel/_TimelineCard.scss index 35eadaa3670..1e442f31014 100644 --- a/res/css/structures/_TimelineCard.scss +++ b/res/css/views/right_panel/_TimelineCard.scss @@ -15,11 +15,6 @@ limitations under the License. */ .mx_TimelineCard { - display: flex; - flex-direction: column; - - padding-right: 0; - .mx_TimelineCard__header { width: calc(100% - 60px); margin-left: 6px; @@ -36,29 +31,4 @@ limitations under the License. color: $secondary-content; } } - - .mx_AutoHideScrollbar { - border-radius: 8px; - } - - .mx_RoomView_messageListWrapper { - background-color: $background; - padding: 8px; - border-radius: inherit; - } - - .mx_ScrollPanel { - .mx_RoomView_MessageList { - padding: 0; - } - } - - .mx_MessageComposer { - background-color: $background; - border-radius: 8px; - margin-top: 8px; - width: calc(100% - 8px); - padding: 0 8px; - box-sizing: border-box; - } } diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 66b400038e2..022943a995b 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -54,7 +54,7 @@ import SpaceStore from "../../stores/spaces/SpaceStore"; import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks'; import { E2EStatus } from '../../utils/ShieldUtils'; import { dispatchShowThreadsPanelEvent } from '../../dispatcher/dispatch-actions/threads'; -import TimelineCard from './TimelineCard'; +import TimelineCard from '../views/right_panel/TimelineCard'; interface IProps { room?: Room; // if showing panels for a given room, this is set diff --git a/src/components/structures/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx similarity index 87% rename from src/components/structures/TimelineCard.tsx rename to src/components/views/right_panel/TimelineCard.tsx index 62172d51de4..7aba3829edf 100644 --- a/src/components/structures/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -18,20 +18,20 @@ import React from 'react'; import { MatrixEvent, Room } from 'matrix-js-sdk/src'; import { Thread } from 'matrix-js-sdk/src/models/thread'; -import BaseCard from "../views/right_panel/BaseCard"; -import { RightPanelPhases } from "../../stores/RightPanelStorePhases"; +import BaseCard from "./BaseCard"; +import { RightPanelPhases } from "../../../stores/RightPanelStorePhases"; -import ResizeNotifier from '../../utils/ResizeNotifier'; -import MessageComposer from '../views/rooms/MessageComposer'; -import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks'; -import { Layout } from '../../settings/Layout'; -import TimelinePanel from './TimelinePanel'; -import { E2EStatus } from '../../utils/ShieldUtils'; -import EditorStateTransfer from '../../utils/EditorStateTransfer'; -import RoomContext from '../../contexts/RoomContext'; +import ResizeNotifier from '../../../utils/ResizeNotifier'; +import MessageComposer from '../rooms/MessageComposer'; +import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks'; +import { Layout } from '../../../settings/Layout'; +import TimelinePanel from '../../structures/TimelinePanel'; +import { E2EStatus } from '../../../utils/ShieldUtils'; +import EditorStateTransfer from '../../../utils/EditorStateTransfer'; +import RoomContext from '../../../contexts/RoomContext'; -import { _t } from '../../languageHandler'; -import { replaceableComponent } from '../../utils/replaceableComponent'; +import { _t } from '../../../languageHandler'; +import { replaceableComponent } from '../../../utils/replaceableComponent'; interface IProps { room: Room; @@ -121,7 +121,7 @@ export default class TimelineCard extends React.Component { public render(): JSX.Element { return ( From 6e1f1feb233187c4b65d3c3464d5cdc6adf7d9bc Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 16 Nov 2021 16:29:37 +0100 Subject: [PATCH 43/70] clean up TimelinCard class and disable RearReceipts --- .../views/right_panel/TimelineCard.tsx | 75 +------------------ 1 file changed, 4 insertions(+), 71 deletions(-) diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index 7aba3829edf..e993e8e06bb 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -52,23 +52,10 @@ interface IState { export default class TimelineCard extends React.Component { static contextType = RoomContext; - private messagePanel: TimelinePanel; - constructor(props: IProps) { super(props); this.state = {}; } - public componentDidMount(): void { - - } - - public componentWillUnmount(): void { - - } - - public componentDidUpdate(prevProps) { - - } private renderTimelineCardHeader = (): JSX.Element => { return
@@ -76,48 +63,6 @@ export default class TimelineCard extends React.Component {
; }; - private gatherTimelinePanelRef = r => { - this.messagePanel = r; - }; - - private onMessageListScroll = ev => { - // if (this.messagePanel.isAtEndOfLiveTimeline()) { - // this.setState({ - // numUnreadMessages: 0, - // atEndOfLiveTimeline: true, - // }); - // } else { - // this.setState({ - // atEndOfLiveTimeline: false, - // }); - // } - // this.updateTopUnreadMessagesBar(); - }; - - private onUserScroll = () => { - // if (this.state.initialEventId && this.state.isInitialEventHighlighted) { - // dis.dispatch({ - // action: 'view_room', - // room_id: this.state.room.roomId, - // event_id: this.state.initialEventId, - // highlighted: false, - // replyingToEvent: this.state.replyToEvent, - // }); - // } - }; - - // decide whether or not the top 'unread messages' bar should be shown - private updateTopUnreadMessagesBar = () => { - if (!this.messagePanel) { - return; - } - - // const showBar = this.messagePanel.canJumpToReadMarker(); - // if (this.state.showTopUnreadMessagesBar != showBar) { - // this.setState({ showTopUnreadMessagesBar: showBar }); - // } - }; - public render(): JSX.Element { return ( { withoutScrollContainer={true} header={this.renderTimelineCardHeader()}> { editState={this.state.editState} eventId={this.props.initialEvent?.getId()} resizeNotifier={this.props.resizeNotifier} - onScroll={this.onMessageListScroll} - onUserScroll={this.onUserScroll} - onReadMarkerUpdated={this.updateTopUnreadMessagesBar} - // highlightedEventId={highlightedEventId} - // onUserScroll={this.onScroll} /> - { /* { ContentMessages.sharedInstance().getCurrentUploads(threadRelation).length > 0 && ( - - ) } */ } - - // ); } } From 585ffa8379d1252af75e0965a0a1d06f46b03e39 Mon Sep 17 00:00:00 2001 From: Timo K Date: Tue, 16 Nov 2021 16:58:13 +0100 Subject: [PATCH 44/70] fix maximised state being loaded correctly --- src/components/structures/RoomView.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 7f20d0c824e..342a8c31f34 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -332,15 +332,15 @@ export class RoomView extends React.Component { private checkWidgets = (room) => { this.setState({ - hasPinnedWidgets: WidgetLayoutStore.instance.hasPinnedWidgets(this.state.room), - mainSplitContentType: this.getMainSplitContentType(), - showApps: this.shouldShowApps(this.state.room), + hasPinnedWidgets: WidgetLayoutStore.instance.hasPinnedWidgets(room), + mainSplitContentType: this.getMainSplitContentType(room), + showApps: this.shouldShowApps(room), }); }; - private getMainSplitContentType = () => { + private getMainSplitContentType = (room) => { // TODO-video check if video should be displayed in main panel - return (WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room)) + return (WidgetLayoutStore.instance.hasMaximisedWidget(room)) ? MainSplitContentType.MaximisedWidget : MainSplitContentType.Timeline; }; From 583d7543179c9b877fa90c1e0ca8e6d9d8471cc9 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 11:50:18 +0100 Subject: [PATCH 45/70] enable Read Receipts and sendReadReceiptOnLoad for timelineCard --- src/components/structures/TimelinePanel.tsx | 7 ++----- src/components/views/right_panel/TimelineCard.tsx | 6 +++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index d75d8afda99..3f3e5bc7199 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -477,10 +477,7 @@ class TimelinePanel extends React.Component { }; private onMessageListScroll = e => { - if (this.props.onScroll) { - this.props.onScroll(e); - } - + this.props.onScroll?.(e); if (this.props.manageReadMarkers) { this.doManageReadMarkers(); } @@ -595,7 +592,7 @@ class TimelinePanel extends React.Component { this.setState(updatedState, () => { this.messagePanel.current.updateTimelineMinHeight(); if (callRMUpdated) { - this.props.onReadMarkerUpdated(); + this.props.onReadMarkerUpdated?.(); } }); }); diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index e993e8e06bb..5ee0848dd14 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -71,10 +71,10 @@ export default class TimelineCard extends React.Component { withoutScrollContainer={true} header={this.renderTimelineCardHeader()}> Date: Wed, 17 Nov 2021 18:02:23 +0100 Subject: [PATCH 46/70] Update src/components/structures/RightPanel.tsx Co-authored-by: J. Ryan Stinnett --- src/components/structures/RightPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 022943a995b..5af2535da24 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -336,7 +336,7 @@ export default class RightPanel extends React.Component { } break; case RightPanelPhases.TimelineCard: - if (!SettingsStore.getValue("feature_maximised_widgets")) { break; } + if (!SettingsStore.getValue("feature_maximised_widgets")) break; panel = Date: Wed, 17 Nov 2021 18:26:54 +0100 Subject: [PATCH 47/70] fix position of dispatcher --- src/components/structures/RoomView.tsx | 9 +++++++++ src/stores/widgets/WidgetLayoutStore.ts | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 342a8c31f34..ab8c226e20a 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -96,6 +96,8 @@ import { dispatchShowThreadEvent } from '../../dispatcher/dispatch-actions/threa import { fetchInitialEvent } from "../../utils/EventUtils"; import { ComposerType } from "../../dispatcher/payloads/ComposerInsertPayload"; import AppsDrawer from '../views/rooms/AppsDrawer'; +import { SetRightPanelPhasePayload } from '../../dispatcher/payloads/SetRightPanelPhasePayload'; +import { RightPanelPhases } from '../../stores/RightPanelStorePhases'; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -327,6 +329,13 @@ export class RoomView extends React.Component { private onWidgetLayoutChange = () => { if (!this.state.room) return; + if (WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room)) { + // Show chat in right panel when a widget is maximised + dis.dispatch({ + action: Action.SetRightPanelPhase, + phase: RightPanelPhases.TimelineCard, + }); + } this.checkWidgets(this.state.room); }; diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index ccc781d712f..8b97d95d3b3 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -456,11 +456,6 @@ export class WidgetLayoutStore extends ReadyWatchingStore { for (const w of this.getContainerWidgets(room, Container.Center)) { this.moveToContainer(room, w, Container.Right); } - // Additionally change the right panel phase to chat: - dis.dispatch({ - action: Action.SetRightPanelPhase, - phase: RightPanelPhases.TimelineCard, - }); break; case Container.Top: // new "top" widget => the center widget moves into "right" From 596af161f9ee5354540f62fa410daaaa4e8b4c96 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 18:27:12 +0100 Subject: [PATCH 48/70] fix header styles (make them prettier and simpler) --- res/css/views/right_panel/_TimelineCard.scss | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/res/css/views/right_panel/_TimelineCard.scss b/res/css/views/right_panel/_TimelineCard.scss index 1e442f31014..ebf1eec1172 100644 --- a/res/css/views/right_panel/_TimelineCard.scss +++ b/res/css/views/right_panel/_TimelineCard.scss @@ -16,13 +16,9 @@ limitations under the License. .mx_TimelineCard { .mx_TimelineCard__header { - width: calc(100% - 60px); margin-left: 6px; - margin-bottom: 4px; display: flex; flex: 1; - justify-content: space-between; - align-items: center; span:first-of-type { font-weight: 600; @@ -31,4 +27,10 @@ limitations under the License. color: $secondary-content; } } + .mx_BaseCardHeader { + margin: 5px 0 9px 0; + .mx_BaseCard_close { + margin: 8px; + } + } } From 90e331fd159a68b96cc82e5fa8076e52238ad895 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 18:30:14 +0100 Subject: [PATCH 49/70] fix up event tile --- src/components/views/rooms/EventTile.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index a3e5f6087a3..16de55dbe5f 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -67,7 +67,6 @@ import { MediaEventHelper } from "../../../utils/MediaEventHelper"; import Toolbar from '../../../accessibility/Toolbar'; import { POLL_START_EVENT_TYPE } from '../../../polls/consts'; import { RovingAccessibleTooltipButton } from '../../../accessibility/roving/RovingAccessibleTooltipButton'; -import { RightPanelPhases } from '../../../stores/RightPanelStorePhases'; import ThreadListContextMenu from '../context_menus/ThreadListContextMenu'; const eventTileTypes = { @@ -323,7 +322,6 @@ interface IProps { showThreadInfo?: boolean; timelineRenderingType?: TimelineRenderingType; - threadViewPreviousCard?: RightPanelPhases; } interface IState { @@ -623,7 +621,6 @@ export default class EventTile extends React.Component { onClick={() => { dispatchShowThreadEvent(this.props.mxEvent); }}> - { _t("%(count)s reply", { count: this.thread.length, From 8dfa9402d31a0d61482d635be38b19813ff29165 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 18:32:51 +0100 Subject: [PATCH 50/70] rename RightPanelPhases.TimelineCard -> Timeline --- src/components/structures/RightPanel.tsx | 2 +- src/components/structures/RoomView.tsx | 2 +- src/components/structures/ThreadView.tsx | 2 +- src/components/views/elements/AppTile.tsx | 2 +- src/components/views/right_panel/RoomHeaderButtons.tsx | 4 ++-- src/components/views/right_panel/TimelineCard.tsx | 2 +- src/stores/RightPanelStorePhases.ts | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index 022943a995b..5239e7370f4 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -335,7 +335,7 @@ export default class RightPanel extends React.Component { panel = ; } break; - case RightPanelPhases.TimelineCard: + case RightPanelPhases.Timeline: if (!SettingsStore.getValue("feature_maximised_widgets")) { break; } panel = { // Show chat in right panel when a widget is maximised dis.dispatch({ action: Action.SetRightPanelPhase, - phase: RightPanelPhases.TimelineCard, + phase: RightPanelPhases.Timeline, }); } this.checkWidgets(this.state.room); diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index 7f4ca5abbaf..bed116212d4 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -208,7 +208,7 @@ export default class ThreadView extends React.Component { const previousPhaseLabels = {}; previousPhaseLabels[RightPanelPhases.ThreadPanel] = _t("All threads"); - previousPhaseLabels[RightPanelPhases.TimelineCard] = _t("Chat"); + previousPhaseLabels[RightPanelPhases.Timeline] = _t("Chat"); return ( { : Container.Center; WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer); if (targetContainer === Container.Right - && RightPanelStore.getSharedInstance().visibleRoomPanelPhase === RightPanelPhases.TimelineCard) { + && RightPanelStore.getSharedInstance().visibleRoomPanelPhase === RightPanelPhases.Timeline) { // If the widget gets closed also close the RightPanel chat. dis.dispatch({ action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomSummary }); } diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index 1683a32a23b..8b0a3e3670c 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -142,7 +142,7 @@ export default class RoomHeaderButtons extends HeaderButtons { this.setPhase(RightPanelPhases.PinnedMessages); }; private onTimelineCardClicked = () => { - this.setPhase(RightPanelPhases.TimelineCard); + this.setPhase(RightPanelPhases.Timeline); }; private onThreadsPanelClicked = () => { @@ -165,7 +165,7 @@ export default class RoomHeaderButtons extends HeaderButtons { /> diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index 5ee0848dd14..38878355d7a 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -77,7 +77,7 @@ export default class TimelineCard extends React.Component { sendReadReceiptOnLoad={true} timelineSet={this.props.room.getUnfilteredTimelineSet()} showUrlPreview={true} - threadViewPreviousCard={RightPanelPhases.TimelineCard} + threadViewPreviousCard={RightPanelPhases.Timeline} layout={Layout.Group} hideThreadedMessages={false} hidden={false} diff --git a/src/stores/RightPanelStorePhases.ts b/src/stores/RightPanelStorePhases.ts index e67a841e90e..0b8d9c69edb 100644 --- a/src/stores/RightPanelStorePhases.ts +++ b/src/stores/RightPanelStorePhases.ts @@ -25,7 +25,7 @@ export enum RightPanelPhases { RoomSummary = 'RoomSummary', Widget = 'Widget', PinnedMessages = "PinnedMessages", - TimelineCard = "TimelineCard", + Timeline = "Timeline", Room3pidMemberInfo = 'Room3pidMemberInfo', // Group stuff @@ -54,7 +54,7 @@ export const RIGHT_PANEL_PHASES_NO_ARGS = [ RightPanelPhases.RoomMemberList, RightPanelPhases.GroupMemberList, RightPanelPhases.GroupRoomList, - RightPanelPhases.TimelineCard, + RightPanelPhases.Timeline, ]; // Subset of phases visible in the Space View From 304e788a5843d728d06cf1eb3e74fdcc576c70b5 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 18:57:39 +0100 Subject: [PATCH 51/70] fix style --- src/components/views/right_panel/TimelineCard.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index 38878355d7a..451295afc4e 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -69,7 +69,8 @@ export default class TimelineCard extends React.Component { className="mx_ThreadPanel mx_TimelineCard" onClose={this.props.onClose} withoutScrollContainer={true} - header={this.renderTimelineCardHeader()}> + header={this.renderTimelineCardHeader()} + > Date: Wed, 17 Nov 2021 19:30:56 +0100 Subject: [PATCH 52/70] code cleanup for previous phase logic --- src/components/structures/RightPanel.tsx | 3 +-- src/components/structures/ThreadView.tsx | 9 ++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index b30c8d18fdd..5609247bd9f 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -355,8 +355,7 @@ export default class RightPanel extends React.Component { initialEvent={this.state.initialEvent} initialEventHighlighted={this.state.initialEventHighlighted} permalinkCreator={this.props.permalinkCreator} - e2eStatus={this.props.e2eStatus} - previousPhase={RightPanelStore.getSharedInstance().previousPhase} />; + e2eStatus={this.props.e2eStatus} />; break; case RightPanelPhases.ThreadPanel: diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index bed116212d4..fbeef1a8ea3 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -41,6 +41,7 @@ import ContentMessages from '../../ContentMessages'; import UploadBar from './UploadBar'; import { _t } from '../../languageHandler'; import ThreadListContextMenu from '../views/context_menus/ThreadListContextMenu'; +import RightPanelStore from '../../stores/RightPanelStore'; interface IProps { room: Room; @@ -51,7 +52,6 @@ interface IProps { e2eStatus?: E2EStatus; initialEvent?: MatrixEvent; initialEventHighlighted?: boolean; - previousPhase?: RightPanelPhases; } interface IState { thread?: Thread; @@ -204,8 +204,11 @@ export default class ThreadView extends React.Component { event_id: this.state.thread?.id, }; - const previousPhase = (this.props.previousPhase) ? this.props.previousPhase : RightPanelPhases.ThreadPanel; - + let previousPhase = RightPanelStore.getSharedInstance().previousPhase; + // Make sure the previous Phase is always one of the two: Timeline or ThreadPanel + if (![RightPanelPhases.ThreadPanel, RightPanelPhases.Timeline].includes(previousPhase)) { + previousPhase = RightPanelPhases.ThreadPanel; + } const previousPhaseLabels = {}; previousPhaseLabels[RightPanelPhases.ThreadPanel] = _t("All threads"); previousPhaseLabels[RightPanelPhases.Timeline] = _t("Chat"); From 65c752d0ed23fecbf1c58765006989c45ed00322 Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 19:51:08 +0100 Subject: [PATCH 53/70] remove artifacts from the previousPhase logic. Now we just get the previous phase by asking the RightPanelStore In the ThreadView directly. --- src/components/structures/MessagePanel.tsx | 2 -- src/components/structures/TimelinePanel.tsx | 2 -- src/components/views/right_panel/TimelineCard.tsx | 1 - src/stores/widgets/WidgetLayoutStore.ts | 4 ---- 4 files changed, 9 deletions(-) diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 0f013791a42..446fc2062b8 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -180,7 +180,6 @@ interface IProps { getRelationsForEvent?(eventId: string, relationType: string, eventType: string): Relations; hideThreadedMessages?: boolean; - threadViewPreviousCard?: RightPanelPhases; } interface IState { @@ -791,7 +790,6 @@ export default class MessagePanel extends React.Component { callEventGrouper={callEventGrouper} hideSender={this.membersCount <= 2 && this.props.layout === Layout.Bubble} timelineRenderingType={this.context.timelineRenderingType} - threadViewPreviousCard={this.props.threadViewPreviousCard} /> , ); diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index 3f3e5bc7199..24e352f11c6 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -134,7 +134,6 @@ interface IProps { onPaginationRequest?(timelineWindow: TimelineWindow, direction: string, size: number): Promise; hideThreadedMessages?: boolean; - threadViewPreviousCard?: RightPanelPhases; } interface IState { @@ -1538,7 +1537,6 @@ class TimelinePanel extends React.Component { layout={this.props.layout} enableFlair={SettingsStore.getValue(UIFeature.Flair)} hideThreadedMessages={this.props.hideThreadedMessages} - threadViewPreviousCard={this.props.threadViewPreviousCard} /> ); } diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index 451295afc4e..d6b307eac07 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -78,7 +78,6 @@ export default class TimelineCard extends React.Component { sendReadReceiptOnLoad={true} timelineSet={this.props.room.getUnfilteredTimelineSet()} showUrlPreview={true} - threadViewPreviousCard={RightPanelPhases.Timeline} layout={Layout.Group} hideThreadedMessages={false} hidden={false} diff --git a/src/stores/widgets/WidgetLayoutStore.ts b/src/stores/widgets/WidgetLayoutStore.ts index 8b97d95d3b3..823dd450d22 100644 --- a/src/stores/widgets/WidgetLayoutStore.ts +++ b/src/stores/widgets/WidgetLayoutStore.ts @@ -26,10 +26,6 @@ import { SettingLevel } from "../../settings/SettingLevel"; import { arrayFastClone } from "../../utils/arrays"; import { UPDATE_EVENT } from "../AsyncStore"; import { compare } from "../../utils/strings"; -import dis from '../../dispatcher/dispatcher'; -import { SetRightPanelPhasePayload } from "../../dispatcher/payloads/SetRightPanelPhasePayload"; -import { Action } from "../../dispatcher/actions"; -import { RightPanelPhases } from "../RightPanelStorePhases"; export const WIDGET_LAYOUT_EVENT_TYPE = "io.element.widgets.layout"; From 5a3cf2b8294f3a27073c68434093b74a02640b0f Mon Sep 17 00:00:00 2001 From: Timo K Date: Wed, 17 Nov 2021 19:59:09 +0100 Subject: [PATCH 54/70] remove unecassary imports --- src/components/structures/MessagePanel.tsx | 1 - src/components/structures/TimelinePanel.tsx | 1 - src/components/views/right_panel/TimelineCard.tsx | 1 - 3 files changed, 3 deletions(-) diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 446fc2062b8..6a204775dc0 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -50,7 +50,6 @@ import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; import EditorStateTransfer from "../../utils/EditorStateTransfer"; import { logger } from 'matrix-js-sdk/src/logger'; import { Action } from '../../dispatcher/actions'; -import { RightPanelPhases } from '../../stores/RightPanelStorePhases'; const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes const continuedTypes = [EventType.Sticker, EventType.RoomMessage]; diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index 24e352f11c6..d830d8ef7df 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -50,7 +50,6 @@ import ErrorDialog from '../views/dialogs/ErrorDialog'; import { debounce } from 'lodash'; import { logger } from "matrix-js-sdk/src/logger"; -import { RightPanelPhases } from '../../stores/RightPanelStorePhases'; const PAGINATE_SIZE = 20; const INITIAL_SIZE = 20; diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index d6b307eac07..cc7e7c5823d 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -19,7 +19,6 @@ import { MatrixEvent, Room } from 'matrix-js-sdk/src'; import { Thread } from 'matrix-js-sdk/src/models/thread'; import BaseCard from "./BaseCard"; -import { RightPanelPhases } from "../../../stores/RightPanelStorePhases"; import ResizeNotifier from '../../../utils/ResizeNotifier'; import MessageComposer from '../rooms/MessageComposer'; From 3acb7a38e2a5bea804f2401d2fd7f05e44aa27dd Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 18 Nov 2021 12:26:27 +0100 Subject: [PATCH 55/70] fix settings layout path --- src/components/views/right_panel/TimelineCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index cc7e7c5823d..890a50bf02b 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -23,7 +23,7 @@ import BaseCard from "./BaseCard"; import ResizeNotifier from '../../../utils/ResizeNotifier'; import MessageComposer from '../rooms/MessageComposer'; import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks'; -import { Layout } from '../../../settings/Layout'; +import { Layout } from '../../../settings/enums/Layout'; import TimelinePanel from '../../structures/TimelinePanel'; import { E2EStatus } from '../../../utils/ShieldUtils'; import EditorStateTransfer from '../../../utils/EditorStateTransfer'; From 786cff865c0809160a9f488e4370cccd7249933e Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 18 Nov 2021 13:05:43 +0100 Subject: [PATCH 56/70] timeline panel header fixups --- res/css/views/right_panel/_TimelineCard.scss | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/res/css/views/right_panel/_TimelineCard.scss b/res/css/views/right_panel/_TimelineCard.scss index ebf1eec1172..101eef59bc2 100644 --- a/res/css/views/right_panel/_TimelineCard.scss +++ b/res/css/views/right_panel/_TimelineCard.scss @@ -17,8 +17,6 @@ limitations under the License. .mx_TimelineCard { .mx_TimelineCard__header { margin-left: 6px; - display: flex; - flex: 1; span:first-of-type { font-weight: 600; @@ -27,10 +25,11 @@ limitations under the License. color: $secondary-content; } } - .mx_BaseCardHeader { + .mx_BaseCard_header { margin: 5px 0 9px 0; .mx_BaseCard_close { margin: 8px; + right: 0; } } } From 842150cadc0e6019c1f45d295b4b2f9ff0196dee Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 18 Nov 2021 14:25:14 +0100 Subject: [PATCH 57/70] only enable new back button behaviour if feature enabled --- src/components/structures/ThreadView.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index d640715c2a9..4641fb2a161 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -42,6 +42,7 @@ import UploadBar from './UploadBar'; import { _t } from '../../languageHandler'; import ThreadListContextMenu from '../views/context_menus/ThreadListContextMenu'; import RightPanelStore from '../../stores/RightPanelStore'; +import SettingsStore from '../../settings/SettingsStore'; interface IProps { room: Room; @@ -205,6 +206,9 @@ export default class ThreadView extends React.Component { }; let previousPhase = RightPanelStore.getSharedInstance().previousPhase; + if (SettingsStore.getValue("feature_maximised_widgets")) { + previousPhase = RightPanelPhases.ThreadPanel; + } // Make sure the previous Phase is always one of the two: Timeline or ThreadPanel if (![RightPanelPhases.ThreadPanel, RightPanelPhases.Timeline].includes(previousPhase)) { previousPhase = RightPanelPhases.ThreadPanel; From f8ae27ee1857ec5bfddf3dd5812f72b9a8391178 Mon Sep 17 00:00:00 2001 From: Timo K Date: Thu, 18 Nov 2021 16:12:27 +0100 Subject: [PATCH 58/70] prevent double timeline --- src/components/structures/RoomView.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index a05372f33fe..5c5910860dd 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -2098,7 +2098,14 @@ export class RoomView extends React.Component { />); } - const showRightPanel = this.state.room && this.state.showRightPanel; + let showRightPanel = this.state.room && this.state.showRightPanel; + // This is a hack to hide the chat. This should not be necassary once the right panel + // phase is stored per room. + if (RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline + && this.state.mainSplitContentType === MainSplitContentType.Timeline ) { + // Two timelines are shown prevent this by hiding the right panel + showRightPanel = false; + } const rightPanel = showRightPanel ? Date: Fri, 19 Nov 2021 16:50:51 +0100 Subject: [PATCH 59/70] disable RR's --- src/components/views/right_panel/TimelineCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index 890a50bf02b..b2def30b62f 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -71,7 +71,7 @@ export default class TimelineCard extends React.Component { header={this.renderTimelineCardHeader()} > Date: Fri, 19 Nov 2021 16:51:54 +0100 Subject: [PATCH 60/70] remove unread indicator fragments HeaderButton --- src/components/views/right_panel/RoomHeaderButtons.tsx | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index 8b0a3e3670c..b3f563455ed 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -70,20 +70,13 @@ const PinnedMessagesHeaderButton = ({ room, isHighlighted, onClick }) => { const TimelineCardHeaderButton = ({ room, isHighlighted, showNewMessage, onClick }) => { if (!SettingsStore.getValue("feature_maximised_widgets")) return null; - let unreadIndicator; - if (/*pinnedEvents.some(id => !readPinnedEvents.has(id)*/ showNewMessage) { - unreadIndicator =
; - } - return - { unreadIndicator } - ; + />; }; interface IProps { From 1e3b157bbb7e40a5de88f6ddd99030b86b37d4fa Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 19 Nov 2021 16:57:22 +0100 Subject: [PATCH 61/70] dont go to room info when widget gets closed --- src/components/views/elements/AppTile.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index c6745bde4f3..07353dea055 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -409,11 +409,6 @@ export default class AppTile extends React.Component { ? Container.Right : Container.Center; WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer); - if (targetContainer === Container.Right - && RightPanelStore.getSharedInstance().visibleRoomPanelPhase === RightPanelPhases.Timeline) { - // If the widget gets closed also close the RightPanel chat. - dis.dispatch({ action: Action.SetRightPanelPhase, phase: RightPanelPhases.RoomSummary }); - } }; private onContextMenuClick = (): void => { From 7999cdfd9c0ed6aada80075bfe986a9332a2d711 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 19 Nov 2021 17:00:25 +0100 Subject: [PATCH 62/70] styling stuff --- res/css/views/right_panel/_TimelineCard.scss | 1 + src/components/views/elements/AppTile.tsx | 6 +++--- src/components/views/rooms/EventTile.tsx | 7 +++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/res/css/views/right_panel/_TimelineCard.scss b/res/css/views/right_panel/_TimelineCard.scss index 101eef59bc2..c6e6f9d51b7 100644 --- a/res/css/views/right_panel/_TimelineCard.scss +++ b/res/css/views/right_panel/_TimelineCard.scss @@ -25,6 +25,7 @@ limitations under the License. color: $secondary-content; } } + .mx_BaseCard_header { margin: 5px 0 9px 0; .mx_BaseCard_close { diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index 07353dea055..ae3d5d9d525 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -405,9 +405,9 @@ export default class AppTile extends React.Component { private onMaxMinWidgetClick = (): void => { const targetContainer = - WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Center) - ? Container.Right - : Container.Center; + WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Center) + ? Container.Right + : Container.Center; WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer); }; diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 01ae555e5cf..0ed29d18b63 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -619,8 +619,11 @@ export default class EventTile extends React.Component {
{ - dispatchShowThreadEvent(this.props.mxEvent); - }}> + dispatchShowThreadEvent( + this.props.mxEvent, + ); + }} + > { _t("%(count)s reply", { count: this.thread.length, From 92d8895ca341c5270f2579588824b22b900a2114 Mon Sep 17 00:00:00 2001 From: Timo K Date: Fri, 19 Nov 2021 17:23:13 +0100 Subject: [PATCH 63/70] solve "never show two timelines" more properly --- src/components/structures/RoomView.tsx | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 5c5910860dd..4698ad3a39a 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -337,6 +337,7 @@ export class RoomView extends React.Component { }); } this.checkWidgets(this.state.room); + this.checkRightPanel(this.state.room); }; private checkWidgets = (room) => { @@ -354,6 +355,20 @@ export class RoomView extends React.Component { : MainSplitContentType.Timeline; }; + private checkRightPanel = (room) => { + // This is a hack to hide the chat. This should not be necassary once the right panel + // phase is stored per room. (need to be done after check widget so that mainSplitContentType is updated) + if (RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline + && this.state.showRightPanel + && !WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room)) { + // Two timelines are shown prevent this by hiding the right panel + dis.dispatch({ + action: Action.ToggleRightPanel, + type: "room", + }); + } + }; + private onReadReceiptsChange = () => { this.setState({ showReadReceipts: SettingsStore.getValue("showReadReceipts", this.state.roomId), @@ -1004,6 +1019,7 @@ export class RoomView extends React.Component { this.updateE2EStatus(room); this.updatePermissions(room); this.checkWidgets(room); + this.checkRightPanel(room); this.setState({ liveTimeline: room.getLiveTimeline(), @@ -2098,14 +2114,8 @@ export class RoomView extends React.Component { />); } - let showRightPanel = this.state.room && this.state.showRightPanel; - // This is a hack to hide the chat. This should not be necassary once the right panel - // phase is stored per room. - if (RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline - && this.state.mainSplitContentType === MainSplitContentType.Timeline ) { - // Two timelines are shown prevent this by hiding the right panel - showRightPanel = false; - } + const showRightPanel = this.state.room && this.state.showRightPanel; + const rightPanel = showRightPanel ? Date: Fri, 19 Nov 2021 17:27:02 +0100 Subject: [PATCH 64/70] hello linter ;) --- src/components/views/elements/AppTile.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/views/elements/AppTile.tsx b/src/components/views/elements/AppTile.tsx index ae3d5d9d525..c341e9bec9b 100644 --- a/src/components/views/elements/AppTile.tsx +++ b/src/components/views/elements/AppTile.tsx @@ -88,9 +88,6 @@ interface IState { } import { logger } from "matrix-js-sdk/src/logger"; -import { RightPanelPhases } from '../../../stores/RightPanelStorePhases'; -import { Action } from '../../../dispatcher/actions'; -import RightPanelStore from '../../../stores/RightPanelStore'; @replaceableComponent("views.elements.AppTile") export default class AppTile extends React.Component { From 1bf0704fe14e5844483b40cc995c53266b480b2a Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Fri, 19 Nov 2021 17:45:01 +0100 Subject: [PATCH 65/70] Update src/components/structures/RoomView.tsx Co-authored-by: J. Ryan Stinnett --- src/components/structures/RoomView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 4698ad3a39a..81a6c8e0e94 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -356,7 +356,7 @@ export class RoomView extends React.Component { }; private checkRightPanel = (room) => { - // This is a hack to hide the chat. This should not be necassary once the right panel + // This is a hack to hide the chat. This should not be necessary once the right panel // phase is stored per room. (need to be done after check widget so that mainSplitContentType is updated) if (RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline && this.state.showRightPanel From f03de7163397a4479518d8889c43384e40e3e7cf Mon Sep 17 00:00:00 2001 From: Timo <16718859+toger5@users.noreply.github.com> Date: Fri, 19 Nov 2021 17:45:46 +0100 Subject: [PATCH 66/70] Update src/components/structures/RoomView.tsx Co-authored-by: J. Ryan Stinnett --- src/components/structures/RoomView.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 81a6c8e0e94..3a7397b2de6 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -358,9 +358,11 @@ export class RoomView extends React.Component { private checkRightPanel = (room) => { // This is a hack to hide the chat. This should not be necessary once the right panel // phase is stored per room. (need to be done after check widget so that mainSplitContentType is updated) - if (RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline - && this.state.showRightPanel - && !WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room)) { + if ( + RightPanelStore.getSharedInstance().roomPanelPhase === RightPanelPhases.Timeline && + this.state.showRightPanel && + !WidgetLayoutStore.instance.hasMaximisedWidget(this.state.room) + ) { // Two timelines are shown prevent this by hiding the right panel dis.dispatch({ action: Action.ToggleRightPanel, From 4f4b1851c56a535449d8dd897de7b7973780cd5c Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 22 Nov 2021 17:25:15 +0100 Subject: [PATCH 67/70] remove unused var (showNewMessages) --- src/components/views/right_panel/RoomHeaderButtons.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index b3f563455ed..5405689fb30 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -67,7 +67,7 @@ const PinnedMessagesHeaderButton = ({ room, isHighlighted, onClick }) => { ; }; -const TimelineCardHeaderButton = ({ room, isHighlighted, showNewMessage, onClick }) => { +const TimelineCardHeaderButton = ({ room, isHighlighted, onClick }) => { if (!SettingsStore.getValue("feature_maximised_widgets")) return null; return { { SettingsStore.getValue("feature_thread") && Date: Mon, 22 Nov 2021 17:27:47 +0100 Subject: [PATCH 68/70] add comment about RR's --- src/components/views/right_panel/TimelineCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/right_panel/TimelineCard.tsx b/src/components/views/right_panel/TimelineCard.tsx index b2def30b62f..940185c206e 100644 --- a/src/components/views/right_panel/TimelineCard.tsx +++ b/src/components/views/right_panel/TimelineCard.tsx @@ -71,7 +71,7 @@ export default class TimelineCard extends React.Component { header={this.renderTimelineCardHeader()} > Date: Wed, 24 Nov 2021 16:48:51 +0100 Subject: [PATCH 69/70] fix feature flag check --- src/components/structures/ThreadView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index 4641fb2a161..9341a48a2cb 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -206,7 +206,7 @@ export default class ThreadView extends React.Component { }; let previousPhase = RightPanelStore.getSharedInstance().previousPhase; - if (SettingsStore.getValue("feature_maximised_widgets")) { + if (!SettingsStore.getValue("feature_maximised_widgets")) { previousPhase = RightPanelPhases.ThreadPanel; } // Make sure the previous Phase is always one of the two: Timeline or ThreadPanel From bfdb6d1829ed2dff47fbaf1527743509cbf23ad1 Mon Sep 17 00:00:00 2001 From: Timo K Date: Mon, 29 Nov 2021 14:16:40 +0100 Subject: [PATCH 70/70] remove viewInRoom button if a widget is maximised - if the widget is maximised there is not main split timeline to in which the thread could be shown. --- .../views/context_menus/MessageContextMenu.tsx | 6 +++++- .../context_menus/ThreadListContextMenu.tsx | 16 +++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index 2b39f9f7176..4f05115daf4 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -40,6 +40,7 @@ import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import { IPosition, ChevronFace } from '../../structures/ContextMenu'; import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext'; import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload"; +import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore'; export function canCancel(eventStatus: EventStatus): boolean { return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT; @@ -404,9 +405,12 @@ export default class MessageContextMenu extends React.Component ); const isThreadRootEvent = isThread && this.props.mxEvent?.getThread()?.rootEvent === this.props.mxEvent; + const isMainSplitTimelineShown = !WidgetLayoutStore.instance.hasMaximisedWidget( + MatrixClientPeg.get().getRoom(mxEvent.getRoomId()), + ); const commonItemsList = ( - { isThreadRootEvent && = ({ mxEvent, permalinkCreator, on } }, [optionsPosition, onMenuToggle]); + const isMainSplitTimelineShown = !WidgetLayoutStore.instance.hasMaximisedWidget( + MatrixClientPeg.get().getRoom(mxEvent.getRoomId()), + ); return = ({ mxEvent, permalinkCreator, on {...contextMenuBelow(optionsPosition)} > - viewInRoom(e)} - label={_t("View in room")} - iconClassName="mx_ThreadPanel_viewInRoom" - /> + { isMainSplitTimelineShown && + viewInRoom(e)} + label={_t("View in room")} + iconClassName="mx_ThreadPanel_viewInRoom" + /> } copyLinkToThread(e)} label={_t("Copy link to thread")}