Merge branch 'develop' into sort-imports

Signed-off-by: Aaron Raimist <aaron@raim.ist>
This commit is contained in:
Aaron Raimist 2021-12-09 08:34:20 +00:00
commit 7b94e13a84
642 changed files with 30052 additions and 8035 deletions

View file

@ -48,6 +48,7 @@ import { WidgetType } from "../../widgets/WidgetType";
import ActiveWidgetStore from "../ActiveWidgetStore";
import { objectShallowClone } from "../../utils/objects";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { Action } from "../../dispatcher/actions";
import { ElementWidgetActions, IViewRoomApiRequest } from "./ElementWidgetActions";
import { ModalWidgetStore } from "../ModalWidgetStore";
import ThemeWatcher from "../../settings/watchers/ThemeWatcher";
@ -291,7 +292,7 @@ export class StopGapWidget extends EventEmitter {
// at this point we can change rooms, so do that
defaultDispatcher.dispatch({
action: 'view_room',
action: Action.ViewRoom,
room_id: targetRoomId,
});

View file

@ -29,11 +29,6 @@ import {
WidgetEventCapability,
WidgetKind,
} from "matrix-widget-api";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { IEvent, MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room";
import { logger } from "matrix-js-sdk/src/logger";
import { iterableDiff, iterableUnion } from "../../utils/iterables";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import ActiveRoomObserver from "../../ActiveRoomObserver";
@ -43,10 +38,16 @@ import WidgetCapabilitiesPromptDialog from "../../components/views/dialogs/Widge
import { WidgetPermissionCustomisations } from "../../customisations/WidgetPermissions";
import { OIDCState, WidgetPermissionStore } from "./WidgetPermissionStore";
import { WidgetType } from "../../widgets/WidgetType";
import { EventType, RelationType } from "matrix-js-sdk/src/@types/event";
import { CHAT_EFFECTS } from "../../effects";
import { containsEmoji } from "../../effects/utils";
import dis from "../../dispatcher/dispatcher";
import { tryTransformPermalinkToLocalHref } from "../../utils/permalinks/Permalinks";
import { IContent, IEvent, MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room";
import { logger } from "matrix-js-sdk/src/logger";
import SettingsStore from "../../settings/SettingsStore";
// TODO: Purge this from the universe
@ -141,7 +142,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
public async sendEvent(
eventType: string,
content: any,
content: IContent,
stateKey: string = null,
targetRoomId: string = null,
): Promise<ISendEventDetails> {
@ -164,7 +165,12 @@ export class StopGapWidgetDriver extends WidgetDriver {
if (eventType === EventType.RoomMessage) {
CHAT_EFFECTS.forEach((effect) => {
if (containsEmoji(content, effect.emojis)) {
dis.dispatch({ action: `effects.${effect.command}` });
// For initial threads launch, chat effects are disabled
// see #19731
const isNotThread = content["m.relates_to"].rel_type !== RelationType.Thread;
if (!SettingsStore.getValue("feature_thread") || isNotThread) {
dis.dispatch({ action: `effects.${effect.command}` });
}
}
});
}

View file

@ -39,8 +39,7 @@ export enum Container {
// changes needed", though this may change in the future.
Right = "right",
// ... more as needed. Note that most of this code assumes that there
// are only two containers, and that only the top container is special.
Center = "center"
}
export interface IStoredLayout {
@ -175,7 +174,7 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
}
};
private recalculateRoom(room: Room) {
public recalculateRoom(room: Room) {
const widgets = WidgetStore.instance.getApps(room.roomId);
if (!widgets?.length) {
this.byRoom[room.roomId] = {};
@ -196,18 +195,26 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
}
const roomLayout: ILayoutStateEvent = layoutEv ? layoutEv.getContent() : null;
// We essentially just need to find the top container's widgets because we
// only have two containers. Anything not in the top widget by the end of this
// function will go into the right container.
// We filter for the center container first.
// (An error is raised, if there are multiple widgets marked for the center container)
// For the right and top container multiple widgets are allowed.
const topWidgets: IApp[] = [];
const rightWidgets: IApp[] = [];
const centerWidgets: IApp[] = [];
for (const widget of widgets) {
const stateContainer = roomLayout?.widgets?.[widget.id]?.container;
const manualContainer = userLayout?.widgets?.[widget.id]?.container;
const isLegacyPinned = !!legacyPinned?.[widget.id];
const defaultContainer = WidgetType.JITSI.matches(widget.type) ? Container.Top : Container.Right;
if ((manualContainer) ? manualContainer === Container.Center : stateContainer === Container.Center) {
if (centerWidgets.length) {
console.error("Tried to push a second widget into the center container");
} else {
centerWidgets.push(widget);
}
// The widget won't need to be put in any other container.
continue;
}
let targetContainer = defaultContainer;
if (!!manualContainer || !!stateContainer) {
targetContainer = (manualContainer) ? manualContainer : stateContainer;
@ -324,6 +331,11 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
ordered: rightWidgets,
};
}
if (centerWidgets.length) {
this.byRoom[room.roomId][Container.Center] = {
ordered: centerWidgets,
};
}
const afterChanges = JSON.stringify(this.byRoom[room.roomId]);
if (afterChanges !== beforeChanges) {
@ -340,7 +352,11 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
}
public canAddToContainer(room: Room, container: Container): boolean {
return this.getContainerWidgets(room, container).length < MAX_PINNED;
switch (container) {
case Container.Top: return this.getContainerWidgets(room, container).length < MAX_PINNED;
case Container.Right: return this.getContainerWidgets(room, container).length < MAX_PINNED;
case Container.Center: return this.getContainerWidgets(room, container).length < 1;
}
}
public getResizerDistributions(room: Room, container: Container): string[] { // yes, string.
@ -424,11 +440,42 @@ export class WidgetLayoutStore extends ReadyWatchingStore {
public moveToContainer(room: Room, widget: IApp, toContainer: Container) {
const allWidgets = this.getAllWidgets(room);
if (!allWidgets.some(([w]) => w.id === widget.id)) return; // invalid
// Prepare other containers (potentially move widgets to obay the following rules)
switch (toContainer) {
case Container.Right:
// new "right" widget
break;
case Container.Center:
// new "center" widget => all other widgets go into "right"
for (const w of this.getContainerWidgets(room, Container.Top)) {
this.moveToContainer(room, w, Container.Right);
}
for (const w of this.getContainerWidgets(room, Container.Center)) {
this.moveToContainer(room, w, Container.Right);
}
break;
case Container.Top:
// new "top" widget => the center widget moves into "right"
if (this.hasMaximisedWidget(room)) {
this.moveToContainer(room, this.getContainerWidgets(room, Container.Center)[0], Container.Right);
}
break;
}
// move widgets into requested container.
this.updateUserLayout(room, {
[widget.id]: { container: toContainer },
});
}
public hasMaximisedWidget(room: Room) {
return this.getContainerWidgets(room, Container.Center).length > 0;
}
public hasPinnedWidgets(room: Room) {
return this.getContainerWidgets(room, Container.Top).length > 0;
}
public canCopyLayoutToRoom(room: Room): boolean {
if (!this.matrixClient) return false; // not ready yet
return room.currentState.maySendStateEvent(WIDGET_LAYOUT_EVENT_TYPE, this.matrixClient.getUserId());