mirror of https://github.com/vector-im/riot-web
				
				
				
			Group Labs flags (#7190)
							parent
							
								
									e4c00d1123
								
							
						
					
					
						commit
						c8765821b5
					
				|  | @ -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>; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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", | ||||
|  |  | |||
|  | @ -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": { | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski