nukeop/nuclear

View on GitHub
packages/app/app/store/middlewares/ipc.ts

Summary

Maintainability
B
5 hrs
Test Coverage
import { getOption, IpcEvents, isValidPort } from '@nuclear/core';
import { ipcRenderer } from 'electron';
import _ from 'lodash';
import { LocalLibrary } from '../../actions/actionTypes';
import { Queue, Settings } from '../../actions/actionTypes';
import { changeConnectivity } from '../../actions/connectivity';
import * as DownloadActions from '../../actions/downloads';
import * as PlayerActions from '../../actions/player';
import { CLOSE_WINDOW, MINIMIZE_WINDOW, MAXIMIZE_WINDOW, OPEN_DEVTOOLS } from '../../actions/window';
import { getType } from 'typesafe-actions';
import { Middleware } from 'redux';

type IpcActionType = {
  type: string;
  payload: any;
  meta: {
    fromMain?: boolean;
  };
}

const ipcConnect: Middleware = () => next => {
  next({
    type: LocalLibrary.UPDATE_LOCAL_FOLDERS,
    payload: ipcRenderer.sendSync(IpcEvents.LOCALFOLDERS_GET)
  });

  next({
    type: LocalLibrary.SCAN_LOCAL_FOLDERS_SUCCESS,
    payload: ipcRenderer.sendSync(IpcEvents.LOCAL_METAS)
  });

  return ({ meta = {}, payload, type }: IpcActionType) => {
    if (meta.fromMain) {
      next({ type, payload });
      return;
    }
  
    switch (type) {
    case getType(PlayerActions.startPlayback):
      ipcRenderer.send(IpcEvents.PLAY);
      break;
    case getType(PlayerActions.updateVolume):
      ipcRenderer.send(IpcEvents.VOLUME, payload);
      break;
    case getType(PlayerActions.pausePlayback):
      ipcRenderer.send(IpcEvents.PAUSE);
      break;
    
    case LocalLibrary.SCAN_LOCAL_FOLDERS:
      ipcRenderer.send(IpcEvents.LOCALFOLDERS_REFRESH);
      break;
    case LocalLibrary.REMOVE_LOCAL_FOLDER:
      ipcRenderer.send(IpcEvents.LOCALFOLDER_REMOVE, payload);
      break;
    case LocalLibrary.UPDATE_LOCAL_FOLDERS:
      ipcRenderer.send(IpcEvents.LOCALFOLDERS_SET, payload);
      break;
  
    case Queue.ADD_QUEUE_ITEM:
      ipcRenderer.send(IpcEvents.TRACK_ADD, payload.item);
      break;
    case Queue.CLEAR_QUEUE:
      ipcRenderer.send(IpcEvents.QUEUE_CLEAR);
      break;
    case Queue.REMOVE_QUEUE_ITEM:
      ipcRenderer.send(IpcEvents.TRACK_REMOVE, payload);
      break;
    case Queue.QUEUE_DROP:
      return ipcRenderer.send(IpcEvents.QUEUE_DROP, payload);
  
    case Settings.SET_BOOLEAN_OPTION:
      switch (payload.option) {
      case 'api.enabled':
        ipcRenderer.send(payload.state ? IpcEvents.API_RESTART : IpcEvents.API_STOP);
        break;
      case 'shuffleQueue':
        ipcRenderer.send(IpcEvents.SHUFFLE, payload.state);
        break;
      case 'loopAfterQueueEnd':
        ipcRenderer.send(IpcEvents.LOOP, payload.state);
        break;
      }
      break;
    case Settings.SET_NUMBER_OPTION:
      if (payload.option === 'api.port' && isValidPort(payload.state) && getOption('api.enabled')) {
        ipcRenderer.send(IpcEvents.API_RESTART);
      }
      break;
      
    case getType(changeConnectivity):
      ipcRenderer.send(IpcEvents.CONNECTIVITY, payload);
      break;

    case getType(DownloadActions.addToDownloads):
    case getType(DownloadActions.onDownloadResume): {
      if (!payload.track) {
        break;
      }

      const {track} =_.find(payload.downloads, (item) => item.track.uuid === payload.track);
      
      let maxDownloads;
      try {
        maxDownloads = Number(getOption('max.downloads'));
      } catch (err){
        maxDownloads = 1;
      }
      if (payload.downloads.filter(({status}) => status === 'Started' || status === 'Waiting').length > maxDownloads) {
        break;
      }
      
      ipcRenderer.send(IpcEvents.DOWNLOAD_START, track);
      break;
    }
    case getType(DownloadActions.onDownloadPause): {
      const {track} =_.find(payload.downloads, (item) => item.track.uuid === payload.track);

      ipcRenderer.send(IpcEvents.DOWNLOAD_PAUSE, track);
      break;
    }
    case getType(DownloadActions.onDownloadFinished):
    case getType(DownloadActions.onDownloadError): {
      const nextDownload = payload.find((download) =>
        download.status==='Waiting'
      );
      if (nextDownload) {
        ipcRenderer.send(IpcEvents.DOWNLOAD_START, nextDownload.track); 
      }
      break;
    }

    case CLOSE_WINDOW:
      return ipcRenderer.send(IpcEvents.WINDOW_CLOSE);
    case MAXIMIZE_WINDOW:
      return ipcRenderer.send(IpcEvents.WINDOW_MAXIMIZE);
    case MINIMIZE_WINDOW:
      return ipcRenderer.send(IpcEvents.WINDOW_MINIMIZE);
    case OPEN_DEVTOOLS:
      return ipcRenderer.send(IpcEvents.WINDOW_OPEN_DEVTOOLS);
    }
  
    next({ type, payload });
  };
};

export default ipcConnect;