1
0
This repository has been archived on 2025-10-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
siadrive/htdocs/js/index.js
2025-10-21 07:58:47 -05:00

728 lines
22 KiB
JavaScript

// 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);
});
})();