Skip to content

Commit 85c5bb3

Browse files
authored
Merge pull request matrix-org#4835 from matrix-org/t3chguy/notifications0
More small tweaks in preparation for Notifications rework
2 parents 30489ce + 4885615 commit 85c5bb3

File tree

4 files changed

+139
-15
lines changed

4 files changed

+139
-15
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright 2020 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+
*/
16+
17+
import React from "react";
18+
import classNames from "classnames";
19+
20+
import StyledRadioButton from "./StyledRadioButton";
21+
22+
interface IDefinition<T extends string> {
23+
value: T;
24+
className?: string;
25+
disabled?: boolean;
26+
label: React.ReactChild;
27+
description?: React.ReactChild;
28+
}
29+
30+
interface IProps<T extends string> {
31+
name: string;
32+
className?: string;
33+
definitions: IDefinition<T>[];
34+
value?: T; // if not provided no options will be selected
35+
onChange(newValue: T);
36+
}
37+
38+
function StyledRadioGroup<T extends string>({name, definitions, value, className, onChange}: IProps<T>) {
39+
const _onChange = e => {
40+
onChange(e.target.value);
41+
};
42+
43+
return <React.Fragment>
44+
{definitions.map(d => <React.Fragment>
45+
<StyledRadioButton
46+
key={d.value}
47+
className={classNames(className, d.className)}
48+
onChange={_onChange}
49+
checked={d.value === value}
50+
name={name}
51+
value={d.value}
52+
disabled={d.disabled}
53+
>
54+
{d.label}
55+
</StyledRadioButton>
56+
{d.description}
57+
</React.Fragment>)}
58+
</React.Fragment>;
59+
}
60+
61+
export default StyledRadioGroup;

src/components/views/rooms/NotificationBadge.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,20 @@ export default class NotificationBadge extends React.PureComponent<IProps, IStat
141141
}
142142
}
143143

144+
export class StaticNotificationState extends EventEmitter implements INotificationState {
145+
constructor(public symbol: string, public count: number, public color: NotificationColor) {
146+
super();
147+
}
148+
149+
public static forCount(count: number, color: NotificationColor): StaticNotificationState {
150+
return new StaticNotificationState(null, count, color);
151+
}
152+
153+
public static forSymbol(symbol: string, color: NotificationColor): StaticNotificationState {
154+
return new StaticNotificationState(symbol, 0, color);
155+
}
156+
}
157+
144158
export class RoomNotificationState extends EventEmitter implements IDestroyable, INotificationState {
145159
private _symbol: string;
146160
private _count: number;

src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import StyledCheckbox from '../../../elements/StyledCheckbox';
3333
import SettingsFlag from '../../../elements/SettingsFlag';
3434
import Field from '../../../elements/Field';
3535
import EventTilePreview from '../../../elements/EventTilePreview';
36+
import StyledRadioGroup from "../../../elements/StyledRadioGroup";
3637

3738
interface IProps {
3839
}
@@ -116,8 +117,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
116117
};
117118
}
118119

119-
private onThemeChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
120-
const newTheme = e.target.value;
120+
private onThemeChange = (newTheme: string): void => {
121121
if (this.state.theme === newTheme) return;
122122

123123
// doing getValue in the .catch will still return the value we failed to set,
@@ -277,19 +277,18 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
277277
<div className="mx_SettingsTab_section mx_AppearanceUserSettingsTab_themeSection">
278278
<span className="mx_SettingsTab_subheading">{_t("Theme")}</span>
279279
{systemThemeSection}
280-
<div className="mx_ThemeSelectors" onChange={this.onThemeChange}>
281-
{orderedThemes.map(theme => {
282-
return <StyledRadioButton
283-
key={theme.id}
284-
value={theme.id}
285-
name="theme"
286-
disabled={this.state.useSystemTheme}
287-
checked={!this.state.useSystemTheme && theme.id === this.state.theme}
288-
className={"mx_ThemeSelector_" + theme.id}
289-
>
290-
{theme.name}
291-
</StyledRadioButton>;
292-
})}
280+
<div className="mx_ThemeSelectors">
281+
<StyledRadioGroup
282+
name="theme"
283+
definitions={orderedThemes.map(t => ({
284+
value: t.id,
285+
label: t.name,
286+
disabled: this.state.useSystemTheme,
287+
className: "mx_ThemeSelector_" + t.id,
288+
}))}
289+
onChange={this.onThemeChange}
290+
value={this.state.useSystemTheme ? undefined : this.state.theme}
291+
/>
293292
</div>
294293
{customThemeForm}
295294
<SettingsFlag name="useCompactLayout" level={SettingLevel.ACCOUNT} useCheckbox={true} />

src/hooks/useAccountData.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2020 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+
*/
16+
17+
import {useCallback, useState} from "react";
18+
import {MatrixClient} from "matrix-js-sdk/src/client";
19+
import {MatrixEvent} from "matrix-js-sdk/src/models/event";
20+
import {Room} from "matrix-js-sdk/src/models/room";
21+
22+
import {useEventEmitter} from "./useEventEmitter";
23+
24+
const tryGetContent = (ev?: MatrixEvent) => ev ? ev.getContent() : undefined;
25+
26+
// Hook to simplify listening to Matrix account data
27+
export const useAccountData = <T extends {}>(cli: MatrixClient, eventType: string) => {
28+
const [value, setValue] = useState<T>(() => tryGetContent(cli.getAccountData(eventType)));
29+
30+
const handler = useCallback((event) => {
31+
if (event.getType() !== eventType) return;
32+
setValue(event.getContent());
33+
}, [cli, eventType]);
34+
useEventEmitter(cli, "accountData", handler);
35+
36+
return value || {} as T;
37+
};
38+
39+
// Hook to simplify listening to Matrix room account data
40+
export const useRoomAccountData = <T extends {}>(room: Room, eventType: string) => {
41+
const [value, setValue] = useState<T>(() => tryGetContent(room.getAccountData(eventType)));
42+
43+
const handler = useCallback((event) => {
44+
if (event.getType() !== eventType) return;
45+
setValue(event.getContent());
46+
}, [room, eventType]);
47+
useEventEmitter(room, "Room.accountData", handler);
48+
49+
return value || {} as T;
50+
};

0 commit comments

Comments
 (0)