// Main (() => { function copyToClipboard(text) { const clip = document.createElement('input'); clip.id = 'clipper'; clip.value = text; document.body.appendChild(clip); clip.select(); document.execCommand('copy'); clip.value = ''; clip.parentNode.removeChild(clip); } function setInnerText(id, text) { document.getElementById(id).innerText = text; } function getInnerText(id) { return document.getElementById(id).innerText; } function setValue(id, value) { document.getElementById(id).value = value; } function setChecked(id, value) { document.getElementById(id)["checked"] = value; } function getChecked(id) { return document.getElementById(id)["checked"]; } function getValue(id) { return document.getElementById(id).value; } function setSelect(id, itemList) { const select = document.getElementById(id); const allowChange = select['allow_change'] !== false; if (allowChange) { while (select.options.length > itemList.length) { select.removeChild(select.options[select.options.length - 1]); } for (let i = 0; i < itemList.length; i++) { if (select.options[i]) { if (select.options[i].text !== itemList[i]) { select.options[i].text = itemList[i]; } } else { const opt = document.createElement('option'); opt.text = itemList[i]; select.appendChild(opt); } } } } window.uiUpdate = (() => { const _renter = (() => { return { setAllocatedFunds: (currency) => { setInnerText('ID_Renter_AllocatedFunds', currency); }, setUsedFunds: (currency) => { setInnerText('ID_Renter_UsedFunds', currency); }, setAvailableFunds: (currency) => { setInnerText('ID_Renter_AvailableFunds', currency); }, setHostCount: (count) => { setInnerText('ID_Renter_HostCount', count); }, setEstimatedSpace: (space) => { setInnerText('ID_Renter_EstimatedSpace', space); }, setUsedSpace: (space) => { setInnerText('ID_Renter_UsedSpace', space); }, setEstimatedCost: (currency) => { setInnerText('ID_Renter_EstimatedCost', currency); }, setAvailableSpace: (space) => { setInnerText('ID_Renter_AvailablSpace', space); }, setDownloadCost: (currency) => { setInnerText('ID_Renter_EstimatedDownloadCost', currency); }, setUploadCost: (currency) => { setInnerText('ID_Renter_EstimatedUploadCost', currency); }, setEstimatedCost: (currency) => { setInnerText('ID_Renter_EstimatedCost', currency); }, setEstimatedDownloadCost: (currency) => { setInnerText('ID_Renter_EstimatedDownloadCost', currency); }, setEstimatedUploadCost: (currency) => { setInnerText('ID_Renter_EstimatedUploadCost', currency); }, setAllowance: (allowance) => { if (document.getElementById('renter_settings_window').classList.contains('hidden-element')) { setValue('ID_RenterSetFunds', allowance.Funds); setValue('ID_RenterSetHosts', allowance.Hosts); setValue('ID_RenterSetPeriod', allowance.Period); setValue('ID_RenterSetRenewWindow', allowance.RenewWindowInBlocks); AppActions.calculateEstimatedStorage(allowance.Funds, (res) => { setInnerText('ID_RenterCalcStorage', '~' + res); }); } }, setUploadProgress: (items) => { _uploadItems = JSON.parse(items || "[]"); buildUploadTable(); } }; })(); const _wallet = (() => { return { setConfirmedBalance: (balance) => { setInnerText('ID_WalletConfirmedBalance', balance); setInnerText('ID_Send_Balance', balance); }, setUnconfirmedBalance: (balance) => { setInnerText('ID_WalletBalanceUnconfirmed', balance); }, setTotalBalance: (balance) => { setInnerText('ID_WalletTotalBalance', balance); }, setReceiveAddress: (address) => { setInnerText('ID_WalletReceiveAddress', address); }, setLockWalletOnExit: (lock) => { if (document.getElementById('sia_settings_window').classList.contains('hidden-element')) { setChecked('ID_SettingsLockWalletOnExit', lock); } } }; })(); return { Renter: _renter, Wallet: _wallet, setBlockHeight: (height) => { setInnerText('ID_BlockHeight', height); }, setServerVersion: (version) => { setInnerText('ID_ServerVersion', version); }, setAvailableDriveLetters: (drives) => { setSelect('ID_MountDrives', drives); }, notifyDriveUnmounted: _notifyDriveUnmounted, reloadApplication: reloadApplication, setSiaSettings: (settings) => { if (document.getElementById('sia_settings_window').classList.contains('hidden-element')) { const j = JSON.parse(settings); for (const s in j) { if (j.hasOwnProperty(s)) { const id = 'ID_Settings_' + s; const input = document.getElementById(id); if (input.type === 'checkbox') { setChecked(id, j[s]); } else { setValue(id, j[s]); } } } } }, displayShutdownWindow: () => { const div = document.getElementById('shutdown_window'); document.body.innerHTML = ''; document.body.appendChild(div); div.classList.remove('hidden-element'); }, notifyDriveMounting: _notifyDriveMounting, displayPrompt: (title) => { return confirm(title); } }; })(); const UiState = (() => { function _clientVersion() { return 'v' + window.uiState.clientVersion; } function _isOnline() { return window.uiState.isOnline; } function _isWalletConfigured() { return window.uiState.isWalletConfigured; } function _isWalletLocked() { return window.uiState.isWalletLocked; } function _allocatedRenterFunds() { return window.uiState.allocatedRenterFunds; } function _defaultRenterSettings() { return window.uiState.defaultRenterSettings; } function _getStoreUnlockPassword() { return window.uiState.storeUnlockPassword; } return { clientVersion: _clientVersion, isOnline: _isOnline, isWalletConfigured: _isWalletConfigured, isWalletLocked: _isWalletLocked, allocatedRenterFunds: _allocatedRenterFunds, defaultRenterSettings: _defaultRenterSettings, getStoreUnlockPassword: _getStoreUnlockPassword }; })(); const AppActions = (() => { function _createWallet(password, cb) { console.log('Create wallet'); return window.appActions.createWallet(password, cb); } function _mountDrive(mountLocation, cb) { console.log('Mount drive: ' + mountLocation); return window.appActions.mountDrive(mountLocation, cb); } function _autoUnlockWallet(cb) { return window.appActions.autoUnlockWallet(cb); } function _unlockWallet(pwd, cb) { return window.appActions.unlockWallet(pwd, cb); } function _unmountDrive(cb) { console.log('Unmount drive'); return window.appActions.unmountDrive(cb); } function _shutdown() { window.appActions.shutdown(); } function _setRenterSettings(allowance, cb) { window.appActions.setRenterSettings(allowance, cb); } function _calculateEstimatedStorage(funds, cb) { window.appActions.calculateEstimatedStorage(funds, cb) } function _setSiaSettings(settings, cb) { window.appActions.setSiaSettings(settings, cb); } function _autoMountDrive() { window.appActions.autoMountDrive(); } function _walletSend(address, amount, cb) { window.appActions.walletSend(address, amount, cb); } return { createWallet: _createWallet, mountDrive: _mountDrive, unlockWallet: _unlockWallet, autoUnlockWallet: _autoUnlockWallet, unmountDrive: _unmountDrive, shutdown: _shutdown, setRenterSettings: _setRenterSettings, calculateEstimatedStorage: _calculateEstimatedStorage, setSiaSettings: _setSiaSettings, autoMountDrive: _autoMountDrive, walletSend: _walletSend }; })(); let _mountHandler; let _allowRenterSave = true; let _uploadItems; let _uploadTableInitialized = false; function buildUploadTable() { const table = $('#ID_UploadProgressTable'); if (!table.hasClass('hidden-element')) { if (!_uploadTableInitialized) { _uploadTableInitialized = true; table.DataTable({ data: [], columns: [ {title: "SiaPath"}, {title: "Progress"} ], deferRender: true, scrollY: 343, scrollCollapse: false, paging: false, dom: '<"pull-left"f>rt<"bottom"lip><"clear">', }); } const dataTable = table.DataTable(); dataTable.clear(); dataTable.rows.add(_uploadItems); dataTable.draw(false); } } function setMainWindow(name) { console.log('Setting main window: ' + name); const elem = document.getElementById(name); const mainWindow = document.getElementById('main_window'); if (mainWindow.childElementCount === 1) { const curElem = mainWindow.firstChild; mainWindow.removeChild(curElem); curElem.classList.add('hidden-element'); document.body.appendChild(curElem); } elem.parentElement.removeChild(elem); elem.classList.remove('hidden-element'); mainWindow.appendChild(elem); const focusElem = elem.getElementsByClassName('vfocus'); if (focusElem.length) { focusElem[0].focus(); } } function displayErrorPopup(title, msg, cb) { alert(msg); if (cb) { cb(); } } function _notifyDriveMounting(mountLocation) { const mountButton = document.getElementById('ID_MountButton'); const mountSelect = document.getElementById('ID_MountDrives'); mountButton.innerText = "Unmount"; mountButton.onclick = _mountHandler; mountSelect['allow_change'] = false; mountSelect.disabled = true; mountSelect.value = mountLocation; } function _notifyDriveUnmounted() { const mountButton = document.getElementById('ID_MountButton'); const mountSelect = document.getElementById('ID_MountDrives'); if (mountButton.innerText === 'Unmount') { mountButton.innerText = "Mount"; mountButton.onclick = _mountHandler; mountButton.disabled = false; mountSelect.disabled = false; mountSelect['allow_change'] = true; } } function displayFormingContracts(show) { const img = document.getElementById('ID_Renter_Allowance_Active'); if (show) { img.style.display = 'inline-block'; } else { img.style.display = 'none'; } } function handleRenterUploads() { const table = $('#ID_UploadProgressTable'); const okButton = document.getElementById('ID_RenterUploadsOk'); okButton.onclick = () => { okButton.onclick = null; table.addClass('hidden-element'); beginMainApplication(false); }; setMainWindow('upload_progress_window'); table.removeClass('hidden-element'); buildUploadTable(); } function handleSiaEditSettings() { const cancelButton = document.getElementById('ID_SiaSettingsCancel'); cancelButton.onclick = () => { cancelButton.onclick = null; saveButton.onclick = null; beginMainApplication(false); }; const saveButton = document.getElementById('ID_SiaSettingsOK'); saveButton.onclick = () => { saveButton.onclick = null; cancelButton.onclick = null; AppActions.setSiaSettings({ 'AutoMountOnUnlock': getChecked('ID_Settings_AutoMountOnUnlock'), 'AutoStartOnLogon': getChecked('ID_Settings_AutoStartOnLogon'), 'CloseToTray': getChecked('ID_Settings_CloseToTray'), 'ConfirmApplicationExit': getChecked('ID_Settings_ConfirmApplicationExit'), 'LaunchFileMgrOnMount': getChecked('ID_Settings_LaunchFileMgrOnMount'), 'LockWalletOnExit': getChecked('ID_Settings_LockWalletOnExit'), 'StoreUnlockPassword': getChecked('ID_Settings_StoreUnlockPassword'), 'LaunchBundledSiad': getChecked('ID_Settings_LaunchBundledSiad'), 'ApiPort': getValue('ID_Settings_ApiPort'), 'HostPort': getValue('ID_Settings_HostPort'), 'RpcPort': getValue('ID_Settings_RpcPort') }, (success, reason) => { if (success) { reloadApplication(false); } else { displayErrorPopup('Settings Failed', reason); handleSiaEditSettings(); } }); }; setMainWindow('sia_settings_window'); } function handleWalletSend() { const saveButton = document.getElementById('ID_SendOK'); const cancelButton = document.getElementById('ID_SendCancel'); cancelButton.onclick = () => { cancelButton.onclick = null; saveButton.onclick = null; beginMainApplication(false); }; saveButton.onclick = () => { cancelButton.onclick = null; saveButton.onclick = null; const address = getValue('ID_Send_Address'); const amount = getValue('ID_Send_Amount'); AppActions.walletSend(address, amount, (success, reason) => { if (success) { setValue('ID_Send_Address', ''); setValue('ID_Send_Amount', ''); } else { displayErrorPopup('Send Failed', reason); } beginMainApplication(false); }); }; setMainWindow('send_window'); } function beginMainApplication(checkAutoMount) { const settingsEditLink = document.getElementById('ID_Sia_Settings_Edit'); settingsEditLink.onclick = () => { settingsEditLink.onclick = null; handleSiaEditSettings(); }; const copyAddressLink = document.getElementById('ID_WalletReceiveAddressCopy'); copyAddressLink.onclick = () => { const address = getInnerText('ID_WalletReceiveAddress'); copyToClipboard(address); }; const sendLink = document.getElementById('ID_Wallet_Send'); sendLink.onclick = () => { sendLink.onclick = null; handleWalletSend(); }; const renterEditLink = document.getElementById('ID_Renter_Edit'); renterEditLink.onclick = () => { renterEditLink.onclick = null; handleRenterEditSettings(); }; const renterUploadsLink = document.getElementById('ID_Renter_Uploads'); renterUploadsLink.onclick = () => { renterUploadsLink.onclick = null; handleRenterUploads(); }; const mountButton = document.getElementById('ID_MountButton'); const mountSelect = document.getElementById('ID_MountDrives'); _mountHandler = () => { mountSelect['allow_change'] = false; if (UiState.allocatedRenterFunds() === '0') { displayErrorPopup('Error', 'Renter funding must be configured before trying to mount.') } else { mountButton.onclick = null; mountButton.disabled = true; mountSelect.disabled = true; if (mountButton.innerText === "Mount") { AppActions.mountDrive(mountSelect.value, (success, reason) => { if (success) { mountButton.innerText = "Unmount"; } else { displayErrorPopup('Mount Failed', reason); } mountButton.onclick = _mountHandler; mountButton.disabled = false; }); } else { AppActions.unmountDrive((success, reason) => { if (success) { _notifyDriveUnmounted() } else { displayErrorPopup('Unmount Failed', reason); mountButton.onclick = _mountHandler; mountButton.disabled = false; mountSelect['allow_change'] = true; } }); } } }; mountButton.onclick = _mountHandler; if (checkAutoMount) { AppActions.autoMountDrive( ); } setMainWindow('app_window'); } function handleRenterEditSettings() { const funds = document.getElementById('ID_RenterSetFunds'); funds.oninput = () => { AppActions.calculateEstimatedStorage(funds.value, (res) => { setInnerText('ID_RenterCalcStorage', '~' + res); }); }; const defaultsButton = document.getElementById('ID_RenterSettingsDefaults'); const cancelButton = document.getElementById('ID_RenterSettingsCancel'); const saveButton = document.getElementById('ID_RenterSettingsOK'); cancelButton.onclick = () => { funds.oninput = null; saveButton.onclick = null; cancelButton.onclick = null; defaultsButton.onclick = null; beginMainApplication(false); }; if (_allowRenterSave) { defaultsButton.classList.remove('hidden-element'); saveButton.classList.remove('hidden-element'); defaultsButton.onclick = () => { funds.oninput = null; const settings = UiState.defaultRenterSettings(); if (getValue('ID_RenterSetFunds') === '0') { setValue('ID_RenterSetFunds', settings.Funds); } setValue('ID_RenterSetHosts', settings.Hosts); setValue('ID_RenterSetPeriod', settings.Period); setValue('ID_RenterSetRenewWindow', settings.RenewWindowInBlocks); }; saveButton.onclick = () => { _allowRenterSave = false; funds.oninput = null; saveButton.onclick = null; cancelButton.onclick = null; defaultsButton.onclick = null; AppActions.setRenterSettings({ 'Funds': getValue('ID_RenterSetFunds'), 'Hosts': getValue('ID_RenterSetHosts'), 'Period': getValue('ID_RenterSetPeriod'), 'RenewWindowInBlocks': getValue('ID_RenterSetRenewWindow') }, (success, reason) => { if (!success) { displayErrorPopup('Allocation Failed', reason); } displayFormingContracts(false); _allowRenterSave = true; }); displayFormingContracts(true); beginMainApplication(false); }; } else { defaultsButton.classList.add('hidden-element'); saveButton.classList.add('hidden-element'); } setMainWindow('renter_settings_window'); } function manualUnlockWallet() { const unlockButton = document.getElementById('ID_UnlockWalletButton'); unlockButton.onclick = () => { unlockButton.onclick = null; const password = document.getElementById('ID_WalletUnlockPwd'); if (AppActions.unlockWallet(password.value, (success, reason) => { if (success) { beginMainApplication(true); } else { displayErrorPopup('Error', reason, () => { handleUnlockWallet(); }); } })) { password.value = ''; setMainWindow('unlocking_window'); } else { password.value = ''; } }; setMainWindow('unlock_window'); } function handleUnlockWallet() { if (UiState.getStoreUnlockPassword()) { if (AppActions.autoUnlockWallet((success) => { if (success) { beginMainApplication(true); } else { manualUnlockWallet(); } })) { setMainWindow('unlocking_window'); } else { manualUnlockWallet(); } } else { manualUnlockWallet(); } } function handleWalletCreated(seed) { document.getElementById('ID_WalletSeed').innerText = seed; const button = document.getElementById('ID_WalletCreatedButton'); button.onclick = () => { button.onclick = null; handleUnlockWallet(); }; setMainWindow('wallet_created_window'); } function handleCreateWallet() { const createButton = document.getElementById('ID_CreateWalletButton'); const createClickHandler = () => { createButton.onclick = null; let create = true; let password = null; if (getChecked('ID_UsePwdForUnlock')) { document.getElementById('ID_SetWalletPassword').focus(); const pwd1 = getValue('ID_SetWalletPassword'); const pwd2 = getValue('ID_ConfirmWalletPassword'); if (pwd1) { create = (pwd1 === pwd2); if (create) { password = pwd1; } else { displayErrorPopup('Password Error', 'Password\'s do not match'); } } else { displayErrorPopup('Password Error', 'Password cannot be empty'); create = false; } } if (create) { AppActions.createWallet(password, (success, reasonOrSeed) => { password = null; if (success) { useSeedButton.onclick = null; usePwdButton.onclick = null; handleWalletCreated(reasonOrSeed); } else { displayErrorPopup('Error', reasonOrSeed, () => { createButton.onclick = createClickHandler; }); } }); } else { createButton.onclick = createClickHandler; } }; createButton.onclick = createClickHandler; const div = document.getElementById('create_wallet_password'); const useSeedButton = document.getElementById('ID_UseSeedForUnlock'); useSeedButton.onclick = () => { if (!div.classList.contains('hidden-element')) { div.classList.add('hidden-element'); } }; const usePwdButton = document.getElementById('ID_UsePwdForUnlock'); usePwdButton.onclick = () => { if (div.classList.contains('hidden-element')) { div.classList.remove('hidden-element'); } }; setMainWindow('create_window'); } function reloadApplication(checkAutoMount) { document.getElementById('ID_SiaDrive').innerText = 'SiaDrive ' + UiState.clientVersion(); if (UiState.isOnline()) { if (UiState.isWalletConfigured()) { if (UiState.isWalletLocked()) { handleUnlockWallet(); } else { beginMainApplication(checkAutoMount); } } else { handleCreateWallet(); } } else { setMainWindow('offline_window'); } } window.addEventListener('load', ()=> { console.log('Main window load'); document.getElementById('ID_ServerVersion').innerText = '...'; reloadApplication(true); }); })();