Skip to content

Commit f7af134

Browse files
committed
Add option to toggle corner roundness (including bubbles)
1 parent f167688 commit f7af134

File tree

6 files changed

+158
-9
lines changed

6 files changed

+158
-9
lines changed

res/css/_border-radii.scss

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,57 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
$border-radius-2px: 2px;
18-
$border-radius-3px: 3px;
19-
$border-radius-4px: 3px;
20-
$border-radius-5px: 3px;
21-
$border-radius-6px: 3px;
22-
$border-radius-8px: 3px;
23-
$border-radius-10px: 3px;
24-
$border-radius-12px: 3px;
17+
$border-radius-2px: var(--sc-border-radius-2px, 2px);
18+
$border-radius-3px: var(--sc-border-radius-3px, 3px);
19+
$border-radius-4px: var(--sc-border-radius-4px, 3px);
20+
$border-radius-5px: var(--sc-border-radius-5px, 3px);
21+
$border-radius-6px: var(--sc-border-radius-6px, 3px);
22+
$border-radius-8px: var(--sc-border-radius-8px, 3px);
23+
$border-radius-10px: var(--sc-border-radius-10px, 3px);
24+
$border-radius-12px: var(--sc-border-radius-12px, 3px);
25+
26+
body, .mx_MatrixChat_wrapper, .mx_NonUrgentToastContainer {
27+
&[data-border-radius="default"] {
28+
--sc-border-radius-2px: 2px;
29+
--sc-border-radius-3px: 3px;
30+
--sc-border-radius-4px: 3px;
31+
--sc-border-radius-5px: 3px;
32+
--sc-border-radius-6px: 3px;
33+
--sc-border-radius-8px: 3px;
34+
--sc-border-radius-10px: 3px;
35+
--sc-border-radius-12px: 3px;
36+
}
37+
38+
&[data-border-radius="round"] {
39+
--sc-border-radius-2px: 2px;
40+
--sc-border-radius-3px: 8px;
41+
--sc-border-radius-4px: 8px;
42+
--sc-border-radius-5px: 8px;
43+
--sc-border-radius-6px: 8px;
44+
--sc-border-radius-8px: 8px;
45+
--sc-border-radius-10px: 8px;
46+
--sc-border-radius-12px: 8px;
47+
}
48+
49+
&[data-border-radius="extraround"] {
50+
--sc-border-radius-2px: 2px;
51+
--sc-border-radius-3px: 12px;
52+
--sc-border-radius-4px: 12px;
53+
--sc-border-radius-5px: 12px;
54+
--sc-border-radius-6px: 12px;
55+
--sc-border-radius-8px: 12px;
56+
--sc-border-radius-10px: 12px;
57+
--sc-border-radius-12px: 12px;
58+
}
59+
60+
&[data-border-radius="mixed"] {
61+
--sc-border-radius-2px: 2px;
62+
--sc-border-radius-3px: 3px;
63+
--sc-border-radius-4px: 4px;
64+
--sc-border-radius-5px: 5px;
65+
--sc-border-radius-6px: 6px;
66+
--sc-border-radius-8px: 8px;
67+
--sc-border-radius-10px: 10px;
68+
--sc-border-radius-12px: 12px;
69+
}
70+
}

res/css/views/settings/_ThemeChoicePanel.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
.mx_ThemeChoicePanel_themeInUseSection {
17+
.mx_ThemeChoicePanel_themeInUseSection,
18+
.mx_ThemeChoicePanel_borderRadiusSection {
1819
color: $primary-content;
1920
}
2021

src/components/structures/LoggedInView.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class LoggedInView extends React.Component<IProps, IState> {
138138
protected readonly resizeHandler: React.RefObject<HTMLDivElement>;
139139
protected layoutWatcherRef: string;
140140
protected compactLayoutWatcherRef: string;
141+
protected borderRadiusWatcherRef: string;
141142
protected backgroundImageWatcherRef: string;
142143
protected resizer: Resizer;
143144

@@ -189,6 +190,9 @@ class LoggedInView extends React.Component<IProps, IState> {
189190
this.compactLayoutWatcherRef = SettingsStore.watchSetting(
190191
"useCompactLayout", null, this.onCompactLayoutChanged,
191192
);
193+
this.borderRadiusWatcherRef = SettingsStore.watchSetting(
194+
"borderRadius", null, this.onBorderRadiusChanged,
195+
);
192196
this.backgroundImageWatcherRef = SettingsStore.watchSetting(
193197
"RoomList.backgroundImage", null, this.refreshBackgroundImage,
194198
);
@@ -199,6 +203,9 @@ class LoggedInView extends React.Component<IProps, IState> {
199203
OwnProfileStore.instance.on(UPDATE_EVENT, this.refreshBackgroundImage);
200204
this.loadResizerPreferences();
201205
this.refreshBackgroundImage();
206+
207+
// SC: Initially apply border radius on load without being actually changed
208+
this.onBorderRadiusChanged();
202209
}
203210

204211
componentWillUnmount() {
@@ -304,6 +311,11 @@ class LoggedInView extends React.Component<IProps, IState> {
304311
});
305312
};
306313

314+
private onBorderRadiusChanged = () => {
315+
// SC: This is messy here, but whatever
316+
document.body.setAttribute("data-border-radius", SettingsStore.getValue("borderRadius"));
317+
};
318+
307319
private onSync = (syncState: SyncState, oldSyncState?: SyncState, data?: ISyncStateData): void => {
308320
const oldErrCode = this.state.syncErrorData?.error?.errcode;
309321
const newErrCode = data && data.error && data.error.errcode;

src/components/views/settings/ThemeChoicePanel.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import PosthogTrackers from "../../../PosthogTrackers";
3434
import StyledRadioButton from '../elements/StyledRadioButton';
3535
import { Theme } from '../../../settings/enums/Theme';
3636
import { UserNameColorMode } from '../../../settings/enums/UserNameColorMode';
37+
import { BorderRadius } from '../../../settings/enums/BorderRadius';
3738

3839
interface IProps {
3940
}
@@ -42,6 +43,7 @@ interface IThemeState {
4243
lightTheme: string;
4344
darkTheme: string;
4445
themeInUse: Theme;
46+
borderRadius: BorderRadius;
4547
}
4648

4749
export interface CustomThemeMessage {
@@ -68,6 +70,7 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
6870
lightTheme: SettingsStore.getValue("light_theme"),
6971
darkTheme: SettingsStore.getValue("dark_theme"),
7072
themeInUse: SettingsStore.getValue("theme_in_use"),
73+
borderRadius: SettingsStore.getValue("borderRadius"),
7174
customThemeUrl: "",
7275
customThemeMessage: { isError: false, text: "" },
7376
showAdvancedThemeSettings: false,
@@ -120,6 +123,12 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
120123
dis.dispatch<RecheckThemePayload>({ action: Action.RecheckTheme });
121124
};
122125

126+
private onBorderRadiusChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
127+
const borderRadius = e.target.value as BorderRadius;
128+
this.setState({ borderRadius: borderRadius });
129+
SettingsStore.setValue("borderRadius", null, SettingLevel.DEVICE, borderRadius);
130+
};
131+
123132
private onAddCustomTheme = async (): Promise<void> => {
124133
let currentThemes: string[] = SettingsStore.getValue("custom_themes");
125134
if (!currentThemes) currentThemes = [];
@@ -271,6 +280,49 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
271280
}
272281
</div>;
273282

283+
const borderRadiusSection = <div className="mx_SettingsTab_inlineRadioSelectors">
284+
<label>
285+
<StyledRadioButton
286+
name="border_radius"
287+
value={BorderRadius.Default}
288+
checked={this.state.borderRadius === BorderRadius.Default}
289+
onChange={this.onBorderRadiusChange}
290+
>
291+
{ _t("Default") }
292+
</StyledRadioButton>
293+
</label>
294+
<label>
295+
<StyledRadioButton
296+
name="border_radius"
297+
value={BorderRadius.Round}
298+
checked={this.state.borderRadius === BorderRadius.Round}
299+
onChange={this.onBorderRadiusChange}
300+
>
301+
{ _t("Round") }
302+
</StyledRadioButton>
303+
</label>
304+
<label>
305+
<StyledRadioButton
306+
name="border_radius"
307+
value={BorderRadius.ExtraRound}
308+
checked={this.state.borderRadius === BorderRadius.ExtraRound}
309+
onChange={this.onBorderRadiusChange}
310+
>
311+
{ _t("Extra round") }
312+
</StyledRadioButton>
313+
</label>
314+
<label>
315+
<StyledRadioButton
316+
name="border_radius"
317+
value={BorderRadius.Mixed}
318+
checked={this.state.borderRadius === BorderRadius.Mixed}
319+
onChange={this.onBorderRadiusChange}
320+
>
321+
{ _t("Mixed") }
322+
</StyledRadioButton>
323+
</label>
324+
</div>;
325+
274326
let customThemeForm: JSX.Element;
275327
if (SettingsStore.getValue("feature_custom_themes")) {
276328
let messageElement = null;
@@ -364,6 +416,10 @@ export default class ThemeChoicePanel extends React.Component<IProps, IState> {
364416
<span className="mx_SettingsTab_subheading">{ _t("Theme in use") }</span>
365417
{ themeInUseSection }
366418
</div>
419+
<div className="mx_SettingsTab_section mx_ThemeChoicePanel_borderRadiusSection">
420+
<span className="mx_SettingsTab_subheading">{ _t("Corners") }</span>
421+
{ borderRadiusSection }
422+
</div>
367423
<div className="mx_SettingsTab_section mx_ThemeChoicePanel_Advanced">
368424
{ toggle }
369425
{ advanced }

src/settings/Settings.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { MetaSpace } from "../stores/spaces";
4646
import SdkConfig from "../SdkConfig";
4747
import ThreadBetaController from './controllers/ThreadBetaController';
4848
import { FontWatcher } from "./watchers/FontWatcher";
49+
import { BorderRadius } from './enums/BorderRadius';
4950

5051
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
5152
const LEVELS_ROOM_SETTINGS = [
@@ -482,6 +483,10 @@ export const SETTINGS: {[setting: string]: ISetting} = {
482483
default: false,
483484
controller: new IncompatibleController("layout", false, v => v !== Layout.Group),
484485
},
486+
"borderRadius": {
487+
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
488+
default: BorderRadius.Default,
489+
},
485490
"showRedactions": {
486491
supportedLevels: LEVELS_ROOM_SETTINGS_WITH_ROOM,
487492
displayName: _td('Show a placeholder for removed messages'),

src/settings/enums/BorderRadius.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
Copyright 2021 Quirin Götz <[email protected]>
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+
*/
16+
17+
import PropTypes from 'prop-types';
18+
19+
/* TODO: This should be later reworked into something more generic */
20+
21+
export enum BorderRadius {
22+
Default = "default",
23+
Round = "round",
24+
ExtraRound = "extraround",
25+
Mixed = "mixed",
26+
}
27+
28+
/* We need this because multiple components are still using JavaScript */
29+
export const BorderRadiusPropType = PropTypes.oneOf(Object.values(BorderRadius));

0 commit comments

Comments
 (0)