Force DMs to always be red notifications
This also passes the tagId to the sublist so it doesn't have to rip it out of the `layout`. It doesn't get a layout until later anyways, which causes some null issues.
This commit is contained in:
parent
894357f7f6
commit
fb551781c2
4 changed files with 54 additions and 15 deletions
|
@ -27,6 +27,7 @@ import { EventEmitter } from "events";
|
||||||
import { arrayDiff } from "../../../utils/arrays";
|
import { arrayDiff } from "../../../utils/arrays";
|
||||||
import { IDestroyable } from "../../../utils/IDestroyable";
|
import { IDestroyable } from "../../../utils/IDestroyable";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||||
|
|
||||||
export const NOTIFICATION_STATE_UPDATE = "update";
|
export const NOTIFICATION_STATE_UPDATE = "update";
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ export default class NotificationBadge extends React.PureComponent<IProps, IStat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RoomNotificationState extends EventEmitter implements IDestroyable {
|
export class RoomNotificationState extends EventEmitter implements IDestroyable, INotificationState {
|
||||||
private _symbol: string;
|
private _symbol: string;
|
||||||
private _count: number;
|
private _count: number;
|
||||||
private _color: NotificationColor;
|
private _color: NotificationColor;
|
||||||
|
@ -237,13 +238,38 @@ export class RoomNotificationState extends EventEmitter implements IDestroyable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ListNotificationState extends EventEmitter implements IDestroyable {
|
export class TagSpecificNotificationState extends RoomNotificationState {
|
||||||
|
private static TAG_TO_COLOR: {
|
||||||
|
// @ts-ignore - TS wants this to be a string key, but we know better
|
||||||
|
[tagId: TagID]: NotificationColor,
|
||||||
|
} = {
|
||||||
|
[DefaultTagID.DM]: NotificationColor.Red,
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly colorWhenNotIdle?: NotificationColor;
|
||||||
|
|
||||||
|
constructor(room: Room, tagId: TagID) {
|
||||||
|
super(room);
|
||||||
|
|
||||||
|
const specificColor = TagSpecificNotificationState.TAG_TO_COLOR[tagId];
|
||||||
|
if (specificColor) this.colorWhenNotIdle = specificColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get color(): NotificationColor {
|
||||||
|
if (!this.colorWhenNotIdle) return super.color;
|
||||||
|
|
||||||
|
if (super.color !== NotificationColor.None) return this.colorWhenNotIdle;
|
||||||
|
return super.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ListNotificationState extends EventEmitter implements IDestroyable, INotificationState {
|
||||||
private _count: number;
|
private _count: number;
|
||||||
private _color: NotificationColor;
|
private _color: NotificationColor;
|
||||||
private rooms: Room[] = [];
|
private rooms: Room[] = [];
|
||||||
private states: { [roomId: string]: RoomNotificationState } = {};
|
private states: { [roomId: string]: RoomNotificationState } = {};
|
||||||
|
|
||||||
constructor(private byTileCount = false) {
|
constructor(private byTileCount = false, private tagId: TagID) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +304,7 @@ export class ListNotificationState extends EventEmitter implements IDestroyable
|
||||||
state.destroy();
|
state.destroy();
|
||||||
}
|
}
|
||||||
for (const newRoom of diff.added) {
|
for (const newRoom of diff.added) {
|
||||||
const state = new RoomNotificationState(newRoom);
|
const state = new TagSpecificNotificationState(newRoom, this.tagId);
|
||||||
state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate);
|
state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate);
|
||||||
if (this.states[newRoom.roomId]) {
|
if (this.states[newRoom.roomId]) {
|
||||||
// "Should never happen" disclaimer.
|
// "Should never happen" disclaimer.
|
||||||
|
@ -291,6 +317,12 @@ export class ListNotificationState extends EventEmitter implements IDestroyable
|
||||||
this.calculateTotalState();
|
this.calculateTotalState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getForRoom(room: Room) {
|
||||||
|
const state = this.states[room.roomId];
|
||||||
|
if (!state) throw new Error("Unknown room for notification state");
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
for (const state of Object.values(this.states)) {
|
for (const state of Object.values(this.states)) {
|
||||||
state.destroy();
|
state.destroy();
|
||||||
|
|
|
@ -193,6 +193,7 @@ export default class RoomList2 extends React.Component<IProps, IState> {
|
||||||
components.push(
|
components.push(
|
||||||
<RoomSublist2
|
<RoomSublist2
|
||||||
key={`sublist-${orderedTagId}`}
|
key={`sublist-${orderedTagId}`}
|
||||||
|
tagId={orderedTagId}
|
||||||
forRooms={true}
|
forRooms={true}
|
||||||
rooms={orderedRooms}
|
rooms={orderedRooms}
|
||||||
startAsHidden={aesthetics.defaultHidden}
|
startAsHidden={aesthetics.defaultHidden}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import StyledCheckbox from "../elements/StyledCheckbox";
|
||||||
import StyledRadioButton from "../elements/StyledRadioButton";
|
import StyledRadioButton from "../elements/StyledRadioButton";
|
||||||
import RoomListStore from "../../../stores/room-list/RoomListStore2";
|
import RoomListStore from "../../../stores/room-list/RoomListStore2";
|
||||||
import { ListAlgorithm, SortAlgorithm } from "../../../stores/room-list/algorithms/models";
|
import { ListAlgorithm, SortAlgorithm } from "../../../stores/room-list/algorithms/models";
|
||||||
|
import { TagID } from "../../../stores/room-list/models";
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* CAUTION *
|
* CAUTION *
|
||||||
|
@ -56,6 +57,7 @@ interface IProps {
|
||||||
isInvite: boolean;
|
isInvite: boolean;
|
||||||
layout: ListLayout;
|
layout: ListLayout;
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
|
tagId: TagID;
|
||||||
|
|
||||||
// TODO: Collapsed state
|
// TODO: Collapsed state
|
||||||
// TODO: Group invites
|
// TODO: Group invites
|
||||||
|
@ -78,7 +80,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
notificationState: new ListNotificationState(this.props.isInvite),
|
notificationState: new ListNotificationState(this.props.isInvite, this.props.tagId),
|
||||||
menuDisplayed: false,
|
menuDisplayed: false,
|
||||||
};
|
};
|
||||||
this.state.notificationState.setRooms(this.props.rooms);
|
this.state.notificationState.setRooms(this.props.rooms);
|
||||||
|
@ -130,13 +132,13 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private onUnreadFirstChanged = async () => {
|
private onUnreadFirstChanged = async () => {
|
||||||
const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.layout.tagId) === ListAlgorithm.Importance;
|
const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.tagId) === ListAlgorithm.Importance;
|
||||||
const newAlgorithm = isUnreadFirst ? ListAlgorithm.Natural : ListAlgorithm.Importance;
|
const newAlgorithm = isUnreadFirst ? ListAlgorithm.Natural : ListAlgorithm.Importance;
|
||||||
await RoomListStore.instance.setListOrder(this.props.layout.tagId, newAlgorithm);
|
await RoomListStore.instance.setListOrder(this.props.tagId, newAlgorithm);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onTagSortChanged = async (sort: SortAlgorithm) => {
|
private onTagSortChanged = async (sort: SortAlgorithm) => {
|
||||||
await RoomListStore.instance.setTagSorting(this.props.layout.tagId, sort);
|
await RoomListStore.instance.setTagSorting(this.props.tagId, sort);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onMessagePreviewChanged = () => {
|
private onMessagePreviewChanged = () => {
|
||||||
|
@ -176,7 +178,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
key={`room-${room.roomId}`}
|
key={`room-${room.roomId}`}
|
||||||
showMessagePreview={this.props.layout.showPreviews}
|
showMessagePreview={this.props.layout.showPreviews}
|
||||||
isMinimized={this.props.isMinimized}
|
isMinimized={this.props.isMinimized}
|
||||||
tag={this.props.layout.tagId}
|
tag={this.props.tagId}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -189,8 +191,8 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
let contextMenu = null;
|
let contextMenu = null;
|
||||||
if (this.state.menuDisplayed) {
|
if (this.state.menuDisplayed) {
|
||||||
const elementRect = this.menuButtonRef.current.getBoundingClientRect();
|
const elementRect = this.menuButtonRef.current.getBoundingClientRect();
|
||||||
const isAlphabetical = RoomListStore.instance.getTagSorting(this.props.layout.tagId) === SortAlgorithm.Alphabetic;
|
const isAlphabetical = RoomListStore.instance.getTagSorting(this.props.tagId) === SortAlgorithm.Alphabetic;
|
||||||
const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.layout.tagId) === ListAlgorithm.Importance;
|
const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.tagId) === ListAlgorithm.Importance;
|
||||||
contextMenu = (
|
contextMenu = (
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
chevronFace="none"
|
chevronFace="none"
|
||||||
|
@ -204,14 +206,14 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
||||||
<StyledRadioButton
|
<StyledRadioButton
|
||||||
onChange={() => this.onTagSortChanged(SortAlgorithm.Recent)}
|
onChange={() => this.onTagSortChanged(SortAlgorithm.Recent)}
|
||||||
checked={!isAlphabetical}
|
checked={!isAlphabetical}
|
||||||
name={`mx_${this.props.layout.tagId}_sortBy`}
|
name={`mx_${this.props.tagId}_sortBy`}
|
||||||
>
|
>
|
||||||
{_t("Activity")}
|
{_t("Activity")}
|
||||||
</StyledRadioButton>
|
</StyledRadioButton>
|
||||||
<StyledRadioButton
|
<StyledRadioButton
|
||||||
onChange={() => this.onTagSortChanged(SortAlgorithm.Alphabetic)}
|
onChange={() => this.onTagSortChanged(SortAlgorithm.Alphabetic)}
|
||||||
checked={isAlphabetical}
|
checked={isAlphabetical}
|
||||||
name={`mx_${this.props.layout.tagId}_sortBy`}
|
name={`mx_${this.props.tagId}_sortBy`}
|
||||||
>
|
>
|
||||||
{_t("A-Z")}
|
{_t("A-Z")}
|
||||||
</StyledRadioButton>
|
</StyledRadioButton>
|
||||||
|
|
|
@ -26,7 +26,11 @@ import RoomAvatar from "../../views/avatars/RoomAvatar";
|
||||||
import dis from '../../../dispatcher/dispatcher';
|
import dis from '../../../dispatcher/dispatcher';
|
||||||
import { Key } from "../../../Keyboard";
|
import { Key } from "../../../Keyboard";
|
||||||
import ActiveRoomObserver from "../../../ActiveRoomObserver";
|
import ActiveRoomObserver from "../../../ActiveRoomObserver";
|
||||||
import NotificationBadge, { INotificationState, NotificationColor, RoomNotificationState } from "./NotificationBadge";
|
import NotificationBadge, {
|
||||||
|
INotificationState,
|
||||||
|
NotificationColor,
|
||||||
|
TagSpecificNotificationState
|
||||||
|
} from "./NotificationBadge";
|
||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import { ContextMenu, ContextMenuButton } from "../../structures/ContextMenu";
|
import { ContextMenu, ContextMenuButton } from "../../structures/ContextMenu";
|
||||||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||||
|
@ -79,7 +83,7 @@ export default class RoomTile2 extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
hover: false,
|
hover: false,
|
||||||
notificationState: new RoomNotificationState(this.props.room),
|
notificationState: new TagSpecificNotificationState(this.props.room, this.props.tag),
|
||||||
selected: ActiveRoomObserver.activeRoomId === this.props.room.roomId,
|
selected: ActiveRoomObserver.activeRoomId === this.props.room.roomId,
|
||||||
generalMenuDisplayed: false,
|
generalMenuDisplayed: false,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue