Search component
This commit is contained in:
		
							parent
							
								
									8152584cf5
								
							
						
					
					
						commit
						f0bdfadab7
					
				
							
								
								
									
										51
									
								
								app/assets/javascripts/components/actions/search.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								app/assets/javascripts/components/actions/search.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					import api from '../api'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const SEARCH_CHANGE            = 'SEARCH_CHANGE';
 | 
				
			||||||
 | 
					export const SEARCH_SUGGESTIONS_CLEAR = 'SEARCH_SUGGESTIONS_CLEAR';
 | 
				
			||||||
 | 
					export const SEARCH_SUGGESTIONS_READY = 'SEARCH_SUGGESTIONS_READY';
 | 
				
			||||||
 | 
					export const SEARCH_RESET             = 'SEARCH_RESET';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function changeSearch(value) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SEARCH_CHANGE,
 | 
				
			||||||
 | 
					    value
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function clearSearchSuggestions() {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SEARCH_SUGGESTIONS_CLEAR
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function readySearchSuggestions(value, accounts) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SEARCH_SUGGESTIONS_READY,
 | 
				
			||||||
 | 
					    value,
 | 
				
			||||||
 | 
					    accounts
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function fetchSearchSuggestions(value) {
 | 
				
			||||||
 | 
					  return (dispatch, getState) => {
 | 
				
			||||||
 | 
					    if (getState().getIn(['search', 'loaded_value']) === value) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    api(getState).get('/api/v1/accounts/search', {
 | 
				
			||||||
 | 
					      params: {
 | 
				
			||||||
 | 
					        q: value,
 | 
				
			||||||
 | 
					        resolve: true,
 | 
				
			||||||
 | 
					        limit: 4
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }).then(response => {
 | 
				
			||||||
 | 
					      dispatch(readySearchSuggestions(value, response.data));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function resetSearch() {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: SEARCH_RESET
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -0,0 +1,126 @@
 | 
				
			|||||||
 | 
					import PureRenderMixin from 'react-addons-pure-render-mixin';
 | 
				
			||||||
 | 
					import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
				
			||||||
 | 
					import Autosuggest from 'react-autosuggest';
 | 
				
			||||||
 | 
					import AutosuggestAccountContainer from '../containers/autosuggest_account_container';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getSuggestionValue = suggestion => suggestion.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const renderSuggestion = suggestion => {
 | 
				
			||||||
 | 
					  if (suggestion.type === 'account') {
 | 
				
			||||||
 | 
					    return <AutosuggestAccountContainer id={suggestion.id} />;
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    return <span>#{suggestion.id}</span>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const renderSectionTitle = section => (
 | 
				
			||||||
 | 
					  <strong>{section.title}</strong>
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getSectionSuggestions = section => section.items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const outerStyle = {
 | 
				
			||||||
 | 
					  padding: '10px',
 | 
				
			||||||
 | 
					  lineHeight: '20px',
 | 
				
			||||||
 | 
					  position: 'relative'
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const inputStyle = {
 | 
				
			||||||
 | 
					  boxSizing: 'border-box',
 | 
				
			||||||
 | 
					  display: 'block',
 | 
				
			||||||
 | 
					  width: '100%',
 | 
				
			||||||
 | 
					  border: 'none',
 | 
				
			||||||
 | 
					  padding: '10px',
 | 
				
			||||||
 | 
					  paddingRight: '30px',
 | 
				
			||||||
 | 
					  fontFamily: 'Roboto',
 | 
				
			||||||
 | 
					  background: '#282c37',
 | 
				
			||||||
 | 
					  color: '#9baec8',
 | 
				
			||||||
 | 
					  fontSize: '14px',
 | 
				
			||||||
 | 
					  margin: '0'
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const iconStyle = {
 | 
				
			||||||
 | 
					  position: 'absolute',
 | 
				
			||||||
 | 
					  top: '18px',
 | 
				
			||||||
 | 
					  right: '20px',
 | 
				
			||||||
 | 
					  color: '#9baec8',
 | 
				
			||||||
 | 
					  fontSize: '18px',
 | 
				
			||||||
 | 
					  pointerEvents: 'none'
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Search = React.createClass({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  contextTypes: {
 | 
				
			||||||
 | 
					    router: React.PropTypes.object
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  propTypes: {
 | 
				
			||||||
 | 
					    suggestions: React.PropTypes.array.isRequired,
 | 
				
			||||||
 | 
					    value: React.PropTypes.string.isRequired,
 | 
				
			||||||
 | 
					    onChange: React.PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    onClear: React.PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    onFetch: React.PropTypes.func.isRequired,
 | 
				
			||||||
 | 
					    onReset: React.PropTypes.func.isRequired
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mixins: [PureRenderMixin],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onChange (_, { newValue }) {
 | 
				
			||||||
 | 
					    if (typeof newValue !== 'string') {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.props.onChange(newValue);
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSuggestionsClearRequested () {
 | 
				
			||||||
 | 
					    this.props.onClear();
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSuggestionsFetchRequested ({ value }) {
 | 
				
			||||||
 | 
					    value = value.replace('#', '');
 | 
				
			||||||
 | 
					    this.props.onFetch(value.trim());
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onSuggestionSelected (_, { suggestion }) {
 | 
				
			||||||
 | 
					    if (suggestion.type === 'account') {
 | 
				
			||||||
 | 
					      this.context.router.push(`/accounts/${suggestion.id}`);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.context.router.push(`/statuses/tag/${suggestion.id}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  render () {
 | 
				
			||||||
 | 
					    const inputProps = {
 | 
				
			||||||
 | 
					      placeholder: 'Search',
 | 
				
			||||||
 | 
					      value: this.props.value,
 | 
				
			||||||
 | 
					      onChange: this.onChange,
 | 
				
			||||||
 | 
					      style: inputStyle
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div style={outerStyle}>
 | 
				
			||||||
 | 
					        <Autosuggest
 | 
				
			||||||
 | 
					          multiSection={true}
 | 
				
			||||||
 | 
					          suggestions={this.props.suggestions}
 | 
				
			||||||
 | 
					          focusFirstSuggestion={true}
 | 
				
			||||||
 | 
					          focusInputOnSuggestionClick={false}
 | 
				
			||||||
 | 
					          alwaysRenderSuggestions={false}
 | 
				
			||||||
 | 
					          onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
 | 
				
			||||||
 | 
					          onSuggestionsClearRequested={this.onSuggestionsClearRequested}
 | 
				
			||||||
 | 
					          onSuggestionSelected={this.onSuggestionSelected}
 | 
				
			||||||
 | 
					          getSuggestionValue={getSuggestionValue}
 | 
				
			||||||
 | 
					          renderSuggestion={renderSuggestion}
 | 
				
			||||||
 | 
					          renderSectionTitle={renderSectionTitle}
 | 
				
			||||||
 | 
					          getSectionSuggestions={getSectionSuggestions}
 | 
				
			||||||
 | 
					          inputProps={inputProps}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div style={iconStyle}><i className='fa fa-search' /></div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Search;
 | 
				
			||||||
@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					import { connect } from 'react-redux';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  changeSearch,
 | 
				
			||||||
 | 
					  clearSearchSuggestions,
 | 
				
			||||||
 | 
					  fetchSearchSuggestions,
 | 
				
			||||||
 | 
					  resetSearch
 | 
				
			||||||
 | 
					} from '../../../actions/search';
 | 
				
			||||||
 | 
					import Search from '../components/search';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mapStateToProps = state => ({
 | 
				
			||||||
 | 
					  suggestions: state.getIn(['search', 'suggestions']),
 | 
				
			||||||
 | 
					  value: state.getIn(['search', 'value'])
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const mapDispatchToProps = dispatch => ({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onChange (value) {
 | 
				
			||||||
 | 
					    dispatch(changeSearch(value));
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onClear () {
 | 
				
			||||||
 | 
					    dispatch(clearSearchSuggestions());
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onFetch (value) {
 | 
				
			||||||
 | 
					    dispatch(fetchSearchSuggestions(value));
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onReset () {
 | 
				
			||||||
 | 
					    dispatch(resetSearch());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default connect(mapStateToProps, mapDispatchToProps)(Search);
 | 
				
			||||||
@ -5,6 +5,7 @@ import UploadFormContainer  from '../ui/containers/upload_form_container';
 | 
				
			|||||||
import NavigationContainer  from '../ui/containers/navigation_container';
 | 
					import NavigationContainer  from '../ui/containers/navigation_container';
 | 
				
			||||||
import PureRenderMixin      from 'react-addons-pure-render-mixin';
 | 
					import PureRenderMixin      from 'react-addons-pure-render-mixin';
 | 
				
			||||||
import SuggestionsContainer from './containers/suggestions_container';
 | 
					import SuggestionsContainer from './containers/suggestions_container';
 | 
				
			||||||
 | 
					import SearchContainer      from './containers/search_container';
 | 
				
			||||||
import { fetchSuggestions } from '../../actions/suggestions';
 | 
					import { fetchSuggestions } from '../../actions/suggestions';
 | 
				
			||||||
import { connect }          from 'react-redux';
 | 
					import { connect }          from 'react-redux';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -24,13 +25,13 @@ const Compose = React.createClass({
 | 
				
			|||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <Drawer>
 | 
					      <Drawer>
 | 
				
			||||||
        <div style={{ flex: '1 1 auto' }}>
 | 
					        <div style={{ flex: '1 1 auto' }}>
 | 
				
			||||||
 | 
					          <SearchContainer />
 | 
				
			||||||
          <NavigationContainer />
 | 
					          <NavigationContainer />
 | 
				
			||||||
          <ComposeFormContainer />
 | 
					          <ComposeFormContainer />
 | 
				
			||||||
          <UploadFormContainer />
 | 
					          <UploadFormContainer />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <SuggestionsContainer />
 | 
					        <SuggestionsContainer />
 | 
				
			||||||
        <FollowFormContainer />
 | 
					 | 
				
			||||||
      </Drawer>
 | 
					      </Drawer>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,7 @@ import {
 | 
				
			|||||||
  STATUS_FETCH_SUCCESS,
 | 
					  STATUS_FETCH_SUCCESS,
 | 
				
			||||||
  CONTEXT_FETCH_SUCCESS
 | 
					  CONTEXT_FETCH_SUCCESS
 | 
				
			||||||
} from '../actions/statuses';
 | 
					} from '../actions/statuses';
 | 
				
			||||||
 | 
					import { SEARCH_SUGGESTIONS_READY } from '../actions/search';
 | 
				
			||||||
import Immutable from 'immutable';
 | 
					import Immutable from 'immutable';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const normalizeAccount = (state, account) => state.set(account.id, Immutable.fromJS(account));
 | 
					const normalizeAccount = (state, account) => state.set(account.id, Immutable.fromJS(account));
 | 
				
			||||||
@ -70,6 +71,7 @@ export default function accounts(state = initialState, action) {
 | 
				
			|||||||
    case REBLOGS_FETCH_SUCCESS:
 | 
					    case REBLOGS_FETCH_SUCCESS:
 | 
				
			||||||
    case FAVOURITES_FETCH_SUCCESS:
 | 
					    case FAVOURITES_FETCH_SUCCESS:
 | 
				
			||||||
    case COMPOSE_SUGGESTIONS_READY:
 | 
					    case COMPOSE_SUGGESTIONS_READY:
 | 
				
			||||||
 | 
					    case SEARCH_SUGGESTIONS_READY:
 | 
				
			||||||
      return normalizeAccounts(state, action.accounts);
 | 
					      return normalizeAccounts(state, action.accounts);
 | 
				
			||||||
    case TIMELINE_REFRESH_SUCCESS:
 | 
					    case TIMELINE_REFRESH_SUCCESS:
 | 
				
			||||||
    case TIMELINE_EXPAND_SUCCESS:
 | 
					    case TIMELINE_EXPAND_SUCCESS:
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@ import user_lists            from './user_lists';
 | 
				
			|||||||
import accounts              from './accounts';
 | 
					import accounts              from './accounts';
 | 
				
			||||||
import statuses              from './statuses';
 | 
					import statuses              from './statuses';
 | 
				
			||||||
import relationships         from './relationships';
 | 
					import relationships         from './relationships';
 | 
				
			||||||
 | 
					import search                from './search';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default combineReducers({
 | 
					export default combineReducers({
 | 
				
			||||||
  timelines,
 | 
					  timelines,
 | 
				
			||||||
@ -22,5 +23,6 @@ export default combineReducers({
 | 
				
			|||||||
  user_lists,
 | 
					  user_lists,
 | 
				
			||||||
  accounts,
 | 
					  accounts,
 | 
				
			||||||
  statuses,
 | 
					  statuses,
 | 
				
			||||||
  relationships
 | 
					  relationships,
 | 
				
			||||||
 | 
					  search
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										60
									
								
								app/assets/javascripts/components/reducers/search.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								app/assets/javascripts/components/reducers/search.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					import {
 | 
				
			||||||
 | 
					  SEARCH_CHANGE,
 | 
				
			||||||
 | 
					  SEARCH_SUGGESTIONS_READY,
 | 
				
			||||||
 | 
					  SEARCH_RESET
 | 
				
			||||||
 | 
					} from '../actions/search';
 | 
				
			||||||
 | 
					import Immutable from 'immutable';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const initialState = Immutable.Map({
 | 
				
			||||||
 | 
					  value: '',
 | 
				
			||||||
 | 
					  loaded_value: '',
 | 
				
			||||||
 | 
					  suggestions: []
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const normalizeSuggestions = (state, value, accounts) => {
 | 
				
			||||||
 | 
					  let newSuggestions = [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      title: 'Account',
 | 
				
			||||||
 | 
					      items: accounts.map(item => ({
 | 
				
			||||||
 | 
					        type: 'account',
 | 
				
			||||||
 | 
					        id: item.id,
 | 
				
			||||||
 | 
					        value: item.acct
 | 
				
			||||||
 | 
					      }))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (value.indexOf('@') === -1) {
 | 
				
			||||||
 | 
					    newSuggestions.push({
 | 
				
			||||||
 | 
					      title: 'Hashtag',
 | 
				
			||||||
 | 
					      items: [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          type: 'hashtag',
 | 
				
			||||||
 | 
					          id: value,
 | 
				
			||||||
 | 
					          value: `#${value}`
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return state.withMutations(map => {
 | 
				
			||||||
 | 
					    map.set('suggestions', newSuggestions);
 | 
				
			||||||
 | 
					    map.set('loaded_value', value);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function search(state = initialState, action) {
 | 
				
			||||||
 | 
					  switch(action.type) {
 | 
				
			||||||
 | 
					    case SEARCH_CHANGE:
 | 
				
			||||||
 | 
					      return state.set('value', action.value);
 | 
				
			||||||
 | 
					    case SEARCH_SUGGESTIONS_READY:
 | 
				
			||||||
 | 
					      return normalizeSuggestions(state, action.value, action.accounts);
 | 
				
			||||||
 | 
					    case SEARCH_RESET:
 | 
				
			||||||
 | 
					      return state.withMutations(map => {
 | 
				
			||||||
 | 
					        map.set('suggestions', []);
 | 
				
			||||||
 | 
					        map.set('value', '');
 | 
				
			||||||
 | 
					        map.set('loaded_value', '');
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      return state;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -325,12 +325,22 @@
 | 
				
			|||||||
  top: 100%;
 | 
					  top: 100%;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  z-index: 99;
 | 
					  z-index: 99;
 | 
				
			||||||
 | 
					  box-shadow: 0 0 15px rgba(0, 0, 0, 0.4);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.react-autosuggest__section-title {
 | 
				
			||||||
 | 
					  background: #9baec8;
 | 
				
			||||||
 | 
					  padding: 4px 10px;
 | 
				
			||||||
 | 
					  font-weight: 500;
 | 
				
			||||||
 | 
					  cursor: default;
 | 
				
			||||||
 | 
					  color: #282c37;
 | 
				
			||||||
 | 
					  text-transform: uppercase;
 | 
				
			||||||
 | 
					  font-size: 11px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.react-autosuggest__suggestions-list {
 | 
					.react-autosuggest__suggestions-list {
 | 
				
			||||||
  background: #9baec8;
 | 
					  background: #d9e1e8;
 | 
				
			||||||
  color: #282c37;
 | 
					  color: #282c37;
 | 
				
			||||||
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
 | 
					 | 
				
			||||||
  font-size: 14px;
 | 
					  font-size: 14px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user