diff --git a/src/components/views/elements/PersistentApp.tsx b/src/components/views/elements/PersistentApp.tsx index 80e57b537b..aba42236bb 100644 --- a/src/components/views/elements/PersistentApp.tsx +++ b/src/components/views/elements/PersistentApp.tsx @@ -25,6 +25,10 @@ import WidgetUtils from '../../../utils/WidgetUtils'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { replaceableComponent } from "../../../utils/replaceableComponent"; import AppTile from "./AppTile"; +import { Container, WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore'; +import { RightPanelPhases } from '../../../stores/right-panel/RightPanelStorePhases'; +import RightPanelStore from '../../../stores/right-panel/RightPanelStore'; +import { UPDATE_EVENT } from '../../../stores/AsyncStore'; interface IProps { // none @@ -33,6 +37,7 @@ interface IProps { interface IState { roomId: string; persistentWidgetId: string; + rightPanelPhase?: RightPanelPhases; } @replaceableComponent("views.elements.PersistentApp") @@ -45,12 +50,14 @@ export default class PersistentApp extends React.Component { this.state = { roomId: RoomViewStore.getRoomId(), persistentWidgetId: ActiveWidgetStore.instance.getPersistentWidgetId(), + rightPanelPhase: RightPanelStore.instance.currentCard.phase, }; } public componentDidMount(): void { this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate); ActiveWidgetStore.instance.on(ActiveWidgetStoreEvent.Update, this.onActiveWidgetStoreUpdate); + RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate); MatrixClientPeg.get().on("Room.myMembership", this.onMyMembership); } @@ -59,6 +66,7 @@ export default class PersistentApp extends React.Component { this.roomStoreToken.remove(); } ActiveWidgetStore.instance.removeListener(ActiveWidgetStoreEvent.Update, this.onActiveWidgetStoreUpdate); + RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate); if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("Room.myMembership", this.onMyMembership); } @@ -71,6 +79,12 @@ export default class PersistentApp extends React.Component { }); }; + private onRightPanelStoreUpdate = () => { + this.setState({ + rightPanelPhase: RightPanelStore.instance.currentCard.phase, + }); + }; + private onActiveWidgetStoreUpdate = (): void => { this.setState({ persistentWidgetId: ActiveWidgetStore.instance.getPersistentWidgetId(), @@ -88,8 +102,9 @@ export default class PersistentApp extends React.Component { }; public render(): JSX.Element { - if (this.state.persistentWidgetId) { - const persistentWidgetInRoomId = ActiveWidgetStore.instance.getRoomId(this.state.persistentWidgetId); + const wId = this.state.persistentWidgetId; + if (wId) { + const persistentWidgetInRoomId = ActiveWidgetStore.instance.getRoomId(wId); const persistentWidgetInRoom = MatrixClientPeg.get().getRoom(persistentWidgetInRoomId); @@ -97,8 +112,24 @@ export default class PersistentApp extends React.Component { // thus no room is associated anymore. if (!persistentWidgetInRoom) return null; - const myMembership = persistentWidgetInRoom.getMyMembership(); - if (this.state.roomId !== persistentWidgetInRoomId && myMembership === "join") { + const wls = WidgetLayoutStore.instance; + + const userIsPartOfTheRoom = persistentWidgetInRoom.getMyMembership() == "join"; + const fromAnotherRoom = this.state.roomId !== persistentWidgetInRoomId; + + const notInRightPanel = + !(this.state.rightPanelPhase == RightPanelPhases.Widget && + wId == RightPanelStore.instance.currentCard.state?.widgetId); + const notInCenterContainer = + !wls.getContainerWidgets(persistentWidgetInRoom, Container.Center).some((app) => app.id == wId); + const notInTopContainer = + !wls.getContainerWidgets(persistentWidgetInRoom, Container.Top).some(app => app.id == wId); + if ( + // the widget should only be shown as a persistent app (in a floating pip container) if it is not visible on screen + // either, because we are viewing a different room OR because it is in none of the possible containers of the room view. + (fromAnotherRoom && userIsPartOfTheRoom) || + (notInRightPanel && notInCenterContainer && notInTopContainer && userIsPartOfTheRoom) + ) { // get the widget data const appEvent = WidgetUtils.getRoomWidgets(persistentWidgetInRoom).find((ev) => { return ev.getStateKey() === ActiveWidgetStore.instance.getPersistentWidgetId(); diff --git a/src/components/views/rooms/Stickerpicker.tsx b/src/components/views/rooms/Stickerpicker.tsx index 96e759ec93..f46017959e 100644 --- a/src/components/views/rooms/Stickerpicker.tsx +++ b/src/components/views/rooms/Stickerpicker.tsx @@ -29,13 +29,14 @@ import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; import SettingsStore from "../../../settings/SettingsStore"; import ContextMenu, { ChevronFace } from "../../structures/ContextMenu"; import { WidgetType } from "../../../widgets/WidgetType"; -import { Action } from "../../../dispatcher/actions"; import { WidgetMessagingStore } from "../../../stores/widgets/WidgetMessagingStore"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import { ActionPayload } from '../../../dispatcher/payloads'; import ScalarAuthClient from '../../../ScalarAuthClient'; import GenericElementContextMenu from "../context_menus/GenericElementContextMenu"; import { IApp } from "../../../stores/WidgetStore"; +import RightPanelStore from '../../../stores/right-panel/RightPanelStore'; +import { UPDATE_EVENT } from '../../../stores/AsyncStore'; // This should be below the dialog level (4000), but above the rest of the UI (1000-2000). // We sit in a context menu, so this should be given to the context menu. @@ -139,6 +140,7 @@ export default class Stickerpicker extends React.PureComponent { // Track updates to widget state in account data MatrixClientPeg.get().on('accountData', this.updateWidget); + RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate); // Initialise widget state from current account data this.updateWidget(); } @@ -146,7 +148,7 @@ export default class Stickerpicker extends React.PureComponent { public componentWillUnmount(): void { const client = MatrixClientPeg.get(); if (client) client.removeListener('accountData', this.updateWidget); - + RightPanelStore.instance.off(UPDATE_EVENT, this.onRightPanelStoreUpdate); window.removeEventListener('resize', this.onResize); if (this.dispatcherRef) { dis.unregister(this.dispatcherRef); @@ -204,7 +206,6 @@ export default class Stickerpicker extends React.PureComponent { case "stickerpicker_close": this.props.setShowStickers(false); break; - case Action.AfterRightPanelPhaseChange: case "show_left_panel": case "hide_left_panel": this.props.setShowStickers(false); @@ -212,6 +213,10 @@ export default class Stickerpicker extends React.PureComponent { } }; + private onRightPanelStoreUpdate = () => { + this.props.setShowStickers(false); + }; + private defaultStickerpickerContent(): JSX.Element { return ( { draggable={pipMode} onDoubleClick={this.onDoubleClick} > - { ({ onStartMoving, onResize }) => } + { + ({ onStartMoving, onResize }) => + + } ); diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index b0bb02d79e..fe635983ee 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -102,11 +102,6 @@ export enum Action { */ ViewRoomDelta = "view_room_delta", - /** - * Trigged after the phase of the right panel is set. Should be used with AfterRightPanelPhaseChangePayload. - */ - AfterRightPanelPhaseChange = "after_right_panel_phase_change", - /** * Opens the modal dial pad */