aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/settings
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2017-12-24 22:11:36 +0100
committerLibravatar Stefan Malzner <stefan@adlk.io>2017-12-24 22:11:36 +0100
commitdf44b69c4655415fe1e44689ece443ec06ef0f52 (patch)
treee677ed5f5328bb3b14bc976c7392d8e259f89034 /src/components/settings
parent[wip] add icon upload (diff)
parentMerge pull request #494 from heavypackets/websecurity-enable-patch (diff)
downloadferdium-app-df44b69c4655415fe1e44689ece443ec06ef0f52.tar.gz
ferdium-app-df44b69c4655415fe1e44689ece443ec06ef0f52.tar.zst
ferdium-app-df44b69c4655415fe1e44689ece443ec06ef0f52.zip
Merge branch 'develop' into feature/icon-upload
Diffstat (limited to 'src/components/settings')
-rw-r--r--src/components/settings/account/AccountDashboard.js49
-rw-r--r--src/components/settings/navigation/SettingsNavigation.js1
-rw-r--r--src/components/settings/recipes/RecipesDashboard.js57
-rw-r--r--src/components/settings/services/EditServiceForm.js79
-rw-r--r--src/components/settings/settings/EditSettingsForm.js38
5 files changed, 175 insertions, 49 deletions
diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js
index 75dbdef49..89fa07800 100644
--- a/src/components/settings/account/AccountDashboard.js
+++ b/src/components/settings/account/AccountDashboard.js
@@ -28,6 +28,10 @@ const messages = defineMessages({
28 id: 'settings.account.headlineInvoices', 28 id: 'settings.account.headlineInvoices',
29 defaultMessage: '!!Invoices', 29 defaultMessage: '!!Invoices',
30 }, 30 },
31 headlineDangerZone: {
32 id: 'settings.account.headlineDangerZone',
33 defaultMessage: '!!Danger Zone',
34 },
31 manageSubscriptionButtonLabel: { 35 manageSubscriptionButtonLabel: {
32 id: 'settings.account.manageSubscription.label', 36 id: 'settings.account.manageSubscription.label',
33 defaultMessage: '!!!Manage your subscription', 37 defaultMessage: '!!!Manage your subscription',
@@ -72,6 +76,18 @@ const messages = defineMessages({
72 id: 'settings.account.mining.cancel', 76 id: 'settings.account.mining.cancel',
73 defaultMessage: '!!!Cancel mining', 77 defaultMessage: '!!!Cancel mining',
74 }, 78 },
79 deleteAccount: {
80 id: 'settings.account.deleteAccount',
81 defaultMessage: '!!!Delete account',
82 },
83 deleteInfo: {
84 id: 'settings.account.deleteInfo',
85 defaultMessage: '!!!If you don\'t need your Franz account any longer, you can delete your account and all related data here.',
86 },
87 deleteEmailSent: {
88 id: 'settings.account.deleteEmailSent',
89 defaultMessage: '!!!You have received an email with a link to confirm your account deletion. Your account and data cannot be restored!',
90 },
75}); 91});
76 92
77@observer 93@observer
@@ -90,6 +106,9 @@ export default class AccountDashboard extends Component {
90 openExternalUrl: PropTypes.func.isRequired, 106 openExternalUrl: PropTypes.func.isRequired,
91 onCloseSubscriptionWindow: PropTypes.func.isRequired, 107 onCloseSubscriptionWindow: PropTypes.func.isRequired,
92 stopMiner: PropTypes.func.isRequired, 108 stopMiner: PropTypes.func.isRequired,
109 deleteAccount: PropTypes.func.isRequired,
110 isLoadingDeleteAccount: PropTypes.bool.isRequired,
111 isDeleteAccountSuccessful: PropTypes.bool.isRequired,
93 }; 112 };
94 113
95 static contextTypes = { 114 static contextTypes = {
@@ -111,6 +130,9 @@ export default class AccountDashboard extends Component {
111 retryUserInfoRequest, 130 retryUserInfoRequest,
112 onCloseSubscriptionWindow, 131 onCloseSubscriptionWindow,
113 stopMiner, 132 stopMiner,
133 deleteAccount,
134 isLoadingDeleteAccount,
135 isDeleteAccountSuccessful,
114 } = this.props; 136 } = this.props;
115 const { intl } = this.context; 137 const { intl } = this.context;
116 138
@@ -201,7 +223,7 @@ export default class AccountDashboard extends Component {
201 /> 223 />
202 </div> 224 </div>
203 </div> 225 </div>
204 <div className="account__box account__box--last"> 226 <div className="account__box">
205 <h2>{intl.formatMessage(messages.headlineInvoices)}</h2> 227 <h2>{intl.formatMessage(messages.headlineInvoices)}</h2>
206 <table className="invoices"> 228 <table className="invoices">
207 <tbody> 229 <tbody>
@@ -230,7 +252,7 @@ export default class AccountDashboard extends Component {
230 252
231 {user.isMiner && ( 253 {user.isMiner && (
232 <div className="account franz-form"> 254 <div className="account franz-form">
233 <div className="account__box"> 255 <div className="account__box account__box--last">
234 <h2>{intl.formatMessage(messages.headlineSubscription)}</h2> 256 <h2>{intl.formatMessage(messages.headlineSubscription)}</h2>
235 <div className="account__subscription"> 257 <div className="account__subscription">
236 <div> 258 <div>
@@ -267,7 +289,7 @@ export default class AccountDashboard extends Component {
267 <Loader /> 289 <Loader />
268 ) : ( 290 ) : (
269 <div className="account franz-form"> 291 <div className="account franz-form">
270 <div className="account__box account__box--last"> 292 <div className="account__box">
271 <h2>{intl.formatMessage(messages.headlineUpgrade)}</h2> 293 <h2>{intl.formatMessage(messages.headlineUpgrade)}</h2>
272 <SubscriptionForm 294 <SubscriptionForm
273 onCloseWindow={onCloseSubscriptionWindow} 295 onCloseWindow={onCloseSubscriptionWindow}
@@ -276,8 +298,29 @@ export default class AccountDashboard extends Component {
276 </div> 298 </div>
277 ) 299 )
278 )} 300 )}
301
302 <div className="account franz-form">
303 <div className="account__box">
304 <h2>{intl.formatMessage(messages.headlineDangerZone)}</h2>
305 {!isDeleteAccountSuccessful && (
306 <div className="account__subscription">
307 <p>{intl.formatMessage(messages.deleteInfo)}</p>
308 <Button
309 label={intl.formatMessage(messages.deleteAccount)}
310 buttonType="danger"
311 onClick={() => deleteAccount()}
312 loaded={!isLoadingDeleteAccount}
313 />
314 </div>
315 )}
316 {isDeleteAccountSuccessful && (
317 <p>{intl.formatMessage(messages.deleteEmailSent)}</p>
318 )}
319 </div>
320 </div>
279 </div> 321 </div>
280 )} 322 )}
323
281 </div> 324 </div>
282 <ReactTooltip place="right" type="dark" effect="solid" /> 325 <ReactTooltip place="right" type="dark" effect="solid" />
283 </div> 326 </div>
diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js
index 3b21a7765..fea8d682d 100644
--- a/src/components/settings/navigation/SettingsNavigation.js
+++ b/src/components/settings/navigation/SettingsNavigation.js
@@ -74,7 +74,6 @@ export default class SettingsNavigation extends Component {
74 <Link 74 <Link
75 to="/auth/logout" 75 to="/auth/logout"
76 className="settings-navigation__link" 76 className="settings-navigation__link"
77 activeClassName="is-active"
78 > 77 >
79 {intl.formatMessage(messages.logout)} 78 {intl.formatMessage(messages.logout)}
80 </Link> 79 </Link>
diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js
index 02ea04e35..b6ade5da4 100644
--- a/src/components/settings/recipes/RecipesDashboard.js
+++ b/src/components/settings/recipes/RecipesDashboard.js
@@ -9,6 +9,7 @@ import Infobox from '../../ui/Infobox';
9import RecipeItem from './RecipeItem'; 9import RecipeItem from './RecipeItem';
10import Loader from '../../ui/Loader'; 10import Loader from '../../ui/Loader';
11import Appear from '../../ui/effects/Appear'; 11import Appear from '../../ui/effects/Appear';
12import { FRANZ_SERVICE_REQUEST } from '../../../config';
12 13
13const messages = defineMessages({ 14const messages = defineMessages({
14 headline: { 15 headline: {
@@ -35,6 +36,10 @@ const messages = defineMessages({
35 id: 'settings.recipes.servicesSuccessfulAddedInfo', 36 id: 'settings.recipes.servicesSuccessfulAddedInfo',
36 defaultMessage: '!!!Service successfully added', 37 defaultMessage: '!!!Service successfully added',
37 }, 38 },
39 missingService: {
40 id: 'settings.recipes.missingService',
41 defaultMessage: '!!!Missing a service?',
42 },
38}); 43});
39 44
40@observer 45@observer
@@ -96,33 +101,39 @@ export default class RecipesDashboard extends Component {
96 </Infobox> 101 </Infobox>
97 </Appear> 102 </Appear>
98 )} 103 )}
99 {!searchNeedle && ( 104 {/* {!searchNeedle && ( */}
100 <div className="recipes__navigation"> 105 <div className="recipes__navigation">
101 <Link 106 <Link
102 to="/settings/recipes" 107 to="/settings/recipes"
103 className="badge" 108 className="badge"
104 activeClassName="badge--primary" 109 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`}
105 > 110 onClick={() => resetSearch()}
106 {intl.formatMessage(messages.mostPopularRecipes)} 111 >
107 </Link> 112 {intl.formatMessage(messages.mostPopularRecipes)}
113 </Link>
114 <Link
115 to="/settings/recipes/all"
116 className="badge"
117 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`}
118 onClick={() => resetSearch()}
119 >
120 {intl.formatMessage(messages.allRecipes)}
121 </Link>
122 {devRecipesCount > 0 && (
108 <Link 123 <Link
109 to="/settings/recipes/all" 124 to="/settings/recipes/dev"
110 className="badge" 125 className="badge"
111 activeClassName="badge--primary" 126 activeClassName={`${!searchNeedle ? 'badge--primary' : ''}`}
127 onClick={() => resetSearch()}
112 > 128 >
113 {intl.formatMessage(messages.allRecipes)} 129 {intl.formatMessage(messages.devRecipes)} ({devRecipesCount})
114 </Link> 130 </Link>
115 {devRecipesCount > 0 && ( 131 )}
116 <Link 132 <a href={FRANZ_SERVICE_REQUEST} target="_blank" className="link recipes__service-request">
117 to="/settings/recipes/dev" 133 {intl.formatMessage(messages.missingService)} <i className="mdi mdi-open-in-new" />
118 className="badge" 134 </a>
119 activeClassName="badge--primary" 135 </div>
120 > 136 {/* )} */}
121 {intl.formatMessage(messages.devRecipes)} ({devRecipesCount})
122 </Link>
123 )}
124 </div>
125 )}
126 {isLoading ? ( 137 {isLoading ? (
127 <Loader /> 138 <Loader />
128 ) : ( 139 ) : (
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index bcbda7773..ee69d53aa 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -48,6 +48,10 @@ const messages = defineMessages({
48 id: 'settings.service.form.tabOnPremise', 48 id: 'settings.service.form.tabOnPremise',
49 defaultMessage: '!!!Self hosted ⭐️', 49 defaultMessage: '!!!Self hosted ⭐️',
50 }, 50 },
51 useHostedService: {
52 id: 'settings.service.form.useHostedService',
53 defaultMessage: '!!!Use the hosted {name} service.',
54 },
51 customUrlValidationError: { 55 customUrlValidationError: {
52 id: 'settings.service.form.customUrlValidationError', 56 id: 'settings.service.form.customUrlValidationError',
53 defaultMessage: '!!!Could not validate custom {name} server.', 57 defaultMessage: '!!!Could not validate custom {name} server.',
@@ -68,6 +72,18 @@ const messages = defineMessages({
68 id: 'settings.service.form.isMutedInfo', 72 id: 'settings.service.form.isMutedInfo',
69 defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted', 73 defaultMessage: '!!!When disabled, all notification sounds and audio playback are muted',
70 }, 74 },
75 headlineNotifications: {
76 id: 'settings.service.form.headlineNotifications',
77 defaultMessage: '!!!Notifications',
78 },
79 headlineBadges: {
80 id: 'settings.service.form.headlineBadges',
81 defaultMessage: '!!!Unread message dadges',
82 },
83 headlineGeneral: {
84 id: 'settings.service.form.headlineGeneral',
85 defaultMessage: '!!!General',
86 },
71}); 87});
72 88
73@observer 89@observer
@@ -109,13 +125,12 @@ export default class EditServiceForm extends Component {
109 this.props.form.submit({ 125 this.props.form.submit({
110 onSuccess: async (form) => { 126 onSuccess: async (form) => {
111 const values = form.values(); 127 const values = form.values();
112
113 let isValid = true; 128 let isValid = true;
114 129
115 if (recipe.validateUrl && values.customUrl) { 130 if (recipe.validateUrl && values.customUrl) {
116 this.setState({ isValidatingCustomUrl: true }); 131 this.setState({ isValidatingCustomUrl: true });
117 try { 132 try {
118 values.customUrl = normalizeUrl(values.customUrl); 133 values.customUrl = normalizeUrl(values.customUrl, { stripWWW: false });
119 isValid = await recipe.validateUrl(values.customUrl); 134 isValid = await recipe.validateUrl(values.customUrl);
120 } catch (err) { 135 } catch (err) {
121 console.warn('ValidateURL', err); 136 console.warn('ValidateURL', err);
@@ -167,6 +182,13 @@ export default class EditServiceForm extends Component {
167 /> 182 />
168 ); 183 );
169 184
185 let activeTabIndex = 0;
186 if (recipe.hasHostedOption && service.team) {
187 activeTabIndex = 1;
188 } else if (recipe.hasHostedOption && service.customUrl) {
189 activeTabIndex = 2;
190 }
191
170 return ( 192 return (
171 <div className="settings__main"> 193 <div className="settings__main">
172 <div className="settings__header"> 194 <div className="settings__header">
@@ -207,11 +229,20 @@ export default class EditServiceForm extends Component {
207 </div> 229 </div>
208 {(recipe.hasTeamId || recipe.hasCustomUrl) && ( 230 {(recipe.hasTeamId || recipe.hasCustomUrl) && (
209 <Tabs 231 <Tabs
210 active={service.customUrl ? 1 : 0} 232 active={activeTabIndex}
211 > 233 >
234 {recipe.hasHostedOption && (
235 <TabItem title={recipe.name}>
236 {intl.formatMessage(messages.useHostedService, { name: recipe.name })}
237 </TabItem>
238 )}
212 {recipe.hasTeamId && ( 239 {recipe.hasTeamId && (
213 <TabItem title={intl.formatMessage(messages.tabHosted)}> 240 <TabItem title={intl.formatMessage(messages.tabHosted)}>
214 <Input field={form.$('team')} suffix={recipe.urlInputSuffix} /> 241 <Input
242 field={form.$('team')}
243 prefix={recipe.urlInputPrefix}
244 suffix={recipe.urlInputSuffix}
245 />
215 </TabItem> 246 </TabItem>
216 )} 247 )}
217 {recipe.hasCustomUrl && ( 248 {recipe.hasCustomUrl && (
@@ -240,20 +271,32 @@ export default class EditServiceForm extends Component {
240 </Tabs> 271 </Tabs>
241 )} 272 )}
242 <div className="settings__options"> 273 <div className="settings__options">
243 <Toggle field={form.$('isNotificationEnabled')} /> 274 <div className="settings__settings-group">
244 {recipe.hasIndirectMessages && ( 275 <h3>{intl.formatMessage(messages.headlineNotifications)}</h3>
245 <div> 276 <Toggle field={form.$('isNotificationEnabled')} />
246 <Toggle field={form.$('isIndirectMessageBadgeEnabled')} /> 277 <Toggle field={form.$('isMuted')} />
247 <p className="settings__help"> 278 <p className="settings__help">
248 {intl.formatMessage(messages.indirectMessageInfo)} 279 {intl.formatMessage(messages.isMutedInfo)}
249 </p> 280 </p>
250 </div> 281 </div>
251 )} 282
252 <Toggle field={form.$('isMuted')} /> 283 <div className="settings__settings-group">
253 <p className="settings__help"> 284 <h3>{intl.formatMessage(messages.headlineBadges)}</h3>
254 {intl.formatMessage(messages.isMutedInfo)} 285 <Toggle field={form.$('isBadgeEnabled')} />
255 </p> 286 {recipe.hasIndirectMessages && form.$('isBadgeEnabled').value && (
256 <Toggle field={form.$('isEnabled')} /> 287 <div>
288 <Toggle field={form.$('isIndirectMessageBadgeEnabled')} />
289 <p className="settings__help">
290 {intl.formatMessage(messages.indirectMessageInfo)}
291 </p>
292 </div>
293 )}
294 </div>
295
296 <div className="settings__settings-group">
297 <h3>{intl.formatMessage(messages.headlineGeneral)}</h3>
298 <Toggle field={form.$('isEnabled')} />
299 </div>
257 </div> 300 </div>
258 {recipe.message && ( 301 {recipe.message && (
259 <p className="settings__message"> 302 <p className="settings__message">
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index ba07b1a5b..ff398aa33 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -9,6 +9,8 @@ import Button from '../../ui/Button';
9import Toggle from '../../ui/Toggle'; 9import Toggle from '../../ui/Toggle';
10import Select from '../../ui/Select'; 10import Select from '../../ui/Select';
11 11
12import { FRANZ_TRANSLATION } from '../../../config';
13
12const messages = defineMessages({ 14const messages = defineMessages({
13 headline: { 15 headline: {
14 id: 'settings.app.headline', 16 id: 'settings.app.headline',
@@ -30,6 +32,14 @@ const messages = defineMessages({
30 id: 'settings.app.headlineAppearance', 32 id: 'settings.app.headlineAppearance',
31 defaultMessage: '!!!Appearance', 33 defaultMessage: '!!!Appearance',
32 }, 34 },
35 headlineAdvanced: {
36 id: 'settings.app.headlineAdvanced',
37 defaultMessage: '!!!Advanced',
38 },
39 translationHelp: {
40 id: 'settings.app.translationHelp',
41 defaultMessage: '!!!Help us to translate Franz into your language.',
42 },
33 buttonSearchForUpdate: { 43 buttonSearchForUpdate: {
34 id: 'settings.app.buttonSearchForUpdate', 44 id: 'settings.app.buttonSearchForUpdate',
35 defaultMessage: '!!!Check for updates', 45 defaultMessage: '!!!Check for updates',
@@ -116,18 +126,38 @@ export default class EditSettingsForm extends Component {
116 onChange={e => this.submit(e)} 126 onChange={e => this.submit(e)}
117 id="form" 127 id="form"
118 > 128 >
119 <h2>{intl.formatMessage(messages.headlineGeneral)}</h2> 129 {/* General */}
130 <h2 id="general">{intl.formatMessage(messages.headlineGeneral)}</h2>
120 <Toggle field={form.$('autoLaunchOnStart')} /> 131 <Toggle field={form.$('autoLaunchOnStart')} />
121 <Toggle field={form.$('runInBackground')} /> 132 <Toggle field={form.$('runInBackground')} />
122 <Toggle field={form.$('enableSystemTray')} /> 133 <Toggle field={form.$('enableSystemTray')} />
123 {process.platform === 'win32' && ( 134 {process.platform === 'win32' && (
124 <Toggle field={form.$('minimizeToSystemTray')} /> 135 <Toggle field={form.$('minimizeToSystemTray')} />
125 )} 136 )}
126 <h2>{intl.formatMessage(messages.headlineAppearance)}</h2> 137
138 {/* Appearance */}
139 <h2 id="apperance">{intl.formatMessage(messages.headlineAppearance)}</h2>
127 <Toggle field={form.$('showDisabledServices')} /> 140 <Toggle field={form.$('showDisabledServices')} />
128 <h2>{intl.formatMessage(messages.headlineLanguage)}</h2> 141 <Toggle field={form.$('showMessageBadgeWhenMuted')} />
142
143 {/* Language */}
144 <h2 id="language">{intl.formatMessage(messages.headlineLanguage)}</h2>
129 <Select field={form.$('locale')} showLabel={false} /> 145 <Select field={form.$('locale')} showLabel={false} />
130 <h2>{intl.formatMessage(messages.headlineUpdates)}</h2> 146 <a
147 href={FRANZ_TRANSLATION}
148 target="_blank"
149 className="link"
150 >
151 {intl.formatMessage(messages.translationHelp)} <i className="mdi mdi-open-in-new" />
152 </a>
153
154 {/* Advanced */}
155 <h2 id="advanced">{intl.formatMessage(messages.headlineAdvanced)}</h2>
156 <Toggle field={form.$('enableSpellchecking')} />
157 {/* <Select field={form.$('spellcheckingLanguage')} /> */}
158
159 {/* Updates */}
160 <h2 id="updates">{intl.formatMessage(messages.headlineUpdates)}</h2>
131 {updateIsReadyToInstall ? ( 161 {updateIsReadyToInstall ? (
132 <Button 162 <Button
133 label={intl.formatMessage(messages.buttonInstallUpdate)} 163 label={intl.formatMessage(messages.buttonInstallUpdate)}