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

Commit

Permalink
Merge pull request #4906 from matrix-org/travis/room-list/invites-list
Browse files Browse the repository at this point in the history
Fix a number of issues with the new room list's invites
  • Loading branch information
turt2live committed Jul 7, 2020
2 parents d04bcdf + 1b48b99 commit b3b404f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 45 deletions.
12 changes: 3 additions & 9 deletions src/components/views/rooms/RoomList2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ interface IState {
}

const TAG_ORDER: TagID[] = [
// -- Community Invites Placeholder --

DefaultTagID.Invite,
DefaultTagID.Favourite,
DefaultTagID.DM,
Expand All @@ -77,7 +75,6 @@ const TAG_ORDER: TagID[] = [
DefaultTagID.ServerNotice,
DefaultTagID.Archived,
];
const COMMUNITY_TAGS_BEFORE_TAG = DefaultTagID.Invite;
const CUSTOM_TAGS_BEFORE_TAG = DefaultTagID.LowPriority;
const ALWAYS_VISIBLE_TAGS: TagID[] = [
DefaultTagID.DM,
Expand Down Expand Up @@ -227,25 +224,22 @@ export default class RoomList2 extends React.Component<IProps, IState> {
const components: React.ReactElement[] = [];

for (const orderedTagId of TAG_ORDER) {
if (COMMUNITY_TAGS_BEFORE_TAG === orderedTagId) {
// Populate community invites if we have the chance
// TODO: Community invites: https://github.com/vector-im/riot-web/issues/14179
}
if (CUSTOM_TAGS_BEFORE_TAG === orderedTagId) {
// Populate custom tags if needed
// TODO: Custom tags: https://github.com/vector-im/riot-web/issues/14091
}

const orderedRooms = this.state.sublists[orderedTagId] || [];
if (orderedRooms.length === 0 && !ALWAYS_VISIBLE_TAGS.includes(orderedTagId)) {
const extraTiles = orderedTagId === DefaultTagID.Invite ? this.renderCommunityInvites() : null;
const totalTiles = orderedRooms.length + (extraTiles ? extraTiles.length : 0);
if (totalTiles === 0 && !ALWAYS_VISIBLE_TAGS.includes(orderedTagId)) {
continue; // skip tag - not needed
}

const aesthetics: ITagAesthetics = TAG_AESTHETICS[orderedTagId];
if (!aesthetics) throw new Error(`Tag ${orderedTagId} does not have aesthetics`);

const onAddRoomFn = aesthetics.onAddRoom ? () => aesthetics.onAddRoom(dis) : null;
const extraTiles = orderedTagId === DefaultTagID.Invite ? this.renderCommunityInvites() : null;
components.push(
<RoomSublist2
key={`sublist-${orderedTagId}`}
Expand Down
67 changes: 36 additions & 31 deletions src/components/views/rooms/RoomSublist2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@ import RoomTile2 from "./RoomTile2";
import { ResizableBox, ResizeCallbackData } from "react-resizable";
import { ListLayout } from "../../../stores/room-list/ListLayout";
import { ContextMenu, ContextMenuButton } from "../../structures/ContextMenu";
import StyledCheckbox from "../elements/StyledCheckbox";
import StyledRadioButton from "../elements/StyledRadioButton";
import RoomListStore from "../../../stores/room-list/RoomListStore2";
import { ListAlgorithm, SortAlgorithm } from "../../../stores/room-list/algorithms/models";
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
import dis from "../../../dispatcher/dispatcher";
import NotificationBadge from "./NotificationBadge";
import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
import Tooltip from "../elements/Tooltip";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { Key } from "../../../Keyboard";
import StyledCheckbox from "../elements/StyledCheckbox";

// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231
// TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231
Expand Down Expand Up @@ -280,10 +279,6 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {

const tiles: React.ReactElement[] = [];

if (this.props.extraBadTilesThatShouldntExist) {
tiles.push(...this.props.extraBadTilesThatShouldntExist);
}

if (this.props.rooms) {
const visibleRooms = this.props.rooms.slice(0, this.numVisibleTiles);
for (const room of visibleRooms) {
Expand All @@ -299,6 +294,10 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
}
}

if (this.props.extraBadTilesThatShouldntExist) {
tiles.push(...this.props.extraBadTilesThatShouldntExist);
}

// We only have to do this because of the extra tiles. We do it conditionally
// to avoid spending cycles on slicing. It's generally fine to do this though
// as users are unlikely to have more than a handful of tiles when the extra
Expand All @@ -311,15 +310,40 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
}

private renderMenu(): React.ReactElement {
// TODO: Get a proper invite context menu, or take invites out of the room list.
if (this.props.tagId === DefaultTagID.Invite) {
return null;
}

let contextMenu = null;
if (this.state.contextMenuPosition) {
const isAlphabetical = RoomListStore.instance.getTagSorting(this.props.tagId) === SortAlgorithm.Alphabetic;
const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.tagId) === ListAlgorithm.Importance;

// Invites don't get some nonsense options, so only add them if we have to.
let otherSections = null;
if (this.props.tagId !== DefaultTagID.Invite) {
otherSections = (
<React.Fragment>
<hr />
<div>
<div className='mx_RoomSublist2_contextMenu_title'>{_t("Unread rooms")}</div>
<StyledCheckbox
onChange={this.onUnreadFirstChanged}
checked={isUnreadFirst}
>
{_t("Always show first")}
</StyledCheckbox>
</div>
<hr />
<div>
<div className='mx_RoomSublist2_contextMenu_title'>{_t("Show")}</div>
<StyledCheckbox
onChange={this.onMessagePreviewChanged}
checked={this.props.layout.showPreviews}
>
{_t("Message preview")}
</StyledCheckbox>
</div>
</React.Fragment>
);
}

contextMenu = (
<ContextMenu
chevronFace="none"
Expand All @@ -345,26 +369,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
{_t("A-Z")}
</StyledRadioButton>
</div>
<hr />
<div>
<div className='mx_RoomSublist2_contextMenu_title'>{_t("Unread rooms")}</div>
<StyledCheckbox
onChange={this.onUnreadFirstChanged}
checked={isUnreadFirst}
>
{_t("Always show first")}
</StyledCheckbox>
</div>
<hr />
<div>
<div className='mx_RoomSublist2_contextMenu_title'>{_t("Show")}</div>
<StyledCheckbox
onChange={this.onMessagePreviewChanged}
checked={this.props.layout.showPreviews}
>
{_t("Message preview")}
</StyledCheckbox>
</div>
{otherSections}
</div>
</ContextMenu>
);
Expand Down
6 changes: 3 additions & 3 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1200,13 +1200,13 @@
"Securely back up your keys to avoid losing them. <a>Learn more.</a>": "Securely back up your keys to avoid losing them. <a>Learn more.</a>",
"Not now": "Not now",
"Don't ask me again": "Don't ask me again",
"Sort by": "Sort by",
"Activity": "Activity",
"A-Z": "A-Z",
"Unread rooms": "Unread rooms",
"Always show first": "Always show first",
"Show": "Show",
"Message preview": "Message preview",
"Sort by": "Sort by",
"Activity": "Activity",
"A-Z": "A-Z",
"List options": "List options",
"Add room": "Add room",
"Show %(count)s more|other": "Show %(count)s more",
Expand Down
17 changes: 15 additions & 2 deletions src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TagID } from "../../models";
import { IAlgorithm } from "./IAlgorithm";
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
import * as Unread from "../../../../Unread";
import { EffectiveMembership, getEffectiveMembership } from "../../membership";

/**
* Sorts rooms according to the last event's timestamp in each room that seems
Expand All @@ -37,6 +38,8 @@ export class RecentAlgorithm implements IAlgorithm {
// actually changed (probably needs to be done higher up?) then we could do an
// insertion sort or similar on the limited set of changes.

const myUserId = MatrixClientPeg.get().getUserId();

const tsCache: { [roomId: string]: number } = {};
const getLastTs = (r: Room) => {
if (tsCache[r.roomId]) {
Expand All @@ -50,13 +53,23 @@ export class RecentAlgorithm implements IAlgorithm {
return Number.MAX_SAFE_INTEGER;
}

// If the room hasn't been joined yet, it probably won't have a timeline to
// parse. We'll still fall back to the timeline if this fails, but chances
// are we'll at least have our own membership event to go off of.
const effectiveMembership = getEffectiveMembership(r.getMyMembership());
if (effectiveMembership !== EffectiveMembership.Join) {
const membershipEvent = r.currentState.getStateEvents("m.room.member", myUserId);
if (membershipEvent && !Array.isArray(membershipEvent)) {
return membershipEvent.getTs();
}
}

for (let i = r.timeline.length - 1; i >= 0; --i) {
const ev = r.timeline[i];
if (!ev.getTs()) continue; // skip events that don't have timestamps (tests only?)

// TODO: Don't assume we're using the same client as the peg
if (ev.getSender() === MatrixClientPeg.get().getUserId()
|| Unread.eventTriggersUnreadCount(ev)) {
if (ev.getSender() === myUserId || Unread.eventTriggersUnreadCount(ev)) {
return ev.getTs();
}
}
Expand Down

0 comments on commit b3b404f

Please sign in to comment.