Fix “Mention” appearing for otherwise filtered posts (#32356)
This commit is contained in:
		
							parent
							
								
									cdf603239e
								
							
						
					
					
						commit
						a5a3733c97
					
				@ -13,6 +13,7 @@ import {
 | 
				
			|||||||
import type { IconProp } from 'mastodon/components/icon';
 | 
					import type { IconProp } from 'mastodon/components/icon';
 | 
				
			||||||
import { Icon } from 'mastodon/components/icon';
 | 
					import { Icon } from 'mastodon/components/icon';
 | 
				
			||||||
import Status from 'mastodon/containers/status_container';
 | 
					import Status from 'mastodon/containers/status_container';
 | 
				
			||||||
 | 
					import { getStatusHidden } from 'mastodon/selectors/filters';
 | 
				
			||||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
 | 
					import { useAppSelector, useAppDispatch } from 'mastodon/store';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { DisplayedName } from './displayed_name';
 | 
					import { DisplayedName } from './displayed_name';
 | 
				
			||||||
@ -48,6 +49,12 @@ export const NotificationWithStatus: React.FC<{
 | 
				
			|||||||
    (state) => state.statuses.getIn([statusId, 'visibility']) === 'direct',
 | 
					    (state) => state.statuses.getIn([statusId, 'visibility']) === 'direct',
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const isFiltered = useAppSelector(
 | 
				
			||||||
 | 
					    (state) =>
 | 
				
			||||||
 | 
					      statusId &&
 | 
				
			||||||
 | 
					      getStatusHidden(state, { id: statusId, contextType: 'notifications' }),
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handlers = useMemo(
 | 
					  const handlers = useMemo(
 | 
				
			||||||
    () => ({
 | 
					    () => ({
 | 
				
			||||||
      open: () => {
 | 
					      open: () => {
 | 
				
			||||||
@ -73,7 +80,7 @@ export const NotificationWithStatus: React.FC<{
 | 
				
			|||||||
    [dispatch, statusId],
 | 
					    [dispatch, statusId],
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!statusId) return null;
 | 
					  if (!statusId || isFiltered) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <HotKeys handlers={handlers}>
 | 
					    <HotKeys handlers={handlers}>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										50
									
								
								app/javascript/mastodon/selectors/filters.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								app/javascript/mastodon/selectors/filters.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					import { createSelector } from '@reduxjs/toolkit';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import type { RootState } from 'mastodon/store';
 | 
				
			||||||
 | 
					import { toServerSideType } from 'mastodon/utils/filters';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: move to `app/javascript/mastodon/models` and use more globally
 | 
				
			||||||
 | 
					type Filter = Immutable.Map<string, unknown>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: move to `app/javascript/mastodon/models` and use more globally
 | 
				
			||||||
 | 
					type FilterResult = Immutable.Map<string, unknown>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getFilters = createSelector(
 | 
				
			||||||
 | 
					  [
 | 
				
			||||||
 | 
					    (state: RootState) => state.filters as Immutable.Map<string, Filter>,
 | 
				
			||||||
 | 
					    (_, { contextType }: { contextType: string }) => contextType,
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  (filters, contextType) => {
 | 
				
			||||||
 | 
					    if (!contextType) {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const now = new Date();
 | 
				
			||||||
 | 
					    const serverSideType = toServerSideType(contextType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return filters.filter((filter) => {
 | 
				
			||||||
 | 
					      const context = filter.get('context') as Immutable.List<string>;
 | 
				
			||||||
 | 
					      const expiration = filter.get('expires_at') as Date | null;
 | 
				
			||||||
 | 
					      return (
 | 
				
			||||||
 | 
					        context.includes(serverSideType) &&
 | 
				
			||||||
 | 
					        (expiration === null || expiration > now)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getStatusHidden = (
 | 
				
			||||||
 | 
					  state: RootState,
 | 
				
			||||||
 | 
					  { id, contextType }: { id: string; contextType: string },
 | 
				
			||||||
 | 
					) => {
 | 
				
			||||||
 | 
					  const filters = getFilters(state, { contextType });
 | 
				
			||||||
 | 
					  if (filters === null) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const filtered = state.statuses.getIn([id, 'filtered']) as
 | 
				
			||||||
 | 
					    | Immutable.List<FilterResult>
 | 
				
			||||||
 | 
					    | undefined;
 | 
				
			||||||
 | 
					  return filtered?.some(
 | 
				
			||||||
 | 
					    (result) =>
 | 
				
			||||||
 | 
					      filters.getIn([result.get('filter'), 'filter_action']) === 'hide',
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,23 +1,12 @@
 | 
				
			|||||||
import { createSelector } from '@reduxjs/toolkit';
 | 
					import { createSelector } from '@reduxjs/toolkit';
 | 
				
			||||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
 | 
					import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { toServerSideType } from 'mastodon/utils/filters';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { me } from '../initial_state';
 | 
					import { me } from '../initial_state';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { getFilters } from './filters';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { makeGetAccount } from "./accounts";
 | 
					export { makeGetAccount } from "./accounts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getFilters = createSelector([state => state.get('filters'), (_, { contextType }) => contextType], (filters, contextType) => {
 | 
					 | 
				
			||||||
  if (!contextType) {
 | 
					 | 
				
			||||||
    return null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const now = new Date();
 | 
					 | 
				
			||||||
  const serverSideType = toServerSideType(contextType);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return filters.filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || filter.get('expires_at') > now));
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const makeGetStatus = () => {
 | 
					export const makeGetStatus = () => {
 | 
				
			||||||
  return createSelector(
 | 
					  return createSelector(
 | 
				
			||||||
    [
 | 
					    [
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user