From becaddeb80c54014473604b73d3f99d452a57916 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Tue, 28 Apr 2020 14:12:58 -0600
Subject: [PATCH] Categorize rooms by effective membership

---
 .../room-list/algorithms/ChaoticAlgorithm.ts  |  4 +-
 src/stores/room-list/membership.ts            | 73 +++++++++++++++++++
 2 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 src/stores/room-list/membership.ts

diff --git a/src/stores/room-list/algorithms/ChaoticAlgorithm.ts b/src/stores/room-list/algorithms/ChaoticAlgorithm.ts
index f72adb3aa8..9dfe6f6205 100644
--- a/src/stores/room-list/algorithms/ChaoticAlgorithm.ts
+++ b/src/stores/room-list/algorithms/ChaoticAlgorithm.ts
@@ -18,6 +18,7 @@ import { IAlgorithm, ITagMap, ITagSortingMap, ListAlgorithm } from "./IAlgorithm
 import { Room } from "matrix-js-sdk/src/models/room";
 import { isNullOrUndefined } from "matrix-js-sdk/src/utils";
 import { DefaultTagID } from "../models";
+import { splitRoomsByMembership } from "../membership";
 
 /**
  * A demonstration/temporary algorithm to verify the API surface works.
@@ -65,7 +66,8 @@ export class ChaoticAlgorithm implements IAlgorithm {
         }
 
         // TODO: Remove logging
-        console.log({alg: this.representativeAlgorithm});
+        const memberships = splitRoomsByMembership(rooms);
+        console.log({alg: this.representativeAlgorithm, memberships});
 
         // Step through each room and determine which tags it should be in.
         // We don't care about ordering or sorting here - we're simply organizing things.
diff --git a/src/stores/room-list/membership.ts b/src/stores/room-list/membership.ts
new file mode 100644
index 0000000000..884e2a4a04
--- /dev/null
+++ b/src/stores/room-list/membership.ts
@@ -0,0 +1,73 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import {Room} from "matrix-js-sdk/src/models/room";
+import {Event} from "matrix-js-sdk/src/models/event";
+
+/**
+ * Approximation of a membership status for a given room.
+ */
+export enum EffectiveMembership {
+    /**
+     * The user is effectively joined to the room. For example, actually joined
+     * or knocking on the room (when that becomes possible).
+     */
+    Join = "JOIN",
+
+    /**
+     * The user is effectively invited to the room. Currently this is a direct map
+     * to the invite membership as no other membership states are effectively
+     * invites.
+     */
+    Invite = "INVITE",
+
+    /**
+     * The user is effectively no longer in the room. For example, kicked,
+     * banned, or voluntarily left.
+     */
+    Leave = "LEAVE",
+}
+
+export interface MembershipSplit {
+    // @ts-ignore - TS wants this to be a string key, but we know better.
+    [state: EffectiveMembership]: Room[];
+}
+
+export function splitRoomsByMembership(rooms: Room[]): MembershipSplit {
+    const split: MembershipSplit = {
+        [EffectiveMembership.Invite]: [],
+        [EffectiveMembership.Join]: [],
+        [EffectiveMembership.Leave]: [],
+    };
+
+    for (const room of rooms) {
+        split[getEffectiveMembership(room.getMyMembership())].push(room);
+    }
+
+    return split;
+}
+
+export function getEffectiveMembership(membership: string): EffectiveMembership {
+    if (membership === 'invite') {
+        return EffectiveMembership.Invite;
+    } else if (membership === 'join') {
+        // TODO: Do the same for knock? Update docs as needed in the enum.
+        return EffectiveMembership.Join;
+    } else {
+        // Probably a leave, kick, or ban
+        return EffectiveMembership.Leave;
+    }
+}