diff --git a/electron/index.js b/electron/index.js
index 182a2d4f9..bd2602353 100644
--- a/electron/index.js
+++ b/electron/index.js
@@ -17,8 +17,12 @@ import startSandbox from './startSandbox';
import installDevtools from './installDevtools';
import fs from 'fs';
import path from 'path';
+import { diskSpaceLinux } from '../ui/util/diskspace';
+
const { download } = require('electron-dl');
const remote = require('@electron/remote/main');
+const os = require('os');
+
remote.initialize();
const filePath = path.join(process.resourcesPath, 'static', 'upgradeDisabled');
let upgradeDisabled;
@@ -292,6 +296,22 @@ app.on('before-quit', () => {
appState.isQuitting = true;
});
+ipcMain.on('get-disk-space', async (event) => {
+ try {
+ const { data_dir } = await Lbry.settings_get();
+ if (os.platform() === 'linux') {
+ const stdout = await diskSpaceLinux(data_dir);
+ const dfResult = stdout.split('\n')[1].split(/\s+/);
+ const total_and_available = { total: dfResult[1], free: dfResult[3]};
+ rendererWindow.webContents.send('send-disk-space', { diskSpace: total_and_available });
+ }
+ // const space = await nodeDiskInfo.getDiskInfo();
+ } catch (e) {
+ rendererWindow.webContents.send('send-disk-space', { error: e.message || e });
+ console.log('Failed to start LbryFirst', e);
+ }
+});
+
ipcMain.on('download-upgrade', async (event, params) => {
const { url, options } = params;
const dir = fs.mkdtempSync(app.getPath('temp') + path.sep);
diff --git a/flow-typed/Settings.js b/flow-typed/Settings.js
index 89fc59118..f98fa2d99 100644
--- a/flow-typed/Settings.js
+++ b/flow-typed/Settings.js
@@ -6,3 +6,8 @@ declare type CommentServerDetails = {
declare type WalletServerDetails = {
};
+
+declare type DiskSpace = {
+ total: string,
+ free: string,
+};
diff --git a/static/app-strings.json b/static/app-strings.json
index 831f549a8..0b8dc8edd 100644
--- a/static/app-strings.json
+++ b/static/app-strings.json
@@ -2287,5 +2287,9 @@
"View History Hosting": "View History Hosting",
"Disable automatic updates": "Disable automatic updates",
"Preven't new updates to be downloaded automatically in the background (we will keep notifying you if there is an update)": "Preven't new updates to be downloaded automatically in the background (we will keep notifying you if there is an update)",
+ "Unlimited View Hosting": "Unlimited View Hosting",
+ "Choose View Hosting Limit": "Choose View Hosting Limit",
+ "View Hosting Limit (GB)": "View Hosting Limit (GB)",
+ "%free% of %total% available": "%free% of %total% available",
"--end--": "--end--"
}
diff --git a/ui/component/settingDataHosting/index.js b/ui/component/settingDataHosting/index.js
index 1bbdf3971..c001ae8d1 100644
--- a/ui/component/settingDataHosting/index.js
+++ b/ui/component/settingDataHosting/index.js
@@ -2,10 +2,12 @@ import { connect } from 'react-redux';
import { doSetDaemonSetting, doGetDaemonStatus, doCleanBlobs } from 'redux/actions/settings';
import { selectDaemonStatus, selectDaemonSettings } from 'redux/selectors/settings';
import SettingWalletServer from './view';
+import { selectDiskSpace } from 'redux/selectors/app';
const select = (state) => ({
daemonSettings: selectDaemonSettings(state),
daemonStatus: selectDaemonStatus(state),
+ diskSpace: selectDiskSpace(state),
});
const perform = (dispatch) => ({
diff --git a/ui/component/settingDataHosting/view.jsx b/ui/component/settingDataHosting/view.jsx
index 035a32ef4..d2d05b458 100644
--- a/ui/component/settingDataHosting/view.jsx
+++ b/ui/component/settingDataHosting/view.jsx
@@ -5,6 +5,8 @@ import { FormField } from 'component/common/form';
import Button from 'component/button';
import * as DAEMON_SETTINGS from 'constants/daemon_settings';
import { formatBytes } from 'util/format-bytes';
+import { isTrulyANumber } from 'util/number';
+import I18nMessage from 'component/i18nMessage';
const BYTES_PER_MB = 1048576;
const ENABLE_AUTOMATIC_HOSTING = false;
@@ -41,155 +43,168 @@ type Props = {
daemonStatus: DaemonStatus,
// --- perform ---
setDaemonSetting: (string, ?SetDaemonSettingArg) => void,
- cleanBlobs: () => void,
+ cleanBlobs: () => string,
+ diskSpace?: DiskSpace,
+ getDaemonStatus: () => void,
};
-function SettingWalletServer(props: Props) {
- const { daemonSettings, daemonStatus, setDaemonSetting, cleanBlobs } = props;
+function SettingDataHosting(props: Props) {
+ const { daemonSettings, daemonStatus, setDaemonSetting, cleanBlobs, diskSpace, getDaemonStatus } = props;
- const { disk_space } = daemonStatus;
- const contentSpaceUsed = Number(disk_space.content_blobs_storage_used_mb);
- const networkSpaceUsed = Number(disk_space.seed_blobs_storage_used_mb);
- const blobLimitSetting = daemonSettings[DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB];
- const networkLimitSetting = daemonSettings[DAEMON_SETTINGS.NETWORK_STORAGE_LIMIT_MB];
+ const { disk_space: blobSpace } = daemonStatus;
+ const contentSpaceUsed = Number(blobSpace.content_blobs_storage_used_mb);
+ const blobLimitSetting = daemonSettings[DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB] || '0';
const [contentBlobSpaceLimitGB, setContentBlobSpaceLimit] = React.useState(
- blobLimitSetting ? blobLimitSetting / 1024 : 0
+ blobLimitSetting ? String(blobLimitSetting / 1024) : '10'
);
+ const [applying, setApplying] = React.useState(false);
+
+ const networkSpaceUsed = Number(blobSpace.seed_blobs_storage_used_mb);
+ const networkLimitSetting = daemonSettings[DAEMON_SETTINGS.NETWORK_STORAGE_LIMIT_MB] || '0';
const [networkBlobSpaceLimitGB, setNetworkBlobSpaceLimit] = React.useState(
- networkLimitSetting ? networkLimitSetting / 1024 : 0
+ networkLimitSetting ? String(networkLimitSetting / 1024) : '0'
);
- const [limitSpace, setLimitSpace] = React.useState(Boolean(blobLimitSetting));
- function updateContentBlobLimitField(gb) {
- if (gb === 0) {
- setContentBlobSpaceLimit(0);
- } else if (!gb || !isNaN(gb)) {
- setContentBlobSpaceLimit(gb);
- }
+ const [unlimited, setUnlimited] = React.useState(blobLimitSetting === '0');
+
+ React.useEffect(() => {
+ getDaemonStatus();
+ }, []);
+
+ function convertGbToMb(gb) {
+ return Number(gb) * 1024;
}
- function updateNetworkBlobLimitField(gb) {
- if (gb === 0) {
- setNetworkBlobSpaceLimit(0);
- } else if (!gb || !isNaN(gb)) {
- setNetworkBlobSpaceLimit(gb);
- }
- }
-
- function handleLimitSpace(value) {
- setLimitSpace(value);
- if (!value) {
- setDaemonSetting(DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB, String(0));
+ function handleContentLimitChange(gb) {
+ if (gb === '') {
+ setContentBlobSpaceLimit('');
+ } else if (gb === '0') {
+ setContentBlobSpaceLimit('0.01'); // setting 0 means unlimited.
} else {
- const spaceLimitMB = contentBlobSpaceLimitGB * 1024;
- setDaemonSetting(DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB, String(spaceLimitMB));
+ if (isTrulyANumber(Number(gb))) {
+ setContentBlobSpaceLimit(gb);
+ }
}
}
- function handleSetContentBlobSpaceLimit() {
- const spaceLimitMB = contentBlobSpaceLimitGB * 1024;
- if (!isNaN(spaceLimitMB) && blobLimitSetting !== spaceLimitMB * 1024) {
- setDaemonSetting(DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB, String(spaceLimitMB));
+ function handleNetworkLimitChange(gb) {
+ if (gb === '') {
+ setNetworkBlobSpaceLimit('');
+ } else {
+ const numberGb = Number(gb);
+ if (isTrulyANumber(numberGb)) {
+ setNetworkBlobSpaceLimit(gb);
+ }
}
}
- function handleSetNetworkBlobSpaceLimit() {
- const spaceLimitMB = networkBlobSpaceLimitGB * 1024;
- if (!isNaN(spaceLimitMB) && blobLimitSetting !== spaceLimitMB * 1024) {
- setDaemonSetting(DAEMON_SETTINGS.NETWORK_STORAGE_LIMIT_MB, String(spaceLimitMB));
+ async function handleApply() {
+ setApplying(true);
+ if (unlimited) {
+ await setDaemonSetting(DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB, '0');
+ } else {
+ await setDaemonSetting(
+ DAEMON_SETTINGS.BLOB_STORAGE_LIMIT_MB,
+ String(contentBlobSpaceLimitGB === '0.01' ? '1' : convertGbToMb(contentBlobSpaceLimitGB))
+ );
}
+ await setDaemonSetting(
+ DAEMON_SETTINGS.NETWORK_STORAGE_LIMIT_MB,
+ String(convertGbToMb(Number(networkBlobSpaceLimitGB)))
+ );
+ await cleanBlobs();
+ getDaemonStatus();
+ setApplying(false);
+ }
+
+ function validHostingAmount(amountString) {
+ const numberAmount = Number(amountString);
+ return amountString.length && ((numberAmount && String(numberAmount)) || numberAmount === 0);
}
return (
<>
-
- {`Automatic Hosting using ${formatBytes(networkSpaceUsed * BYTES_PER_MB)} of ${formatBytes(
- daemonSettings[DAEMON_SETTINGS.NETWORK_STORAGE_LIMIT_MB] * BYTES_PER_MB
- )}`}
-