Skip to content

Commit 6297274

Browse files
committed
feat(App): Add proxy support for services
1 parent 55ea36b commit 6297274

File tree

27 files changed

+381
-112
lines changed

27 files changed

+381
-112
lines changed

src/api/LocalApi.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ export default class LocalApi {
44
this.local = local;
55
}
66

7-
getAppSettings() {
8-
return this.local.getAppSettings();
7+
getAppSettings(type) {
8+
return this.local.getAppSettings(type);
99
}
1010

11-
updateAppSettings(data) {
12-
return this.local.updateAppSettings(data);
11+
updateAppSettings(type, data) {
12+
return this.local.updateAppSettings(type, data);
1313
}
1414

1515
getAppCacheSize() {

src/api/server/LocalApi.js

+11-8
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,23 @@ const { session } = remote;
99

1010
export default class LocalApi {
1111
// Settings
12-
getAppSettings() {
12+
getAppSettings(type) {
1313
return new Promise((resolve) => {
14-
ipcRenderer.once('appSettings', (event, data) => {
15-
debug('LocalApi::getAppSettings resolves', data);
16-
resolve(data);
14+
ipcRenderer.once('appSettings', (event, resp) => {
15+
debug('LocalApi::getAppSettings resolves', resp.type, resp.data);
16+
resolve(resp);
1717
});
1818

19-
ipcRenderer.send('getAppSettings');
19+
ipcRenderer.send('getAppSettings', type);
2020
});
2121
}
2222

23-
async updateAppSettings(data) {
24-
debug('LocalApi::updateAppSettings resolves', data);
25-
ipcRenderer.send('updateAppSettings', data);
23+
async updateAppSettings(type, data) {
24+
debug('LocalApi::updateAppSettings resolves', type, data);
25+
ipcRenderer.send('updateAppSettings', {
26+
type,
27+
data,
28+
});
2629
}
2730

2831
// Services

src/components/settings/account/AccountDashboard.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,9 @@ export default @observer class AccountDashboard extends Component {
180180
<span className="badge badge--success">{intl.formatMessage(messages.accountTypeEnterprise)}</span>
181181
)}
182182
</div>
183-
{!user.isSSO && (
184-
<Link to="/settings/user/edit" className="button">
185-
{intl.formatMessage(messages.accountEditButton)}
186-
</Link>
187-
)}
183+
<Link to="/settings/user/edit" className="button">
184+
{intl.formatMessage(messages.accountEditButton)}
185+
</Link>
188186
{user.emailValidated}
189187
</div>
190188
</div>

src/components/settings/navigation/SettingsNavigation.js

+7-18
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,17 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
4343

4444
render() {
4545
const { serviceCount } = this.props;
46-
const { features } = this.props.stores.features;
4746
const { intl } = this.context;
4847

4948
return (
5049
<div className="settings-navigation">
51-
{features.userCanManageServices && (
52-
<Link
53-
to="/settings/recipes"
54-
className="settings-navigation__link"
55-
activeClassName="is-active"
56-
>
57-
{intl.formatMessage(messages.availableServices)}
58-
</Link>
59-
)}
50+
<Link
51+
to="/settings/recipes"
52+
className="settings-navigation__link"
53+
activeClassName="is-active"
54+
>
55+
{intl.formatMessage(messages.availableServices)}
56+
</Link>
6057
<Link
6158
to="/settings/services"
6259
className="settings-navigation__link"
@@ -97,11 +94,3 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp
9794
}
9895
}
9996

100-
SettingsNavigation.wrappedComponent.propTypes = {
101-
stores: PropTypes.shape({
102-
features: PropTypes.shape({
103-
features: PropTypes.object.isRequired,
104-
}).isRequired,
105-
}).isRequired,
106-
};
107-

src/components/settings/services/EditServiceForm.js

+42-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import Toggle from '../../ui/Toggle';
1515
import Button from '../../ui/Button';
1616
import ImageUpload from '../../ui/ImageUpload';
1717

18+
import PremiumFeatureContainer from '../../ui/PremiumFeatureContainer';
19+
1820
const messages = defineMessages({
1921
saveService: {
2022
id: 'settings.service.form.saveButton',
@@ -92,6 +94,14 @@ const messages = defineMessages({
9294
id: 'settings.service.form.iconUpload',
9395
defaultMessage: '!!!Drop your image, or click here',
9496
},
97+
headlineProxy: {
98+
id: 'settings.service.form.proxy.headline',
99+
defaultMessage: '!!!Proxy Settings',
100+
},
101+
proxyInfo: {
102+
id: 'settings.service.form.proxy.info',
103+
defaultMessage: '!!!Proxy settings will not be synchronized with the Franz servers.',
104+
},
95105
});
96106

97107
export default @observer class EditServiceForm extends Component {
@@ -106,13 +116,14 @@ export default @observer class EditServiceForm extends Component {
106116
return null;
107117
},
108118
user: PropTypes.instanceOf(User).isRequired,
109-
userCanManageServices: PropTypes.bool.isRequired,
110119
action: PropTypes.string.isRequired,
111120
form: PropTypes.instanceOf(Form).isRequired,
112121
onSubmit: PropTypes.func.isRequired,
113122
onDelete: PropTypes.func.isRequired,
114123
isSaving: PropTypes.bool.isRequired,
115124
isDeleting: PropTypes.bool.isRequired,
125+
isProxyFeatureEnabled: PropTypes.bool.isRequired,
126+
isProxyFeaturePremiumFeature: PropTypes.bool.isRequired,
116127
};
117128

118129
static defaultProps = {
@@ -169,11 +180,12 @@ export default @observer class EditServiceForm extends Component {
169180
service,
170181
action,
171182
user,
172-
userCanManageServices,
173183
form,
174184
isSaving,
175185
isDeleting,
176186
onDelete,
187+
isProxyFeatureEnabled,
188+
isProxyFeaturePremiumFeature,
177189
} = this.props;
178190
const { intl } = this.context;
179191

@@ -318,6 +330,33 @@ export default @observer class EditServiceForm extends Component {
318330
/>
319331
</div>
320332
</div>
333+
334+
{isProxyFeatureEnabled && (
335+
<PremiumFeatureContainer condition={isProxyFeaturePremiumFeature}>
336+
<div className="settings__settings-group">
337+
<h3>
338+
{intl.formatMessage(messages.headlineProxy)}
339+
<span className="badge badge--success">beta</span>
340+
</h3>
341+
<Toggle field={form.$('proxy.isEnabled')} />
342+
{form.$('proxy.isEnabled').value && (
343+
<div>
344+
<Input field={form.$('proxy.host')} />
345+
<Input field={form.$('proxy.user')} />
346+
<Input
347+
field={form.$('proxy.password')}
348+
showPasswordToggle
349+
/>
350+
<p>
351+
<span className="mdi mdi-information" />
352+
{intl.formatMessage(messages.proxyInfo)}
353+
</p>
354+
</div>
355+
)}
356+
</div>
357+
</PremiumFeatureContainer>
358+
)}
359+
321360
{recipe.message && (
322361
<p className="settings__message">
323362
<span className="mdi mdi-information" />
@@ -328,7 +367,7 @@ export default @observer class EditServiceForm extends Component {
328367
</div>
329368
<div className="settings__controls">
330369
{/* Delete Button */}
331-
{action === 'edit' && userCanManageServices && deleteButton}
370+
{action === 'edit' && deleteButton}
332371

333372
{/* Save Button */}
334373
{isSaving || isValidatingCustomUrl ? (

src/components/settings/settings/EditSettingsForm.js

+8-12
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ export default @observer class EditSettingsForm extends Component {
9696
isClearingAllCache: PropTypes.bool.isRequired,
9797
onClearAllCache: PropTypes.func.isRequired,
9898
cacheSize: PropTypes.string.isRequired,
99-
isPremiumUser: PropTypes.bool.isRequired,
10099
isSpellcheckerPremiumFeature: PropTypes.bool.isRequired,
101100
};
102101

@@ -127,7 +126,6 @@ export default @observer class EditSettingsForm extends Component {
127126
isClearingAllCache,
128127
onClearAllCache,
129128
cacheSize,
130-
isPremiumUser,
131129
isSpellcheckerPremiumFeature,
132130
} = this.props;
133131
const { intl } = this.context;
@@ -180,16 +178,14 @@ export default @observer class EditSettingsForm extends Component {
180178

181179
{/* Advanced */}
182180
<h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2>
183-
{!isPremiumUser && isSpellcheckerPremiumFeature ? (
184-
<PremiumFeatureContainer>
185-
<Toggle
186-
field={form.$('enableSpellchecking')}
187-
disabled
188-
/>
189-
</PremiumFeatureContainer>
190-
) : (
191-
<Toggle field={form.$('enableSpellchecking')} />
192-
)}
181+
<PremiumFeatureContainer
182+
condition={isSpellcheckerPremiumFeature}
183+
>
184+
<Toggle
185+
field={form.$('enableSpellchecking')}
186+
disabled
187+
/>
188+
</PremiumFeatureContainer>
193189
<Toggle field={form.$('enableGPUAcceleration')} />
194190
<p className="settings__help">{intl.formatMessage(messages.enableGPUAccelerationInfo)}</p>
195191
{/* <Select field={form.$('spellcheckingLanguage')} /> */}

src/components/subscription/SubscriptionForm.js

-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ const messages = defineMessages({
4040
id: 'subscription.features.onpremise.mattermost',
4141
defaultMessage: '!!!Add on-premise/hosted services like Mattermost',
4242
},
43-
encryptedSync: {
44-
id: 'subscription.features.encryptedSync',
45-
defaultMessage: '!!!Encrypted session synchronization',
4643
noInterruptions: {
4744
id: 'subscription.features.noInterruptions',
4845
defaultMessage: '!!!No app delays & nagging to upgrade license',

src/components/ui/PremiumFeatureContainer/index.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import injectSheet from 'react-jss';
66

77
import { oneOrManyChildElements } from '../../../prop-types';
88

9+
import UserStore from '../../../stores/UserStore';
10+
911
import styles from './styles';
1012

1113
const messages = defineMessages({
@@ -15,9 +17,14 @@ const messages = defineMessages({
1517
},
1618
});
1719

18-
export default @inject('actions') @injectSheet(styles) @observer class PremiumFeatureContainer extends Component {
20+
export default @inject('stores', 'actions') @injectSheet(styles) @observer class PremiumFeatureContainer extends Component {
1921
static propTypes = {
2022
classes: PropTypes.object.isRequired,
23+
condition: PropTypes.bool,
24+
};
25+
26+
static defaultProps = {
27+
condition: true,
2128
};
2229

2330
static contextTypes = {
@@ -29,11 +36,13 @@ export default @inject('actions') @injectSheet(styles) @observer class PremiumFe
2936
classes,
3037
children,
3138
actions,
39+
condition,
40+
stores,
3241
} = this.props;
3342

3443
const { intl } = this.context;
3544

36-
return (
45+
return !stores.user.data.isPremium && !!condition ? (
3746
<div className={classes.container}>
3847
<div className={classes.titleContainer}>
3948
<p className={classes.title}>Premium Feature</p>
@@ -49,12 +58,15 @@ export default @inject('actions') @injectSheet(styles) @observer class PremiumFe
4958
{children}
5059
</div>
5160
</div>
52-
);
61+
) : children;
5362
}
5463
}
5564

5665
PremiumFeatureContainer.wrappedComponent.propTypes = {
5766
children: oneOrManyChildElements.isRequired,
67+
stores: PropTypes.shape({
68+
user: PropTypes.instanceOf(UserStore).isRequired,
69+
}).isRequired,
5870
actions: PropTypes.shape({
5971
ui: PropTypes.shape({
6072
openSettings: PropTypes.func.isRequired,

src/config.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ export const DEFAULT_APP_SETTINGS = {
2929
export const FRANZ_SERVICE_REQUEST = 'https://bit.ly/franz-service-request';
3030
export const FRANZ_TRANSLATION = 'https://bit.ly/franz-translate';
3131

32-
export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config', 'settings.json');
32+
export const FILE_SYSTEM_SETTINGS_TYPES = [
33+
'app',
34+
'proxy',
35+
];
36+
37+
export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config');

0 commit comments

Comments
 (0)