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

Commit 6a46c7a

Browse files
authored
Merge branch 'develop' into matthew/fix-quicktime
2 parents 9a76bb0 + a80e55d commit 6a46c7a

25 files changed

+2544
-2772
lines changed

res/css/structures/_LeftPanel.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ $roomListCollapsedWidth: 68px;
3737
display: flex;
3838
flex-direction: row;
3939
flex: 1;
40+
height: 100%; // ensure space panel is still scrollable with an outer wrapper
4041

4142
.mx_LeftPanel_wrapper--user {
4243
background-color: $roomlist-bg-color;

src/components/structures/MatrixChat.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,24 +1465,24 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
14651465
setTimeout(() => {
14661466
if (SettingsStore.getValue("feature_thread") && SdkConfig.get("show_labs_settings")) {
14671467
Modal.createDialog(InfoDialog, {
1468-
title: _t("Threads are no longer experimental! 🎉"),
1468+
title: _t("Threads Approaching Beta 🎉"),
14691469
description: <>
14701470
<p>
1471-
{ _t("We’ve recently introduced key stability "
1472-
+ "improvements for Threads, which also means "
1473-
+ "phasing out support for experimental Threads.") }
1471+
{ _t("We're getting closer to releasing a public Beta for Threads.") }
14741472
</p>
14751473
<p>
1476-
{ _t("All thread events created during the "
1477-
+ "experimental period will now be rendered in "
1478-
+ "the room timeline and displayed as replies. "
1479-
+ "This is a one-off transition. Threads are now "
1480-
+ "part of the Matrix specification.") }
1474+
{ _t("As we prepare for it, we need to make some changes: threads created "
1475+
+ "before this point will be <strong>displayed as regular replies</strong>.",
1476+
{}, {
1477+
"strong": sub => <strong>{ sub }</strong>,
1478+
}) }
14811479
</p>
14821480
<p>
1483-
{ _t("Thank you for helping us testing Threads!") }
1481+
{ _t("This will be a one-off transition, as threads are now part "
1482+
+ "of the Matrix specification.") }
14841483
</p>
14851484
</>,
1485+
button: _t("Got it"),
14861486
onFinished: () => {
14871487
localStorage.setItem("mx_seen_feature_thread_experimental", "true");
14881488
},

src/i18n/strings/en_EN.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3098,10 +3098,10 @@
30983098
"Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s",
30993099
"Unable to copy room link": "Unable to copy room link",
31003100
"Unable to copy a link to the room to the clipboard.": "Unable to copy a link to the room to the clipboard.",
3101-
"Threads are no longer experimental! 🎉": "Threads are no longer experimental! 🎉",
3102-
"We’ve recently introduced key stability improvements for Threads, which also means phasing out support for experimental Threads.": "We’ve recently introduced key stability improvements for Threads, which also means phasing out support for experimental Threads.",
3103-
"All thread events created during the experimental period will now be rendered in the room timeline and displayed as replies. This is a one-off transition. Threads are now part of the Matrix specification.": "All thread events created during the experimental period will now be rendered in the room timeline and displayed as replies. This is a one-off transition. Threads are now part of the Matrix specification.",
3104-
"Thank you for helping us testing Threads!": "Thank you for helping us testing Threads!",
3101+
"Threads Approaching Beta 🎉": "Threads Approaching Beta 🎉",
3102+
"We're getting closer to releasing a public Beta for Threads.": "We're getting closer to releasing a public Beta for Threads.",
3103+
"As we prepare for it, we need to make some changes: threads created before this point will be <strong>displayed as regular replies</strong>.": "As we prepare for it, we need to make some changes: threads created before this point will be <strong>displayed as regular replies</strong>.",
3104+
"This will be a one-off transition, as threads are now part of the Matrix specification.": "This will be a one-off transition, as threads are now part of the Matrix specification.",
31053105
"New search beta available": "New search beta available",
31063106
"We're testing a new search to make finding what you want quicker.\n": "We're testing a new search to make finding what you want quicker.\n",
31073107
"Signed Out": "Signed Out",

src/utils/Reply.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
2222
import { PERMITTED_URL_SCHEMES } from "../HtmlUtils";
2323
import { makeUserPermalink, RoomPermalinkCreator } from "./permalinks/Permalinks";
2424
import { RecursivePartial } from "../@types/common";
25+
import SettingsStore from "../settings/SettingsStore";
2526

2627
export function getParentEventId(ev: MatrixEvent): string | undefined {
2728
if (!ev || ev.isRedacted()) return;
@@ -178,7 +179,10 @@ export function shouldDisplayReply(event: MatrixEvent): boolean {
178179
}
179180

180181
const relation = event.getRelation();
181-
if (relation?.rel_type === THREAD_RELATION_TYPE.name && relation?.is_falling_back) {
182+
if (SettingsStore.getValue("feature_thread") &&
183+
relation?.rel_type === THREAD_RELATION_TYPE.name &&
184+
relation?.is_falling_back
185+
) {
182186
return false;
183187
}
184188

src/utils/beacon/duration.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import { Beacon } from "matrix-js-sdk/src/matrix";
18+
19+
/**
20+
* Get ms until expiry
21+
* Returns 0 when expiry is already passed
22+
* @param startTimestamp
23+
* @param durationMs
24+
* @returns remainingMs
25+
*/
26+
export const msUntilExpiry = (startTimestamp: number, durationMs: number): number =>
27+
Math.max(0, (startTimestamp + durationMs) - Date.now());
28+
29+
export const getBeaconMsUntilExpiry = (beacon: Beacon): number =>
30+
msUntilExpiry(beacon.beaconInfo.timestamp, beacon.beaconInfo.timeout);
31+
32+
export const getBeaconExpiryTimestamp = (beacon: Beacon): number =>
33+
beacon.beaconInfo.timestamp + beacon.beaconInfo.timeout;
34+
35+
export const sortBeaconsByLatestExpiry = (left: Beacon, right: Beacon): number =>
36+
getBeaconExpiryTimestamp(right) - getBeaconExpiryTimestamp(left);

src/utils/beacon/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
export * from './duration';

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ describe("AppTile", () => {
114114
await RightPanelStore.instance.onReady();
115115
});
116116

117+
beforeEach(() => {
118+
jest.spyOn(SettingsStore, "getValue").mockRestore();
119+
});
120+
117121
it("tracks live tiles correctly", () => {
118122
expect(AppTile.isLive("1", "r1")).toEqual(false);
119123

@@ -196,7 +200,7 @@ describe("AppTile", () => {
196200
it("distinguishes widgets with the same ID in different rooms", async () => {
197201
// Set up right panel state
198202
const realGetValue = SettingsStore.getValue;
199-
SettingsStore.getValue = (name, roomId) => {
203+
jest.spyOn(SettingsStore, 'getValue').mockImplementation((name, roomId) => {
200204
if (name === "RightPanel.phases") {
201205
if (roomId === "r1") {
202206
return {
@@ -212,7 +216,7 @@ describe("AppTile", () => {
212216
return null;
213217
}
214218
return realGetValue(name, roomId);
215-
};
219+
});
216220

217221
// Run initial render with room 1, and also running lifecycle methods
218222
const renderer = TestRenderer.create(<MatrixClientContext.Provider value={cli}>
@@ -232,7 +236,7 @@ describe("AppTile", () => {
232236
expect(AppTile.isLive("1", "r1")).toBe(true);
233237
expect(AppTile.isLive("1", "r2")).toBe(false);
234238

235-
SettingsStore.getValue = (name, roomId) => {
239+
jest.spyOn(SettingsStore, "getValue").mockImplementation((name, roomId) => {
236240
if (name === "RightPanel.phases") {
237241
if (roomId === "r2") {
238242
return {
@@ -248,7 +252,7 @@ describe("AppTile", () => {
248252
return null;
249253
}
250254
return realGetValue(name, roomId);
251-
};
255+
});
252256
// Wait for RPS room 2 updates to fire
253257
const rpsUpdated2 = waitForRps("r2");
254258
// Switch to room 2
@@ -266,8 +270,6 @@ describe("AppTile", () => {
266270

267271
expect(AppTile.isLive("1", "r1")).toBe(false);
268272
expect(AppTile.isLive("1", "r2")).toBe(true);
269-
270-
SettingsStore.getValue = realGetValue;
271273
});
272274

273275
it("preserves non-persisted widget on container move", async () => {

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

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,15 @@ import {
2626
M_TEXT,
2727
PollStartEvent,
2828
} from 'matrix-events-sdk';
29-
import { IContent, MatrixEvent } from 'matrix-js-sdk/src/models/event';
29+
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
3030

3131
import {
32-
wrapInMatrixClientContext,
3332
findById,
34-
stubClient,
33+
getMockClientWithEventEmitter,
3534
} from '../../../test-utils';
3635
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
37-
import _PollCreateDialog from "../../../../src/components/views/elements/PollCreateDialog";
38-
const PollCreateDialog = wrapInMatrixClientContext(_PollCreateDialog);
36+
import PollCreateDialog from "../../../../src/components/views/elements/PollCreateDialog";
37+
import MatrixClientContext from '../../../../src/contexts/MatrixClientContext';
3938

4039
// Fake date to give a predictable snapshot
4140
const realDateNow = Date.now;
@@ -51,9 +50,21 @@ afterAll(() => {
5150
});
5251

5352
describe("PollCreateDialog", () => {
53+
const mockClient = getMockClientWithEventEmitter({
54+
sendEvent: jest.fn().mockResolvedValue({ event_id: '1' }),
55+
});
56+
57+
beforeEach(() => {
58+
mockClient.sendEvent.mockClear();
59+
});
60+
5461
it("renders a blank poll", () => {
5562
const dialog = mount(
5663
<PollCreateDialog room={createRoom()} onFinished={jest.fn()} />,
64+
{
65+
wrappingComponent: MatrixClientContext.Provider,
66+
wrappingComponentProps: { value: mockClient },
67+
},
5768
);
5869
expect(dialog.html()).toMatchSnapshot();
5970
});
@@ -207,9 +218,6 @@ describe("PollCreateDialog", () => {
207218
});
208219

209220
it("displays a spinner after submitting", () => {
210-
stubClient();
211-
MatrixClientPeg.get().sendEvent = jest.fn(() => Promise.resolve());
212-
213221
const dialog = mount(
214222
<PollCreateDialog room={createRoom()} onFinished={jest.fn()} />,
215223
);
@@ -223,21 +231,6 @@ describe("PollCreateDialog", () => {
223231
});
224232

225233
it("sends a poll create event when submitted", () => {
226-
stubClient();
227-
let sentEventContent: IContent = null;
228-
MatrixClientPeg.get().sendEvent = jest.fn(
229-
(
230-
_roomId: string,
231-
_threadId: string,
232-
eventType: string,
233-
content: IContent,
234-
) => {
235-
expect(M_POLL_START.matches(eventType)).toBeTruthy();
236-
sentEventContent = content;
237-
return Promise.resolve();
238-
},
239-
);
240-
241234
const dialog = mount(
242235
<PollCreateDialog room={createRoom()} onFinished={jest.fn()} />,
243236
);
@@ -246,6 +239,8 @@ describe("PollCreateDialog", () => {
246239
changeValue(dialog, "Option 2", "A2");
247240

248241
dialog.find("button").simulate("click");
242+
const [, , eventType, sentEventContent] = mockClient.sendEvent.mock.calls[0];
243+
expect(M_POLL_START.matches(eventType)).toBeTruthy();
249244
expect(sentEventContent).toEqual(
250245
{
251246
[M_TEXT.name]: "Q\n1. A1\n2. A2",
@@ -275,21 +270,6 @@ describe("PollCreateDialog", () => {
275270
});
276271

277272
it("sends a poll edit event when editing", () => {
278-
stubClient();
279-
let sentEventContent: IContent = null;
280-
MatrixClientPeg.get().sendEvent = jest.fn(
281-
(
282-
_roomId: string,
283-
_threadId: string,
284-
eventType: string,
285-
content: IContent,
286-
) => {
287-
expect(M_POLL_START.matches(eventType)).toBeTruthy();
288-
sentEventContent = content;
289-
return Promise.resolve();
290-
},
291-
);
292-
293273
const previousEvent: MatrixEvent = new MatrixEvent(
294274
PollStartEvent.from(
295275
"Poll Q",
@@ -312,6 +292,8 @@ describe("PollCreateDialog", () => {
312292
changeKind(dialog, M_POLL_KIND_UNDISCLOSED.name);
313293
dialog.find("button").simulate("click");
314294

295+
const [, , eventType, sentEventContent] = mockClient.sendEvent.mock.calls[0];
296+
expect(M_POLL_START.matches(eventType)).toBeTruthy();
315297
expect(sentEventContent).toEqual(
316298
{
317299
"m.new_content": {

test/components/views/messages/DateSeparator-test.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@ limitations under the License.
1616

1717
import React from "react";
1818
import { mount } from "enzyme";
19+
import { mocked } from "jest-mock";
1920

2021
import sdk from "../../../skinned-sdk";
21-
import * as TestUtils from "../../../test-utils";
2222
import { formatFullDateNoTime } from "../../../../src/DateUtils";
2323
import SettingsStore from "../../../../src/settings/SettingsStore";
2424
import { UIFeature } from "../../../../src/settings/UIFeature";
25+
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
26+
import { getMockClientWithEventEmitter } from "../../../test-utils";
2527

2628
jest.mock("../../../../src/settings/SettingsStore");
2729

28-
const _DateSeparator = sdk.getComponent("views.messages.DateSeparator");
29-
const DateSeparator = TestUtils.wrapInMatrixClientContext(_DateSeparator);
30+
const DateSeparator = sdk.getComponent("views.messages.DateSeparator");
3031

3132
describe("DateSeparator", () => {
3233
const HOUR_MS = 3600000;
@@ -45,8 +46,12 @@ describe("DateSeparator", () => {
4546
}
4647
}
4748

49+
const mockClient = getMockClientWithEventEmitter({});
4850
const getComponent = (props = {}) =>
49-
mount(<DateSeparator {...defaultProps} {...props} />);
51+
mount(<DateSeparator {...defaultProps} {...props} />, {
52+
wrappingComponent: MatrixClientContext.Provider,
53+
wrappingComponentProps: { value: mockClient },
54+
});
5055

5156
type TestCase = [string, number, string];
5257
const testCases: TestCase[] = [
@@ -106,7 +111,7 @@ describe("DateSeparator", () => {
106111

107112
describe('when feature_jump_to_date is enabled', () => {
108113
beforeEach(() => {
109-
(SettingsStore.getValue as jest.Mock) = jest.fn((arg) => {
114+
mocked(SettingsStore).getValue.mockImplementation((arg) => {
110115
if (arg === "feature_jump_to_date") {
111116
return true;
112117
}

test/components/views/messages/MLocationBody-test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ describe("MLocationBody", () => {
222222

223223
describe("isSelfLocation", () => {
224224
it("Returns true for a full m.asset event", () => {
225-
const content = makeLocationContent("", 0);
225+
const content = makeLocationContent("", '0');
226226
expect(isSelfLocation(content)).toBe(true);
227227
});
228228

0 commit comments

Comments
 (0)