Former-commit-id: 1c84dfabb826073dd4223cdf075826f8c2271690
This commit is contained in:
troyeguo
2020-09-26 00:29:56 +08:00
parent f282eb9725
commit 6008bfb1c8
65 changed files with 476 additions and 180 deletions

View File

@@ -58,6 +58,8 @@ app.on("ready", () => {
.getFonts()
.then((fonts) => {
event.returnValue = fonts;
const server = require("./server");
})
.catch((err) => {
console.log(err);

View File

@@ -12,13 +12,19 @@
"dependencies": {
"@types/lodash": "^4.14.161",
"axios": "^0.19.2",
"body-parser": "^1.19.0",
"copy-text-to-clipboard": "^2.2.0",
"cors": "^2.8.5",
"electron-is-dev": "^1.1.0",
"express": "^4.17.1",
"express-fileupload": "^1.2.0",
"font-list": "^1.2.11",
"i18next": "^19.4.4",
"i18next-browser-languagedetector": "^4.2.0",
"is-electron": "^2.2.0",
"md5": "^2.3.0",
"onedrive-api": "^0.5.0",
"qs": "^6.9.4",
"react-device-detect": "^1.12.1",
"react-dropzone": "^11.0.1",
"react-i18next": "^9.0.10"

199
server.js Normal file
View File

@@ -0,0 +1,199 @@
const express = require("express");
const cors = require("cors");
const axios = require("axios");
const bodyParser = require("body-parser");
const qs = require("qs");
const fileUpload = require("express-fileupload");
const oneDriveAPI = require("onedrive-api");
const path = require("path");
const fs = require("fs");
var dirPath = "uploads";
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
console.log("文件夹创建成功");
} else {
console.log("文件夹已存在");
}
const server = express();
server.use(
fileUpload({
createParentPath: true,
})
);
server.use(cors());
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true }));
server.get("/onedrive_refresh", (req, res) => {
const { refresh_token, redirect_uri } = req.query;
const requestBody = {
client_id: "ac96f9bf-94f2-49c0-8418-999b919bc236",
refresh_token,
grant_type: "refresh_token",
client_secret: "-Fb8Lees-b~4EzgB2O48H4r-bOo.yLwpcF",
redirect_uri,
};
axios
.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
qs.stringify(requestBody),
{
headers: {
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
},
}
)
.then((result) => {
res.send(result.data);
})
.catch((err) => {
console.log(err);
res.status(404).send("Something Wrong!");
});
});
server.get("/onedrive_get", (req, res) => {
const { code, redirect_uri } = req.query;
console.log("test2");
const requestBody = {
client_id: "ac96f9bf-94f2-49c0-8418-999b919bc236",
code,
grant_type: "authorization_code",
client_secret: "-Fb8Lees-b~4EzgB2O48H4r-bOo.yLwpcF",
redirect_uri,
};
axios
.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
qs.stringify(requestBody),
{
headers: {
"content-type": "application/x-www-form-urlencoded;charset=utf-8",
},
}
)
.then((result) => {
res.send(result.data);
})
.catch((err) => {
res.status(404).send("Something Wrong!");
});
});
server.post("/onedrive_download", (req, res) => {
var fileStream = oneDriveAPI.items.download({
accessToken: req.body.ACCESS_TOKEN,
itemId: req.body.backupId,
});
const writeStream = fs.createWriteStream("uploads/data.zip");
writeStream.on("close", () => {
console.log("close");
res.sendFile(path.resolve("./uploads/data.zip"));
res.on("finish", function () {
try {
fs.unlink(path.resolve("./uploads/data.zip"), (err) => {
if (err) throw err;
console.log("successfully deleted");
});
} catch (e) {
console.log("error removing ");
}
});
});
fileStream.pipe(writeStream);
});
server.post("/onedrive_upload", async (req, res) => {
try {
if (!req.files) {
res.send({
status: false,
message: "No file uploaded",
});
} else {
const makeid = (length) => {
var result = "";
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(
Math.floor(Math.random() * charactersLength)
);
}
return result;
};
let name = "data.zip";
fs.writeFile(path.resolve("./uploads/" + name), "Hey there!", function (
err
) {
if (err) {
return console.log(err);
}
let file = req.files.file;
file.mv("./uploads/" + name);
console.log(name, "test1");
oneDriveAPI.items
.uploadSession({
accessToken: req.body.ACCESS_TOKEN,
filename: name,
fileSize: file.size,
parentPath: "/Apps/Koodo Reader/",
readableStream: fs.createReadStream("./uploads/" + name),
})
.then((result) => {
res.send({
status: true,
message: "File is uploaded",
data: {
name: file.name,
mimetype: file.mimetype,
size: file.size,
id: result.id,
},
});
res.on("finish", function () {
fs.unlink(path.resolve("./uploads/" + name), (err) => {
if (err) throw err;
console.log("successfully deleted");
});
});
})
.catch((err) => {
console.log("upload failed");
res.status(401).send(err);
});
});
}
} catch (err) {
console.log(err);
res.status(500).send(err);
}
});
async function start() {
try {
const port = 3366;
expressServer = await server.listen(port);
const address = expressServer.address();
serverInfo = {
port: address.port,
local: "localhost",
url: `http://localhost:${address.port}`,
};
return serverInfo;
// await reload(config, preload);
return serverInfo;
} catch (e) {
return { message: e.message };
}
}
async function startServer() {
const { port, local, message } = await start();
if (message) {
console.error(message);
} else {
console.info(`启动成功,本地访问 http://${local}:${port}`);
}
}
startServer();

View File

@@ -7,6 +7,9 @@
"My Favorites": "我的喜爱",
"My Digests": "我的书摘",
"My Shelves": "我的书架",
"Please continue in desktop version": "仅客户端版本支持",
"Book not exsit": "书籍不存在",
"Delete Shelf": "删除书架",
"Dont't use mimical background": "不使用仿真背景",
"Auto hide cursor when reading": "阅读时自动隐藏鼠标",
"Sort": "排序",

View File

@@ -39,6 +39,7 @@
"Medium": "Mid",
"Large": "Large",
"Cancel Successfully": "Cancel Successfully",
"Please continue in desktop version": "Please continue in desktop version",
"Don't use mimical background": "Don't use mimical background",
"Auto hide cursor when reading": "Auto hide cursor when reading",
"Extra Large": "Extra",
@@ -65,10 +66,12 @@
"Sort by Name": "by Name",
"Bind": "Bind",
"Token": "Token",
"Book not exsit": "Book not exsit",
"Token Info": "Please copy the following link and open in your browser to finish authorizing, once it's over, you'll get a bunch of codes, then fill the following box with the codes",
"Copy Link": "Copy Link",
"Copy Token": "Copy Token",
"Copied": "Copied",
"Delete Shelf": "Delete Shelf",
"Empty Shelf Title": "Empty Shelf Title",
"Copy Link Successfully": "Copy Link Successfully",
"Add Successfully": "Add Successfully",

View File

@@ -119,9 +119,6 @@
"Current Font Size": "目前大小",
"Current Chapter": "目前章節",
"Loading": "載入中",
"Cancel Successfully": "取消成功",
"Don't use realisc background": "不使用仿真背景",
"Auto hide cursor when reading": "阅读时自动隐藏鼠标",
"Pick Up Color": "選擇顏色",
"Highlight Successfully": "高亮成功",
"Take Notes": "筆記",
@@ -173,5 +170,11 @@
"Our Website": "歡迎造訪我們的網站",
"What's New": "新增功能",
"What's been fixed": "問題修復",
"语言 / Language": "語言 / Language"
"语言 / Language": "語言 / Language",
"Cancel Successfully": "取消成功",
"Don't use realisc background": "不使用仿真背景",
"Please continue in desktop version": "仅客户端版本支持",
"Auto hide cursor when reading": "阅读时自动隐藏鼠标",
"Book not exsit": "书籍不存在",
"Delete Shelf": "删除书架"
}

View File

@@ -123,7 +123,4 @@
font-weight: bold;
width: 106px;
height: 38px;
/* display: flex;
align-items: center;
justify-content: flex-start; */
}

View File

@@ -1,7 +1,7 @@
//卡片模式下的图书显示
import React from "react";
import RecentBooks from "../../utils/recordRecent";
import "./book.css";
import "./bookCardItem.css";
import { BookProps, BookState } from "./interface";
import AddFavorite from "../../utils/addFavorite";
import ActionDialog from "../../containers/actionDialog";
@@ -10,7 +10,7 @@ import localforage from "localforage";
declare var window: any;
class Book extends React.Component<BookProps, BookState> {
class BookCardItem extends React.Component<BookProps, BookState> {
epub: any;
constructor(props: BookProps) {
super(props);
@@ -24,12 +24,14 @@ class Book extends React.Component<BookProps, BookState> {
}
UNSAFE_componentWillMount() {
//判断此书是否为喜爱的图书
this.setState({
isFavorite:
AddFavorite.getAllFavorite().indexOf(this.props.book.key) > -1,
});
}
componentDidMount() {
//控制是否自动打开本书
if (
OtherUtil.getReaderConfig("isOpenBook") === "yes" &&
RecentBooks.getAllRecent()[0] === this.props.book.key &&
@@ -52,7 +54,7 @@ class Book extends React.Component<BookProps, BookState> {
if (x > document.body.clientWidth - 100) {
x = x - 80;
}
this.setState({ left: x - 210, top: e.clientY - 100 }, () => {
this.setState({ left: x - 210, top: e.clientY - 120 }, () => {
this.props.handleActionDialog(true);
this.props.handleReadingBook(this.props.book);
});
@@ -147,4 +149,4 @@ class Book extends React.Component<BookProps, BookState> {
);
}
}
export default Book;
export default BookCardItem;

View File

@@ -1,7 +1,7 @@
//控制列表模式下的图书显示
import React from "react";
import RecentBooks from "../../utils/recordRecent";
import "./bookItem.css";
import "./bookListItem.css";
import RecordLocation from "../../utils/recordLocation";
import { BookItemProps, BookItemState } from "./interface";
import { Trans } from "react-i18next";
@@ -9,7 +9,7 @@ import localforage from "localforage";
declare var window: any;
class Book extends React.Component<BookItemProps, BookItemState> {
class BookListItem extends React.Component<BookItemProps, BookItemState> {
epub: any;
constructor(props: BookItemProps) {
super(props);
@@ -101,4 +101,4 @@ class Book extends React.Component<BookItemProps, BookItemState> {
}
}
export default Book;
export default BookListItem;

View File

@@ -1,4 +1,4 @@
//我的书摘页面
//我的书摘,笔记的卡片
import React from "react";
import "./cardList.css";
import NoteModel from "../../model/Note";
@@ -8,7 +8,6 @@ import DeleteIcon from "../../components/deleteIcon";
import RecentBooks from "../../utils/recordRecent";
import RecordLocation from "../../utils/recordLocation";
import localforage from "localforage";
import BookModel from "../../model/Book";
declare var window: any;
@@ -34,7 +33,7 @@ class CardList extends React.Component<CardListProps, CardListStates> {
};
handleJump = (cfi: string, bookKey: string, percentage: number) => {
let { books } = this.props;
let book: BookModel;
let book: any;
//根据bookKey获取指定的book和epub
for (let i = 0; i < books.length; i++) {
if (books[i].key === bookKey) {
@@ -42,7 +41,12 @@ class CardList extends React.Component<CardListProps, CardListStates> {
break;
}
}
// if (!book) return;
if (!book) {
this.props.handleMessage("Book not exsit");
this.props.handleMessageBox(true);
return;
}
localforage.getItem(book!.key).then((result) => {
this.props.handleReadingBook(book);
this.props.handleReadingEpub(window.ePub(result, {}));

View File

@@ -8,6 +8,7 @@ import {
handleReadingBook,
handleReadingEpub,
} from "../../redux/actions/book";
import { handleMessageBox, handleMessage } from "../../redux/actions/manager";
const mapStateToProps = (state: stateType) => {
return {
@@ -23,6 +24,8 @@ const actionCreator = {
handleReadingState,
handleReadingBook,
handleReadingEpub,
handleMessageBox,
handleMessage,
};
export default connect(
mapStateToProps,

View File

@@ -13,6 +13,8 @@ export interface CardListProps {
handleReadingState: (isReading: boolean) => void;
handleReadingBook: (currentBook: BookModel) => void;
handleReadingEpub: (currentEpub: any) => void;
handleMessage: (message: string) => void;
handleMessageBox: (isShow: boolean) => void;
}
export interface CardListStates {
deleteKey: string;

View File

@@ -1,4 +1,4 @@
//左下角的图标外链
//高亮,下划线颜色选择
import React from "react";
import "./colorOption.css";
import { ColorProps, ColorStates } from "./interface";

View File

@@ -10,6 +10,7 @@ class ContentList extends React.Component<ContentListProps, ContentListState> {
}
componentWillMount() {
//获取目录
this.props.currentEpub.loaded.navigation
.then((chapters: any) => {
this.setState({ chapters: chapters.toc });

View File

@@ -86,7 +86,7 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
handleBook = (file: any, md5: string) => {
return new Promise((resolve, reject) => {
//md5重复不导入
let isRepeat= false;
let isRepeat = false;
if (this.props.books) {
this.props.books.forEach((item) => {
if (item.md5 === md5) {
@@ -160,7 +160,7 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
reject();
});
};
}
}
});
};
@@ -175,6 +175,7 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
}
for (let i = 0; i < acceptedFiles.length; i++) {
//异步解析文件
await this.doIncrementalTest(acceptedFiles[i]);
}
}}

View File

@@ -1,15 +1,12 @@
//单双页切换
//阅读模式切换
import React from "react";
import "./singleControl.css";
import "./modeControl.css";
import { Trans } from "react-i18next";
import { SingleControlProps, SingleControlState } from "./interface";
import { ModeControlProps, ModeControlState } from "./interface";
import OtherUtil from "../../utils/otherUtil";
class SingleControl extends React.Component<
SingleControlProps,
SingleControlState
> {
constructor(props: SingleControlProps) {
class ModeControl extends React.Component<ModeControlProps, ModeControlState> {
constructor(props: ModeControlProps) {
super(props);
this.state = {
readerMode: OtherUtil.getReaderConfig("readerMode") || "double",
@@ -34,7 +31,7 @@ class SingleControl extends React.Component<
>
<span className="icon-single-page single-page-icon"></span>
<div className="single-mode-text">
<Trans>Single-Page Mode</Trans>
<Trans>Mode-Page Mode</Trans>
</div>
</div>
<div
@@ -65,4 +62,4 @@ class SingleControl extends React.Component<
);
}
}
export default SingleControl;
export default ModeControl;

View File

@@ -2,7 +2,7 @@
import { connect } from "react-redux";
import { handleMessageBox, handleMessage } from "../../redux/actions/manager";
import { withNamespaces } from "react-i18next";
import SingleControl from "./component";
import ModeControl from "./component";
import { stateType } from "../../redux/store";
const mapStateToProps = (state: stateType) => {
@@ -12,4 +12,4 @@ const actionCreator = { handleMessageBox, handleMessage };
export default connect(
mapStateToProps,
actionCreator
)(withNamespaces()(SingleControl as any));
)(withNamespaces()(ModeControl as any));

View File

@@ -1,8 +1,8 @@
export interface SingleControlProps {
export interface ModeControlProps {
handleMessageBox: (isShow: boolean) => void;
handleMessage: (message: string) => void;
}
export interface SingleControlState {
export interface ModeControlState {
readerMode: string;
}

View File

@@ -1,11 +1,11 @@
//图书导航栏页面的书签页面
//图书导航栏页面的书签,笔记,书摘页面
import React from "react";
import "./bookNavList.css";
import "./navList.css";
import { Trans } from "react-i18next";
import { BookNavListProps, BookNavListState } from "./interface";
import { NavListProps, NavListState } from "./interface";
import DeleteIcon from "../deleteIcon";
class BookNavList extends React.Component<BookNavListProps, BookNavListState> {
constructor(props: BookNavListProps) {
class NavList extends React.Component<NavListProps, NavListState> {
constructor(props: NavListProps) {
super(props);
this.state = {
deleteIndex: -1,
@@ -92,4 +92,4 @@ class BookNavList extends React.Component<BookNavListProps, BookNavListState> {
}
}
export default BookNavList;
export default NavList;

View File

@@ -2,7 +2,7 @@
import { connect } from "react-redux";
import { stateType } from "../../redux/store";
import { withNamespaces } from "react-i18next";
import BookNavList from "./component";
import NavList from "./component";
import { handleMessageBox, handleMessage } from "../../redux/actions/manager";
const mapStateToProps = (state: stateType) => {
return {
@@ -17,4 +17,4 @@ const actionCreator = { handleMessageBox, handleMessage };
export default connect(
mapStateToProps,
actionCreator
)(withNamespaces()(BookNavList as any));
)(withNamespaces()(NavList as any));

View File

@@ -1,7 +1,7 @@
import BookmarkModel from "../../model/Bookmark";
import BookModel from "../../model/Book";
import NoteModel from "../../model/Note";
export interface BookNavListProps {
export interface NavListProps {
currentBook: BookModel;
currentEpub: any;
bookmarks: BookmarkModel[];
@@ -11,6 +11,6 @@ export interface BookNavListProps {
handleMessage: (message: string) => void;
handleMessageBox: (isShow: boolean) => void;
}
export interface BookNavListState {
export interface NavListState {
deleteIndex: number;
}

View File

@@ -10,9 +10,9 @@
.book-bookmark-digest {
margin: 15px 5px 10px;
width: 236px;
max-height: 186px;
max-height: 198px;
font-size: 14px;
line-height: 14px;
line-height: 18px;
color: rgba(75, 75, 75, 1);
opacity: 1;
text-overflow: ellipsis;

View File

@@ -1,3 +1,4 @@
//笔记书摘的标签
import React from "react";
import "./noteTag.css";
import { NoteTagProps, NoteTagState } from "./interface";

View File

@@ -1,3 +1,4 @@
//添加笔记的弹窗
import React from "react";
import "./popupNote.css";
import Note from "../../model/Note";
@@ -79,10 +80,10 @@ class PopupNote extends React.Component<PopupNoteProps, PopupNoteState> {
text = text.replace(/\n/g, "");
text = text.replace(/\t/g, "");
text = text.replace(/\f/g, "");
let percentage =
RecordLocation.getCfi(this.props.currentBook.key) === null
? 0
: RecordLocation.getCfi(this.props.currentBook.key).percentage;
let percentage = RecordLocation.getCfi(this.props.currentBook.key)
.percentage
? RecordLocation.getCfi(this.props.currentBook.key).percentage
: 0;
let color = this.props.color || 0;
let tag = this.state.tag;

View File

@@ -1,3 +1,4 @@
//选中文字后的弹窗,四个按钮
import React from "react";
import "./popupOption.css";
import localforage from "localforage";
@@ -76,10 +77,10 @@ class PopupOption extends React.Component<PopupOptionProps> {
}
const cfi = RecordLocation.getCfi(this.props.currentBook.key).cfi;
let percentage =
RecordLocation.getCfi(this.props.currentBook.key) === null
? 0
: RecordLocation.getCfi(this.props.currentBook.key).percentage;
let percentage = RecordLocation.getCfi(this.props.currentBook.key)
.percentage
? RecordLocation.getCfi(this.props.currentBook.key).percentage
: 0;
let color = this.props.color;
let notes = "";
let iframe = document.getElementsByTagName("iframe")[0];

View File

@@ -1,3 +1,4 @@
//翻译弹窗
import React from "react";
import "./popupTrans.css";
import { PopupTransProps, PopupTransState } from "./interface";

View File

@@ -1,3 +1,4 @@
//搜索框
import React from "react";
import "./searchBox.css";
import OtherUtil from "../../utils/otherUtil";

View File

@@ -20,7 +20,6 @@ class SettingDialog extends React.Component<
isOpenBook: OtherUtil.getReaderConfig("isOpenBook") === "yes",
isUseFont: OtherUtil.getReaderConfig("isUseFont") === "yes",
isUseBackground: OtherUtil.getReaderConfig("isUseBackground") === "yes",
isHideCursor: OtherUtil.getReaderConfig("isHideCursor") === "yes",
};
}
componentDidMount() {
@@ -81,17 +80,7 @@ class SettingDialog extends React.Component<
: this.props.handleMessage("Turn On Successfully");
this.props.handleMessageBox(true);
};
handleChangeCursor = () => {
this.setState({ isHideCursor: !this.state.isHideCursor });
OtherUtil.setReaderConfig(
"isHideCursor",
this.state.isHideCursor ? "no" : "yes"
);
this.state.isHideCursor
? this.props.handleMessage("Turn Off Successfully")
: this.props.handleMessage("Turn On Successfully");
this.props.handleMessageBox(true);
};
render() {
return (
<div className="setting-dialog-container">
@@ -178,21 +167,7 @@ class SettingDialog extends React.Component<
></span>
</span>
</div>
<div className="setting-dialog-new-title">
<Trans>Auto hide cursor when reading</Trans>
<span
className="single-control-switch"
onClick={() => {
this.handleChangeCursor();
}}
style={{ float: "right" }}
>
<span
className="single-control-button"
style={this.state.isHideCursor ? { float: "right" } : {}}
></span>
</span>
</div>
<div className="setting-dialog-new-title">
<Trans> / Language</Trans>
<div className="setting-language">

View File

@@ -8,6 +8,5 @@ export interface SettingInfoState {
isTouch: boolean;
isOpenBook: boolean;
isUseFont: boolean;
isHideCursor: boolean;
isUseBackground: boolean;
}

View File

@@ -1,3 +1,4 @@
//修改阅读器背景色
import React from "react";
import { themeList } from "../../utils/readerConfig";
import ReaderConfig from "../../utils/readerConfig";

View File

@@ -1,4 +1,4 @@
//添加图书到书架的对话框
//绑定网盘的弹窗
import React, { Component } from "react";
import "./tokenDialog.css";
import copy from "copy-text-to-clipboard";

View File

@@ -1,4 +1,4 @@
//左下角的图标外链
//更新提示弹窗
import React from "react";
import "./updateDialog.css";
import { UpdateInfoProps, UpdateInfoState } from "./interface";

View File

@@ -1,4 +1,4 @@
//左下角的图标外链
//提示更新的文字
import React from "react";
import "./updateInfo.css";
import { UpdateInfoProps, UpdateInfoState } from "./interface";

View File

@@ -1,3 +1,4 @@
//对图书操作的菜单
import React from "react";
import "./actionDialog.css";
import { Trans } from "react-i18next";

View File

@@ -50,6 +50,7 @@ class AddDialog extends Component<AddDialogProps, AddDialogState> {
this.props.handleMessage("Add Successfully");
this.props.handleMessageBox(true);
this.props.handleActionDialog(false);
this.props.handleMode("shelf");
};
//如果是添加到已存在的书架就diable新建图书的input框
handleChange = (shelfTitle: string) => {

View File

@@ -5,6 +5,7 @@ import { handleAddDialog, handleActionDialog } from "../../redux/actions/book";
import { stateType } from "../../redux/store";
import { withNamespaces } from "react-i18next";
import AddDialog from "./component";
import { handleMode } from "../../redux/actions/sidebar";
const mapStateToProps = (state: stateType) => {
return {
@@ -21,6 +22,7 @@ const actionCreator = {
handleActionDialog,
handleMessageBox,
handleMessage,
handleMode,
};
export default connect(
mapStateToProps,

View File

@@ -6,6 +6,7 @@ export interface AddDialogProps {
currentBook: BookModel;
handleMessage: (message: string) => void;
handleMessageBox: (isShow: boolean) => void;
handleMode: (mode: string) => void;
}
export interface AddDialogState {
isNew: boolean;

View File

@@ -1,18 +1,22 @@
//备份和恢复页面
import React from "react";
import "./backupPage.css";
import "./backupDialog.css";
import { driveList } from "../../utils/readerConfig";
import BackupUtil from "../../utils/backupUtil";
import RestoreUtil from "../../utils/restoreUtil";
import { Trans } from "react-i18next";
import DropboxUtil from "../../utils/syncUtils/dropbox";
import OnedriveUtil from "../../utils/syncUtils/onedrive";
import { BackupPageProps, BackupPageState } from "./interface";
import { BackupDialogProps, BackupDialogState } from "./interface";
import TokenDialog from "../../components/tokenDialog";
import OtherUtil from "../../utils/otherUtil";
const isElectron = require("is-electron");
class BackupPage extends React.Component<BackupPageProps, BackupPageState> {
constructor(props: BackupPageProps) {
class BackupDialog extends React.Component<
BackupDialogProps,
BackupDialogState
> {
constructor(props: BackupDialogProps) {
super(props);
this.state = {
currentStep: 0,
@@ -73,6 +77,9 @@ class BackupPage extends React.Component<BackupPageProps, BackupPageState> {
this.showMessage("Coming Soon");
break;
case 3:
if (isElectron()) {
this.showMessage("Please continue in desktop version");
}
if (!OtherUtil.getReaderConfig("onedrive_access_token")) {
this.props.handleTokenDialog(true);
break;
@@ -256,4 +263,4 @@ class BackupPage extends React.Component<BackupPageProps, BackupPageState> {
}
}
export default BackupPage;
export default BackupDialog;

View File

@@ -7,7 +7,7 @@ import { connect } from "react-redux";
import { handleMessageBox, handleMessage } from "../../redux/actions/manager";
import { stateType } from "../../redux/store";
import { withNamespaces } from "react-i18next";
import BackupPage from "./component";
import BackupDialog from "./component";
const mapStateToProps = (state: stateType) => {
return {
@@ -27,4 +27,4 @@ const actionCreator = {
export default connect(
mapStateToProps,
actionCreator
)(withNamespaces()(BackupPage as any));
)(withNamespaces()(BackupDialog as any));

View File

@@ -2,7 +2,7 @@ import BookModel from "../../model/Book";
import NoteModel from "../../model/Note";
import BookmarkModel from "../../model/Bookmark";
export interface BackupPageProps {
export interface BackupDialogProps {
handleBackupDialog: (isBackup: boolean) => void;
handleTokenDialog: (isOpenTokenDialog: boolean) => void;
handleMessage: (message: string) => void;
@@ -13,7 +13,7 @@ export interface BackupPageProps {
digests: NoteModel[];
bookmarks: BookmarkModel[];
}
export interface BackupPageState {
export interface BackupDialogState {
currentStep: number | null;
isBackup: string;
currentDrive: number | null;

View File

@@ -3,7 +3,7 @@
top: 115px;
left: 200px;
width: calc(100% - 200px);
height: calc(100% - 75px);
height: calc(100% - 110px);
overflow: hidden;
}
.book-list-container {
@@ -75,3 +75,7 @@
font-size: 15px;
line-height: 31px;
}
.delete-shelf-icon {
cursor: pointer;
margin-left: 20px;
}

View File

@@ -1,21 +1,27 @@
//全部图书,最近阅读,搜索结果,排序结果的数据
import React from "react";
import "./booklist.css";
import Book from "../../components/book";
import BookItem from "../../components/bookItem";
import Book from "../../components/bookCardtem";
import BookItem from "../../components/bookListItem";
import AddFavorite from "../../utils/addFavorite";
import RecordRecent from "../../utils/recordRecent";
import ShelfUtil from "../../utils/shelfUtil";
import SortUtil from "../../utils/sortUtil";
import BookModel from "../../model/Book";
import { Trans, NamespacesConsumer } from "react-i18next";
import { BookListProps } from "./interface";
import { BookListProps, BookListState } from "./interface";
import OtherUtil from "../../utils/otherUtil";
import localforage from "localforage";
declare var window: any;
class BookList extends React.Component<BookListProps> {
class BookList extends React.Component<BookListProps, BookListState> {
constructor(props: BookListProps) {
super(props);
this.state = {
shelfIndex: 0,
};
}
componentDidMount() {
this.handleOldVersion();
}
@@ -121,7 +127,6 @@ class BookList extends React.Component<BookListProps> {
arr.forEach((item) => {
items[item] && itemArr.push(items[item]);
});
console.log(itemArr);
return itemArr;
};
renderBookList = () => {
@@ -159,11 +164,26 @@ class BookList extends React.Component<BookListProps> {
);
});
};
//切换书架
handleShelfItem = (event: any) => {
let index = event.target.value.split(",")[1];
console.log(index, "index");
this.setState({ shelfIndex: index });
this.props.handleShelfIndex(index);
if (index > 0) {
this.props.handleMode("shelf");
} else {
this.props.handleMode("home");
}
};
handleDeleteShelf = () => {
if (this.state.shelfIndex < 1) return;
let shelfTitles = Object.keys(ShelfUtil.getShelf());
//获取当前书架名
let currentShelfTitle = shelfTitles[this.state.shelfIndex];
ShelfUtil.removeShelf(currentShelfTitle);
// this.setState({ shelfIndex: 0 });
this.props.handleShelfIndex(0);
this.props.handleMode("shelf");
};
renderShelfList = () => {
@@ -230,6 +250,14 @@ class BookList extends React.Component<BookListProps> {
>
{this.renderShelfList()}
</select>
{this.state.shelfIndex > 0 ? (
<span
className="icon-trash delete-shelf-icon"
onClick={() => {
this.handleDeleteShelf();
}}
></span>
) : null}
</div>
<div className="book-list-container-parent">
<div className="book-list-container">

View File

@@ -13,3 +13,6 @@ export interface BookListProps {
handleMode: (mode: string) => void;
handleShelfIndex: (index: number) => void;
}
export interface BookListState {
shelfIndex: number;
}

View File

@@ -3,12 +3,14 @@
top: 80px;
left: 200px;
width: calc(100% - 200px);
height: calc(100% - 90px);
height: calc(100% - 80px);
overflow: hidden;
}
.bookmark-page-container {
width: 100%;
height: 100%;
padding-right: 17px; /* Increase/decrease this value for cross-browser compatibility */
box-sizing: content-box; /* So the width will be 100% + 17px */
display: flex;
flex-wrap: wrap;
overflow-y: scroll;
@@ -36,6 +38,7 @@
height: 160px;
min-width: 403px;
margin-top: 15px;
margin-bottom: 15px;
}
.bookmark-page-cover {
@@ -50,10 +53,8 @@
cursor: pointer;
}
.bookmark-page-name {
/* float: left; */
height: 29px;
width: 110px;
/* margin-left: 10px; */
display: block;
font-size: 14px;
color: rgba(75, 75, 75, 1);

View File

@@ -89,29 +89,26 @@ class BookmarkPage extends React.Component<
</li>
));
};
const renderBookmarkPageItem = (item: BookModel, index: number) => {
return (
<li className="bookmark-page-item" key={item.key}>
<img
className="bookmark-page-cover"
src={item.cover}
alt=""
onClick={() => {
this.handleRedirect(item.key, "", 0);
}}
/>
<p className="bookmark-page-name">{bookArr[index].name}</p>
<div className="bookmark-page-bookmark-container-parent">
<ul className="bookmark-page-bookmark-container">
{renderBookmarklistItem(item)}
</ul>
</div>
</li>
);
};
const renderBookmarkPage = () => {
return bookArr.map((item, index) => {
return <div key={item.key}>{renderBookmarkPageItem(item, index)}</div>;
return (
<li className="bookmark-page-item" key={item.key}>
<img
className="bookmark-page-cover"
src={item.cover}
alt=""
onClick={() => {
this.handleRedirect(item.key, "", 0);
}}
/>
<p className="bookmark-page-name">{bookArr[index].name}</p>
<div className="bookmark-page-bookmark-container-parent">
<ul className="bookmark-page-bookmark-container">
{renderBookmarklistItem(item)}
</ul>
</div>
</li>
);
});
};
return (

View File

@@ -1,8 +1,8 @@
//图书导航
//左侧图书导航面板
import React from "react";
import "./navigationPanel.css";
import ContentList from "../../components/contentList";
import BookNavList from "../../components/bookNavList";
import BookNavList from "../../components/navList";
import ReadingTime from "../../utils/readingTime";
import { Trans } from "react-i18next";
import { NavigationPanelProps, NavigationPanelState } from "./interface";

View File

@@ -1,4 +1,4 @@
//图书操作
//顶部图书操作面
import React from "react";
import "./operationPanel.css";
import Bookmark from "../../model/Bookmark";
@@ -84,17 +84,17 @@ class OperationPanel extends React.Component<
const cfiRange = `epubcfi(${cfibase}!,${cfistart},${cfiend})`;
const cfi = RecordLocation.getCfi(this.props.currentBook.key).cfi;
this.props.currentEpub.getRange(cfiRange).then((range: any) => {
if (!range) return;
let text = range.toString();
text = text.replace(/\s\s/g, "");
text = text.replace(/\r/g, "");
text = text.replace(/\n/g, "");
text = text.replace(/\t/g, "");
text = text.replace(/\f/g, "");
let percentage =
RecordLocation.getCfi(this.props.currentBook.key) === null
? 0
: RecordLocation.getCfi(this.props.currentBook.key).percentage;
let percentage = RecordLocation.getCfi(this.props.currentBook.key)
.percentage
? RecordLocation.getCfi(this.props.currentBook.key).percentage
: 0;
let bookmark = new Bookmark(bookKey, cfi, text, percentage, chapter);
let bookmarkArr = this.props.bookmarks ?? [];
bookmarkArr.push(bookmark);

View File

@@ -1,3 +1,4 @@
//选中文字后的弹窗
import React from "react";
import "./popupMenu.css";
import PopupNote from "../../components/popupNote";

View File

@@ -1,3 +1,4 @@
//底部阅读进度面板
import React from "react";
import "./progressPanel.css";
import RecordLocation from "../../utils/recordLocation";
@@ -51,10 +52,10 @@ class ProgressPanel extends React.Component<
const section = this.props.currentEpub.section(chapterIndex - 1);
if (section && section.href) {
this.props.currentEpub.rendition.display(section.href).then(() => {
let percentage =
RecordLocation.getCfi(this.props.currentBook.key) === null
? 0
: RecordLocation.getCfi(this.props.currentBook.key).percentage;
let percentage = RecordLocation.getCfi(this.props.currentBook.key)
.percentage
? RecordLocation.getCfi(this.props.currentBook.key).percentage
: 0;
this.setState({ displayPercentage: percentage });
});
}
@@ -65,10 +66,10 @@ class ProgressPanel extends React.Component<
const section = this.props.currentEpub.section(chapterIndex + 1);
if (section && section.href) {
this.props.currentEpub.rendition.display(section.href).then(() => {
let percentage =
RecordLocation.getCfi(this.props.currentBook.key) === null
? 0
: RecordLocation.getCfi(this.props.currentBook.key).percentage;
let percentage = RecordLocation.getCfi(this.props.currentBook.key)
.percentage
? RecordLocation.getCfi(this.props.currentBook.key).percentage
: 0;
this.setState({ displayPercentage: percentage });
});
}

View File

@@ -1,9 +1,10 @@
//右侧阅读选项面板
import React from "react";
import "./settingPanel.css";
import ThemeList from "../../components/themeList";
import FontSizeList from "../../components/fontSizeList";
import DropdownList from "../../components/dropdownList";
import SingleControl from "../../components/singleControl";
import ModeControl from "../../components/modeControl";
import { SettingPanelProps, SettingPanelState } from "./interface";
import { Trans } from "react-i18next";
@@ -78,7 +79,7 @@ class SettingPanel extends React.Component<
<div className="setting-panel-title">
<Trans>Reading Option</Trans>
</div>
<SingleControl />
<ModeControl />
{this.state.isSupported && this.props.locations ? (
<div className="single-control-switch-container">
<span className="single-control-switch-title">

View File

@@ -1,3 +1,4 @@
//排序弹窗
import React from "react";
import "./sortDialog.css";
import OtherUtil from "../../utils/otherUtil";

View File

@@ -1,3 +1,4 @@
//阅读器图书内容区域
import React from "react";
import "./viewArea.css";
import PopupMenu from "../popupMenu";

View File

@@ -1,5 +1,5 @@
//欢迎页面
import { withNamespaces } from "react-i18next";
import { handleFirst } from "../../redux/actions/manager";
import { connect } from "react-redux";
import WelcomePage from "./component";

View File

@@ -12,7 +12,7 @@ import AddDialog from "../../containers/addDialog";
import SortDialog from "../../containers/sortDialog";
import MessageBox from "../../containers/messageBox";
import LoadingPage from "../../containers/loadingPage";
import BackupPage from "../../containers/backupPage";
import BackupPage from "../../containers/backupDialog";
import EmptyPage from "../../containers/emptyPage";
import WelcomePage from "../../containers/welcomePage";
import "./manager.css";

View File

@@ -1,5 +1,4 @@
import OtherUtil from "./otherUtil";
import ReaderConfig from "./readerConfig";
let Hammer = (window as any).Hammer;
export const MouseEvent = (rendition: any) => {
@@ -94,16 +93,6 @@ export const MouseEvent = (rendition: any) => {
doc.addEventListener("mousewheel", mouseChrome, false);
}
};
const handleCursor = () => {
if (lock) return;
OtherUtil.setReaderConfig("isHideCursor", "yes");
ReaderConfig.addDefaultCss();
lock = true;
setTimeout(function () {
lock = false;
}, 500);
return false;
};
rendition.on("rendered", () => {
let iframe = document.getElementsByTagName("iframe")[0];
@@ -118,7 +107,6 @@ export const MouseEvent = (rendition: any) => {
gesture(event);
});
}
doc.addEventListener("mousemove", handleCursor);
// 鼠标滚轮翻页
window.addEventListener("keydown", arrowKeys);

View File

@@ -30,19 +30,7 @@ class readerConfig {
static getDefaultCss() {
let colors = ["#FBF1D1", "#EFEEB0", "#CAEFC9", "#76BEE9"];
let lines = ["#FF0000", "#000080", "#0000FF", "#2EFF2E"];
let css1 = `::selection{background:#f3a6a68c}::-moz-selection{background:#f3a6a68c}[class*=color-]:hover{cursor:pointer;background-image:linear-gradient(0,rgba(0,0,0,.075),rgba(0,0,0,.075))}.color-0{background-color:${
colors[0]
}}.color-1{background-color:${colors[1]}}.color-2{background-color:${
colors[2]
}}.color-3{background-color:${colors[3]}}.line-0{border-bottom:2px solid ${
lines[0]
}}.line-1{border-bottom:2px solid ${
lines[1]
}}.line-2{border-bottom:2px solid ${
lines[2]
}}.line-3{border-bottom:2px solid ${lines[3]}}*{cursor:${
OtherUtil.getReaderConfig("isHideCursor") === "yes" ? "none" : ""
}}`;
let css1 = `::selection{background:#f3a6a68c}::-moz-selection{background:#f3a6a68c}[class*=color-]:hover{cursor:pointer;background-image:linear-gradient(0,rgba(0,0,0,.075),rgba(0,0,0,.075))}.color-0{background-color:${colors[0]}}.color-1{background-color:${colors[1]}}.color-2{background-color:${colors[2]}}.color-3{background-color:${colors[3]}}.line-0{border-bottom:2px solid ${lines[0]}}.line-1{border-bottom:2px solid ${lines[1]}}.line-2{border-bottom:2px solid ${lines[2]}}.line-3{border-bottom:2px solid ${lines[3]}}}`;
return css1;
}
@@ -133,8 +121,8 @@ export const config = {
: "http://localhost:3000",
token_url:
process.env.NODE_ENV === "production"
? "https://koodo.960960.xyz"
: "http://localhost:3001",
? "http://localhost:3366"
: "http://localhost:3366",
dropbox_client_id: "e3zgg310xbizvaf",
googledrive_client_id:
"99440516227-ifr1ann33f2j610i3ri17ej0i51c7m6e.apps.googleusercontent.com",

View File

@@ -27,7 +27,7 @@ class ShelfUtil {
let json = localStorage.getItem("shelfList");
let obj = JSON.parse(json!) || defaultShelf;
let shelfTitle = Object.keys(obj);
let currentShelfTitle = shelfTitle[shelfIndex + 1];
let currentShelfTitle = shelfTitle[shelfIndex];
let index = obj[currentShelfTitle].indexOf(bookKey);
obj[currentShelfTitle].splice(index, 1);
localStorage.setItem("shelfList", JSON.stringify(obj));
@@ -45,10 +45,10 @@ class ShelfUtil {
});
localStorage.setItem("shelfList", JSON.stringify(obj));
}
static removeShelf() {
static removeShelf(shelfTitle: string) {
let json = localStorage.getItem("shelfList");
let obj = JSON.parse(json!) || defaultShelf;
delete obj.shelfTitle;
delete obj[shelfTitle];
localStorage.setItem("shelfList", JSON.stringify(obj));
}
}

View File

@@ -2824,6 +2824,11 @@ bluebird-lst@^1.0.9:
dependencies:
bluebird "^3.5.5"
bluebird@^2.3:
version "2.11.0"
resolved "https://registry.npm.taobao.org/bluebird/download/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=
bluebird@^3.5.5:
version "3.7.2"
resolved "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -2839,7 +2844,7 @@ bn.js@^5.1.1:
resolved "https://registry.npm.taobao.org/bn.js/download/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b"
integrity sha1-vsoAVAj2Quvr6oCwQrTRjSrA7ms=
body-parser@1.19.0:
body-parser@1.19.0, body-parser@^1.19.0:
version "1.19.0"
resolved "https://registry.npm.taobao.org/body-parser/download/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
integrity sha1-lrJwnlfJxOCab9Zqj9l5hE9p8Io=
@@ -3094,6 +3099,13 @@ builtin-status-codes@^3.0.0:
resolved "https://registry.npm.taobao.org/builtin-status-codes/download/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
busboy@^0.3.1:
version "0.3.1"
resolved "https://registry.npm.taobao.org/busboy/download/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
integrity sha1-FwiZJ0xb84quJ9XGK3EmjNWF/Rs=
dependencies:
dicer "0.3.0"
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/bytes/download/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -3789,6 +3801,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
resolved "https://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
cors@^2.8.5:
version "2.8.5"
resolved "https://registry.npm.taobao.org/cors/download/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
integrity sha1-6sEdpRWS3Ya58G9uesKTs9+HXSk=
dependencies:
object-assign "^4"
vary "^1"
cosmiconfig@^5.0.0, cosmiconfig@^5.2.1:
version "5.2.1"
resolved "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-5.2.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
@@ -4352,6 +4372,13 @@ detect-port-alt@1.1.6:
address "^1.0.1"
debug "^2.6.0"
dicer@0.3.0:
version "0.3.0"
resolved "https://registry.npm.taobao.org/dicer/download/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872"
integrity sha1-6s2Ys7+/kuirXC/bcaqsRLsGuHI=
dependencies:
streamsearch "0.1.2"
diff-sequences@^24.9.0:
version "24.9.0"
resolved "https://registry.npm.taobao.org/diff-sequences/download/diff-sequences-24.9.0.tgz?cache=0&sync_timestamp=1597057408594&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff-sequences%2Fdownload%2Fdiff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
@@ -5110,6 +5137,13 @@ expect@^24.9.0:
jest-message-util "^24.9.0"
jest-regex-util "^24.9.0"
express-fileupload@^1.2.0:
version "1.2.0"
resolved "https://registry.npm.taobao.org/express-fileupload/download/express-fileupload-1.2.0.tgz#356c4dfd645be71ab9fb2f4e6d84eeb00d247979"
integrity sha1-NWxN/WRb5xq5+y9ObYTusA0keXk=
dependencies:
busboy "^0.3.1"
express@^4.17.1:
version "4.17.1"
resolved "https://registry.npm.taobao.org/express/download/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
@@ -6604,6 +6638,11 @@ is-electron@^2.2.0:
resolved "https://registry.npm.taobao.org/is-electron/download/is-electron-2.2.0.tgz#8943084f09e8b731b3a7a0298a7b5d56f6b7eef0"
integrity sha1-iUMITwnotzGzp6ApintdVva37vA=
is-empty-object@^1.1.1:
version "1.1.1"
resolved "https://registry.npm.taobao.org/is-empty-object/download/is-empty-object-1.1.1.tgz#86d5d4d5c5229cea31ec2772f528bf5efc519f23"
integrity sha1-htXU1cUinOox7Cdy9Si/XvxRnyM=
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.npm.taobao.org/is-extendable/download/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -7751,7 +7790,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@~4.17.10:
"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.5, lodash@^4.5.0, lodash@~4.17.10:
version "4.17.20"
resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz?cache=0&sync_timestamp=1597336097104&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI=
@@ -8463,7 +8502,7 @@ oauth-sign@~0.9.0:
resolved "https://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -8590,6 +8629,15 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
onedrive-api@^0.5.0:
version "0.5.0"
resolved "https://registry.npm.taobao.org/onedrive-api/download/onedrive-api-0.5.0.tgz#197150da29b741e882bfd68a78ae14e8d8763f28"
integrity sha1-GXFQ2im3QeiCv9aKeK4U6Nh2Pyg=
dependencies:
is-empty-object "^1.1.1"
request "^2.88.0"
request-promise "^2.0.1"
onetime@^5.1.0:
version "5.1.2"
resolved "https://registry.npm.taobao.org/onetime/download/onetime-5.1.2.tgz?cache=0&sync_timestamp=1597005190531&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fonetime%2Fdownload%2Fonetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
@@ -9936,6 +9984,11 @@ qs@6.7.0:
resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
integrity sha1-QdwaAV49WB8WIXdr4xr7KHapsbw=
qs@^6.9.4:
version "6.9.4"
resolved "https://registry.npm.taobao.org/qs/download/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
integrity sha1-kJCykNH5FyjTwi5UhDykSupatoc=
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@@ -10523,7 +10576,16 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
request@^2.87.0, request@^2.88.0:
request-promise@^2.0.1:
version "2.0.1"
resolved "https://registry.npm.taobao.org/request-promise/download/request-promise-2.0.1.tgz#acbd47b725e39372ede3174cf29c38d9ecf2b30d"
integrity sha1-rL1HtyXjk3Lt4xdM8pw42ezysw0=
dependencies:
bluebird "^2.3"
lodash "^4.5.0"
request "^2.34"
request@^2.34, request@^2.87.0, request@^2.88.0:
version "2.88.2"
resolved "https://registry.npm.taobao.org/request/download/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM=
@@ -11402,6 +11464,11 @@ stream-shift@^1.0.0:
resolved "https://registry.npm.taobao.org/stream-shift/download/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha1-1wiCgVWasneEJCebCHfaPDktWj0=
streamsearch@0.1.2:
version "0.1.2"
resolved "https://registry.npm.taobao.org/streamsearch/download/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
@@ -12252,7 +12319,7 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
vary@~1.1.2:
vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=