diff --git a/res/css/views/right_panel/_RoomSummaryCard.scss b/res/css/views/right_panel/_RoomSummaryCard.scss index 41df1ca2eb..84e02af7bc 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.scss +++ b/res/css/views/right_panel/_RoomSummaryCard.scss @@ -17,7 +17,7 @@ limitations under the License. .mx_RoomSummaryCard { // shrink left gutter by 12 and instead add it as margin to all things except the buttons // as their hover effect should go into the gutter - & > * { // TODO consolidate this as the standard effect + & > * { margin-left: 10px; margin-right: 10px; } @@ -57,7 +57,7 @@ limitations under the License. width: 54px; height: 54px; border-radius: 50%; - background-color: #737D8C; + background-color: #737D8C; // TODO margin-top: -3px; // alignment margin-left: -10px; // overlap border: 3px solid $dark-panel-bg-color; @@ -77,8 +77,8 @@ limitations under the License. } } - .mx_RoomSummaryCard_e2ee_secure{ - background-color: #5ABFF2; + .mx_RoomSummaryCard_e2ee_secure { + background-color: #5ABFF2; // TODO &::before { mask-image: url('$(res)/img/e2e/normal.svg'); } diff --git a/src/components/views/right_panel/RoomHeaderButtons.tsx b/src/components/views/right_panel/RoomHeaderButtons.tsx index fa97568fba..338290b7c9 100644 --- a/src/components/views/right_panel/RoomHeaderButtons.tsx +++ b/src/components/views/right_panel/RoomHeaderButtons.tsx @@ -25,6 +25,7 @@ import HeaderButtons, {HeaderKind} from './HeaderButtons'; import {RightPanelPhases} from "../../../stores/RightPanelStorePhases"; import {Action} from "../../../dispatcher/actions"; import {ActionPayload} from "../../../dispatcher/payloads"; +import RightPanelStore from "../../../stores/RightPanelStore"; const ROOM_INFO_PHASES = [ RightPanelPhases.RoomSummary, @@ -57,11 +58,15 @@ export default class RoomHeaderButtons extends HeaderButtons { } } - // TODO make it restore whatever widget they were on last private onRoomSummaryClicked = () => { - if (this.state.phase === RightPanelPhases.Widget) { - // Close the panel - this.setPhase(RightPanelPhases.Widget); + // use roomPanelPhase rather than this.state.phase as it remembers the latest one if we close + const lastPhase = RightPanelStore.getSharedInstance().roomPanelPhase; + if (ROOM_INFO_PHASES.includes(lastPhase)) { + if (this.state.phase === lastPhase) { + this.setPhase(lastPhase); + } else { + this.setPhase(lastPhase, RightPanelStore.getSharedInstance().roomPanelPhaseParams); + } } else { // This toggles for us, if needed this.setPhase(RightPanelPhases.RoomSummary); diff --git a/src/components/views/right_panel/WidgetCard.tsx b/src/components/views/right_panel/WidgetCard.tsx index bbd02c18fb..621b1aa1c7 100644 --- a/src/components/views/right_panel/WidgetCard.tsx +++ b/src/components/views/right_panel/WidgetCard.tsx @@ -46,13 +46,6 @@ interface IProps { onClose(): void; } -const onFinished = () => { - defaultDispatcher.dispatch({ - action: Action.SetRightPanelPhase, - phase: RightPanelPhases.RoomSummary, - }); -} - const WidgetCard: React.FC = ({ room, widgetId, onClose }) => { const cli = useContext(MatrixClientContext); @@ -64,8 +57,11 @@ const WidgetCard: React.FC = ({ room, widgetId, onClose }) => { useEffect(() => { if (!app || isPinned) { - // TODO maybe we should do this in the ActiveWidgetStore instead - onFinished(); + // stop showing this card + defaultDispatcher.dispatch({ + action: Action.SetRightPanelPhase, + phase: RightPanelPhases.RoomSummary, + }); } }, [app, isPinned]); diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 43bb989d1f..e15cb46145 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -609,6 +609,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { }, "Widgets.pinned": { supportedLevels: LEVELS_ROOM_OR_ACCOUNT, - default: [], + default: {}, }, }; diff --git a/src/stores/WidgetStore.ts b/src/stores/WidgetStore.ts index cf74081633..a43a6bfc30 100644 --- a/src/stores/WidgetStore.ts +++ b/src/stores/WidgetStore.ts @@ -24,6 +24,7 @@ import SettingsStore from "../settings/SettingsStore"; import WidgetEchoStore from "../stores/WidgetEchoStore"; import WidgetUtils from "../utils/WidgetUtils"; import {SettingLevel} from "../settings/SettingLevel"; +import {WidgetType} from "../widgets/WidgetType"; interface IState {} @@ -40,7 +41,7 @@ export interface IApp { interface IRoomWidgets { widgets: IApp[]; - pinned: Set; + pinned: Record; } // TODO consolidate WidgetEchoStore into this @@ -65,7 +66,7 @@ export default class WidgetStore extends AsyncStoreWithClient { private initRoom(roomId: string) { if (!this.roomMap.has(roomId)) { this.roomMap.set(roomId, { - pinned: new Set(), + pinned: {}, widgets: [], }); } @@ -81,7 +82,7 @@ export default class WidgetStore extends AsyncStoreWithClient { } if (pinned) { - this.getRoom(room.roomId).pinned = new Set(pinned); + this.getRoom(room.roomId).pinned = pinned; } this.loadRoomWidgets(room); @@ -144,9 +145,8 @@ export default class WidgetStore extends AsyncStoreWithClient { }; private onPinnedWidgetsChange = (settingName: string, roomId: string) => { - const pinned = SettingsStore.getValue(settingName, roomId); this.initRoom(roomId); - this.getRoom(roomId).pinned = new Set(pinned); + this.getRoom(roomId).pinned = SettingsStore.getValue(settingName, roomId); this.emit(roomId); this.emit("update"); }; @@ -154,8 +154,11 @@ export default class WidgetStore extends AsyncStoreWithClient { public isPinned(widgetId: string) { const roomId = this.getRoomId(widgetId); const roomInfo = this.getRoom(roomId); - // TODO heuristic for Jitsi etc - return roomInfo ? roomInfo.pinned.has(widgetId) : false; + + let pinned = roomInfo && roomInfo.pinned[widgetId]; + // Jitsi widgets should be pinned by default + if (pinned === undefined && WidgetType.JITSI.matches(this.widgetMap.get(widgetId).type)) pinned = true; + return pinned; } public canPin(widgetId: string) { @@ -163,25 +166,31 @@ export default class WidgetStore extends AsyncStoreWithClient { // the only case it will go to three is if you have two and then a Jitsi gets added const roomId = this.getRoomId(widgetId); const roomInfo = this.getRoom(roomId); - return roomInfo && roomInfo.pinned.size < 2; + return roomInfo && Object.keys(roomInfo.pinned).length < 2; } public pinWidget(widgetId: string) { - const roomId = this.getRoomId(widgetId); - const roomInfo = this.getRoom(roomId); - if (!roomInfo) return; - roomInfo.pinned.add(widgetId); - SettingsStore.setValue("Widgets.pinned", roomId, SettingLevel.ROOM_ACCOUNT, Array.from(roomInfo.pinned)); - this.emit(roomId); - this.emit("update"); + this.setPinned(widgetId, true); } public unpinWidget(widgetId: string) { + this.setPinned(widgetId, false); + } + + private setPinned(widgetId: string, value: boolean) { const roomId = this.getRoomId(widgetId); const roomInfo = this.getRoom(roomId); if (!roomInfo) return; - roomInfo.pinned.delete(widgetId); - SettingsStore.setValue("Widgets.pinned", roomId, SettingLevel.ROOM_ACCOUNT, Array.from(roomInfo.pinned)); + roomInfo.pinned[widgetId] = value; + + // Clean up the pinned record + Object.keys(roomInfo).forEach(wId => { + if (!roomInfo.widgets.some(w => w.id === wId)) { + delete roomInfo.pinned[wId]; + } + }); + + SettingsStore.setValue("Widgets.pinned", roomId, SettingLevel.ROOM_ACCOUNT, roomInfo.pinned); this.emit(roomId); this.emit("update"); }