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

Commit 1369660

Browse files
authored
Merge branch 'develop' into weeman1337/pillify-permalinks
2 parents 7d81563 + 1e651bf commit 1369660

34 files changed

+506
-199
lines changed

CHANGELOG.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1+
Changes in [3.68.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.68.0) (2023-03-15)
2+
=====================================================================================================
3+
4+
## ✨ Features
5+
* Only allow to start a DM with one email if encryption by default is enabled ([\#10253](https://github.com/matrix-org/matrix-react-sdk/pull/10253)). Fixes vector-im/element-web#23133.
6+
* DM rooms are now encrypted if encryption by default is enabled and only inviting a single email address. Any action in the result DM room will be blocked until the other has joined. ([\#10229](https://github.com/matrix-org/matrix-react-sdk/pull/10229)).
7+
* Reduce bottom margin of ReplyChain on compact modern layout ([\#8972](https://github.com/matrix-org/matrix-react-sdk/pull/8972)). Fixes vector-im/element-web#22748. Contributed by @luixxiul.
8+
* Support for v2 of MSC3903 ([\#10165](https://github.com/matrix-org/matrix-react-sdk/pull/10165)). Contributed by @hughns.
9+
* When starting a DM, existing rooms with pending third-party invites will be reused. ([\#10256](https://github.com/matrix-org/matrix-react-sdk/pull/10256)). Fixes vector-im/element-web#23139.
10+
* Polls push rules: synchronise poll rules with message rules ([\#10263](https://github.com/matrix-org/matrix-react-sdk/pull/10263)). Contributed by @kerryarchibald.
11+
* New verification request toast button labels ([\#10259](https://github.com/matrix-org/matrix-react-sdk/pull/10259)).
12+
* Remove padding around integration manager iframe ([\#10148](https://github.com/matrix-org/matrix-react-sdk/pull/10148)).
13+
* Fix block code styling in rich text editor ([\#10246](https://github.com/matrix-org/matrix-react-sdk/pull/10246)). Contributed by @alunturner.
14+
* Poll history: fetch more poll history ([\#10235](https://github.com/matrix-org/matrix-react-sdk/pull/10235)). Contributed by @kerryarchibald.
15+
* Sort short/exact emoji matches before longer incomplete matches ([\#10212](https://github.com/matrix-org/matrix-react-sdk/pull/10212)). Fixes vector-im/element-web#23210. Contributed by @grimhilt.
16+
* Poll history: detail screen ([\#10172](https://github.com/matrix-org/matrix-react-sdk/pull/10172)). Contributed by @kerryarchibald.
17+
* Provide a more detailed error message than "No known servers" ([\#6048](https://github.com/matrix-org/matrix-react-sdk/pull/6048)). Fixes vector-im/element-web#13247. Contributed by @aaronraimist.
18+
* Say when a call was answered from a different device ([\#10224](https://github.com/matrix-org/matrix-react-sdk/pull/10224)).
19+
* Widget permissions customizations using module api ([\#10121](https://github.com/matrix-org/matrix-react-sdk/pull/10121)). Contributed by @maheichyk.
20+
* Fix copy button icon overlapping with copyable text ([\#10227](https://github.com/matrix-org/matrix-react-sdk/pull/10227)). Contributed by @Adesh-Pandey.
21+
* Support joining non-peekable rooms via the module API ([\#10154](https://github.com/matrix-org/matrix-react-sdk/pull/10154)). Contributed by @maheichyk.
22+
* The "new login" toast does now display the same device information as in the settings. "No" does now open the device settings. "Yes, it was me" dismisses the toast. ([\#10200](https://github.com/matrix-org/matrix-react-sdk/pull/10200)).
23+
* Do not prompt for a password when doing a „reset all“ after login ([\#10208](https://github.com/matrix-org/matrix-react-sdk/pull/10208)).
24+
25+
## 🐛 Bug Fixes
26+
* Fix incorrect copy in space creation flow ([\#10296](https://github.com/matrix-org/matrix-react-sdk/pull/10296)). Fixes vector-im/element-web#24741.
27+
* Fix space settings dialog having rogue title tooltip ([\#10293](https://github.com/matrix-org/matrix-react-sdk/pull/10293)). Fixes vector-im/element-web#24740.
28+
* Show spinner when starting a DM from the user profile (right panel) ([\#10290](https://github.com/matrix-org/matrix-react-sdk/pull/10290)).
29+
* Reduce height of toggle on expanded view source event ([\#10283](https://github.com/matrix-org/matrix-react-sdk/pull/10283)). Fixes vector-im/element-web#22873. Contributed by @luixxiul.
30+
* Pillify http and non-prefixed matrix.to links ([\#10277](https://github.com/matrix-org/matrix-react-sdk/pull/10277)). Fixes vector-im/element-web#20844.
31+
* Fix some features not being configurable via `features` ([\#10276](https://github.com/matrix-org/matrix-react-sdk/pull/10276)).
32+
* Fix starting a DM from the right panel in some cases ([\#10278](https://github.com/matrix-org/matrix-react-sdk/pull/10278)). Fixes vector-im/element-web#24722.
33+
* Align info EventTile and normal EventTile on IRC layout ([\#10197](https://github.com/matrix-org/matrix-react-sdk/pull/10197)). Fixes vector-im/element-web#22782. Contributed by @luixxiul.
34+
* Fix blowout of waveform of the voice message player on narrow UI ([\#8861](https://github.com/matrix-org/matrix-react-sdk/pull/8861)). Fixes vector-im/element-web#22604. Contributed by @luixxiul.
35+
* Fix the hidden view source toggle on IRC layout ([\#10266](https://github.com/matrix-org/matrix-react-sdk/pull/10266)). Fixes vector-im/element-web#22872. Contributed by @luixxiul.
36+
* Fix buttons on the room header being compressed due to long room name ([\#10155](https://github.com/matrix-org/matrix-react-sdk/pull/10155)). Contributed by @luixxiul.
37+
* Use the room avatar as a placeholder in calls ([\#10231](https://github.com/matrix-org/matrix-react-sdk/pull/10231)).
38+
* Fix calls showing as 'connecting' after hangup ([\#10223](https://github.com/matrix-org/matrix-react-sdk/pull/10223)).
39+
* Prevent multiple Jitsi calls started at the same time ([\#10183](https://github.com/matrix-org/matrix-react-sdk/pull/10183)). Fixes vector-im/element-web#23009.
40+
* Make localization keys compatible with agglutinative and/or SOV type languages ([\#10159](https://github.com/matrix-org/matrix-react-sdk/pull/10159)). Contributed by @luixxiul.
41+
142
Changes in [3.67.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.67.0) (2023-02-28)
243
=====================================================================================================
344

docs/jitsi.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ _Hash/fragment (formatted as a query string)_:
1919
- `conferenceId`: The room or conference ID to connect Jitsi Meet to.
2020
- `isAudioOnly`: Boolean for whether this is a voice-only conference. May not
2121
be present, should default to `false`.
22+
- `startWithAudioMuted`: Boolean for whether the calls start with audio
23+
muted. May not be present.
24+
- `startWithVideoMuted`: Boolean for whether the calls start with video
25+
muted. May not be present.
2226
- `displayName`: The display name of the user viewing the widget. May not
2327
be present or could be null.
2428
- `avatarUrl`: The HTTP(S) URL for the avatar of the user viewing the widget. May

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.67.0",
3+
"version": "3.68.0",
44
"description": "SDK for matrix.org using React",
55
"author": "matrix.org",
66
"repository": {

src/BasePlatform.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,4 +442,12 @@ export default abstract class BasePlatform {
442442
logger.error("idbDelete failed in destroyPickleKey", e);
443443
}
444444
}
445+
446+
/**
447+
* Clear app storage, called when logging out to perform data clean up.
448+
*/
449+
public async clearStorage(): Promise<void> {
450+
window.sessionStorage.clear();
451+
window.localStorage.clear();
452+
}
445453
}

src/Lifecycle.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ export async function onLoggedOut(): Promise<void> {
862862
stopMatrixClient();
863863
await clearStorage({ deleteEverything: true });
864864
LifecycleCustomisations.onLoggedOutAndStorageCleared?.();
865+
await PlatformPeg.get()?.clearStorage();
865866

866867
// Do this last, so we can make sure all storage has been cleared and all
867868
// customisations got the memo.

src/async-components/views/dialogs/security/ImportE2eKeysDialog.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ export default class ImportE2eKeysDialog extends React.Component<IProps, IState>
8484
};
8585

8686
private onPassphraseChange = (ev: React.ChangeEvent<HTMLInputElement>): void => {
87-
this.setState({ passphrase: ev.target.value });
88-
this.onFormChange(); // update general form state too
87+
this.setState({ passphrase: ev.target.value }, this.onFormChange); // update general form state too
8988
};
9089

9190
private onFormSubmit = (ev: React.FormEvent): boolean => {

src/components/views/context_menus/MessageContextMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
284284
this.closeMenu();
285285
};
286286

287-
private onShareClick = (e: React.MouseEvent): void => {
287+
private onShareClick = (e: ButtonEvent): void => {
288288
e.preventDefault();
289289
Modal.createDialog(ShareDialog, {
290290
target: this.props.mxEvent,

src/components/views/elements/EditableItemList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import Field from "./Field";
2121
import AccessibleButton, { ButtonEvent } from "./AccessibleButton";
2222

2323
interface IItemProps {
24-
index?: number;
24+
index: number;
2525
value?: string;
2626
onRemove?(index: number): void;
2727
}
@@ -99,7 +99,7 @@ interface IProps {
9999
canEdit?: boolean;
100100
canRemove?: boolean;
101101
suggestionsListId?: string;
102-
onItemAdded?(item: string): void;
102+
onItemAdded?(item?: string): void;
103103
onItemRemoved?(index: number): void;
104104
onNewItemChanged?(item: string): void;
105105
}

src/components/views/elements/SettingsFlag.tsx

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { _t } from "../../../languageHandler";
2222
import ToggleSwitch from "./ToggleSwitch";
2323
import StyledCheckbox from "./StyledCheckbox";
2424
import { SettingLevel } from "../../../settings/SettingLevel";
25+
import { defaultWatchManager } from "../../../settings/Settings";
2526

2627
interface IProps {
2728
// The setting must be a boolean
@@ -32,34 +33,58 @@ interface IProps {
3233
isExplicit?: boolean;
3334
// XXX: once design replaces all toggles make this the default
3435
useCheckbox?: boolean;
35-
disabled?: boolean;
36-
disabledDescription?: string;
3736
hideIfCannotSet?: boolean;
3837
onChange?(checked: boolean): void;
3938
}
4039

4140
interface IState {
4241
value: boolean;
42+
/** true if `SettingsStore.isEnabled` returned false. */
43+
disabled: boolean;
4344
}
4445

4546
export default class SettingsFlag extends React.Component<IProps, IState> {
4647
public constructor(props: IProps) {
4748
super(props);
4849

4950
this.state = {
50-
value: SettingsStore.getValueAt(
51-
this.props.level,
52-
this.props.name,
53-
this.props.roomId,
54-
this.props.isExplicit,
55-
),
51+
value: this.getSettingValue(),
52+
disabled: this.isSettingDisabled(),
5653
};
5754
}
5855

56+
public componentDidMount(): void {
57+
defaultWatchManager.watchSetting(this.props.name, this.props.roomId ?? null, this.onSettingChange);
58+
}
59+
60+
public componentWillUnmount(): void {
61+
defaultWatchManager.unwatchSetting(this.onSettingChange);
62+
}
63+
64+
private getSettingValue(): boolean {
65+
return SettingsStore.getValueAt(
66+
this.props.level,
67+
this.props.name,
68+
this.props.roomId ?? null,
69+
this.props.isExplicit,
70+
);
71+
}
72+
73+
private isSettingDisabled(): boolean {
74+
return !SettingsStore.isEnabled(this.props.name);
75+
}
76+
77+
private onSettingChange = (): void => {
78+
this.setState({
79+
value: this.getSettingValue(),
80+
disabled: this.isSettingDisabled(),
81+
});
82+
};
83+
5984
private onChange = async (checked: boolean): Promise<void> => {
6085
await this.save(checked);
6186
this.setState({ value: checked });
62-
if (this.props.onChange) this.props.onChange(checked);
87+
this.props.onChange?.(checked);
6388
};
6489

6590
private checkBoxOnChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
@@ -86,19 +111,11 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
86111
: SettingsStore.getDisplayName(this.props.name, this.props.level)) ?? undefined;
87112
const description = SettingsStore.getDescription(this.props.name);
88113
const shouldWarn = SettingsStore.shouldHaveWarning(this.props.name);
89-
90-
let disabledDescription: JSX.Element | null = null;
91-
if (this.props.disabled && this.props.disabledDescription) {
92-
disabledDescription = <div className="mx_SettingsFlag_microcopy">{this.props.disabledDescription}</div>;
93-
}
114+
const disabled = this.state.disabled || !canChange;
94115

95116
if (this.props.useCheckbox) {
96117
return (
97-
<StyledCheckbox
98-
checked={this.state.value}
99-
onChange={this.checkBoxOnChange}
100-
disabled={this.props.disabled || !canChange}
101-
>
118+
<StyledCheckbox checked={this.state.value} onChange={this.checkBoxOnChange} disabled={disabled}>
102119
{label}
103120
</StyledCheckbox>
104121
);
@@ -117,18 +134,18 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
117134
w: (sub) => (
118135
<span className="mx_SettingsTab_microcopy_warning">{sub}</span>
119136
),
120-
description: description,
137+
description,
121138
},
122139
)
123140
: description}
124141
</div>
125142
)}
126-
{disabledDescription}
127143
</label>
128144
<ToggleSwitch
129145
checked={this.state.value}
130146
onChange={this.onChange}
131-
disabled={this.props.disabled || !canChange}
147+
disabled={disabled}
148+
tooltip={disabled ? SettingsStore.disabledMessage(this.props.name) : undefined}
132149
title={label}
133150
/>
134151
</div>

src/components/views/right_panel/PinnedMessagesCard.tsx

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -45,50 +45,53 @@ interface IProps {
4545
onClose(): void;
4646
}
4747

48+
function getPinnedEventIds(room?: Room): string[] {
49+
return room?.currentState.getStateEvents(EventType.RoomPinnedEvents, "")?.getContent()?.pinned ?? [];
50+
}
51+
4852
export const usePinnedEvents = (room?: Room): string[] => {
49-
const [pinnedEvents, setPinnedEvents] = useState<string[]>([]);
53+
const [pinnedEvents, setPinnedEvents] = useState<string[]>(getPinnedEventIds(room));
5054

5155
const update = useCallback(
5256
(ev?: MatrixEvent) => {
53-
if (!room) return;
5457
if (ev && ev.getType() !== EventType.RoomPinnedEvents) return;
55-
setPinnedEvents(
56-
room.currentState.getStateEvents(EventType.RoomPinnedEvents, "")?.getContent()?.pinned || [],
57-
);
58+
setPinnedEvents(getPinnedEventIds(room));
5859
},
5960
[room],
6061
);
6162

6263
useTypedEventEmitter(room?.currentState, RoomStateEvent.Events, update);
6364
useEffect(() => {
64-
update();
65+
setPinnedEvents(getPinnedEventIds(room));
6566
return () => {
6667
setPinnedEvents([]);
6768
};
68-
}, [update]);
69+
}, [room]);
6970
return pinnedEvents;
7071
};
7172

72-
export const useReadPinnedEvents = (room: Room): Set<string> => {
73+
function getReadPinnedEventIds(room?: Room): Set<string> {
74+
return new Set(room.getAccountData(ReadPinsEventId)?.getContent()?.event_ids ?? []);
75+
}
76+
77+
export const useReadPinnedEvents = (room?: Room): Set<string> => {
7378
const [readPinnedEvents, setReadPinnedEvents] = useState<Set<string>>(new Set());
7479

7580
const update = useCallback(
7681
(ev?: MatrixEvent) => {
77-
if (!room) return;
7882
if (ev && ev.getType() !== ReadPinsEventId) return;
79-
const readPins = room.getAccountData(ReadPinsEventId)?.getContent()?.event_ids;
80-
setReadPinnedEvents(new Set(readPins || []));
83+
setReadPinnedEvents(getReadPinnedEventIds(room));
8184
},
8285
[room],
8386
);
8487

8588
useTypedEventEmitter(room, RoomEvent.AccountData, update);
8689
useEffect(() => {
87-
update();
90+
setReadPinnedEvents(getReadPinnedEventIds(room));
8891
return () => {
8992
setReadPinnedEvents(new Set());
9093
};
91-
}, [update]);
94+
}, [room]);
9295
return readPinnedEvents;
9396
};
9497

@@ -157,34 +160,8 @@ const PinnedMessagesCard: React.FC<IProps> = ({ room, onClose, permalinkCreator
157160
null,
158161
);
159162

160-
let content;
161-
if (!pinnedEvents) {
162-
content = <Spinner />;
163-
} else if (pinnedEvents.length > 0) {
164-
const onUnpinClicked = async (event: MatrixEvent): Promise<void> => {
165-
const pinnedEvents = room.currentState.getStateEvents(EventType.RoomPinnedEvents, "");
166-
if (pinnedEvents?.getContent()?.pinned) {
167-
const pinned = pinnedEvents.getContent().pinned;
168-
const index = pinned.indexOf(event.getId());
169-
if (index !== -1) {
170-
pinned.splice(index, 1);
171-
await cli.sendStateEvent(room.roomId, EventType.RoomPinnedEvents, { pinned }, "");
172-
}
173-
}
174-
};
175-
176-
// show them in reverse, with latest pinned at the top
177-
content = filterBoolean(pinnedEvents)
178-
.reverse()
179-
.map((ev) => (
180-
<PinnedEventTile
181-
key={ev.getId()}
182-
event={ev}
183-
onUnpinClicked={canUnpin ? () => onUnpinClicked(ev) : undefined}
184-
permalinkCreator={permalinkCreator}
185-
/>
186-
));
187-
} else {
163+
let content: JSX.Element[] | JSX.Element | undefined;
164+
if (!pinnedEventIds.length) {
188165
content = (
189166
<div className="mx_PinnedMessagesCard_empty_wrapper">
190167
<div className="mx_PinnedMessagesCard_empty">
@@ -215,6 +192,32 @@ const PinnedMessagesCard: React.FC<IProps> = ({ room, onClose, permalinkCreator
215192
</div>
216193
</div>
217194
);
195+
} else if (pinnedEvents?.length) {
196+
const onUnpinClicked = async (event: MatrixEvent): Promise<void> => {
197+
const pinnedEvents = room.currentState.getStateEvents(EventType.RoomPinnedEvents, "");
198+
if (pinnedEvents?.getContent()?.pinned) {
199+
const pinned = pinnedEvents.getContent().pinned;
200+
const index = pinned.indexOf(event.getId());
201+
if (index !== -1) {
202+
pinned.splice(index, 1);
203+
await cli.sendStateEvent(room.roomId, EventType.RoomPinnedEvents, { pinned }, "");
204+
}
205+
}
206+
};
207+
208+
// show them in reverse, with latest pinned at the top
209+
content = filterBoolean(pinnedEvents)
210+
.reverse()
211+
.map((ev) => (
212+
<PinnedEventTile
213+
key={ev.getId()}
214+
event={ev}
215+
onUnpinClicked={canUnpin ? () => onUnpinClicked(ev) : undefined}
216+
permalinkCreator={permalinkCreator}
217+
/>
218+
));
219+
} else {
220+
content = <Spinner />;
218221
}
219222

220223
return (

0 commit comments

Comments
 (0)