userThatNotMeReducer.js 5.28 KB
'use strict'

import InitialState from './userThatNotMeInitialState';
import Immutable, {List, Record} from 'immutable';

const {
    GO_TO_USER_THAT_NOT_ME,

    USER_TNM_INFO_REQUEST,
    USER_TNM_INFO_SUCCESS,
    USER_TNM_INFO_FAILURE,

    USER_TNM_POSTS_REQUEST,
    USER_TNM_POSTS_SUCCESS,
    USER_TNM_POSTS_FAILURE,
    USER_TNM_CLEAN,

    POST_LIKE_REQUEST,
    POST_UNLIKE_REQUEST,
} = require('../../constants/actionTypes').default;

const initialState = new InitialState;

export default function userThatNotMe(state = initialState, action) {
    if (!(state instanceof InitialState)) {
        return initialState.merge(state);
    }

    switch (action.type) {
        case GO_TO_USER_THAT_NOT_ME: {

            let currentSid = state.sid;
			let newItems = state.items;
			let newSid = currentSid;
			// componentWillUnmount未调用,导致clean操作未进行
            if (currentSid == -1) {
                newItems = List();
            }

			if (action.payload.tryToClean && currentSid > -1 && !state.cleaned) {
				newItems = newItems.pop();
				newSid = newSid - 1;
			}

            let sid = newSid + 1;
			// 获取新的初始状态item
			let item = initialState.item;
			// 设置item的value
			item = item.setIn(['profile', 'uid'], action.payload.uid);
			// items新增item
			newItems = newItems.push(item);
			let nextState =  state.set('sid', sid)
				.set('items', newItems)
                .set('cleaned', false);
			return nextState;
        }

        case USER_TNM_INFO_REQUEST: {
            let sid = action.payload;
			let nextState =  state.setIn(['items', sid, 'profile', 'isFetching'], true)
				.setIn(['items', sid, 'profile', 'error'], null);
			return nextState;
        }

        case USER_TNM_INFO_SUCCESS: {
            let {sid, json} = action.payload;
            let {avatar, backgroundImage, nickName, realName, gender, sign, age, birthday, height, weight} = json;
            let item = state.items.get(sid);
            item = item.setIn(['profile', 'isFetching'], false)
                .setIn(['profile', 'error'], null)
                .setIn(['profile', 'avatar'], avatar)
                .setIn(['profile', 'backgroundImage'], backgroundImage)
                .setIn(['profile', 'nickName'], nickName)
                .setIn(['profile', 'realName'], realName)
                .setIn(['profile', 'gender'], gender)
                .setIn(['profile', 'sign'], sign)
                .setIn(['profile', 'age'], age)
                .setIn(['profile', 'birthday'], birthday)
                .setIn(['profile', 'height'], height)
                .setIn(['profile', 'weight'], weight);
            let nextState = state.setIn(['items', sid], item);
			return nextState;
        }

        case USER_TNM_INFO_FAILURE: {
            let {sid, error} = action.payload;
			let nextState =  state.setIn(['items', sid, 'profile', 'isFetching'], false)
				.setIn(['items', sid, 'profile', 'error'], error);
			return nextState;
        }

        case USER_TNM_POSTS_REQUEST: {
            let sid = action.payload;
			let nextState =  state.setIn(['items', sid, 'posts', 'isFetching'], true)
				.setIn(['items', sid, 'posts', 'error'], null);
            return nextState;
        }

        case USER_TNM_POSTS_SUCCESS: {
            let {sid, json} = action.payload;
            let {lastedTime, list, endReached} = json;
            let item = state.items.get(sid);
            item = item.setIn(['posts', 'isFetching'], false)
                .setIn(['posts', 'error'], null)
                .setIn(['posts', 'lastedTime'], lastedTime)
                .setIn(['posts', 'list'], Immutable.fromJS(list))
                .setIn(['posts', 'endReached'], endReached);
            let nextState = state.setIn(['items', sid], item);
			return nextState;
        }

        case USER_TNM_POSTS_FAILURE: {
            let {sid, error} = action.payload;
			let nextState =  state.setIn(['items', sid, 'posts', 'isFetching'], false)
				.setIn(['items', sid, 'posts', 'error'], error);
            return nextState;
        }

        case USER_TNM_CLEAN: {
            let sid = action.payload;
			if (state.items.size > sid) {
				let items = state.items.pop();
				let nextState =  state.set('sid', sid - 1)
					.set('items', items)
                    .set('cleaned', true);
				return nextState;
			}
            return state;
        }

        case POST_LIKE_REQUEST: {
			return utnmNewLikeState(state, action.payload, true);
		}

		case POST_UNLIKE_REQUEST: {
			return utnmNewLikeState(state, action.payload, false);
		}
    }

    return state;
}

function utnmNewLikeState(state, postId, like) {

    let likeState = (list, postId, like) => {
		let index = list.findIndex((item) => {
			return item.get('id') == postId;
		})
		if (index == -1) {
			return list;
		}

		let likeCount = 0;
		if (like) {
			likeCount = list.get(index).get('likeCount') + 1;
		} else {
			likeCount = list.get(index).get('likeCount') - 1;
			likeCount = likeCount < 0 ? 0 : likeCount;
		}

		let nextList =  list.setIn([index, 'isLike'], like)
			.setIn([index, 'likeCount'], likeCount);
		return nextList;
	};

	let nextState = state;
	state.items.map((item, i) => {
		let postsList = likeState(item.posts.list, postId, like);
		item = item.setIn(['posts', 'list'], postsList);
		nextState = nextState.setIn(['items', i], item);
	});

	return nextState;
}