diff --git a/package.json b/package.json index ca94655d..72fec202 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "koodo-reader", "main": "main.js", - "version": "1.9.9", + "version": "1.9.8", "description": "Koodo Reader is a cross-platform ebook reader", "author": { "name": "App by Troye", diff --git a/src/components/dialogs/updateDialog/component.tsx b/src/components/dialogs/updateDialog/component.tsx index 947608c5..7c0c7e45 100644 --- a/src/components/dialogs/updateDialog/component.tsx +++ b/src/components/dialogs/updateDialog/component.tsx @@ -45,7 +45,6 @@ class UpdateInfo extends React.Component { res = await checkDeveloperUpdate(); } const newVersion = res.version; - await sleep(500); if ( res.stable === "no" && @@ -89,6 +88,21 @@ class UpdateInfo extends React.Component {
Update to {" " + this.state.updateLog.version} +
+ {this.props.t( + this.state.updateLog.stable === "yes" + ? "Stable version" + : "Developer version" + )} +
{(this.props.isAuthed && this.state.updateLog.skippable === "yes") || @@ -143,28 +157,32 @@ class UpdateInfo extends React.Component { Download -
{ - ConfigService.setReaderConfig( - "skipVersion", - this.state.updateLog.version - ); - this.handleClose(); - }} - style={{ marginTop: 5 }} - > - Skip this version -
-
{ - ConfigService.setReaderConfig("updateChannel", "stable"); - this.handleClose(); - }} - > - Only receive stable version -
+ {this.state.updateLog.stable !== "yes" && ( +
{ + ConfigService.setReaderConfig( + "skipVersion", + this.state.updateLog.version + ); + this.handleClose(); + }} + style={{ marginTop: 5 }} + > + Skip this version +
+ )} + {this.state.updateLog.stable !== "yes" && ( +
{ + ConfigService.setReaderConfig("updateChannel", "stable"); + this.handleClose(); + }} + > + Only receive stable version +
+ )} {this.state.updateLog && ( <> diff --git a/src/components/dialogs/updateDialog/updateInfo.css b/src/components/dialogs/updateDialog/updateInfo.css index 85a5f902..e1a64f60 100644 --- a/src/components/dialogs/updateDialog/updateInfo.css +++ b/src/components/dialogs/updateDialog/updateInfo.css @@ -129,3 +129,16 @@ transition: 0.1s; font-size: 13px; } +.new-version-badge { + display: inline-block; + font-size: 12px; + font-weight: bold; + color: white; + margin-left: 10px; + height: 20px; + line-height: 20px; + border-radius: 5px; + padding: 0px 5px; + position: relative; + top: -2px; +} diff --git a/src/components/popups/popupRefer/component.tsx b/src/components/popups/popupRefer/component.tsx index 5a5b9efa..455f8bf2 100644 --- a/src/components/popups/popupRefer/component.tsx +++ b/src/components/popups/popupRefer/component.tsx @@ -4,7 +4,7 @@ import { PopupReferProps, PopupReferStates } from "./interface"; import { getIframeDoc } from "../../../utils/reader/docUtil"; import { getTargetHref, openExternalUrl } from "../../../utils/common"; import Parser from "html-react-parser"; -import DOMPurify from "dompurify"; + class PopupRefer extends React.Component { highlighter: any; timer!: NodeJS.Timeout; @@ -63,10 +63,44 @@ class PopupRefer extends React.Component { let node = doc.body.querySelector("#" + id); if (!node) return false; console.log("node", event.target.getBoundingClientRect()); + console.log(node.innerHTML, "innerHTML"); + //将html代码中的img标签由blob转换为base64 + let htmlContent = node.innerHTML; + + const convertBlobToDataURL = async (blobUrl) => { + const response = await fetch(blobUrl); + const blob = await response.blob(); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => resolve(reader.result); + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + }; + + const processHtml = async (html) => { + const parser = new DOMParser(); + const doc = parser.parseFromString(html, "text/html"); + const images: any[] = Array.from(doc.getElementsByTagName("img")); + for (const img of images) { + if (img.src && img.src.startsWith("blob:")) { + try { + const dataUrl = await convertBlobToDataURL(img.src); + img.src = dataUrl; + img.style.maxWidth = "100%"; // 确保图片不会超出容器宽度 + } catch (error) { + console.error("Error converting blob to data URL:", error); + } + } + } + return doc.body.innerHTML; + }; + + htmlContent = await processHtml(htmlContent); this.setState( { rect: event.target.getBoundingClientRect(), - footnote: node.innerHTML, + footnote: htmlContent, isOpenMenu: true, }, () => { @@ -185,8 +219,15 @@ class PopupRefer extends React.Component { className="popup-menu-container popup-ref-container" style={this.state.isOpenMenu ? {} : { display: "none" }} > -
- {Parser(DOMPurify.sanitize(this.state.footnote))} +
{ + this.handleLinkJump(event, this.props.rendition); + event.stopPropagation(); + event.preventDefault(); + }} + > + {Parser(this.state.footnote)}
diff --git a/src/components/popups/popupRefer/popupRefer.css b/src/components/popups/popupRefer/popupRefer.css index a276c93e..873a9d9c 100644 --- a/src/components/popups/popupRefer/popupRefer.css +++ b/src/components/popups/popupRefer/popupRefer.css @@ -3,4 +3,19 @@ max-height: 250px; padding: 20px; overflow: scroll; + overflow-x: hidden; + line-height: 1.25; +} +.popup-ref-box { + user-select: text; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; +} + +.popup-ref-box * { + user-select: text; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; } diff --git a/src/containers/settings/accountSetting/component.tsx b/src/containers/settings/accountSetting/component.tsx index af112207..e970503b 100644 --- a/src/containers/settings/accountSetting/component.tsx +++ b/src/containers/settings/accountSetting/component.tsx @@ -372,6 +372,7 @@ class AccountSetting extends React.Component< let userRequest = await getUserRequest(); let response = await userRequest.sendEmailCode({ email: this.state.loginConfig.email, + lang: ConfigService.getReaderConfig("lang"), }); if (response.code === 200) { toast.success(this.props.t("Send successfully"), { diff --git a/src/pages/login/component.tsx b/src/pages/login/component.tsx index 47f7c081..9cde558c 100644 --- a/src/pages/login/component.tsx +++ b/src/pages/login/component.tsx @@ -614,6 +614,7 @@ class Login extends React.Component { let userRequest = await getUserRequest(); let response = await userRequest.sendEmailCode({ email: this.state.loginConfig.email, + lang: ConfigService.getReaderConfig("lang"), }); if (response.code === 200) { toast.success(this.props.t("Send successfully"), { diff --git a/src/utils/file/bookUtil.ts b/src/utils/file/bookUtil.ts index 21ff98a7..0e37366f 100644 --- a/src/utils/file/bookUtil.ts +++ b/src/utils/file/bookUtil.ts @@ -356,9 +356,6 @@ class BookUtil { const { ipcRenderer } = window.require("electron"); let tokenConfig = await getCloudConfig(service); - toast.loading(i18n.t("Uploading book"), { - id: "upload-book", - }); let result = await ipcRenderer.invoke("cloud-upload", { ...tokenConfig, fileName: key + "." + format.toLowerCase(), @@ -372,18 +369,12 @@ class BookUtil { }); return; } - toast.success(i18n.t("Upload successful"), { - id: "upload-book", - }); } else { let syncUtil = await SyncService.getSyncUtil(); let bookBuffer: any = await this.fetchBook(key, format, true, ""); let bookBlob = new Blob([bookBuffer], { type: CommonTool.getMimeType(format.toLowerCase()), }); - toast.loading(i18n.t("Uploading book"), { - id: "upload-book", - }); let result = await syncUtil.uploadFile( key + "." + format.toLowerCase(), "book", @@ -395,9 +386,6 @@ class BookUtil { }); return; } - toast.success(i18n.t("Upload successful"), { - id: "upload-book", - }); } } static async deleteCloudBook(key: string, format: string) {