mirror of
https://github.com/element-hq/element-web
synced 2024-11-29 04:48:50 +03:00
enable/disable features in config.json
As per https://docs.google.com/document/d/1Kn-mz2dDce9Cqc4oUTl5yJXGvmTlky1_KezuwUg58x0/edit# Replaces: * enableLabs setting * 'override' flag in labs * 'default' flag in labs Un-feature-flags matrix apps since this was now overidden to be enabled.
This commit is contained in:
parent
757e42ddca
commit
e50478aa1d
5 changed files with 76 additions and 84 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2017 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -17,33 +18,42 @@ limitations under the License.
|
||||||
import Promise from 'bluebird';
|
import Promise from 'bluebird';
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import Notifier from './Notifier';
|
import Notifier from './Notifier';
|
||||||
import { _t } from './languageHandler';
|
import { _t, _td } from './languageHandler';
|
||||||
|
import SdkConfig from './SdkConfig';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: Make things use this. This is all WIP - see UserSettings.js for usage.
|
* TODO: Make things use this. This is all WIP - see UserSettings.js for usage.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const FEATURES = [
|
||||||
|
{
|
||||||
|
id: 'feature_groups',
|
||||||
|
name: _td("Groups"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
LABS_FEATURES: [
|
getLabsFeatures() {
|
||||||
{
|
const featuresConfig = SdkConfig.get()['features'] || {};
|
||||||
name: "-",
|
|
||||||
id: 'matrix_apps',
|
|
||||||
default: true,
|
|
||||||
|
|
||||||
// XXX: Always use default, ignore localStorage and remove from labs
|
return FEATURES.filter((f) => {
|
||||||
override: true,
|
const sdkConfigValue = featuresConfig[f.id];
|
||||||
},
|
if (!['enable', 'disable'].includes(sdkConfigValue)) {
|
||||||
{
|
return true;
|
||||||
name: "-",
|
}
|
||||||
id: 'feature_groups',
|
}).map((f) => {
|
||||||
default: false,
|
return f.id;
|
||||||
},
|
});
|
||||||
],
|
},
|
||||||
|
|
||||||
// horrible but it works. The locality makes this somewhat more palatable.
|
translatedNameForFeature(featureId) {
|
||||||
doTranslations: function() {
|
const feature = FEATURES.filter((f) => {
|
||||||
this.LABS_FEATURES[0].name = _t("Matrix Apps");
|
return f.id === featureId;
|
||||||
this.LABS_FEATURES[1].name = _t("Groups");
|
})[0];
|
||||||
|
|
||||||
|
if (feature === undefined) return null;
|
||||||
|
|
||||||
|
return _t(feature.name);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadProfileInfo: function() {
|
loadProfileInfo: function() {
|
||||||
|
@ -180,33 +190,30 @@ export default {
|
||||||
localStorage.setItem('mx_local_settings', JSON.stringify(settings));
|
localStorage.setItem('mx_local_settings', JSON.stringify(settings));
|
||||||
},
|
},
|
||||||
|
|
||||||
getFeatureById(feature: string) {
|
|
||||||
for (let i = 0; i < this.LABS_FEATURES.length; i++) {
|
|
||||||
const f = this.LABS_FEATURES[i];
|
|
||||||
if (f.id === feature) {
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
isFeatureEnabled: function(featureId: string): boolean {
|
isFeatureEnabled: function(featureId: string): boolean {
|
||||||
// Disable labs for guests.
|
const featuresConfig = SdkConfig.get()['features'];
|
||||||
if (MatrixClientPeg.get().isGuest()) return false;
|
|
||||||
|
|
||||||
const feature = this.getFeatureById(featureId);
|
let sdkConfigValue = 'labs';
|
||||||
if (!feature) {
|
if (featuresConfig && featuresConfig[featureId] !== undefined) {
|
||||||
console.warn(`Unknown feature "${featureId}"`);
|
sdkConfigValue = featuresConfig[featureId];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdkConfigValue === 'enable') {
|
||||||
|
return true;
|
||||||
|
} else if (sdkConfigValue === 'enable') {
|
||||||
|
return false;
|
||||||
|
} else if (sdkConfigValue === 'labs') {
|
||||||
|
if (!MatrixClientPeg.get().isGuest()) {
|
||||||
|
const userValue = localStorage.getItem(`mx_labs_feature_${featureId}`);
|
||||||
|
if (userValue !== null) {
|
||||||
|
return userValue === 'true';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
console.warn(`Unknown features config for ${featureId}: ${sdkConfigValue}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Return the default if this feature has an override to be the default value or
|
|
||||||
// if the feature has never been toggled and is therefore not in localStorage
|
|
||||||
if (Object.keys(feature).includes('override') ||
|
|
||||||
localStorage.getItem(`mx_labs_feature_${featureId}`) === null
|
|
||||||
) {
|
|
||||||
return feature.default;
|
|
||||||
}
|
|
||||||
return localStorage.getItem(`mx_labs_feature_${featureId}`) === 'true';
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setFeatureEnabled: function(featureId: string, enabled: boolean) {
|
setFeatureEnabled: function(featureId: string, enabled: boolean) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2017 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -250,7 +251,6 @@ export default React.createClass({
|
||||||
page_element = <UserSettings
|
page_element = <UserSettings
|
||||||
onClose={this.props.onUserSettingsClose}
|
onClose={this.props.onUserSettingsClose}
|
||||||
brand={this.props.config.brand}
|
brand={this.props.config.brand}
|
||||||
enableLabs={this.props.config.enableLabs}
|
|
||||||
referralBaseUrl={this.props.config.referralBaseUrl}
|
referralBaseUrl={this.props.config.referralBaseUrl}
|
||||||
teamToken={this.props.teamToken}
|
teamToken={this.props.teamToken}
|
||||||
/>;
|
/>;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
Copyright 2017 Vector Creations Ltd
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
Copyright 2017 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -212,9 +213,6 @@ module.exports = React.createClass({
|
||||||
// The brand string given when creating email pushers
|
// The brand string given when creating email pushers
|
||||||
brand: React.PropTypes.string,
|
brand: React.PropTypes.string,
|
||||||
|
|
||||||
// True to show the 'labs' section of experimental features
|
|
||||||
enableLabs: React.PropTypes.bool,
|
|
||||||
|
|
||||||
// The base URL to use in the referral link. Defaults to window.location.origin.
|
// The base URL to use in the referral link. Defaults to window.location.origin.
|
||||||
referralBaseUrl: React.PropTypes.string,
|
referralBaseUrl: React.PropTypes.string,
|
||||||
|
|
||||||
|
@ -226,7 +224,6 @@ module.exports = React.createClass({
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
onClose: function() {},
|
onClose: function() {},
|
||||||
enableLabs: true,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -923,34 +920,25 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
_renderLabs: function() {
|
_renderLabs: function() {
|
||||||
// default to enabled if undefined
|
|
||||||
if (this.props.enableLabs === false) return null;
|
|
||||||
UserSettingsStore.doTranslations();
|
|
||||||
|
|
||||||
const features = [];
|
const features = [];
|
||||||
UserSettingsStore.LABS_FEATURES.forEach((feature) => {
|
UserSettingsStore.getLabsFeatures().forEach((featureId) => {
|
||||||
// This feature has an override and will be set to the default, so do not
|
|
||||||
// show it here.
|
|
||||||
if (feature.override) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO: this ought to be a separate component so that we don't need
|
// TODO: this ought to be a separate component so that we don't need
|
||||||
// to rebind the onChange each time we render
|
// to rebind the onChange each time we render
|
||||||
const onChange = (e) => {
|
const onChange = (e) => {
|
||||||
UserSettingsStore.setFeatureEnabled(feature.id, e.target.checked);
|
UserSettingsStore.setFeatureEnabled(featureId, e.target.checked);
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
features.push(
|
features.push(
|
||||||
<div key={feature.id} className="mx_UserSettings_toggle">
|
<div key={featureId} className="mx_UserSettings_toggle">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id={feature.id}
|
id={featureId}
|
||||||
name={feature.id}
|
name={featureId}
|
||||||
defaultChecked={UserSettingsStore.isFeatureEnabled(feature.id)}
|
defaultChecked={UserSettingsStore.isFeatureEnabled(featureId)}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<label htmlFor={feature.id}>{ feature.name }</label>
|
<label htmlFor={featureId}>{ UserSettingsStore.translatedNameForFeature(featureId) }</label>
|
||||||
</div>);
|
</div>);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2017 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -128,15 +129,12 @@ module.exports = React.createClass({
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
let appsDrawer = null;
|
const appsDrawer = <AppsDrawer ref="appsDrawer"
|
||||||
if(UserSettingsStore.isFeatureEnabled('matrix_apps')) {
|
room={this.props.room}
|
||||||
appsDrawer = <AppsDrawer ref="appsDrawer"
|
userId={this.props.userId}
|
||||||
room={this.props.room}
|
maxHeight={this.props.maxHeight}
|
||||||
userId={this.props.userId}
|
showApps={this.props.showApps}
|
||||||
maxHeight={this.props.maxHeight}
|
/>;
|
||||||
showApps={this.props.showApps}
|
|
||||||
/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomView_auxPanel" style={{maxHeight: this.props.maxHeight}} >
|
<div className="mx_RoomView_auxPanel" style={{maxHeight: this.props.maxHeight}} >
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016 OpenMarket Ltd
|
||||||
|
Copyright 2017 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -285,18 +286,16 @@ export default class MessageComposer extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apps
|
// Apps
|
||||||
if (UserSettingsStore.isFeatureEnabled('matrix_apps')) {
|
if (this.props.showApps) {
|
||||||
if (this.props.showApps) {
|
hideAppsButton =
|
||||||
hideAppsButton =
|
<div key="controls_hide_apps" className="mx_MessageComposer_apps" onClick={this.onHideAppsClick} title={_t("Hide Apps")}>
|
||||||
<div key="controls_hide_apps" className="mx_MessageComposer_apps" onClick={this.onHideAppsClick} title={_t("Hide Apps")}>
|
<TintableSvg src="img/icons-hide-apps.svg" width="35" height="35" />
|
||||||
<TintableSvg src="img/icons-hide-apps.svg" width="35" height="35" />
|
</div>;
|
||||||
</div>;
|
} else {
|
||||||
} else {
|
showAppsButton =
|
||||||
showAppsButton =
|
<div key="show_apps" className="mx_MessageComposer_apps" onClick={this.onShowAppsClick} title={_t("Show Apps")}>
|
||||||
<div key="show_apps" className="mx_MessageComposer_apps" onClick={this.onShowAppsClick} title={_t("Show Apps")}>
|
<TintableSvg src="img/icons-show-apps.svg" width="35" height="35" />
|
||||||
<TintableSvg src="img/icons-show-apps.svg" width="35" height="35" />
|
</div>;
|
||||||
</div>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const canSendMessages = this.props.room.currentState.maySendMessage(
|
const canSendMessages = this.props.room.currentState.maySendMessage(
|
||||||
|
|
Loading…
Reference in a new issue