diff --git a/src/core/client/framework/hooks/index.ts b/src/core/client/framework/hooks/index.ts index 0dde5d606..92b69f39b 100644 --- a/src/core/client/framework/hooks/index.ts +++ b/src/core/client/framework/hooks/index.ts @@ -7,3 +7,4 @@ export { default as useUUID } from "./useUUID"; export { default as useToken } from "./useToken"; export { default as useResizeObserver } from "./useResizeObserver"; export { default as useToggleState } from "./useToggleState"; +export { default as useLive } from "./useLive"; diff --git a/src/core/client/framework/hooks/useLive.ts b/src/core/client/framework/hooks/useLive.ts new file mode 100644 index 000000000..05864e931 --- /dev/null +++ b/src/core/client/framework/hooks/useLive.ts @@ -0,0 +1,44 @@ +import { useMemo } from "react"; + +interface Props { + story: { + isClosed: boolean; + settings: { + live: { + enabled: boolean; + }; + }; + }; + settings: { + disableCommenting: { + enabled: boolean; + }; + }; +} + +const useLive = ({ story, settings }: Props) => + useMemo(() => { + if ( + // If live updates are disable for this story... + !story.settings.live.enabled || + // Or the story is closed... + story.isClosed || + // Or commenting is disabled... + settings.disableCommenting.enabled + ) { + // Then we aren't live! + return false; + } + + // The story is open! Mark the story as open. + return true; + }, [ + // When used in conjunction with the StoryClosedTimeoutContainer, we don't + // have to inspect the `story.closedAt` because it'll update the store for + // us! + story.isClosed, + settings.disableCommenting.enabled, + story.settings.live.enabled, + ]); + +export default useLive; diff --git a/src/core/client/stream/tabs/Comments/ReplyList/ReplyListContainer.tsx b/src/core/client/stream/tabs/Comments/ReplyList/ReplyListContainer.tsx index f51977fb7..3664eab0a 100644 --- a/src/core/client/stream/tabs/Comments/ReplyList/ReplyListContainer.tsx +++ b/src/core/client/stream/tabs/Comments/ReplyList/ReplyListContainer.tsx @@ -1,9 +1,8 @@ -import { clearLongTimeout } from "long-settimeout"; import React, { FunctionComponent, useCallback, useEffect } from "react"; import { graphql, GraphQLTaggedNode, RelayPaginationProp } from "react-relay"; import { withProps } from "recompose"; -import { createTimeoutAt } from "coral-common/utils"; +import { useLive } from "coral-framework/hooks"; import { useViewerNetworkEvent } from "coral-framework/lib/events"; import { useLoadMore, @@ -80,17 +79,16 @@ export const ReplyListContainer: React.FunctionComponent = (props) => { const subcribeToCommentReplyCreated = useSubscription( CommentReplyCreatedSubscription ); + + const live = useLive(props); useEffect(() => { // If the comment is pending, no need to subscribe the comment! if (props.comment.pending) { return; } - if (!props.story.settings.live.enabled) { - return; - } - - if (props.story.isClosed || props.settings.disableCommenting.enabled) { + // If live updates aren't enabled, don't subscribe! + if (!live) { return; } @@ -103,37 +101,16 @@ export const ReplyListContainer: React.FunctionComponent = (props) => { liveDirectRepliesInsertion: props.liveDirectRepliesInsertion, }); - // If the story is scheduled to be closed, cancel the subscriptions because - // we can't add any more comments! - if (props.story.closedAt) { - const timer = createTimeoutAt(() => { - disposable.dispose(); - }, props.story.closedAt); - - return () => { - // Cancel the timer if there was one enabled. - if (timer) { - clearLongTimeout(timer); - } - - // Dispose the subscriptions. - disposable.dispose(); - }; - } - return () => { disposable.dispose(); }; }, [ + live, subcribeToCommentReplyCreated, props.comment.id, props.indentLevel, props.comment.pending, - props.settings.disableCommenting.enabled, props.liveDirectRepliesInsertion, - props.story.isClosed, - props.story.closedAt, - props.story.settings.live.enabled, ]); const viewNew = useMutation(ReplyListViewNewMutation); diff --git a/src/core/client/stream/tabs/Comments/Stream/AllCommentsTab/AllCommentsTabContainer.tsx b/src/core/client/stream/tabs/Comments/Stream/AllCommentsTab/AllCommentsTabContainer.tsx index 02da47770..39b503ded 100644 --- a/src/core/client/stream/tabs/Comments/Stream/AllCommentsTab/AllCommentsTabContainer.tsx +++ b/src/core/client/stream/tabs/Comments/Stream/AllCommentsTab/AllCommentsTabContainer.tsx @@ -1,11 +1,10 @@ import { Localized } from "@fluent/react/compat"; import cn from "classnames"; -import { clearLongTimeout } from "long-settimeout"; import React, { FunctionComponent, useCallback, useEffect } from "react"; import { graphql, RelayPaginationProp } from "react-relay"; -import { createTimeoutAt } from "coral-common/utils"; import FadeInTransition from "coral-framework/components/FadeInTransition"; +import { useLive } from "coral-framework/hooks"; import { useViewerNetworkEvent } from "coral-framework/lib/events"; import { combineDisposables, @@ -73,22 +72,19 @@ export const AllCommentsTabContainer: FunctionComponent = ({ const subscribeToCommentReleased = useSubscription( CommentReleasedSubscription ); + + const live = useLive({ story, settings }); + const hasMore = relay.hasMore(); useEffect(() => { // If live updates are disabled, don't subscribe to new comments!! - if (!story.settings.live.enabled) { - return; - } - - // If the story is closed or commenting is disabled, then don't subscribe - // to new comments because there isn't any! - if (story.isClosed || settings.disableCommenting.enabled) { + if (!live) { return; } // Check the sort ordering to apply extra logic. switch (commentsOrderBy) { case GQLCOMMENT_SORT.CREATED_AT_ASC: - if (relay.hasMore()) { + if (hasMore) { // Oldest first when there is more than one page of content can't // possibly have new comments to show in view! return; @@ -116,37 +112,16 @@ export const AllCommentsTabContainer: FunctionComponent = ({ }) ); - // If the story is scheduled to be closed, cancel the subscriptions because - // we can't add any more comments! - if (story.closedAt) { - const timer = createTimeoutAt(() => { - disposable.dispose(); - }, story.closedAt); - - return () => { - // Cancel the timer if there was one enabled. - if (timer) { - clearLongTimeout(timer); - } - - // Dispose the subscriptions. - disposable.dispose(); - }; - } - return () => { disposable.dispose(); }; }, [ commentsOrderBy, + hasMore, + live, + story.id, subscribeToCommentCreated, subscribeToCommentReleased, - story.id, - story.isClosed, - story.closedAt, - story.settings.live.enabled, - settings.disableCommenting.enabled, - relay.hasMore(), ]); const [loadMore, isLoadingMore] = useLoadMore(relay, 20); @@ -245,7 +220,7 @@ export const AllCommentsTabContainer: FunctionComponent = ({ ))} - {relay.hasMore() && ( + {hasMore && (