Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/feat/widgets

This commit is contained in:
Michael Telatynski 2020-10-19 13:08:17 +01:00
commit 744a4abd1c
68 changed files with 795 additions and 593 deletions

View file

@ -23,7 +23,7 @@ import SettingsStore from "../settings/SettingsStore";
import * as utils from "matrix-js-sdk/src/utils";
import { UPDATE_EVENT } from "./AsyncStore";
import FlairStore from "./FlairStore";
import TagOrderStore from "./TagOrderStore";
import GroupFilterOrderStore from "./GroupFilterOrderStore";
import GroupStore from "./GroupStore";
import dis from "../dispatcher/dispatcher";
import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
@ -50,7 +50,7 @@ export class CommunityPrototypeStore extends AsyncStoreWithClient<IState> {
public getSelectedCommunityId(): string {
if (SettingsStore.getValue("feature_communities_v2_prototypes")) {
return TagOrderStore.getSelectedTags()[0];
return GroupFilterOrderStore.getSelectedTags()[0];
}
return null; // no selection as far as this function is concerned
}

View file

@ -46,7 +46,7 @@ function commonPrefix(a, b) {
return "";
}
/**
* A class for storing application state for ordering tags in the TagPanel.
* A class for storing application state for ordering tags in the GroupFilterPanel.
*/
class CustomRoomTagStore extends EventEmitter {
constructor() {

View file

@ -33,9 +33,9 @@ const INITIAL_STATE = {
};
/**
* A class for storing application state for ordering tags in the TagPanel.
* A class for storing application state for ordering tags in the GroupFilterPanel.
*/
class TagOrderStore extends Store {
class GroupFilterOrderStore extends Store {
constructor() {
super(dis);
@ -268,7 +268,7 @@ class TagOrderStore extends Store {
}
}
if (global.singletonTagOrderStore === undefined) {
global.singletonTagOrderStore = new TagOrderStore();
if (global.singletonGroupFilterOrderStore === undefined) {
global.singletonGroupFilterOrderStore = new GroupFilterOrderStore();
}
export default global.singletonTagOrderStore;
export default global.singletonGroupFilterOrderStore;

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import { RoomListStoreClass } from "./RoomListStore";
import TagOrderStore from "../TagOrderStore";
import GroupFilterOrderStore from "../GroupFilterOrderStore";
import { CommunityFilterCondition } from "./filters/CommunityFilterCondition";
import { arrayDiff, arrayHasDiff } from "../../utils/arrays";
@ -26,12 +26,12 @@ export class TagWatcher {
private filters = new Map<string, CommunityFilterCondition>();
constructor(private store: RoomListStoreClass) {
TagOrderStore.addListener(this.onTagsUpdated);
GroupFilterOrderStore.addListener(this.onTagsUpdated);
}
private onTagsUpdated = () => {
const lastTags = Array.from(this.filters.keys());
const newTags = TagOrderStore.getSelectedTags();
const newTags = GroupFilterOrderStore.getSelectedTags();
if (arrayHasDiff(lastTags, newTags)) {
// Selected tags changed, do some filtering

View file

@ -27,7 +27,13 @@ export class ReactionEventPreview implements IPreview {
const showDms = SettingsStore.getValue("feature_roomlist_preview_reactions_dms");
const showAll = SettingsStore.getValue("feature_roomlist_preview_reactions_all");
if (!showAll && (!showDms || DMRoomMap.shared().getUserIdForRoomId(event.getRoomId()))) return null;
// If we're not showing all reactions, see if we're showing DMs instead
if (!showAll) {
// If we're not showing reactions on DMs, or we are and the room isn't a DM, skip
if (!(showDms && DMRoomMap.shared().getUserIdForRoomId(event.getRoomId()))) {
return null;
}
}
const relation = event.getRelation();
if (!relation) return null; // invalid reaction (probably redacted)

View file

@ -17,6 +17,8 @@
import { Room } from "matrix-js-sdk/src/models/room";
import {
ClientWidgetApi,
IGetOpenIDActionRequest,
IGetOpenIDActionResponseData,
IStickerActionRequest,
IStickyActionRequest,
ITemplateParams,
@ -25,8 +27,10 @@ import {
IWidgetApiRequestEmptyData,
IWidgetData,
MatrixCapabilities,
OpenIDRequestState,
runTemplate,
Widget,
WidgetApiToWidgetAction,
WidgetApiFromWidgetAction,
} from "matrix-widget-api";
import { StopGapWidgetDriver } from "./StopGapWidgetDriver";
@ -43,6 +47,8 @@ import ActiveWidgetStore from "../ActiveWidgetStore";
import { objectShallowClone } from "../../utils/objects";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { ElementWidgetActions } from "./ElementWidgetActions";
import Modal from "../../Modal";
import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog";
// TODO: Destroy all of this code
@ -161,17 +167,20 @@ export class StopGapWidget extends EventEmitter {
userHttpAvatarUrl: OwnProfileStore.instance.getHttpAvatarUrl(),
}, opts?.asPopout);
// Add in some legacy support sprinkles
const parsed = new URL(templated);
// Add in some legacy support sprinkles (for non-popout widgets)
// TODO: Replace these with proper widget params
// See https://github.com/matrix-org/matrix-doc/pull/1958/files#r405714833
const parsed = new URL(templated);
parsed.searchParams.set('widgetId', this.mockWidget.id);
parsed.searchParams.set('parentUrl', window.location.href.split('#', 2)[0]);
if (!opts?.asPopout) {
parsed.searchParams.set('widgetId', this.mockWidget.id);
parsed.searchParams.set('parentUrl', window.location.href.split('#', 2)[0]);
// Give the widget a scalar token if we're supposed to (more legacy)
// TODO: Stop doing this
if (this.scalarToken) {
parsed.searchParams.set('scalar_token', this.scalarToken);
// Give the widget a scalar token if we're supposed to (more legacy)
// TODO: Stop doing this
if (this.scalarToken) {
parsed.searchParams.set('scalar_token', this.scalarToken);
}
}
// Replace the encoded dollar signs back to dollar signs. They have no special meaning
@ -187,12 +196,66 @@ export class StopGapWidget extends EventEmitter {
return !!this.messaging;
}
private get widgetId() {
return this.messaging.widget.id;
}
private onOpenIdReq = async (ev: CustomEvent<IGetOpenIDActionRequest>) => {
if (ev?.detail?.widgetId !== this.widgetId) return;
const rawUrl = this.appTileProps.app.url;
const widgetSecurityKey = WidgetUtils.getWidgetSecurityKey(this.widgetId, rawUrl, this.appTileProps.userWidget);
const settings = SettingsStore.getValue("widgetOpenIDPermissions");
if (settings.deny && settings.deny.includes(widgetSecurityKey)) {
this.messaging.transport.reply(ev.detail, <IGetOpenIDActionResponseData>{
state: OpenIDRequestState.Blocked,
});
return;
}
if (settings.allow && settings.allow.includes(widgetSecurityKey)) {
const credentials = await MatrixClientPeg.get().getOpenIdToken();
this.messaging.transport.reply(ev.detail, <IGetOpenIDActionResponseData>{
state: OpenIDRequestState.Allowed,
...credentials,
});
return;
}
// Confirm that we received the request
this.messaging.transport.reply(ev.detail, <IGetOpenIDActionResponseData>{
state: OpenIDRequestState.PendingUserConfirmation,
});
// Actually ask for permission to send the user's data
Modal.createTrackedDialog("OpenID widget permissions", '', WidgetOpenIDPermissionsDialog, {
widgetUrl: rawUrl.substr(0, rawUrl.lastIndexOf("?")),
widgetId: this.widgetId,
isUserWidget: this.appTileProps.userWidget,
onFinished: async (confirm) => {
const responseBody: IGetOpenIDActionResponseData = {
state: confirm ? OpenIDRequestState.Allowed : OpenIDRequestState.Blocked,
original_request_id: ev.detail.requestId, // eslint-disable-line camelcase
};
if (confirm) {
const credentials = await MatrixClientPeg.get().getOpenIdToken();
Object.assign(responseBody, credentials);
}
this.messaging.transport.send(WidgetApiToWidgetAction.OpenIDCredentials, responseBody).catch(error => {
console.error("Failed to send OpenID credentials: ", error);
});
},
});
};
public start(iframe: HTMLIFrameElement) {
if (this.started) return;
const driver = new StopGapWidgetDriver( this.appTileProps.whitelistCapabilities || []);
this.messaging = new ClientWidgetApi(this.mockWidget, iframe, driver);
this.messaging.addEventListener("preparing", () => this.emit("preparing"));
this.messaging.addEventListener("ready", () => this.emit("ready"));
this.messaging.addEventListener(`action:${WidgetApiFromWidgetAction.GetOpenIDCredentials}`, this.onOpenIdReq);
WidgetMessagingStore.instance.storeMessaging(this.mockWidget, this.messaging);
if (!this.appTileProps.userWidget && this.appTileProps.room) {