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

Support dynamic room predecessors in OwnBeaconStore #10339

Merged
merged 5 commits into from
Mar 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/stores/OwnBeaconStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
} from "../utils/beacon";
import { getCurrentPosition } from "../utils/beacon";
import { doMaybeLocalRoomAction } from "../utils/local-room";
import SettingsStore from "../settings/SettingsStore";

const isOwnBeacon = (beacon: Beacon, userId: string): boolean => beacon.beaconInfoOwner === userId;

Expand Down Expand Up @@ -119,6 +120,10 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
* when the target is stationary
*/
private lastPublishedPositionTimestamp?: number;
/**
* Ref returned from watchSetting for the MSC3946 labs flag
*/
private dynamicWatcherRef: string | undefined;

public constructor() {
super(defaultDispatcher);
Expand All @@ -142,7 +147,12 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon);
this.matrixClient.removeListener(BeaconEvent.Destroy, this.onDestroyBeacon);
this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers);
SettingsStore.unwatchSetting(this.dynamicWatcherRef ?? "");

this.clearBeacons();
}

private clearBeacons(): void {
this.beacons.forEach((beacon) => beacon.destroy());

this.stopPollingLocation();
Expand All @@ -159,6 +169,11 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
this.matrixClient.on(BeaconEvent.Update, this.onUpdateBeacon);
this.matrixClient.on(BeaconEvent.Destroy, this.onDestroyBeacon);
this.matrixClient.on(RoomStateEvent.Members, this.onRoomStateMembers);
this.dynamicWatcherRef = SettingsStore.watchSetting(
"feature_dynamic_room_predecessors",
null,
this.reinitialiseBeaconState,
);

this.initialiseBeaconState();
}
Expand Down Expand Up @@ -308,9 +323,19 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
);
}

/**
* @internal public for test only
*/
public reinitialiseBeaconState = (): void => {
this.clearBeacons();
this.initialiseBeaconState();
};

private initialiseBeaconState = (): void => {
const userId = this.matrixClient.getUserId()!;
const visibleRooms = this.matrixClient.getVisibleRooms();
const visibleRooms = this.matrixClient.getVisibleRooms(
SettingsStore.getValue("feature_dynamic_room_predecessors"),
);

visibleRooms.forEach((room) => {
const roomState = room.currentState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe("<RoomLiveShareWarning />", () => {
getUserId: jest.fn().mockReturnValue(aliceId),
unstable_setLiveBeacon: jest.fn().mockResolvedValue({ event_id: "1" }),
sendEvent: jest.fn(),
isGuest: jest.fn().mockReturnValue(false),
});

// 14.03.2022 16:15
Expand Down
39 changes: 39 additions & 0 deletions test/stores/OwnBeaconStore-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
} from "../test-utils";
import { makeBeaconInfoEvent, mockGeolocation, watchPositionMockImplementation } from "../test-utils/beacon";
import { getMockClientWithEventEmitter } from "../test-utils/client";
import SettingsStore from "../../src/settings/SettingsStore";

// modern fake timers and lodash.debounce are a faff
// short circuit it
Expand All @@ -62,6 +63,7 @@ describe("OwnBeaconStore", () => {
unstable_setLiveBeacon: jest.fn().mockResolvedValue({ event_id: "1" }),
sendEvent: jest.fn().mockResolvedValue({ event_id: "1" }),
unstable_createLiveBeacon: jest.fn().mockResolvedValue({ event_id: "1" }),
isGuest: jest.fn().mockReturnValue(false),
});
const room1Id = "$room1:server.org";
const room2Id = "$room2:server.org";
Expand Down Expand Up @@ -1204,4 +1206,41 @@ describe("OwnBeaconStore", () => {
expect(mockClient.unstable_createLiveBeacon).toHaveBeenCalledWith(room1Id, content);
});
});

describe("If the feature_dynamic_room_predecessors is not enabled", () => {
beforeEach(() => {
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
});

it("Passes through the dynamic predecessor setting", async () => {
mockClient.getVisibleRooms.mockReset();
mockClient.getVisibleRooms.mockReturnValue([]);
await makeOwnBeaconStore();
expect(mockClient.getVisibleRooms).toHaveBeenCalledWith(false);
});
});

describe("If the feature_dynamic_room_predecessors is enabled", () => {
beforeEach(() => {
// Turn on feature_dynamic_room_predecessors setting
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(settingName) => settingName === "feature_dynamic_room_predecessors",
);
});

it("Passes through the dynamic predecessor setting", async () => {
mockClient.getVisibleRooms.mockReset();
mockClient.getVisibleRooms.mockReturnValue([]);
await makeOwnBeaconStore();
expect(mockClient.getVisibleRooms).toHaveBeenCalledWith(true);
});

it("Passes through the dynamic predecessor when reinitialised", async () => {
const store = await makeOwnBeaconStore();
mockClient.getVisibleRooms.mockReset();
mockClient.getVisibleRooms.mockReturnValue([]);
store.reinitialiseBeaconState();
expect(mockClient.getVisibleRooms).toHaveBeenCalledWith(true);
});
});
});