Skip to content

Commit

Permalink
Add option to toggle bubble layout on and off
Browse files Browse the repository at this point in the history
  • Loading branch information
su-ex committed Nov 27, 2020
1 parent 03016fd commit 1daecfb
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/components/structures/MessagePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ export default class MessagePanel extends React.Component {
// whether to use the irc layout
useIRCLayout: PropTypes.bool,

// whether to use the message bubble layout
useBubbleLayout: PropTypes.bool,

// whether or not to show flair at all
enableFlair: PropTypes.bool,
};
Expand Down Expand Up @@ -613,6 +616,7 @@ export default class MessagePanel extends React.Component {
getRelationsForEvent={this.props.getRelationsForEvent}
showReactions={this.props.showReactions}
useIRCLayout={this.props.useIRCLayout}
useBubbleLayout={this.props.useBubbleLayout}
enableFlair={this.props.enableFlair}
/>
</TileErrorBoundary>
Expand Down
14 changes: 14 additions & 0 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export interface IState {
canReact: boolean;
canReply: boolean;
useIRCLayout: boolean;
useBubbleLayout: boolean;
matrixClientIsReady: boolean;
showUrlPreview?: boolean;
e2eStatus?: E2EStatus;
Expand All @@ -193,6 +194,7 @@ export default class RoomView extends React.Component<IProps, IState> {
private readonly rightPanelStoreToken: EventSubscription;
private readonly showReadReceiptsWatchRef: string;
private readonly layoutWatcherRef: string;
private readonly bubbleLayoutWatcherRef: string;

private unmounted = false;
private permalinkCreators: Record<string, RoomPermalinkCreator> = {};
Expand Down Expand Up @@ -234,6 +236,7 @@ export default class RoomView extends React.Component<IProps, IState> {
canReact: false,
canReply: false,
useIRCLayout: SettingsStore.getValue("useIRCLayout"),
useBubbleLayout: SettingsStore.getValue("useBubbleLayout"),
matrixClientIsReady: this.context && this.context.isInitialSyncComplete(),
};

Expand All @@ -260,6 +263,8 @@ export default class RoomView extends React.Component<IProps, IState> {
this.showReadReceiptsWatchRef = SettingsStore.watchSetting("showReadReceipts", null,
this.onReadReceiptsChange);
this.layoutWatcherRef = SettingsStore.watchSetting("useIRCLayout", null, this.onLayoutChange);

this.bubbleLayoutWatcherRef = SettingsStore.watchSetting("useBubbleLayout", null, this.onBubbleLayoutChange);
}

// TODO: [REACT-WARNING] Move into constructor
Expand Down Expand Up @@ -618,6 +623,7 @@ export default class RoomView extends React.Component<IProps, IState> {
// Tinter.tint(); // reset colourscheme

SettingsStore.unwatchSetting(this.layoutWatcherRef);
SettingsStore.unwatchSetting(this.bubbleLayoutWatcherRef);
}

private onLayoutChange = () => {
Expand All @@ -626,6 +632,12 @@ export default class RoomView extends React.Component<IProps, IState> {
});
};

private onBubbleLayoutChange = () => {
this.setState({
useBubbleLayout: SettingsStore.getValue("useBubbleLayout"),
});
};

private onRightPanelStoreUpdate = () => {
this.setState({
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
Expand Down Expand Up @@ -1973,6 +1985,7 @@ export default class RoomView extends React.Component<IProps, IState> {
{
"mx_IRCLayout": this.state.useIRCLayout,
"mx_GroupLayout": !this.state.useIRCLayout,
"sc_BubbleLayout": this.state.useBubbleLayout,
});

// console.info("ShowUrlPreview for %s is %s", this.state.room.roomId, this.state.showUrlPreview);
Expand All @@ -1996,6 +2009,7 @@ export default class RoomView extends React.Component<IProps, IState> {
resizeNotifier={this.props.resizeNotifier}
showReactions={true}
useIRCLayout={this.state.useIRCLayout}
useBubbleLayout={this.state.useBubbleLayout}
/>);

let topUnreadMessagesBar = null;
Expand Down
4 changes: 4 additions & 0 deletions src/components/structures/TimelinePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ class TimelinePanel extends React.Component {

// whether to use the irc layout
useIRCLayout: PropTypes.bool,

// whether to use the message bubble layout
useBubbleLayout: PropTypes.bool,
}

// a map from room id to read marker event timestamp
Expand Down Expand Up @@ -1447,6 +1450,7 @@ class TimelinePanel extends React.Component {
editState={this.state.editState}
showReactions={this.props.showReactions}
useIRCLayout={this.props.useIRCLayout}
useBubbleLayout={this.props.useBubbleLayout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
/>
);
Expand Down
7 changes: 7 additions & 0 deletions src/components/views/elements/EventTilePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ interface IProps {
*/
useIRCLayout: boolean;

/**
* Whether to use the message bubble layout or not
*/
useBubbleLayout: boolean;

/**
* classnames to apply to the wrapper of the preview
*/
Expand Down Expand Up @@ -123,12 +128,14 @@ export default class EventTilePreview extends React.Component<IProps, IState> {
const className = classnames(this.props.className, {
"mx_IRCLayout": this.props.useIRCLayout,
"mx_GroupLayout": !this.props.useIRCLayout,
"sc_BubbleLayout": this.props.useBubbleLayout,
});

return <div className={className}>
<EventTile
mxEvent={event}
useIRCLayout={this.props.useIRCLayout}
useBubbleLayout={this.props.useBubbleLayout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
/>
</div>;
Expand Down
5 changes: 4 additions & 1 deletion src/components/views/elements/ReplyThread.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class ReplyThread extends React.Component {
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
// Specifies which layout to use.
useIRCLayout: PropTypes.bool,
useBubbleLayout: PropTypes.bool,
};

static contextType = MatrixClientContext;
Expand Down Expand Up @@ -209,7 +210,7 @@ export default class ReplyThread extends React.Component {
};
}

static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, useIRCLayout) {
static makeThread(parentEv, onHeightChanged, permalinkCreator, ref, useIRCLayout, useBubbleLayout) {
if (!ReplyThread.getParentEventId(parentEv)) {
return <div className="mx_ReplyThread_wrapper_empty" />;
}
Expand All @@ -219,6 +220,7 @@ export default class ReplyThread extends React.Component {
ref={ref}
permalinkCreator={permalinkCreator}
useIRCLayout={useIRCLayout}
useBubbleLayout={useBubbleLayout}
/>;
}

Expand Down Expand Up @@ -387,6 +389,7 @@ export default class ReplyThread extends React.Component {
isRedacted={ev.isRedacted()}
isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")}
useIRCLayout={this.props.useIRCLayout}
useBubbleLayout={this.props.useBubbleLayout}
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
replacingEventId={ev.replacingEventId()}
/>
Expand Down
7 changes: 6 additions & 1 deletion src/components/views/rooms/EventTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ export default class EventTile extends React.Component {
// whether to use the irc layout
useIRCLayout: PropTypes.bool,

// whether to use the message bubble layout
useBubbleLayout: PropTypes.bool,

// whether or not to show flair at all
enableFlair: PropTypes.bool,
};
Expand Down Expand Up @@ -686,7 +689,8 @@ export default class EventTile extends React.Component {

const client = MatrixClientPeg.get();
const me = client && client.getUserId();
const scBubbleEnabled = !isBubbleMessage && !isInfoMessage
const scBubbleEnabled = this.props.useBubbleLayout
&& !isBubbleMessage && !isInfoMessage
&& this.props.tileShape !== 'reply_preview' && this.props.tileShape !== 'reply'
&& this.props.tileShape !== 'notif' && this.props.tileShape !== 'file_grid';
const sentByMe = me === this.props.mxEvent.getSender();
Expand Down Expand Up @@ -948,6 +952,7 @@ export default class EventTile extends React.Component {
this.props.permalinkCreator,
this._replyThread,
this.props.useIRCLayout,
this.props.useBubbleLayout,
);

var msgOption;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ interface IState extends IThemeState {
systemFont: string;
showAdvanced: boolean;
useIRCLayout: boolean;
useBubbleLayout: boolean;
}


Expand All @@ -84,6 +85,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
systemFont: SettingsStore.getValue("systemFont"),
showAdvanced: false,
useIRCLayout: SettingsStore.getValue("useIRCLayout"),
useBubbleLayout: SettingsStore.getValue("useBubbleLayout"),
};
}

Expand Down Expand Up @@ -223,6 +225,16 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
SettingsStore.setValue("useIRCLayout", null, SettingLevel.DEVICE, val);
};

private onBubbleLayoutChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
const val = e.target.value === "true";

this.setState({
useBubbleLayout: val,
});

SettingsStore.setValue("useBubbleLayout", null, SettingLevel.DEVICE, val);
};

private renderThemeSection() {
const themeWatcher = new ThemeWatcher();
let systemThemeSection: JSX.Element;
Expand Down Expand Up @@ -307,6 +319,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
className="mx_AppearanceUserSettingsTab_fontSlider_preview"
message={this.MESSAGE_PREVIEW_TEXT}
useIRCLayout={this.state.useIRCLayout}
useBubbleLayout={this.state.useBubbleLayout}
/>
<div className="mx_AppearanceUserSettingsTab_fontSlider">
<div className="mx_AppearanceUserSettingsTab_fontSlider_smallText">Aa</div>
Expand Down Expand Up @@ -386,6 +399,50 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
</div>;
};

private renderBubbleLayoutSection = () => {
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={classNames("mx_AppearanceUserSettingsTab_Layout_RadioButton", {
mx_AppearanceUserSettingsTab_Layout_RadioButton_selected: this.state.useBubbleLayout,
})}>
<EventTilePreview
className="mx_AppearanceUserSettingsTab_Layout_RadioButton_preview"
message={this.MESSAGE_PREVIEW_TEXT}
useBubbleLayout={true}
/>
<StyledRadioButton
name="layout"
value="true"
checked={this.state.useBubbleLayout}
onChange={this.onBubbleLayoutChange}
>
{_t("Bubbles")}
</StyledRadioButton>
</div>
<div className="mx_AppearanceUserSettingsTab_spacer" />
<div className={classNames("mx_AppearanceUserSettingsTab_Layout_RadioButton", {
mx_AppearanceUserSettingsTab_Layout_RadioButton_selected: !this.state.useBubbleLayout,
})}>
<EventTilePreview
className="mx_AppearanceUserSettingsTab_Layout_RadioButton_preview"
message={this.MESSAGE_PREVIEW_TEXT}
useBubbleLayout={false}
/>
<StyledRadioButton
name="layout"
value="false"
checked={!this.state.useBubbleLayout}
onChange={this.onBubbleLayoutChange}
>
{_t("No bubbles")}
</StyledRadioButton>
</div>
</div>
</div>;
};

private renderAdvancedSection() {
if (!SettingsStore.getValue(UIFeature.AdvancedSettings)) return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default class PreferencesUserSettingsTab extends React.Component {
'showDisplaynameChanges',
'showImages',
'Pill.shouldShowPillAvatar',
'useBubbleLayout',
];

static GENERAL_SETTINGS = [
Expand Down
1 change: 1 addition & 0 deletions src/contexts/RoomContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const RoomContext = createContext<IState>({
canReact: false,
canReply: false,
useIRCLayout: false,
useBubbleLayout: true,
matrixClientIsReady: false,
});
RoomContext.displayName = "RoomContext";
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/de_DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,7 @@
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
"Enable advanced debugging for the room list": "Erweiterte Fehlersuche für die Raumliste aktivieren",
"Enable experimental, compact IRC style layout": "Kompaktes, experimentelles Layout im IRC-Stil aktivieren",
"Enable layout with message bubbles": "Layout mit Sprechblasen aktivieren",
"User menu": "Benutzermenü",
"%(brand)s Web": "%(brand)s Web",
"%(brand)s Desktop": "%(brand)s Desktop",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@
"Manually verify all remote sessions": "Manually verify all remote sessions",
"IRC display name width": "IRC display name width",
"Enable experimental, compact IRC style layout": "Enable experimental, compact IRC style layout",
"Enable layout with message bubbles": "Enable layout with message bubbles",
"Collecting app version information": "Collecting app version information",
"Collecting logs": "Collecting logs",
"Uploading logs": "Uploading logs",
Expand Down
5 changes: 5 additions & 0 deletions src/settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,11 @@ export const SETTINGS: {[setting: string]: ISetting} = {
displayName: _td("Enable experimental, compact IRC style layout"),
default: false,
},
"useBubbleLayout": {
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
displayName: _td("Enable layout with message bubbles"),
default: true,
},
"Widgets.pinned": {
supportedLevels: LEVELS_ROOM_OR_ACCOUNT,
default: {},
Expand Down

0 comments on commit 1daecfb

Please sign in to comment.