Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/notifications0

This commit is contained in:
Michael Telatynski 2020-06-25 08:45:32 +01:00
commit edd09f66d1
142 changed files with 4631 additions and 1005 deletions

View file

@ -113,7 +113,7 @@ export default class CrossSigningPanel extends React.PureComponent {
_bootstrapSecureSecretStorage = async (forceReset=false) => {
this.setState({ error: null });
try {
await accessSecretStorage(() => undefined, {forceReset});
await accessSecretStorage(() => undefined, forceReset);
} catch (e) {
this.setState({ error: e });
console.error("Error bootstrapping secret storage", e);
@ -154,13 +154,6 @@ export default class CrossSigningPanel extends React.PureComponent {
errorSection = <div className="error">{error.toString()}</div>;
}
// Whether the various keys exist on your account (but not necessarily
// on this device).
const enabledForAccount = (
crossSigningPrivateKeysInStorage &&
secretStorageKeyInAccount
);
let summarisedStatus;
if (homeserverSupportsCrossSigning === undefined) {
const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
@ -184,8 +177,19 @@ export default class CrossSigningPanel extends React.PureComponent {
)}</p>;
}
const keysExistAnywhere = (
secretStorageKeyInAccount ||
crossSigningPrivateKeysInStorage ||
crossSigningPublicKeysOnDevice
);
const keysExistEverywhere = (
secretStorageKeyInAccount &&
crossSigningPrivateKeysInStorage &&
crossSigningPublicKeysOnDevice
);
let resetButton;
if (enabledForAccount) {
if (keysExistAnywhere) {
resetButton = (
<div className="mx_CrossSigningPanel_buttonRow">
<AccessibleButton kind="danger" onClick={this._destroySecureSecretStorage}>
@ -197,10 +201,7 @@ export default class CrossSigningPanel extends React.PureComponent {
// TODO: determine how better to expose this to users in addition to prompts at login/toast
let bootstrapButton;
if (
(!enabledForAccount || !crossSigningPublicKeysOnDevice) &&
homeserverSupportsCrossSigning
) {
if (!keysExistEverywhere && homeserverSupportsCrossSigning) {
bootstrapButton = (
<div className="mx_CrossSigningPanel_buttonRow">
<AccessibleButton kind="primary" onClick={this._onBootstrapClick}>

View file

@ -19,10 +19,8 @@ limitations under the License.
import React from 'react';
import {_t} from "../../../../../languageHandler";
import SettingsStore, {SettingLevel} from "../../../../../settings/SettingsStore";
import * as sdk from "../../../../../index";
import { enumerateThemes } from "../../../../../theme";
import ThemeWatcher from "../../../../../settings/watchers/ThemeWatcher";
import Field from "../../../elements/Field";
import Slider from "../../../elements/Slider";
import AccessibleButton from "../../../elements/AccessibleButton";
import dis from "../../../../../dispatcher/dispatcher";
@ -30,31 +28,42 @@ import { FontWatcher } from "../../../../../settings/watchers/FontWatcher";
import { RecheckThemePayload } from '../../../../../dispatcher/payloads/RecheckThemePayload';
import { Action } from '../../../../../dispatcher/actions';
import { IValidationResult, IFieldState } from '../../../elements/Validation';
import StyledRadioButton from '../../../elements/StyledRadioButton';
import StyledCheckbox from '../../../elements/StyledCheckbox';
import SettingsFlag from '../../../elements/SettingsFlag';
import Field from '../../../elements/Field';
import EventTilePreview from '../../../elements/EventTilePreview';
interface IProps {
}
interface IThemeState {
theme: string,
useSystemTheme: boolean,
theme: string;
useSystemTheme: boolean;
}
export interface CustomThemeMessage {
isError: boolean,
text: string
};
isError: boolean;
text: string;
}
interface IState extends IThemeState {
// String displaying the current selected fontSize.
// Needs to be string for things like '17.' without
// trailing 0s.
fontSize: string,
customThemeUrl: string,
customThemeMessage: CustomThemeMessage,
useCustomFontSize: boolean,
fontSize: string;
customThemeUrl: string;
customThemeMessage: CustomThemeMessage;
useCustomFontSize: boolean;
useSystemFont: boolean;
systemFont: string;
showAdvanced: boolean;
useIRCLayout: boolean;
}
export default class AppearanceUserSettingsTab extends React.Component<IProps, IState> {
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
private themeTimer: NodeJS.Timeout;
@ -67,6 +76,10 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
customThemeUrl: "",
customThemeMessage: {isError: false, text: ""},
useCustomFontSize: SettingsStore.getValue("useCustomFontSize"),
useSystemFont: SettingsStore.getValue("useSystemFont"),
systemFont: SettingsStore.getValue("systemFont"),
showAdvanced: false,
useIRCLayout: SettingsStore.getValue("useIRCLayout"),
};
}
@ -159,7 +172,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
);
return {valid: true, feedback: _t('Use between %(min)s pt and %(max)s pt', {min, max})};
}
};
private onAddCustomTheme = async (): Promise<void> => {
let currentThemes: string[] = SettingsStore.getValue("custom_themes");
@ -197,11 +210,17 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
this.setState({customThemeUrl: e.target.value});
};
private renderThemeSection() {
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
const StyledCheckbox = sdk.getComponent("views.elements.StyledCheckbox");
const StyledRadioButton = sdk.getComponent("views.elements.StyledRadioButton");
private onLayoutChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
const val = e.target.value === "true";
this.setState({
useIRCLayout: val,
});
SettingsStore.setValue("useIRCLayout", null, SettingLevel.DEVICE, val);
};
private renderThemeSection() {
const themeWatcher = new ThemeWatcher();
let systemThemeSection: JSX.Element;
if (themeWatcher.isSystemThemeSupported()) {
@ -263,7 +282,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
return <StyledRadioButton
key={theme.id}
value={theme.id}
name={"theme"}
name="theme"
disabled={this.state.useSystemTheme}
checked={!this.state.useSystemTheme && theme.id === this.state.theme}
className={"mx_ThemeSelector_" + theme.id}
@ -279,9 +298,14 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
}
private renderFontSection() {
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
return <div className="mx_SettingsTab_section mx_AppearanceUserSettingsTab_fontScaling">
<span className="mx_SettingsTab_subheading">{_t("Font size")}</span>
<EventTilePreview
className="mx_AppearanceUserSettingsTab_fontSlider_preview"
message={this.MESSAGE_PREVIEW_TEXT}
useIRCLayout={this.state.useIRCLayout}
/>
<div className="mx_AppearanceUserSettingsTab_fontSlider">
<div className="mx_AppearanceUserSettingsTab_fontSlider_smallText">Aa</div>
<Slider
@ -293,12 +317,14 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
/>
<div className="mx_AppearanceUserSettingsTab_fontSlider_largeText">Aa</div>
</div>
<SettingsFlag
name="useCustomFontSize"
level={SettingLevel.ACCOUNT}
onChange={(checked) => this.setState({useCustomFontSize: checked})}
useCheckbox={true}
/>
<Field
type="number"
label={_t("Font size")}
@ -314,6 +340,87 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
</div>;
}
private renderLayoutSection = () => {
return <div className="mx_SettingsTab_section mx_AppearanceUserSettingsTab_Layout">
<span className="mx_SettingsTab_subheading">{_t("Message layout")}</span>
<div className="mx_AppearanceUserSettingsTab_Layout_RadioButtons" >
<div className="mx_AppearanceUserSettingsTab_Layout_RadioButton">
<EventTilePreview
className="mx_AppearanceUserSettingsTab_Layout_RadioButton_preview"
message={this.MESSAGE_PREVIEW_TEXT}
useIRCLayout={true}
/>
<StyledRadioButton
name="layout"
value="true"
checked={this.state.useIRCLayout}
onChange={this.onLayoutChange}
>
{_t("Compact")}
</StyledRadioButton>
</div>
<div className="mx_AppearanceUserSettingsTab_spacer" />
<div className="mx_AppearanceUserSettingsTab_Layout_RadioButton">
<EventTilePreview
className="mx_AppearanceUserSettingsTab_Layout_RadioButton_preview"
message={this.MESSAGE_PREVIEW_TEXT}
useIRCLayout={false}
/>
<StyledRadioButton
name="layout"
value="false"
checked={!this.state.useIRCLayout}
onChange={this.onLayoutChange}
>
{_t("Modern")}
</StyledRadioButton>
</div>
</div>
</div>;
};
private renderAdvancedSection() {
const toggle = <div
className="mx_AppearanceUserSettingsTab_AdvancedToggle"
onClick={() => this.setState({showAdvanced: !this.state.showAdvanced})}
>
{this.state.showAdvanced ? "Hide advanced" : "Show advanced"}
</div>;
let advanced: React.ReactNode;
if (this.state.showAdvanced) {
advanced = <div>
<SettingsFlag
name="useSystemFont"
level={SettingLevel.DEVICE}
useCheckbox={true}
onChange={(checked) => this.setState({useSystemFont: checked})}
/>
<Field
className="mx_AppearanceUserSettingsTab_systemFont"
label={SettingsStore.getDisplayName("systemFont")}
onChange={(value) => {
this.setState({
systemFont: value.target.value,
});
SettingsStore.setValue("systemFont", null, SettingLevel.DEVICE, value.target.value);
}}
tooltipContent="Set the name of a font installed on your system & Riot will attempt to use it."
forceTooltipVisible={true}
disabled={!this.state.useSystemFont}
value={this.state.systemFont}
/>
</div>;
}
return <div className="mx_SettingsTab_section mx_AppearanceUserSettingsTab_Advanced">
{toggle}
{advanced}
</div>;
}
render() {
return (
<div className="mx_SettingsTab mx_AppearanceUserSettingsTab">
@ -323,6 +430,8 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
</div>
{this.renderThemeSection()}
{SettingsStore.isFeatureEnabled("feature_font_scaling") ? this.renderFontSection() : null}
{SettingsStore.isFeatureEnabled("feature_irc_ui") ? this.renderLayoutSection() : null}
{this.renderAdvancedSection()}
</div>
);
}

View file

@ -66,7 +66,6 @@ export default class LabsUserSettingsTab extends React.Component {
<SettingsFlag name={"showHiddenEventsInTimeline"} level={SettingLevel.DEVICE} />
<SettingsFlag name={"lowBandwidth"} level={SettingLevel.DEVICE} />
<SettingsFlag name={"sendReadReceipts"} level={SettingLevel.ACCOUNT} />
<SettingsFlag name={"keepSecretStoragePassphraseForSession"} level={SettingLevel.DEVICE} />
</div>
</div>
);