about summary refs log tree commit diff
path: root/app/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/mastodon/actions/identity_proofs.js30
-rw-r--r--app/javascript/mastodon/features/account/components/header.js17
-rw-r--r--app/javascript/mastodon/features/account_timeline/components/header.js4
-rw-r--r--app/javascript/mastodon/features/account_timeline/containers/header_container.js2
-rw-r--r--app/javascript/mastodon/features/account_timeline/index.js3
-rw-r--r--app/javascript/mastodon/reducers/identity_proofs.js25
-rw-r--r--app/javascript/mastodon/reducers/index.js2
-rw-r--r--app/javascript/styles/mastodon/containers.scss8
-rw-r--r--app/javascript/styles/mastodon/forms.scss9
9 files changed, 91 insertions, 9 deletions
diff --git a/app/javascript/mastodon/actions/identity_proofs.js b/app/javascript/mastodon/actions/identity_proofs.js
new file mode 100644
index 000000000..449debf61
--- /dev/null
+++ b/app/javascript/mastodon/actions/identity_proofs.js
@@ -0,0 +1,30 @@
+import api from '../api';
+
+export const IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST = 'IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST';
+export const IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS = 'IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS';
+export const IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL    = 'IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL';
+
+export const fetchAccountIdentityProofs = accountId => (dispatch, getState) => {
+  dispatch(fetchAccountIdentityProofsRequest(accountId));
+
+  api(getState).get(`/api/v1/accounts/${accountId}/identity_proofs`)
+    .then(({ data }) => dispatch(fetchAccountIdentityProofsSuccess(accountId, data)))
+    .catch(err => dispatch(fetchAccountIdentityProofsFail(accountId, err)));
+};
+
+export const fetchAccountIdentityProofsRequest = id => ({
+  type: IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST,
+  id,
+});
+
+export const fetchAccountIdentityProofsSuccess = (accountId, identity_proofs) => ({
+  type: IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS,
+  accountId,
+  identity_proofs,
+});
+
+export const fetchAccountIdentityProofsFail = (accountId, err) => ({
+  type: IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
+  accountId,
+  err,
+});
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index d957de73d..76f50a5a4 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -62,6 +62,7 @@ class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
+    identity_props: ImmutablePropTypes.list,
     onFollow: PropTypes.func.isRequired,
     onBlock: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
@@ -81,7 +82,7 @@ class Header extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, intl, domain } = this.props;
+    const { account, intl, domain, identity_proofs } = this.props;
 
     if (!account) {
       return null;
@@ -234,8 +235,20 @@ class Header extends ImmutablePureComponent {
 
           <div className='account__header__extra'>
             <div className='account__header__bio'>
-              {fields.size > 0 && (
+              { (fields.size > 0 || identity_proofs.size > 0) && (
                 <div className='account__header__fields'>
+                  {identity_proofs.map((proof, i) => (
+                    <dl key={i}>
+                      <dt dangerouslySetInnerHTML={{ __html: proof.get('provider') }} />
+
+                      <dd className='verified'>
+                        <a href={proof.get('proof_url')} target='_blank' rel='noopener'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
+                          <Icon id='check' className='verified__mark' />
+                        </span></a>
+                        <a href={proof.get('profile_url')} target='_blank' rel='noopener'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
+                      </dd>
+                    </dl>
+                  ))}
                   {fields.map((pair, i) => (
                     <dl key={i}>
                       <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 16ada18c0..27dfcc516 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -12,6 +12,7 @@ export default class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
+    identity_proofs: ImmutablePropTypes.list,
     onFollow: PropTypes.func.isRequired,
     onBlock: PropTypes.func.isRequired,
     onMention: PropTypes.func.isRequired,
@@ -84,7 +85,7 @@ export default class Header extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, hideTabs } = this.props;
+    const { account, hideTabs, identity_proofs } = this.props;
 
     if (account === null) {
       return <MissingIndicator />;
@@ -96,6 +97,7 @@ export default class Header extends ImmutablePureComponent {
 
         <InnerHeader
           account={account}
+          identity_proofs={identity_proofs}
           onFollow={this.handleFollow}
           onBlock={this.handleBlock}
           onMention={this.handleMention}
diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.js b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
index a06a0b095..4d4ae6e82 100644
--- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js
+++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.js
@@ -21,6 +21,7 @@ import { openModal } from '../../../actions/modal';
 import { blockDomain, unblockDomain } from '../../../actions/domain_blocks';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { unfollowModal } from '../../../initial_state';
+import { List as ImmutableList } from 'immutable';
 
 const messages = defineMessages({
   unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
@@ -35,6 +36,7 @@ const makeMapStateToProps = () => {
   const mapStateToProps = (state, { accountId }) => ({
     account: getAccount(state, accountId),
     domain: state.getIn(['meta', 'domain']),
+    identity_proofs: state.getIn(['identity_proofs', accountId], ImmutableList()),
   });
 
   return mapStateToProps;
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index afc484c60..883f40d77 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -12,6 +12,7 @@ import ColumnBackButton from '../../components/column_back_button';
 import { List as ImmutableList } from 'immutable';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
+import { fetchAccountIdentityProofs } from '../../actions/identity_proofs';
 
 const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => {
   const path = withReplies ? `${accountId}:with_replies` : accountId;
@@ -42,6 +43,7 @@ class AccountTimeline extends ImmutablePureComponent {
     const { params: { accountId }, withReplies } = this.props;
 
     this.props.dispatch(fetchAccount(accountId));
+    this.props.dispatch(fetchAccountIdentityProofs(accountId));
     if (!withReplies) {
       this.props.dispatch(expandAccountFeaturedTimeline(accountId));
     }
@@ -51,6 +53,7 @@ class AccountTimeline extends ImmutablePureComponent {
   componentWillReceiveProps (nextProps) {
     if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) {
       this.props.dispatch(fetchAccount(nextProps.params.accountId));
+      this.props.dispatch(fetchAccountIdentityProofs(nextProps.params.accountId));
       if (!nextProps.withReplies) {
         this.props.dispatch(expandAccountFeaturedTimeline(nextProps.params.accountId));
       }
diff --git a/app/javascript/mastodon/reducers/identity_proofs.js b/app/javascript/mastodon/reducers/identity_proofs.js
new file mode 100644
index 000000000..58af0a5fa
--- /dev/null
+++ b/app/javascript/mastodon/reducers/identity_proofs.js
@@ -0,0 +1,25 @@
+import { Map as ImmutableMap, fromJS } from 'immutable';
+import {
+  IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST,
+  IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS,
+  IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL,
+} from '../actions/identity_proofs';
+
+const initialState = ImmutableMap();
+
+export default function identityProofsReducer(state = initialState, action) {
+  switch(action.type) {
+  case IDENTITY_PROOFS_ACCOUNT_FETCH_REQUEST:
+    return state.set('isLoading', true);
+  case IDENTITY_PROOFS_ACCOUNT_FETCH_FAIL:
+    return state.set('isLoading', false);
+  case IDENTITY_PROOFS_ACCOUNT_FETCH_SUCCESS:
+    return state.update(identity_proofs => identity_proofs.withMutations(map => {
+      map.set('isLoading', false);
+      map.set('loaded', true);
+      map.set(action.accountId, fromJS(action.identity_proofs));
+    }));
+  default:
+    return state;
+  }
+};
diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js
index a7e9c4d0f..981ad8e64 100644
--- a/app/javascript/mastodon/reducers/index.js
+++ b/app/javascript/mastodon/reducers/index.js
@@ -30,6 +30,7 @@ import filters from './filters';
 import conversations from './conversations';
 import suggestions from './suggestions';
 import polls from './polls';
+import identity_proofs from './identity_proofs';
 
 const reducers = {
   dropdown_menu,
@@ -56,6 +57,7 @@ const reducers = {
   notifications,
   height_cache,
   custom_emojis,
+  identity_proofs,
   lists,
   listEditor,
   listAdder,
diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss
index 2b1d988f2..368c2304b 100644
--- a/app/javascript/styles/mastodon/containers.scss
+++ b/app/javascript/styles/mastodon/containers.scss
@@ -10,12 +10,10 @@
 }
 
 .logo-container {
-  margin: 100px auto;
-  margin-bottom: 50px;
+  margin: 100px auto 50px;
 
-  @media screen and (max-width: 400px) {
-    margin: 30px auto;
-    margin-bottom: 20px;
+  @media screen and (max-width: 500px) {
+    margin: 40px auto 0;
   }
 
   h1 {
diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss
index 3ea104786..91888d305 100644
--- a/app/javascript/styles/mastodon/forms.scss
+++ b/app/javascript/styles/mastodon/forms.scss
@@ -854,13 +854,19 @@ code {
     flex: 1;
     flex-direction: column;
     flex-shrink: 1;
+    max-width: 50%;
 
     &-sep {
+      align-self: center;
       flex-grow: 0;
       overflow: visible;
       position: relative;
       z-index: 1;
     }
+
+    p {
+      word-break: break-word;
+    }
   }
 
   .account__avatar {
@@ -882,12 +888,13 @@ code {
       height: 100%;
       left: 50%;
       position: absolute;
+      top: 0;
       width: 1px;
     }
   }
 
   &__row {
-    align-items: center;
+    align-items: flex-start;
     display: flex;
     flex-direction: row;
   }