diff --git a/.env b/.env index 805961de..9fc7c719 100644 --- a/.env +++ b/.env @@ -14,6 +14,7 @@ LOGO_WHITE_URL='' FAVICON_URL='' MARKETING_SITE_BASE_URL='' ORDER_HISTORY_URL='' +POST_MARK_AS_READ_DELAY=2000 REFRESH_ACCESS_TOKEN_ENDPOINT='' SEGMENT_KEY='' SITE_NAME='' diff --git a/.env.development b/.env.development index 80f1b345..5266dd5d 100644 --- a/.env.development +++ b/.env.development @@ -15,6 +15,7 @@ LOGO_WHITE_URL=https://edx-cdn.org/v3/default/logo-white.svg FAVICON_URL=https://edx-cdn.org/v3/default/favicon.ico MARKETING_SITE_BASE_URL='http://localhost:18000' ORDER_HISTORY_URL='http://localhost:1996/orders' +POST_MARK_AS_READ_DELAY=2000 REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh' SEGMENT_KEY='' SITE_NAME=localhost diff --git a/.env.test b/.env.test index 79c0f681..e6a9bc01 100644 --- a/.env.test +++ b/.env.test @@ -13,6 +13,7 @@ LOGO_WHITE_URL=https://edx-cdn.org/v3/default/logo-white.svg FAVICON_URL=https://edx-cdn.org/v3/default/favicon.ico MARKETING_SITE_BASE_URL='http://localhost:18000' ORDER_HISTORY_URL='http://localhost:1996/orders' +POST_MARK_AS_READ_DELAY=2000 REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh' SEGMENT_KEY='' SITE_NAME=localhost diff --git a/src/discussions/comments/CommentsView.jsx b/src/discussions/comments/CommentsView.jsx index 4acacfe3..34993c2c 100644 --- a/src/discussions/comments/CommentsView.jsx +++ b/src/discussions/comments/CommentsView.jsx @@ -3,16 +3,20 @@ import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useParams } from 'react-router'; +import { ensureConfig, getConfig } from '@edx/frontend-platform'; import { injectIntl, intlShape } from '@edx/frontend-platform/i18n'; import { Button, Spinner } from '@edx/paragon'; import { selectThread } from '../posts/data/selectors'; +import { markThreadAsRead } from '../posts/data/thunks'; import Post from '../posts/post/Post'; import { selectThreadComments } from './data/selectors'; import { fetchThreadComments } from './data/thunks'; import Reply from './reply/Reply'; import messages from './messages'; +ensureConfig(['POST_MARK_AS_READ_DELAY'], 'Comment thread view'); + function CommentsView({ intl }) { const { postId } = useParams(); const dispatch = useDispatch(); @@ -20,6 +24,14 @@ function CommentsView({ intl }) { const comments = useSelector(selectThreadComments(postId)); useEffect(() => { dispatch(fetchThreadComments(postId)); + const markReadTimer = setTimeout(() => { + if (thread && !thread.read) { + dispatch(markThreadAsRead(postId)); + } + }, getConfig().POST_MARK_AS_READ_DELAY); + return () => { + clearTimeout(markReadTimer); + }; }, [postId]); if (!thread) { return ( diff --git a/src/discussions/posts/data/thunks.js b/src/discussions/posts/data/thunks.js index 5a7db1c7..f17ac1c6 100644 --- a/src/discussions/posts/data/thunks.js +++ b/src/discussions/posts/data/thunks.js @@ -96,6 +96,23 @@ export function fetchThread(threadId) { }; } +export function markThreadAsRead(threadId) { + return async (dispatch) => { + try { + dispatch(updateThreadRequest({ threadId, read: true })); + const data = await updateThread(threadId, { read: true }); + dispatch(updateThreadSuccess(camelCaseObject(data))); + } catch (error) { + if (getHttpErrorStatus(error) === 403) { + dispatch(updateThreadDenied()); + } else { + dispatch(updateThreadFailed()); + } + logError(error); + } + }; +} + export function createNewThread(courseId, topicId, type, title, content, following = false) { return async (dispatch) => { try { diff --git a/src/index.jsx b/src/index.jsx index 50805cdc..10008c49 100755 --- a/src/index.jsx +++ b/src/index.jsx @@ -7,7 +7,7 @@ import ReactDOM from 'react-dom'; import Footer, { messages as footerMessages } from '@edx/frontend-component-footer'; import Header, { messages as headerMessages } from '@edx/frontend-component-header'; import { - APP_INIT_ERROR, APP_READY, initialize, subscribe, + APP_INIT_ERROR, APP_READY, initialize, mergeConfig, subscribe, } from '@edx/frontend-platform'; import { AppProvider, ErrorPage } from '@edx/frontend-platform/react'; @@ -40,4 +40,11 @@ initialize({ headerMessages, footerMessages, ], + handlers: { + config() { + mergeConfig({ + POST_MARK_AS_READ_DELAY: process.env.POST_MARK_AS_READ_DELAY || 2000, + }); + }, + }, });