Skip to content

Commit

Permalink
Merge pull request #713 from meetfranz/develop
Browse files Browse the repository at this point in the history
Beta 16
  • Loading branch information
adlk authored Feb 23, 2018
2 parents a4b665e + 2c7f650 commit f234292
Show file tree
Hide file tree
Showing 73 changed files with 824 additions and 1,067 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
<a name="5.0.0-beta.16"></a>
# [5.0.0-beta.16](https://github.com/meetfranz/franz/compare/v5.0.0-beta.15...v5.0.0-beta.16) (2018-02-23)

### General
* **App:** Update Electron version to 1.7.12 (fixes critical security vulnerability CVE-2018–1000006 ) ([c67d7d1](https://github.com/meetfranz/franz/commit/c67d7d1))

### Features
* **App:** Invite Friends in Settings ([ab33c44](https://github.com/meetfranz/franz/commit/ab33c44))

### Bug Fixes

* **App:** Fix memory leak in recipe polling loop ([c99848f](https://github.com/meetfranz/franz/commit/c99848f))
* **App:** Fix validation for side-by-side teamId & customURL ([bd51150](https://github.com/meetfranz/franz/commit/bd51150))
* **App:** Reload Franz instead of all services one by one on sleep resume ([4e5f7af](https://github.com/meetfranz/franz/commit/4e5f7af))
* **App:** Fix toggle buttons shown during import ([1220e2c](https://github.com/meetfranz/franz/commit/1220e2c))
fix(App): Bugfix Fix memory leak in recipe polling loop
* **App:** Fix invite screen [object Object] values ([81c4e99](https://github.com/meetfranz/franz/commit/81c4e99))
* **App:** Fix Franz-wide form validation ([7618f51](https://github.com/meetfranz/franz/commit/7618f51))
* **App:** Fix service tooltips not initialized properly ([8765b8f](https://github.com/meetfranz/franz/commit/8765b8f))
* **Linux:** Invert tray icon color & add border for bright UI's ([0de9c60](https://github.com/meetfranz/franz/commit/0de9c60))
* **Translations:** Improved translations. **[A million thanks to the amazing community. 🎉](http://i18n.meetfranz.com/)**



<a name="5.0.0-beta.15"></a>
# [5.0.0-beta.15](https://github.com/meetfranz/franz/compare/v5.0.0-beta.14...v5.0.0-beta.15) (2018-01-10)

Expand Down
Binary file modified build-helpers/images/icon.ico
Binary file not shown.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "franz",
"productName": "Franz",
"appId": "com.meetfranz.franz",
"version": "5.0.0-beta.15",
"version": "5.0.0-beta.16",
"description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.",
"copyright": "adlk x franz - Stefan Malzner",
"main": "index.js",
Expand All @@ -28,7 +28,6 @@
"license": "Apache-2.0",
"dependencies": {
"@meetfranz/electron-notification-state": "^1.0.0",
"@paulcbetts/system-idle-time": "^1.0.4",
"address-rfc2822": "^2.0.1",
"auto-launch": "https://github.com/meetfranz/node-auto-launch.git",
"babel-polyfill": "^6.23.0",
Expand All @@ -50,6 +49,7 @@
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"mobx": "^3.1.0",
"mobx-localstorage": "^0.1.7",
"mobx-react": "^4.1.0",
"mobx-react-form": "^1.32.2",
"mobx-react-router": "^3.1.2",
Expand Down Expand Up @@ -91,7 +91,7 @@
"cz-conventional-changelog": "^2.0.0",
"del": "^2.2.2",
"dotenv": "^4.0.0",
"electron": "^1.7.9",
"electron": "^1.7.12",
"electron-builder": "19.15.1",
"electron-packager": "^8.7.0",
"electron-rebuild": "^1.6.0",
Expand Down
12 changes: 0 additions & 12 deletions src/api/LocalApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@ export default class LocalApi {
this.local = local;
}

getSettings() {
return this.local.getAppSettings();
}

updateSettings(data) {
return this.local.updateAppSettings(data);
}

removeKey(key) {
return this.local.removeKey(key);
}

getAppCacheSize() {
return this.local.getAppCacheSize();
}
Expand Down
32 changes: 0 additions & 32 deletions src/api/server/LocalApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,6 @@ import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js'
const { session } = remote;

export default class LocalApi {
// App
async updateAppSettings(data) {
const currentSettings = await this.getAppSettings();
const settings = Object.assign(currentSettings, data);

localStorage.setItem('app', JSON.stringify(settings));
console.debug('LocalApi::updateAppSettings resolves', settings);

return settings;
}

async getAppSettings() {
const settingsString = localStorage.getItem('app');
try {
const settings = JSON.parse(settingsString) || {};
console.debug('LocalApi::getAppSettings resolves', settings);

return settings;
} catch (err) {
return {};
}
}

async removeKey(key) {
const settings = await this.getAppSettings();

if (Object.hasOwnProperty.call(settings, key)) {
delete settings[key];
localStorage.setItem('app', JSON.stringify(settings));
}
}

// Services
async getAppCacheSize() {
const partitionsDir = getServicePartitionsDirectory();
Expand Down
1 change: 1 addition & 0 deletions src/api/server/ServerApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path';
import tar from 'tar';
import fs from 'fs-extra';
import { remote } from 'electron';
import localStorage from 'mobx-localstorage';

import ServiceModel from '../../models/Service';
import RecipePreviewModel from '../../models/RecipePreview';
Expand Down
4 changes: 3 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import EditServiceScreen from './containers/settings/EditServiceScreen';
import AccountScreen from './containers/settings/AccountScreen';
import EditUserScreen from './containers/settings/EditUserScreen';
import EditSettingsScreen from './containers/settings/EditSettingsScreen';
import InviteSettingsScreen from './containers/settings/InviteScreen';
import WelcomeScreen from './containers/auth/WelcomeScreen';
import LoginScreen from './containers/auth/LoginScreen';
import PasswordScreen from './containers/auth/PasswordScreen';
Expand All @@ -35,7 +36,7 @@ import ImportScreen from './containers/auth/ImportScreen';
import PricingScreen from './containers/auth/PricingScreen';
import InviteScreen from './containers/auth/InviteScreen';
import AuthLayoutContainer from './containers/auth/AuthLayoutContainer';
import SubscriptionPopupScreen from './containers/ui/SubscriptionPopupScreen';
import SubscriptionPopupScreen from './containers/subscription/SubscriptionPopupScreen';

// Add Polyfills
smoothScroll.polyfill();
Expand Down Expand Up @@ -74,6 +75,7 @@ window.addEventListener('load', () => {
<Route path="/settings/user" component={AccountScreen} />
<Route path="/settings/user/edit" component={EditUserScreen} />
<Route path="/settings/app" component={EditSettingsScreen} />
<Route path="/settings/invite" component={InviteSettingsScreen} />
</Route>
</Route>
<Route path="/auth" component={AuthLayoutContainer}>
Expand Down
Binary file modified src/assets/images/tray/linux/tray-unread.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/tray/linux/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/tray/linux/tray.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/tray/linux/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 8 additions & 9 deletions src/components/auth/Import.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ export default class Import extends Component {
intl: intlShape,
};

prepareForm() {
const { services } = this.props;

componentWillMount() {
const config = {
fields: {
import: [...services.filter(s => s.recipe).map(s => ({
add: {
default: true,
options: s,
import: [...this.props.services.filter(s => s.recipe).map(s => ({
fields: {
add: {
default: true,
options: s,
},
},
}))],
},
};

return new Form(config, this.context.intl);
this.form = new Form(config, this.context.intl);
}

submit(e) {
Expand All @@ -74,7 +74,6 @@ export default class Import extends Component {
}

render() {
this.form = this.prepareForm();
const { intl } = this.context;
const { services, isSubmitting, inviteRoute } = this.props;

Expand Down
128 changes: 103 additions & 25 deletions src/components/auth/Invite.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ import PropTypes from 'prop-types';
import { observer } from 'mobx-react';
import { defineMessages, intlShape } from 'react-intl';
import { Link } from 'react-router';
import classnames from 'classnames';

import Infobox from '../ui/Infobox';
import Appear from '../ui/effects/Appear';
import Form from '../../lib/Form';
import { email } from '../../helpers/validation-helpers';
import Input from '../ui/Input';
import Button from '../ui/Button';

const messages = defineMessages({
settingsHeadline: {
id: 'settings.invite.headline',
defaultMessage: '!!!Invite Friends',
},
headline: {
id: 'invite.headline.friends',
defaultMessage: '!!!Invite 3 of your friends or colleagues',
Expand All @@ -30,41 +37,77 @@ const messages = defineMessages({
id: 'invite.skip.label',
defaultMessage: '!!!I want to do this later',
},
inviteSuccessInfo: {
id: 'invite.successInfo',
defaultMessage: '!!!Invitations sent successfully',
},
});

@observer
export default class Invite extends Component {
static propTypes = {
onSubmit: PropTypes.func.isRequired,
embed: PropTypes.bool,
isInviteSuccessful: PropTypes.bool,
isLoadingInvite: PropTypes.bool,
};

static defaultProps = {
embed: false,
isInviteSuccessful: false,
isLoadingInvite: false,
};

static contextTypes = {
intl: intlShape,
};

form = new Form({
fields: {
invite: [...Array(3).fill({
name: {
label: this.context.intl.formatMessage(messages.nameLabel),
// value: '',
placeholder: this.context.intl.formatMessage(messages.nameLabel),
},
email: {
label: this.context.intl.formatMessage(messages.emailLabel),
// value: '',
validate: [email],
placeholder: this.context.intl.formatMessage(messages.emailLabel),
},
})],
},
}, this.context.intl);
state = { showSuccessInfo: false };

componentWillMount() {
const handlers = {
onChange: () => {
this.setState({ showSuccessInfo: false });
},
};

this.form = new Form({
fields: {
invite: [...Array(3).fill({
fields: {
name: {
label: this.context.intl.formatMessage(messages.nameLabel),
placeholder: this.context.intl.formatMessage(messages.nameLabel),
handlers,
// related: ['invite.0.email'], // path accepted but does not work
},
email: {
label: this.context.intl.formatMessage(messages.emailLabel),
placeholder: this.context.intl.formatMessage(messages.emailLabel),
handlers,
validators: [email],
},
},
})],
},
}, this.context.intl);
}

componentDidMount() {
document.querySelector('input:first-child').focus();
}

submit(e) {
e.preventDefault();

this.form.submit({
onSuccess: (form) => {
this.props.onSubmit({ invites: form.values().invite });

this.form.clear();
// this.form.$('invite.0.name').focus(); // path accepted but does not focus ;(
document.querySelector('input:first-child').focus();
this.setState({ showSuccessInfo: true });
},
onError: () => {},
});
Expand All @@ -73,16 +116,38 @@ export default class Invite extends Component {
render() {
const { form } = this;
const { intl } = this.context;
const { embed, isInviteSuccessful, isLoadingInvite } = this.props;

const atLeastOneEmailAddress = form.$('invite')
.map(invite => invite.$('email').value)
.some(emailValue => emailValue.trim() !== '');

const sendButtonClassName = classnames({
auth__button: true,
'invite__embed--button': embed,
});

const renderForm = (
<div>
{this.state.showSuccessInfo && isInviteSuccessful && (
<Appear>
<Infobox
type="success"
icon="checkbox-marked-circle-outline"
dismissable
>
{intl.formatMessage(messages.inviteSuccessInfo)}
</Infobox>
</Appear>
)}

return (
<div className="auth__container auth__container--signup">
<form className="franz-form auth__form" onSubmit={e => this.submit(e)}>
<img
{!embed && (<img
src="./assets/images/logo.svg"
className="auth__logo"
alt=""
/>
<h1>
/>)}
<h1 className={embed && 'invite__embed'}>
{intl.formatMessage(messages.headline)}
</h1>
{form.$('invite').map(invite => (
Expand All @@ -95,17 +160,30 @@ export default class Invite extends Component {
))}
<Button
type="submit"
className="auth__button"
className={sendButtonClassName}
disabled={!atLeastOneEmailAddress}
label={intl.formatMessage(messages.submitButtonLabel)}
loaded={!isLoadingInvite}
/>
<Link
{!embed && (<Link
to="/"
className="franz-form__button franz-form__button--secondary auth__button auth__button--skip"
>
{intl.formatMessage(messages.skipButtonLabel)}
</Link>
</Link>)}
</form>
</div>
);

return (
<div className={!embed ? 'auth__container auth__container--signup' : 'settings__main'}>
{embed && (
<div className="settings__header">
<h1>{this.context.intl.formatMessage(messages.settingsHeadline)}</h1>
</div>
)}
{!embed ? <div>{renderForm}</div> : <div className="settings__body invite__form">{renderForm}</div>}
</div>
);
}
}
4 changes: 2 additions & 2 deletions src/components/auth/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ export default class Login extends Component {
email: {
label: this.context.intl.formatMessage(messages.emailLabel),
value: '',
validate: [required, email],
validators: [required, email],
},
password: {
label: this.context.intl.formatMessage(messages.passwordLabel),
value: '',
validate: [required],
validators: [required],
type: 'password',
},
},
Expand Down
Loading

0 comments on commit f234292

Please sign in to comment.