Implement feature to add filtered phrases to content warnings
This commit is contained in:
		
							parent
							
								
									42b59b730b
								
							
						
					
					
						commit
						85f3bc1ab3
					
				
					 2 changed files with 26 additions and 7 deletions
				
			
		|  | @ -106,7 +106,7 @@ class Status extends ImmutablePureComponent { | ||||||
|     statusId: undefined, |     statusId: undefined, | ||||||
|     revealBehindCW: undefined, |     revealBehindCW: undefined, | ||||||
|     showCard: false, |     showCard: false, | ||||||
|     bypassFilter: false, |     forceFilter: undefined, | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // Avoid checking props that are functions (and whose equality will always
 |   // Avoid checking props that are functions (and whose equality will always
 | ||||||
|  | @ -127,7 +127,7 @@ class Status extends ImmutablePureComponent { | ||||||
|     'isExpanded', |     'isExpanded', | ||||||
|     'isCollapsed', |     'isCollapsed', | ||||||
|     'showMedia', |     'showMedia', | ||||||
|     'bypassFilter', |     'forceFilter', | ||||||
|   ] |   ] | ||||||
| 
 | 
 | ||||||
|   //  If our settings have changed to disable collapsed statuses, then we
 |   //  If our settings have changed to disable collapsed statuses, then we
 | ||||||
|  | @ -431,11 +431,11 @@ class Status extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|   handleUnfilterClick = e => { |   handleUnfilterClick = e => { | ||||||
|     const { onUnfilter, status } = this.props; |     const { onUnfilter, status } = this.props; | ||||||
|     onUnfilter(status.get('reblog') ? status.get('reblog') : status, () => this.setState({ bypassFilter: true })); |     onUnfilter(status.get('reblog') ? status.get('reblog') : status, () => this.setState({ forceFilter: false })); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleFilterClick = () => { |   handleFilterClick = () => { | ||||||
|     this.setState({ bypassFilter: false }); |     this.setState({ forceFilter: true }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleRef = c => { |   handleRef = c => { | ||||||
|  | @ -496,7 +496,7 @@ class Status extends ImmutablePureComponent { | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((status.get('filtered') || status.getIn(['reblog', 'filtered'])) && !this.state.bypassFilter) { |     if ((status.get('filtered') || status.getIn(['reblog', 'filtered'])) && (this.state.forceFilter === true || settings.get('filtering_behavior') !== 'content_warning')) { | ||||||
|       const minHandlers = this.props.muted ? {} : { |       const minHandlers = this.props.muted ? {} : { | ||||||
|         moveUp: this.handleHotkeyMoveUp, |         moveUp: this.handleHotkeyMoveUp, | ||||||
|         moveDown: this.handleHotkeyMoveDown, |         moveDown: this.handleHotkeyMoveDown, | ||||||
|  | @ -506,7 +506,7 @@ class Status extends ImmutablePureComponent { | ||||||
|         <HotKeys handlers={minHandlers}> |         <HotKeys handlers={minHandlers}> | ||||||
|           <div className='status__wrapper status__wrapper--filtered focusable' tabIndex='0' ref={this.handleRef}> |           <div className='status__wrapper status__wrapper--filtered focusable' tabIndex='0' ref={this.handleRef}> | ||||||
|             <FormattedMessage id='status.filtered' defaultMessage='Filtered' /> |             <FormattedMessage id='status.filtered' defaultMessage='Filtered' /> | ||||||
|             {settings.get('filtering_behavior') === 'hide' && ( |             {settings.get('filtering_behavior') !== 'upstream' && ( | ||||||
|               <button className='status__wrapper--filtered__button' onClick={this.handleUnfilterClick}> |               <button className='status__wrapper--filtered__button' onClick={this.handleUnfilterClick}> | ||||||
|                 <FormattedMessage id='status.show_filter_reason' defaultMessage='Show why' /> |                 <FormattedMessage id='status.show_filter_reason' defaultMessage='Show why' /> | ||||||
|               </button> |               </button> | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | import escapeTextContentForBrowser from 'escape-html'; | ||||||
| import { createSelector } from 'reselect'; | import { createSelector } from 'reselect'; | ||||||
| import { List as ImmutableList, is } from 'immutable'; | import { List as ImmutableList, is } from 'immutable'; | ||||||
| import { me } from 'flavours/glitch/util/initial_state'; | import { me } from 'flavours/glitch/util/initial_state'; | ||||||
|  | @ -90,10 +91,12 @@ export const makeGetStatus = () => { | ||||||
|       (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]), |       (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', id, 'account'])]), | ||||||
|       (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]), |       (state, { id }) => state.getIn(['accounts', state.getIn(['statuses', state.getIn(['statuses', id, 'reblog']), 'account'])]), | ||||||
|       (state, _) => state.getIn(['local_settings', 'filtering_behavior']), |       (state, _) => state.getIn(['local_settings', 'filtering_behavior']), | ||||||
|  |       (state, _) => state.get('filters', ImmutableList()), | ||||||
|  |       (_, { contextType }) => contextType, | ||||||
|       getFiltersRegex, |       getFiltersRegex, | ||||||
|     ], |     ], | ||||||
| 
 | 
 | ||||||
|     (statusBase, statusReblog, accountBase, accountReblog, filteringBehavior, filtersRegex) => { |     (statusBase, statusReblog, accountBase, accountReblog, filteringBehavior, filters, contextType, filtersRegex) => { | ||||||
|       if (!statusBase) { |       if (!statusBase) { | ||||||
|         return null; |         return null; | ||||||
|       } |       } | ||||||
|  | @ -119,6 +122,22 @@ export const makeGetStatus = () => { | ||||||
| 
 | 
 | ||||||
|       if (filtered && filteringBehavior === 'drop') { |       if (filtered && filteringBehavior === 'drop') { | ||||||
|         return null; |         return null; | ||||||
|  |       } else if (filtered && filteringBehavior === 'content_warning') { | ||||||
|  |         let spoilerText = (statusReblog || statusBase).get('spoiler_text', ''); | ||||||
|  |         const searchIndex = (statusReblog || statusBase).get('search_index'); | ||||||
|  |         const serverSideType = toServerSideType(contextType); | ||||||
|  |         const enabledFilters = filters.filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || Date.parse(filter.get('expires_at')) > (new Date()))).toArray(); | ||||||
|  |         const matchingFilters = enabledFilters.filter(filter => { | ||||||
|  |           const regexp = regexFromFilters([filter]); | ||||||
|  |           return regexp.test(searchIndex) && !regexp.test(spoilerText); | ||||||
|  |         }); | ||||||
|  |         if (statusReblog) { | ||||||
|  |           statusReblog = statusReblog.set('spoiler_text', matchingFilters.map(filter => filter.get('phrase')).concat([spoilerText]).filter(cw => !!cw).join(', ')); | ||||||
|  |           statusReblog = statusReblog.update('spoilerHtml', '', spoilerText => matchingFilters.map(filter => escapeTextContentForBrowser(filter.get('phrase'))).concat([spoilerText]).filter(cw => !!cw).join(', ')); | ||||||
|  |         } else { | ||||||
|  |           statusBase = statusBase.set('spoiler_text', matchingFilters.map(filter => filter.get('phrase')).concat([spoilerText]).filter(cw => !!cw).join(', ')); | ||||||
|  |           statusBase = statusBase.update('spoilerHtml', '', spoilerText => matchingFilters.map(filter => escapeTextContentForBrowser(filter.get('phrase'))).concat([spoilerText]).filter(cw => !!cw).join(', ')); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       return statusBase.withMutations(map => { |       return statusBase.withMutations(map => { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue