Merge branch 'develop' of https://github.com/nordeck/matrix-react-sdk into feature_confetti#14676

 Conflicts:
	src/SlashCommands.tsx
	src/i18n/strings/de_DE.json
This commit is contained in:
nurjinn jafar 2020-08-25 11:52:48 +02:00
commit 1123545cfa
141 changed files with 3418 additions and 2777 deletions

View file

@ -1,5 +1,5 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -14,8 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import React from "react";
import {Room} from "matrix-js-sdk/src/models/room";
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
import {_t} from "../../../../../languageHandler";
import {MatrixClientPeg} from "../../../../../MatrixClientPeg";
import BridgeTile from "../../BridgeTile";
@ -27,28 +29,26 @@ const BRIDGE_EVENT_TYPES = [
const BRIDGES_LINK = "https://matrix.org/bridges/";
export default class BridgeSettingsTab extends React.Component {
static propTypes = {
roomId: PropTypes.string.isRequired,
};
interface IProps {
roomId: string;
}
_renderBridgeCard(event, room) {
export default class BridgeSettingsTab extends React.Component<IProps> {
private renderBridgeCard(event: MatrixEvent, room: Room) {
const content = event.getContent();
if (!content || !content.channel || !content.protocol) {
return null;
}
return <BridgeTile room={room} ev={event}></BridgeTile>;
return <BridgeTile key={event.getId()} room={room} ev={event} />;
}
static getBridgeStateEvents(roomId) {
static getBridgeStateEvents(roomId: string) {
const client = MatrixClientPeg.get();
const roomState = (client.getRoom(roomId)).currentState;
const roomState = client.getRoom(roomId).currentState;
const bridgeEvents = [].concat(...BRIDGE_EVENT_TYPES.map((typeName) =>
Object.values(roomState.events[typeName] || {}),
return [].concat(...BRIDGE_EVENT_TYPES.map((typeName) =>
Array.from(roomState.events.get(typeName).values()),
));
return bridgeEvents;
}
render() {
@ -58,8 +58,7 @@ export default class BridgeSettingsTab extends React.Component {
const client = MatrixClientPeg.get();
const room = client.getRoom(this.props.roomId);
let content = null;
let content: JSX.Element;
if (bridgeEvents.length > 0) {
content = <div>
<p>{_t(
@ -72,7 +71,7 @@ export default class BridgeSettingsTab extends React.Component {
},
)}</p>
<ul className="mx_RoomSettingsDialog_BridgeList">
{ bridgeEvents.map((event) => this._renderBridgeCard(event, room)) }
{ bridgeEvents.map((event) => this.renderBridgeCard(event, room)) }
</ul>
</div>;
} else {

View file

@ -22,6 +22,7 @@ import * as sdk from "../../../../..";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import Modal from "../../../../../Modal";
import QuestionDialog from "../../../dialogs/QuestionDialog";
import StyledRadioGroup from '../../../elements/StyledRadioGroup';
import {SettingLevel} from "../../../../../settings/SettingLevel";
export default class SecurityRoomSettingsTab extends React.Component {
@ -144,7 +145,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
});
};
_onRoomAccessRadioToggle = (ev) => {
_onRoomAccessRadioToggle = (roomAccess) => {
// join_rule
// INVITE | PUBLIC
// ----------------------+----------------
@ -161,7 +162,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
let joinRule = "invite";
let guestAccess = "can_join";
switch (ev.target.value) {
switch (roomAccess) {
case "invite_only":
// no change - use defaults above
break;
@ -190,11 +191,11 @@ export default class SecurityRoomSettingsTab extends React.Component {
});
};
_onHistoryRadioToggle = (ev) => {
_onHistoryRadioToggle = (history) => {
const beforeHistory = this.state.history;
this.setState({history: ev.target.value});
this.setState({history: history});
MatrixClientPeg.get().sendStateEvent(this.props.roomId, "m.room.history_visibility", {
history_visibility: ev.target.value,
history_visibility: history,
}, "").catch((e) => {
console.error(e);
this.setState({history: beforeHistory});
@ -257,27 +258,31 @@ export default class SecurityRoomSettingsTab extends React.Component {
<div>
{guestWarning}
{aliasWarning}
<label>
<input type="radio" name="roomVis" value="invite_only"
disabled={!canChangeAccess}
onChange={this._onRoomAccessRadioToggle}
checked={joinRule !== "public"} />
{_t('Only people who have been invited')}
</label>
<label>
<input type="radio" name="roomVis" value="public_no_guests"
disabled={!canChangeAccess}
onChange={this._onRoomAccessRadioToggle}
checked={joinRule === "public" && guestAccess !== "can_join"} />
{_t('Anyone who knows the room\'s link, apart from guests')}
</label>
<label>
<input type="radio" name="roomVis" value="public_with_guests"
disabled={!canChangeAccess}
onChange={this._onRoomAccessRadioToggle}
checked={joinRule === "public" && guestAccess === "can_join"} />
{_t("Anyone who knows the room's link, including guests")}
</label>
<StyledRadioGroup
name="roomVis"
value={joinRule}
onChange={this._onRoomAccessRadioToggle}
definitions={[
{
value: "invite_only",
disabled: !canChangeAccess,
label: _t('Only people who have been invited'),
checked: joinRule !== "public",
},
{
value: "public_no_guests",
disabled: !canChangeAccess,
label: _t('Anyone who knows the room\'s link, apart from guests'),
checked: joinRule === "public" && guestAccess !== "can_join",
},
{
value: "public_with_guests",
disabled: !canChangeAccess,
label: _t("Anyone who knows the room's link, including guests"),
checked: joinRule === "public" && guestAccess === "can_join",
},
]}
/>
</div>
);
}
@ -294,34 +299,33 @@ export default class SecurityRoomSettingsTab extends React.Component {
{_t('Changes to who can read history will only apply to future messages in this room. ' +
'The visibility of existing history will be unchanged.')}
</div>
<label>
<input type="radio" name="historyVis" value="world_readable"
disabled={!canChangeHistory}
checked={history === "world_readable"}
onChange={this._onHistoryRadioToggle} />
{_t("Anyone")}
</label>
<label>
<input type="radio" name="historyVis" value="shared"
disabled={!canChangeHistory}
checked={history === "shared"}
onChange={this._onHistoryRadioToggle} />
{_t('Members only (since the point in time of selecting this option)')}
</label>
<label>
<input type="radio" name="historyVis" value="invited"
disabled={!canChangeHistory}
checked={history === "invited"}
onChange={this._onHistoryRadioToggle} />
{_t('Members only (since they were invited)')}
</label>
<label >
<input type="radio" name="historyVis" value="joined"
disabled={!canChangeHistory}
checked={history === "joined"}
onChange={this._onHistoryRadioToggle} />
{_t('Members only (since they joined)')}
</label>
<StyledRadioGroup
name="historyVis"
value={history}
onChange={this._onHistoryRadioToggle}
definitions={[
{
value: "world_readable",
disabled: !canChangeHistory,
label: _t("Anyone"),
},
{
value: "shared",
disabled: !canChangeHistory,
label: _t('Members only (since the point in time of selecting this option)'),
},
{
value: "invited",
disabled: !canChangeHistory,
label: _t('Members only (since they were invited)'),
},
{
value: "joined",
disabled: !canChangeHistory,
label: _t('Members only (since they joined)'),
},
]}
/>
</div>
);
}

View file

@ -237,7 +237,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
}
let customThemeForm: JSX.Element;
if (SettingsStore.isFeatureEnabled("feature_custom_themes")) {
if (SettingsStore.getValue("feature_custom_themes")) {
let messageElement = null;
if (this.state.customThemeMessage.text) {
if (this.state.customThemeMessage.isError) {

View file

@ -28,14 +28,15 @@ export class LabsSettingToggle extends React.Component {
};
_onChange = async (checked) => {
await SettingsStore.setFeatureEnabled(this.props.featureId, checked);
await SettingsStore.setValue(this.props.featureId, null, SettingLevel.DEVICE, checked);
this.forceUpdate();
};
render() {
const label = SettingsStore.getDisplayName(this.props.featureId);
const value = SettingsStore.isFeatureEnabled(this.props.featureId);
return <LabelledToggleSwitch value={value} label={label} onChange={this._onChange} />;
const value = SettingsStore.getValue(this.props.featureId);
const canChange = SettingsStore.canSetValue(this.props.featureId, null, SettingLevel.DEVICE);
return <LabelledToggleSwitch value={value} label={label} onChange={this._onChange} disabled={!canChange} />;
}
}
@ -46,7 +47,7 @@ export default class LabsUserSettingsTab extends React.Component {
render() {
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
const flags = SettingsStore.getLabsFeatures().map(f => <LabsSettingToggle featureId={f} key={f} />);
const flags = SettingsStore.getFeatureSettingNames().map(f => <LabsSettingToggle featureId={f} key={f} />);
return (
<div className="mx_SettingsTab">
<div className="mx_SettingsTab_heading">{_t("Labs")}</div>

View file

@ -157,6 +157,9 @@ export default class VoiceUserSettingsTab extends React.Component {
label: _t('Default Device'),
};
const getDefaultDevice = (devices) => {
// Note we're looking for a device with deviceId 'default' but adding a device
// with deviceId == the empty string: this is because Chrome gives us a device
// with deviceId 'default', so we're looking for this, not the one we are adding.
if (!devices.some((i) => i.deviceId === 'default')) {
devices.unshift(defaultOption);
return '';