text: // @flow
  import * as ACTIONS from 'constants/action_types';
  import { parseURI, ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux';
  import { VIEW_ALL } from 'constants/subscriptions';
  import { handleActions } from 'util/redux-utils';
  
  const defaultState: SubscriptionState = {
    subscriptions: [],
    unread: {},
    suggested: {},
    loading: false,
    viewMode: VIEW_ALL,
    loadingSuggested: false,
    firstRunCompleted: false,
    showSuggestedSubs: false,
    enabledChannelNotifications: [],
  };
  
  export default handleActions(
    {
      [ACTIONS.CHANNEL_SUBSCRIBE]: (state: SubscriptionState, action: DoChannelSubscribe): SubscriptionState => {
        const newSubscription: Subscription = action.data;
        const newSubscriptions: Array<Subscription> = state.subscriptions.slice();
        // prevent duplicates in the sidebar
        if (!newSubscriptions.some(sub => sub.uri === newSubscription.uri)) {
          newSubscriptions.unshift(newSubscription);
        }
  
        return {
          ...state,
          subscriptions: newSubscriptions,
        };
      },
      [ACTIONS.CHANNEL_UNSUBSCRIBE]: (state: SubscriptionState, action: DoChannelUnsubscribe): SubscriptionState => {
        const subscriptionToRemove: Subscription = action.data;
        const newSubscriptions = state.subscriptions
          .slice()
          .filter(subscription => subscription.channelName !== subscriptionToRemove.channelName);
  
        // Check if we need to remove it from the 'unread' state
        const { unread } = state;
        if (unread[subscriptionToRemove.uri]) {
          delete unread[subscriptionToRemove.uri];
        }
        return {
          ...state,
          unread: { ...unread },
          subscriptions: newSubscriptions,
        };
      },
      [ACTIONS.SET_SUBSCRIPTION_LATEST]: (
        state: SubscriptionState,
        action: SetSubscriptionLatest
      ): SubscriptionState => ({
        ...state,
        subscriptions: state.subscriptions.map(subscription =>
          subscription.channelName === action.data.subscription.channelName
            ? { ...subscription, latest: action.data.uri }
            : subscription
        ),
      }),
      [ACTIONS.UPDATE_SUBSCRIPTION_UNREADS]: (
        state: SubscriptionState,
        action: DoUpdateSubscriptionUnreads
      ): SubscriptionState => {
        const { channel, uris, type } = action.data;
  
        return {
          ...state,
          unread: {
            ...state.unread,
            [channel]: {
              uris,
              type,
            },
          },
        };
      },
      [ACTIONS.REMOVE_SUBSCRIPTION_UNREADS]: (
        state: SubscriptionState,
        action: DoRemoveSubscriptionUnreads
      ): SubscriptionState => {
        const { channel, uris } = action.data;
  
        // If no channel is passed in, remove all unreads
        let newUnread;
        if (channel) {
          newUnread = { ...state.unread };
  
          if (!uris) {
            delete newUnread[channel];
          } else {
            newUnread[channel].uris = uris;
          }
        } else {
          newUnread = {};
        }
  
        return {
          ...state,
          unread: {
            ...newUnread,
          },
        };
      },
      [ACTIONS.FETCH_SUBSCRIPTIONS_START]: (state: SubscriptionState): SubscriptionState => ({
        ...state,
        loading: true,
      }),
      [ACTIONS.FETCH_SUBSCRIPTIONS_FAIL]: (state: SubscriptionState): SubscriptionState => ({
        ...state,
        loading: false,
      }),
      [ACTIONS.FETCH_SUBSCRIPTIONS_SUCCESS]: (
        state: SubscriptionState,
        action: FetchedSubscriptionsSucess
      ): SubscriptionState => ({
        ...state,
        loading: false,
        subscriptions: action.data,
      }),
      [ACTIONS.SET_VIEW_MODE]: (state: SubscriptionState, action: SetViewMode): SubscriptionState => ({
        ...state,
        viewMode: action.data,
      }),
      [ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_START]: (state: SubscriptionState): SubscriptionState => ({
        ...state,
        loadingSuggested: true,
      }),
      [ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_SUCCESS]: (
        state: SubscriptionState,
        action: GetSuggestedSubscriptionsSuccess
      ): SubscriptionState => ({
        ...state,
        suggested: action.data,
        loadingSuggested: false,
      }),
      [ACTIONS.GET_SUGGESTED_SUBSCRIPTIONS_FAIL]: (state: SubscriptionState): SubscriptionState => ({
        ...state,
        loadingSuggested: false,
      }),
      [LBRY_REDUX_ACTIONS.USER_STATE_POPULATE]: (
        state: SubscriptionState,
        action: { data: { subscriptions: ?Array<string> } }
      ) => {
        const { subscriptions } = action.data;
        let newSubscriptions;
  
        if (!subscriptions) {
          newSubscriptions = state.subscriptions;
        } else {
          const parsedSubscriptions = subscriptions.map(uri => {
            const { channelName } = parseURI(uri);
  
            return {
              uri,
              channelName: `@${channelName}`,
            };
          });
          newSubscriptions = parsedSubscriptions;
        }
  
        return {
          ...state,
          subscriptions: newSubscriptions,
        };
      },
    },
    defaultState
  );
  