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

Commit 6122bdc

Browse files
committed
Merge develop into psf-771-button-for-live-location-share (using imerge)
2 parents 430eecd + 2778fd1 commit 6122bdc

31 files changed

+502
-220
lines changed

CHANGELOG.md

Lines changed: 148 additions & 0 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "matrix-react-sdk",
3-
"version": "3.41.1",
3+
"version": "3.42.0",
44
"description": "SDK for matrix.org using React",
55
"author": "matrix.org",
66
"repository": {

src/CallHandler.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ export default class CallHandler extends EventEmitter {
11231123

11241124
const jitsiWidgets = roomInfo.widgets.filter(w => WidgetType.JITSI.matches(w.type));
11251125
jitsiWidgets.forEach(w => {
1126-
const messaging = WidgetMessagingStore.instance.getMessagingForId(w.id);
1126+
const messaging = WidgetMessagingStore.instance.getMessagingForUid(WidgetUtils.getWidgetUid(w));
11271127
if (!messaging) return; // more "should never happen" words
11281128

11291129
messaging.transport.send(ElementWidgetActions.HangupCall, {});

src/components/structures/ThreadPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
309309
manageReadMarkers={false} // No RM support in thread's MVP
310310
sendReadReceiptOnLoad={false} // No RR support in thread's MVP
311311
timelineSet={timelineSet}
312-
showUrlPreview={true}
312+
showUrlPreview={false} // No URL previews at the threads list level
313313
empty={<EmptyThread
314314
filterOption={filterOption}
315315
showAllThreadsCallback={() => setFilterOption(ThreadFilterType.All)}

src/components/structures/ThreadView.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
289289
return {
290290
"rel_type": THREAD_RELATION_TYPE.name,
291291
"event_id": this.state.thread?.id,
292+
"is_falling_back": true,
292293
"m.in_reply_to": {
293294
"event_id": this.state.lastThreadReply?.getId() ?? this.state.thread?.id,
294295
},
@@ -350,7 +351,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
350351
manageReadMarkers={true}
351352
sendReadReceiptOnLoad={true}
352353
timelineSet={this.state?.thread?.timelineSet}
353-
showUrlPreview={true}
354+
showUrlPreview={this.context.showUrlPreview}
354355
// ThreadView doesn't support IRC layout at this time
355356
layout={this.state.layout === Layout.Bubble ? Layout.Bubble : Layout.Group}
356357
hideThreadedMessages={false}

src/components/views/context_menus/WidgetContextMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const WidgetContextMenu: React.FC<IProps> = ({
5757
const cli = useContext(MatrixClientContext);
5858
const { room, roomId } = useContext(RoomContext);
5959

60-
const widgetMessaging = WidgetMessagingStore.instance.getMessagingForId(app.id);
60+
const widgetMessaging = WidgetMessagingStore.instance.getMessagingForUid(WidgetUtils.getWidgetUid(app));
6161
const canModify = userWidget || WidgetUtils.canUserModifyWidgets(roomId);
6262

6363
let streamAudioStreamButton;

src/components/views/elements/AppTile.tsx

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -118,24 +118,27 @@ export default class AppTile extends React.Component<IProps, IState> {
118118
showLayoutButtons: true,
119119
};
120120

121-
// We track a count of all "live" `AppTile`s for a given widget ID.
121+
// We track a count of all "live" `AppTile`s for a given widget UID.
122122
// For this purpose, an `AppTile` is considered live from the time it is
123123
// constructed until it is unmounted. This is used to aid logic around when
124124
// to tear down the widget iframe. See `componentWillUnmount` for details.
125-
private static liveTilesById: { [key: string]: number } = {};
125+
private static liveTilesByUid = new Map<string, number>();
126126

127-
public static addLiveTile(widgetId: string): void {
128-
const refs = this.liveTilesById[widgetId] || 0;
129-
this.liveTilesById[widgetId] = refs + 1;
127+
public static addLiveTile(widgetId: string, roomId: string): void {
128+
const uid = WidgetUtils.calcWidgetUid(widgetId, roomId);
129+
const refs = this.liveTilesByUid.get(uid) ?? 0;
130+
this.liveTilesByUid.set(uid, refs + 1);
130131
}
131132

132-
public static removeLiveTile(widgetId: string): void {
133-
const refs = this.liveTilesById[widgetId] || 0;
134-
this.liveTilesById[widgetId] = refs - 1;
133+
public static removeLiveTile(widgetId: string, roomId: string): void {
134+
const uid = WidgetUtils.calcWidgetUid(widgetId, roomId);
135+
const refs = this.liveTilesByUid.get(uid);
136+
if (refs) this.liveTilesByUid.set(uid, refs - 1);
135137
}
136138

137-
public static isLive(widgetId: string): boolean {
138-
const refs = this.liveTilesById[widgetId] || 0;
139+
public static isLive(widgetId: string, roomId: string): boolean {
140+
const uid = WidgetUtils.calcWidgetUid(widgetId, roomId);
141+
const refs = this.liveTilesByUid.get(uid) ?? 0;
139142
return refs > 0;
140143
}
141144

@@ -150,10 +153,10 @@ export default class AppTile extends React.Component<IProps, IState> {
150153
constructor(props: IProps) {
151154
super(props);
152155

153-
AppTile.addLiveTile(this.props.app.id);
156+
AppTile.addLiveTile(this.props.app.id, this.props.app.roomId);
154157

155158
// The key used for PersistedElement
156-
this.persistKey = getPersistKey(this.props.app.id);
159+
this.persistKey = getPersistKey(WidgetUtils.getWidgetUid(this.props.app));
157160
try {
158161
this.sgWidget = new StopGapWidget(this.props);
159162
this.setupSgListeners();
@@ -189,7 +192,9 @@ export default class AppTile extends React.Component<IProps, IState> {
189192
};
190193

191194
private onUserLeftRoom() {
192-
const isActiveWidget = ActiveWidgetStore.instance.getWidgetPersistence(this.props.app.id);
195+
const isActiveWidget = ActiveWidgetStore.instance.getWidgetPersistence(
196+
this.props.app.id, this.props.app.roomId,
197+
);
193198
if (isActiveWidget) {
194199
// We just left the room that the active widget was from.
195200
if (this.props.room && RoomViewStore.getRoomId() !== this.props.room.roomId) {
@@ -200,7 +205,7 @@ export default class AppTile extends React.Component<IProps, IState> {
200205
this.reload();
201206
} else {
202207
// Otherwise just cancel its persistence.
203-
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id);
208+
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id, this.props.app.roomId);
204209
}
205210
}
206211
}
@@ -241,7 +246,7 @@ export default class AppTile extends React.Component<IProps, IState> {
241246

242247
if (this.state.hasPermissionToLoad && !hasPermissionToLoad) {
243248
// Force the widget to be non-persistent (able to be deleted/forgotten)
244-
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id);
249+
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id, this.props.app.roomId);
245250
PersistedElement.destroyElement(this.persistKey);
246251
this.sgWidget?.stopMessaging();
247252
}
@@ -291,14 +296,16 @@ export default class AppTile extends React.Component<IProps, IState> {
291296
// container is constructed before the old one unmounts. By counting the
292297
// mounted `AppTile`s for each widget, we know to only tear down the
293298
// widget iframe when the last the `AppTile` unmounts.
294-
AppTile.removeLiveTile(this.props.app.id);
299+
AppTile.removeLiveTile(this.props.app.id, this.props.app.roomId);
295300

296301
// We also support a separate "persistence" mode where a single widget
297302
// can request to be "sticky" and follow you across rooms in a PIP
298303
// container.
299-
const isActiveWidget = ActiveWidgetStore.instance.getWidgetPersistence(this.props.app.id);
304+
const isActiveWidget = ActiveWidgetStore.instance.getWidgetPersistence(
305+
this.props.app.id, this.props.app.roomId,
306+
);
300307

301-
if (!AppTile.isLive(this.props.app.id) && !isActiveWidget) {
308+
if (!AppTile.isLive(this.props.app.id, this.props.app.roomId) && !isActiveWidget) {
302309
this.endWidgetActions();
303310
}
304311

@@ -408,7 +415,7 @@ export default class AppTile extends React.Component<IProps, IState> {
408415

409416
// Delete the widget from the persisted store for good measure.
410417
PersistedElement.destroyElement(this.persistKey);
411-
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id);
418+
ActiveWidgetStore.instance.destroyPersistentWidget(this.props.app.id, this.props.app.roomId);
412419

413420
this.sgWidget?.stopMessaging({ forceDestroy: true });
414421
}

src/components/views/elements/PersistentApp.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ limitations under the License.
1616
*/
1717

1818
import React, { ContextType } from 'react';
19+
import { Room } from "matrix-js-sdk/src/models/room";
1920

20-
import ActiveWidgetStore from '../../../stores/ActiveWidgetStore';
2121
import WidgetUtils from '../../../utils/WidgetUtils';
2222
import { replaceableComponent } from "../../../utils/replaceableComponent";
2323
import AppTile from "./AppTile";
@@ -26,39 +26,40 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
2626

2727
interface IProps {
2828
persistentWidgetId: string;
29+
persistentRoomId: string;
2930
pointerEvents?: string;
3031
}
3132

3233
@replaceableComponent("views.elements.PersistentApp")
3334
export default class PersistentApp extends React.Component<IProps> {
3435
public static contextType = MatrixClientContext;
3536
context: ContextType<typeof MatrixClientContext>;
37+
private room: Room;
3638

37-
private get app(): IApp {
38-
const persistentWidgetInRoomId = ActiveWidgetStore.instance.getRoomId(this.props.persistentWidgetId);
39-
const persistentWidgetInRoom = this.context.getRoom(persistentWidgetInRoomId);
39+
constructor(props: IProps, context: ContextType<typeof MatrixClientContext>) {
40+
super(props, context);
41+
this.room = context.getRoom(this.props.persistentRoomId);
42+
}
4043

44+
private get app(): IApp {
4145
// get the widget data
42-
const appEvent = WidgetUtils.getRoomWidgets(persistentWidgetInRoom).find((ev) => {
43-
return ev.getStateKey() === ActiveWidgetStore.instance.getPersistentWidgetId();
44-
});
46+
const appEvent = WidgetUtils.getRoomWidgets(this.room).find(ev =>
47+
ev.getStateKey() === this.props.persistentWidgetId,
48+
);
4549
return WidgetUtils.makeAppConfig(
4650
appEvent.getStateKey(), appEvent.getContent(), appEvent.getSender(),
47-
persistentWidgetInRoomId, appEvent.getId(),
51+
this.room.roomId, appEvent.getId(),
4852
);
4953
}
5054

5155
public render(): JSX.Element {
5256
const app = this.app;
5357
if (app) {
54-
const persistentWidgetInRoomId = ActiveWidgetStore.instance.getRoomId(this.props.persistentWidgetId);
55-
const persistentWidgetInRoom = this.context.getRoom(persistentWidgetInRoomId);
56-
5758
return <AppTile
5859
key={app.id}
5960
app={app}
6061
fullWidth={true}
61-
room={persistentWidgetInRoom}
62+
room={this.room}
6263
userId={this.context.credentials.userId}
6364
creatorUserId={app.creatorUserId}
6465
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}

src/components/views/elements/ReplyChain.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import ReplyTile from "../rooms/ReplyTile";
3535
import Pill from './Pill';
3636
import { ButtonEvent } from './AccessibleButton';
3737
import { getParentEventId, shouldDisplayReply } from '../../../utils/Reply';
38-
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
38+
import RoomContext from "../../../contexts/RoomContext";
3939
import { MatrixClientPeg } from '../../../MatrixClientPeg';
4040

4141
/**
@@ -205,16 +205,14 @@ export default class ReplyChain extends React.Component<IProps, IState> {
205205

206206
render() {
207207
let header = null;
208-
209-
const inThread = this.context.timelineRenderingType === TimelineRenderingType.Thread;
210208
if (this.state.err) {
211209
header = <blockquote className="mx_ReplyChain mx_ReplyChain_error">
212210
{
213211
_t('Unable to load event that was replied to, ' +
214212
'it either does not exist or you do not have permission to view it.')
215213
}
216214
</blockquote>;
217-
} else if (this.state.loadedEv && shouldDisplayReply(this.state.events[0], inThread)) {
215+
} else if (this.state.loadedEv && shouldDisplayReply(this.state.events[0])) {
218216
const ev = this.state.loadedEv;
219217
const room = this.matrixClient.getRoom(ev.getRoomId());
220218
header = <blockquote className={`mx_ReplyChain ${this.getReplyChainColorClass(ev)}`}>

src/components/views/right_panel/TimelineCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ export default class TimelineCard extends React.Component<IProps, IState> {
248248
manageReadMarkers={false} // No RM support in the TimelineCard
249249
sendReadReceiptOnLoad={true}
250250
timelineSet={this.props.timelineSet}
251-
showUrlPreview={true}
251+
showUrlPreview={this.context.showUrlPreview}
252252
// The right panel timeline (and therefore threads) don't support IRC layout at this time
253253
layout={this.state.layout === Layout.Bubble ? Layout.Bubble : Layout.Group}
254254
hideThreadedMessages={false}

0 commit comments

Comments
 (0)