Merge tag 'v2.6.5' into chinwag-2.6.5
This commit is contained in:
commit
065f346467
63 changed files with 372 additions and 244 deletions
|
|
@ -145,12 +145,14 @@ export function fetchAccountFail(id, error) {
|
|||
export function followAccount(id, reblogs = true) {
|
||||
return (dispatch, getState) => {
|
||||
const alreadyFollowing = getState().getIn(['relationships', id, 'following']);
|
||||
dispatch(followAccountRequest(id));
|
||||
const locked = getState().getIn(['accounts', id, 'locked'], false);
|
||||
|
||||
dispatch(followAccountRequest(id, locked));
|
||||
|
||||
api(getState).post(`/api/v1/accounts/${id}/follow`, { reblogs }).then(response => {
|
||||
dispatch(followAccountSuccess(response.data, alreadyFollowing));
|
||||
}).catch(error => {
|
||||
dispatch(followAccountFail(error));
|
||||
dispatch(followAccountFail(error, locked));
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
@ -167,10 +169,12 @@ export function unfollowAccount(id) {
|
|||
};
|
||||
};
|
||||
|
||||
export function followAccountRequest(id) {
|
||||
export function followAccountRequest(id, locked) {
|
||||
return {
|
||||
type: ACCOUNT_FOLLOW_REQUEST,
|
||||
id,
|
||||
locked,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -179,13 +183,16 @@ export function followAccountSuccess(relationship, alreadyFollowing) {
|
|||
type: ACCOUNT_FOLLOW_SUCCESS,
|
||||
relationship,
|
||||
alreadyFollowing,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
export function followAccountFail(error) {
|
||||
export function followAccountFail(error, locked) {
|
||||
return {
|
||||
type: ACCOUNT_FOLLOW_FAIL,
|
||||
error,
|
||||
locked,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -193,6 +200,7 @@ export function unfollowAccountRequest(id) {
|
|||
return {
|
||||
type: ACCOUNT_UNFOLLOW_REQUEST,
|
||||
id,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -201,6 +209,7 @@ export function unfollowAccountSuccess(relationship, statuses) {
|
|||
type: ACCOUNT_UNFOLLOW_SUCCESS,
|
||||
relationship,
|
||||
statuses,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -208,6 +217,7 @@ export function unfollowAccountFail(error) {
|
|||
return {
|
||||
type: ACCOUNT_UNFOLLOW_FAIL,
|
||||
error,
|
||||
skipLoading: true,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ class Status extends ImmutablePureComponent {
|
|||
unread: PropTypes.bool,
|
||||
onMoveUp: PropTypes.func,
|
||||
onMoveDown: PropTypes.func,
|
||||
showThread: PropTypes.bool,
|
||||
};
|
||||
|
||||
// Avoid checking props that are functions (and whose equality will always
|
||||
|
|
@ -168,7 +169,7 @@ class Status extends ImmutablePureComponent {
|
|||
let media = null;
|
||||
let statusAvatar, prepend, rebloggedByText;
|
||||
|
||||
const { intl, hidden, featured, otherAccounts, unread } = this.props;
|
||||
const { intl, hidden, featured, otherAccounts, unread, showThread } = this.props;
|
||||
|
||||
let { status, account, ...other } = this.props;
|
||||
|
||||
|
|
@ -309,6 +310,12 @@ class Status extends ImmutablePureComponent {
|
|||
|
||||
{media}
|
||||
|
||||
{showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) && (
|
||||
<button className='status__content__read-more-button' onClick={this.handleClick}>
|
||||
<FormattedMessage id='status.show_thread' defaultMessage='Show thread' />
|
||||
</button>
|
||||
)}
|
||||
|
||||
<StatusActionBar status={status} account={account} {...other} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
|
||||
let menu = [];
|
||||
let reblogIcon = 'retweet';
|
||||
let replyIcon;
|
||||
let replyTitle;
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen });
|
||||
|
|
@ -191,10 +190,8 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
if (status.get('in_reply_to_id', null) === null) {
|
||||
replyIcon = 'reply';
|
||||
replyTitle = intl.formatMessage(messages.reply);
|
||||
} else {
|
||||
replyIcon = 'reply-all';
|
||||
replyTitle = intl.formatMessage(messages.replyAll);
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +201,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<div className='status__action-bar'>
|
||||
<div className='status__action-bar__counter'><IconButton className='status__action-bar-button' disabled={anonymousAccess} title={replyTitle} icon={replyIcon} onClick={this.handleReplyClick} /><span className='status__action-bar__counter__label' >{obfuscatedCount(status.get('replies_count'))}</span></div>
|
||||
<div className='status__action-bar__counter'><IconButton className='status__action-bar-button' disabled={anonymousAccess} title={replyTitle} icon='reply' onClick={this.handleReplyClick} /><span className='status__action-bar__counter__label' >{obfuscatedCount(status.get('replies_count'))}</span></div>
|
||||
<IconButton className='status__action-bar-button' disabled={anonymousAccess || !publicStatus} active={status.get('reblogged')} pressed={status.get('reblogged')} title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} />
|
||||
<IconButton className='status__action-bar-button star-icon' disabled={anonymousAccess} animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />
|
||||
{shareButton}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
showThread
|
||||
/>
|
||||
))
|
||||
) : null;
|
||||
|
|
@ -117,6 +118,7 @@ export default class StatusList extends ImmutablePureComponent {
|
|||
onMoveUp={this.handleMoveUp}
|
||||
onMoveDown={this.handleMoveDown}
|
||||
contextType={timelineId}
|
||||
showThread
|
||||
/>
|
||||
)).concat(scrollableContent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class ActionBar extends React.PureComponent {
|
|||
|
||||
return (
|
||||
<div className='detailed-status__action-bar'>
|
||||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_id', null) === null ? 'reply' : 'reply-all'} onClick={this.handleReplyClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon='reply' onClick={this.handleReplyClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton disabled={reblog_disabled} active={status.get('reblogged')} title={reblog_disabled ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)} icon={reblogIcon} onClick={this.handleReblogClick} /></div>
|
||||
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} /></div>
|
||||
{shareButton}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ export default class Card extends React.PureComponent {
|
|||
};
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (this.props.card !== nextProps.card) {
|
||||
if (!Immutable.is(this.props.card, nextProps.card)) {
|
||||
this.setState({ embedded: false });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,13 @@ const expandNormalizedConversations = (state, conversations, next) => {
|
|||
|
||||
list = list.concat(items);
|
||||
|
||||
return list.sortBy(x => x.get('last_status'), (a, b) => compareId(a, b) * -1);
|
||||
return list.sortBy(x => x.get('last_status'), (a, b) => {
|
||||
if(a === null || b === null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return compareId(a, b) * -1;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import {
|
||||
ACCOUNT_FOLLOW_SUCCESS,
|
||||
ACCOUNT_FOLLOW_REQUEST,
|
||||
ACCOUNT_FOLLOW_FAIL,
|
||||
ACCOUNT_UNFOLLOW_SUCCESS,
|
||||
ACCOUNT_UNFOLLOW_REQUEST,
|
||||
ACCOUNT_UNFOLLOW_FAIL,
|
||||
ACCOUNT_BLOCK_SUCCESS,
|
||||
ACCOUNT_UNBLOCK_SUCCESS,
|
||||
ACCOUNT_MUTE_SUCCESS,
|
||||
|
|
@ -37,6 +41,14 @@ const initialState = ImmutableMap();
|
|||
|
||||
export default function relationships(state = initialState, action) {
|
||||
switch(action.type) {
|
||||
case ACCOUNT_FOLLOW_REQUEST:
|
||||
return state.setIn([action.id, action.locked ? 'requested' : 'following'], true);
|
||||
case ACCOUNT_FOLLOW_FAIL:
|
||||
return state.setIn([action.id, action.locked ? 'requested' : 'following'], false);
|
||||
case ACCOUNT_UNFOLLOW_REQUEST:
|
||||
return state.setIn([action.id, 'following'], false);
|
||||
case ACCOUNT_UNFOLLOW_FAIL:
|
||||
return state.setIn([action.id, 'following'], true);
|
||||
case ACCOUNT_FOLLOW_SUCCESS:
|
||||
case ACCOUNT_UNFOLLOW_SUCCESS:
|
||||
case ACCOUNT_BLOCK_SUCCESS:
|
||||
|
|
|
|||
|
|
@ -38,11 +38,11 @@ export default function statuses(state = initialState, action) {
|
|||
case FAVOURITE_REQUEST:
|
||||
return state.setIn([action.status.get('id'), 'favourited'], true);
|
||||
case FAVOURITE_FAIL:
|
||||
return state.setIn([action.status.get('id'), 'favourited'], false);
|
||||
return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], false);
|
||||
case REBLOG_REQUEST:
|
||||
return state.setIn([action.status.get('id'), 'reblogged'], true);
|
||||
case REBLOG_FAIL:
|
||||
return state.setIn([action.status.get('id'), 'reblogged'], false);
|
||||
return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false);
|
||||
case STATUS_MUTE_SUCCESS:
|
||||
return state.setIn([action.id, 'muted'], true);
|
||||
case STATUS_UNMUTE_SUCCESS:
|
||||
|
|
|
|||
|
|
@ -1847,7 +1847,7 @@ a.account__display-name {
|
|||
}
|
||||
|
||||
.column {
|
||||
width: 330px;
|
||||
width: 350px;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
|
|
|||
|
|
@ -330,9 +330,12 @@ code {
|
|||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=number],
|
||||
input[type=email],
|
||||
input[type=password] {
|
||||
border-bottom-color: $valid-value-color;
|
||||
input[type=password],
|
||||
textarea,
|
||||
select {
|
||||
border-color: lighten($error-red, 12%);
|
||||
}
|
||||
|
||||
.error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue