mirror of
https://github.com/koodo-reader/koodo-reader.git
synced 2026-06-18 21:00:35 -04:00
fix bug
This commit is contained in:
2
src/assets/lib/kookit-extra-browser.min.js
vendored
2
src/assets/lib/kookit-extra-browser.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -36,7 +36,11 @@
|
||||
"Downloading, please wait": "Downloading, please wait",
|
||||
"Uploading, please wait": "Uploading, please wait",
|
||||
"Import": "Import",
|
||||
"Sync and backup": "Sync and backup",
|
||||
"Add data source": "Add data source",
|
||||
"Please select": "Please select",
|
||||
"Backup": "Backup",
|
||||
"Server path": "Server path",
|
||||
"Search my library": "Search my library",
|
||||
"Search my notes": "Search my notes",
|
||||
"Search my highlights": "Search my highlights",
|
||||
@@ -413,6 +417,10 @@
|
||||
"Add new plugin": "Add new plugin",
|
||||
"Pot is running": "Pot is running",
|
||||
"Please select the service": "Please select the service",
|
||||
"Set default sync option": "Set default sync option",
|
||||
"This feature is not available in the free version": "This feature is not available in the free version",
|
||||
"Please add data source in the setting": "Please add data source in the setting",
|
||||
"Select data source": "Select data source",
|
||||
"Upgrade failed": "Upgrade failed",
|
||||
"Restore failed": "Restore failed",
|
||||
"Backup failed": "Backup failed",
|
||||
|
||||
@@ -412,13 +412,25 @@
|
||||
"Pot is running": "Pot 正在运行中",
|
||||
"Plugin verification failed": "插件校验失败",
|
||||
"Please select the service": "请选择服务",
|
||||
"Delete data source": "删除数据源",
|
||||
"Please select": "请选择",
|
||||
"Set default sync option": "设置默认同步选项",
|
||||
"This feature is not available in the free version": "免费版不支持此功能",
|
||||
"Upgrade failed": "升级失败",
|
||||
"Restore failed": "恢复失败",
|
||||
"Backup failed": "备份失败",
|
||||
"Reset reader window's position": "重置阅读窗口的位置",
|
||||
"Reset successful": "重置成功",
|
||||
"Select data source": "选择数据源",
|
||||
"Please add data source in the setting": "请在设置中添加数据源",
|
||||
"Reset failed": "重置失败",
|
||||
"Reset": "重置",
|
||||
"Backup to": "备份到",
|
||||
"Restore from": "恢复自",
|
||||
"Sync and backup": "同步和备份",
|
||||
"Server path": "服务器路径",
|
||||
"Add data source": "添加数据源",
|
||||
"S3 Compatible": "S3 兼容",
|
||||
"This feature is only available in the developer version": "本功能仅支持开发版",
|
||||
"Paste the code of the plugin here, check out document to learn how to get more plugins": "将插件的代码粘贴在这里,查看帮助文档了解如何获取更多插件",
|
||||
"Full screen": "全屏模式"
|
||||
|
||||
@@ -235,3 +235,16 @@
|
||||
line-height: 50px;
|
||||
font-size: 18px;
|
||||
}
|
||||
.backup-source-dropdown {
|
||||
display: inline-block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
border: 0px;
|
||||
font-size: 15px;
|
||||
line-height: 18px;
|
||||
opacity: 1;
|
||||
/* padding-left: 10px; */
|
||||
cursor: pointer;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { backup } from "../../../utils/file/backup";
|
||||
import { restore } from "../../../utils/file/restore";
|
||||
import { Trans } from "react-i18next";
|
||||
import { BackupDialogProps, BackupDialogState } from "./interface";
|
||||
import TokenDialog from "../tokenDialog";
|
||||
import ConfigService from "../../../utils/storage/configService";
|
||||
import Lottie from "react-lottie";
|
||||
import animationSuccess from "../../../assets/lotties/success.json";
|
||||
@@ -59,67 +58,34 @@ class BackupDialog extends React.Component<
|
||||
showMessage = (message: string) => {
|
||||
toast(this.props.t(message));
|
||||
};
|
||||
handleBackup = (name: string) => {
|
||||
this.setState({ currentDrive: name }, async () => {
|
||||
if (name === "local") {
|
||||
let result = await backup(name);
|
||||
if (result) {
|
||||
this.handleFinish();
|
||||
} else {
|
||||
this.showMessage("Upload failed, check your connection");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (name === "onedrive" || name === "googledrive" || name === "dropbox") {
|
||||
if (!this.state.isDeveloperVer) {
|
||||
this.showMessage(
|
||||
"This feature is only available in the developer version"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!ConfigService.getReaderConfig(name + "_token") && name !== "local") {
|
||||
this.props.handleTokenDialog(true);
|
||||
return;
|
||||
}
|
||||
this.showMessage("Uploading, please wait");
|
||||
this.props.handleLoadingDialog(true);
|
||||
handleBackup = async () => {
|
||||
let name = this.state.currentDrive;
|
||||
if (name === "local") {
|
||||
let result = await backup(name);
|
||||
if (result) {
|
||||
this.handleFinish();
|
||||
} else {
|
||||
this.showMessage("Upload failed, check your connection");
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ConfigService.getReaderConfig(name + "_token") && name !== "local") {
|
||||
this.props.handleTokenDialog(true);
|
||||
return;
|
||||
}
|
||||
this.showMessage("Uploading, please wait");
|
||||
this.props.handleLoadingDialog(true);
|
||||
let result = await backup(name);
|
||||
if (result) {
|
||||
this.handleFinish();
|
||||
} else {
|
||||
this.showMessage("Upload failed, check your connection");
|
||||
}
|
||||
};
|
||||
handleRestore = (name: string) => {
|
||||
this.setState({ currentDrive: name }, async () => {
|
||||
if (name === "local") {
|
||||
let result = await restore(name);
|
||||
if (result) {
|
||||
this.handleFinish();
|
||||
} else {
|
||||
this.showMessage("Download failed,network problem or no backup");
|
||||
this.props.handleLoadingDialog(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (name === "onedrive" || name === "googledrive" || name === "dropbox") {
|
||||
if (!this.state.isDeveloperVer) {
|
||||
this.showMessage(
|
||||
"This feature is only available in the developer version"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ConfigService.getReaderConfig(name + "_token")) {
|
||||
this.props.handleTokenDialog(true);
|
||||
return;
|
||||
}
|
||||
this.props.handleLoadingDialog(true);
|
||||
this.showMessage("Downloading, please wait");
|
||||
|
||||
handleRestore = async () => {
|
||||
let name = this.state.currentDrive;
|
||||
if (name === "local") {
|
||||
let result = await restore(name);
|
||||
if (result) {
|
||||
this.handleFinish();
|
||||
@@ -127,123 +93,135 @@ class BackupDialog extends React.Component<
|
||||
this.showMessage("Download failed,network problem or no backup");
|
||||
this.props.handleLoadingDialog(false);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ConfigService.getReaderConfig(name + "_token")) {
|
||||
this.props.handleTokenDialog(true);
|
||||
return;
|
||||
}
|
||||
this.props.handleLoadingDialog(true);
|
||||
this.showMessage("Downloading, please wait");
|
||||
|
||||
let result = await restore(name);
|
||||
if (result) {
|
||||
this.handleFinish();
|
||||
} else {
|
||||
this.showMessage("Download failed,network problem or no backup");
|
||||
this.props.handleLoadingDialog(false);
|
||||
}
|
||||
};
|
||||
handleSelectSource = (event: any) => {
|
||||
if (
|
||||
(event.target.value === "ftp" ||
|
||||
event.target.value === "webdav" ||
|
||||
event.target.value === "sftp") &&
|
||||
!isElectron
|
||||
) {
|
||||
toast(
|
||||
this.props.t(
|
||||
"Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version."
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
event.target.value === "google" ||
|
||||
event.target.value === "s3compatible" ||
|
||||
event.target.value === "microsoft" ||
|
||||
event.target.value === "dropbox"
|
||||
) {
|
||||
toast(this.props.t("This feature is not available in the free version"));
|
||||
return;
|
||||
}
|
||||
if (event.target.value === "add") {
|
||||
toast(this.props.t("Please add data source in the setting"));
|
||||
return;
|
||||
}
|
||||
this.setState({ currentDrive: event.target.value });
|
||||
};
|
||||
render() {
|
||||
const renderDrivePage = () => {
|
||||
return driveList.map((item) => {
|
||||
return (
|
||||
<li
|
||||
key={item.value}
|
||||
className="backup-page-list-item"
|
||||
onClick={() => {
|
||||
//webdav is avavilible on desktop
|
||||
if (
|
||||
(item.value === "ftp" || item.value === "sftp") &&
|
||||
!isElectron
|
||||
) {
|
||||
toast(
|
||||
this.props.t(
|
||||
"Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version."
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (this.state.isBackup === "yes") {
|
||||
this.handleBackup(item.value);
|
||||
} else {
|
||||
this.handleRestore(item.value);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="backup-page-list-item-container">
|
||||
<span
|
||||
className={`icon-${item.value} backup-page-list-icon`}
|
||||
></span>
|
||||
{ConfigService.getReaderConfig(item.value + "_token") ? (
|
||||
<div
|
||||
className="backup-page-list-title"
|
||||
onClick={() => {
|
||||
ConfigService.setReaderConfig(item.value + "_token", "");
|
||||
this.showMessage("Unauthorize successful");
|
||||
}}
|
||||
style={{ color: "rgb(0, 120, 212)" }}
|
||||
>
|
||||
<Trans>Unauthorize</Trans>
|
||||
</div>
|
||||
) : (
|
||||
<div className="backup-page-list-title">
|
||||
<Trans>{item.label}</Trans>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
});
|
||||
};
|
||||
let syncUtil = new SyncUtil(this.state.currentDrive, {});
|
||||
|
||||
const dialogProps = {
|
||||
driveName: this.state.currentDrive,
|
||||
url: syncUtil.getAuthUrl(),
|
||||
title:
|
||||
driveList[
|
||||
_.findLastIndex(driveList, {
|
||||
value: this.state.currentDrive,
|
||||
})
|
||||
].label,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="backup-page-container">
|
||||
{this.props.isOpenTokenDialog ? <TokenDialog {...dialogProps} /> : null}
|
||||
|
||||
{this.state.currentStep === 0 ? (
|
||||
<div className="backup-page-option">
|
||||
<div
|
||||
className={
|
||||
this.state.isBackup === "yes"
|
||||
? "backup-page-backup active"
|
||||
: "backup-page-backup"
|
||||
}
|
||||
onClick={() => {
|
||||
this.setState({ isBackup: "yes" });
|
||||
}}
|
||||
>
|
||||
<span className="icon-backup"></span>
|
||||
<div style={{ lineHeight: 1.0 }}>
|
||||
<Trans>Backup</Trans>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={
|
||||
this.state.isBackup === "no"
|
||||
? "backup-page-backup active"
|
||||
: "backup-page-backup"
|
||||
}
|
||||
onClick={(event) => {
|
||||
if (!isElectron) {
|
||||
event.preventDefault();
|
||||
toast(
|
||||
this.props.t(
|
||||
"Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version."
|
||||
<div className="backup-page-backup">
|
||||
<span
|
||||
className="icon-backup"
|
||||
onClick={() => {
|
||||
this.setState({ currentStep: 1, isBackup: "yes" });
|
||||
this.handleBackup();
|
||||
}}
|
||||
></span>
|
||||
<div style={{ lineHeight: 1.0, fontSize: 15 }}>
|
||||
<Trans>Backup to</Trans>
|
||||
<select
|
||||
name=""
|
||||
className="backup-source-dropdown"
|
||||
onChange={this.handleSelectSource}
|
||||
>
|
||||
{[...driveList, { label: "Add data source", value: "add" }]
|
||||
.filter(
|
||||
(item) =>
|
||||
this.props.dataSourceList.includes(item.value) ||
|
||||
item.value === "local" ||
|
||||
item.value === "add"
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.setState({ isBackup: "no" });
|
||||
}}
|
||||
>
|
||||
<span className="icon-restore"></span>
|
||||
<div style={{ lineHeight: 1.0 }}>
|
||||
<Trans>Restore</Trans>
|
||||
.map((item) => (
|
||||
<option
|
||||
value={item.value}
|
||||
key={item.value}
|
||||
className="lang-setting-option"
|
||||
>
|
||||
{this.props.t(item.label)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="backup-page-backup">
|
||||
<span
|
||||
className="icon-restore"
|
||||
onClick={(event) => {
|
||||
if (!isElectron) {
|
||||
event.preventDefault();
|
||||
toast(
|
||||
this.props.t(
|
||||
"Koodo Reader's web version are limited by the browser, for more powerful features, please download the desktop version."
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.setState({ currentStep: 1, isBackup: "no" });
|
||||
this.handleRestore();
|
||||
}}
|
||||
></span>
|
||||
<div style={{ lineHeight: 1.0, fontSize: 15 }}>
|
||||
<Trans>Restore from</Trans>
|
||||
<select
|
||||
name=""
|
||||
className="backup-source-dropdown"
|
||||
onChange={this.handleSelectSource}
|
||||
>
|
||||
{[...driveList, { label: "Add data source", value: "add" }]
|
||||
.filter(
|
||||
(item) =>
|
||||
this.props.dataSourceList.includes(item.value) ||
|
||||
item.value === "local" ||
|
||||
item.value === "add"
|
||||
)
|
||||
.map((item) => (
|
||||
<option
|
||||
value={item.value}
|
||||
key={item.value}
|
||||
className="lang-setting-option"
|
||||
>
|
||||
{this.props.t(item.label)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : this.state.currentStep === 1 ? (
|
||||
<div className="backup-page-drive-container">
|
||||
<div>{renderDrivePage()}</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="backup-page-finish-container">
|
||||
@@ -256,11 +234,6 @@ class BackupDialog extends React.Component<
|
||||
: "Restore successful"}
|
||||
</Trans>
|
||||
</div>
|
||||
{this.state.isBackup ? null : (
|
||||
<div style={{ opacity: 0.6 }}>
|
||||
<Trans>Try refresh or restart</Trans>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -17,6 +17,7 @@ const mapStateToProps = (state: stateType) => {
|
||||
notes: state.reader.notes,
|
||||
digests: state.reader.digests,
|
||||
isOpenTokenDialog: state.backupPage.isOpenTokenDialog,
|
||||
dataSourceList: state.backupPage.dataSourceList,
|
||||
};
|
||||
};
|
||||
const actionCreator = {
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface BackupDialogProps extends RouteComponentProps<any> {
|
||||
books: BookModel[];
|
||||
notes: NoteModel[];
|
||||
digests: NoteModel[];
|
||||
dataSourceList: string[];
|
||||
bookmarks: BookmarkModel[];
|
||||
}
|
||||
export interface BackupDialogState {
|
||||
|
||||
@@ -27,7 +27,8 @@ import {
|
||||
} from "../../../utils/common";
|
||||
import { getStorageLocation, reloadManager } from "../../../utils/common";
|
||||
import DatabaseService from "../../../utils/storage/databaseService";
|
||||
import { driveList } from "../../../constants/driveList";
|
||||
import { driveInputConfig, driveList } from "../../../constants/driveList";
|
||||
import { SyncUtil } from "../../../assets/lib/kookit-extra-browser.min";
|
||||
declare var window: any;
|
||||
class SettingDialog extends React.Component<
|
||||
SettingInfoProps,
|
||||
@@ -72,18 +73,16 @@ class SettingDialog extends React.Component<
|
||||
}),
|
||||
storageLocation: getStorageLocation() || "",
|
||||
isAddNew: false,
|
||||
currentDrive: "",
|
||||
driveConfig: {},
|
||||
};
|
||||
}
|
||||
componentDidMount(): void {
|
||||
this.props.handleFetchPlugins();
|
||||
this.loadFont();
|
||||
let dataSourceList = ConfigService.getReaderConfig("dataSourceList") || [
|
||||
"local",
|
||||
];
|
||||
if (dataSourceList) {
|
||||
dataSourceList = JSON.parse(dataSourceList);
|
||||
this.props.setDataSource(dataSourceList);
|
||||
}
|
||||
let dataSourceList = ConfigService.getAllListConfig("dataSourceList");
|
||||
|
||||
this.props.setDataSource(dataSourceList);
|
||||
}
|
||||
loadFont = () => {
|
||||
if (dropdownList[0].option.length <= 2) {
|
||||
@@ -207,6 +206,36 @@ class SettingDialog extends React.Component<
|
||||
}
|
||||
this.handleSetting("isOpenInMain");
|
||||
};
|
||||
handleCancel = () => {
|
||||
this.setState({ currentDrive: "" });
|
||||
};
|
||||
handleConfirm = async () => {
|
||||
if (
|
||||
this.state.currentDrive === "webdav" ||
|
||||
this.state.currentDrive === "ftp" ||
|
||||
this.state.currentDrive === "sftp" ||
|
||||
this.state.currentDrive === "s3compatible"
|
||||
) {
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.state.currentDrive}_token`,
|
||||
JSON.stringify(this.state.driveConfig)
|
||||
);
|
||||
} else {
|
||||
let syncUtil = new SyncUtil(this.state.currentDrive, {});
|
||||
let refreshToken = await syncUtil.authToken(this.state.driveConfig.token);
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.state.currentDrive}_token`,
|
||||
JSON.stringify({ refresh_token: refreshToken })
|
||||
);
|
||||
}
|
||||
ConfigService.setListConfig(this.state.currentDrive, "dataSourceList");
|
||||
this.props.setDataSource(
|
||||
ConfigService.getAllListConfig("dataSourceList") || []
|
||||
);
|
||||
|
||||
this.setState({ currentDrive: "" });
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<div className="setting-dialog-container">
|
||||
@@ -280,7 +309,7 @@ class SettingDialog extends React.Component<
|
||||
this.handleChangeTab("sync");
|
||||
}}
|
||||
>
|
||||
<Trans>Sync and Backup</Trans>
|
||||
<Trans>Sync and backup</Trans>
|
||||
</span>
|
||||
<span
|
||||
className="book-bookmark-title"
|
||||
@@ -653,6 +682,96 @@ class SettingDialog extends React.Component<
|
||||
</>
|
||||
) : this.state.currentTab === "sync" ? (
|
||||
<>
|
||||
{this.state.currentDrive && (
|
||||
<div
|
||||
className="voice-add-new-container"
|
||||
style={{
|
||||
marginLeft: "25px",
|
||||
width: "calc(100% - 50px)",
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{this.state.currentDrive === "webdav" ||
|
||||
this.state.currentDrive === "ftp" ||
|
||||
this.state.currentDrive === "sftp" ||
|
||||
this.state.currentDrive === "s3compatible" ? (
|
||||
<>
|
||||
{driveInputConfig[this.state.currentDrive].map((item) => {
|
||||
return (
|
||||
<input
|
||||
type={item.type}
|
||||
name={item.value}
|
||||
key={item.value}
|
||||
placeholder={this.props.t(item.label)}
|
||||
onChange={(e) => {
|
||||
this.setState((prevState) => ({
|
||||
driveConfig: {
|
||||
...prevState.driveConfig,
|
||||
[item.value]: e.target.value,
|
||||
},
|
||||
}));
|
||||
}}
|
||||
id={"token-dialog-" + item.value + "-box"}
|
||||
className="token-dialog-username-box"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<textarea
|
||||
className="token-dialog-token-box"
|
||||
id="token-dialog-token-box"
|
||||
placeholder={this.props.t(
|
||||
"Please authorize your account, and fill the following box with the token"
|
||||
)}
|
||||
onChange={(e) => {
|
||||
this.setState((prevState) => ({
|
||||
driveConfig: {
|
||||
...prevState.driveConfig,
|
||||
token: e.target.value,
|
||||
},
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className="token-dialog-button-container">
|
||||
<div
|
||||
className="voice-add-confirm"
|
||||
onClick={async () => {
|
||||
this.handleConfirm();
|
||||
}}
|
||||
>
|
||||
<Trans>Confirm</Trans>
|
||||
</div>
|
||||
<div className="voice-add-button-container">
|
||||
<div
|
||||
className="voice-add-cancel"
|
||||
onClick={() => {
|
||||
this.handleCancel();
|
||||
}}
|
||||
>
|
||||
<Trans>Cancel</Trans>
|
||||
</div>
|
||||
<div
|
||||
className="voice-add-cancel"
|
||||
style={{ marginRight: "10px" }}
|
||||
onClick={() => {
|
||||
this.handleJump(
|
||||
new SyncUtil(
|
||||
this.state.currentDrive,
|
||||
{}
|
||||
).getAuthUrl()
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Trans>Authorize</Trans>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="setting-dialog-new-title">
|
||||
<Trans>Add data source</Trans>
|
||||
<select
|
||||
@@ -661,6 +780,7 @@ class SettingDialog extends React.Component<
|
||||
onChange={(event) => {
|
||||
if (
|
||||
(event.target.value === "ftp" ||
|
||||
event.target.value === "webdav" ||
|
||||
event.target.value === "sftp") &&
|
||||
!isElectron
|
||||
) {
|
||||
@@ -671,12 +791,27 @@ class SettingDialog extends React.Component<
|
||||
);
|
||||
return;
|
||||
}
|
||||
let dataSourceList = this.props.dataSourceList;
|
||||
if (
|
||||
event.target.value === "google" ||
|
||||
event.target.value === "s3compatible" ||
|
||||
event.target.value === "microsoft" ||
|
||||
event.target.value === "dropbox"
|
||||
) {
|
||||
toast(
|
||||
this.props.t(
|
||||
"This feature is not available in the free version"
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.setState({ currentDrive: event.target.value });
|
||||
}}
|
||||
>
|
||||
{driveList
|
||||
{[{ label: "Please select", value: "" }, ...driveList]
|
||||
.filter(
|
||||
(item) => !this.props.dataSourceList.includes(item.value)
|
||||
(item) =>
|
||||
!this.props.dataSourceList.includes(item.value) &&
|
||||
item.value !== "local"
|
||||
)
|
||||
.map((item) => (
|
||||
<option
|
||||
@@ -684,7 +819,59 @@ class SettingDialog extends React.Component<
|
||||
key={item.value}
|
||||
className="lang-setting-option"
|
||||
>
|
||||
{item.label}
|
||||
{this.props.t(item.label)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="setting-dialog-new-title">
|
||||
<Trans>Delete data source</Trans>
|
||||
<select
|
||||
name=""
|
||||
className="lang-setting-dropdown"
|
||||
onChange={(event) => {
|
||||
this.setState({ currentDrive: event.target.value });
|
||||
}}
|
||||
>
|
||||
{[{ label: "Please select", value: "" }, ...driveList]
|
||||
.filter(
|
||||
(item) =>
|
||||
this.props.dataSourceList.includes(item.value) ||
|
||||
item.value === ""
|
||||
)
|
||||
.map((item) => (
|
||||
<option
|
||||
value={item.value}
|
||||
key={item.value}
|
||||
className="lang-setting-option"
|
||||
>
|
||||
{this.props.t(item.label)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="setting-dialog-new-title">
|
||||
<Trans>Set default sync option</Trans>
|
||||
<select
|
||||
name=""
|
||||
className="lang-setting-dropdown"
|
||||
onChange={(event) => {
|
||||
this.setState({ currentDrive: event.target.value });
|
||||
}}
|
||||
>
|
||||
{[{ label: "Please select", value: "" }, ...driveList]
|
||||
.filter(
|
||||
(item) =>
|
||||
this.props.dataSourceList.includes(item.value) ||
|
||||
item.value === ""
|
||||
)
|
||||
.map((item) => (
|
||||
<option
|
||||
value={item.value}
|
||||
key={item.value}
|
||||
className="lang-setting-option"
|
||||
>
|
||||
{this.props.t(item.label)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -693,24 +880,23 @@ class SettingDialog extends React.Component<
|
||||
) : (
|
||||
<>
|
||||
{(this.props.plugins.length === 0 || this.state.isAddNew) && (
|
||||
<div className="navigation-panel-empty-bookmark">
|
||||
<div
|
||||
className="voice-add-new-container"
|
||||
style={{
|
||||
marginLeft: "10px",
|
||||
width: "88%",
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
<textarea
|
||||
name="url"
|
||||
placeholder={this.props.t(
|
||||
"Paste the code of the plugin here, check out document to learn how to get more plugins"
|
||||
)}
|
||||
id="voice-add-content-box"
|
||||
className="voice-add-content-box"
|
||||
/>
|
||||
|
||||
<div
|
||||
className="voice-add-new-container"
|
||||
style={{
|
||||
marginLeft: "25px",
|
||||
width: "calc(100% - 50px)",
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
<textarea
|
||||
name="url"
|
||||
placeholder={this.props.t(
|
||||
"Paste the code of the plugin here, check out document to learn how to get more plugins"
|
||||
)}
|
||||
id="voice-add-content-box"
|
||||
className="voice-add-content-box"
|
||||
/>
|
||||
<div className="token-dialog-button-container">
|
||||
<div
|
||||
className="voice-add-confirm"
|
||||
onClick={async () => {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
handleFetchBooks,
|
||||
handleFetchPlugins,
|
||||
setDataSource,
|
||||
handleTokenDialog,
|
||||
} from "../../../store/actions";
|
||||
import { stateType } from "../../../store";
|
||||
|
||||
@@ -18,6 +19,7 @@ const mapStateToProps = (state: stateType) => {
|
||||
plugins: state.manager.plugins,
|
||||
notes: state.reader.notes,
|
||||
dataSourceList: state.backupPage.dataSourceList,
|
||||
isOpenTokenDialog: state.backupPage.isOpenTokenDialog,
|
||||
};
|
||||
};
|
||||
const actionCreator = {
|
||||
@@ -27,6 +29,7 @@ const actionCreator = {
|
||||
handleFetchBooks,
|
||||
handleFetchPlugins,
|
||||
setDataSource,
|
||||
handleTokenDialog,
|
||||
};
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
|
||||
@@ -5,6 +5,7 @@ import PluginModel from "../../../models/Plugin";
|
||||
export interface SettingInfoProps {
|
||||
handleSetting: (isSettingOpen: boolean) => void;
|
||||
handleTipDialog: (isTipDialog: boolean) => void;
|
||||
handleTokenDialog: (isOpenTokenDialog: boolean) => void;
|
||||
handleTip: (tip: string) => void;
|
||||
setDataSource: (dataSourceList: string[]) => void;
|
||||
t: (title: string) => string;
|
||||
@@ -12,6 +13,7 @@ export interface SettingInfoProps {
|
||||
handleFetchPlugins: () => void;
|
||||
bookmarks: BookmarkModel[];
|
||||
notes: NoteModel[];
|
||||
isOpenTokenDialog: boolean;
|
||||
plugins: PluginModel[];
|
||||
books: BookModel[];
|
||||
dataSourceList: string[];
|
||||
@@ -42,4 +44,6 @@ export interface SettingInfoState {
|
||||
isAddNew: boolean;
|
||||
currentThemeIndex: number;
|
||||
currentTab: string;
|
||||
currentDrive: string;
|
||||
driveConfig: any;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
line-height: 20px;
|
||||
opacity: 1;
|
||||
margin-top: 10px;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
margin-left: 25px;
|
||||
width: calc(100% - 50px);
|
||||
margin-bottom: 5px;
|
||||
/* width: 280px; */
|
||||
display: flex;
|
||||
@@ -183,3 +183,33 @@
|
||||
right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.token-dialog-button-container {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.token-dialog-token-box {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
opacity: 1;
|
||||
font-size: 13px;
|
||||
line-height: 14px;
|
||||
opacity: 1;
|
||||
box-sizing: border-box;
|
||||
/* left: 30px; */
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
margin-top: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.token-dialog-username-box {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
opacity: 1;
|
||||
font-size: 13px;
|
||||
line-height: 14px;
|
||||
opacity: 1;
|
||||
margin-top: 9px;
|
||||
padding-left: 5px;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
import React, { Component } from "react";
|
||||
import "./tokenDialog.css";
|
||||
import { Trans } from "react-i18next";
|
||||
import { TokenDialogProps, TokenDialogState } from "./interface";
|
||||
import ConfigService from "../../../utils/storage/configService";
|
||||
import { SyncUtil } from "../../../assets/lib/kookit-extra-browser.min";
|
||||
import toast from "react-hot-toast";
|
||||
import { openExternalUrl } from "../../../utils/common";
|
||||
import { driveInputConfig, driveList } from "../../../constants/driveList";
|
||||
class TokenDialog extends Component<TokenDialogProps, TokenDialogState> {
|
||||
constructor(props: TokenDialogProps) {
|
||||
super(props);
|
||||
this.state = { isNew: false, config: {} };
|
||||
}
|
||||
|
||||
handleCancel = () => {
|
||||
this.props.handleTokenDialog(false);
|
||||
};
|
||||
handleDropboxComfirm = async () => {
|
||||
let code: string = (
|
||||
document.querySelector("#token-dialog-token-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let syncUtil = new SyncUtil("dropbox", {});
|
||||
let refreshToken = await syncUtil.authToken(code);
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ refresh_token: refreshToken })
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleOneDriveComfirm = async () => {
|
||||
let code: string = (
|
||||
document.querySelector("#token-dialog-token-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let syncUtil = new SyncUtil("onedrive", {});
|
||||
let refreshToken = await syncUtil.authToken(code);
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ refresh_token: refreshToken })
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleGoogleDriveComfirm = async () => {
|
||||
let code: string = (
|
||||
document.querySelector("#token-dialog-token-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let syncUtil = new SyncUtil("googledrive", {});
|
||||
let refreshToken = await syncUtil.authToken(code);
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ refresh_token: refreshToken })
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleDavComfirm = () => {
|
||||
let url: string = (
|
||||
document.querySelector("#token-dialog-url-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let username: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-username-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
let password: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-password-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ url, username, password })
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleFTPComfirm = () => {
|
||||
let url: string = (
|
||||
document.querySelector("#token-dialog-url-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let username: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-username-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
let password: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-password-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
let dir: string = (
|
||||
document.querySelector("#token-dialog-path-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let ssl: string = (
|
||||
document.querySelector("#token-dialog-ssl-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ url, username, password, dir, ssl })
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleS3Comfirm = () => {
|
||||
let endpoint: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-endpoint-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
let region: string = (
|
||||
document.querySelector("#token-dialog-region-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let bucketName: string = (
|
||||
document.querySelector("#token-dialog-bucket-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let accessKeyId: string = (
|
||||
document.querySelector("#token-dialog-id-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let secretAccessKey: string = (
|
||||
document.querySelector("#token-dialog-key-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({
|
||||
endpoint,
|
||||
region,
|
||||
bucketName,
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
})
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleSFTPComfirm = () => {
|
||||
let url: string = (
|
||||
document.querySelector("#token-dialog-url-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let username: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-username-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
let password: string = (
|
||||
document.querySelector(
|
||||
"#token-dialog-password-box"
|
||||
) as HTMLTextAreaElement
|
||||
).value;
|
||||
let dir: string = (
|
||||
document.querySelector("#token-dialog-path-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
let port: string = (
|
||||
document.querySelector("#token-dialog-port-box") as HTMLTextAreaElement
|
||||
).value;
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ url, username, password, dir, port })
|
||||
);
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
handleJump = (url: string) => {
|
||||
openExternalUrl(url);
|
||||
};
|
||||
handleConfirm = async () => {
|
||||
if (
|
||||
this.props.driveName === "webdav" ||
|
||||
this.props.driveName === "ftp" ||
|
||||
this.props.driveName === "sftp" ||
|
||||
this.props.driveName === "s3compatible"
|
||||
) {
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify(this.state.config)
|
||||
);
|
||||
} else {
|
||||
let syncUtil = new SyncUtil(this.props.driveName, {});
|
||||
let refreshToken = await syncUtil.authToken(this.state.config.token);
|
||||
ConfigService.setReaderConfig(
|
||||
`${this.props.driveName}_token`,
|
||||
JSON.stringify({ refresh_token: refreshToken })
|
||||
);
|
||||
}
|
||||
|
||||
this.props.handleTokenDialog(false);
|
||||
toast.success(this.props.t("Addition successful"));
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<div className="token-dialog-container">
|
||||
<div className="token-dialog-box">
|
||||
<div className="token-dialog-title">
|
||||
<Trans>Authorize</Trans>
|
||||
|
||||
{this.props.title}
|
||||
<Trans>Token</Trans>
|
||||
</div>
|
||||
{this.props.driveName === "webdav" ||
|
||||
this.props.driveName === "ftp" ||
|
||||
this.props.driveName === "sftp" ||
|
||||
this.props.driveName === "s3compatible" ? (
|
||||
<>
|
||||
<div
|
||||
className="token-dialog-info-text"
|
||||
style={
|
||||
ConfigService.getReaderConfig("lang") === "en"
|
||||
? { fontSize: "14px" }
|
||||
: {}
|
||||
}
|
||||
>
|
||||
<Trans>
|
||||
{
|
||||
driveList.find(
|
||||
(item) => item.value === this.props.driveName
|
||||
)!.label
|
||||
}{" "}
|
||||
Info
|
||||
</Trans>
|
||||
</div>
|
||||
{driveInputConfig[this.props.driveName].map((item) => {
|
||||
return (
|
||||
<input
|
||||
type={item.type}
|
||||
name={item.value}
|
||||
placeholder={
|
||||
this.props.t(item.label) + ", " + item.placeholder
|
||||
}
|
||||
onChange={(e) => {
|
||||
this.setState((prevState) => ({
|
||||
config: {
|
||||
...prevState.config,
|
||||
[item.value]: e.target.value,
|
||||
},
|
||||
}));
|
||||
}}
|
||||
id={"token-dialog-" + item.value + "-box"}
|
||||
className="token-dialog-username-box"
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div
|
||||
className="token-dialog-info-text"
|
||||
style={
|
||||
ConfigService.getReaderConfig("lang") === "en"
|
||||
? { fontSize: "14px" }
|
||||
: {}
|
||||
}
|
||||
>
|
||||
<Trans>
|
||||
Please authorize your account, and fill the following box with
|
||||
the token
|
||||
</Trans>
|
||||
</div>
|
||||
<div
|
||||
className="token-dialog-link-text"
|
||||
onClick={() => {
|
||||
this.handleJump(this.props.url);
|
||||
}}
|
||||
>
|
||||
<Trans>Authorize</Trans>
|
||||
</div>
|
||||
<textarea
|
||||
className="token-dialog-token-box"
|
||||
id="token-dialog-token-box"
|
||||
placeholder={this.props.t("Token")}
|
||||
onChange={(e) => {
|
||||
this.setState((prevState) => ({
|
||||
config: {
|
||||
...prevState.config,
|
||||
token: e.target.value,
|
||||
},
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="add-dialog-button-container">
|
||||
<div
|
||||
className="add-dialog-cancel"
|
||||
onClick={() => {
|
||||
this.handleCancel();
|
||||
}}
|
||||
>
|
||||
<Trans>Cancel</Trans>
|
||||
</div>
|
||||
<div
|
||||
className="add-dialog-confirm"
|
||||
onClick={() => {
|
||||
this.handleConfirm();
|
||||
}}
|
||||
>
|
||||
<Trans>Confirm</Trans>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TokenDialog;
|
||||
@@ -1,22 +0,0 @@
|
||||
import { connect } from "react-redux";
|
||||
import { handleTokenDialog } from "../../../store/actions";
|
||||
import { stateType } from "../../../store";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import TokenDialog from "./component";
|
||||
const mapStateToProps = (state: stateType) => {
|
||||
return {
|
||||
books: state.manager.books,
|
||||
isOpenDeleteDialog: state.book.isOpenDeleteDialog,
|
||||
currentBook: state.book.currentBook,
|
||||
bookmarks: state.reader.bookmarks,
|
||||
notes: state.reader.notes,
|
||||
digests: state.reader.digests,
|
||||
};
|
||||
};
|
||||
const actionCreator = {
|
||||
handleTokenDialog,
|
||||
};
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
actionCreator
|
||||
)(withTranslation()(TokenDialog as any) as any);
|
||||
@@ -1,13 +0,0 @@
|
||||
import BookModel from "../../../models/Book";
|
||||
export interface TokenDialogProps {
|
||||
handleTokenDialog: (isShow: boolean) => void;
|
||||
currentBook: BookModel;
|
||||
driveName: string;
|
||||
title: string;
|
||||
url: string;
|
||||
t: (title: string) => string;
|
||||
}
|
||||
export interface TokenDialogState {
|
||||
isNew: boolean;
|
||||
config: any;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
.token-dialog-container {
|
||||
width: 454px;
|
||||
height: 278px;
|
||||
position: absolute;
|
||||
left: calc(50% - 227px);
|
||||
top: calc(50% - 139px);
|
||||
overflow: hidden;
|
||||
opacity: 1;
|
||||
z-index: 20;
|
||||
animation: popup 0.1s ease-in-out 0s 1;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.token-dialog-title {
|
||||
width: 120px;
|
||||
height: 20px;
|
||||
font-size: 18px;
|
||||
opacity: 1;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.token-dialog-info-text {
|
||||
width: 90%;
|
||||
height: 46px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 20px;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
overflow-y: scroll;
|
||||
margin-top: 10px;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.token-dialog-link-text {
|
||||
width: 94px;
|
||||
height: 29px;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
left: 181px;
|
||||
top: 100px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
line-height: 29px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.token-dialog-token-box {
|
||||
width: calc(100% - 50px);
|
||||
margin-left: 25px;
|
||||
height: 70px;
|
||||
opacity: 1;
|
||||
font-size: 13px;
|
||||
line-height: 14px;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
top: 144px;
|
||||
box-sizing: border-box;
|
||||
/* left: 30px; */
|
||||
border-radius: 5px;
|
||||
}
|
||||
.token-dialog-url-box,
|
||||
.token-dialog-username-box,
|
||||
.token-dialog-ssl-box,
|
||||
.token-dialog-path-box,
|
||||
.token-dialog-password-box {
|
||||
width: 322px;
|
||||
height: 23px;
|
||||
opacity: 1;
|
||||
font-size: 13px;
|
||||
line-height: 14px;
|
||||
opacity: 1;
|
||||
margin-left: 60px;
|
||||
margin-top: 9px;
|
||||
padding-left: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.token-dialog-cancel {
|
||||
width: 60px;
|
||||
height: 26px;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
left: 157px;
|
||||
top: 236px;
|
||||
font-size: 13px;
|
||||
line-height: 26px;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.token-dialog-confirm {
|
||||
width: 64px;
|
||||
height: 30px;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
left: 237px;
|
||||
top: 236px;
|
||||
font-size: 13px;
|
||||
line-height: 30px;
|
||||
opacity: 1;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
border-radius: 5px;
|
||||
}
|
||||
@@ -16,52 +16,57 @@ export const driveList = [
|
||||
label: "SFTP",
|
||||
value: "sftp",
|
||||
},
|
||||
|
||||
{
|
||||
label: "S3 Compatible",
|
||||
label: "S3 Compatible (Pro)",
|
||||
value: "s3compatible",
|
||||
},
|
||||
{
|
||||
label: "Dropbox",
|
||||
label: "Dropbox (Pro)",
|
||||
value: "dropbox",
|
||||
isPro: true,
|
||||
},
|
||||
{
|
||||
label: "OneDrive",
|
||||
label: "OneDrive (Pro)",
|
||||
value: "microsoft",
|
||||
isPro: true,
|
||||
},
|
||||
{
|
||||
label: "Google Drive",
|
||||
label: "Google Drive (Pro)",
|
||||
value: "google",
|
||||
isPro: true,
|
||||
},
|
||||
];
|
||||
export const driveInputConfig = {
|
||||
interface ConfigItem {
|
||||
label: string;
|
||||
value: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
// Type the driveInputConfig
|
||||
interface DriveInputConfig {
|
||||
[key: string]: ConfigItem[];
|
||||
}
|
||||
export const driveInputConfig: DriveInputConfig = {
|
||||
webdav: [
|
||||
{
|
||||
label: "Server address",
|
||||
value: "url",
|
||||
type: "text",
|
||||
placeholder: "https://example.com",
|
||||
},
|
||||
{
|
||||
label: "Path",
|
||||
label: "Server path",
|
||||
value: "path",
|
||||
type: "text",
|
||||
placeholder: "/path/to/folder",
|
||||
},
|
||||
{
|
||||
label: "Username",
|
||||
value: "username",
|
||||
type: "text",
|
||||
placeholder: "username",
|
||||
},
|
||||
{
|
||||
label: "Password",
|
||||
value: "password",
|
||||
type: "password",
|
||||
placeholder: "password",
|
||||
},
|
||||
],
|
||||
ftp: [
|
||||
@@ -69,31 +74,26 @@ export const driveInputConfig = {
|
||||
label: "Server address",
|
||||
value: "url",
|
||||
type: "text",
|
||||
placeholder: "ftp://example.com",
|
||||
},
|
||||
{
|
||||
label: "Server port",
|
||||
value: "port",
|
||||
type: "text",
|
||||
placeholder: "21",
|
||||
},
|
||||
{
|
||||
label: "Server Path",
|
||||
label: "Server path",
|
||||
value: "path",
|
||||
type: "text",
|
||||
placeholder: "/path/to/folder",
|
||||
},
|
||||
{
|
||||
label: "Username",
|
||||
value: "username",
|
||||
type: "text",
|
||||
placeholder: "username",
|
||||
},
|
||||
{
|
||||
label: "Password",
|
||||
value: "password",
|
||||
type: "password",
|
||||
placeholder: "password",
|
||||
},
|
||||
],
|
||||
sftp: [
|
||||
@@ -101,31 +101,26 @@ export const driveInputConfig = {
|
||||
label: "Server address",
|
||||
value: "url",
|
||||
type: "text",
|
||||
placeholder: "sftp://example.com",
|
||||
},
|
||||
{
|
||||
label: "Server port",
|
||||
value: "port",
|
||||
type: "text",
|
||||
placeholder: "22",
|
||||
},
|
||||
{
|
||||
label: "Server Path",
|
||||
value: "path",
|
||||
type: "text",
|
||||
placeholder: "/path/to/folder",
|
||||
},
|
||||
{
|
||||
label: "Username",
|
||||
value: "username",
|
||||
type: "text",
|
||||
placeholder: "username",
|
||||
},
|
||||
{
|
||||
label: "Password",
|
||||
value: "password",
|
||||
type: "password",
|
||||
placeholder: "password",
|
||||
},
|
||||
],
|
||||
s3compatible: [
|
||||
@@ -144,6 +139,11 @@ export const driveInputConfig = {
|
||||
value: "bucketName",
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
label: "Server Path",
|
||||
value: "path",
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
label: "AccessKeyId",
|
||||
value: "accessKeyId",
|
||||
|
||||
Reference in New Issue
Block a user