import * as types from 'constants/action_types' import lbry from 'lbry' import { selectUpdateUrl, selectUpgradeDownloadPath, selectUpgradeDownloadItem, selectUpgradeFilename, selectPageTitle, selectCurrentPage, selectCurrentParams, } from 'selectors/app' import { doSearch, } from 'actions/search' const {remote, ipcRenderer, shell} = require('electron'); const path = require('path'); const app = require('electron').remote.app; const {download} = remote.require('electron-dl'); const fs = remote.require('fs'); const queryStringFromParams = (params) => { return Object .keys(params) .map(key => `${key}=${params[key]}`) .join('&') } export function doNavigate(path, params = {}) { return function(dispatch, getState) { let url = path if (params) url = `${url}?${queryStringFromParams(params)}` dispatch(doChangePath(url)) const state = getState() const pageTitle = selectPageTitle(state) dispatch(doHistoryPush(params, pageTitle, url)) } } export function doChangePath(path) { return function(dispatch, getState) { dispatch({ type: types.CHANGE_PATH, data: { path, } }) const state = getState() const pageTitle = selectPageTitle(state) window.document.title = pageTitle const currentPage = selectCurrentPage(state) if (currentPage === 'search') { const params = selectCurrentParams(state) dispatch(doSearch(params.query)) } } } export function doHistoryBack() { return function(dispatch, getState) { history.back() } } export function doHistoryPush(params, title, relativeUrl) { return function(dispatch, getState) { let pathParts = window.location.pathname.split('/') pathParts[pathParts.length - 1] = relativeUrl.replace(/^\//, '') const url = pathParts.join('/') title += " - LBRY" history.pushState(params, title, url) } } export function doOpenModal(modal) { return { type: types.OPEN_MODAL, data: { modal } } } export function doCloseModal() { return { type: types.CLOSE_MODAL, } } export function doUpdateDownloadProgress(percent) { return { type: types.UPGRADE_DOWNLOAD_PROGRESSED, data: { percent: percent } } } export function doSkipUpgrade() { return { type: types.SKIP_UPGRADE } } export function doStartUpgrade() { return function(dispatch, getState) { const state = getState() const upgradeDownloadPath = selectUpgradeDownloadPath(state) ipcRenderer.send('upgrade', upgradeDownloadPath) } } export function doDownloadUpgrade() { return function(dispatch, getState) { const state = getState() // Make a new directory within temp directory so the filename is guaranteed to be available const dir = fs.mkdtempSync(app.getPath('temp') + require('path').sep); const upgradeFilename = selectUpgradeFilename(state) let options = { onProgress: (p) => dispatch(doUpdateDownloadProgress(Math.round(p * 100))), directory: dir, }; download(remote.getCurrentWindow(), selectUpdateUrl(state), options) .then(downloadItem => { /** * TODO: get the download path directly from the download object. It should just be * downloadItem.getSavePath(), but the copy on the main process is being garbage collected * too soon. */ dispatch({ type: types.UPGRADE_DOWNLOAD_COMPLETED, data: { downloadItem, path: path.join(dir, upgradeFilename) } }) }); dispatch({ type: types.UPGRADE_DOWNLOAD_STARTED }) dispatch({ type: types.OPEN_MODAL, data: { modal: 'downloading' } }) } } export function doCancelUpgrade() { return function(dispatch, getState) { const state = getState() const upgradeDownloadItem = selectUpgradeDownloadItem(state) if (upgradeDownloadItem) { /* * Right now the remote reference to the download item gets garbage collected as soon as the * the download is over (maybe even earlier), so trying to cancel a finished download may * throw an error. */ try { upgradeDownloadItem.cancel(); } catch (err) { console.error(err) // Do nothing } } dispatch({ type: types.UPGRADE_CANCELLED }) } } export function doCheckUpgradeAvailable() { return function(dispatch, getState) { const state = getState() lbry.getAppVersionInfo().then(({remoteVersion, upgradeAvailable}) => { if (upgradeAvailable) { dispatch({ type: types.UPDATE_VERSION, data: { version: remoteVersion, } }) dispatch({ type: types.OPEN_MODAL, data: { modal: 'upgrade' } }) } }); } } export function doAlertError(errorList) { return function(dispatch, getState) { const state = getState() console.log('do alert error') console.log(errorList) dispatch({ type: types.OPEN_MODAL, data: { modal: 'error', extraContent: errorList } }) } } export function doDaemonReady() { return { type: types.DAEMON_READY } } export function doShowSnackBar(data) { return { type: types.SHOW_SNACKBAR, data, } } export function doRemoveSnackBarSnack() { return { type: types.REMOVE_SNACKBAR_SNACK, } }