Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit e956cea

Browse files
committed
Fix disappearing widget poput button
1 parent 022535e commit e956cea

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

src/components/views/elements/AppTile.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import SettingsStore from "../../../settings/SettingsStore";
3535
import { aboveLeftOf, ContextMenuButton } from "../../structures/ContextMenu";
3636
import PersistedElement, { getPersistKey } from "./PersistedElement";
3737
import { WidgetType } from "../../../widgets/WidgetType";
38-
import { StopGapWidget } from "../../../stores/widgets/StopGapWidget";
38+
import { ElementWidget, StopGapWidget } from "../../../stores/widgets/StopGapWidget";
3939
import { ElementWidgetActions } from "../../../stores/widgets/ElementWidgetActions";
4040
import WidgetContextMenu from "../context_menus/WidgetContextMenu";
4141
import WidgetAvatar from "../avatars/WidgetAvatar";
@@ -50,6 +50,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
5050
import { ActionPayload } from "../../../dispatcher/payloads";
5151
import { Action } from '../../../dispatcher/actions';
5252
import { ElementWidgetCapabilities } from '../../../stores/widgets/ElementWidgetCapabilities';
53+
import { WidgetMessagingStore } from '../../../stores/widgets/WidgetMessagingStore';
5354

5455
interface IProps {
5556
app: IApp;
@@ -196,6 +197,20 @@ export default class AppTile extends React.Component<IProps, IState> {
196197
}
197198
};
198199

200+
private determineInitialRequiresClientState(): boolean {
201+
const mockWidget = new ElementWidget(this.props.app);
202+
const widgetApi = WidgetMessagingStore.instance.getMessaging(mockWidget, this.props.room.roomId);
203+
if (widgetApi) {
204+
// Load value from existing API to prevent resetting the requiresClient value on layout changes.
205+
return widgetApi.hasCapability(ElementWidgetCapabilities.RequiresClient);
206+
}
207+
208+
// requiresClient is initially set to true. This avoids the broken state of the popout
209+
// button being visible (for an instance) and then disappearing when the widget is loaded.
210+
// requiresClient <-> hide the popout button
211+
return true;
212+
}
213+
199214
/**
200215
* Set initial component state when the App wUrl (widget URL) is being updated.
201216
* Component props *must* be passed (rather than relying on this.props).
@@ -214,10 +229,7 @@ export default class AppTile extends React.Component<IProps, IState> {
214229
error: null,
215230
menuDisplayed: false,
216231
widgetPageTitle: this.props.widgetPageTitle,
217-
// requiresClient is initially set to true. This avoids the broken state of the popout
218-
// button being visible (for an instance) and then disappearing when the widget is loaded.
219-
// requiresClient <-> hide the popout button
220-
requiresClient: true,
232+
requiresClient: this.determineInitialRequiresClientState(),
221233
};
222234
}
223235

test/components/views/elements/AppTile-test.tsx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import React from "react";
1818
import TestRenderer from "react-test-renderer";
1919
import { jest } from "@jest/globals";
2020
import { Room } from "matrix-js-sdk/src/models/room";
21-
import { MatrixWidgetType } from "matrix-widget-api";
21+
import { ClientWidgetApi, MatrixWidgetType } from "matrix-widget-api";
2222
import { mount, ReactWrapper } from "enzyme";
2323
import { Optional } from "matrix-events-sdk";
2424

@@ -39,11 +39,14 @@ import ActiveWidgetStore from "../../../../src/stores/ActiveWidgetStore";
3939
import AppTile from "../../../../src/components/views/elements/AppTile";
4040
import { Container, WidgetLayoutStore } from "../../../../src/stores/widgets/WidgetLayoutStore";
4141
import AppsDrawer from "../../../../src/components/views/rooms/AppsDrawer";
42+
import { ElementWidgetCapabilities } from "../../../../src/stores/widgets/ElementWidgetCapabilities";
43+
import { ElementWidget } from "../../../../src/stores/widgets/StopGapWidget";
44+
import { WidgetMessagingStore } from "../../../../src/stores/widgets/WidgetMessagingStore";
4245

4346
describe("AppTile", () => {
4447
let cli;
45-
let r1;
46-
let r2;
48+
let r1: Room;
49+
let r2: Room;
4750
const resizeNotifier = new ResizeNotifier();
4851
let app1: IApp;
4952
let app2: IApp;
@@ -328,6 +331,10 @@ describe("AppTile", () => {
328331
moveToContainerSpy = jest.spyOn(WidgetLayoutStore.instance, 'moveToContainer');
329332
});
330333

334+
it("requiresClient should be true", () => {
335+
expect(wrapper.state('requiresClient')).toBe(true);
336+
});
337+
331338
it("clicking 'minimise' should send the widget to the right", () => {
332339
const minimiseButton = wrapper.find('.mx_AppTileMenuBar_iconButton_minimise');
333340
minimiseButton.first().simulate('click');
@@ -355,5 +362,35 @@ describe("AppTile", () => {
355362
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Top);
356363
});
357364
});
365+
366+
describe("with an existing widgetApi holding requiresClient = false", () => {
367+
let wrapper: ReactWrapper;
368+
369+
beforeEach(() => {
370+
const api = {
371+
hasCapability: (capability: ElementWidgetCapabilities): boolean => {
372+
return !(capability === ElementWidgetCapabilities.RequiresClient);
373+
},
374+
once: () => {},
375+
} as unknown as ClientWidgetApi;
376+
377+
const mockWidget = new ElementWidget(app1);
378+
WidgetMessagingStore.instance.storeMessaging(mockWidget, r1.roomId, api);
379+
380+
wrapper = mount((
381+
<MatrixClientContext.Provider value={cli}>
382+
<AppTile
383+
key={app1.id}
384+
app={app1}
385+
room={r1}
386+
/>
387+
</MatrixClientContext.Provider>
388+
));
389+
});
390+
391+
it("requiresClient should be false", () => {
392+
expect(wrapper.state('requiresClient')).toBe(false);
393+
});
394+
});
358395
});
359396
});

0 commit comments

Comments
 (0)