More generic layout setting

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-01-22 13:44:45 +01:00
parent c69cc550ea
commit 972c947049
No known key found for this signature in database
GPG key ID: 9760693FDD98A790
9 changed files with 65 additions and 46 deletions

View file

@ -26,6 +26,7 @@ import * as sdk from '../../index';
import {MatrixClientPeg} from '../../MatrixClientPeg'; import {MatrixClientPeg} from '../../MatrixClientPeg';
import SettingsStore from '../../settings/SettingsStore'; import SettingsStore from '../../settings/SettingsStore';
import {Layout} from "../../settings/Layout";
import {_t} from "../../languageHandler"; import {_t} from "../../languageHandler";
import {haveTileForEvent} from "../views/rooms/EventTile"; import {haveTileForEvent} from "../views/rooms/EventTile";
import {textForEvent} from "../../TextForEvent"; import {textForEvent} from "../../TextForEvent";
@ -135,14 +136,13 @@ export default class MessagePanel extends React.Component {
// whether to show reactions for an event // whether to show reactions for an event
showReactions: PropTypes.bool, showReactions: PropTypes.bool,
// whether to use the irc layout // which layout to use
useIRCLayout: PropTypes.bool, layout: Layout,
// whether or not to show flair at all // whether or not to show flair at all
enableFlair: PropTypes.bool, enableFlair: PropTypes.bool,
}; };
// Force props to be loaded for useIRCLayout
constructor(props) { constructor(props) {
super(props); super(props);
@ -612,7 +612,7 @@ export default class MessagePanel extends React.Component {
isSelectedEvent={highlight} isSelectedEvent={highlight}
getRelationsForEvent={this.props.getRelationsForEvent} getRelationsForEvent={this.props.getRelationsForEvent}
showReactions={this.props.showReactions} showReactions={this.props.showReactions}
useIRCLayout={this.props.useIRCLayout} layout={this.props.layout}
enableFlair={this.props.enableFlair} enableFlair={this.props.enableFlair}
/> />
</TileErrorBoundary> </TileErrorBoundary>
@ -810,7 +810,7 @@ export default class MessagePanel extends React.Component {
} }
let ircResizer = null; let ircResizer = null;
if (this.props.useIRCLayout) { if (this.props.layout == Layout.IRC) {
ircResizer = <IRCTimelineProfileResizer ircResizer = <IRCTimelineProfileResizer
minWidth={20} minWidth={20}
maxWidth={600} maxWidth={600}

View file

@ -48,6 +48,7 @@ import RoomViewStore from '../../stores/RoomViewStore';
import RoomScrollStateStore from '../../stores/RoomScrollStateStore'; import RoomScrollStateStore from '../../stores/RoomScrollStateStore';
import WidgetEchoStore from '../../stores/WidgetEchoStore'; import WidgetEchoStore from '../../stores/WidgetEchoStore';
import SettingsStore from "../../settings/SettingsStore"; import SettingsStore from "../../settings/SettingsStore";
import {Layout} from "../../settings/Layout";
import AccessibleButton from "../views/elements/AccessibleButton"; import AccessibleButton from "../views/elements/AccessibleButton";
import RightPanelStore from "../../stores/RightPanelStore"; import RightPanelStore from "../../stores/RightPanelStore";
import {haveTileForEvent} from "../views/rooms/EventTile"; import {haveTileForEvent} from "../views/rooms/EventTile";
@ -180,7 +181,7 @@ export interface IState {
}; };
canReact: boolean; canReact: boolean;
canReply: boolean; canReply: boolean;
useIRCLayout: boolean; layout: Layout;
matrixClientIsReady: boolean; matrixClientIsReady: boolean;
showUrlPreview?: boolean; showUrlPreview?: boolean;
e2eStatus?: E2EStatus; e2eStatus?: E2EStatus;
@ -235,7 +236,7 @@ export default class RoomView extends React.Component<IProps, IState> {
statusBarVisible: false, statusBarVisible: false,
canReact: false, canReact: false,
canReply: false, canReply: false,
useIRCLayout: SettingsStore.getValue("useIRCLayout"), layout: SettingsStore.getValue("layout"),
matrixClientIsReady: this.context && this.context.isInitialSyncComplete(), matrixClientIsReady: this.context && this.context.isInitialSyncComplete(),
}; };
@ -263,7 +264,7 @@ export default class RoomView extends React.Component<IProps, IState> {
this.showReadReceiptsWatchRef = SettingsStore.watchSetting("showReadReceipts", null, this.showReadReceiptsWatchRef = SettingsStore.watchSetting("showReadReceipts", null,
this.onReadReceiptsChange); this.onReadReceiptsChange);
this.layoutWatcherRef = SettingsStore.watchSetting("useIRCLayout", null, this.onLayoutChange); this.layoutWatcherRef = SettingsStore.watchSetting("layout", null, this.onLayoutChange);
} }
// TODO: [REACT-WARNING] Move into constructor // TODO: [REACT-WARNING] Move into constructor
@ -624,7 +625,7 @@ export default class RoomView extends React.Component<IProps, IState> {
private onLayoutChange = () => { private onLayoutChange = () => {
this.setState({ this.setState({
useIRCLayout: SettingsStore.getValue("useIRCLayout"), layout: SettingsStore.getValue("layout"),
}); });
}; };
@ -1915,8 +1916,8 @@ export default class RoomView extends React.Component<IProps, IState> {
const messagePanelClassNames = classNames( const messagePanelClassNames = classNames(
"mx_RoomView_messagePanel", "mx_RoomView_messagePanel",
{ {
"mx_IRCLayout": this.state.useIRCLayout, "mx_IRCLayout": this.state.layout == Layout.IRC,
"mx_GroupLayout": !this.state.useIRCLayout, "mx_GroupLayout": this.state.layout == Layout.Group,
}); });
// console.info("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview); // console.info("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
@ -1939,7 +1940,7 @@ export default class RoomView extends React.Component<IProps, IState> {
permalinkCreator={this.getPermalinkCreatorForRoom(this.state.room)} permalinkCreator={this.getPermalinkCreatorForRoom(this.state.room)}
resizeNotifier={this.props.resizeNotifier} resizeNotifier={this.props.resizeNotifier}
showReactions={true} showReactions={true}
useIRCLayout={this.state.useIRCLayout} layout={this.state.layout}
/>); />);
let topUnreadMessagesBar = null; let topUnreadMessagesBar = null;

View file

@ -18,6 +18,7 @@ limitations under the License.
*/ */
import SettingsStore from "../../settings/SettingsStore"; import SettingsStore from "../../settings/SettingsStore";
import {Layout} from "../../settings/Layout";
import React, {createRef} from 'react'; import React, {createRef} from 'react';
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@ -111,8 +112,8 @@ class TimelinePanel extends React.Component {
// whether to show reactions for an event // whether to show reactions for an event
showReactions: PropTypes.bool, showReactions: PropTypes.bool,
// whether to use the irc layout // which layout to use
useIRCLayout: PropTypes.bool, layout: Layout,
} }
// a map from room id to read marker event timestamp // a map from room id to read marker event timestamp
@ -1442,7 +1443,7 @@ class TimelinePanel extends React.Component {
getRelationsForEvent={this.getRelationsForEvent} getRelationsForEvent={this.getRelationsForEvent}
editState={this.state.editState} editState={this.state.editState}
showReactions={this.props.showReactions} showReactions={this.props.showReactions}
useIRCLayout={this.props.useIRCLayout} layout={this.props.layout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)} enableFlair={SettingsStore.getValue(UIFeature.Flair)}
/> />
); );

View file

@ -22,6 +22,7 @@ import * as Avatar from '../../../Avatar';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import EventTile from '../rooms/EventTile'; import EventTile from '../rooms/EventTile';
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import {Layout} from "../../../settings/Layout";
import {UIFeature} from "../../../settings/UIFeature"; import {UIFeature} from "../../../settings/UIFeature";
interface IProps { interface IProps {
@ -33,7 +34,7 @@ interface IProps {
/** /**
* Whether to use the irc layout or not * Whether to use the irc layout or not
*/ */
useIRCLayout: boolean; layout: Layout;
/** /**
* classnames to apply to the wrapper of the preview * classnames to apply to the wrapper of the preview
@ -121,14 +122,14 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
const event = this.fakeEvent(this.state); const event = this.fakeEvent(this.state);
const className = classnames(this.props.className, { const className = classnames(this.props.className, {
"mx_IRCLayout": this.props.useIRCLayout, "mx_IRCLayout": this.props.layout == Layout.IRC,
"mx_GroupLayout": !this.props.useIRCLayout, "mx_GroupLayout": this.props.layout == Layout.Group,
}); });
return <div className={className}> return <div className={className}>
<EventTile <EventTile
mxEvent={event} mxEvent={event}
useIRCLayout={this.props.useIRCLayout} layout={this.props.layout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)} enableFlair={SettingsStore.getValue(UIFeature.Flair)}
/> />
</div>; </div>;

View file

@ -24,6 +24,7 @@ import {wantsDateSeparator} from '../../../DateUtils';
import {MatrixEvent} from 'matrix-js-sdk'; import {MatrixEvent} from 'matrix-js-sdk';
import {makeUserPermalink, RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks"; import {makeUserPermalink, RoomPermalinkCreator} from "../../../utils/permalinks/Permalinks";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import {Layout} from "../../../settings/Layout";
import escapeHtml from "escape-html"; import escapeHtml from "escape-html";
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
import {Action} from "../../../dispatcher/actions"; import {Action} from "../../../dispatcher/actions";
@ -42,7 +43,7 @@ export default class ReplyThread extends React.Component {
onHeightChanged: PropTypes.func.isRequired, onHeightChanged: PropTypes.func.isRequired,
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired, permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
// Specifies which layout to use. // Specifies which layout to use.
useIRCLayout: PropTypes.bool, layout: Layout,
}; };
static contextType = MatrixClientContext; static contextType = MatrixClientContext;
@ -209,7 +210,7 @@ export default class ReplyThread extends React.Component {
}; };
} }
static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, useIRCLayout) { static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, layout) {
if (!ReplyThread.getParentEventId(parentEv)) { if (!ReplyThread.getParentEventId(parentEv)) {
return <div className="mx_ReplyThread_wrapper_empty" />; return <div className="mx_ReplyThread_wrapper_empty" />;
} }
@ -218,7 +219,7 @@ export default class ReplyThread extends React.Component {
onHeightChanged={onHeightChanged} onHeightChanged={onHeightChanged}
ref={ref} ref={ref}
permalinkCreator={permalinkCreator} permalinkCreator={permalinkCreator}
useIRCLayout={useIRCLayout} layout={layout}
/>; />;
} }
@ -386,7 +387,7 @@ export default class ReplyThread extends React.Component {
permalinkCreator={this.props.permalinkCreator} permalinkCreator={this.props.permalinkCreator}
isRedacted={ev.isRedacted()} isRedacted={ev.isRedacted()}
isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")} isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")}
useIRCLayout={this.props.useIRCLayout} layout={this.props.layout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)} enableFlair={SettingsStore.getValue(UIFeature.Flair)}
replacingEventId={ev.replacingEventId()} replacingEventId={ev.replacingEventId()}
/> />

View file

@ -27,6 +27,7 @@ import * as TextForEvent from "../../../TextForEvent";
import * as sdk from "../../../index"; import * as sdk from "../../../index";
import dis from '../../../dispatcher/dispatcher'; import dis from '../../../dispatcher/dispatcher';
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import {Layout} from "../../../settings/Layout";
import {EventStatus} from 'matrix-js-sdk'; import {EventStatus} from 'matrix-js-sdk';
import {formatTime} from "../../../DateUtils"; import {formatTime} from "../../../DateUtils";
import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {MatrixClientPeg} from '../../../MatrixClientPeg';
@ -225,8 +226,8 @@ export default class EventTile extends React.Component {
// whether to show reactions for this event // whether to show reactions for this event
showReactions: PropTypes.bool, showReactions: PropTypes.bool,
// whether to use the irc layout // which layout to use
useIRCLayout: PropTypes.bool, layout: Layout,
// whether or not to show flair at all // whether or not to show flair at all
enableFlair: PropTypes.bool, enableFlair: PropTypes.bool,
@ -732,7 +733,7 @@ export default class EventTile extends React.Component {
// joins/parts/etc // joins/parts/etc
avatarSize = 14; avatarSize = 14;
needsSenderProfile = false; needsSenderProfile = false;
} else if (this.props.useIRCLayout) { } else if (this.props.layout == Layout.IRC) {
avatarSize = 14; avatarSize = 14;
needsSenderProfile = true; needsSenderProfile = true;
} else if (this.props.continuation && this.props.tileShape !== "file_grid") { } else if (this.props.continuation && this.props.tileShape !== "file_grid") {
@ -843,10 +844,11 @@ export default class EventTile extends React.Component {
{ timestamp } { timestamp }
</a>; </a>;
const groupTimestamp = !this.props.useIRCLayout ? linkedTimestamp : null; const useIRCLayout = this.props.layout == Layout.IRC;
const ircTimestamp = this.props.useIRCLayout ? linkedTimestamp : null; const groupTimestamp = !useIRCLayout ? linkedTimestamp : null;
const groupPadlock = !this.props.useIRCLayout && !isBubbleMessage && this._renderE2EPadlock(); const ircTimestamp = useIRCLayout ? linkedTimestamp : null;
const ircPadlock = this.props.useIRCLayout && !isBubbleMessage && this._renderE2EPadlock(); const groupPadlock = !useIRCLayout && !isBubbleMessage && this._renderE2EPadlock();
const ircPadlock = useIRCLayout && !isBubbleMessage && this._renderE2EPadlock();
switch (this.props.tileShape) { switch (this.props.tileShape) {
case 'notif': { case 'notif': {
@ -941,7 +943,7 @@ export default class EventTile extends React.Component {
this.props.onHeightChanged, this.props.onHeightChanged,
this.props.permalinkCreator, this.props.permalinkCreator,
this._replyThread, this._replyThread,
this.props.useIRCLayout, this.props.layout,
); );
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers // tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers

View file

@ -37,6 +37,7 @@ import StyledRadioGroup from "../../../elements/StyledRadioGroup";
//import classNames from 'classnames'; //import classNames from 'classnames';
import { SettingLevel } from "../../../../../settings/SettingLevel"; import { SettingLevel } from "../../../../../settings/SettingLevel";
import {UIFeature} from "../../../../../settings/UIFeature"; import {UIFeature} from "../../../../../settings/UIFeature";
import {Layout} from "../../../../../settings/Layout";
interface IProps { interface IProps {
} }
@ -62,7 +63,7 @@ interface IState extends IThemeState {
useSystemFont: boolean; useSystemFont: boolean;
systemFont: string; systemFont: string;
showAdvanced: boolean; showAdvanced: boolean;
useIRCLayout: boolean; layout: Layout;
} }
@ -83,7 +84,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
useSystemFont: SettingsStore.getValue("useSystemFont"), useSystemFont: SettingsStore.getValue("useSystemFont"),
systemFont: SettingsStore.getValue("systemFont"), systemFont: SettingsStore.getValue("systemFont"),
showAdvanced: false, showAdvanced: false,
useIRCLayout: SettingsStore.getValue("useIRCLayout"), layout: SettingsStore.getValue("layout"),
}; };
} }
@ -223,6 +224,16 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
SettingsStore.setValue("useIRCLayout", null, SettingLevel.DEVICE, val); SettingsStore.setValue("useIRCLayout", null, SettingLevel.DEVICE, val);
};*/ };*/
private onIRCLayoutChange = (enabled: boolean) => {
if (enabled) {
this.setState({layout: Layout.IRC});
SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
} else {
this.setState({layout: Layout.Group});
SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Group);
}
}
private renderThemeSection() { private renderThemeSection() {
const themeWatcher = new ThemeWatcher(); const themeWatcher = new ThemeWatcher();
let systemThemeSection: JSX.Element; let systemThemeSection: JSX.Element;
@ -306,7 +317,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
<EventTilePreview <EventTilePreview
className="mx_AppearanceUserSettingsTab_fontSlider_preview" className="mx_AppearanceUserSettingsTab_fontSlider_preview"
message={this.MESSAGE_PREVIEW_TEXT} message={this.MESSAGE_PREVIEW_TEXT}
useIRCLayout={this.state.useIRCLayout} layout={this.state.layout}
/> />
<div className="mx_AppearanceUserSettingsTab_fontSlider"> <div className="mx_AppearanceUserSettingsTab_fontSlider">
<div className="mx_AppearanceUserSettingsTab_fontSlider_smallText">Aa</div> <div className="mx_AppearanceUserSettingsTab_fontSlider_smallText">Aa</div>
@ -409,14 +420,15 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
name="useCompactLayout" name="useCompactLayout"
level={SettingLevel.DEVICE} level={SettingLevel.DEVICE}
useCheckbox={true} useCheckbox={true}
disabled={this.state.useIRCLayout} disabled={this.state.layout == Layout.IRC}
/>
<SettingsFlag
name="useIRCLayout"
level={SettingLevel.DEVICE}
useCheckbox={true}
onChange={(checked) => this.setState({useIRCLayout: checked})}
/> />
<StyledCheckbox
checked={this.state.layout == Layout.IRC}
onChange={(ev) => this.onIRCLayoutChange(ev.target.checked)}
>
{_t("Enable experimental, compact IRC style layout")}
</StyledCheckbox>
<SettingsFlag <SettingsFlag
name="useSystemFont" name="useSystemFont"
level={SettingLevel.DEVICE} level={SettingLevel.DEVICE}

View file

@ -17,6 +17,7 @@ limitations under the License.
import { createContext } from "react"; import { createContext } from "react";
import {IState} from "../components/structures/RoomView"; import {IState} from "../components/structures/RoomView";
import {Layout} from "../settings/Layout";
const RoomContext = createContext<IState>({ const RoomContext = createContext<IState>({
roomLoading: true, roomLoading: true,
@ -40,7 +41,7 @@ const RoomContext = createContext<IState>({
statusBarVisible: false, statusBarVisible: false,
canReact: false, canReact: false,
canReply: false, canReply: false,
useIRCLayout: false, layout: Layout.Group,
matrixClientIsReady: false, matrixClientIsReady: false,
}); });
RoomContext.displayName = "RoomContext"; RoomContext.displayName = "RoomContext";

View file

@ -36,6 +36,7 @@ import { isMac } from '../Keyboard';
import UIFeatureController from "./controllers/UIFeatureController"; import UIFeatureController from "./controllers/UIFeatureController";
import { UIFeature } from "./UIFeature"; import { UIFeature } from "./UIFeature";
import { OrderedMultiController } from "./controllers/OrderedMultiController"; import { OrderedMultiController } from "./controllers/OrderedMultiController";
import {Layout} from "./Layout";
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times // These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
const LEVELS_ROOM_SETTINGS = [ const LEVELS_ROOM_SETTINGS = [
@ -623,10 +624,9 @@ export const SETTINGS: {[setting: string]: ISetting} = {
displayName: _td("IRC display name width"), displayName: _td("IRC display name width"),
default: 80, default: 80,
}, },
"useIRCLayout": { "layout": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td("Enable experimental, compact IRC style layout"), default: Layout.Group,
default: false,
}, },
"showChatEffects": { "showChatEffects": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ACCOUNT_SETTINGS,