import { call , put , select , takeEvery } from 'redux-saga/effects' ; import Logic from '../../logic' ; import { EMenuKey , IFeed , IIArticlesState , IIFeedsState , IIMenuState , IReduxAction , } from '../../schemas' ; import { addFeedAction , asyncFetchArticlesAction , asyncFetchFeedsAction , asyncSelectMenuKeyAction , FeedsActionTypes , IAsyncDeleteFeedsPayload , IAsyncParseFeedPayload , setCurrentArticleAction , setFeedsAction , } from '../actions' ; import { makeSagaWorkersDispatcher } from './helpers' ; import { getArticles , getFeeds , getMenu } from './selectors' ; let LAST_UPDATE_FEEDS_AT = 0 ; export function * fetchFeedsSaga ( action ) { const feeds = yield call ( Logic . getAllFeeds ) ; yield put ( setFeedsAction ( feeds ) ) ; const menuState = yield select ( getMenu ) ; const menuKey = menuState . selectedKey ; const articlesState = yield select ( getArticles ) ; const currentArticle = articlesState . current ; if ( menuKey in EMenuKey ) { yield put ( asyncFetchArticlesAction ( ) ) ; } else if ( ! feeds . some ( feed => feed . _id === menuKey ) ) { yield put ( asyncSelectMenuKeyAction ( EMenuKey . ALL_ITEMS ) ) ; } if ( currentArticle && ! feeds . some ( feed => feed . _id === currentArticle . feedId ) ) { yield put ( setCurrentArticleAction ( null ) ) ; } return feeds ; } export function * parseFeedSaga ( action ) { const feed = yield call ( Logic . createFeed , action . payload . feedUrl ) ; if ( feed ) { yield put ( addFeedAction ( feed ) ) ; const menuState = yield select ( getMenu ) ; const menuKey = menuState . selectedKey ; if ( menuKey === EMenuKey . ALL_ITEMS || menuKey === EMenuKey . UNREAD_ITEMS ) { yield put ( asyncFetchArticlesAction ( ) ) ; } } return feed ; } export function * deleteFeedsSaga ( action ) { if ( action . payload . feedIds . length > 0 ) { const feedIds = action . payload . feedIds ; const changes = yield call ( Logic . deleteFeeds , feedIds ) ; if ( changes ) { yield put ( asyncFetchFeedsAction ( ) ) ; return changes ; } } return 0 ; } export function * updateFeedsSaga ( action ) { const now = Date . now ( ) ; if ( now < LAST_UPDATE_FEEDS_AT + 60 * 60 * 1000 ) { return 0 ; } LAST_UPDATE_FEEDS_AT = now ; const feedsState = yield select ( getFeeds ) ; const list = feedsState . list . toArray ( ) ; let changes = 0 ; for ( const feed of list ) { try { changes += yield call ( Logic . updateFeedArticles , feed ) ; } catch ( err ) { console . error ( err ) ; } } if ( changes > 0 ) { yield put ( asyncFetchFeedsAction ( ) ) ; yield put ( asyncFetchArticlesAction ( ) ) ; } return changes ; } const dispatcher = makeSagaWorkersDispatcher ( { [ FeedsActionTypes . ASYNC_PARSE_FEED ] : parseFeedSaga , [ FeedsActionTypes . ASYNC_FETCH_FEEDS ] : fetchFeedsSaga , [ FeedsActionTypes . ASYNC_UPDATE_FEEDS ] : updateFeedsSaga , [ FeedsActionTypes . ASYNC_DELETE_FEEDS ] : deleteFeedsSaga , } ) ; export function * watchFeedsSagas ( ) { yield takeEvery ( [ FeedsActionTypes . ASYNC_PARSE_FEED , FeedsActionTypes . ASYNC_FETCH_FEEDS , FeedsActionTypes . ASYNC_UPDATE_FEEDS , FeedsActionTypes . ASYNC_DELETE_FEEDS , ] , dispatcher ) ; }