Merge pull request #1179 from ThibG/glitch-soc/merge-upstream
Merge upstream changes
This commit is contained in:
@@ -23,6 +23,7 @@ export function blockDomain(domain) {
|
||||
api(getState).post('/api/v1/domain_blocks', { domain }).then(() => {
|
||||
const at_domain = '@' + domain;
|
||||
const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id'));
|
||||
|
||||
dispatch(blockDomainSuccess(domain, accounts));
|
||||
}).catch(err => {
|
||||
dispatch(blockDomainFail(domain, err));
|
||||
|
@@ -10,6 +10,10 @@ export const SEARCH_FETCH_REQUEST = 'SEARCH_FETCH_REQUEST';
|
||||
export const SEARCH_FETCH_SUCCESS = 'SEARCH_FETCH_SUCCESS';
|
||||
export const SEARCH_FETCH_FAIL = 'SEARCH_FETCH_FAIL';
|
||||
|
||||
export const SEARCH_EXPAND_REQUEST = 'SEARCH_EXPAND_REQUEST';
|
||||
export const SEARCH_EXPAND_SUCCESS = 'SEARCH_EXPAND_SUCCESS';
|
||||
export const SEARCH_EXPAND_FAIL = 'SEARCH_EXPAND_FAIL';
|
||||
|
||||
export function changeSearch(value) {
|
||||
return {
|
||||
type: SEARCH_CHANGE,
|
||||
@@ -77,8 +81,50 @@ export function fetchSearchFail(error) {
|
||||
};
|
||||
};
|
||||
|
||||
export function showSearch() {
|
||||
return {
|
||||
type: SEARCH_SHOW,
|
||||
};
|
||||
export const expandSearch = type => (dispatch, getState) => {
|
||||
const value = getState().getIn(['search', 'value']);
|
||||
const offset = getState().getIn(['search', 'results', type]).size;
|
||||
|
||||
dispatch(expandSearchRequest());
|
||||
|
||||
api(getState).get('/api/v2/search', {
|
||||
params: {
|
||||
q: value,
|
||||
type,
|
||||
offset,
|
||||
},
|
||||
}).then(({ data }) => {
|
||||
if (data.accounts) {
|
||||
dispatch(importFetchedAccounts(data.accounts));
|
||||
}
|
||||
|
||||
if (data.statuses) {
|
||||
dispatch(importFetchedStatuses(data.statuses));
|
||||
}
|
||||
|
||||
dispatch(expandSearchSuccess(data, value, type));
|
||||
dispatch(fetchRelationships(data.accounts.map(item => item.id)));
|
||||
}).catch(error => {
|
||||
dispatch(expandSearchFail(error));
|
||||
});
|
||||
};
|
||||
|
||||
export const expandSearchRequest = () => ({
|
||||
type: SEARCH_EXPAND_REQUEST,
|
||||
});
|
||||
|
||||
export const expandSearchSuccess = (results, searchTerm, searchType) => ({
|
||||
type: SEARCH_EXPAND_SUCCESS,
|
||||
results,
|
||||
searchTerm,
|
||||
searchType,
|
||||
});
|
||||
|
||||
export const expandSearchFail = error => ({
|
||||
type: SEARCH_EXPAND_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
export const showSearch = () => ({
|
||||
type: SEARCH_SHOW,
|
||||
});
|
||||
|
@@ -51,6 +51,7 @@ export default class StatusContent extends React.PureComponent {
|
||||
} else {
|
||||
link.addEventListener('click', this.onLinkClick.bind(this), false);
|
||||
link.setAttribute('title', link.href);
|
||||
link.classList.add('unhandled-link');
|
||||
}
|
||||
|
||||
link.setAttribute('target', '_blank');
|
||||
|
@@ -8,6 +8,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import Hashtag from 'flavours/glitch/components/hashtag';
|
||||
import Icon from 'flavours/glitch/components/icon';
|
||||
import { searchEnabled } from 'flavours/glitch/util/initial_state';
|
||||
import LoadMore from 'flavours/glitch/components/load_more';
|
||||
|
||||
const messages = defineMessages({
|
||||
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
|
||||
@@ -20,15 +21,24 @@ class SearchResults extends ImmutablePureComponent {
|
||||
results: ImmutablePropTypes.map.isRequired,
|
||||
suggestions: ImmutablePropTypes.list.isRequired,
|
||||
fetchSuggestions: PropTypes.func.isRequired,
|
||||
expandSearch: PropTypes.func.isRequired,
|
||||
dismissSuggestion: PropTypes.func.isRequired,
|
||||
searchTerm: PropTypes.string,
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount () {
|
||||
this.props.fetchSuggestions();
|
||||
if (this.props.searchTerm === '') {
|
||||
this.props.fetchSuggestions();
|
||||
}
|
||||
}
|
||||
|
||||
handleLoadMoreAccounts = () => this.props.expandSearch('accounts');
|
||||
|
||||
handleLoadMoreStatuses = () => this.props.expandSearch('statuses');
|
||||
|
||||
handleLoadMoreHashtags = () => this.props.expandSearch('hashtags');
|
||||
|
||||
render () {
|
||||
const { intl, results, suggestions, dismissSuggestion, searchTerm } = this.props;
|
||||
|
||||
@@ -75,6 +85,8 @@ class SearchResults extends ImmutablePureComponent {
|
||||
<h5><Icon icon='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
|
||||
|
||||
{results.get('accounts').map(accountId => <AccountContainer id={accountId} key={accountId} />)}
|
||||
|
||||
{results.get('accounts').size >= 5 && <LoadMore visible onClick={this.handleLoadMoreAccounts} />}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -86,6 +98,8 @@ class SearchResults extends ImmutablePureComponent {
|
||||
<h5><Icon icon='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
|
||||
|
||||
{results.get('statuses').map(statusId => <StatusContainer id={statusId} key={statusId}/>)}
|
||||
|
||||
{results.get('statuses').size >= 5 && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -97,6 +111,8 @@ class SearchResults extends ImmutablePureComponent {
|
||||
<h5><Icon icon='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
|
||||
|
||||
{results.get('hashtags').map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
|
||||
|
||||
{results.get('hashtags').size >= 5 && <LoadMore visible onClick={this.handleLoadMoreHashtags} />}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { connect } from 'react-redux';
|
||||
import SearchResults from '../components/search_results';
|
||||
import { fetchSuggestions, dismissSuggestion } from '../../../actions/suggestions';
|
||||
import { fetchSuggestions, dismissSuggestion } from 'mastodon/actions/suggestions';
|
||||
import { expandSearch } from 'mastodon/actions/search';
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
results: state.getIn(['search', 'results']),
|
||||
@@ -10,6 +11,7 @@ const mapStateToProps = state => ({
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
fetchSuggestions: () => dispatch(fetchSuggestions()),
|
||||
expandSearch: type => dispatch(expandSearch(type)),
|
||||
dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))),
|
||||
});
|
||||
|
||||
|
@@ -8,6 +8,8 @@ import {
|
||||
CONVERSATIONS_UPDATE,
|
||||
CONVERSATIONS_READ,
|
||||
} from '../actions/conversations';
|
||||
import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'flavours/glitch/actions/accounts';
|
||||
import { DOMAIN_BLOCK_SUCCESS } from 'flavours/glitch/actions/domain_blocks';
|
||||
import compareId from 'flavours/glitch/util/compare_id';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
@@ -74,6 +76,10 @@ const expandNormalizedConversations = (state, conversations, next, isLoadingRece
|
||||
});
|
||||
};
|
||||
|
||||
const filterConversations = (state, accountIds) => {
|
||||
return state.update('items', list => list.filterNot(item => item.get('accounts').some(accountId => accountIds.includes(accountId))));
|
||||
};
|
||||
|
||||
export default function conversations(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case CONVERSATIONS_FETCH_REQUEST:
|
||||
@@ -96,6 +102,11 @@ export default function conversations(state = initialState, action) {
|
||||
|
||||
return item;
|
||||
}));
|
||||
case ACCOUNT_BLOCK_SUCCESS:
|
||||
case ACCOUNT_MUTE_SUCCESS:
|
||||
return filterConversations(state, [action.relationship.id]);
|
||||
case DOMAIN_BLOCK_SUCCESS:
|
||||
return filterConversations(state, action.accounts);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ import {
|
||||
ACCOUNT_BLOCK_SUCCESS,
|
||||
ACCOUNT_MUTE_SUCCESS,
|
||||
} from 'flavours/glitch/actions/accounts';
|
||||
import { DOMAIN_BLOCK_SUCCESS } from 'flavours/glitch/actions/domain_blocks';
|
||||
import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from 'flavours/glitch/actions/timelines';
|
||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||
import compareId from 'flavours/glitch/util/compare_id';
|
||||
@@ -110,8 +111,8 @@ const expandNormalizedNotifications = (state, notifications, next, usePendingIte
|
||||
});
|
||||
};
|
||||
|
||||
const filterNotifications = (state, relationship) => {
|
||||
const helper = list => list.filterNot(item => item !== null && item.get('account') === relationship.id);
|
||||
const filterNotifications = (state, accountIds) => {
|
||||
const helper = list => list.filterNot(item => item !== null && accountIds.includes(item.get('account')));
|
||||
return state.update('items', helper).update('pendingItems', helper);
|
||||
};
|
||||
|
||||
@@ -217,9 +218,11 @@ export default function notifications(state = initialState, action) {
|
||||
case NOTIFICATIONS_EXPAND_SUCCESS:
|
||||
return expandNormalizedNotifications(state, action.notifications, action.next, action.usePendingItems);
|
||||
case ACCOUNT_BLOCK_SUCCESS:
|
||||
return filterNotifications(state, action.relationship);
|
||||
return filterNotifications(state, [action.relationship.id]);
|
||||
case ACCOUNT_MUTE_SUCCESS:
|
||||
return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state;
|
||||
return action.relationship.muting_notifications ? filterNotifications(state, [action.relationship.id]) : state;
|
||||
case DOMAIN_BLOCK_SUCCESS:
|
||||
return filterNotifications(state, action.accounts);
|
||||
case NOTIFICATIONS_CLEAR:
|
||||
return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false);
|
||||
case TIMELINE_DELETE:
|
||||
|
@@ -3,6 +3,7 @@ import {
|
||||
SEARCH_CLEAR,
|
||||
SEARCH_FETCH_SUCCESS,
|
||||
SEARCH_SHOW,
|
||||
SEARCH_EXPAND_SUCCESS,
|
||||
} from 'flavours/glitch/actions/search';
|
||||
import {
|
||||
COMPOSE_MENTION,
|
||||
@@ -42,6 +43,8 @@ export default function search(state = initialState, action) {
|
||||
statuses: ImmutableList(action.results.statuses.map(item => item.id)),
|
||||
hashtags: fromJS(action.results.hashtags),
|
||||
})).set('submitted', true).set('searchTerm', action.searchTerm);
|
||||
case SEARCH_EXPAND_SUCCESS:
|
||||
return state.updateIn(['results', action.searchType], list => list.concat(action.results[action.searchType].map(item => item.id)));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ import {
|
||||
SUGGESTIONS_FETCH_FAIL,
|
||||
SUGGESTIONS_DISMISS,
|
||||
} from '../actions/suggestions';
|
||||
import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'mastodon/actions/accounts';
|
||||
import { DOMAIN_BLOCK_SUCCESS } from 'mastodon/actions/domain_blocks';
|
||||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||
|
||||
const initialState = ImmutableMap({
|
||||
@@ -24,6 +26,11 @@ export default function suggestionsReducer(state = initialState, action) {
|
||||
return state.set('isLoading', false);
|
||||
case SUGGESTIONS_DISMISS:
|
||||
return state.update('items', list => list.filterNot(id => id === action.id));
|
||||
case ACCOUNT_BLOCK_SUCCESS:
|
||||
case ACCOUNT_MUTE_SUCCESS:
|
||||
return state.update('items', list => list.filterNot(id => id === action.relationship.id));
|
||||
case DOMAIN_BLOCK_SUCCESS:
|
||||
return state.update('items', list => list.filterNot(id => action.accounts.includes(id)));
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@@ -79,8 +79,9 @@
|
||||
}
|
||||
|
||||
.search-results__info {
|
||||
padding: 10px;
|
||||
color: $secondary-text-color;
|
||||
padding: 20px;
|
||||
color: $darker-text-color;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.trends {
|
||||
|
@@ -133,6 +133,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
a.unhandled-link {
|
||||
color: lighten($ui-highlight-color, 8%);
|
||||
}
|
||||
|
||||
.status__content__spoiler-link {
|
||||
background: lighten($ui-base-color, 30%);
|
||||
|
||||
|
Reference in New Issue
Block a user