Group Labs flags (#7190)

This commit is contained in:
Michael Telatynski 2021-11-25 16:21:10 +00:00 committed by GitHub
parent e4c00d1123
commit c8765821b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 25 deletions

View file

@ -15,6 +15,8 @@ limitations under the License.
*/
import React from 'react';
import { sortBy } from "lodash";
import { _t } from "../../../../../languageHandler";
import SettingsStore from "../../../../../settings/SettingsStore";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
@ -24,6 +26,8 @@ import SdkConfig from "../../../../../SdkConfig";
import BetaCard from "../../../beta/BetaCard";
import SettingsFlag from '../../../elements/SettingsFlag';
import { MatrixClientPeg } from '../../../../../MatrixClientPeg';
import { LabGroup, labGroupNames } from "../../../../../settings/Settings";
import { EnhancedMap } from "../../../../../utils/maps";
interface ILabsSettingToggleProps {
featureId: string;
@ -66,7 +70,7 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
const [labs, betas] = features.reduce((arr, f) => {
arr[SettingsStore.getBetaInfo(f) ? 1 : 0].push(f);
return arr;
}, [[], []]);
}, [[], []] as [string[], string[]]);
let betaSection;
if (betas.length) {
@ -77,23 +81,43 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
let labsSection;
if (SdkConfig.get()['showLabsSettings']) {
const flags = labs.map(f => <LabsSettingToggle featureId={f} key={f} />);
const groups = new EnhancedMap<LabGroup, JSX.Element[]>();
labs.forEach(f => {
groups.getOrCreate(SettingsStore.getLabGroup(f), []).push(
<LabsSettingToggle featureId={f} key={f} />,
);
});
groups.get(LabGroup.Widgets).push(
<SettingsFlag name="enableWidgetScreenshots" level={SettingLevel.ACCOUNT} />,
);
groups.get(LabGroup.Experimental).push(
<SettingsFlag name="lowBandwidth" level={SettingLevel.DEVICE} />,
);
groups.getOrCreate(LabGroup.Developer, []).push(
<SettingsFlag name="developerMode" level={SettingLevel.ACCOUNT} />,
<SettingsFlag name="showHiddenEventsInTimeline" level={SettingLevel.DEVICE} />,
);
groups.get(LabGroup.Analytics).push(
<SettingsFlag name="automaticErrorReporting" level={SettingLevel.DEVICE} />,
);
let hiddenReadReceipts;
if (this.state.showHiddenReadReceipts) {
hiddenReadReceipts = (
<SettingsFlag name="feature_hidden_read_receipts" level={SettingLevel.DEVICE} />
groups.get(LabGroup.Messaging).push(
<SettingsFlag name="feature_hidden_read_receipts" level={SettingLevel.DEVICE} />,
);
}
labsSection = <div className="mx_SettingsTab_section">
<SettingsFlag name="developerMode" level={SettingLevel.ACCOUNT} />
{ flags }
<SettingsFlag name="enableWidgetScreenshots" level={SettingLevel.ACCOUNT} />
<SettingsFlag name="showHiddenEventsInTimeline" level={SettingLevel.DEVICE} />
<SettingsFlag name="lowBandwidth" level={SettingLevel.DEVICE} />
<SettingsFlag name="automaticErrorReporting" level={SettingLevel.DEVICE} />
{ hiddenReadReceipts }
{ sortBy(Array.from(groups.entries()), "0").map(([group, flags]) => (
<div key={group}>
<span className="mx_SettingsTab_subheading">{ _t(labGroupNames[group]) }</span>
{ flags }
</div>
)) }
</div>;
}

View file

@ -813,6 +813,17 @@
"%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
"Change notification settings": "Change notification settings",
"Messaging": "Messaging",
"Profile": "Profile",
"Spaces": "Spaces",
"Widgets": "Widgets",
"Rooms": "Rooms",
"Moderation": "Moderation",
"Message Previews": "Message Previews",
"Themes": "Themes",
"Encryption": "Encryption",
"Experimental": "Experimental",
"Developer": "Developer",
"Report to moderators prototype. In rooms that support moderation, the `report` button will let you report abuse to room moderators": "Report to moderators prototype. In rooms that support moderation, the `report` button will let you report abuse to room moderators",
"Show options to enable 'Do not disturb' mode": "Show options to enable 'Do not disturb' mode",
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
@ -1073,7 +1084,6 @@
"Favourites": "Favourites",
"People": "People",
"Other rooms": "Other rooms",
"Spaces": "Spaces",
"Expand space panel": "Expand space panel",
"Collapse space panel": "Collapse space panel",
"Click to copy": "Click to copy",
@ -1172,7 +1182,6 @@
"Sign Out": "Sign Out",
"Display Name": "Display Name",
"Rename": "Rename",
"Encryption": "Encryption",
"Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.",
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|other": "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.",
"Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s rooms.|one": "Securely cache encrypted messages locally for them to appear in search results, using %(size)s to store messages from %(rooms)s room.",
@ -1236,7 +1245,6 @@
"Failed to save your profile": "Failed to save your profile",
"The operation could not be completed": "The operation could not be completed",
"<a>Upgrade</a> to your own domain": "<a>Upgrade</a> to your own domain",
"Profile": "Profile",
"Profile picture": "Profile picture",
"Save": "Save",
"Delete Backup": "Delete Backup",
@ -1700,7 +1708,6 @@
"Search": "Search",
"Invites": "Invites",
"Start chat": "Start chat",
"Rooms": "Rooms",
"Add room": "Add room",
"Create new room": "Create new room",
"You do not have permissions to create new rooms in this space": "You do not have permissions to create new rooms in this space",
@ -1882,7 +1889,6 @@
"Unpin this widget to view it in this panel": "Unpin this widget to view it in this panel",
"Close this widget to view it in this panel": "Close this widget to view it in this panel",
"Set my room layout for everyone": "Set my room layout for everyone",
"Widgets": "Widgets",
"Edit widgets, bridges & bots": "Edit widgets, bridges & bots",
"Add widgets, bridges & bots": "Add widgets, bridges & bots",
"Not encrypted": "Not encrypted",

View file

@ -86,9 +86,38 @@ const LEVELS_UI_FEATURE = [
// in future we might have a .well-known level or something
];
export interface ISetting {
// Must be set to true for features. Default is 'false'.
isFeature?: boolean;
export enum LabGroup {
Messaging,
Profile,
Spaces,
Widgets,
Rooms,
Moderation,
Analytics,
MessagePreviews,
Themes,
Encryption,
Experimental,
Developer,
}
export const labGroupNames: Record<LabGroup, string> = {
[LabGroup.Messaging]: _td("Messaging"),
[LabGroup.Profile]: _td("Profile"),
[LabGroup.Spaces]: _td("Spaces"),
[LabGroup.Widgets]: _td("Widgets"),
[LabGroup.Rooms]: _td("Rooms"),
[LabGroup.Moderation]: _td("Moderation"),
[LabGroup.Analytics]: _td("Analytics"),
[LabGroup.MessagePreviews]: _td("Message Previews"),
[LabGroup.Themes]: _td("Themes"),
[LabGroup.Encryption]: _td("Encryption"),
[LabGroup.Experimental]: _td("Experimental"),
[LabGroup.Developer]: _td("Developer"),
};
interface IBaseSetting {
isFeature?: false | undefined;
// Display names are strongly recommended for clarity.
// Display name can also be an object for different levels.
@ -138,9 +167,19 @@ export interface ISetting {
};
}
export interface IFeature extends Omit<IBaseSetting, "isFeature"> {
// Must be set to true for features.
isFeature: true;
labsGroup: LabGroup;
}
// Type using I-identifier for backwards compatibility from before it became a discriminated union
export type ISetting = IBaseSetting | IFeature;
export const SETTINGS: {[setting: string]: ISetting} = {
"feature_report_to_moderators": {
isFeature: true,
labsGroup: LabGroup.Moderation,
displayName: _td("Report to moderators prototype. " +
"In rooms that support moderation, the `report` button will let you report abuse to room moderators"),
supportedLevels: LEVELS_FEATURE,
@ -148,18 +187,21 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_dnd": {
isFeature: true,
labsGroup: LabGroup.Profile,
displayName: _td("Show options to enable 'Do not disturb' mode"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_latex_maths": {
isFeature: true,
labsGroup: LabGroup.Messaging,
displayName: _td("Render LaTeX maths in messages"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_communities_v2_prototypes": {
isFeature: true,
labsGroup: LabGroup.Spaces,
displayName: _td(
"Communities v2 prototypes. Requires compatible homeserver. " +
"Highly experimental - use with caution.",
@ -170,18 +212,21 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_pinning": {
isFeature: true,
labsGroup: LabGroup.Messaging,
displayName: _td("Message Pinning"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_maximised_widgets": {
isFeature: true,
labsGroup: LabGroup.Widgets,
displayName: _td("Maximised widgets"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_thread": {
isFeature: true,
labsGroup: LabGroup.Messaging,
// Requires a reload as we change an option flag on the `js-sdk`
// And the entire sync history needs to be parsed again
controller: new ReloadOnChangeController(),
@ -191,6 +236,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_custom_status": {
isFeature: true,
labsGroup: LabGroup.Profile,
displayName: _td("Custom user status messages"),
supportedLevels: LEVELS_FEATURE,
default: false,
@ -198,6 +244,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_custom_tags": {
isFeature: true,
labsGroup: LabGroup.Experimental,
displayName: _td("Group & filter rooms by custom tags (refresh to apply changes)"),
supportedLevels: LEVELS_FEATURE,
default: false,
@ -205,30 +252,35 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_state_counters": {
isFeature: true,
labsGroup: LabGroup.Rooms,
displayName: _td("Render simple counters in room header"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_many_integration_managers": {
isFeature: true,
labsGroup: LabGroup.Experimental,
displayName: _td("Multiple integration managers (requires manual setup)"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_mjolnir": {
isFeature: true,
labsGroup: LabGroup.Moderation,
displayName: _td("Try out new ways to ignore people (experimental)"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_custom_themes": {
isFeature: true,
labsGroup: LabGroup.Themes,
displayName: _td("Support adding custom themes"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_roomlist_preview_reactions_dms": {
isFeature: true,
labsGroup: LabGroup.MessagePreviews,
displayName: _td("Show message previews for reactions in DMs"),
supportedLevels: LEVELS_FEATURE,
default: false,
@ -237,18 +289,21 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_roomlist_preview_reactions_all": {
isFeature: true,
labsGroup: LabGroup.MessagePreviews,
displayName: _td("Show message previews for reactions in all rooms"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_dehydration": {
isFeature: true,
labsGroup: LabGroup.Encryption,
displayName: _td("Offline encrypted messaging using dehydrated devices"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_pseudonymous_analytics_opt_in": {
isFeature: true,
labsGroup: LabGroup.Analytics,
supportedLevels: LEVELS_FEATURE,
displayName: _td('Send pseudonymous analytics data'),
default: false,
@ -256,6 +311,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_polls": {
isFeature: true,
labsGroup: LabGroup.Messaging,
supportedLevels: LEVELS_FEATURE,
displayName: _td("Polls (under active development)"),
default: false,
@ -274,12 +330,14 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_bridge_state": {
isFeature: true,
labsGroup: LabGroup.Rooms,
supportedLevels: LEVELS_FEATURE,
displayName: _td("Show info about bridges in room settings"),
default: false,
},
"feature_new_layout_switcher": {
isFeature: true,
labsGroup: LabGroup.Messaging,
supportedLevels: LEVELS_FEATURE,
displayName: _td("New layout switcher (with message bubbles)"),
default: false,
@ -287,6 +345,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_spaces_metaspaces": {
isFeature: true,
labsGroup: LabGroup.Spaces,
supportedLevels: LEVELS_FEATURE,
displayName: _td("Meta Spaces"),
default: false,
@ -301,9 +360,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
},
"feature_hidden_read_receipts": {
supportedLevels: LEVELS_FEATURE,
displayName: _td(
"Don't send read receipts",
),
displayName: _td("Don't send read receipts"),
default: false,
},
"baseFontSize": {

View file

@ -24,7 +24,7 @@ import RoomSettingsHandler from "./handlers/RoomSettingsHandler";
import ConfigSettingsHandler from "./handlers/ConfigSettingsHandler";
import { _t } from '../languageHandler';
import dis from '../dispatcher/dispatcher';
import { ISetting, SETTINGS } from "./Settings";
import { IFeature, ISetting, LabGroup, SETTINGS } from "./Settings";
import LocalEchoWrapper from "./handlers/LocalEchoWrapper";
import { WatchManager, CallbackFn as WatchCallbackFn } from "./WatchManager";
import { SettingLevel } from "./SettingLevel";
@ -273,7 +273,7 @@ export default class SettingsStore {
return SETTINGS[settingName].isFeature;
}
public static getBetaInfo(settingName: string) {
public static getBetaInfo(settingName: string): ISetting["betaInfo"] {
// consider a beta disabled if the config is explicitly set to false, in which case treat as normal Labs flag
if (SettingsStore.isFeature(settingName)
&& SettingsStore.getValueAt(SettingLevel.CONFIG, settingName, null, true, true) !== false
@ -282,6 +282,12 @@ export default class SettingsStore {
}
}
public static getLabGroup(settingName: string): LabGroup {
if (SettingsStore.isFeature(settingName)) {
return (<IFeature>SETTINGS[settingName]).labsGroup;
}
}
/**
* Determines if a setting is enabled.
* If a setting is disabled then it should be hidden from the user.