Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/notifications0
This commit is contained in:
commit
edd09f66d1
142 changed files with 4631 additions and 1005 deletions
|
@ -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}>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue