Support custom tags in the room list again
Fixes https://github.com/vector-im/riot-web/issues/14091 Design needs work, however this is behind labs anyways. This re-implements the behaviour of the old room list. The implementation ended up being a lot easier due to early confusion with what the TagOrderStore and TagPanel take care of. Turns out they don't deal with tags, but groups. As such, we don't need to do anything with filtering (though we keep some sanity checks in place for safety), and just have to wire up the CustomRoomTagPanel and CustomRoomTagStore.
This commit is contained in:
parent
4de1645ac7
commit
a0b2859436
10 changed files with 89 additions and 54 deletions
|
@ -72,17 +72,17 @@ class CustomRoomTagTile extends React.Component {
|
|||
const tag = this.props.tag;
|
||||
const avatarHeight = 40;
|
||||
const className = classNames({
|
||||
CustomRoomTagPanel_tileSelected: tag.selected,
|
||||
"CustomRoomTagPanel_tileSelected": tag.selected,
|
||||
});
|
||||
const name = tag.name;
|
||||
const badge = tag.badge;
|
||||
const badgeNotifState = tag.badgeNotifState;
|
||||
let badgeElement;
|
||||
if (badge) {
|
||||
if (badgeNotifState) {
|
||||
const badgeClasses = classNames({
|
||||
"mx_TagTile_badge": true,
|
||||
"mx_TagTile_badgeHighlight": badge.highlight,
|
||||
"mx_TagTile_badgeHighlight": badgeNotifState.hasMentions,
|
||||
});
|
||||
badgeElement = (<div className={badgeClasses}>{FormattingUtils.formatCount(badge.count)}</div>);
|
||||
badgeElement = (<div className={badgeClasses}>{FormattingUtils.formatCount(badgeNotifState.count)}</div>);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
import * as React from "react";
|
||||
import { createRef } from "react";
|
||||
import TagPanel from "./TagPanel";
|
||||
import CustomRoomTagPanel from "./CustomRoomTagPanel";
|
||||
import classNames from "classnames";
|
||||
import dis from "../../dispatcher/dispatcher";
|
||||
import { _t } from "../../languageHandler";
|
||||
|
@ -361,6 +362,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
|||
const tagPanel = !this.state.showTagPanel ? null : (
|
||||
<div className="mx_LeftPanel_tagPanelContainer">
|
||||
<TagPanel/>
|
||||
{SettingsStore.isFeatureEnabled("feature_custom_tags") ? <CustomRoomTagPanel /> : null}
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import { ResizeNotifier } from "../../../utils/ResizeNotifier";
|
|||
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
|
||||
import RoomViewStore from "../../../stores/RoomViewStore";
|
||||
import { ITagMap } from "../../../stores/room-list/algorithms/models";
|
||||
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
|
||||
import { DefaultTagID, isCustomTag, TagID } from "../../../stores/room-list/models";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import RoomSublist from "./RoomSublist";
|
||||
|
@ -41,6 +41,7 @@ import { Action } from "../../../dispatcher/actions";
|
|||
import { ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload";
|
||||
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import CustomRoomTagStore from "../../../stores/CustomRoomTagStore";
|
||||
|
||||
interface IProps {
|
||||
onKeyDown: (ev: React.KeyboardEvent) => void;
|
||||
|
@ -77,6 +78,7 @@ const ALWAYS_VISIBLE_TAGS: TagID[] = [
|
|||
|
||||
interface ITagAesthetics {
|
||||
sectionLabel: string;
|
||||
sectionLabelRaw?: string;
|
||||
addRoomLabel?: string;
|
||||
onAddRoom?: (dispatcher: Dispatcher<ActionPayload>) => void;
|
||||
isInvite: boolean;
|
||||
|
@ -130,9 +132,22 @@ const TAG_AESTHETICS: {
|
|||
},
|
||||
};
|
||||
|
||||
function customTagAesthetics(tagId: TagID): ITagAesthetics {
|
||||
if (tagId.startsWith("u.")) {
|
||||
tagId = tagId.substring(2);
|
||||
}
|
||||
return {
|
||||
sectionLabel: _td("Custom Tag"),
|
||||
sectionLabelRaw: tagId,
|
||||
isInvite: false,
|
||||
defaultHidden: false,
|
||||
};
|
||||
}
|
||||
|
||||
export default class RoomList extends React.Component<IProps, IState> {
|
||||
private searchFilter: NameFilterCondition = new NameFilterCondition();
|
||||
private dispatcherRef;
|
||||
private customTagStoreRef;
|
||||
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
@ -161,12 +176,14 @@ export default class RoomList extends React.Component<IProps, IState> {
|
|||
|
||||
public componentDidMount(): void {
|
||||
RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.updateLists);
|
||||
this.customTagStoreRef = CustomRoomTagStore.addListener(this.updateLists);
|
||||
this.updateLists(); // trigger the first update
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists);
|
||||
defaultDispatcher.unregister(this.dispatcherRef);
|
||||
if (this.customTagStoreRef) this.customTagStoreRef.remove();
|
||||
}
|
||||
|
||||
private onAction = (payload: ActionPayload) => {
|
||||
|
@ -257,12 +274,18 @@ export default class RoomList extends React.Component<IProps, IState> {
|
|||
private renderSublists(): React.ReactElement[] {
|
||||
const components: React.ReactElement[] = [];
|
||||
|
||||
for (const orderedTagId of TAG_ORDER) {
|
||||
if (CUSTOM_TAGS_BEFORE_TAG === orderedTagId) {
|
||||
// Populate custom tags if needed
|
||||
// TODO: Custom tags: https://github.com/vector-im/riot-web/issues/14091
|
||||
const tagOrder = TAG_ORDER.reduce((p, c) => {
|
||||
if (c === CUSTOM_TAGS_BEFORE_TAG) {
|
||||
const customTags = Object.keys(this.state.sublists)
|
||||
.filter(t => isCustomTag(t))
|
||||
.filter(t => CustomRoomTagStore.getTags()[t]); // isSelected
|
||||
p.push(...customTags);
|
||||
}
|
||||
p.push(c);
|
||||
return p;
|
||||
}, [] as TagID[]);
|
||||
|
||||
for (const orderedTagId of tagOrder) {
|
||||
const orderedRooms = this.state.sublists[orderedTagId] || [];
|
||||
const extraTiles = orderedTagId === DefaultTagID.Invite ? this.renderCommunityInvites() : null;
|
||||
const totalTiles = orderedRooms.length + (extraTiles ? extraTiles.length : 0);
|
||||
|
@ -270,7 +293,9 @@ export default class RoomList extends React.Component<IProps, IState> {
|
|||
continue; // skip tag - not needed
|
||||
}
|
||||
|
||||
const aesthetics: ITagAesthetics = TAG_AESTHETICS[orderedTagId];
|
||||
const aesthetics: ITagAesthetics = isCustomTag(orderedTagId)
|
||||
? customTagAesthetics(orderedTagId)
|
||||
: TAG_AESTHETICS[orderedTagId];
|
||||
if (!aesthetics) throw new Error(`Tag ${orderedTagId} does not have aesthetics`);
|
||||
|
||||
const onAddRoomFn = aesthetics.onAddRoom ? () => aesthetics.onAddRoom(dis) : null;
|
||||
|
@ -281,7 +306,7 @@ export default class RoomList extends React.Component<IProps, IState> {
|
|||
forRooms={true}
|
||||
rooms={orderedRooms}
|
||||
startAsHidden={aesthetics.defaultHidden}
|
||||
label={_t(aesthetics.sectionLabel)}
|
||||
label={aesthetics.sectionLabelRaw ? aesthetics.sectionLabelRaw : _t(aesthetics.sectionLabel)}
|
||||
onAddRoom={onAddRoomFn}
|
||||
addRoomLabel={aesthetics.addRoomLabel}
|
||||
isMinimized={this.props.isMinimized}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue