about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2019-12-08 21:27:36 +0100
committerGitHub <noreply@github.com>2019-12-08 21:27:36 +0100
commit246addd5b33a172600342af3fb6fb5e4c80ad95e (patch)
tree98b87efd3f5f3d41d75482707924fde708c074ec /app/javascript/flavours/glitch/features
parent7d59e25fbd7a0209c11cbe6aac4400bbca4de82b (diff)
parent49027ee948bc76cc89214f8f340d353763796f1d (diff)
Merge pull request #1251 from ThibG/glitch-soc/merge-upstream
Merge upstream changes
Diffstat (limited to 'app/javascript/flavours/glitch/features')
-rw-r--r--app/javascript/flavours/glitch/features/account/components/header.js11
-rw-r--r--app/javascript/flavours/glitch/features/notifications/components/column_settings.js11
-rw-r--r--app/javascript/flavours/glitch/features/notifications/components/follow_request.js130
-rw-r--r--app/javascript/flavours/glitch/features/notifications/components/notification.js13
-rw-r--r--app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js16
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js13
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/video_modal.js2
7 files changed, 185 insertions, 11 deletions
diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js
index e65a68b4d..6b4aff616 100644
--- a/app/javascript/flavours/glitch/features/account/components/header.js
+++ b/app/javascript/flavours/glitch/features/account/components/header.js
@@ -232,9 +232,18 @@ class Header extends ImmutablePureComponent {
     const content          = { __html: account.get('note_emojified') };
     const displayNameHtml = { __html: account.get('display_name_html') };
     const fields          = account.get('fields');
-    const badge           = account.get('bot') ? (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>) : null;
     const acct            = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct');
 
+    let badge;
+
+    if (account.get('bot')) {
+      badge = (<div className='account-role bot'><FormattedMessage id='account.badges.bot' defaultMessage='Bot' /></div>);
+    } else if (account.get('group')) {
+      badge = (<div className='account-role group'><FormattedMessage id='account.badges.group' defaultMessage='Group' /></div>);
+    } else {
+      badge = null;
+    }
+
     return (
       <div className={classNames('account__header', { inactive: !!account.get('moved') })} ref={this.setRef}>
         <div className='account__header__image'>
diff --git a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js
index e29bd61f5..e4d5d0eda 100644
--- a/app/javascript/flavours/glitch/features/notifications/components/column_settings.js
+++ b/app/javascript/flavours/glitch/features/notifications/components/column_settings.js
@@ -58,6 +58,17 @@ export default class ColumnSettings extends React.PureComponent {
           </div>
         </div>
 
+        <div role='group' aria-labelledby='notifications-follow-request'>
+          <span id='notifications-follow-request' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow_request' defaultMessage='New follow requests:' /></span>
+
+          <div className='column-settings__row'>
+            <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow_request']} onChange={onChange} label={alertStr} />
+            {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'follow_request']} onChange={this.onPushChange} label={pushStr} />}
+            <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow_request']} onChange={onChange} label={showStr} />
+            <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow_request']} onChange={onChange} label={soundStr} />
+          </div>
+        </div>
+
         <div role='group' aria-labelledby='notifications-favourite'>
           <span id='notifications-favourite' className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span>
 
diff --git a/app/javascript/flavours/glitch/features/notifications/components/follow_request.js b/app/javascript/flavours/glitch/features/notifications/components/follow_request.js
new file mode 100644
index 000000000..d73dac434
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/notifications/components/follow_request.js
@@ -0,0 +1,130 @@
+import React, { Fragment } from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
+import Avatar from 'flavours/glitch/components/avatar';
+import DisplayName from 'flavours/glitch/components/display_name';
+import Permalink from 'flavours/glitch/components/permalink';
+import IconButton from 'flavours/glitch/components/icon_button';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import NotificationOverlayContainer from '../containers/overlay_container';
+import { HotKeys } from 'react-hotkeys';
+import Icon from 'flavours/glitch/components/icon';
+
+const messages = defineMessages({
+  authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' },
+  reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
+});
+
+export default @injectIntl
+class FollowRequest extends ImmutablePureComponent {
+
+  static propTypes = {
+    account: ImmutablePropTypes.map.isRequired,
+    onAuthorize: PropTypes.func.isRequired,
+    onReject: PropTypes.func.isRequired,
+    intl: PropTypes.object.isRequired,
+    notification: ImmutablePropTypes.map.isRequired,
+  };
+
+  handleMoveUp = () => {
+    const { notification, onMoveUp } = this.props;
+    onMoveUp(notification.get('id'));
+  }
+
+  handleMoveDown = () => {
+    const { notification, onMoveDown } = this.props;
+    onMoveDown(notification.get('id'));
+  }
+
+  handleOpen = () => {
+    this.handleOpenProfile();
+  }
+
+  handleOpenProfile = () => {
+    const { notification } = this.props;
+    this.context.router.history.push(`/accounts/${notification.getIn(['account', 'id'])}`);
+  }
+
+  handleMention = e => {
+    e.preventDefault();
+
+    const { notification, onMention } = this.props;
+    onMention(notification.get('account'), this.context.router.history);
+  }
+
+  getHandlers () {
+    return {
+      moveUp: this.handleMoveUp,
+      moveDown: this.handleMoveDown,
+      open: this.handleOpen,
+      openProfile: this.handleOpenProfile,
+      mention: this.handleMention,
+      reply: this.handleMention,
+    };
+  }
+
+  render () {
+    const { intl, hidden, account, onAuthorize, onReject, notification } = this.props;
+
+    if (!account) {
+      return <div />;
+    }
+
+    if (hidden) {
+      return (
+        <Fragment>
+          {account.get('display_name')}
+          {account.get('username')}
+        </Fragment>
+      );
+    }
+
+    //  Links to the display name.
+    const displayName = account.get('display_name_html') || account.get('username');
+    const link = (
+      <bdi><Permalink
+        className='notification__display-name'
+        href={account.get('url')}
+        title={account.get('acct')}
+        to={`/accounts/${account.get('id')}`}
+        dangerouslySetInnerHTML={{ __html: displayName }}
+      /></bdi>
+    );
+
+    return (
+      <HotKeys handlers={this.getHandlers()}>
+        <div className='notification notification-follow-request focusable' tabIndex='0'>
+          <div className='notification__message'>
+            <div className='notification__favourite-icon-wrapper'>
+              <Icon id='user' fixedWidth />
+            </div>
+
+            <FormattedMessage
+              id='notification.follow_request'
+              defaultMessage='{name} has requested to follow you'
+              values={{ name: link }}
+            />
+          </div>
+
+          <div className='account'>
+            <div className='account__wrapper'>
+              <Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/accounts/${account.get('id')}`}>
+                <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div>
+                <DisplayName account={account} />
+              </Permalink>
+
+              <div className='account__relationship'>
+                <IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} />
+                <IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} />
+              </div>
+            </div>
+          </div>
+
+          <NotificationOverlayContainer notification={notification} />
+        </div>
+      </HotKeys>
+    );
+  }
+
+}
diff --git a/app/javascript/flavours/glitch/features/notifications/components/notification.js b/app/javascript/flavours/glitch/features/notifications/components/notification.js
index 5c5bbf604..62fc28386 100644
--- a/app/javascript/flavours/glitch/features/notifications/components/notification.js
+++ b/app/javascript/flavours/glitch/features/notifications/components/notification.js
@@ -7,6 +7,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 //  Our imports,
 import StatusContainer from 'flavours/glitch/containers/status_container';
 import NotificationFollow from './follow';
+import NotificationFollowRequestContainer from '../containers/follow_request_container';
 
 export default class Notification extends ImmutablePureComponent {
 
@@ -47,6 +48,18 @@ export default class Notification extends ImmutablePureComponent {
           onMention={onMention}
         />
       );
+    case 'follow_request':
+      return (
+        <NotificationFollowRequestContainer
+          hidden={hidden}
+          id={notification.get('id')}
+          account={notification.get('account')}
+          notification={notification}
+          onMoveDown={onMoveDown}
+          onMoveUp={onMoveUp}
+          onMention={onMention}
+        />
+      );
     case 'mention':
       return (
         <StatusContainer
diff --git a/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js b/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js
new file mode 100644
index 000000000..82357adfb
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/notifications/containers/follow_request_container.js
@@ -0,0 +1,16 @@
+import { connect } from 'react-redux';
+import { makeGetAccount } from 'flavours/glitch/selectors';
+import FollowRequest from '../components/follow_request';
+import { authorizeFollowRequest, rejectFollowRequest } from 'flavours/glitch/actions/accounts';
+
+const mapDispatchToProps = (dispatch, { account }) => ({
+  onAuthorize () {
+    dispatch(authorizeFollowRequest(account.get('id')));
+  },
+
+  onReject () {
+    dispatch(rejectFollowRequest(account.get('id')));
+  },
+});
+
+export default connect(null, mapDispatchToProps)(FollowRequest);
diff --git a/app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js b/app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js
index 189f403bd..c30427896 100644
--- a/app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js
+++ b/app/javascript/flavours/glitch/features/ui/components/follow_requests_nav_link.js
@@ -4,12 +4,10 @@ import { fetchFollowRequests } from 'flavours/glitch/actions/accounts';
 import { connect } from 'react-redux';
 import { NavLink, withRouter } from 'react-router-dom';
 import IconWithBadge from 'flavours/glitch/components/icon_with_badge';
-import { me } from 'flavours/glitch/util/initial_state';
 import { List as ImmutableList } from 'immutable';
 import { FormattedMessage } from 'react-intl';
 
 const mapStateToProps = state => ({
-  locked: state.getIn(['accounts', me, 'locked']),
   count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size,
 });
 
@@ -19,22 +17,19 @@ class FollowRequestsNavLink extends React.Component {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
-    locked: PropTypes.bool,
     count: PropTypes.number.isRequired,
   };
 
   componentDidMount () {
-    const { dispatch, locked } = this.props;
+    const { dispatch } = this.props;
 
-    if (locked) {
-      dispatch(fetchFollowRequests());
-    }
+    dispatch(fetchFollowRequests());
   }
 
   render () {
-    const { locked, count } = this.props;
+    const { count } = this.props;
 
-    if (!locked || count === 0) {
+    if (count === 0) {
       return null;
     }
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/video_modal.js b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
index ef69f60f4..e7309021e 100644
--- a/app/javascript/flavours/glitch/features/ui/components/video_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
@@ -5,7 +5,7 @@ import Video from 'flavours/glitch/features/video';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
 import classNames from 'classnames';
-import Icon from 'mastodon/components/icon';
+import Icon from 'flavours/glitch/components/icon';
 
 export default class VideoModal extends ImmutablePureComponent {