From b28a267669f1aeeab4a3c99d370bf832bfdeb307 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 Jul 2020 20:32:09 -0600 Subject: [PATCH 1/7] Remove old community invite placeholder handling We ended up shoving it into the invite list, so don't render it here. --- src/components/views/rooms/RoomList2.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index 3933b66c92..b0284bac66 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -64,8 +64,6 @@ interface IState { } const TAG_ORDER: TagID[] = [ - // -- Community Invites Placeholder -- - DefaultTagID.Invite, DefaultTagID.Favourite, DefaultTagID.DM, @@ -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, @@ -227,10 +224,6 @@ export default class RoomList2 extends React.Component { 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 From f103fd1ccfd4ff1f041eac7a07d2207356e9dff6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 Jul 2020 20:32:37 -0600 Subject: [PATCH 2/7] Make community invites appear even if there's no room invites Fixes https://github.com/vector-im/riot-web/issues/14358 --- src/components/views/rooms/RoomList2.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index b0284bac66..91bef0fc3d 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -230,7 +230,9 @@ export default class RoomList2 extends React.Component { } 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 } @@ -238,7 +240,6 @@ export default class RoomList2 extends React.Component { 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( Date: Mon, 6 Jul 2020 20:37:04 -0600 Subject: [PATCH 3/7] Show ordering options on invites Fixes https://github.com/vector-im/riot-web/issues/14309 --- src/components/views/rooms/RoomSublist2.tsx | 61 ++++++++++++--------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index 2ca9ec5dd1..f5a1b67571 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -27,7 +27,6 @@ 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"; @@ -35,9 +34,9 @@ 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 @@ -311,15 +310,42 @@ export default class RoomSublist2 extends React.Component { } 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. We do + // this with an array instead of a containing div to ensure that the DOM structure + // is relatively sane. + let otherSections = []; + if (this.props.tagId !== DefaultTagID.Invite) { + otherSections.push(
); + otherSections.push( +
+
{_t("Unread rooms")}
+ + {_t("Always show first")} + +
, + ); + otherSections.push(
); + otherSections.push( +
+
{_t("Show")}
+ + {_t("Message preview")} + +
, + ); + } + contextMenu = ( { {_t("A-Z")} -
-
-
{_t("Unread rooms")}
- - {_t("Always show first")} - -
-
-
-
{_t("Show")}
- - {_t("Message preview")} - -
+ {otherSections}
); From 56333ae017583d149fc00fb60d4b85b62740339d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 Jul 2020 20:42:25 -0600 Subject: [PATCH 4/7] Ensure the recents algorithm is aware of invites --- .../algorithms/tag-sorting/RecentAlgorithm.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts index a122ee3ae6..e7ca94ed95 100644 --- a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts +++ b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts @@ -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 @@ -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]) { @@ -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(); } } From 29aeea2974d46940cda34e597b1824837deb3201 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 Jul 2020 20:45:36 -0600 Subject: [PATCH 5/7] Fix i18n --- src/i18n/strings/en_EN.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b23264a297..b551805184 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1200,13 +1200,13 @@ "Securely back up your keys to avoid losing them. Learn more.": "Securely back up your keys to avoid losing them. Learn more.", "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", From 994d8708f2e62f944aec46d2c7890cb23072170a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 7 Jul 2020 06:52:44 -0600 Subject: [PATCH 6/7] Move to a fragment --- src/components/views/rooms/RoomSublist2.tsx | 52 ++++++++++----------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index f5a1b67571..ca798d12f1 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -315,34 +315,32 @@ export default class RoomSublist2 extends React.Component { 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. We do - // this with an array instead of a containing div to ensure that the DOM structure - // is relatively sane. - let otherSections = []; + // 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.push(
); - otherSections.push( -
-
{_t("Unread rooms")}
- - {_t("Always show first")} - -
, - ); - otherSections.push(
); - otherSections.push( -
-
{_t("Show")}
- - {_t("Message preview")} - -
, + otherSections = ( + +
+
+
{_t("Unread rooms")}
+ + {_t("Always show first")} + +
+
+
+
{_t("Show")}
+ + {_t("Message preview")} + +
+
); } From 1b48b99f99b712ecbef7cc5fb5643000b5115a1a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 7 Jul 2020 06:53:17 -0600 Subject: [PATCH 7/7] Append community invites to bottom instead --- src/components/views/rooms/RoomSublist2.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index ca798d12f1..90ca8b2d4b 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -279,10 +279,6 @@ export default class RoomSublist2 extends React.Component { 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) { @@ -298,6 +294,10 @@ export default class RoomSublist2 extends React.Component { } } + 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