Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 03d0483

Browse files
committed
legacy layout: remove
1 parent d88da5a commit 03d0483

File tree

4 files changed

+147
-388
lines changed

4 files changed

+147
-388
lines changed

res/css/views/settings/_LayoutSwitcher.pcss

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -15,83 +15,6 @@ See the License for the specific language governing permissions and
1515
limitations under the License.
1616
*/
1717

18-
.mx_LayoutSwitcher_RadioButtons {
19-
display: flex;
20-
flex-direction: row;
21-
gap: 24px;
22-
width: 100%;
23-
24-
color: $primary-content;
25-
26-
> .mx_LayoutSwitcher_RadioButton {
27-
flex-grow: 0;
28-
flex-shrink: 1;
29-
display: flex;
30-
flex-direction: column;
31-
overflow: hidden;
32-
33-
flex-basis: 33%;
34-
min-width: 0;
35-
36-
border: 1px solid $quinary-content;
37-
border-radius: 10px;
38-
39-
.mx_EventTile_msgOption,
40-
.mx_MessageActionBar {
41-
display: none;
42-
}
43-
44-
.mx_LayoutSwitcher_RadioButton_preview {
45-
flex-grow: 1;
46-
display: flex;
47-
align-items: center;
48-
padding: 10px;
49-
pointer-events: none;
50-
51-
.mx_EventTile[data-layout="bubble"] .mx_EventTile_line {
52-
padding-right: 11px;
53-
}
54-
}
55-
56-
.mx_StyledRadioButton {
57-
flex-grow: 0;
58-
padding: 10px;
59-
}
60-
61-
.mx_EventTile_content {
62-
margin-right: 0;
63-
}
64-
65-
&.mx_LayoutSwitcher_RadioButton_selected {
66-
border-color: var(--cpd-color-bg-accent-rest);
67-
}
68-
}
69-
70-
.mx_StyledRadioButton {
71-
border-top: 1px solid $quinary-content;
72-
}
73-
74-
.mx_StyledRadioButton_checked {
75-
background-color: var(--cpd-color-bg-subtle-secondary);
76-
}
77-
78-
.mx_EventTile {
79-
margin: 0;
80-
&[data-layout="bubble"] {
81-
margin-right: 40px;
82-
flex-shrink: 1;
83-
}
84-
&[data-layout="irc"] {
85-
> a {
86-
display: none;
87-
}
88-
}
89-
.mx_EventTile_line {
90-
max-width: 90%;
91-
}
92-
}
93-
}
94-
9518
.mx_LayoutSwitcher_LayoutSelector {
9619
display: flex;
9720
flex-direction: column;
Lines changed: 146 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,163 @@
11
/*
2-
Copyright 2019 New Vector Ltd
3-
Copyright 2019 - 2021 The Matrix.org Foundation C.I.C.
4-
Copyright 2021 Šimon Brandner <[email protected]>
2+
* Copyright 2024 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
516

6-
Licensed under the Apache License, Version 2.0 (the "License");
7-
you may not use this file except in compliance with the License.
8-
You may obtain a copy of the License at
17+
import React, { JSX, useEffect, useState } from "react";
18+
import { InlineField, ToggleControl, Label, Root, RadioControl } from "@vector-im/compound-web";
919

10-
http://www.apache.org/licenses/LICENSE-2.0
11-
12-
Unless required by applicable law or agreed to in writing, software
13-
distributed under the License is distributed on an "AS IS" BASIS,
14-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15-
See the License for the specific language governing permissions and
16-
limitations under the License.
17-
*/
18-
19-
import React from "react";
20-
import classNames from "classnames";
21-
22-
import SettingsStore from "../../../settings/SettingsStore";
23-
import EventTilePreview from "../elements/EventTilePreview";
24-
import StyledRadioButton from "../elements/StyledRadioButton";
20+
import SettingsSubsection from "./shared/SettingsSubsection";
2521
import { _t } from "../../../languageHandler";
26-
import { Layout } from "../../../settings/enums/Layout";
22+
import SettingsStore from "../../../settings/SettingsStore";
2723
import { SettingLevel } from "../../../settings/SettingLevel";
28-
import SettingsSubsection from "./shared/SettingsSubsection";
24+
import { useSettingValue } from "../../../hooks/useSettings";
25+
import { Layout } from "../../../settings/enums/Layout";
26+
import EventTilePreview from "../elements/EventTilePreview";
27+
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
2928

30-
interface IProps {
31-
userId?: string;
32-
displayName?: string;
33-
avatarUrl?: string;
34-
messagePreviewText: string;
35-
onLayoutChanged: (layout: Layout) => void;
29+
/**
30+
* A section to switch between different message layouts.
31+
*/
32+
export function LayoutSwitcher(): JSX.Element {
33+
return (
34+
<SettingsSubsection heading={_t("common|message_layout")} newUi={true} data-testid="layoutPanel">
35+
<LayoutSelector />
36+
<ToggleCompactLayout />
37+
</SettingsSubsection>
38+
);
39+
}
40+
41+
/**
42+
* A selector to choose the layout of the messages.
43+
*/
44+
function LayoutSelector(): JSX.Element {
45+
return (
46+
<Root
47+
className="mx_LayoutSwitcher_LayoutSelector"
48+
onChange={async (evt) => {
49+
// We don't have any file in the form, we can cast it as string safely
50+
const newLayout = new FormData(evt.currentTarget).get("layout") as string | null;
51+
await SettingsStore.setValue("layout", null, SettingLevel.DEVICE, newLayout);
52+
}}
53+
>
54+
<LayoutRadio layout={Layout.Group} label={_t("common|modern")} />
55+
<LayoutRadio layout={Layout.Bubble} label={_t("settings|appearance|layout_bubbles")} />
56+
<LayoutRadio layout={Layout.IRC} label={_t("settings|appearance|layout_irc")} />
57+
</Root>
58+
);
3659
}
3760

38-
interface IState {
61+
/**
62+
* A radio button to select a layout.
63+
*/
64+
interface LayoutRadioProps {
65+
/**
66+
* The value of the layout.
67+
*/
3968
layout: Layout;
69+
/**
70+
* The label to display for the layout.
71+
*/
72+
label: string;
4073
}
4174

42-
export default class LayoutSwitcher extends React.Component<IProps, IState> {
43-
public constructor(props: IProps) {
44-
super(props);
75+
/**
76+
* A radio button to select a layout.
77+
* @param layout
78+
* @param label
79+
*/
80+
function LayoutRadio({ layout, label }: LayoutRadioProps): JSX.Element {
81+
const currentLayout = useSettingValue<Layout>("layout");
82+
const eventTileInfo = useEventTileInfo();
4583

46-
this.state = {
47-
layout: SettingsStore.getValue("layout"),
48-
};
49-
}
84+
return (
85+
<div className="mxLayoutSwitcher_LayoutSelector_LayoutRadio">
86+
<InlineField
87+
className="mxLayoutSwitcher_LayoutSelector_LayoutRadio_InlineField"
88+
control={<RadioControl name="layout" value={layout} defaultChecked={currentLayout === layout} />}
89+
name="layout"
90+
>
91+
<Label>{label}</Label>
92+
</InlineField>
93+
<div role="separator" className="mxLayoutSwitcher_LayoutSelector_LayoutRadio_separator" />
94+
<EventTilePreview
95+
message={_t("common|preview_message")}
96+
layout={layout}
97+
className="mxLayoutSwitcher_LayoutSelector_LayoutRadio_EventTilePreview"
98+
{...eventTileInfo}
99+
/>
100+
</div>
101+
);
102+
}
50103

51-
private onLayoutChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
52-
const layout = e.target.value as Layout;
104+
type EventTileInfo = {
105+
/**
106+
* The ID of the user to display.
107+
*/
108+
userId: string;
109+
/**
110+
* The display name of the user to display.
111+
*/
112+
displayName?: string;
113+
/**
114+
* The avatar URL of the user to display.
115+
*/
116+
avatarUrl?: string;
117+
};
118+
119+
/**
120+
* Fetch the information to display in the event tile preview.
121+
*/
122+
function useEventTileInfo(): EventTileInfo {
123+
const matrixClient = useMatrixClientContext();
124+
const userId = matrixClient.getSafeUserId();
125+
const [eventTileInfo, setEventTileInfo] = useState<EventTileInfo>({ userId });
53126

54-
this.setState({ layout: layout });
55-
SettingsStore.setValue("layout", null, SettingLevel.DEVICE, layout);
56-
this.props.onLayoutChanged(layout);
57-
};
127+
useEffect(() => {
128+
const run = async (): Promise<void> => {
129+
const profileInfo = await matrixClient.getProfileInfo(userId);
130+
setEventTileInfo({
131+
userId,
132+
displayName: profileInfo.displayname,
133+
avatarUrl: profileInfo.avatar_url,
134+
});
135+
};
136+
137+
run();
138+
}, [userId, matrixClient, setEventTileInfo]);
139+
return eventTileInfo;
140+
}
58141

59-
public render(): React.ReactNode {
60-
const ircClasses = classNames("mx_LayoutSwitcher_RadioButton", {
61-
mx_LayoutSwitcher_RadioButton_selected: this.state.layout == Layout.IRC,
62-
});
63-
const groupClasses = classNames("mx_LayoutSwitcher_RadioButton", {
64-
mx_LayoutSwitcher_RadioButton_selected: this.state.layout == Layout.Group,
65-
});
66-
const bubbleClasses = classNames("mx_LayoutSwitcher_RadioButton", {
67-
mx_LayoutSwitcher_RadioButton_selected: this.state.layout === Layout.Bubble,
68-
});
142+
/**
143+
* A toggleable setting to enable or disable the compact layout.
144+
*/
145+
function ToggleCompactLayout(): JSX.Element {
146+
const compactLayoutEnabled = useSettingValue<boolean>("useCompactLayout");
69147

70-
return (
71-
<SettingsSubsection heading={_t("common|message_layout")}>
72-
<div className="mx_LayoutSwitcher_RadioButtons">
73-
<label className={ircClasses}>
74-
<EventTilePreview
75-
className="mx_LayoutSwitcher_RadioButton_preview"
76-
message={this.props.messagePreviewText}
77-
layout={Layout.IRC}
78-
userId={this.props.userId}
79-
displayName={this.props.displayName}
80-
avatarUrl={this.props.avatarUrl}
81-
/>
82-
<StyledRadioButton
83-
name="layout"
84-
value={Layout.IRC}
85-
checked={this.state.layout === Layout.IRC}
86-
onChange={this.onLayoutChange}
87-
>
88-
{_t("settings|appearance|layout_irc")}
89-
</StyledRadioButton>
90-
</label>
91-
<label className={groupClasses}>
92-
<EventTilePreview
93-
className="mx_LayoutSwitcher_RadioButton_preview"
94-
message={this.props.messagePreviewText}
95-
layout={Layout.Group}
96-
userId={this.props.userId}
97-
displayName={this.props.displayName}
98-
avatarUrl={this.props.avatarUrl}
99-
/>
100-
<StyledRadioButton
101-
name="layout"
102-
value={Layout.Group}
103-
checked={this.state.layout == Layout.Group}
104-
onChange={this.onLayoutChange}
105-
>
106-
{_t("common|modern")}
107-
</StyledRadioButton>
108-
</label>
109-
<label className={bubbleClasses}>
110-
<EventTilePreview
111-
className="mx_LayoutSwitcher_RadioButton_preview"
112-
message={this.props.messagePreviewText}
113-
layout={Layout.Bubble}
114-
userId={this.props.userId}
115-
displayName={this.props.displayName}
116-
avatarUrl={this.props.avatarUrl}
117-
/>
118-
<StyledRadioButton
119-
name="layout"
120-
value={Layout.Bubble}
121-
checked={this.state.layout == Layout.Bubble}
122-
onChange={this.onLayoutChange}
123-
>
124-
{_t("settings|appearance|layout_bubbles")}
125-
</StyledRadioButton>
126-
</label>
127-
</div>
128-
</SettingsSubsection>
129-
);
130-
}
148+
return (
149+
<Root
150+
onChange={async (evt) => {
151+
const checked = new FormData(evt.currentTarget).get("compactLayout") === "on";
152+
await SettingsStore.setValue("useCompactLayout", null, SettingLevel.DEVICE, checked);
153+
}}
154+
>
155+
<InlineField
156+
name="compactLayout"
157+
control={<ToggleControl name="compactLayout" defaultChecked={compactLayoutEnabled} />}
158+
>
159+
<Label>{_t("settings|appearance|compact_layout")}</Label>
160+
</InlineField>
161+
</Root>
162+
);
131163
}

0 commit comments

Comments
 (0)