about summary refs log tree commit diff
path: root/app/javascript/mastodon/features/ui
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-08-13 12:22:16 +0200
committerGitHub <noreply@github.com>2019-08-13 12:22:16 +0200
commitc09ecbc53eb3d3a8a1e2a1e61e20c9e5dbd4f560 (patch)
tree660f048dabcb1fac8bfc80246302d7c974118dd4 /app/javascript/mastodon/features/ui
parent5f63339744eecd75b1065135559ddbe688636be1 (diff)
Add indicator of unread content to window title when web UI is out of focus (#11560)
Fix #1288
Diffstat (limited to 'app/javascript/mastodon/features/ui')
-rw-r--r--app/javascript/mastodon/features/ui/components/document_title.js41
-rw-r--r--app/javascript/mastodon/features/ui/index.js18
2 files changed, 58 insertions, 1 deletions
diff --git a/app/javascript/mastodon/features/ui/components/document_title.js b/app/javascript/mastodon/features/ui/components/document_title.js
new file mode 100644
index 000000000..cd081b20c
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/components/document_title.js
@@ -0,0 +1,41 @@
+import { PureComponent } from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import { title } from 'mastodon/initial_state';
+
+const mapStateToProps = state => ({
+  unread: state.getIn(['missed_updates', 'unread']),
+});
+
+export default @connect(mapStateToProps)
+class DocumentTitle extends PureComponent {
+
+  static propTypes = {
+    unread: PropTypes.number.isRequired,
+  };
+
+  componentDidMount () {
+    this._sideEffects();
+  }
+
+  componentDidUpdate() {
+    this._sideEffects();
+  }
+
+  _sideEffects () {
+    const { unread } = this.props;
+
+    if (unread > 99) {
+      document.title = `(*) ${title}`;
+    } else if (unread > 0) {
+      document.title = `(${unread}) ${title}`;
+    } else {
+      document.title = title;
+    }
+  }
+
+  render () {
+    return null;
+  }
+
+}
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index d1a3dc949..f0c3eff83 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -15,9 +15,11 @@ import { expandHomeTimeline } from '../../actions/timelines';
 import { expandNotifications } from '../../actions/notifications';
 import { fetchFilters } from '../../actions/filters';
 import { clearHeight } from '../../actions/height_cache';
+import { focusApp, unfocusApp } from 'mastodon/actions/app';
 import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers';
 import UploadArea from './components/upload_area';
 import ColumnsAreaContainer from './containers/columns_area_container';
+import DocumentTitle from './components/document_title';
 import {
   Compose,
   Status,
@@ -226,7 +228,7 @@ class UI extends React.PureComponent {
     draggingOver: false,
   };
 
-  handleBeforeUnload = (e) => {
+  handleBeforeUnload = e => {
     const { intl, isComposing, hasComposingText, hasMediaAttachments } = this.props;
 
     if (isComposing && (hasComposingText || hasMediaAttachments)) {
@@ -237,6 +239,14 @@ class UI extends React.PureComponent {
     }
   }
 
+  handleWindowFocus = () => {
+    this.props.dispatch(focusApp());
+  }
+
+  handleWindowBlur = () => {
+    this.props.dispatch(unfocusApp());
+  }
+
   handleLayoutChange = () => {
     // The cached heights are no longer accurate, invalidate
     this.props.dispatch(clearHeight());
@@ -314,6 +324,8 @@ class UI extends React.PureComponent {
   }
 
   componentWillMount () {
+    window.addEventListener('focus', this.handleWindowFocus, false);
+    window.addEventListener('blur', this.handleWindowBlur, false);
     window.addEventListener('beforeunload', this.handleBeforeUnload, false);
 
     document.addEventListener('dragenter', this.handleDragEnter, false);
@@ -343,7 +355,10 @@ class UI extends React.PureComponent {
   }
 
   componentWillUnmount () {
+    window.removeEventListener('focus', this.handleWindowFocus);
+    window.removeEventListener('blur', this.handleWindowBlur);
     window.removeEventListener('beforeunload', this.handleBeforeUnload);
+
     document.removeEventListener('dragenter', this.handleDragEnter);
     document.removeEventListener('dragover', this.handleDragOver);
     document.removeEventListener('drop', this.handleDrop);
@@ -502,6 +517,7 @@ class UI extends React.PureComponent {
           <LoadingBarContainer className='loading-bar' />
           <ModalContainer />
           <UploadArea active={draggingOver} onClose={this.closeUploadModal} />
+          <DocumentTitle />
         </div>
       </HotKeys>
     );