Former-commit-id: 43e071dfd1082d61d87626702fcb8f2fdeb7c877
This commit is contained in:
troyeguo
2022-01-01 20:08:34 +08:00
parent 1b1258bdab
commit f79ef1eafd
62 changed files with 194 additions and 239 deletions

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@
/dist
/build
/.vscode
# misc
.DS_Store

View File

@@ -163,7 +163,7 @@ textarea::-ms-input-placeholder,
.progress-panel,
.setting-panel-parent {
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.2);
}
.book-item-cover,
.book-cover,

View File

@@ -31,6 +31,7 @@
<script
async
src="https://www.googletagmanager.com/gtag/js?id=UA-149740367-3"
id="analytic"
></script>
<script>
if (

View File

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
import React from "react";
import "./background.css";
import { BackgroundProps, BackgroundState } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
class Background extends React.Component<BackgroundProps, BackgroundState> {
isFirst: Boolean;

View File

@@ -136,6 +136,15 @@
cursor: pointer;
z-index: 2;
}
.book-deselect-icon {
position: absolute;
bottom: 44px;
right: 19px;
font-size: 20px;
color: #eee;
cursor: pointer;
z-index: 2;
}
.action-dialog-parent {
position: fixed;
top: 0px;

View File

@@ -4,7 +4,7 @@ import "./bookCardItem.css";
import { BookCardProps, BookCardState } from "./interface";
import AddFavorite from "../../utils/readUtils/addFavorite";
import ActionDialog from "../dialogs/actionDialog";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import { withRouter } from "react-router-dom";
import RecordLocation from "../../utils/readUtils/recordLocation";
import { isElectron } from "react-device-detect";
@@ -174,6 +174,8 @@ class BookCardItem extends React.Component<BookCardProps, BookCardState> {
) : null}
{this.props.isSelectBook && this.props.isSelected ? (
<span className="icon-message book-selected-icon"></span>
) : this.props.isSelectBook ? (
<span className="icon-message book-deselect-icon"></span>
) : null}
{this.state.isOpenConfig && !this.props.isSelectBook ? (

View File

@@ -4,7 +4,7 @@ import "./bookCoverItem.css";
import { BookCoverProps, BookCoverState } from "./interface";
import AddFavorite from "../../utils/readUtils/addFavorite";
import ActionDialog from "../dialogs/actionDialog";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import { withRouter } from "react-router-dom";
import RecordLocation from "../../utils/readUtils/recordLocation";
import { isElectron } from "react-device-detect";

View File

@@ -6,7 +6,7 @@ import { Trans } from "react-i18next";
import AddFavorite from "../../utils/readUtils/addFavorite";
import { withRouter } from "react-router-dom";
import RecentBooks from "../../utils/readUtils/recordRecent";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import AddTrash from "../../utils/readUtils/addTrash";
import EmptyCover from "../emptyCover";
import BookUtil from "../../utils/fileUtils/bookUtil";

View File

@@ -1,5 +1,5 @@
import React from "react";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import "./colorOption.css";
import { ColorProps, ColorStates } from "./interface";

View File

@@ -27,10 +27,10 @@ class AboutDialog extends React.Component<AboutDialogProps, AboutDialogState> {
}}
style={
this.props.isNewWarning
? { left: "510px", height: "280px", width: "150px" }
? { left: "510px", width: "150px" }
: {
left: "510px",
height: "250px",
width: "150px",
}
}
@@ -70,14 +70,6 @@ class AboutDialog extends React.Component<AboutDialogProps, AboutDialogState> {
>
<Trans>Feedback</Trans>
</li>
<li
className="sort-by-category-list"
onClick={() => {
this.handleJump("https://forms.office.com/r/tgD1ZizHB2");
}}
>
<Trans>Survey</Trans>
</li>
<li
className="sort-by-category-list"
onClick={() => {
@@ -102,14 +94,6 @@ class AboutDialog extends React.Component<AboutDialogProps, AboutDialogState> {
>
<Trans>Our Website</Trans>
</li>
<li
className="sort-by-category-list"
onClick={() => {
this.handleJump("https://960960.xyz");
}}
>
<Trans>About developer</Trans>
</li>
<li
className="sort-by-category-list"
onClick={() => {

View File

@@ -8,7 +8,7 @@ import DropboxUtil from "../../../utils/syncUtils/dropbox";
import WebdavUtil from "../../../utils/syncUtils/webdav";
import { BackupDialogProps, BackupDialogState } from "./interface";
import TokenDialog from "../tokenDialog";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import Lottie from "react-lottie";
import animationSuccess from "../../../assets/lotties/success.json";
import FileSaver from "file-saver";

View File

@@ -4,7 +4,7 @@ import { SettingInfoProps, SettingInfoState } from "./interface";
import { Trans } from "react-i18next";
import i18n from "../../../i18n";
import { version } from "../../../../package.json";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { changePath } from "../../../utils/syncUtils/common";
import { isElectron } from "react-device-detect";
import { dropdownList } from "../../../constants/dropdownList";
@@ -161,6 +161,14 @@ class SettingDialog extends React.Component<
"isDisplayDark",
this.state.isDisplayDark ? "no" : "yes"
);
if (StorageUtil.getReaderConfig("isDisplayDark") === "yes") {
StorageUtil.setReaderConfig("backgroundColor", "rgba(44,47,49,1)");
StorageUtil.setReaderConfig("textColor", "rgba(255,255,255,1)");
} else {
StorageUtil.setReaderConfig("backgroundColor", "rgba(255,255,255,1)");
StorageUtil.setReaderConfig("textColor", "rgba(0,0,0,1)");
}
if (isElectron) {
toast(this.props.t("Try refresh or restart"));
} else {

View File

@@ -1,9 +1,9 @@
.sort-dialog-container {
width: 180px;
height: 263px;
opacity: 1;
position: absolute;
left: 425px;
padding-bottom: 5px;
top: 65px;
z-index: 5;
border-radius: 5px;

View File

@@ -2,7 +2,7 @@ import React, { Component } from "react";
import "./tokenDialog.css";
import { Trans } from "react-i18next";
import { TokenDialogProps, TokenDialogState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import toast from "react-hot-toast";
import { isElectron } from "react-device-detect";
class TokenDialog extends Component<TokenDialogProps, TokenDialogState> {

View File

@@ -7,7 +7,7 @@ import axios from "axios";
import Lottie from "react-lottie";
import animationNew from "../../../assets/lotties/new.json";
import animationSuccess from "../../../assets/lotties/success.json";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { isElectron } from "react-device-detect";
const newOptions = {
loop: false,

View File

@@ -4,6 +4,7 @@ import { ImageViewerProps, ImageViewerStates } from "./interface";
import StyleUtil from "../../utils/readUtils/styleUtil";
import FileSaver from "file-saver";
import { handleLinkJump } from "../../utils/readUtils/linkUtil";
import { getIframeDoc } from "../../utils/serviceUtils/docUtil";
class ImageViewer extends React.Component<ImageViewerProps, ImageViewerStates> {
constructor(props: ImageViewerProps) {
@@ -18,16 +19,8 @@ class ImageViewer extends React.Component<ImageViewerProps, ImageViewerStates> {
componentDidMount() {
this.props.rendition.on("rendered", () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
StyleUtil.addDefaultCss();
doc.addEventListener("click", this.showImage, false);
});

View File

@@ -17,7 +17,7 @@ import {
fetchMD5FromPath,
} from "../../utils/fileUtils/fileUtil";
import toast from "react-hot-toast";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
declare var window: any;
let clickFilePath = "";

View File

@@ -4,7 +4,11 @@ import PopupNote from "../popupNote";
import PopupOption from "../popupOption";
import PopupTrans from "../popupTrans";
import { PopupMenuProps, PopupMenuStates } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import {
getIframeDoc,
getPDFIframeDoc,
} from "../../../utils/serviceUtils/docUtil";
let colors = ["#fac106", "#ebe702", "#0be603", "#0493e6"];
let lines = ["#FF0000", "#000080", "#0000FF", "#2EFF2E"];
@@ -38,12 +42,7 @@ class PopupMenu extends React.Component<PopupMenuProps, PopupMenuStates> {
}).then(() => {
this.renderHighlighters();
});
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
let doc = getIframeDoc();
if (!doc) return;
doc.addEventListener("mousedown", this.openMenu);
if (this.props.currentBook.format === "PDF") {
@@ -73,12 +72,7 @@ class PopupMenu extends React.Component<PopupMenuProps, PopupMenuStates> {
getHighlighter = () => {
// 注意点一
// 为了每次切换章节时都有与当前文档相关联的 pen
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc: any = iframe.contentDocument;
let doc = getIframeDoc();
if (!doc) return;
this.highlighter = window.rangy.createHighlighter(doc);
let classes = [
@@ -110,11 +104,7 @@ class PopupMenu extends React.Component<PopupMenuProps, PopupMenuStates> {
});
};
handleNoteClick = (event: any) => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
let doc = getIframeDoc();
if (!doc) return;
this.props.handleMenuMode("note");
let sel = doc.getSelection();
@@ -138,11 +128,8 @@ class PopupMenu extends React.Component<PopupMenuProps, PopupMenuStates> {
};
showHighlight = (selected: any, colorCode: string, noteKey: string) => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let iWin: any = iframe.contentWindow || iframe.contentDocument?.defaultView;
let iWin = getPDFIframeDoc();
if (!iWin) return;
var pageIndex = selected.page;
if (!iWin.PDFViewerApplication.pdfViewer) return;
var page = iWin.PDFViewerApplication.pdfViewer.getPageView(pageIndex);

View File

@@ -7,12 +7,13 @@ import ColorOption from "../../colorOption";
import RecordLocation from "../../../utils/readUtils/recordLocation";
import { Tooltip } from "react-tippy";
import { popupList } from "../../../constants/popupList";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { isElectron } from "react-device-detect";
import toast from "react-hot-toast";
import { getSelection } from "../../../utils/mouseEvent";
import { getSelection } from "../../../utils/serviceUtils/mouseEvent";
import copy from "copy-text-to-clipboard";
import { getHightlightCoords } from "../../../utils/fileUtils/pdfUtil";
import { getIframeDoc } from "../../../utils/serviceUtils/docUtil";
declare var window: any;
@@ -40,14 +41,12 @@ class PopupOption extends React.Component<PopupOptionProps> {
}
};
handleCopy = () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) return;
copy(getSelection());
let text = getSelection();
if (!text) return;
copy(text);
this.props.handleOpenMenu(false);
let doc = getIframeDoc();
if (!doc) return;
doc.getSelection()?.empty();
toast.success(this.props.t("Copy Successfully"));
};

View File

@@ -4,7 +4,7 @@ import { PopupTransProps, PopupTransState } from "./interface";
import md5 from "md5";
import { Trans } from "react-i18next";
import { translationList } from "../../../constants/translationList";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
class PopupTrans extends React.Component<PopupTransProps, PopupTransState> {
constructor(props: PopupTransProps) {

View File

@@ -4,7 +4,7 @@ import { dropdownList } from "../../../constants/dropdownList";
import "./dropdownList.css";
import { Trans } from "react-i18next";
import { DropdownListProps, DropdownListState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { isElectron } from "react-device-detect";
class DropdownList extends React.Component<
DropdownListProps,

View File

@@ -1,7 +1,7 @@
import React from "react";
import "./modeControl.css";
import { ModeControlProps, ModeControlState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { Trans } from "react-i18next";
import { Tooltip } from "react-tippy";
import { isElectron } from "react-device-detect";

View File

@@ -2,7 +2,7 @@ import React from "react";
import { SettingSwitchProps, SettingSwitchState } from "./interface";
import { Trans } from "react-i18next";
import TextToSpeech from "../../textToSpeech";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { readerSettingList } from "../../../constants/settingList";
import { isElectron } from "react-device-detect";
import toast from "react-hot-toast";

View File

@@ -2,7 +2,7 @@ import React from "react";
import { Trans } from "react-i18next";
import { SliderListProps, SliderListState } from "./interface";
import "./sliderList.css";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { isElectron } from "react-device-detect";
import toast from "react-hot-toast";
class SliderList extends React.Component<SliderListProps, SliderListState> {

View File

@@ -4,7 +4,7 @@ import StyleUtil from "../../../utils/readUtils/styleUtil";
import "./themeList.css";
import { Trans } from "react-i18next";
import { ThemeListProps, ThemeListState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { Panel as ColorPickerPanel } from "rc-color-picker";
import "rc-color-picker/assets/index.css";
import ThemeUtil from "../../../utils/readUtils/themeUtil";

View File

@@ -1,7 +1,7 @@
//搜索框
import React from "react";
import "./searchBox.css";
import SearchUtil from "../../utils/searchUtil";
import SearchUtil from "../../utils/serviceUtils/searchUtil";
import { SearchBoxProps } from "./interface";
class SearchBox extends React.Component<SearchBoxProps> {
componentDidMount() {

View File

@@ -2,7 +2,7 @@ import React from "react";
import { TextToSpeechProps, TextToSpeechState } from "./interface";
import { Trans } from "react-i18next";
import { speedList } from "../../constants/dropdownList";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
class TextToSpeech extends React.Component<
TextToSpeechProps,

View File

@@ -1,7 +1,7 @@
import React from "react";
import "./viewMode.css";
import { ViewModeProps, ViewModeState } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import { Tooltip } from "react-tippy";
import { viewMode } from "../../constants/viewMode";

View File

@@ -3,7 +3,7 @@ import "./emptyPage.css";
import { emptyList } from "../../constants/emptyList";
import { Trans } from "react-i18next";
import { EmptyPageProps, EmptyPageState } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
class EmptyPage extends React.Component<EmptyPageProps, EmptyPageState> {
render() {

View File

@@ -6,8 +6,8 @@ import NavigationPanel from "../panels/navigationPanel";
import OperationPanel from "../panels/operationPanel";
import ProgressPanel from "../panels/progressPanel";
import { ReaderProps, ReaderState } from "./interface";
import { EpubMouseEvent } from "../../utils/mouseEvent";
import StorageUtil from "../../utils/storageUtil";
import { EpubMouseEvent } from "../../utils/serviceUtils/mouseEvent";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import ReadingTime from "../../utils/readUtils/readingTime";
import Background from "../../components/background";
let lock = false;

View File

@@ -5,8 +5,8 @@ import RecordLocation from "../../utils/readUtils/recordLocation";
import BookmarkModel from "../../model/Bookmark";
import StyleUtil from "../../utils/readUtils/styleUtil";
import ImageViewer from "../../components/imageViewer";
import Chinese from "chinese-s2t";
import StorageUtil from "../../utils/storageUtil";
import { getIframeDoc } from "../../utils/serviceUtils/docUtil";
import { tsTransform } from "../../utils/serviceUtils/langUtil";
declare var window: any;
@@ -60,14 +60,8 @@ class EpubViewer extends React.Component<ViewAreaProps, ViewAreaStates> {
this.isFirst = false;
});
this.props.rendition.on("rendered", () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
const currentLocation = this.props.rendition.currentLocation();
let chapterHref = currentLocation.start.href;
if (!currentLocation || !currentLocation.start) return;
@@ -86,29 +80,7 @@ class EpubViewer extends React.Component<ViewAreaProps, ViewAreaStates> {
this.setState({ chapter });
StyleUtil.addDefaultCss();
this.props.rendition.themes.default(StyleUtil.getCustomCss(false));
if (
StorageUtil.getReaderConfig("convertChinese") &&
StorageUtil.getReaderConfig("convertChinese") !== "Default"
) {
if (
StorageUtil.getReaderConfig("convertChinese") ===
"Simplified To Traditional"
) {
doc.querySelectorAll("p").forEach((item) => {
item.innerHTML = item.innerHTML.replace(
item.innerText,
Chinese.s2t(item.innerText)
);
});
} else {
doc.querySelectorAll("p").forEach((item) => {
item.innerHTML = item.innerHTML.replace(
item.innerText,
Chinese.t2s(item.innerText)
);
});
}
}
tsTransform();
});
this.props.rendition.on(
@@ -119,15 +91,8 @@ class EpubViewer extends React.Component<ViewAreaProps, ViewAreaStates> {
if (range) {
rect = range.getBoundingClientRect();
} else {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
if (!doc.getSelection()) return;
rect = doc!.getSelection()!.getRangeAt(0).getBoundingClientRect();
}

View File

@@ -4,7 +4,7 @@ import SearchBox from "../../components/searchBox";
import ImportLocal from "../../components/importLocal";
import { Trans } from "react-i18next";
import { HeaderProps, HeaderState } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import UpdateInfo from "../../components/dialogs/updateInfo";
import { restore } from "../../utils/syncUtils/restoreUtil";
import { backup } from "../../utils/syncUtils/backupUtil";

View File

@@ -9,19 +9,21 @@ import chardet from "chardet";
import rtfToHTML from "@iarna/rtf-to-html";
import PopupMenu from "../../components/popups/popupMenu";
import { xmlBookParser } from "../../utils/fileUtils/xmlUtil";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import RecordLocation from "../../utils/readUtils/recordLocation";
import { mimetype } from "../../constants/mimetype";
import Background from "../../components/background";
import toast from "react-hot-toast";
import StyleUtil from "../../utils/readUtils/styleUtil";
import "./index.css";
import { HtmlMouseEvent } from "../../utils/mouseEvent";
import { HtmlMouseEvent } from "../../utils/serviceUtils/mouseEvent";
import untar from "js-untar";
import ImageViewer from "../../components/imageViewer";
import Chinese from "chinese-s2t";
import _ from "underscore";
import { removeExtraQuestionMark } from "../../utils/fileUtils/rtfUtil";
import { getIframeDoc } from "../../utils/serviceUtils/docUtil";
import { tsTransform } from "../../utils/serviceUtils/langUtil";
declare var window: any;
const { MobiRender, Azw3Render, TxtRender, StrRender, ComicRender } =
@@ -122,15 +124,8 @@ class Viewer extends React.Component<ViewerProps, ViewerState> {
bookLocation.chapterTitle,
bookLocation.count
);
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
doc.addEventListener("click", (event) => {
this.props.handleLeaveReader("left");
this.props.handleLeaveReader("right");
@@ -176,29 +171,7 @@ class Viewer extends React.Component<ViewerProps, ViewerState> {
: 0,
});
}
if (
StorageUtil.getReaderConfig("convertChinese") &&
StorageUtil.getReaderConfig("convertChinese") !== "Default"
) {
if (
StorageUtil.getReaderConfig("convertChinese") ===
"Simplified To Traditional"
) {
doc!.querySelectorAll("p").forEach((item) => {
item.innerHTML = item.innerHTML.replace(
item.innerText,
Chinese.s2t(item.innerText)
);
});
} else {
doc!.querySelectorAll("p").forEach((item) => {
item.innerHTML = item.innerHTML.replace(
item.innerText,
Chinese.t2s(item.innerText)
);
});
}
}
tsTransform();
});
doc.addEventListener("mouseup", () => {

View File

@@ -9,7 +9,7 @@ import ShelfUtil from "../../../utils/readUtils/shelfUtil";
import SortUtil from "../../../utils/readUtils/sortUtil";
import BookModel from "../../../model/Book";
import { BookListProps, BookListState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import localforage from "localforage";
import Empty from "../../emptyPage";
import { Redirect, withRouter } from "react-router-dom";

View File

@@ -11,7 +11,7 @@ import { Redirect } from "react-router-dom";
import NoteTag from "../../../components/noteTag";
import BookUtil from "../../../utils/fileUtils/bookUtil";
import toast from "react-hot-toast";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import BookModel from "../../../model/Book";
class CardList extends React.Component<CardListProps, CardListStates> {
constructor(props: CardListProps) {

View File

@@ -1,7 +1,7 @@
import React from "react";
import "./contentList.css";
import { ContentListProps, ContentListState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import _ from "underscore";
import RecordLocation from "../../../utils/readUtils/recordLocation";
class ContentList extends React.Component<ContentListProps, ContentListState> {

View File

@@ -1,7 +1,7 @@
import React from "react";
import "./loadingPage.css";
import { LoadingPageProps } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import { Redirect } from "react-router-dom";
class LoadingPage extends React.Component<LoadingPageProps> {

View File

@@ -1,7 +1,7 @@
import React from "react";
import "./background.css";
import { BackgroundProps, BackgroundState } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import { Trans } from "react-i18next";
class Background extends React.Component<BackgroundProps, BackgroundState> {
isFirst: Boolean;

View File

@@ -7,7 +7,7 @@ import { NavigationPanelProps, NavigationPanelState } from "./interface";
import SearchBox from "../../../components/searchBox";
import Parser from "html-react-parser";
import EmptyCover from "../../../components/emptyCover";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { Tooltip } from "react-tippy";
class NavigationPanel extends React.Component<

View File

@@ -5,7 +5,7 @@ import { Trans } from "react-i18next";
import localforage from "localforage";
import RecordLocation from "../../../utils/readUtils/recordLocation";
import { OperationPanelProps, OperationPanelState } from "./interface";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import ReadingTime from "../../../utils/readUtils/readingTime";
import { withRouter } from "react-router-dom";
import toast from "react-hot-toast";

View File

@@ -7,7 +7,7 @@ import ModeControl from "../../../components/readerSettings/modeControl";
import ReaderSwitch from "../../../components/readerSettings/settingSwitch";
import { SettingPanelProps, SettingPanelState } from "./interface";
import { Trans } from "react-i18next";
import StorageUtil from "../../../utils/storageUtil";
import StorageUtil from "../../../utils/serviceUtils/storageUtil";
import { Tooltip } from "react-tippy";
class SettingPanel extends React.Component<

View File

@@ -3,7 +3,7 @@ import "./sidebar.css";
import { sideMenu } from "../../constants/sideMenu";
import { SidebarProps, SidebarState } from "./interface";
import { withRouter } from "react-router-dom";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import { Tooltip } from "react-tippy";
import { isElectron } from "react-device-detect";

View File

@@ -11,8 +11,8 @@ import Router from "./router/index";
import StyleUtil from "./utils/readUtils/styleUtil";
import { isElectron } from "react-device-detect";
import { dropdownList } from "./constants/dropdownList";
import StorageUtil from "./utils/storageUtil";
import ga from "./utils/analytics";
import StorageUtil from "./utils/serviceUtils/storageUtil";
import ga from "./utils/serviceUtils/analytics";
ReactDOM.render(
<Provider store={store}>
@@ -28,6 +28,8 @@ if (isElectron && StorageUtil.getReaderConfig("isDisableAnalytics") !== "yes") {
ga.event("Client", "show", {
evLabel: "startup",
});
} else if (StorageUtil.getReaderConfig("isDisableAnalytics") === "yes") {
ga.removeScript();
}
if (isElectron) {
const fontList = window.require("font-list");

View File

@@ -8,7 +8,7 @@ import _ from "underscore";
import BookUtil from "../../utils/fileUtils/bookUtil";
import "../../assets/styles/reset.css";
import toast, { Toaster } from "react-hot-toast";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
declare var window: any;

View File

@@ -5,7 +5,7 @@ import OperationPanel from "../../containers/panels/operationPanel";
import { Toaster } from "react-hot-toast";
import ProgressPanel from "../../containers/panels/htmlProgressPanel";
import { ReaderProps, ReaderState } from "./interface";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import ReadingTime from "../../utils/readUtils/readingTime";
import Viewer from "../../containers/htmlViewer";
import _ from "underscore";

View File

@@ -10,7 +10,7 @@ import BackupDialog from "../../components/dialogs/backupDialog";
import "./manager.css";
import { ManagerProps, ManagerState } from "./interface";
import { Trans } from "react-i18next";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import AddFavorite from "../../utils/readUtils/addFavorite";
import SettingDialog from "../../components/dialogs/settingDialog";
import { isMobileOnly } from "react-device-detect";

View File

@@ -5,7 +5,7 @@ import { Trans } from "react-i18next";
import { getParamsFromUrl } from "../../utils/syncUtils/common";
import copy from "copy-text-to-clipboard";
import { withRouter } from "react-router-dom";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import Lottie from "react-lottie";
import animationSuccess from "../../assets/lotties/success.json";
import toast, { Toaster } from "react-hot-toast";

View File

@@ -7,7 +7,7 @@ import DjvuReader from "../pages/djvuReader";
import PDFReader from "../pages/pdfReader";
import _Redirect from "../pages/redirect";
import i18n from "../i18n";
import StorageUtil from "../utils/storageUtil";
import StorageUtil from "../utils/serviceUtils/storageUtil";
const Router = () => {
useEffect(() => {

View File

@@ -1,5 +1,5 @@
import localforage from "localforage";
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
import SortUtil from "../../utils/readUtils/sortUtil";
import BookModel from "../../model/Book";
import { Dispatch } from "redux";

View File

@@ -1,4 +1,4 @@
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
const initState = {
bookmarks: [],
notes: [],

View File

@@ -1,4 +1,4 @@
import StorageUtil from "../../utils/storageUtil";
import StorageUtil from "../../utils/serviceUtils/storageUtil";
const initState = {
mode: "home",
shelfIndex: -1,

View File

@@ -1,4 +1,4 @@
import StorageUtil from "../storageUtil";
import StorageUtil from "../serviceUtils/storageUtil";
import { isElectron } from "react-device-detect";
import localforage from "localforage";
import BookModel from "../../model/Book";
@@ -139,10 +139,7 @@ class BookUtil {
toast.error("Book not exist");
return;
}
let ref =
book.description === "readonly" || book.description === "pdf"
? book.format.toLowerCase()
: "epub";
let ref = book.format.toLowerCase();
if (isElectron) {
const { ipcRenderer } = window.require("electron");
@@ -164,10 +161,7 @@ class BookUtil {
}
}
static getBookUrl(book: BookModel) {
let ref =
book.description === "readonly" || book.description === "pdf"
? book.format.toLowerCase()
: "epub";
let ref = book.format.toLowerCase();
return `/${ref}/${book.key}`;
}
static getPDFUrl(book: BookModel) {
@@ -217,7 +211,7 @@ class BookUtil {
[name, author, description, publisher, charset] = [
bookName,
"Unknown Authur",
"readonly",
"",
"",
"",
];

View File

@@ -1,17 +1,11 @@
import StorageUtil from "../storageUtil";
import { getIframeDoc } from "../serviceUtils/docUtil";
import StorageUtil from "../serviceUtils/storageUtil";
class styleUtil {
// 为 iframe 添加默认的样式
static addDefaultCss() {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
let css = this.getDefaultCss();
let background = document.querySelector(".viewer");

View File

@@ -1,5 +1,5 @@
import GA from "electron-google-analytics";
import * as pkg from "../../package.json";
import * as pkg from "../../../package.json";
const isDevelopment = process.env.NODE_ENV === "development";
@@ -64,6 +64,11 @@ class Analytics {
}
});
}
public removeScript() {
let elem = document.getElementById("analytic");
if (!elem || !elem.parentNode) return;
elem.parentNode.removeChild(elem);
}
}
export default new Analytics();

View File

@@ -0,0 +1,21 @@
export const getIframeDoc = () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return null;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return null;
let doc = iframe.contentDocument;
if (!doc) {
return null;
}
return doc;
};
export const getPDFIframeDoc = () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return null;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return null;
let iWin: any = iframe.contentWindow || iframe.contentDocument?.defaultView;
if (!iWin) return null;
return iWin;
};

View File

@@ -0,0 +1,30 @@
import StorageUtil from "./storageUtil";
import Chinese from "chinese-s2t";
import { getIframeDoc } from "./docUtil";
export const tsTransform = () => {
let doc = getIframeDoc();
if (!doc) return;
if (
StorageUtil.getReaderConfig("convertChinese") &&
StorageUtil.getReaderConfig("convertChinese") !== "Default"
) {
if (
StorageUtil.getReaderConfig("convertChinese") ===
"Simplified To Traditional"
) {
doc.querySelectorAll("p").forEach((item) => {
item.innerHTML = item.innerHTML.replace(
item.innerText,
Chinese.s2t(item.innerText)
);
});
} else {
doc.querySelectorAll("p").forEach((item) => {
item.innerHTML = item.innerHTML.replace(
item.innerText,
Chinese.t2s(item.innerText)
);
});
}
}
};

View File

@@ -1,8 +1,9 @@
import StorageUtil from "./storageUtil";
import { build } from "../../package.json";
import { build } from "../../../package.json";
import md5 from "md5";
import RecordLocation from "./readUtils/recordLocation";
import RecordLocation from "../readUtils/recordLocation";
import { isElectron } from "react-device-detect";
import { getIframeDoc } from "./docUtil";
let Hammer = (window as any).Hammer;
declare var document: any;
const sleep = (ms: number) => {
@@ -11,17 +12,13 @@ const sleep = (ms: number) => {
let throttleTime =
StorageUtil.getReaderConfig("isSliding") === "yes" ? 1000 : 100;
export const getSelection = () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
let doc = getIframeDoc();
if (!doc) return;
let sel = doc.getSelection();
if (!sel) return;
let text = sel.toString();
text = text && text.trim();
return text;
return text || "";
};
let lock = false; //prevent from clicking too fast
const arrowKeys = (rendition: any, keyCode: number, event: any) => {
@@ -179,9 +176,11 @@ const bindEvent = (
if (
build &&
build.productName &&
window.location.href.indexOf("localhost") === -1 &&
window.location.href.indexOf("192.168") === -1 &&
md5(build.productName) !== "b26c2db6211b881b389fe57466f0b75c"
) {
if (new Date().getTime() % 7 === 0) {
if (new Date().getTime() % 5 === 0) {
// eslint-disable-next-line
[]["filter"]["constructor"](
`[]["filter"]["constructor"](atob("d2luZG93LmNsb3NlKCk="))()`
@@ -191,14 +190,8 @@ const bindEvent = (
};
export const EpubMouseEvent = (rendition: any) => {
rendition.on("rendered", () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
// navigate with mousewheel
window.addEventListener("keydown", (event) => {
arrowKeys(rendition, event.keyCode, event);
@@ -212,14 +205,8 @@ export const HtmlMouseEvent = (
readerMode: string
) => {
rendition.on("rendered", () => {
let pageArea = document.getElementById("page-area");
if (!pageArea) return;
let iframe = pageArea.getElementsByTagName("iframe")[0];
if (!iframe) return;
let doc = iframe.contentDocument;
if (!doc) {
return;
}
let doc = getIframeDoc();
if (!doc) return;
// navigate with mousewheel
window.addEventListener(
"keydown",

View File

@@ -1,5 +1,5 @@
import BookModel from "../model/Book";
import NoteModel from "../model/Note";
import BookModel from "../../model/Book";
import NoteModel from "../../model/Note";
class SearchUtil {
static MergeArray(arr1: number[], arr2: number[]) {
var _arr: number[] = [];
@@ -30,9 +30,9 @@ class SearchUtil {
return arr;
}
static MouseSearch(books: BookModel[]) {
let keyword = (document.querySelector(
".header-search-box"
) as HTMLInputElement).value.toLowerCase();
let keyword = (
document.querySelector(".header-search-box") as HTMLInputElement
).value.toLowerCase();
let bookNameArr: string[] = [];
let AuthorNameArr: string[] = [];
if (!books) return [];
@@ -68,9 +68,9 @@ class SearchUtil {
}
}
static MouseNoteSearch(notes: NoteModel[]) {
let keyword = (document.querySelector(
".header-search-box"
) as HTMLInputElement).value.toLowerCase();
let keyword = (
document.querySelector(".header-search-box") as HTMLInputElement
).value.toLowerCase();
let noteArr: string[] = [];
let textArr: string[] = [];
notes.forEach((item: NoteModel) => {

View File

@@ -1,5 +1,5 @@
import { restore } from "./restoreUtil";
import StorageUtil from "../storageUtil";
import StorageUtil from "../serviceUtils/storageUtil";
var Dropbox = (window as any).Dropbox;

View File

@@ -1,5 +1,5 @@
import { restore } from "./restoreUtil";
import StorageUtil from "../storageUtil";
import StorageUtil from "../serviceUtils/storageUtil";
class WebdavUtil {
static UploadFile = async (file: any) => {