import keyBy from 'lodash/keyBy';
import omit from 'lodash/omit';

import * as actions from './userActions';

const initialState = {
  // Map<FilePublicId, File>
  files: {},
  // Whether a file is uploading.
  // Map<FileName, Bool>
  fileUploadIsLoading: {},
  fileUploadError: null,

  filesFetchError: null,
  filesFetchIsLoading: true,
  following: {},
};

export default function userProfileReducer(state = initialState, action) {
  switch (action.type) {
    case actions.UPLOAD_FILE_START: {
      return Object.assign({}, state, {
        fileUploadIsLoading: Object.assign({}, state.fileUploadIsLoading, {
          [`${action.meta.filename}`]: true,
        }),
        fileUploadError: null,
      });
    }

    case actions.UPLOAD_FILE_SUCCESS: {
      return Object.assign({}, state, {
        files: Object.assign({}, state.files, {
          [`${action.payload.public_id}`]: action.payload,
        }),
        fileUploadIsLoading: omit(state.fileUploadIsLoading, [
          action.meta.filename,
        ]),
        fileUploadError: null,
      });
    }

    case actions.UPLOAD_FILE_ERROR: {
      return Object.assign({}, state, {
        fileUploadIsLoading: omit(state.fileUploadIsLoading, [
          action.meta.filename,
        ]),
        fileUploadError: action.payload,
      });
    }

    case actions.FETCH_FILES_START: {
      return Object.assign({}, state, {
        filesFetchIsLoading: true,
        filesFetchError: null,
      });
    }

    case actions.FETCH_FILES_SUCCESS: {
      return Object.assign({}, state, {
        files: keyBy(action.payload, 'public_id'),
        filesFetchIsLoading: false,
        filesFetchError: null,
      });
    }

    case actions.FETCH_FILES_ERROR: {
      return Object.assign({}, state, {
        filesFetchIsLoading: false,
        filesFetchError: action.payload,
      });
    }
    case actions.GET_FOLLOWING_START:
      return {
        ...state,
        following: {
          isFetching: true,
        },
      };
    case actions.GET_FOLLOWING_ERROR:
      return {
        ...state,
        following: {
          isFetching: false,
        },
      };
    case actions.GET_FOLLOWING_SUCCESS:
      return {
        ...state,
        following: {
          list: action.payload,
          isFetching: false,
        },
      };
    default: {
      return state;
    }
  }
}

@@ -2310,24 +2310,649 @@
 %7D,%0A      %7D;%0A
+    case actions.FOLLOW_USER_START:%0A      return %7B%0A        ...state,%0A        following: %7B%0A          ...state.following,%0A          list: %5B%0A            ...state.following.list,%0A            action.meta.username,%0A          %5D,%0A        %7D,%0A      %7D;%0A    case actions.UNFOLLOW_USER_START:%0A      const targetIdx = state.following.list.indexOf(action.meta.username);%0A      const newList = %5B%0A        ...state.following.list.slice(0, targetIdx),%0A        ...state.following.list.slice(targetIdx + 1),%0A      %5D;%0A      return %7B%0A        ...state,%0A        following: %7B%0A          ...state.following,%0A          list: newList,%0A        %7D,%0A      %7D;%0A
     default:

change state optimistically on follow/unfollow