kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
StatusList: break out TimelineQueueButtonHeader into StatusListContainer
rodzic
878d26cb4b
commit
47e43b6540
|
@ -1,26 +1,18 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import React, { useRef, useCallback } from 'react';
|
import React, { useRef, useCallback } from 'react';
|
||||||
import { FormattedMessage, defineMessages } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import LoadGap from 'soapbox/components/load_gap';
|
import LoadGap from 'soapbox/components/load_gap';
|
||||||
import ScrollableList from 'soapbox/components/scrollable_list';
|
import ScrollableList from 'soapbox/components/scrollable_list';
|
||||||
import TimelineQueueButtonHeader from 'soapbox/components/timeline_queue_button_header';
|
|
||||||
import StatusContainer from 'soapbox/containers/status_container';
|
import StatusContainer from 'soapbox/containers/status_container';
|
||||||
import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status';
|
import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status';
|
||||||
import PendingStatus from 'soapbox/features/ui/components/pending_status';
|
import PendingStatus from 'soapbox/features/ui/components/pending_status';
|
||||||
|
|
||||||
import type {
|
import type { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||||
Map as ImmutableMap,
|
|
||||||
OrderedSet as ImmutableOrderedSet,
|
|
||||||
} from 'immutable';
|
|
||||||
import type { VirtuosoHandle } from 'react-virtuoso';
|
import type { VirtuosoHandle } from 'react-virtuoso';
|
||||||
import type { IScrollableList } from 'soapbox/components/scrollable_list';
|
import type { IScrollableList } from 'soapbox/components/scrollable_list';
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
queue: { id: 'status_list.queue_label', defaultMessage: 'Click to see {count} new {count, plural, one {post} other {posts}}' },
|
|
||||||
});
|
|
||||||
|
|
||||||
interface IStatusList extends Omit<IScrollableList, 'onLoadMore' | 'children'> {
|
interface IStatusList extends Omit<IScrollableList, 'onLoadMore' | 'children'> {
|
||||||
scrollKey: string,
|
scrollKey: string,
|
||||||
statusIds: ImmutableOrderedSet<string>,
|
statusIds: ImmutableOrderedSet<string>,
|
||||||
|
@ -35,10 +27,6 @@ interface IStatusList extends Omit<IScrollableList, 'onLoadMore' | 'children'> {
|
||||||
alwaysPrepend?: boolean,
|
alwaysPrepend?: boolean,
|
||||||
timelineId?: string,
|
timelineId?: string,
|
||||||
queuedItemSize?: number,
|
queuedItemSize?: number,
|
||||||
onDequeueTimeline?: (timelineId: string) => void,
|
|
||||||
totalQueuedItemsCount?: number,
|
|
||||||
group?: ImmutableMap<string, any>,
|
|
||||||
withGroupAdmin?: boolean,
|
|
||||||
onScrollToTop?: () => void,
|
onScrollToTop?: () => void,
|
||||||
onScroll?: () => void,
|
onScroll?: () => void,
|
||||||
divideType: 'space' | 'border',
|
divideType: 'space' | 'border',
|
||||||
|
@ -51,12 +39,8 @@ const StatusList: React.FC<IStatusList> = ({
|
||||||
divideType = 'border',
|
divideType = 'border',
|
||||||
onLoadMore,
|
onLoadMore,
|
||||||
timelineId,
|
timelineId,
|
||||||
totalQueuedItemsCount,
|
|
||||||
onDequeueTimeline,
|
|
||||||
isLoading,
|
isLoading,
|
||||||
isPartial,
|
isPartial,
|
||||||
withGroupAdmin,
|
|
||||||
group,
|
|
||||||
...other
|
...other
|
||||||
}) => {
|
}) => {
|
||||||
const node = useRef<VirtuosoHandle>(null);
|
const node = useRef<VirtuosoHandle>(null);
|
||||||
|
@ -101,11 +85,6 @@ const StatusList: React.FC<IStatusList> = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDequeueTimeline = () => {
|
|
||||||
if (!onDequeueTimeline || !timelineId) return;
|
|
||||||
onDequeueTimeline(timelineId);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderLoadGap = (index: number) => {
|
const renderLoadGap = (index: number) => {
|
||||||
const ids = statusIds.toList();
|
const ids = statusIds.toList();
|
||||||
const nextId = ids.get(index + 1);
|
const nextId = ids.get(index + 1);
|
||||||
|
@ -204,13 +183,6 @@ const StatusList: React.FC<IStatusList> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<TimelineQueueButtonHeader
|
|
||||||
key='timeline-queue-button-header'
|
|
||||||
onClick={handleDequeueTimeline}
|
|
||||||
count={totalQueuedItemsCount}
|
|
||||||
message={messages.queue}
|
|
||||||
/>
|
|
||||||
<ScrollableList
|
<ScrollableList
|
||||||
id='status-list'
|
id='status-list'
|
||||||
key='scrollable-list'
|
key='scrollable-list'
|
||||||
|
@ -229,8 +201,7 @@ const StatusList: React.FC<IStatusList> = ({
|
||||||
{...other}
|
{...other}
|
||||||
>
|
>
|
||||||
{renderScrollableContent()}
|
{renderScrollableContent()}
|
||||||
</ScrollableList>,
|
</ScrollableList>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ import { useIntl, MessageDescriptor } from 'react-intl';
|
||||||
|
|
||||||
import Icon from 'soapbox/components/icon';
|
import Icon from 'soapbox/components/icon';
|
||||||
import { Text } from 'soapbox/components/ui';
|
import { Text } from 'soapbox/components/ui';
|
||||||
import { useSettings } from 'soapbox/hooks';
|
import { useAppSelector, useSettings } from 'soapbox/hooks';
|
||||||
|
|
||||||
interface ITimelineQueueButtonHeader {
|
interface ITimelineQueueButtonHeader {
|
||||||
onClick: () => void,
|
onClick: () => void,
|
||||||
count?: number,
|
timelineId: string,
|
||||||
message: MessageDescriptor,
|
message: MessageDescriptor,
|
||||||
threshold?: number,
|
threshold?: number,
|
||||||
autoloadThreshold?: number,
|
autoloadThreshold?: number,
|
||||||
|
@ -17,13 +17,14 @@ interface ITimelineQueueButtonHeader {
|
||||||
|
|
||||||
const TimelineQueueButtonHeader: React.FC<ITimelineQueueButtonHeader> = ({
|
const TimelineQueueButtonHeader: React.FC<ITimelineQueueButtonHeader> = ({
|
||||||
onClick,
|
onClick,
|
||||||
count = 0,
|
timelineId,
|
||||||
message,
|
message,
|
||||||
threshold = 400,
|
threshold = 400,
|
||||||
autoloadThreshold = 50,
|
autoloadThreshold = 50,
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const settings = useSettings();
|
const settings = useSettings();
|
||||||
|
const count = useAppSelector(state => state.timelines.getIn([timelineId, 'totalQueuedItemsCount']));
|
||||||
|
|
||||||
const [scrolled, setScrolled] = useState<boolean>(false);
|
const [scrolled, setScrolled] = useState<boolean>(false);
|
||||||
const autoload = settings.get('autoloadTimelines') === true;
|
const autoload = settings.get('autoloadTimelines') === true;
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { dequeueTimeline } from 'soapbox/actions/timelines';
|
import { dequeueTimeline } from 'soapbox/actions/timelines';
|
||||||
import { scrollTopTimeline } from 'soapbox/actions/timelines';
|
import { scrollTopTimeline } from 'soapbox/actions/timelines';
|
||||||
import StatusList, { IStatusList } from 'soapbox/components/status_list';
|
import StatusList, { IStatusList } from 'soapbox/components/status_list';
|
||||||
|
import TimelineQueueButtonHeader from 'soapbox/components/timeline_queue_button_header';
|
||||||
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
||||||
import { makeGetStatusIds } from 'soapbox/selectors';
|
import { makeGetStatusIds } from 'soapbox/selectors';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
queue: { id: 'status_list.queue_label', defaultMessage: 'Click to see {count} new {count, plural, one {post} other {posts}}' },
|
||||||
|
});
|
||||||
|
|
||||||
interface IStatusListContainer extends Omit<IStatusList, 'statusIds' | 'isLoading' | 'hasMore'> {
|
interface IStatusListContainer extends Omit<IStatusList, 'statusIds' | 'isLoading' | 'hasMore'> {
|
||||||
timelineId: string,
|
timelineId: string,
|
||||||
}
|
}
|
||||||
|
@ -25,9 +31,8 @@ const StatusListContainer: React.FC<IStatusListContainer> = ({
|
||||||
const isLoading = useAppSelector(state => state.timelines.getIn([timelineId, 'isLoading'], true) === true);
|
const isLoading = useAppSelector(state => state.timelines.getIn([timelineId, 'isLoading'], true) === true);
|
||||||
const isPartial = useAppSelector(state => state.timelines.getIn([timelineId, 'isPartial'], false) === true);
|
const isPartial = useAppSelector(state => state.timelines.getIn([timelineId, 'isPartial'], false) === true);
|
||||||
const hasMore = useAppSelector(state => state.timelines.getIn([timelineId, 'hasMore']) === true);
|
const hasMore = useAppSelector(state => state.timelines.getIn([timelineId, 'hasMore']) === true);
|
||||||
const totalQueuedItemsCount = useAppSelector(state => state.timelines.getIn([timelineId, 'totalQueuedItemsCount']));
|
|
||||||
|
|
||||||
const handleDequeueTimeline = (timelineId: string) => {
|
const handleDequeueTimeline = () => {
|
||||||
dispatch(dequeueTimeline(timelineId, onLoadMore));
|
dispatch(dequeueTimeline(timelineId, onLoadMore));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,8 +45,15 @@ const StatusListContainer: React.FC<IStatusListContainer> = ({
|
||||||
}, 100), []);
|
}, 100), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<TimelineQueueButtonHeader
|
||||||
|
key='timeline-queue-button-header'
|
||||||
|
onClick={handleDequeueTimeline}
|
||||||
|
timelineId={timelineId}
|
||||||
|
message={messages.queue}
|
||||||
|
/>
|
||||||
|
|
||||||
<StatusList
|
<StatusList
|
||||||
onDequeueTimeline={handleDequeueTimeline}
|
|
||||||
onScrollToTop={handleScrollToTop}
|
onScrollToTop={handleScrollToTop}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
lastStatusId={lastStatusId}
|
lastStatusId={lastStatusId}
|
||||||
|
@ -49,10 +61,10 @@ const StatusListContainer: React.FC<IStatusListContainer> = ({
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
isPartial={isPartial}
|
isPartial={isPartial}
|
||||||
hasMore={hasMore}
|
hasMore={hasMore}
|
||||||
totalQueuedItemsCount={totalQueuedItemsCount}
|
|
||||||
onLoadMore={onLoadMore}
|
onLoadMore={onLoadMore}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue