import ArticleActionCreator from "../models/client/ArticleActionCreator" ; import { Dispatch , AnyAction as Action } from "redux" ; import fetch from "../shared/fetch" ; import actions from "./common" ; import Article from "../models/Article" ; import GetArticlesResponse from "../models/response/GetArticlesResponse.d" ; import { getToast as toast } from "../shared/toast" ; import ArticleCache from "../models/client/ArticleCache" ; import { getStorage as localStorage } from "../shared/storage" ; export const SAVE_ARTICLE_BEGIN = "SAVE_ARTICLE_BEGIN" ; export const SAVE_ARTICLE_SUCCESS = "SAVE_ARTICLE_SUCCESS" ; export const SAVE_ARTICLE_FAILED = "SAVE_ARTICLE_FAILED" ; export const REMOVE_ARTICLE_BEGIN = "REMOVE_ARTICLE_BEGIN" ; export const REMOVE_ARTICLE_SUCCESS = "REMOVE_ARTICLE_SUCCESS" ; export const REMOVE_ARTICLE_FAILED = "REMOVE_ARTICLE_FAILED" ; export const GET_ARTICLE_BEGIN = "GET_ARTICLE_BEGIN" ; export const GET_ARTICLE_SUCCESS = "GET_ARTICLE_SUCCESS" ; export const GET_ARTICLE_FAILED = "GET_ARTICLE_FAILED" ; export const GET_MORE_ARTICLE_BEGIN = "GET_MORE_ARTICLE_BEGIN" ; export const GET_MORE_ARTICLE_SUCCESS = "GET_MORE_ARTICLE_SUCCESS" ; export const GET_MORE_ARTICLE_FAILED = "GET_MORE_ARTICLE_FAILED" ; export const INSERT_IMAGE_BEGIN = "INSERT_IMAGE_BEGIN" ; export const INSERT_IMAGE_SUCCESS = "INSERT_IMAGE_SUCCESS" ; export const INSERT_IMAGE_FAILED = "INSERT_IMAGE_FAILED" ; export const RATE_ARTICLE_SUCCESS = "RATE_ARTICLE_SUCCESS" ; export const RATE_ARTICLE_FAILED = "RATE_ARTICLE_FAILED" ; export const SET_EDIT_ARTICLE_CACHE = "SET_EDIT_ARTICLE_CACHE" ; export const REMOVE_EDIT_ARTICLE_CACHE = "REMOVE_EDIT_ARTICLE_CACHE" ; export const IGNORE_CACHE_RESTORE = "IGNORE_CACHE_RESTORE" ; export const NEW_ARTICLE_CACHE_ID = "NEW_ARTICLE_CACHE_ID" ; export const ARTICLE_EDIT_CACHE_KEY_PREFIX = "articleEdit/" ; const removeEditCacheExec = ( id , dispatch ) : void => { localStorage ( ) . removeItem ( ARTICLE_EDIT_CACHE_KEY_PREFIX + id ) ; dispatch ( { type : REMOVE_EDIT_ARTICLE_CACHE , id : id } ) ; } ; const articleActionCreator = { getArticles ( ) { return ( dispatch ) : void => { dispatch ( { type : GET_ARTICLE_BEGIN } ) ; fetch ( "/api/article" , undefined , "GET" ) . then ( ( json ) => { if ( json && json . data && json . authors ) { dispatch ( { type : GET_ARTICLE_SUCCESS , articles : json . data , authors : json . authors , hasMore : json . hasMore } ) ; } else { return Promise . reject ( { name : "500 Internal Server Error" , message : "" } ) ; } } ) . catch ( ( error ) => { dispatch ( actions . handleFetchError ( GET_ARTICLE_FAILED , error ) ) ; } ) ; } ; } , getMoreArticles ( earlierThan ) { return ( dispatch ) : void => { dispatch ( { type : GET_MORE_ARTICLE_BEGIN } ) ; fetch ( `/api/article?latest=${ earlierThan }` , undefined , "GET" ) . then ( ( json ) => { if ( json && json . data && json . authors ) { dispatch ( { type : GET_MORE_ARTICLE_SUCCESS , articles : json . data , authors : json . authors , hasMore : json . hasMore } ) ; } else { return Promise . reject ( { name : "500 Internal Server Error" , message : "" } ) ; } } ) . catch ( ( error ) => { dispatch ( actions . handleFetchError ( GET_MORE_ARTICLE_FAILED , error ) ) ; } ) ; } ; } , addArticle ( title , content , author , mentions ? ) { return ( dispatch ) : void => { dispatch ( { type : SAVE_ARTICLE_BEGIN } ) ; fetch ( "/api/article/create" , { title , content , author , mentions } , "POST" , true ) . then ( ( added ) => { if ( added ) { removeEditCacheExec ( NEW_ARTICLE_CACHE_ID , dispatch ) ; toast ( ) . success ( "toast.article.save_successfully" ) ; dispatch ( { type : SAVE_ARTICLE_SUCCESS , article : added , redirectTask : { redirected : false , to : `/article/${ added . _id }` } } ) ; } else { return Promise . reject ( { name : "500 Internal Server Error" , message : "Broken data." } ) ; } } ) . catch ( ( error ) => { dispatch ( actions . handleFetchError ( SAVE_ARTICLE_FAILED , error ) ) ; } ) ; } ; } , editArticle ( article ) { return ( dispatch ) : void => { dispatch ( { type : SAVE_ARTICLE_BEGIN } ) ; fetch ( "/api/article/edit" , article , "POST" , true ) . then ( ( updated ) => { removeEditCacheExec ( article . _id , dispatch ) ; toast ( ) . success ( "toast.article.save_successfully" ) ; dispatch ( { type : SAVE_ARTICLE_SUCCESS , article : updated , redirectTask : { redirected : false , to : `/article/${ updated . _id }` } } ) ; } ) . catch ( ( error ) => { dispatch ( actions . handleFetchError ( SAVE_ARTICLE_FAILED , error ) ) ; } ) ; } ; } , removeArticle ( id ) { return ( dispatch ) : void => { dispatch ( { type : REMOVE_ARTICLE_BEGIN } ) ; fetch ( `/api/article/remove/${ id }` , undefined , "GET" , true ) . then ( ( json ) => { toast ( ) . success ( "toast.article.delete_successfully" ) ; removeEditCacheExec ( id , dispatch ) ; dispatch ( { type : REMOVE_ARTICLE_SUCCESS , redirectTask : { redirected : false , to : "/article" } } ) ; } ) . catch ( ( error ) => { dispatch ( actions . handleFetchError ( REMOVE_ARTICLE_FAILED , error ) ) ; } ) ; } ; } , rateArticle ( rating , id , user ) { return ( dispatch ) : void => { fetch ( `/api/article/rate?id=${ id }&rating=${ rating }` , undefined , "GET" , true ) . then ( ( json ) => { dispatch ( { type : RATE_ARTICLE_SUCCESS , article : id , rating : rating , user : user } ) ; } ) . catch ( ( error ) => { dispatch ( actions . handleFetchError ( RATE_ARTICLE_FAILED , error ) ) ; } ) ; } ; } , setEditCache ( id , cache ) { localStorage ( ) . setItem ( ARTICLE_EDIT_CACHE_KEY_PREFIX + id , JSON . stringify ( cache ) ) ; return { type : SET_EDIT_ARTICLE_CACHE , id : id , cache : cache } ; } , removeEditCache ( id ) { return ( dispatch ) : void => { removeEditCacheExec ( id , dispatch ) ; } ; } , restoreEditCache ( ) { return ( dispatch ) : void => { localStorage ( ) . getAllKeys ( ) . then ( ( keys ) => { keys . forEach ( key => { if ( ! key || ! key . startsWith ( ARTICLE_EDIT_CACHE_KEY_PREFIX ) ) { return dispatch ( { type : IGNORE_CACHE_RESTORE } ) ; } localStorage ( ) . getItem ( key ) . then ( ( value ) => { if ( ! key || ! key . startsWith ( ARTICLE_EDIT_CACHE_KEY_PREFIX ) || ! value ) { return dispatch ( { type : IGNORE_CACHE_RESTORE } ) ; } const id = key . slice ( ARTICLE_EDIT_CACHE_KEY_PREFIX . length ) ; dispatch ( { type : SET_EDIT_ARTICLE_CACHE , id : id , cache : JSON . parse ( value ) as ArticleCache } ) ; } ) . catch ( ( reason ) => { return Promise . reject ( ) ; } ) ; } ) ; } ) . catch ( ( reason ) => { dispatch ( { type : IGNORE_CACHE_RESTORE } ) ; } ) ; } ; } } ; export default articleActionCreator ;