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

Commit bc60e59

Browse files
Add stable unstable version for jump to date before v1.6 is fully supported on a homeserver (#10398)
Add stable unstable version (`org.matrix.msc3030.stable`) for jump to date [before `v1.6` is fully supported on a homeserver](matrix-org/synapse#15089). Related to element-hq/element-web#24362 but does not solve immediately because Synapse does not supply `org.matrix.msc3030.stable` yet Also refactored `ServerSupportUnstableFeatureController` to support multiple feature groups where any one of them will enable the setting. All features in a feature group are required. This way having either `org.matrix.msc3030` or `org.matrix.msc3030.stable` will enable the jump to date feature flag with a config of `[["org.matrix.msc3030"], ["org.matrix.msc3030.stable"]]`
1 parent f3f8705 commit bc60e59

File tree

3 files changed

+74
-24
lines changed

3 files changed

+74
-24
lines changed

src/settings/Settings.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export const SETTINGS: { [setting: string]: ISetting } = {
230230
controller: new ServerSupportUnstableFeatureController(
231231
"feature_exploring_public_spaces",
232232
defaultWatchManager,
233-
["org.matrix.msc3827.stable"],
233+
[["org.matrix.msc3827.stable"]],
234234
undefined,
235235
_td("Requires your server to support the stable version of MSC3827"),
236236
),
@@ -372,7 +372,7 @@ export const SETTINGS: { [setting: string]: ISetting } = {
372372
controller: new ServerSupportUnstableFeatureController(
373373
"feature_jump_to_date",
374374
defaultWatchManager,
375-
["org.matrix.msc3030"],
375+
[["org.matrix.msc3030"], ["org.matrix.msc3030.stable"]],
376376
"v1.6",
377377
_td("Requires your server to support MSC3030"),
378378
),
@@ -388,7 +388,7 @@ export const SETTINGS: { [setting: string]: ISetting } = {
388388
controller: new ServerSupportUnstableFeatureController(
389389
"sendReadReceipts",
390390
defaultWatchManager,
391-
["org.matrix.msc2285.stable"],
391+
[["org.matrix.msc2285.stable"]],
392392
"v1.4",
393393
_td("Your server doesn't support disabling sending read receipts."),
394394
true,

src/settings/controllers/ServerSupportUnstableFeatureController.ts

+34-11
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,21 @@ import SettingsStore from "../SettingsStore";
2626
* When a setting gets disabled or enabled from this controller it notifies the given WatchManager
2727
*/
2828
export default class ServerSupportUnstableFeatureController extends MatrixClientBackedController {
29+
// Starts off as `undefined` so when we first compare the `newDisabledValue`, it sees
30+
// it as a change and updates the watchers.
2931
private enabled: boolean | undefined;
3032

33+
/**
34+
* Construct a new ServerSupportUnstableFeatureController.
35+
*
36+
* @param unstableFeatureGroups - If any one of the feature groups is satisfied,
37+
* then the setting is considered enabled. A feature group is satisfied if all of
38+
* the features in the group are supported (all features in a group are required).
39+
*/
3140
public constructor(
3241
private readonly settingName: string,
3342
private readonly watchers: WatchManager,
34-
private readonly unstableFeatures: string[],
43+
private readonly unstableFeatureGroups: string[][],
3544
private readonly stableVersion?: string,
3645
private readonly disabledMessage?: string,
3746
private readonly forcedValue: any = false,
@@ -43,29 +52,43 @@ export default class ServerSupportUnstableFeatureController extends MatrixClient
4352
return !this.enabled;
4453
}
4554

46-
public set disabled(v: boolean) {
47-
if (!v === this.enabled) return;
48-
this.enabled = !v;
55+
public set disabled(newDisabledValue: boolean) {
56+
if (!newDisabledValue === this.enabled) return;
57+
this.enabled = !newDisabledValue;
4958
const level = SettingsStore.firstSupportedLevel(this.settingName);
5059
if (!level) return;
5160
const settingValue = SettingsStore.getValue(this.settingName, null);
5261
this.watchers.notifyUpdate(this.settingName, null, level, settingValue);
5362
}
5463

5564
protected async initMatrixClient(oldClient: MatrixClient, newClient: MatrixClient): Promise<void> {
56-
this.disabled = true;
57-
let supported = true;
58-
65+
// Check for stable version support first
5966
if (this.stableVersion && (await this.client.isVersionSupported(this.stableVersion))) {
6067
this.disabled = false;
6168
return;
6269
}
63-
for (const feature of this.unstableFeatures) {
64-
supported = await this.client.doesServerSupportUnstableFeature(feature);
65-
if (!supported) break;
70+
71+
// Otherwise, only one of the unstable feature groups needs to be satisfied in
72+
// order for this setting overall to be enabled
73+
let isEnabled = false;
74+
for (const featureGroup of this.unstableFeatureGroups) {
75+
const featureSupportList = await Promise.all(
76+
featureGroup.map(async (feature) => {
77+
const isFeatureSupported = await this.client.doesServerSupportUnstableFeature(feature);
78+
return isFeatureSupported;
79+
}),
80+
);
81+
82+
// Every feature in a feature group is required in order
83+
// for this setting overall to be enabled.
84+
const isFeatureGroupSatisfied = featureSupportList.every((isFeatureSupported) => isFeatureSupported);
85+
if (isFeatureGroupSatisfied) {
86+
isEnabled = true;
87+
break;
88+
}
6689
}
6790

68-
this.disabled = !supported;
91+
this.disabled = !isEnabled;
6992
}
7093

7194
public getValueOverride(

test/settings/controllers/ServerSupportUnstableFeatureController-test.ts

+37-10
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ describe("ServerSupportUnstableFeatureController", () => {
5555
const controller = new ServerSupportUnstableFeatureController(
5656
setting,
5757
watchers,
58-
["feature"],
58+
[["feature"]],
5959
undefined,
6060
undefined,
6161
"other_value",
@@ -74,7 +74,7 @@ describe("ServerSupportUnstableFeatureController", () => {
7474
const controller = new ServerSupportUnstableFeatureController(
7575
setting,
7676
watchers,
77-
["feature"],
77+
[["feature"]],
7878
"other_value",
7979
);
8080
await prepareSetting(cli, controller);
@@ -84,38 +84,65 @@ describe("ServerSupportUnstableFeatureController", () => {
8484
});
8585

8686
describe("settingDisabled()", () => {
87-
it("returns true if there is no matrix client", () => {
88-
const controller = new ServerSupportUnstableFeatureController(setting, watchers, ["org.matrix.msc3030"]);
87+
it("considered disabled if there is no matrix client", () => {
88+
const controller = new ServerSupportUnstableFeatureController(setting, watchers, [["org.matrix.msc3030"]]);
8989
expect(controller.settingDisabled).toEqual(true);
9090
});
9191

92-
it("returns true if not all required features are supported", async () => {
92+
it("considered disabled if not all required features in the only feature group are supported", async () => {
9393
const cli = stubClient();
9494
cli.doesServerSupportUnstableFeature = jest.fn(async (featureName) => {
9595
return featureName === "org.matrix.msc3827.stable";
9696
});
9797

9898
const controller = new ServerSupportUnstableFeatureController(setting, watchers, [
99-
"org.matrix.msc3827.stable",
100-
"org.matrix.msc3030",
99+
["org.matrix.msc3827.stable", "org.matrix.msc3030"],
101100
]);
102101
await prepareSetting(cli, controller);
103102

104103
expect(controller.settingDisabled).toEqual(true);
105104
});
106105

107-
it("returns false if all required features are supported", async () => {
106+
it("considered enabled if all required features in the only feature group are supported", async () => {
108107
const cli = stubClient();
109108
cli.doesServerSupportUnstableFeature = jest.fn(async (featureName) => {
110109
return featureName === "org.matrix.msc3827.stable" || featureName === "org.matrix.msc3030";
111110
});
112111
const controller = new ServerSupportUnstableFeatureController(setting, watchers, [
113-
"org.matrix.msc3827.stable",
114-
"org.matrix.msc3030",
112+
["org.matrix.msc3827.stable", "org.matrix.msc3030"],
115113
]);
116114
await prepareSetting(cli, controller);
117115

118116
expect(controller.settingDisabled).toEqual(false);
119117
});
118+
119+
it("considered enabled if all required features in one of the feature groups are supported", async () => {
120+
const cli = stubClient();
121+
cli.doesServerSupportUnstableFeature = jest.fn(async (featureName) => {
122+
return featureName === "org.matrix.msc3827.stable" || featureName === "org.matrix.msc3030";
123+
});
124+
const controller = new ServerSupportUnstableFeatureController(setting, watchers, [
125+
["foo-unsupported", "bar-unsupported"],
126+
["org.matrix.msc3827.stable", "org.matrix.msc3030"],
127+
]);
128+
await prepareSetting(cli, controller);
129+
130+
expect(controller.settingDisabled).toEqual(false);
131+
});
132+
133+
it("considered disabled if not all required features in one of the feature groups are supported", async () => {
134+
const cli = stubClient();
135+
cli.doesServerSupportUnstableFeature = jest.fn(async (featureName) => {
136+
return featureName === "org.matrix.msc3827.stable";
137+
});
138+
139+
const controller = new ServerSupportUnstableFeatureController(setting, watchers, [
140+
["foo-unsupported", "bar-unsupported"],
141+
["org.matrix.msc3827.stable", "org.matrix.msc3030"],
142+
]);
143+
await prepareSetting(cli, controller);
144+
145+
expect(controller.settingDisabled).toEqual(true);
146+
});
120147
});
121148
});

0 commit comments

Comments
 (0)