Merge branch 'profile-media-panel' of gitlab.com:soapbox-pub/soapbox-fe into profile-media-panel

scroll-to-point-in-thread
Mary Kate 2020-08-14 17:46:44 -05:00
commit 368baf818e
8 zmienionych plików z 127 dodań i 24 usunięć

Wyświetl plik

@ -75,7 +75,7 @@ const defaultSettings = ImmutableMap({
community: ImmutableMap({ community: ImmutableMap({
shows: ImmutableMap({ shows: ImmutableMap({
reblog: true, reblog: false,
reply: true, reply: true,
}), }),
other: ImmutableMap({ other: ImmutableMap({

Wyświetl plik

@ -4,7 +4,7 @@ import {
expandHomeTimeline, expandHomeTimeline,
connectTimeline, connectTimeline,
disconnectTimeline, disconnectTimeline,
updateTimelineQueue, processTimelineUpdate,
} from './timelines'; } from './timelines';
import { updateNotificationsQueue, expandNotifications } from './notifications'; import { updateNotificationsQueue, expandNotifications } from './notifications';
import { updateConversations } from './conversations'; import { updateConversations } from './conversations';
@ -36,7 +36,7 @@ export function connectTimelineStream(timelineId, path, pollingRefresh = null, a
onReceive(data) { onReceive(data) {
switch(data.event) { switch(data.event) {
case 'update': case 'update':
dispatch(updateTimelineQueue(timelineId, JSON.parse(data.payload), accept)); dispatch(processTimelineUpdate(timelineId, JSON.parse(data.payload), accept));
break; break;
case 'delete': case 'delete':
dispatch(deleteFromTimelines(data.payload)); dispatch(deleteFromTimelines(data.payload));

Wyświetl plik

@ -1,6 +1,8 @@
import { importFetchedStatus, importFetchedStatuses } from './importer'; import { importFetchedStatus, importFetchedStatuses } from './importer';
import api, { getLinks } from '../api'; import api, { getLinks } from '../api';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
import { getSettings } from 'soapbox/actions/settings';
import { shouldFilter } from 'soapbox/utils/timelines';
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
export const TIMELINE_DELETE = 'TIMELINE_DELETE'; export const TIMELINE_DELETE = 'TIMELINE_DELETE';
@ -18,6 +20,19 @@ export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
export const MAX_QUEUED_ITEMS = 40; export const MAX_QUEUED_ITEMS = 40;
export function processTimelineUpdate(timeline, status, accept) {
return (dispatch, getState) => {
const columnSettings = getSettings(getState()).get(timeline, ImmutableMap());
const shouldSkipQueue = shouldFilter(fromJS(status), columnSettings);
if (shouldSkipQueue) {
return dispatch(updateTimeline(timeline, status, accept));
} else {
return dispatch(updateTimelineQueue(timeline, status, accept));
}
};
}
export function updateTimeline(timeline, status, accept) { export function updateTimeline(timeline, status, accept) {
return dispatch => { return dispatch => {
if (typeof accept === 'function' && !accept(status)) { if (typeof accept === 'function' && !accept(status)) {

Wyświetl plik

@ -58,7 +58,6 @@ export default class ColumnSettings extends React.PureComponent {
<FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' /> <FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' />
</span> </span>
<div className='column-settings__row'> <div className='column-settings__row'>
<SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterShowStr} />
<SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterShowStr} /> <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'show']} onChange={onChange} label={filterShowStr} />
<SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} /> <SettingToggle id='show-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} />
</div> </div>

Wyświetl plik

@ -6,6 +6,7 @@ import { debounce } from 'lodash';
import { dequeueTimeline } from 'soapbox/actions/timelines'; import { dequeueTimeline } from 'soapbox/actions/timelines';
import { scrollTopTimeline } from '../../../actions/timelines'; import { scrollTopTimeline } from '../../../actions/timelines';
import { getSettings } from 'soapbox/actions/settings'; import { getSettings } from 'soapbox/actions/settings';
import { shouldFilter } from 'soapbox/utils/timelines';
const makeGetStatusIds = () => createSelector([ const makeGetStatusIds = () => createSelector([
(state, { type }) => getSettings(state).get(type, ImmutableMap()), (state, { type }) => getSettings(state).get(type, ImmutableMap()),
@ -14,24 +15,9 @@ const makeGetStatusIds = () => createSelector([
(state) => state.get('me'), (state) => state.get('me'),
], (columnSettings, statusIds, statuses, me) => { ], (columnSettings, statusIds, statuses, me) => {
return statusIds.filter(id => { return statusIds.filter(id => {
if (id === null) return true; const status = statuses.get(id);
if (!status) return true;
const statusForId = statuses.get(id); return !shouldFilter(status, columnSettings);
let showStatus = true;
if (columnSettings.getIn(['shows', 'reblog']) === false) {
showStatus = showStatus && statusForId.get('reblog') === null;
}
if (columnSettings.getIn(['shows', 'reply']) === false) {
showStatus = showStatus && (statusForId.get('in_reply_to_id') === null);
}
if (columnSettings.getIn(['shows', 'direct']) === false) {
showStatus = showStatus && (statusForId.get('visibility') !== 'direct');
}
return showStatus;
}); });
}); });

Wyświetl plik

@ -0,0 +1,70 @@
import { shouldFilter } from '../timelines';
import { fromJS } from 'immutable';
describe('shouldFilter', () => {
it('returns false under normal circumstances', () => {
const columnSettings = fromJS({});
const status = fromJS({});
expect(shouldFilter(status, columnSettings)).toBe(false);
});
it('reblog: returns true when `shows.reblog == false`', () => {
const columnSettings = fromJS({ shows: { reblog: false } });
const status = fromJS({ reblog: {} });
expect(shouldFilter(status, columnSettings)).toBe(true);
});
it('reblog: returns false when `shows.reblog == true`', () => {
const columnSettings = fromJS({ shows: { reblog: true } });
const status = fromJS({ reblog: {} });
expect(shouldFilter(status, columnSettings)).toBe(false);
});
it('reply: returns true when `shows.reply == false`', () => {
const columnSettings = fromJS({ shows: { reply: false } });
const status = fromJS({ in_reply_to_id: '1234' });
expect(shouldFilter(status, columnSettings)).toBe(true);
});
it('reply: returns false when `shows.reply == true`', () => {
const columnSettings = fromJS({ shows: { reply: true } });
const status = fromJS({ in_reply_to_id: '1234' });
expect(shouldFilter(status, columnSettings)).toBe(false);
});
it('direct: returns true when `shows.direct == false`', () => {
const columnSettings = fromJS({ shows: { direct: false } });
const status = fromJS({ visibility: 'direct' });
expect(shouldFilter(status, columnSettings)).toBe(true);
});
it('direct: returns false when `shows.direct == true`', () => {
const columnSettings = fromJS({ shows: { direct: true } });
const status = fromJS({ visibility: 'direct' });
expect(shouldFilter(status, columnSettings)).toBe(false);
});
it('direct: returns false for a public post when `shows.direct == false`', () => {
const columnSettings = fromJS({ shows: { direct: false } });
const status = fromJS({ visibility: 'public' });
expect(shouldFilter(status, columnSettings)).toBe(false);
});
it('multiple settings', () => {
const columnSettings = fromJS({ shows: { reblog: false, reply: false, direct: false } });
const status = fromJS({ reblog: null, in_reply_to_id: null, visibility: 'direct' });
expect(shouldFilter(status, columnSettings)).toBe(true);
});
it('multiple settings', () => {
const columnSettings = fromJS({ shows: { reblog: false, reply: true, direct: false } });
const status = fromJS({ reblog: null, in_reply_to_id: '1234', visibility: 'public' });
expect(shouldFilter(status, columnSettings)).toBe(false);
});
it('multiple settings', () => {
const columnSettings = fromJS({ shows: { reblog: true, reply: false, direct: true } });
const status = fromJS({ reblog: {}, in_reply_to_id: '1234', visibility: 'direct' });
expect(shouldFilter(status, columnSettings)).toBe(true);
});
});

Wyświetl plik

@ -0,0 +1,13 @@
import { Map as ImmutableMap } from 'immutable';
export const shouldFilter = (status, columnSettings) => {
const shows = ImmutableMap({
reblog: status.get('reblog') !== null,
reply: status.get('in_reply_to_id') !== null,
direct: status.get('visibility') === 'direct',
});
return shows.some((value, key) => {
return columnSettings.getIn(['shows', key]) === false && value;
});
};

Wyświetl plik

@ -12,10 +12,30 @@ button.column-header__button.active {
} }
.detailed-status__wrapper .detailed-status__action-bar { .detailed-status__wrapper .detailed-status__action-bar {
border-radius: 0; border-radius: 0 0 10px 10px;
} }
.slist .item-list .column-link { .slist .item-list .column-link {
background-color: transparent; background-color: transparent;
border-top: 1px solid var(--brand-color--med); border-top: 1px solid var(--brand-color--med);
} }
.focusable {
&:focus {
border-radius: 0 0 10px 10px;
}
}
.focusable:focus .status.status-direct {
border-radius: 0 0 10px 10px;
}
.status.status-direct:not(.read) {
border-radius: 0 0 10px 10px;
}
// this still looks like shit but at least it's better than it overflowing
.empty-column-indicator {
border-radius: 0 0 10px 10px;
}