parent
d388ef0e96
commit
38b72c4995
|
@ -35,7 +35,7 @@ import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { aboveLeftOf, ContextMenuButton } from "../../structures/ContextMenu";
|
import { aboveLeftOf, ContextMenuButton } from "../../structures/ContextMenu";
|
||||||
import PersistedElement, { getPersistKey } from "./PersistedElement";
|
import PersistedElement, { getPersistKey } from "./PersistedElement";
|
||||||
import { WidgetType } from "../../../widgets/WidgetType";
|
import { WidgetType } from "../../../widgets/WidgetType";
|
||||||
import { StopGapWidget } from "../../../stores/widgets/StopGapWidget";
|
import { ElementWidget, StopGapWidget } from "../../../stores/widgets/StopGapWidget";
|
||||||
import { ElementWidgetActions } from "../../../stores/widgets/ElementWidgetActions";
|
import { ElementWidgetActions } from "../../../stores/widgets/ElementWidgetActions";
|
||||||
import WidgetContextMenu from "../context_menus/WidgetContextMenu";
|
import WidgetContextMenu from "../context_menus/WidgetContextMenu";
|
||||||
import WidgetAvatar from "../avatars/WidgetAvatar";
|
import WidgetAvatar from "../avatars/WidgetAvatar";
|
||||||
|
@ -50,6 +50,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||||
import { Action } from '../../../dispatcher/actions';
|
import { Action } from '../../../dispatcher/actions';
|
||||||
import { ElementWidgetCapabilities } from '../../../stores/widgets/ElementWidgetCapabilities';
|
import { ElementWidgetCapabilities } from '../../../stores/widgets/ElementWidgetCapabilities';
|
||||||
|
import { WidgetMessagingStore } from '../../../stores/widgets/WidgetMessagingStore';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
app: IApp;
|
app: IApp;
|
||||||
|
@ -196,6 +197,24 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private determineInitialRequiresClientState(): boolean {
|
||||||
|
try {
|
||||||
|
const mockWidget = new ElementWidget(this.props.app);
|
||||||
|
const widgetApi = WidgetMessagingStore.instance.getMessaging(mockWidget, this.props.room.roomId);
|
||||||
|
if (widgetApi) {
|
||||||
|
// Load value from existing API to prevent resetting the requiresClient value on layout changes.
|
||||||
|
return widgetApi.hasCapability(ElementWidgetCapabilities.RequiresClient);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// fallback to true
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiresClient is initially set to true. This avoids the broken state of the popout
|
||||||
|
// button being visible (for an instance) and then disappearing when the widget is loaded.
|
||||||
|
// requiresClient <-> hide the popout button
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set initial component state when the App wUrl (widget URL) is being updated.
|
* Set initial component state when the App wUrl (widget URL) is being updated.
|
||||||
* Component props *must* be passed (rather than relying on this.props).
|
* Component props *must* be passed (rather than relying on this.props).
|
||||||
|
@ -214,10 +233,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
error: null,
|
error: null,
|
||||||
menuDisplayed: false,
|
menuDisplayed: false,
|
||||||
widgetPageTitle: this.props.widgetPageTitle,
|
widgetPageTitle: this.props.widgetPageTitle,
|
||||||
// requiresClient is initially set to true. This avoids the broken state of the popout
|
requiresClient: this.determineInitialRequiresClientState(),
|
||||||
// button being visible (for an instance) and then disappearing when the widget is loaded.
|
|
||||||
// requiresClient <-> hide the popout button
|
|
||||||
requiresClient: true,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import React from "react";
|
||||||
import TestRenderer from "react-test-renderer";
|
import TestRenderer from "react-test-renderer";
|
||||||
import { jest } from "@jest/globals";
|
import { jest } from "@jest/globals";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { MatrixWidgetType } from "matrix-widget-api";
|
import { ClientWidgetApi, MatrixWidgetType } from "matrix-widget-api";
|
||||||
import { mount, ReactWrapper } from "enzyme";
|
import { mount, ReactWrapper } from "enzyme";
|
||||||
import { Optional } from "matrix-events-sdk";
|
import { Optional } from "matrix-events-sdk";
|
||||||
|
|
||||||
|
@ -39,11 +39,14 @@ import ActiveWidgetStore from "../../../../src/stores/ActiveWidgetStore";
|
||||||
import AppTile from "../../../../src/components/views/elements/AppTile";
|
import AppTile from "../../../../src/components/views/elements/AppTile";
|
||||||
import { Container, WidgetLayoutStore } from "../../../../src/stores/widgets/WidgetLayoutStore";
|
import { Container, WidgetLayoutStore } from "../../../../src/stores/widgets/WidgetLayoutStore";
|
||||||
import AppsDrawer from "../../../../src/components/views/rooms/AppsDrawer";
|
import AppsDrawer from "../../../../src/components/views/rooms/AppsDrawer";
|
||||||
|
import { ElementWidgetCapabilities } from "../../../../src/stores/widgets/ElementWidgetCapabilities";
|
||||||
|
import { ElementWidget } from "../../../../src/stores/widgets/StopGapWidget";
|
||||||
|
import { WidgetMessagingStore } from "../../../../src/stores/widgets/WidgetMessagingStore";
|
||||||
|
|
||||||
describe("AppTile", () => {
|
describe("AppTile", () => {
|
||||||
let cli;
|
let cli;
|
||||||
let r1;
|
let r1: Room;
|
||||||
let r2;
|
let r2: Room;
|
||||||
const resizeNotifier = new ResizeNotifier();
|
const resizeNotifier = new ResizeNotifier();
|
||||||
let app1: IApp;
|
let app1: IApp;
|
||||||
let app2: IApp;
|
let app2: IApp;
|
||||||
|
@ -328,6 +331,10 @@ describe("AppTile", () => {
|
||||||
moveToContainerSpy = jest.spyOn(WidgetLayoutStore.instance, 'moveToContainer');
|
moveToContainerSpy = jest.spyOn(WidgetLayoutStore.instance, 'moveToContainer');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("requiresClient should be true", () => {
|
||||||
|
expect(wrapper.state('requiresClient')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it("clicking 'minimise' should send the widget to the right", () => {
|
it("clicking 'minimise' should send the widget to the right", () => {
|
||||||
const minimiseButton = wrapper.find('.mx_AppTileMenuBar_iconButton_minimise');
|
const minimiseButton = wrapper.find('.mx_AppTileMenuBar_iconButton_minimise');
|
||||||
minimiseButton.first().simulate('click');
|
minimiseButton.first().simulate('click');
|
||||||
|
@ -355,5 +362,35 @@ describe("AppTile", () => {
|
||||||
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Top);
|
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Top);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("with an existing widgetApi holding requiresClient = false", () => {
|
||||||
|
let wrapper: ReactWrapper;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const api = {
|
||||||
|
hasCapability: (capability: ElementWidgetCapabilities): boolean => {
|
||||||
|
return !(capability === ElementWidgetCapabilities.RequiresClient);
|
||||||
|
},
|
||||||
|
once: () => {},
|
||||||
|
} as unknown as ClientWidgetApi;
|
||||||
|
|
||||||
|
const mockWidget = new ElementWidget(app1);
|
||||||
|
WidgetMessagingStore.instance.storeMessaging(mockWidget, r1.roomId, api);
|
||||||
|
|
||||||
|
wrapper = mount((
|
||||||
|
<MatrixClientContext.Provider value={cli}>
|
||||||
|
<AppTile
|
||||||
|
key={app1.id}
|
||||||
|
app={app1}
|
||||||
|
room={r1}
|
||||||
|
/>
|
||||||
|
</MatrixClientContext.Provider>
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("requiresClient should be false", () => {
|
||||||
|
expect(wrapper.state('requiresClient')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue