From 893a9f6d9a1bcdbbfe925e718b2c907dcceaa64e Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 1 Dec 2017 12:26:41 +0100 Subject: feat(App): Add option to show/hide notification badges for muted services (@maximiliancsuk) --- src/components/services/tabs/TabBarSortableList.js | 6 ++++ src/components/services/tabs/TabItem.js | 37 +++++++++++++++------- src/components/services/tabs/Tabbar.js | 6 ++++ .../settings/settings/EditSettingsForm.js | 1 + src/config.js | 1 + src/containers/layout/AppLayoutContainer.js | 2 ++ src/containers/settings/EditSettingsScreen.js | 10 ++++++ src/i18n/locales/en-US.json | 1 + src/models/Settings.js | 1 + src/stores/AppStore.js | 9 ++++++ src/stores/ServicesStore.js | 19 ++++++++--- src/stores/UIStore.js | 8 ++++- src/styles/tabs.scss | 20 ++++++++++++ 13 files changed, 103 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/components/services/tabs/TabBarSortableList.js b/src/components/services/tabs/TabBarSortableList.js index 2daf55676..489027d57 100644 --- a/src/components/services/tabs/TabBarSortableList.js +++ b/src/components/services/tabs/TabBarSortableList.js @@ -17,6 +17,8 @@ class TabBarSortableList extends Component { deleteService: PropTypes.func.isRequired, disableService: PropTypes.func.isRequired, enableService: PropTypes.func.isRequired, + showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, + showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, } render() { @@ -30,6 +32,8 @@ class TabBarSortableList extends Component { disableService, enableService, openSettings, + showMessageBadgeWhenMutedSetting, + showMessageBadgesEvenWhenMuted, } = this.props; return ( @@ -50,6 +54,8 @@ class TabBarSortableList extends Component { disableService={() => disableService({ serviceId: service.id })} enableService={() => enableService({ serviceId: service.id })} openSettings={openSettings} + showMessageBadgeWhenMutedSetting={showMessageBadgeWhenMutedSetting} + showMessageBadgesEvenWhenMuted={showMessageBadgesEvenWhenMuted} /> ))} {/*
  • diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js index a7136c43f..8403d9462 100644 --- a/src/components/services/tabs/TabItem.js +++ b/src/components/services/tabs/TabItem.js @@ -63,6 +63,8 @@ class TabItem extends Component { deleteService: PropTypes.func.isRequired, disableService: PropTypes.func.isRequired, enableService: PropTypes.func.isRequired, + showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, + showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, }; static contextTypes = { @@ -81,6 +83,8 @@ class TabItem extends Component { disableService, enableService, openSettings, + showMessageBadgeWhenMutedSetting, + showMessageBadgesEvenWhenMuted, } = this.props; const { intl } = this.context; @@ -121,6 +125,26 @@ class TabItem extends Component { }]; const menu = Menu.buildFromTemplate(menuTemplate); + let notificationBadge = null; + if ((showMessageBadgeWhenMutedSetting || service.isNotificationEnabled) && showMessageBadgesEvenWhenMuted) { + notificationBadge = ( + + {service.unreadDirectMessageCount > 0 && ( + + {service.unreadDirectMessageCount} + + )} + {service.unreadIndirectMessageCount > 0 + && service.unreadDirectMessageCount === 0 + && service.isIndirectMessageBadgeEnabled && ( + + • + + )} + + ); + } + return (
  • - {service.unreadDirectMessageCount > 0 && ( - - {service.unreadDirectMessageCount} - - )} - {service.unreadIndirectMessageCount > 0 - && service.unreadDirectMessageCount === 0 - && service.isIndirectMessageBadgeEnabled && ( - - • - - )} + {notificationBadge}
  • ); } diff --git a/src/components/services/tabs/Tabbar.js b/src/components/services/tabs/Tabbar.js index 9da1090b7..ceb88c51c 100644 --- a/src/components/services/tabs/Tabbar.js +++ b/src/components/services/tabs/Tabbar.js @@ -18,6 +18,8 @@ export default class TabBar extends Component { toggleAudio: PropTypes.func.isRequired, deleteService: PropTypes.func.isRequired, updateService: PropTypes.func.isRequired, + showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, + showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, } onSortEnd = ({ oldIndex, newIndex }) => { @@ -64,6 +66,8 @@ export default class TabBar extends Component { toggleNotifications, toggleAudio, deleteService, + showMessageBadgeWhenMutedSetting, + showMessageBadgesEvenWhenMuted, } = this.props; return ( @@ -85,6 +89,8 @@ export default class TabBar extends Component { axis="y" lockAxis="y" helperClass="is-reordering" + showMessageBadgeWhenMutedSetting={showMessageBadgeWhenMutedSetting} + showMessageBadgesEvenWhenMuted={showMessageBadgesEvenWhenMuted} /> ); diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 4ce9b7ab2..878e46d6d 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js @@ -142,6 +142,7 @@ export default class EditSettingsForm extends Component { {/* Appearance */}

    {intl.formatMessage(messages.headlineAppearance)}

    + {/* Language */}

    {intl.formatMessage(messages.headlineLanguage)}

    diff --git a/src/config.js b/src/config.js index b3e00c92c..e6d8958e6 100644 --- a/src/config.js +++ b/src/config.js @@ -11,6 +11,7 @@ export const DEFAULT_APP_SETTINGS = { enableSystemTray: true, minimizeToSystemTray: false, showDisabledServices: true, + showMessageBadgeWhenMuted: true, enableSpellchecking: true, // spellcheckingLanguage: 'auto', locale: 'en-US', diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js index da0896844..e4a9d60c3 100644 --- a/src/containers/layout/AppLayoutContainer.js +++ b/src/containers/layout/AppLayoutContainer.js @@ -87,6 +87,8 @@ export default class AppLayoutContainer extends Component { deleteService={deleteService} updateService={updateService} toggleMuteApp={toggleMuteApp} + showMessageBadgeWhenMutedSetting={settings.all.showMessageBadgeWhenMuted} + showMessageBadgesEvenWhenMuted={ui.showMessageBadgesEvenWhenMuted} /> ); diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 62e255dab..45ded9e5c 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -43,6 +43,10 @@ const messages = defineMessages({ id: 'settings.app.form.showDisabledServices', defaultMessage: '!!!Display disabled services tabs', }, + showMessageBadgeWhenMuted: { + id: 'settings.app.form.showMessagesBadgesWhenMuted', + defaultMessage: '!!!Show unread message badge when notifications are disabled', + }, enableSpellchecking: { id: 'settings.app.form.enableSpellchecking', defaultMessage: '!!!Enable spell checking', @@ -85,6 +89,7 @@ export default class EditSettingsScreen extends Component { enableSystemTray: settingsData.enableSystemTray, minimizeToSystemTray: settingsData.minimizeToSystemTray, showDisabledServices: settingsData.showDisabledServices, + showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted, enableSpellchecking: settingsData.enableSpellchecking, // spellcheckingLanguage: settingsData.spellcheckingLanguage, locale: settingsData.locale, @@ -154,6 +159,11 @@ export default class EditSettingsScreen extends Component { value: settings.all.showDisabledServices, default: DEFAULT_APP_SETTINGS.showDisabledServices, }, + showMessageBadgeWhenMuted: { + label: intl.formatMessage(messages.showMessageBadgeWhenMuted), + value: settings.all.showMessageBadgeWhenMuted, + default: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted, + }, enableSpellchecking: { label: intl.formatMessage(messages.enableSpellchecking), value: settings.all.enableSpellchecking, diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 37034d4e1..380871668 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -148,6 +148,7 @@ "settings.app.form.language": "Language", "settings.app.form.enableSpellchecking": "Enable spell checking", "settings.app.form.showDisabledServices": "Display disabled services tabs", + "settings.app.form.showMessagesBadgesWhenMuted": "Show unread message badge when notifications are disabled", "settings.app.form.beta": "Include beta versions", "settings.app.translationHelp": "Help us to translate Franz into your language.", "settings.app.currentVersion": "Current version:", diff --git a/src/models/Settings.js b/src/models/Settings.js index 3b352f9aa..35bfe0d05 100644 --- a/src/models/Settings.js +++ b/src/models/Settings.js @@ -8,6 +8,7 @@ export default class Settings { @observable enableSystemTray = DEFAULT_APP_SETTINGS.enableSystemTray; @observable minimizeToSystemTray = DEFAULT_APP_SETTINGS.minimizeToSystemTray; @observable showDisabledServices = DEFAULT_APP_SETTINGS.showDisabledServices; + @observable showMessageBadgeWhenMuted = DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted; @observable enableSpellchecking = DEFAULT_APP_SETTINGS.enableSpellchecking; @observable locale = DEFAULT_APP_SETTINGS.locale; @observable beta = DEFAULT_APP_SETTINGS.beta; diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 0cfe08a28..6125a7cff 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js @@ -67,6 +67,7 @@ export default class AppStore extends Store { this._setLocale.bind(this), this._handleMiner.bind(this), this._handleMinerThrottle.bind(this), + this._muteAppHandler.bind(this), ]); } @@ -300,6 +301,14 @@ export default class AppStore extends Store { } } + _muteAppHandler() { + const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted; + + if (!showMessageBadgesEvenWhenMuted) { + this.actions.app.setBadge({ unreadDirectMessageCount: 0, unreadIndirectMessageCount: 0 }); + } + } + // Helpers async _appStartsCounter() { // we need to wait until the settings request is resolved diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 22c376c06..e79677400 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js @@ -488,19 +488,28 @@ export default class ServicesStore extends Store { } _getUnreadMessageCountReaction() { + const showMessageBadgeWhenMuted = this.stores.settings.all.showMessageBadgeWhenMuted; + const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted; + + // TODO: unfinished monkey business + const unreadDirectMessageCount = this.enabled + .filter(s => (showMessageBadgeWhenMuted || s.isNotificationEnabled) && showMessageBadgesEvenWhenMuted) .map(s => s.unreadDirectMessageCount) .reduce((a, b) => a + b, 0); const unreadIndirectMessageCount = this.enabled - .filter(s => s.isIndirectMessageBadgeEnabled) + // .filter(s => s.isIndirectMessageBadgeEnabled && (s.isNotificationEnabled && showMessageBadgeWhenMuted)) .map(s => s.unreadIndirectMessageCount) .reduce((a, b) => a + b, 0); - this.actions.app.setBadge({ - unreadDirectMessageCount, - unreadIndirectMessageCount, - }); + // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases + if (showMessageBadgesEvenWhenMuted) { + this.actions.app.setBadge({ + unreadDirectMessageCount, + unreadIndirectMessageCount, + }); + } } _logoutReaction() { diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js index cb45b88b5..5e9cc9ba7 100644 --- a/src/stores/UIStore.js +++ b/src/stores/UIStore.js @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, computed } from 'mobx'; import Store from './lib/Store'; @@ -14,6 +14,12 @@ export default class UIStore extends Store { this.actions.ui.toggleServiceUpdatedInfoBar.listen(this._toggleServiceUpdatedInfoBar.bind(this)); } + @computed get showMessageBadgesEvenWhenMuted() { + const settings = this.stores.settings.all; + + return (settings.isAppMuted && settings.showMessageBadgeWhenMuted) || !settings.isAppMuted; + } + // Actions @action _openSettings({ path = '/settings' }) { const settingsPath = path !== '/settings' ? `/settings/${path}` : path; diff --git a/src/styles/tabs.scss b/src/styles/tabs.scss index 3ffc53558..ac48aabd6 100644 --- a/src/styles/tabs.scss +++ b/src/styles/tabs.scss @@ -78,6 +78,26 @@ } } + .tab-item__info-badge { + width: 17px; + height: 17px; + background: $theme-gray-light; + color: $theme-gray-lighter; + border-radius: 20px; + padding: 0px 5px; + font-size: 11px; + position: absolute; + right: 8px; + bottom: 8px; + display: flex; + justify-content: center; + align-items: center; + + &.is-indirect { + padding-top: 0px; + } + } + &.is-reordering { z-index: 99999; } -- cgit v1.2.3-70-g09d2