import React from 'react'; import {Line} from 'rc-progress'; import lbry from './lbry.js'; import SettingsPage from './page/settings.js'; import HelpPage from './page/help.js'; import WatchPage from './page/watch.js'; import ReportPage from './page/report.js'; import StartPage from './page/start.js'; import ClaimCodePage from './page/claim_code.js'; import ReferralPage from './page/referral.js'; import WalletPage from './page/wallet.js'; import DetailPage from './page/show.js'; import PublishPage from './page/publish.js'; import DiscoverPage from './page/discover.js'; import SplashScreen from './component/splash.js'; import DeveloperPage from './page/developer.js'; import {FileListDownloaded, FileListPublished} from './page/file-list.js'; import Drawer from './component/drawer.js'; import Header from './component/header.js'; import {Modal, ExpandableModal} from './component/modal.js'; import {Link} from './component/link.js'; const {remote, ipcRenderer, shell} = require('electron'); const {download} = remote.require('electron-dl'); const os = require('os'); const path = require('path'); const app = require('electron').remote.app; var App = React.createClass({ _error_key_labels: { connectionString: 'API connection string', method: 'Method', params: 'Parameters', code: 'Error code', message: 'Error message', data: 'Error data', }, _upgradeDownloadItem: null, _isMounted: false, _version: null, // Temporary workaround since electron-dl throws errors when you try to get the filename getDefaultProps: function() { return { address: window.location.search }; }, getUpgradeFilename: function() { if (os.platform() == 'darwin') { return `LBRY-${this._version}.dmg`; } else if (os.platform() == 'linux') { return `LBRY_${this._version}_amd64.deb`; } else { return `LBRY.Setup.${this._version}.exe`; } }, getViewingPageAndArgs: function(address) { // For now, routes are in format ?page or ?page=args let [isMatch, viewingPage, pageArgs] = address.match(/\??([^=]*)(?:=(.*))?/); return { viewingPage: viewingPage, pageArgs: pageArgs === undefined ? null : pageArgs }; }, getInitialState: function() { var match, param, val, viewingPage, pageArgs, drawerOpenRaw = sessionStorage.getItem('drawerOpen'); return Object.assign(this.getViewingPageAndArgs(this.props.address), { drawerOpen: drawerOpenRaw !== null ? JSON.parse(drawerOpenRaw) : true, errorInfo: null, modal: null, updateUrl: null, isOldOSX: null, downloadProgress: null, downloadComplete: false, }); }, componentWillMount: function() { document.addEventListener('unhandledError', (event) => { this.alertError(event.detail); }); //open links in external browser and skip full redraw on changing page document.addEventListener('click', (event) => { var target = event.target; while (target && target !== document) { if (target.matches('a[href^="http"]')) { event.preventDefault(); shell.openExternal(target.href); return; } if (target.matches('a[href^="?"]')) { event.preventDefault(); if (this._isMounted) { this.setState(this.getViewingPageAndArgs(target.getAttribute('href'))); } } target = target.parentNode; } }); lbry.checkNewVersionAvailable((isAvailable) => { if (!isAvailable || sessionStorage.getItem('upgradeSkipped')) { return; } lbry.getVersionInfo((versionInfo) => { this._version = versionInfo.lbrynet_version; // temp for building upgrade filename var isOldOSX = false; if (versionInfo.os_system == 'Darwin') { var updateUrl = 'https://lbry.io/get/lbry.dmg'; var maj, min, patch; [maj, min, patch] = versionInfo.lbrynet_version.split('.'); if (maj == 0 && min <= 2 && patch <= 2) { isOldOSX = true; } } else if (versionInfo.os_system == 'Linux') { var updateUrl = 'https://lbry.io/get/lbry.deb'; } else if (versionInfo.os_system == 'Windows') { var updateUrl = 'https://lbry.io/get/lbry.exe'; } else { var updateUrl = 'https://lbry.io/get'; } this.setState({ modal: 'upgrade', isOldOSX: isOldOSX, updateUrl: updateUrl, }) }); }); }, openDrawer: function() { sessionStorage.setItem('drawerOpen', true); this.setState({ drawerOpen: true }); }, closeDrawer: function() { sessionStorage.setItem('drawerOpen', false); this.setState({ drawerOpen: false }); }, closeModal: function() { this.setState({ modal: null, }); }, componentDidMount: function() { this._isMounted = true; }, componentWillUnmount: function() { this._isMounted = false; }, handleUpgradeClicked: function() { // TODO: create a callback for onProgress and have the UI // show download progress // TODO: calling lbry.stop() ends up displaying the "daemon // unexpectedly stopped" page. Have a better way of shutting down let dir = app.getPath('temp'); let options = { onProgress: (p) => this.setState({downloadProgress: Math.round(p * 100)}), directory: dir, }; download(remote.getCurrentWindow(), this.state.updateUrl, 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. */ this._upgradeDownloadItem = downloadItem; this._upgradeDownloadPath = path.join(dir, this.getUpgradeFilename()); this.setState({ downloadComplete: true }); }); this.setState({modal: 'downloading'}); }, handleStartUpgradeClicked: function() { ipcRenderer.send('upgrade', this._upgradeDownloadPath); }, cancelUpgrade: function() { if (this._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 { this._upgradeDownloadItem.cancel(); } catch (err) { // Do nothing } } this.setState({ downloadProgress: null, downloadComplete: false, modal: null, }); }, handleSkipClicked: function() { sessionStorage.setItem('upgradeSkipped', true); this.setState({ modal: null, }); }, onSearch: function(term) { this.setState({ viewingPage: 'discover', pageArgs: term }); }, alertError: function(error) { var errorInfoList = []; for (let key of Object.keys(error)) { let val = typeof error[key] == 'string' ? error[key] : JSON.stringify(error[key]); let label = this._error_key_labels[key]; errorInfoList.push(
  • {label}: {val}
  • ); } this.setState({ modal: 'error', errorInfo: , }); }, getHeaderLinks: function() { switch(this.state.viewingPage) { case 'wallet': case 'send': case 'receive': case 'claim': case 'referral': return { '?wallet' : 'Overview', '?send' : 'Send', '?receive' : 'Receive', '?claim' : 'Claim Beta Code', '?referral' : 'Check Referral Credit', }; case 'downloaded': case 'published': return { '?downloaded': 'Downloaded', '?published': 'Published', }; default: return null; } }, getMainContent: function() { switch(this.state.viewingPage) { case 'settings': return ; case 'help': return ; case 'watch': return ; case 'report': return ; case 'downloaded': return ; case 'published': return ; case 'start': return ; case 'claim': return ; case 'referral': return ; case 'wallet': case 'send': case 'receive': return ; case 'show': return ; case 'publish': return ; case 'developer': return ; case 'discover': default: return ; } }, render: function() { var mainContent = this.getMainContent(), headerLinks = this.getHeaderLinks(), searchQuery = this.state.viewingPage == 'discover' && this.state.pageArgs ? this.state.pageArgs : ''; return ( this.state.viewingPage == 'watch' ? mainContent :
    {mainContent}

    Your version of LBRY is out of date and may be unreliable or insecure.

    {this.state.isOldOSX ?

    Before installing the new version, make sure to exit LBRY. If you started the app, click the LBRY icon in your status bar and choose "Quit."

    : null}
    Downloading Update{this.state.downloadProgress ? `: ${this.state.downloadProgress}%` : null} {this.state.downloadComplete ? (

    Click "Begin Upgrade" to start the upgrade process.

    The app will close, and you will be prompted to install the latest version of LBRY.

    After the install is complete, please reopen the app.

    ) : null }
    {this.state.downloadComplete ? : null}

    Error

    We're sorry that LBRY has encountered an error. This has been reported and we will investigate the problem.

    ); } }); export default App;