Permalink
Browse files

feat(App): Add option to mute all services in sidebar

Closes #8 #162
  • Loading branch information...
adlk committed Nov 10, 2017
1 parent b405ba1 commit f5a9aa21e2ab958f60c143668f4836bc47e2b539
@@ -20,4 +20,8 @@ export default {
resetUpdateStatus: {},
installUpdate: {},
healthCheck: {},
muteApp: {
isMuted: PropTypes.bool.isRequired,
},
toggleMuteApp: {},
};
@@ -71,6 +71,9 @@ export default {
toggleNotifications: {
serviceId: PropTypes.string.isRequired,
},
toggleAudio: {
serviceId: PropTypes.string.isRequired,
},
openDevTools: {
serviceId: PropTypes.string.isRequired,
},
@@ -11,16 +11,25 @@ const messages = defineMessages({
id: 'sidebar.settings',
defaultMessage: '!!!Settings',
},
addNewService: {
id: 'sidebar.addNewService',
defaultMessage: '!!!Add new service',
},
mute: {
id: 'sidebar.mute',
defaultMessage: '!!!Disable audio',
},
unmute: {
id: 'sidebar.unmute',
defaultMessage: '!!!Enable audio',
},
});
export default class Sidebar extends Component {
static propTypes = {
openSettings: PropTypes.func.isRequired,
isPremiumUser: PropTypes.bool,
}
static defaultProps = {
isPremiumUser: false,
toggleMuteApp: PropTypes.func.isRequired,
isAppMuted: PropTypes.bool.isRequired,
}
static contextTypes = {
@@ -40,8 +49,9 @@ export default class Sidebar extends Component {
}
render() {
const { openSettings, isPremiumUser } = this.props;
const { openSettings, toggleMuteApp, isAppMuted } = this.props;
const { intl } = this.context;
return (
<div className="sidebar">
<Tabbar
@@ -50,21 +60,25 @@ export default class Sidebar extends Component {
disableToolTip={() => this.disableToolTip()}
/>
<button
onClick={openSettings}
className="sidebar__settings-button"
onClick={toggleMuteApp}
className={`sidebar__button ${isAppMuted ? 'is-muted' : ''}`}
data-tip={`${intl.formatMessage(isAppMuted ? messages.unmute : messages.mute)} (${ctrlKey}+Shift+M)`}
>
<i className={`mdi mdi-bell${isAppMuted ? '-off' : ''}`} />
</button>
<button
onClick={() => openSettings({ path: 'recipes' })}
className="sidebar__button"
data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`}
>
<i className="mdi mdi-plus-box" />
</button>
<button
onClick={() => openSettings({ path: 'app' })}
className="sidebar__button"
data-tip={`${intl.formatMessage(messages.settings)} (${ctrlKey}+,)`}
>
{isPremiumUser && (
<span className="emoji">
<img src="./assets/images/emoji/star.png" alt="" />
</span>
)}
<img
src="./assets/images/logo.svg"
className="sidebar__logo"
alt=""
/>
{intl.formatMessage(messages.settings)}
<i className="mdi mdi-settings" />
</button>
{this.state.tooltipEnabled && (
<ReactTooltip place="right" type="dark" effect="solid" />
@@ -15,6 +15,7 @@ export default class ServiceWebview extends Component {
service: PropTypes.instanceOf(ServiceModel).isRequired,
setWebviewReference: PropTypes.func.isRequired,
reload: PropTypes.func.isRequired,
isAppMuted: PropTypes.bool.isRequired,
};
static defaultProps = {
@@ -56,6 +57,7 @@ export default class ServiceWebview extends Component {
service,
setWebviewReference,
reload,
isAppMuted,
} = this.props;
const webviewClasses = classnames({
@@ -92,7 +94,7 @@ export default class ServiceWebview extends Component {
})}
onUpdateTargetUrl={this.updateTargetUrl}
useragent={service.userAgent}
muted={service.isMuted}
muted={isAppMuted || service.isMuted}
disablewebsecurity
allowpopups
/>
@@ -26,6 +26,7 @@ export default class Services extends Component {
handleIPCMessage: PropTypes.func.isRequired,
openWindow: PropTypes.func.isRequired,
reload: PropTypes.func.isRequired,
isAppMuted: PropTypes.bool.isRequired,
};
static defaultProps = {
@@ -44,6 +45,7 @@ export default class Services extends Component {
setWebviewReference,
openWindow,
reload,
isAppMuted,
} = this.props;
const { intl } = this.context;
@@ -76,6 +78,7 @@ export default class Services extends Component {
setWebviewReference={setWebviewReference}
openWindow={openWindow}
reload={() => reload({ serviceId: service.id })}
isAppMuted={isAppMuted}
/>
))}
</div>
@@ -2,17 +2,8 @@ import React, { Component } from 'react';
import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
import PropTypes from 'prop-types';
import { SortableContainer } from 'react-sortable-hoc';
import { defineMessages, intlShape } from 'react-intl';
import TabItem from './TabItem';
import { ctrlKey } from '../../../environment';
const messages = defineMessages({
addNewService: {
id: 'sidebar.addNewService',
defaultMessage: '!!!Add new service',
},
});
@observer
class TabBarSortableList extends Component {
@@ -22,27 +13,23 @@ class TabBarSortableList extends Component {
openSettings: PropTypes.func.isRequired,
reload: PropTypes.func.isRequired,
toggleNotifications: PropTypes.func.isRequired,
toggleAudio: PropTypes.func.isRequired,
deleteService: PropTypes.func.isRequired,
disableService: PropTypes.func.isRequired,
}
static contextTypes = {
intl: intlShape,
};
render() {
const {
services,
setActive,
reload,
toggleNotifications,
toggleAudio,
deleteService,
disableService,
openSettings,
} = this.props;
const { intl } = this.context;
return (
<ul
className="tabs"
@@ -56,20 +43,21 @@ class TabBarSortableList extends Component {
shortcutIndex={index + 1}
reload={() => reload({ serviceId: service.id })}
toggleNotifications={() => toggleNotifications({ serviceId: service.id })}
toggleAudio={() => toggleAudio({ serviceId: service.id })}
deleteService={() => deleteService({ serviceId: service.id })}
disableService={() => disableService({ serviceId: service.id })}
openSettings={openSettings}
/>
))}
<li>
{/* <li>
<button
className="sidebar__add-service"
onClick={() => openSettings({ path: 'recipes' })}
data-tip={`${intl.formatMessage(messages.addNewService)} (${ctrlKey}+N)`}
>
<span className="mdi mdi-plus" />
</button>
</li>
</li> */}
</ul>
);
}
@@ -28,6 +28,14 @@ const messages = defineMessages({
id: 'tabs.item.enableNotification',
defaultMessage: '!!!Enable notifications',
},
disableAudio: {
id: 'tabs.item.disableAudio',
defaultMessage: '!!!Disable audio',
},
enableAudio: {
id: 'tabs.item.enableAudio',
defaultMessage: '!!!Enable audio',
},
disableService: {
id: 'tabs.item.disableService',
defaultMessage: '!!!Disable Service',
@@ -46,6 +54,7 @@ class TabItem extends Component {
shortcutIndex: PropTypes.number.isRequired,
reload: PropTypes.func.isRequired,
toggleNotifications: PropTypes.func.isRequired,
toggleAudio: PropTypes.func.isRequired,
openSettings: PropTypes.func.isRequired,
deleteService: PropTypes.func.isRequired,
disableService: PropTypes.func.isRequired,
@@ -62,6 +71,7 @@ class TabItem extends Component {
shortcutIndex,
reload,
toggleNotifications,
toggleAudio,
deleteService,
disableService,
openSettings,
@@ -89,6 +99,11 @@ class TabItem extends Component {
? intl.formatMessage(messages.disableNotifications)
: intl.formatMessage(messages.enableNotifications),
click: () => toggleNotifications(),
}, {
label: service.isMuted
? intl.formatMessage(messages.enableAudio)
: intl.formatMessage(messages.disableAudio),
click: () => toggleAudio(),
}, {
label: intl.formatMessage(messages.disableService),
click: () => disableService(),
@@ -15,6 +15,7 @@ export default class TabBar extends Component {
reorder: PropTypes.func.isRequired,
reload: PropTypes.func.isRequired,
toggleNotifications: PropTypes.func.isRequired,
toggleAudio: PropTypes.func.isRequired,
deleteService: PropTypes.func.isRequired,
updateService: PropTypes.func.isRequired,
}
@@ -51,6 +52,7 @@ export default class TabBar extends Component {
disableToolTip,
reload,
toggleNotifications,
toggleAudio,
deleteService,
} = this.props;
@@ -63,6 +65,7 @@ export default class TabBar extends Component {
onSortStart={disableToolTip}
reload={reload}
toggleNotifications={toggleNotifications}
toggleAudio={toggleAudio}
deleteService={deleteService}
disableService={this.disableService}
openSettings={openSettings}
@@ -12,4 +12,5 @@ export const DEFAULT_APP_SETTINGS = {
minimizeToSystemTray: false,
locale: 'en-us', // TODO: Replace with proper solution once translations are in
beta: false,
isAppMuted: false,
};
@@ -7,7 +7,7 @@ import RecipesStore from '../../stores/RecipesStore';
import ServicesStore from '../../stores/ServicesStore';
import UIStore from '../../stores/UIStore';
import NewsStore from '../../stores/NewsStore';
import UserStore from '../../stores/UserStore';
import SettingsStore from '../../stores/SettingsStore';
import RequestStore from '../../stores/RequestStore';
import GlobalErrorStore from '../../stores/GlobalErrorStore';
@@ -29,8 +29,8 @@ export default class AppLayoutContainer extends Component {
services,
ui,
news,
settings,
globalError,
user,
requests,
} = this.props.stores;
@@ -43,6 +43,7 @@ export default class AppLayoutContainer extends Component {
reorder,
reload,
toggleNotifications,
toggleAudio,
deleteService,
updateService,
} = this.props.actions.service;
@@ -53,6 +54,7 @@ export default class AppLayoutContainer extends Component {
const {
installUpdate,
toggleMuteApp,
} = this.props.actions.app;
const {
@@ -79,14 +81,16 @@ export default class AppLayoutContainer extends Component {
<Sidebar
services={allServices}
setActive={setActive}
isAppMuted={settings.all.isMuted}
openSettings={openSettings}
closeSettings={closeSettings}
reorder={reorder}
reload={reload}
toggleNotifications={toggleNotifications}
toggleAudio={toggleAudio}
deleteService={deleteService}
updateService={updateService}
isPremiumUser={user.data.isPremium}
toggleMuteApp={toggleMuteApp}
/>
);
@@ -97,6 +101,7 @@ export default class AppLayoutContainer extends Component {
setWebviewReference={setWebviewReference}
openWindow={openWindow}
reload={reload}
isAppMuted={settings.all.isMuted}
/>
);
@@ -130,7 +135,7 @@ AppLayoutContainer.wrappedComponent.propTypes = {
app: PropTypes.instanceOf(AppStore).isRequired,
ui: PropTypes.instanceOf(UIStore).isRequired,
news: PropTypes.instanceOf(NewsStore).isRequired,
user: PropTypes.instanceOf(UserStore).isRequired,
settings: PropTypes.instanceOf(SettingsStore).isRequired,
requests: PropTypes.instanceOf(RequestStore).isRequired,
globalError: PropTypes.instanceOf(GlobalErrorStore).isRequired,
}).isRequired,
@@ -139,6 +144,7 @@ AppLayoutContainer.wrappedComponent.propTypes = {
setActive: PropTypes.func.isRequired,
reload: PropTypes.func.isRequired,
toggleNotifications: PropTypes.func.isRequired,
toggleAudio: PropTypes.func.isRequired,
handleIPCMessage: PropTypes.func.isRequired,
setWebviewReference: PropTypes.func.isRequired,
openWindow: PropTypes.func.isRequired,
@@ -156,7 +162,7 @@ AppLayoutContainer.wrappedComponent.propTypes = {
}).isRequired,
app: PropTypes.shape({
installUpdate: PropTypes.func.isRequired,
healthCheck: PropTypes.func.isRequired,
toggleMuteApp: PropTypes.func.isRequired,
}).isRequired,
requests: PropTypes.shape({
retryRequiredRequests: PropTypes.func.isRequired,
@@ -61,6 +61,8 @@
"infobar.requiredRequestsFailed": "Could not load services and user information",
"sidebar.settings": "Settings",
"sidebar.addNewService": "Add new service",
"sidebar.mute": "Disable audio",
"sidebar.unmute": "Enable audio",
"services.welcome": "Welcome to Franz",
"services.getStarted": "Get started",
"settings.account.headline": "Account",
@@ -167,6 +169,8 @@
"tabs.item.edit": "Edit",
"tabs.item.disableNotifications": "Disable notifications",
"tabs.item.enableNotification": "Enable notifications",
"tabs.item.disableAudio": "Disable audio",
"tabs.item.enableAudio": "Enable audio",
"tabs.item.disableService": "Disable service",
"tabs.item.deleteService": "Delete service",
"service.crashHandler.headline": "Oh no!",
Oops, something went wrong.

0 comments on commit f5a9aa2

Please sign in to comment.