Update to 1.2.0

Former-commit-id: 9e1d3f0fa36a28da2bfb0de2532737d41290ce89
This commit is contained in:
troyeguo
2021-01-23 00:08:41 +08:00
parent c4e26ec525
commit 5a920b02f4
78 changed files with 1237 additions and 1045 deletions

View File

@@ -80,12 +80,18 @@
## 使用方法
桌面端:前往这里下载最新的安装包(技术原因暂不支持 Windows7 系统) [点我前往](https://koodo.960960.xyz/download)
桌面端:前往这里下载最新的安装包(暂不支持 Windows 7 系统) [点我前往](https://koodo.960960.xyz/download)
国内网络下载速度慢的解决办法复制下载链接到这个网站https://d.serctl.com/
网页版:代码托管在 Vercel [点我前往](https://reader.960960.xyz)
[Homebrew](https://brew.sh/)
```shell
brew install --cask koodo-reader
```
## 运行源码
请确保您电脑的 node 的版本大于 10.0.0,已配置好 yarngit 的运行环境。
@@ -112,8 +118,8 @@
## 后续更新
我会根据大家的反馈不定时更新,当有新版本更新时,Github 会自动向您的客户端推送提醒
我会根据大家的反馈不定时更新,当有新版本更新时,您将自动收到更新提示
## 帮助
您可以在 issue 区提问,或者通过邮箱 guo362429@gmail.com 与我取得联系
您可以在[issue](https://github.com/troyeguo/koodo-reader/issues)提问,或者前往[这里]("https://koodo.960960.xyz/support")了解更多。

View File

@@ -80,7 +80,7 @@
## Usage
Desktop : Download the latest software package(Windows7 is not supported yet) [Click me](https://koodo.960960.xyz/download)
Desktop : Download the latest software package(Windows 7 is not supported yet) [Click me](https://koodo.960960.xyz/download)
Install with [Homebrew](https://brew.sh/):
@@ -100,14 +100,14 @@ Make sure node's version on your computer is larger than 10.0.0, yarn and git is
git clone https://github.com/troyeguo/koodo-reader.git
```
2. Enter desktop version
2. Enter desktop mode
```
yarn
yarn dev
```
3. Enter web version
3. Enter web mode
```
yarn
@@ -116,8 +116,8 @@ Make sure node's version on your computer is larger than 10.0.0, yarn and git is
## Update
Whenever there is a update, a short message will show up in the software's header
When an update is available, you will receive a notification when you open the software.
## Help
Click [here](https://github.com/troyeguo/koodo-reader/issues) to report your issue, or contact me with guo362429@gmail.com
Click [here](https://github.com/troyeguo/koodo-reader/issues) to report your issue, or visit https://koodo.960960.xyz/support for help.

View File

@@ -34,7 +34,7 @@
}
.launching {
font-size: 19px;
font-weight: bold;
font-weight: 600;
line-height: 32px;
color: #000000;
margin-left: 10px;

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 266 KiB

View File

@@ -83,8 +83,8 @@ app.on("ready", () => {
} else {
dialog.showMessageBox({
type: "warning",
title: "Port is in use",
message: "Please don't open multiple software at the same time",
title: "Warning",
message: "Another Koodo Reader is already running",
});
}
});

View File

@@ -1,7 +1,7 @@
{
"name": "koodo-reader",
"main": "main.js",
"version": "1.1.9",
"version": "1.2.0",
"description": "A cross-platform open source Epub reader ",
"author": {
"name": "App by Troye",

83
public/assets/_empty.svg Normal file
View File

@@ -0,0 +1,83 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="987.234" height="565.416" viewBox="0 0 987.234 565.416">
<defs>
<linearGradient id="linear-gradient" x1="0.43" y1="0.005" x2="0.43" y2="0.577" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#dae0e6"/>
<stop offset="1" stop-color="#eff1f3"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="0.5" y1="1.739" x2="0.038" y2="-0.34" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#536db5" stop-opacity="0"/>
<stop offset="1" stop-color="#0e284b" stop-opacity="0.212"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="1.146" y1="1" x2="0.038" y2="-0.34" xlink:href="#linear-gradient-2"/>
</defs>
<g id="组_664" data-name="组 664" transform="translate(-295.755 -235)">
<path id="Rectangle_Copy" data-name="Rectangle Copy" d="M924.7,139.541s5.11,66.414,0,195.94c-54.321,0-473.383,1.025-757.763,0-130.459.181-114.97.147-172,0s-55.024.014-55.2,0c34-94.858,111.065-117.526,141.341-136.925,37.1-23.772,186.425-66.258,276.359-88.634S458.856,26.1,570.367,3.674C663.653-15.09,720.693,41.121,859,101.9,914.256,126.178,924.7,139.541,924.7,139.541Z" transform="translate(356.019 464.479)" opacity="0.61" fill="url(#linear-gradient)"/>
<g id="shadow" transform="translate(1382.42 711.827) rotate(180)">
<path id="shadow-2" data-name="shadow" d="M0,17.362l166.231,9.463V2.158L11.279,7.283Z" transform="translate(268.27 26.847) rotate(180)" fill="url(#linear-gradient-2)" style="mix-blend-mode: multiply;isolation: isolate"/>
<path id="shadow-3" data-name="shadow" d="M0,17.362l165.85,9.485V2.158L6.973,7.283Z" transform="translate(268.27 26.847) rotate(180)" fill="rgba(216,216,216,0.08)" style="mix-blend-mode: darken;isolation: isolate"/>
</g>
<g id="shadow-4" data-name="shadow" transform="translate(1068.709 696.823) rotate(180)">
<ellipse id="shadow-5" data-name="shadow" cx="28.937" cy="3.472" rx="28.937" ry="3.472" transform="translate(57.875 6.944) rotate(180)" fill="url(#linear-gradient-3)" style="mix-blend-mode: multiply;isolation: isolate"/>
<ellipse id="shadow-6" data-name="shadow" cx="28.937" cy="3.472" rx="28.937" ry="3.472" transform="translate(57.875 6.944) rotate(180)" fill="rgba(216,216,216,0.08)" style="mix-blend-mode: darken;isolation: isolate"/>
</g>
<path id="Path_39" data-name="Path 39" d="M14.468,6.443a37.827,37.827,0,0,1,4.573,24.593c-2.287,13.934-2,34.451-2,34.451H9.461L0,3.373S10.745-.688,14.468.1,14.468,6.443,14.468,6.443Z" transform="translate(1179.929 626.963)" fill="#9ea4b8"/>
<path id="Path_39_Copy" data-name="Path 39 Copy" d="M14.468,11.386a37.827,37.827,0,0,1,4.573,24.593c-2.287,13.934-2,34.451-2,34.451H9.461L0,8.316,17.552,0Z" transform="translate(1142.736 620.824) rotate(13)" fill="#9ea4b8"/>
<path id="Rectangle_17" data-name="Rectangle 17" d="M27.444,2.8,18.17,0,11.934,2.8l-8.779.914a3.472,3.472,0,0,0-2.979,2.5h0a4.6,4.6,0,0,0,4.409,5.845H22.814a4.629,4.629,0,0,0,4.629-4.629Z" transform="translate(1169.747 689.395)" fill="#302c48"/>
<path id="Rectangle_17_Copy" data-name="Rectangle 17 Copy" d="M27.444,2.8,18.17,0,11.934,2.8l-8.779.914a3.472,3.472,0,0,0-2.979,2.5h0a4.6,4.6,0,0,0,4.409,5.845H22.814a4.629,4.629,0,0,0,4.629-4.629Z" transform="translate(1116.502 689.395)" fill="#302c48"/>
<path id="Path_31" data-name="Path 31" d="M62.628,62.167V0H7.125L0,62.167H25.335l7.8-32.008,5.5,32.008Z" transform="translate(1136.878 570.678)" fill="#302c48"/>
<path id="Path_32" data-name="Path 32" d="M0,70.14C12.567,58.262,12.871,58.6,18.387,51.149c2.633-3.558,5.661-6.342,5.5-6.761C21.431,38.182,12.983,31.253,0,14.494L7.807,0C26.758,18.166,32.49,31.727,35.371,39.02c.7,1.767,1.927,4.976,1.613,7.052C35.6,55.212,23.25,65.773.853,77.662Z" transform="matrix(0.995, -0.105, 0.105, 0.995, 1190.725, 483.355)" fill="#9ea4b8"/>
<g id="single_thread" data-name="single thread" transform="translate(1097.346 686.539) rotate(180)">
<path id="Path_36" data-name="Path 36" d="M11.153,12.624S3.6,3.525,2.906.532C1.254-1.41,0,2.587,0,2.587S4.581,21.959,9.147,25.046s4.565,0,4.565,0Z" transform="translate(26.883 208.789) rotate(180)" fill="#9ea4b8"/>
<path id="Path_37" data-name="Path 37" d="M6.567,205.841c-13.143-18.431-7.175-55.829,23.5-93.621S92.989,33.876,54.24,8.415C42.018.384,20.284-4.075,3.095,5.149" transform="translate(72.016 205.841) rotate(180)" fill="none" stroke="#cdd4e0" stroke-miterlimit="10" stroke-width="1.8"/>
<path id="Path_35" data-name="Path 35" d="M3.706,20.974c2.721.651,4.213-9.617,1.492-11.5S3.768-.343,1.467.012.289,3.411.177,5.584.985,20.323,3.706,20.974Z" transform="translate(17.095 202.544) rotate(180)" fill="#9ea4b8"/>
</g>
<path id="Path_32_Copy" data-name="Path 32 Copy" d="M0,70.14C12.567,58.262,12.871,58.6,18.387,51.149c2.633-3.558,5.661-6.342,5.5-6.761C21.431,38.182,12.983,31.253,0,14.494L7.807,0C26.758,18.166,32.49,31.727,35.371,39.02,39.143,48.57,28.336,63.074.853,77.662Z" transform="translate(1156.074 491.021) rotate(82)" fill="#9ea4b8"/>
<path id="Path_33" data-name="Path 33" d="M11.692,0S11.939,4.47,8.8,6.959C5.3,9.737,1.384,12.948.48,14.1-1.234,16.27,2.194,16.27,2.194,16.27L.48,30.311l14.26,6.381L11.692,48.578H28.776l2.151-11.887s-4.973-22.321-8.106-28.3C18.576.3,11.692,0,11.692,0Z" transform="translate(1157.71 429.263)" fill="#9ea4b8"/>
<path id="Oval_8" data-name="Oval 8" d="M15.756,49.185c-7.26,0-8.271-8.555-12.515-14.11C.011,30.847,0,27.269,0,21.4,0,7.818,2.971,0,15.756,0s23.15,11.01,23.15,24.592S23.8,43.24,15.756,49.185Z" transform="translate(1171.017 417.337)" fill="#302c48"/>
<ellipse id="Oval" cx="8.102" cy="7.522" rx="8.102" ry="7.522" transform="translate(1172.883 414.444)" fill="#302c48"/>
<ellipse id="Oval_Copy" data-name="Oval Copy" cx="5.209" cy="4.836" rx="5.209" ry="4.836" transform="translate(1184.458 414.444)" fill="#302c48"/>
<ellipse id="Oval_Copy_2" data-name="Oval Copy 2" cx="8.102" cy="7.522" rx="8.102" ry="7.522" transform="translate(1190.246 419.073)" fill="#302c48"/>
<ellipse id="Oval_Copy_6" data-name="Oval Copy 6" cx="8.102" cy="7.522" rx="8.102" ry="7.522" transform="translate(1194.876 427.174)" fill="#302c48"/>
<ellipse id="Oval_Copy_3" data-name="Oval Copy 3" cx="4.051" cy="3.761" rx="4.051" ry="3.761" transform="translate(1192.561 416.758)" fill="#302c48"/>
<ellipse id="Oval_Copy_4" data-name="Oval Copy 4" cx="4.051" cy="3.761" rx="4.051" ry="3.761" transform="translate(1169.411 419.073)" fill="#302c48"/>
<ellipse id="Oval_Copy_5" data-name="Oval Copy 5" cx="4.051" cy="3.761" rx="4.051" ry="3.761" transform="translate(1167.096 424.859)" fill="#302c48"/>
<ellipse id="Oval_2" data-name="Oval 2" cx="4.63" cy="5.208" rx="4.63" ry="5.208" transform="translate(1167.096 442.219)" fill="#9ea4b8"/>
<path id="Path_30" data-name="Path 30" d="M92.413,27.082,67.785,4.247S55.934,0,48.224,0h-11.4C32,0,18.195,4.247,18.195,4.247L0,27.082l11.549,16.4,12.633-16.4-14.09,78.261s14.3,4.767,26.736,4.767,30.957-4.629,30.957-4.629V32.657l9.1,10.82Z" transform="translate(1132.132 474.623)" fill="#fcfcfc"/>
<path id="Path_34" data-name="Path 34" d="M5.431,44.328,4.061,0,0,12.311Z" transform="translate(1170.112 588.604)" fill="#3b3c45" opacity="0.195" style="mix-blend-mode: multiply;isolation: isolate"/>
<path id="Path_38" data-name="Path 38" d="M0,50.671,14.863,0s-6.1,1.908-6.442,4.355S0,50.671,0,50.671Z" transform="translate(1147.833 497.706)" fill="#deeaf4" opacity="0.55" style="mix-blend-mode: multiply;isolation: isolate"/>
<g id="Thread" transform="translate(1046.717 694.508) rotate(180)">
<ellipse id="Oval_9_Copy" data-name="Oval 9 Copy" cx="4.051" cy="10.416" rx="4.051" ry="10.416" transform="translate(33.567 21.989) rotate(180)" fill="#302c48"/>
<rect id="Rectangle" width="25.465" height="15.045" transform="translate(28.937 18.517) rotate(180)" fill="#302c48"/>
<path id="Rectangle_Copy-2" data-name="Rectangle Copy" d="M12.732,0H2.315S0,2.487,0,7.416a12.284,12.284,0,0,0,2.315,7.629H12.732a14.017,14.017,0,0,1-2.315-7.2A17.951,17.951,0,0,1,12.732,0Z" transform="translate(24.307 18.517) rotate(180)" fill="#fff"/>
<ellipse id="Oval_9" data-name="Oval 9" cx="4.051" cy="11.573" rx="4.051" ry="11.573" transform="translate(8.102 23.146) rotate(180)" fill="#686b89"/>
</g>
<g id="Kite" transform="translate(993.463 393.948) rotate(180)">
<g id="Group_6" data-name="Group 6" transform="matrix(0.883, -0.469, 0.469, 0.883, 56.551, 113.53)">
<path id="Combined_Shape" data-name="Combined Shape" d="M0,0V24.41H16.529Z" transform="translate(16.529 51.438) rotate(180)" fill="#52556e"/>
<path id="Rectangle_18_Copy" data-name="Rectangle 18 Copy" d="M16.529,0V24.41H0Z" transform="translate(35.281 51.438) rotate(180)" fill="#9ea4b8"/>
<path id="Rectangle_18_Copy_3" data-name="Rectangle 18 Copy 3" d="M16.529,0V24.41H0Z" transform="translate(0 0)" fill="#9ea4b8"/>
<path id="Rectangle_18_Copy_2" data-name="Rectangle 18 Copy 2" d="M0,0V24.41H16.529Z" transform="translate(18.752 0)" fill="#52556e"/>
</g>
<g id="Group_9" data-name="Group 9" transform="translate(56.359 129.838)">
<path id="Triangle_2" data-name="Triangle 2" d="M3.646,0,0,9.356H7.293Z" transform="translate(7.181 5.062) rotate(25)" fill="#52556e"/>
<path id="Triangle_2_Copy_7" data-name="Triangle 2 Copy 7" d="M3.646,0,7.293,9.356H0Z" transform="translate(10.757 2.105) rotate(103)" fill="#9ea4b8"/>
</g>
<g id="Group_8" data-name="Group 8" transform="matrix(-1, 0.017, -0.017, -1, 111.023, 125.412)">
<path id="Triangle_2_Copy_9" data-name="Triangle 2 Copy 9" d="M3.646,0,0,9.356H7.293Z" transform="translate(7.181 5.062) rotate(25)" fill="#52556e"/>
<path id="Triangle_2_Copy_8" data-name="Triangle 2 Copy 8" d="M3.646,0,7.293,9.356H0Z" transform="translate(10.757 2.105) rotate(103)" fill="#9ea4b8"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(61.224 0)">
<path id="Path_41" data-name="Path 41" stroke="#fff" d="M30.055,0c0,3.984,9.7,21.376-15.555,43.447s-12.37,50.917,0,60.569" fill="none" transform="translate(40.847 104.016) rotate(180)" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="3.24" opacity="0.7"/>
<path id="Triangle_2-2" data-name="Triangle 2" d="M3.646,0,0,9.356H7.293Z" transform="matrix(-0.602, 0.799, -0.799, -0.602, 11.861, 83.405)" fill="#52556e"/>
<path id="Triangle_2_Copy_7-2" data-name="Triangle 2 Copy 7" d="M3.646,0,7.293,9.356H0Z" transform="matrix(0.588, -0.809, 0.809, 0.588, 7.295, 87.86)" fill="#9ea4b8"/>
<path id="Triangle_2_Copy" data-name="Triangle 2 Copy" d="M3.646,0,0,9.356H7.293Z" transform="translate(24.755 63.33) rotate(155)" fill="#9ea4b8"/>
<path id="Triangle_2_Copy_6" data-name="Triangle 2 Copy 6" d="M3.646,0,7.293,9.356H0Z" transform="matrix(0.914, -0.407, 0.407, 0.914, 18.411, 66.157)" fill="#52556e"/>
<path id="Triangle_2_Copy_2" data-name="Triangle 2 Copy 2" d="M3.646,0,0,9.356H7.293Z" transform="translate(40.715 37.911) rotate(109)" fill="#52556e"/>
<path id="Triangle_2_Copy_5" data-name="Triangle 2 Copy 5" d="M3.646,0,7.293,9.356H0Z" transform="matrix(0.407, -0.914, 0.914, 0.407, 37.683, 44.383)" fill="#9ea4b8"/>
<path id="Triangle_2_Copy_3" data-name="Triangle 2 Copy 3" d="M3.646,0,0,9.356H7.293Z" transform="translate(35.635 10.22) rotate(76)" fill="#9ea4b8"/>
<path id="Triangle_2_Copy_4" data-name="Triangle 2 Copy 4" d="M3.646,0,7.293,9.356H0Z" transform="translate(37.156 16.999) rotate(-97)" fill="#52556e"/>
</g>
<path id="Path_40" data-name="Path 40" d="M82.34,85.36c-15.2-.889-38.511-9.777-44.068-38.656S17.838,3.77,0,0" transform="translate(82.34 127.666) rotate(180)" fill="none" stroke="#cdd4e0" stroke-miterlimit="10" stroke-width="1.62"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,24 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="987.234" height="565.416" viewBox="0 0 987.234 565.416">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1371.37" height="565.416" viewBox="0 0 1371.37 565.416">
<defs>
<linearGradient id="linear-gradient" x1="0.43" y1="0.005" x2="0.43" y2="0.577" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#dae0e6"/>
<stop offset="1" stop-color="#eff1f3"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="0.5" y1="1.739" x2="0.038" y2="-0.34" gradientUnits="objectBoundingBox">
<linearGradient id="linear-gradient-2" x1="1.146" y1="1" x2="0.038" y2="-0.34" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#536db5" stop-opacity="0"/>
<stop offset="1" stop-color="#0e284b" stop-opacity="0.212"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="1.146" y1="1" x2="0.038" y2="-0.34" xlink:href="#linear-gradient-2"/>
</defs>
<g id="组_664" data-name="组 664" transform="translate(-295.755 -235)">
<path id="Rectangle_Copy" data-name="Rectangle Copy" d="M924.7,139.541s5.11,66.414,0,195.94c-54.321,0-473.383,1.025-757.763,0-130.459.181-114.97.147-172,0s-55.024.014-55.2,0c34-94.858,111.065-117.526,141.341-136.925,37.1-23.772,186.425-66.258,276.359-88.634S458.856,26.1,570.367,3.674C663.653-15.09,720.693,41.121,859,101.9,914.256,126.178,924.7,139.541,924.7,139.541Z" transform="translate(356.019 464.479)" opacity="0.61" fill="url(#linear-gradient)"/>
<g id="shadow" transform="translate(1382.42 711.827) rotate(180)">
<path id="shadow-2" data-name="shadow" d="M0,17.362l166.231,9.463V2.158L11.279,7.283Z" transform="translate(268.27 26.847) rotate(180)" fill="url(#linear-gradient-2)" style="mix-blend-mode: multiply;isolation: isolate"/>
<path id="shadow-3" data-name="shadow" d="M0,17.362l165.85,9.485V2.158L6.973,7.283Z" transform="translate(268.27 26.847) rotate(180)" fill="rgba(216,216,216,0.08)" style="mix-blend-mode: darken;isolation: isolate"/>
</g>
<g id="shadow-4" data-name="shadow" transform="translate(1068.709 696.823) rotate(180)">
<ellipse id="shadow-5" data-name="shadow" cx="28.937" cy="3.472" rx="28.937" ry="3.472" transform="translate(57.875 6.944) rotate(180)" fill="url(#linear-gradient-3)" style="mix-blend-mode: multiply;isolation: isolate"/>
<ellipse id="shadow-6" data-name="shadow" cx="28.937" cy="3.472" rx="28.937" ry="3.472" transform="translate(57.875 6.944) rotate(180)" fill="rgba(216,216,216,0.08)" style="mix-blend-mode: darken;isolation: isolate"/>
<g id="组_763" data-name="组 763" transform="translate(-295.755 -235)">
<path id="Rectangle_Copy" data-name="Rectangle Copy" d="M1311.106,335.481H924.7c-54.321,0-473.383,1.025-757.763,0-130.459.181-114.97.147-172,0s-55.024.014-55.2,0c34-94.858,111.065-117.526,141.341-136.925,37.1-23.772,186.425-66.258,276.359-88.634S458.856,26.1,570.367,3.674C663.653-15.09,760.674,41.28,889.9,132.376c106.941,77.594,154.175,95.475,273.271,129.213S1311.106,335.481,1311.106,335.481Z" transform="translate(356.019 464.479)" opacity="0.61" fill="url(#linear-gradient)"/>
<g id="shadow" transform="translate(1068.709 696.823) rotate(180)">
<ellipse id="shadow-2" data-name="shadow" cx="28.937" cy="3.472" rx="28.937" ry="3.472" transform="translate(57.875 6.944) rotate(180)" fill="url(#linear-gradient-2)" style="mix-blend-mode: multiply;isolation: isolate"/>
<ellipse id="shadow-3" data-name="shadow" cx="28.937" cy="3.472" rx="28.937" ry="3.472" transform="translate(57.875 6.944) rotate(180)" fill="rgba(216,216,216,0.08)" style="mix-blend-mode: darken;isolation: isolate"/>
</g>
<path id="Path_39" data-name="Path 39" d="M14.468,6.443a37.827,37.827,0,0,1,4.573,24.593c-2.287,13.934-2,34.451-2,34.451H9.461L0,3.373S10.745-.688,14.468.1,14.468,6.443,14.468,6.443Z" transform="translate(1179.929 626.963)" fill="#9ea4b8"/>
<path id="Path_39_Copy" data-name="Path 39 Copy" d="M14.468,11.386a37.827,37.827,0,0,1,4.573,24.593c-2.287,13.934-2,34.451-2,34.451H9.461L0,8.316,17.552,0Z" transform="translate(1142.736 620.824) rotate(13)" fill="#9ea4b8"/>
@@ -67,7 +62,7 @@
<path id="Triangle_2_Copy_8" data-name="Triangle 2 Copy 8" d="M3.646,0,7.293,9.356H0Z" transform="translate(10.757 2.105) rotate(103)" fill="#9ea4b8"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(61.224 0)">
<path id="Path_41" data-name="Path 41" stroke="#fff" d="M30.055,0c0,3.984,9.7,21.376-15.555,43.447s-12.37,50.917,0,60.569" fill="none" transform="translate(40.847 104.016) rotate(180)" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="3.24" opacity="0.7"/>
<path id="Path_41" data-name="Path 41" d="M30.055,0c0,3.984,9.7,21.376-15.555,43.447s-12.37,50.917,0,60.569" transform="translate(40.847 104.016) rotate(180)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="3.24" opacity="0.7"/>
<path id="Triangle_2-2" data-name="Triangle 2" d="M3.646,0,0,9.356H7.293Z" transform="matrix(-0.602, 0.799, -0.799, -0.602, 11.861, 83.405)" fill="#52556e"/>
<path id="Triangle_2_Copy_7-2" data-name="Triangle 2 Copy 7" d="M3.646,0,7.293,9.356H0Z" transform="matrix(0.588, -0.809, 0.809, 0.588, 7.295, 87.86)" fill="#9ea4b8"/>
<path id="Triangle_2_Copy" data-name="Triangle 2 Copy" d="M3.646,0,0,9.356H7.293Z" transform="translate(24.755 63.33) rotate(155)" fill="#9ea4b8"/>
@@ -79,5 +74,9 @@
</g>
<path id="Path_40" data-name="Path 40" d="M82.34,85.36c-15.2-.889-38.511-9.777-44.068-38.656S17.838,3.77,0,0" transform="translate(82.34 127.666) rotate(180)" fill="none" stroke="#cdd4e0" stroke-miterlimit="10" stroke-width="1.62"/>
</g>
<g id="shadow-4" data-name="shadow" transform="translate(1296.024 708.416) rotate(180)">
<ellipse id="shadow-5" data-name="shadow" cx="91.095" cy="6.269" rx="91.095" ry="6.269" transform="translate(182.19 12.537) rotate(180)" fill="url(#linear-gradient-2)" style="mix-blend-mode: multiply;isolation: isolate"/>
<ellipse id="shadow-6" data-name="shadow" cx="91.095" cy="6.269" rx="91.095" ry="6.269" transform="translate(182.19 12.537) rotate(180)" fill="rgba(216,216,216,0.08)" style="mix-blend-mode: darken;isolation: isolate"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -41,7 +41,7 @@
}
.launching {
font-size: 19px;
font-weight: bold;
font-weight: 600;
line-height: 32px;
color: #000000;
margin-left: 10px;
@@ -93,10 +93,12 @@
</div>
<script>
let words = [
"悲伤的情绪是一张向两面观望着的脸,一面朝着恐怖,一面朝着怜悯,而这两者都不过是它的两个不同的阶段。",
"我曾努力过,去爱上帝。他最后说道。不过现在看来,我失败了。那样做很难。我曾努力一点一点地把自己的意志同上帝的意志结合起来,也不是完全没有办到,或许我会继续这么做。",
"我几乎没有耐心来严肃地生活,既然这正儿八经的生活挡在我和我的愿望中间,那在我看来它就好像是儿戏,丑陋单调的儿戏。",
"我除了几句日常客气话,再没有对她说过什么,可是她的名字却像一声呼唤,会调动我全身血液喷发愚蠢的激情。",
"人类一向有这个独特之处:它保留了两套法则——一套私下的,一套真正的;一套公开的,一套矫揉造作的。",
"人类中绝大多数人,不论是野蛮的或是文明的,在暗地里都是心地善良和畏畏缩缩地不敢叫人受苦的人,可是当着一小撮专事侵略和残酷无情的人面前,他们就不敢固执己见。",
"如果你照顾一只肚子饿的狗,给它食物,让它过好日子,这只狗绝对不会反咬你一口,这就是狗与人类最主要的不同。",
"跳舞,像没有人看着那样;热恋,像从未受伤一样;唱歌,像无人听着那样;活着,就把人间当天堂。",
"这些贵妇仿佛一大片花海,五光十色,灿烂耀眼,她们身上的钻石熠熠生辉,连成一片,仿佛天上的银河。",
"永远要像你不需要金钱那样地工作,永远要像你不曾被伤害过那样地爱,永远要像没有人在注视你那样地跳舞,永远要像在天堂那样地生活。",
];
let number = Math.floor(Math.random() * words.length);
let word = words[number];

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 266 KiB

View File

@@ -5,7 +5,7 @@
<link rel="icon" href="%PUBLIC_URL%/favicon.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link
href="https://fonts.googleapis.com/css?family=Noto+Sans+TC"
href="https://fonts.googleapis.com/css?family=Noto+Sans+TC:400,500,600"
rel="stylesheet"
/>
<link rel="dns-prefetch" href="https://reader.960960.xyz" />
@@ -19,19 +19,16 @@
itemprop="description"
content="Koodo Reader is a open-source epub reader with backup and restore support, runs on Windows, Mac and Web"
/>
<script
async
src="https://www.googletagmanager.com/gtag/js?id=G-P4ZLVVECVF"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-P4ZLVVECVF");
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?358570be1bfc40e01db43adefade5ad5";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<style>
#root {
height: 100%;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,8 @@
"This action will clear and remove this shelf": "此操作会清空并删除此书架",
"Scale": "页面缩放",
"Delete this tag": "删除此标签",
"Don't show footer and header": "不显示页眉页脚",
"Don't show footer": "不显示页脚",
"Don't show header": "不显示页眉",
"Default expand all content": "默认展开所有目录",
"This action will clear and remove this tag": "此操作会清空并删除此标签",
"Dont't use mimical background": "不使用仿真背景",
@@ -33,7 +34,7 @@
"Current Font Size": "当前大小",
"Import from Local": "从本地导入",
"Backup and Restore": "备份和恢复",
"Search My Library": "搜索我的书库",
"Search my library": "搜索我的书库",
"Card Mode": "卡片模式",
"List Mode": "列表模式",
"Work": "工作学习",
@@ -110,6 +111,8 @@
"Chapter Scroll": "分章滚动",
"Turn off audio": "关闭听书",
"Search the book": "全书搜索",
"Search my notes": "搜索我的笔记",
"Search my digests": "搜索我的书摘",
"Book size is over 20M": "图书大小超过20兆",
"Wrong bookmark": "书签出问题了",
"Last Step": "上一步",

View File

@@ -6,7 +6,7 @@
"My Favorites": "Favorites",
"My Notes": "Notes",
"My Digests": "Digests",
"My Shelves": "Shelves",
"My Shelves": "Shelf",
"Sort": "Sort",
"Import Failed": "Import Failed",
"New Version Available": "New Version Available",
@@ -18,7 +18,9 @@
"Uploading": "Uploading, please wait",
"Import from Local": "Import from Local",
"Backup and Restore": "Backup and Restore",
"Search My Library": "Search My Library",
"Search my library": "Search my library",
"Search my notes": "Search my notes",
"Search my digests": "Search my digests",
"Card Mode": "Card",
"List Mode": "List",
"Work": "Work",
@@ -60,10 +62,10 @@
"Edit Book": "Edit Book",
"Edit Successfully": "Edit Successfully",
"Book Name": "Name",
"Sort by Date": "by Date",
"Sort by Date": "Date",
"Descending Order": "Descend",
"Ascending Order": "Ascend",
"Sort by Name": "by Name",
"Sort by Name": "Name",
"Bind": "Bind",
"Token": "Token",
"Book not exsit": "Book not exsit",
@@ -82,8 +84,8 @@
"Do you want to backup or restore?": "Do You Want To Backup Or Restore?",
"Where is your data?": "Where is your data?",
"Where to keep your data?": "Where to keep your data?",
"I want to backup": "I want to backup",
"I want to restore": "I want to restore",
"I want to backup": "Backup",
"I want to restore": "Restore",
"Delete this shelf": "Delete this shelf",
"This action will clear and remove this shelf": "This action will clear and remove this shelf",
"Delete this tag": "Delete this tag",
@@ -99,7 +101,8 @@
"Scale": "Page Scale",
"Digest": "Digest",
"Default expand all content": "Default expand all content",
"Don't show footer and header": "Hide footer and header",
"Don't show footer": "Hide footer",
"Don't show header": "Hide header",
"Book size is over 20M": "Book size is over 20M",
"Current Font Size": "Current Font Size",
"Current Chapter": "Current Chapter",
@@ -151,7 +154,7 @@
"More Notes": "More Notes",
"Pick Up Color": "Pick Up Color",
"Highlight Successfully": "Highlight Successfully",
"Take Notes": "Take Notes",
"Take Notes": "Note",
"Highlight": "Highlight",
"Copy Successfully": "Copy Successfully",
"Copy ": "Copy",
@@ -160,11 +163,11 @@
"Restore": "Restore",
"Deleted Books": "Deleted",
"Delete All Books": "Delete All Books",
"Sort by Duration": "by Duration",
"Sort by Author": "by Author",
"Sort by Duration": "Duration",
"Sort by Author": "Author",
"Audio is not ready yet": "Audio is not ready yet",
"Drop your books here": "Drop your books here",
"Sort by Percentage": "by Percentage",
"Sort by Percentage": "Percentage",
"This action will remove all the books in recycle bin,together with their notes, bookmarks and digests": "This action will permanently remove all the books in recycle bin,together with their notes, bookmarks and digests",
"Batch import only support epub or pdf files": "Batch import only support epub or pdf files",
"Drag any book to the Deleted tab to add it to Recycle Bin": "Drag any book to the Deleted tab to add it to Recycle Bin",

View File

@@ -18,7 +18,7 @@
"Uploading": "上傳中,請稍候",
"Import from Local": "從本機導入",
"Backup and Restore": "備份和還原",
"Search My Library": "搜尋我的書庫",
"Search my library": "搜尋我的書庫",
"Card Mode": "卡片模式",
"List Mode": "列表模式",
"More Digests": "顯示書摘出處",
@@ -181,7 +181,8 @@
"This action will clear and remove this tag": "此操作会清空并删除此标签",
"Scale": "页面缩放",
"Next Chapter": "下一章",
"Don't show footer and header": "不显示页眉页脚",
"Don't show footer": "不显示页脚",
"Don't show header": "不显示页眉",
"Default expand all content": "默认展开所有目录",
"Prev Chapter": "上一章",
"Current Reading Time": "本次阅读时间:{{count}}分钟",
@@ -209,6 +210,7 @@
"Drop your books here": "拖拽图书到此处",
"Export": "导出",
"Text Color": "文字颜色",
"Search my notes": "搜索我的笔记",
"Search my digests": "搜索我的书摘",
"Sort by Percentage": "按阅读进度"
}

View File

Binary file not shown.

View File

@@ -46,7 +46,7 @@
<glyph unicode="&#xe933;" glyph-name="fullscreen" d="M930.902 960c51.351-0.118 92.933-41.773 92.933-93.14 0 0 0 0 0 0v0-837.762c-0.118-51.278-41.655-92.815-92.921-92.933h-837.773c0 0 0 0 0 0-51.367 0-93.022 41.582-93.14 92.921v837.773c0 51.44 41.7 93.14 93.14 93.14v0zM599.876 103.627l258.528-2.073-2.073 258.528-93.927 0.705 0.87-98.28-150.549 150.591-65.824-65.824 150.591-150.549-98.28 0.87 0.705-93.927zM421.637 795.026l-258.736 2.073 2.073-258.528 93.927-0.705-0.87 98.28 150.591-150.591 65.824 65.824-150.591 150.591 98.28-0.87-0.663 93.927z" />
<glyph unicode="&#xe934;" glyph-name="googledrive" horiz-adv-x="1212" d="M404.326 941.271l-404.305-716.399 214.37-286.638 409.383 621.627-219.449 381.409zM1210.918 240.151h-762.819l-205.408-304.151h843.441l124.785 304.151zM807.416 958.98l-369.907 1.020 392.89-690.942 381.518 1.020-404.522 688.924zM807.459 958.98l-369.907 1.020 392.846-690.942 381.518 1.020-404.457 688.902z" />
<glyph unicode="&#xe937;" glyph-name="list" d="M160 224h-128c-17.673 0-32-14.327-32-32v0-128c0-17.673 14.327-32 32-32v0h128c17.673 0 32 14.327 32 32v0 128c0 17.673-14.327 32-32 32v0zM160 864h-128c-17.673 0-32-14.327-32-32v0-128c0-17.673 14.327-32 32-32v0h128c17.673 0 32 14.327 32 32v0 128c0 17.673-14.327 32-32 32v0zM160 544h-128c-17.673 0-32-14.327-32-32v0-128c0-17.673 14.327-32 32-32v0h128c17.673 0 32 14.327 32 32v0 128c0 17.673-14.327 32-32 32v0zM992 192h-640c-17.673 0-32-14.327-32-32v0-64c0-17.673 14.327-32 32-32v0h640c17.673 0 32 14.327 32 32v0 64c0 17.673-14.327 32-32 32v0zM992 832h-640c-17.673 0-32-14.327-32-32v0-64c0-17.673 14.327-32 32-32v0h640c17.673 0 32 14.327 32 32v0 64c0 17.673-14.327 32-32 32v0zM992 512h-640c-17.673 0-32-14.327-32-32v0-64c0-17.673 14.327-32 32-32v0h640c17.673 0 32 14.327 32 32v0 64c0 17.673-14.327 32-32 32v0z" />
<glyph unicode="&#xe938;" glyph-name="more" d="M4.684 446.491c0-62.26 50.472-112.732 112.732-112.732s112.732 50.472 112.732 112.732v0c0 62.26-50.472 112.732-112.732 112.732s-112.732-50.472-112.732-112.732v0zM399.249 446.491c0-62.26 50.472-112.732 112.732-112.732s112.732 50.472 112.732 112.732v0c0 62.26-50.472 112.732-112.732 112.732s-112.732-50.472-112.732-112.732v0zM793.815 446.491c0-62.26 50.472-112.732 112.732-112.732s112.732 50.472 112.732 112.732v0c0 62.26-50.472 112.732-112.732 112.732s-112.732-50.472-112.732-112.732v0z" />
<glyph unicode="&#xe938;" glyph-name="more" d="M513.509-59.316c62.26 0 112.732 50.472 112.732 112.732s-50.472 112.732-112.732 112.732v0c-62.26 0-112.732-50.472-112.732-112.732s50.472-112.732 112.732-112.732v0zM513.509 335.249c62.26 0 112.732 50.472 112.732 112.732s-50.472 112.732-112.732 112.732v0c-62.26 0-112.732-50.472-112.732-112.732s50.472-112.732 112.732-112.732v0zM513.509 729.815c62.26 0 112.732 50.472 112.732 112.732s-50.472 112.732-112.732 112.732v0c-62.26 0-112.732-50.472-112.732-112.732s50.472-112.732 112.732-112.732v0z" />
<glyph unicode="&#xe939;" glyph-name="bookmark" d="M149.847 960v-1024l362.153 249.752 362.153-249.752v1024z" />
<glyph unicode="&#xe93a;" glyph-name="shelf" d="M314.343-36.583h235.688v942.524h-235.688zM392.906 630.994h78.563v-392.768h-78.563zM860.747 931.838l-232.153-40.957 164.013-928.152 232.153 41.049zM753.808 633.887l77.369 13.775 68.369-386.707-77.369-13.775zM0-33.139h235.734v942.524h-235.734zM78.563 634.438h78.563v-392.492h-78.563z" />
<glyph unicode="&#xe93b;" glyph-name="idea" d="M487.345 959.079c-181.191-13.547-323.069-163.888-323.069-347.365 0-86.92 31.841-166.403 84.495-227.421l-0.378 0.448c39.112-44.631 66.291-100.639 76.011-162.444l0.237-1.833c2.832-20.078 19.89-35.358 40.52-35.38h293.752c20.633 0.022 37.69 15.302 40.497 35.163l0.025 0.217c9.286 63.089 36.102 118.686 75.279 163.124l-0.297-0.343c52.895 60.769 85.139 140.726 85.139 228.214 0 192.434-155.999 348.432-348.432 348.432-8.367 0-16.666-0.295-24.886-0.875l1.106 0.063zM510.906 816.521c-107.672-0.338-195.763-83.713-203.608-189.425l-0.040-0.677c0.032-0.43 0.050-0.931 0.050-1.437 0-11.317-9.174-20.492-20.492-20.492s-20.492 9.174-20.492 20.492c0 1.806 0.234 3.557 0.672 5.225l-0.032-0.143c9.817 127.647 115.785 227.509 245.087 227.556h0.005c11.092-0.321 19.962-9.389 19.962-20.53 0-11.343-9.195-20.538-20.538-20.538-0.202 0-0.404 0.003-0.605 0.009l0.030-0.001zM629.865-64h-235.345c-72.488 0-91.022 103.877-29.356 103.877h293.98c61.551 0 43.324-103.877-29.356-103.877zM696.443 123.263v-21.95c0-11.317-9.174-20.492-20.492-20.492h-327.749c-11.317 0-20.492 9.174-20.492 20.492v22.103c0 11.317 9.174 20.492 20.492 20.492v0h327.672c11.301-0.022 20.453-9.188 20.453-20.491 0 0 0 0 0 0v0z" />

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -1,10 +1,10 @@
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?x6b7dj');
src: url('fonts/icomoon.eot?x6b7dj#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?x6b7dj') format('truetype'),
url('fonts/icomoon.woff?x6b7dj') format('woff'),
url('fonts/icomoon.svg?x6b7dj#icomoon') format('svg');
src: url('fonts/icomoon.eot?r0ucr2');
src: url('fonts/icomoon.eot?r0ucr2#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?r0ucr2') format('truetype'),
url('fonts/icomoon.woff?r0ucr2') format('woff'),
url('fonts/icomoon.svg?r0ucr2#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;

View File

@@ -10,7 +10,7 @@
height: 137px;
background: white;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.22);
opacity: 0.73;
opacity: 1;
margin: 15px 15px 5px 15px;
cursor: pointer;
overflow: hidden;
@@ -25,13 +25,10 @@
opacity: 1;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
white-space: normal;
word-break: keep-all;
overflow: hidden;
overflow: visible;
position: relative;
}
.book-item-config {
@@ -64,11 +61,11 @@
position: absolute;
top: 23px;
right: 17px;
transform: rotate(90deg);
font-size: 18px;
color: white;
cursor: pointer;
text-shadow: 0px 0px 5px rgba(75, 75, 75, 0.6);
animation: slide-down-rotate 0.1s ease-in-out 0s 1;
}
.reading-progress-icon {
position: absolute;
@@ -83,6 +80,37 @@
color: white;
cursor: pointer;
transform: scale(0.9);
animation: slide-down 0.1s ease-in-out 0s 1;
}
@keyframes slide-down {
0% {
transform: translateY(-20px);
opacity: 0;
}
100% {
transform: translateY(0px);
opacity: 1;
}
}
@keyframes slide-down-rotate {
0% {
transform: translateY(-20px);
opacity: 0;
}
100% {
transform: translateY(0px);
opacity: 1;
}
}
@keyframes slide-up {
0% {
transform: translateY(20px);
opacity: 0;
}
100% {
transform: translateY(0px);
opacity: 1;
}
}
.reading-percentage-char {
display: inline-block;
@@ -97,6 +125,7 @@
cursor: pointer;
z-index: 1;
text-shadow: 0px 0px 5px rgba(75, 75, 75, 0.6);
animation: slide-up 0.1s ease-in-out 0s 1;
}
.book-loved-icon {
position: absolute;
@@ -142,7 +171,7 @@
position: absolute;
top: 115px;
left: 15px;
font-weight: bold;
font-weight: 600;
width: 106px;
height: 38px;
}

View File

@@ -9,7 +9,7 @@
height: 74px;
background: rgba(0, 0, 0, 0);
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.22);
opacity: 0.73;
opacity: 1;
cursor: pointer;
}
.book-item-list-title,

View File

@@ -165,9 +165,3 @@
bottom: 5px;
margin-left: calc(50% - 6px);
}
/* 控制小于888px是书脊消失 */
@media screen and (max-width: 888px) {
.card-list-item-citation {
display: none;
}
}

View File

@@ -79,9 +79,12 @@ class CardList extends React.Component<CardListProps, CardListStates> {
}}
style={this.props.mode === "note" ? { height: "250px" } : {}}
>
{this.state.deleteKey === item.key ? (
<DeleteIcon {...cardProps} />
) : null}
<div style={{ position: "relative", bottom: "25px" }}>
{this.state.deleteKey === item.key ? (
<DeleteIcon {...cardProps} />
) : null}
</div>
<div className="card-list-item-card">
<div className="card-list-item-text-parent">
<div className="card-list-item-text">

View File

@@ -1,20 +1,23 @@
.color-option-container {
width: 100%;
width: 90%;
height: 40px;
margin-left: 5%;
position: relative;
top: 8px;
top: 15px;
display: flex;
justify-content: space-around;
}
.color-option {
width: 30px;
height: 30px;
width: 25px;
height: 25px;
background: rgba(228, 255, 154, 1);
border-radius: 50%;
opacity: 1;
box-sizing: border-box;
position: relative;
bottom: 5px;
cursor: pointer;
animation: slide-left 0.2s ease-in-out 0s 1;
}
.popup-color-more {
display: inline-block;
@@ -36,6 +39,27 @@
display: flex;
align-items: center;
justify-content: center;
animation: slide-right 0.2s ease-in-out 0s 1;
}
@keyframes slide-right {
0% {
transform: translateX(30px);
opacity: 0;
}
100% {
transform: translateX(0px);
opacity: 1;
}
}
@keyframes slide-left {
0% {
transform: translateX(-50px);
opacity: 0;
}
100% {
transform: translateX(0px);
opacity: 1;
}
}
.demo-line {
width: 100%;

View File

@@ -10,6 +10,7 @@
top: 2px !important;
right: 2px !important;
z-index: 10;
animation: popup 0.1s ease-in-out 0s 1;
}
.delete-digest-icon {
position: relative;

View File

@@ -94,7 +94,6 @@ class DropdownList extends React.Component<
value={[subItem, index.toString()]}
className="general-setting-option"
key={index}
style={item.id === 1 ? { fontFamily: subItem } : {}}
>
{subItem}
</option>

View File

@@ -8,7 +8,9 @@
.general-setting-title {
font-size: 16px;
color: rgba(75, 75, 75, 1);
margin: 15px 0px 17px 0px;
font-weight: 500;
margin-top: 15px;
margin-bottom: 10px;
}
.general-setting-dropdown {
width: 220px;

View File

@@ -40,6 +40,7 @@ class ImageViewer extends React.Component<ImageViewerProps, ImageViewerStates> {
this.props.handleLeaveReader("bottom");
}
let href =
event.target ||
event.target.href ||
event.target.parentNode.href ||
event.target.parentNode.parentNode.href;

View File

@@ -423,7 +423,9 @@ class ImportLocal extends React.Component<ImportLocalProps, ImportLocalState> {
className="import-from-local"
{...getRootProps()}
style={
OtherUtil.getReaderConfig("lang") === "en" ? { right: 390 } : {}
OtherUtil.getReaderConfig("lang") === "en"
? { fontSize: "14px" }
: {}
}
>
<Trans>Import from Local</Trans>

View File

@@ -14,6 +14,7 @@
color: white;
cursor: pointer;
z-index: 50;
transition: 0.1s;
}
.import-from-local:hover {
background-color: rgba(75, 75, 75, 0.9);

View File

@@ -45,18 +45,7 @@ class ModeControl extends React.Component<ModeControlProps, ModeControlState> {
<Trans>Double-Page Mode</Trans>
</div>
</div>
<div
className="double-mode-container"
onClick={() => {
this.handleChangeMode("scroll");
}}
style={this.state.readerMode === "scroll" ? {} : { opacity: 0.4 }}
>
<span className="icon-scroll1 two-page-icon"></span>
<div className="double-mode-text">
<Trans>Chapter Scroll</Trans>
</div>
</div>
<div
className="double-mode-container"
onClick={() => {

View File

@@ -1,13 +1,13 @@
.single-control-container {
width: calc(100% - 10px);
width: calc(100% - 30px);
height: 80px;
margin: 0px 5px 0px 5px;
margin: 0px 15px 0px 15px;
display: flex;
justify-content: space-around;
}
.single-page-icon,
.two-page-icon {
font-size: 50px;
font-size: 60px;
color: rgba(75, 75, 75, 1);
text-align: center;
}

View File

@@ -71,7 +71,9 @@ class NoteTag extends React.Component<NoteTagProps, NoteTagState> {
this.props.handleTag(this.indextoTag([]));
};
handleInput = () => {
this.setState({ isInput: true });
this.setState({ isInput: true }, () => {
document.getElementById("newTag")?.focus();
});
};
render() {
const renderTag = () => {

View File

@@ -24,7 +24,7 @@
color: #4b4b4b;
opacity: 1;
margin-left: 10px;
font-weight: bold;
font-weight: 600;
}
.tag-container {
display: inline-block;

View File

@@ -57,7 +57,7 @@
position: absolute;
bottom: 15px;
right: 15px;
width: 100px;
width: 120px;
display: flex;
justify-content: space-between;
}
@@ -74,6 +74,7 @@
color: rgba(0, 0, 0, 1);
opacity: 1;
cursor: pointer;
margin-right: 20px;
}
.note-tags {
width: 100%;

View File

@@ -9,10 +9,9 @@
.digest-option,
.translation-option,
.copy-option {
height: 55px;
height: 69px;
width: 69px;
font-size: 14px !important;
line-height: 15px !important;
color: rgba(0, 0, 0, 1);
opacity: 1;
@@ -20,10 +19,17 @@
display: flex;
box-sizing: border-box;
cursor: pointer;
transition: 0.1s;
/* align-items: center; */
justify-content: center;
}
.note-option:hover,
.digest-option:hover,
.translation-option:hover,
.copy-option:hover {
background-color: rgba(75, 75, 75, 0.035);
border-radius: 8px;
}
.digest-option {
margin-top: 5px;
margin-right: 10px;

View File

@@ -2,7 +2,7 @@
import React from "react";
import "./searchBox.css";
import OtherUtil from "../../utils/otherUtil";
import { Trans } from "react-i18next";
import { Trans, withNamespaces } from "react-i18next";
import { SearchBoxProps } from "./interface";
class SearchBox extends React.Component<SearchBoxProps> {
componentDidMount() {
@@ -100,12 +100,12 @@ class SearchBox extends React.Component<SearchBoxProps> {
}}
placeholder={
this.props.isNavSearch || this.props.mode === "nav"
? "搜索全书"
? this.props.t("Search the book")
: this.props.tabMode === "note"
? "搜索我的笔记"
? this.props.t("Search my notes")
: this.props.tabMode === "digest"
? "搜索我的书摘"
: "搜索我的书库"
? this.props.t("Search my digests")
: this.props.t("Search my library")
}
style={
this.props.mode === "nav"
@@ -137,4 +137,4 @@ class SearchBox extends React.Component<SearchBoxProps> {
}
}
export default SearchBox;
export default withNamespaces()(SearchBox as any);

View File

@@ -16,4 +16,5 @@ export interface SearchBoxProps {
handleSearch: (isSearch: boolean) => void;
handleSearchState: (isSearch: boolean) => void;
handleSearchList: (searchList: any) => void;
t: any;
}

View File

@@ -19,8 +19,6 @@ class SettingDialog extends React.Component<
isTouch: OtherUtil.getReaderConfig("isTouch") === "yes",
isOpenBook: OtherUtil.getReaderConfig("isOpenBook") === "yes",
isExpandContent: OtherUtil.getReaderConfig("isExpandContent") === "yes",
isUseBackground: OtherUtil.getReaderConfig("isUseBackground") === "yes",
isShowFooter: OtherUtil.getReaderConfig("isShowFooter") !== "no",
};
}
componentDidMount() {
@@ -79,28 +77,7 @@ class SettingDialog extends React.Component<
: this.props.handleMessage("Turn On Successfully");
this.props.handleMessageBox(true);
};
handleChangeBackground = () => {
this.setState({ isUseBackground: !this.state.isUseBackground });
OtherUtil.setReaderConfig(
"isUseBackground",
this.state.isUseBackground ? "no" : "yes"
);
this.state.isUseBackground
? this.props.handleMessage("Turn Off Successfully")
: this.props.handleMessage("Turn On Successfully");
this.props.handleMessageBox(true);
};
handleFooterHeader = () => {
this.setState({ isShowFooter: !this.state.isShowFooter });
OtherUtil.setReaderConfig(
"isShowFooter",
this.state.isShowFooter ? "no" : "yes"
);
this.state.isShowFooter
? this.props.handleMessage("Turn On Successfully")
: this.props.handleMessage("Turn Off Successfully");
this.props.handleMessageBox(true);
};
render() {
return (
<div className="setting-dialog-container">
@@ -115,12 +92,15 @@ class SettingDialog extends React.Component<
<Trans>Date</Trans>
{updateLog.date}
</p>
<span
className="icon-close setting-close"
onClick={() => {
this.props.handleSetting(false);
}}
></span>
<div className="setting-close-container">
<span
className="icon-close setting-close"
onClick={() => {
this.props.handleSetting(false);
}}
></span>
</div>
<div className="setting-dialog-info">
<div className="setting-dialog-new-title">
{this.state.isTouch ? (
@@ -203,56 +183,6 @@ class SettingDialog extends React.Component<
></span>
</span>
</div>
<div className="setting-dialog-new-title">
<Trans>Don't show footer and header</Trans>
<span
className="single-control-switch"
onClick={() => {
this.handleFooterHeader();
}}
style={{ float: "right" }}
>
<span
className="single-control-button"
style={
this.state.isShowFooter
? {
transform: "translateX(0px)",
transition: "transform 0.5s ease",
}
: {
transform: "translateX(20px)",
transition: "transform 0.5s ease",
}
}
></span>
</span>
</div>
<div className="setting-dialog-new-title">
<Trans>Dont't use mimical background</Trans>
<span
className="single-control-switch"
onClick={() => {
this.handleChangeBackground();
}}
style={{ float: "right" }}
>
<span
className="single-control-button"
style={
this.state.isUseBackground
? {
transform: "translateX(20px)",
transition: "transform 0.5s ease",
}
: {
transform: "translateX(0px)",
transition: "transform 0.5s ease",
}
}
></span>
</span>
</div>
<div className="setting-dialog-new-title">
<Trans> / Language</Trans>
@@ -294,23 +224,13 @@ class SettingDialog extends React.Component<
<div
className="setting-dialog-subtitle"
onClick={() => {
this.handleJump("https://github.com/troyeguo");
this.handleJump("https://960960.xyz");
}}
>
<Trans>About author</Trans>
</div>
</div>
</div>
<img
src={
process.env.NODE_ENV === "production"
? "./assets/empty.svg"
: "../../assets/empty.svg"
}
alt=""
className="setting-dialog-illustration"
/>
</div>
);
}

View File

@@ -7,7 +7,5 @@ export interface SettingInfoState {
language: string;
isTouch: boolean;
isOpenBook: boolean;
isUseBackground: boolean;
isShowFooter: boolean;
isExpandContent: boolean;
}

View File

@@ -13,7 +13,7 @@
}
.setting-dialog-title {
font-size: 20px;
font-weight: bold;
font-weight: 600;
line-height: 15px;
color: rgba(75, 75, 75, 1);
opacity: 1;
@@ -85,15 +85,23 @@
font-size: 25px;
color: rgba(75, 75, 75, 1);
}
.setting-close {
.setting-close-container {
position: absolute;
top: 10px;
right: 10px;
transition: 0.1s;
width: 38px;
height: 38px;
}
.setting-close-container:hover {
background-color: rgba(75, 75, 75, 0.035);
border-radius: 50%;
}
.about-this-project {
position: absolute;
bottom: 20px;
left: 40px;
left: 100px;
width: 150px;
cursor: pointer;
z-index: 10;

View File

@@ -12,7 +12,9 @@ class SliderList extends React.Component<SliderListProps, SliderListState> {
value:
this.props.mode === "fontSize"
? OtherUtil.getReaderConfig("fontSize") || "17"
: OtherUtil.getReaderConfig("scale") || "1",
: this.props.mode === "scale"
? OtherUtil.getReaderConfig("scale") || "1"
: OtherUtil.getReaderConfig("margin") || "30",
};
}
@@ -26,11 +28,14 @@ class SliderList extends React.Component<SliderListProps, SliderListState> {
"font-size": `${fontSize || 17}px !important`,
},
});
} else {
} else if (this.props.mode === "scale") {
const scale = event.target.value;
this.setState({ value: scale });
OtherUtil.setReaderConfig("scale", scale);
window.location.reload();
} else {
const margin = event.target.value;
this.setState({ value: margin });
OtherUtil.setReaderConfig("margin", margin);
}
};
//使进度百分比随拖动实时变化
@@ -46,25 +51,27 @@ class SliderList extends React.Component<SliderListProps, SliderListState> {
<Trans>Font Size</Trans>&nbsp;&nbsp; &nbsp;
<span>{this.state.value}px</span>
</>
) : (
) : this.props.mode === "scale" ? (
<>
<Trans>Scale</Trans>&nbsp;&nbsp; &nbsp;
<span>
{parseInt((parseFloat(this.state.value) * 100).toString())}%
</span>
</>
) : (
<>
<Trans>Margin</Trans>&nbsp;&nbsp; &nbsp;
<span>{this.state.value}px</span>
</>
)}
</div>
<span
className="ultra-small-size"
style={
this.props.mode === "fontSize"
? {}
: { position: "relative", right: 7 }
}
>
{this.props.mode === "fontSize" ? "A" : "1"}
<span className="ultra-small-size">
{this.props.mode === "fontSize"
? "A"
: this.props.mode === "scale"
? "1"
: "0"}
</span>
<div className="font-size-selector">
<input
@@ -73,23 +80,39 @@ class SliderList extends React.Component<SliderListProps, SliderListState> {
type="range"
max={this.props.maxValue}
min={this.props.minValue}
step={this.props.mode === "fontSize" ? "1" : "0.1"}
step={
this.props.mode === "fontSize"
? "1"
: this.props.mode === "scale"
? "0.1"
: "5"
}
onInput={(event) => {
this.onValueChange(event);
}}
onChange={(event) => {
this.onValueInput(event);
}}
onMouseUp={() => {
window.location.reload();
}}
/>
</div>
{this.props.mode === "fontSize" ? (
<span className="ultra-large-size">A</span>
) : this.props.mode === "scale" ? (
<span
className="ultra-large-size"
style={{ fontSize: "16px", right: "5px" }}
>
2
</span>
) : (
<span
className="ultra-large-size"
style={{ fontSize: "16px", left: 5 }}
style={{ fontSize: "16px", right: "5px" }}
>
2
50
</span>
)}
</div>

View File

@@ -8,12 +8,16 @@
line-height: 27px;
color: rgba(75, 75, 75, 1);
padding-bottom: 10px;
font-weight: 500;
margin-bottom: -5px;
margin-top: 15px;
}
.ultra-small-size {
float: left;
font-size: 16px;
line-height: 27px;
color: rgba(75, 75, 75, 1);
position: relative;
}
.ultra-large-size {
@@ -23,7 +27,7 @@
color: rgba(75, 75, 75, 1);
position: relative;
bottom: 49px;
left: 5px;
text-align: left;
}
.font-size-selector {
width: 205px;

View File

@@ -24,7 +24,7 @@ class ThemeList extends React.Component<ThemeListProps, ThemeListState> {
currentTextIndex: textList.findIndex((item) => {
return (
item.theme ===
(OtherUtil.getReaderConfig("textColor") || "rgba(255,255,255,1)")
(OtherUtil.getReaderConfig("textColor") || "rgba(0,0,0,1)")
);
}),
isShowTextPicker: false,
@@ -42,6 +42,15 @@ class ThemeList extends React.Component<ThemeListProps, ThemeListState> {
color: `white !important`,
},
});
} else if (
index === 2 &&
OtherUtil.getReaderConfig("backgroundColor") === "rgba(255,255,255,1)"
) {
this.props.currentEpub.rendition.themes.default({
"a, article, cite, code, div, li, p, pre, span, table": {
color: `black !important`,
},
});
} else {
this.props.currentEpub.rendition.themes.default({
"a, article, cite, code, div, li, p, pre, span, table": {

View File

@@ -7,7 +7,9 @@
width: 100%;
font-size: 16px;
color: rgba(75, 75, 75, 1);
margin: 6px 0px;
font-weight: 500;
margin-bottom: -5px;
margin-top: 15px;
}
.background-color-list {
margin: 10px 0px 0px;

View File

@@ -59,21 +59,6 @@ class UpdateDialog extends React.Component<UpdateInfoProps, UpdateInfoState> {
>
<Trans>Confirm</Trans>
</div>
<p className="update-dialog-url">
<span style={{ color: "#959595" }}>
<Trans>Our Website</Trans>
</span>
koodo.960960.xyz
</p>
<img
src={
process.env.NODE_ENV === "production"
? "./assets/empty.svg"
: "../../assets/empty.svg"
}
alt=""
className="update-dialog-illustration"
/>
</div>
);
}

View File

@@ -13,7 +13,7 @@
}
.update-dialog-title {
font-size: 20px;
font-weight: bold;
font-weight: 600;
line-height: 15px;
color: rgba(75, 75, 75, 1);
opacity: 1;
@@ -44,7 +44,7 @@
}
.update-dialog-info {
margin-top: 10px;
height: 300px;
height: 330px;
overflow-y: scroll;
width: 346px;
}

View File

@@ -32,12 +32,7 @@
place-content: center; */
overflow: hidden;
}
/* 控制小于888px是书脊消失 */
@media screen and (max-width: 888px) {
.background-box3 {
display: none;
}
}
.book-spine {
position: absolute;
width: 1px;
@@ -86,7 +81,6 @@
position: absolute;
top: 5px;
line-height: 30px;
color: rgba(191, 191, 191, 1);
text-align: center;
}
.progress-chapter-name {
@@ -104,7 +98,6 @@
position: absolute;
bottom: 10px;
line-height: 30px;
color: rgba(191, 191, 191, 1);
text-align: center;
font-size: 14px;
}

View File

@@ -18,6 +18,7 @@ class Background extends React.Component<BackgroundProps, BackgroundState> {
nextPage: 0,
scale: OtherUtil.getReaderConfig("scale") || 1,
isShowFooter: OtherUtil.getReaderConfig("isShowFooter") !== "no",
isShowHeader: OtherUtil.getReaderConfig("isShowHeader") !== "no",
isUseBackground: OtherUtil.getReaderConfig("isUseBackground") === "yes",
};
this.isFirst = true;
@@ -53,8 +54,15 @@ class Background extends React.Component<BackgroundProps, BackgroundState> {
render() {
if (this.state.isUseBackground) {
return (
<div className="background">
{this.state.isShowFooter && this.state.currentChapter && (
<div
className="background"
style={{
color: OtherUtil.getReaderConfig("textColor")
? OtherUtil.getReaderConfig("textColor")
: "",
}}
>
{this.state.isShowHeader && this.state.currentChapter && (
<p
className="progress-chapter-name"
style={
@@ -69,7 +77,7 @@ class Background extends React.Component<BackgroundProps, BackgroundState> {
<Trans>{this.state.currentChapter}</Trans>
</p>
)}
{this.state.isShowFooter && !this.state.isSingle && (
{this.state.isShowHeader && !this.state.isSingle && (
<p
className="progress-book-name"
style={
@@ -120,8 +128,15 @@ class Background extends React.Component<BackgroundProps, BackgroundState> {
);
}
return (
<div className="background">
{this.state.isShowFooter && this.state.currentChapter && (
<div
className="background"
style={{
color: OtherUtil.getReaderConfig("textColor")
? OtherUtil.getReaderConfig("textColor")
: "",
}}
>
{this.state.isShowHeader && this.state.currentChapter && (
<p
className="progress-chapter-name"
style={
@@ -137,7 +152,7 @@ class Background extends React.Component<BackgroundProps, BackgroundState> {
</p>
)}
{this.state.isShowFooter && !this.state.isSingle && (
{this.state.isShowHeader && !this.state.isSingle && (
<p
className="progress-book-name"
style={

View File

@@ -10,6 +10,7 @@ export interface BackgroundProps {
export interface BackgroundState {
isSingle: boolean;
isShowFooter: boolean;
isShowHeader: boolean;
isUseBackground: boolean;
currentChapter: string;
prevPage: number;

View File

@@ -97,6 +97,13 @@
right: 10px;
top: 10px;
cursor: pointer;
transition: 0.1s;
width: 38px;
height: 38px;
}
.backup-page-close-icon:hover {
background-color: rgba(75, 75, 75, 0.035);
border-radius: 50%;
}
.backup-page-option {
width: 100%;

View File

@@ -206,12 +206,15 @@ class BackupDialog extends React.Component<
style={{ marginLeft: "252px" }}
></div>
) : null}
<span
className="icon-close backup-page-close-icon"
onClick={() => {
this.handleClose();
}}
></span>
<div className="backup-page-close-icon">
<span
className="icon-close "
onClick={() => {
this.handleClose();
}}
></span>
</div>
{this.state.currentStep === 1 ? (
<div
className="backup-page-next"

View File

@@ -50,15 +50,19 @@
float: left;
line-height: 17px;
cursor: pointer;
height: 27px;
padding: 5px;
}
.list-view-mode {
min-width: 51px;
height: 17px;
height: 27px;
float: left;
line-height: 17px;
margin-left: 15px;
cursor: pointer;
padding: 5px;
}
.book-list-item-box {
position: relative;
top: 0px;
@@ -72,12 +76,7 @@
top: 1px;
margin-right: 5px;
}
.booklist-shelf-container {
position: absolute;
top: 80px;
left: calc(50vw - 100px);
width: 400px;
}
.booklist-shelf-list {
width: 169px;
height: 31px;

View File

@@ -128,13 +128,15 @@ class BookList extends React.Component<BookListProps, BookListState> {
? this.handleShelf(this.props.books, this.props.shelfIndex)
: this.props.mode === "favorite" && !this.props.isSort
? this.handleKeyFilter(this.props.books, AddFavorite.getAllFavorite())
: this.props.mode === "favorite" && this.props.isSort
: this.props.mode === "favorite" &&
this.props.isSort &&
!this.props.noteSortCode
? this.handleIndexFilter(
this.handleKeyFilter(this.props.books, AddFavorite.getAllFavorite()),
//返回排序后的图书index
SortUtil.sortBooks(this.props.books, this.props.bookSortCode) || []
)
: this.props.isSort
: this.props.isSort && !this.props.noteSortCode
? this.handleIndexFilter(
this.props.books,
//返回排序后的图书index
@@ -217,6 +219,7 @@ class BookList extends React.Component<BookListProps, BookListState> {
this.setState({ isOpenDelete });
};
render() {
console.log(this.state.favoriteBooks, "this.state.favoriteBooks");
if (
(this.state.favoriteBooks === 0 && this.props.mode === "favorite") ||
!this.props.books ||

View File

@@ -17,6 +17,7 @@ const mappropsToProps = (state: stateType) => {
isSort: state.manager.isSort,
isList: state.manager.isList,
bookSortCode: state.manager.bookSortCode,
noteSortCode: state.manager.noteSortCode,
};
};
const actionCreator = {

View File

@@ -9,6 +9,7 @@ export interface BookListProps extends RouteComponentProps<any> {
isSort: boolean;
isList: string;
bookSortCode: { sort: number; order: number };
noteSortCode: { sort: number; order: number };
handleFetchList: () => void;
handleMode: (mode: string) => void;
handleShelfIndex: (index: number) => void;

View File

@@ -47,7 +47,7 @@
height: 117px;
background: rgba(0, 0, 0, 0);
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.22);
opacity: 0.73;
opacity: 1;
margin: 10px;
margin-left: 15px;
cursor: pointer;

View File

@@ -1,14 +1,13 @@
.delete-dialog-container {
width: 309px;
height: 189px;
width: 319px;
height: 199px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 16px rgba(0, 0, 0, 0.34);
opacity: 1;
position: fixed;
left: calc(50% - 155px);
top: calc(50% - 95px);
left: calc(50% - 160px);
top: calc(50% - 100px);
z-index: 10;
padding: 5px;
animation: popup 0.1s ease-in-out 0s 1;
}
.delete-dialog-title {
@@ -49,7 +48,9 @@
opacity: 1;
position: absolute;
top: 106px;
width: 100%;
padding-left: 5px;
padding-right: 5px;
width: calc(100% - 10px);
/* margin-left: 25px; */
}
.icon-check {
@@ -69,7 +70,7 @@
opacity: 1;
position: absolute;
left: 147px;
top: 144px;
top: 154px;
font-size: 14px;
@@ -86,9 +87,8 @@
opacity: 1;
position: absolute;
left: 227px;
top: 144px;
top: 154px;
font-size: 14px;
line-height: 30px;
color: white;
opacity: 1;

View File

@@ -87,6 +87,7 @@
margin-left: 16px;
font-size: 15px;
line-height: 31px;
cursor: pointer;
}
.delete-shelf-icon {
cursor: pointer;

View File

@@ -54,7 +54,7 @@ class BookList extends React.Component<BookListProps, BookListState> {
//根据不同的场景获取不同的图书数据
let books = !this.props.isSort
? this.handleKeyFilter(this.props.deletedBooks, AddTrash.getAllTrash())
: this.props.isSort
: this.props.isSort && !this.props.noteSortCode
? this.handleIndexFilter(
this.handleKeyFilter(this.props.deletedBooks, AddTrash.getAllTrash()),
//返回排序后的图书index
@@ -63,7 +63,7 @@ class BookList extends React.Component<BookListProps, BookListState> {
this.props.bookSortCode
) || []
)
: this.props.isSort
: this.props.isSort && !this.props.noteSortCode
? this.handleIndexFilter(
this.props.deletedBooks,
//返回排序后的图书index

View File

@@ -15,6 +15,7 @@ const mappropsToProps = (state: stateType) => {
isSort: state.manager.isSort,
isList: state.manager.isList,
bookSortCode: state.manager.bookSortCode,
noteSortCode: state.manager.noteSortCode,
};
};
const actionCreator = {

View File

@@ -7,6 +7,7 @@ export interface BookListProps extends RouteComponentProps<any> {
isSort: boolean;
isList: string;
bookSortCode: { sort: number; order: number };
noteSortCode: { sort: number; order: number };
handleFetchList: () => void;
handleMode: (mode: string) => void;
handleDeleteDialog: (isShow: boolean) => void;

View File

@@ -29,15 +29,21 @@ class EmptyPage extends React.Component<EmptyPageProps, EmptyPageState> {
};
return (
<div className="empty-page-container">
<img
src={
process.env.NODE_ENV === "production"
? "./assets/empty.svg"
: "../../assets/empty.svg"
}
alt=""
className="empty-page-illustration"
/>
<div
className="empty-illustration-container"
style={{ width: "calc(100% - 50px)" }}
>
<img
src={
process.env.NODE_ENV === "production"
? "./assets/empty.svg"
: "../../assets/empty.svg"
}
alt=""
className="empty-page-illustration"
/>
</div>
{renderEmptyList()}
</div>
);

View File

@@ -7,11 +7,16 @@
overflow: hidden;
}
.empty-page-illustration {
height: 100%;
}
.empty-illustration-container {
height: 450px;
position: absolute;
right: 0;
bottom: 0;
width: 787px;
z-index: -1;
overflow: hidden;
}
.empty-page-info-container {
position: absolute;

View File

@@ -26,6 +26,7 @@ class Reader extends React.Component<ReaderProps, ReaderState> {
isMessage: false,
rendition: null,
scale: OtherUtil.getReaderConfig("scale") || 1,
margin: OtherUtil.getReaderConfig("margin") || 30,
time: ReadingTime.getTime(this.props.currentBook.key),
isTouch: OtherUtil.getReaderConfig("isTouch") === "yes",
readerMode: OtherUtil.getReaderConfig("readerMode") || "double",
@@ -57,12 +58,7 @@ class Reader extends React.Component<ReaderProps, ReaderState> {
this.rendition = epub.renderTo(page, {
manager:
this.state.readerMode === "continuous" ? "continuous" : "default",
flow:
this.state.readerMode === "scroll"
? "scrolled-doc"
: this.state.readerMode === "continuous"
? "scrolled"
: "auto",
flow: this.state.readerMode === "continuous" ? "scrolled" : "auto",
width: "100%",
height: "100%",
snap: true,
@@ -70,9 +66,7 @@ class Reader extends React.Component<ReaderProps, ReaderState> {
OtherUtil.getReaderConfig("readerMode") === "single" ? "none" : "",
});
this.setState({ rendition: this.rendition });
this.state.readerMode !== "scroll" &&
this.state.readerMode !== "continuous" &&
MouseEvent(this.rendition); // 绑定事件
this.state.readerMode !== "continuous" && MouseEvent(this.rendition); // 绑定事件
this.tickTimer = setInterval(() => {
let time = this.state.time;
time += 1;
@@ -168,6 +162,17 @@ class Reader extends React.Component<ReaderProps, ReaderState> {
>
<span className="icon-dropdown next-chapter-single"></span>
</div>
<div
className="reader-setting-icon-container"
onClick={() => {
this.handleEnterReader("left");
this.handleEnterReader("right");
this.handleEnterReader("bottom");
this.handleEnterReader("top");
}}
>
<span className="icon-setting reader-setting-icon"></span>
</div>
{this.state.isMessage ? <MessageBox /> : null}
<div
className="left-panel"
@@ -294,7 +299,6 @@ class Reader extends React.Component<ReaderProps, ReaderState> {
className="view-area-page"
id="page-area"
style={
this.state.readerMode === "scroll" ||
this.state.readerMode === "continuous"
? {
left: `calc(50vw - ${270 * parseFloat(this.state.scale)}px)`,
@@ -307,6 +311,11 @@ class Reader extends React.Component<ReaderProps, ReaderState> {
left: `calc(50vw - ${270 * parseFloat(this.state.scale)}px)`,
right: `calc(50vw - ${270 * parseFloat(this.state.scale)}px)`,
}
: this.state.readerMode === "double"
? {
left: this.state.margin + "px",
right: this.state.margin + "px",
}
: {}
}
></div>

View File

@@ -21,4 +21,5 @@ export interface ReaderState {
rendition: any;
time: number;
scale: string;
margin: string;
}

View File

@@ -133,8 +133,8 @@
}
.view-area-page {
position: absolute;
left: 30px;
right: 30px;
left: 0px;
right: 0px;
top: 30px;
bottom: 30px;
/* width: calc(100% - 100px);
@@ -155,7 +155,7 @@
font-size: 30px;
transform: rotate(90deg);
cursor: pointer;
opacity: 0.1;
opacity: 0.05;
display: flex;
justify-content: center;
align-items: center;
@@ -173,7 +173,7 @@
right: 20px;
transform: rotate(-90deg);
cursor: pointer;
opacity: 0.1;
opacity: 0.05;
display: flex;
justify-content: center;
align-items: center;
@@ -193,3 +193,12 @@
font-size: 20px;
height: 20px;
}
.reader-setting-icon-container {
position: absolute;
top: 15px;
right: 20px;
font-size: 27px;
opacity: 0.1;
cursor: pointer;
z-index: 10;
}

View File

@@ -71,6 +71,11 @@ class Header extends React.Component<HeaderProps, HeaderState> {
onClick={() => {
this.props.handleBackupDialog(true);
}}
style={
OtherUtil.getReaderConfig("lang") === "en"
? { fontSize: "14px" }
: {}
}
>
<Trans>Backup and Restore</Trans>
</div>

View File

@@ -10,6 +10,16 @@
left: 265px;
top: 29px;
cursor: pointer;
transition: 0.1s;
width: 48px;
height: 27px;
padding-left: 8px;
transition: 0.1s;
}
.header-sort-container:hover,
.setting-icon-container:hover {
background-color: rgba(75, 75, 75, 0.035);
border-radius: 8px;
}
.header-sort-text,
.download-demo-book {
@@ -73,6 +83,7 @@
color: #4b4b4b;
box-sizing: border-box;
cursor: pointer;
transition: 0.1s;
}
.import-from-cloud:hover {
background-color: rgba(75, 75, 75, 0.035);
@@ -113,12 +124,15 @@
font-size: 25px;
}
.setting-icon-container {
width: 25px;
height: 25px;
width: 32px;
height: 35px;
font-size: 25px;
line-height: 37px;
position: absolute;
left: 335px;
top: 33px;
top: 25px;
color: rgba(75, 75, 75, 1);
cursor: pointer;
transition: 0.1s;
padding-left: 5px;
}

View File

@@ -145,14 +145,17 @@ class NavigationPanel extends React.Component<
<div className="navigation-panel">
{this.state.isSearch ? (
<>
<span
className="icon-close nav-close-icon"
onClick={() => {
this.handleSearchState(false);
this.props.handleSearch(false);
this.setState({ searchList: null });
}}
></span>
<div className="nav-close-icon">
<span
className="icon-close"
onClick={() => {
this.handleSearchState(false);
this.props.handleSearch(false);
this.setState({ searchList: null });
}}
></span>
</div>
<div
className="header-search-container"
style={this.state.isSearch ? { left: 40 } : {}}

View File

@@ -142,6 +142,13 @@
right: 10px;
top: 10px;
font-size: 20px;
transition: 0.1s;
width: 38px;
height: 38px;
}
.nav-close-icon:hover {
background-color: rgba(75, 75, 75, 0.035);
border-radius: 50%;
}
.nav-search-list {
position: absolute;
@@ -159,7 +166,7 @@
}
.content-search-text {
color: red !important;
font-weight: bold !important;
font-weight: 600 !important;
}
.nav-search-page {
position: absolute;

View File

@@ -18,7 +18,10 @@ class SettingPanel extends React.Component<
this.state = {
isSupported: false,
isAudioOn: false,
readerMode: OtherUtil.getReaderConfig("readerMode"),
readerMode: OtherUtil.getReaderConfig("readerMode") || "double",
isUseBackground: OtherUtil.getReaderConfig("isUseBackground") === "yes",
isShowFooter: OtherUtil.getReaderConfig("isShowFooter") !== "no",
isShowHeader: OtherUtil.getReaderConfig("isShowHeader") !== "no",
};
}
componentDidMount() {
@@ -76,6 +79,45 @@ class SettingPanel extends React.Component<
};
});
};
handleChangeBackground = () => {
this.setState({ isUseBackground: !this.state.isUseBackground });
OtherUtil.setReaderConfig(
"isUseBackground",
this.state.isUseBackground ? "no" : "yes"
);
this.state.isUseBackground
? this.props.handleMessage("Turn Off Successfully")
: this.props.handleMessage("Turn On Successfully");
this.props.handleMessageBox(true);
};
handleFooter = () => {
this.setState({ isShowFooter: !this.state.isShowFooter });
OtherUtil.setReaderConfig(
"isShowFooter",
this.state.isShowFooter ? "no" : "yes"
);
this.state.isShowFooter
? this.props.handleMessage("Turn On Successfully")
: this.props.handleMessage("Turn Off Successfully");
this.props.handleMessageBox(true);
setTimeout(() => {
window.location.reload();
}, 500);
};
handleHeader = () => {
this.setState({ isShowHeader: !this.state.isShowHeader });
OtherUtil.setReaderConfig(
"isShowHeader",
this.state.isShowHeader ? "no" : "yes"
);
this.state.isShowHeader
? this.props.handleMessage("Turn On Successfully")
: this.props.handleMessage("Turn Off Successfully");
this.props.handleMessageBox(true);
setTimeout(() => {
window.location.reload();
}, 500);
};
render() {
return (
<div className="setting-panel-parent">
@@ -85,35 +127,6 @@ class SettingPanel extends React.Component<
</div>
<ModeControl />
{this.state.isSupported ? (
<div className="single-control-switch-container">
<span className="single-control-switch-title">
{this.state.isAudioOn ? (
<Trans>Turn off audio</Trans>
) : (
<Trans>Turn on audio</Trans>
)}
</span>
<span
className="single-control-switch"
onClick={() => {
if (this.props.locations) {
this.handleChangeAudio();
} else {
this.props.handleMessage("Audio is not ready yet");
this.props.handleMessageBox(true);
}
}}
style={this.props.locations ? {} : { opacity: 0.5 }}
>
<span
className="single-control-button"
style={this.state.isAudioOn ? { float: "right" } : {}}
></span>
</span>
</div>
) : null}
<ThemeList />
<SliderList
{...{
@@ -122,6 +135,13 @@ class SettingPanel extends React.Component<
mode: "fontSize",
}}
/>
<SliderList
{...{
maxValue: 50,
minValue: 0,
mode: "margin",
}}
/>
{this.state.readerMode && this.state.readerMode !== "double" ? (
<SliderList
{...{
@@ -133,6 +153,152 @@ class SettingPanel extends React.Component<
) : null}
<DropdownList />
{this.state.isSupported ? (
<div className="single-control-switch-container">
<span className="single-control-switch-title">
<Trans>Turn on audio</Trans>
</span>
<span
className="single-control-switch"
onClick={() => {
if (this.props.locations) {
this.handleChangeAudio();
} else {
this.props.handleMessage("Audio is not ready yet");
this.props.handleMessageBox(true);
}
}}
style={
this.props.locations
? this.state.isAudioOn
? { background: "rgba(46, 170, 220)" }
: {}
: { opacity: 0.5 }
}
>
<span
className="single-control-button"
style={
this.state.isAudioOn
? {
transform: "translateX(20px)",
transition: "transform 0.5s ease",
}
: {
transform: "translateX(0px)",
transition: "transform 0.5s ease",
}
}
></span>
</span>
</div>
) : null}
<div
className="single-control-switch-container"
style={
this.state.isAudioOn ? { background: "rgba(46, 170, 220)" } : {}
}
>
<span className="single-control-switch-title">
<Trans>Don't show footer</Trans>
</span>
<span
className="single-control-switch"
onClick={() => {
this.handleFooter();
}}
style={
!this.state.isShowFooter
? { background: "rgba(46, 170, 220)", float: "right" }
: { float: "right" }
}
>
<span
className="single-control-button"
style={
this.state.isShowFooter
? {
transform: "translateX(0px)",
transition: "transform 0.5s ease",
}
: {
transform: "translateX(20px)",
transition: "transform 0.5s ease",
}
}
></span>
</span>
</div>
<div
className="single-control-switch-container"
style={
this.state.isAudioOn ? { background: "rgba(46, 170, 220)" } : {}
}
>
<span className="single-control-switch-title">
<Trans>Don't show header</Trans>
</span>
<span
className="single-control-switch"
onClick={() => {
this.handleHeader();
}}
style={
!this.state.isShowHeader
? { background: "rgba(46, 170, 220)", float: "right" }
: { float: "right" }
}
>
<span
className="single-control-button"
style={
this.state.isShowHeader
? {
transform: "translateX(0px)",
transition: "transform 0.5s ease",
}
: {
transform: "translateX(20px)",
transition: "transform 0.5s ease",
}
}
></span>
</span>
</div>
<div className="single-control-switch-container">
<span className="single-control-switch-title">
<Trans>Dont't use mimical background</Trans>
</span>
<span
className="single-control-switch"
onClick={() => {
this.handleChangeBackground();
}}
style={
this.state.isUseBackground
? { background: "rgba(46, 170, 220)", float: "right" }
: { float: "right" }
}
>
<span
className="single-control-button"
style={
this.state.isUseBackground
? {
transform: "translateX(20px)",
transition: "transform 0.5s ease",
}
: {
transform: "translateX(0px)",
transition: "transform 0.5s ease",
}
}
></span>
</span>
</div>
</div>
</div>
);

View File

@@ -9,4 +9,7 @@ export interface SettingPanelState {
isSupported: boolean;
isAudioOn: boolean;
readerMode: string;
isUseBackground: boolean;
isShowFooter: boolean;
isShowHeader: boolean;
}

View File

@@ -4,8 +4,8 @@
align-items: center;
width: calc(100% - 44px);
height: 38px;
font-size: 16px;
color: rgba(75, 75, 75, 1);
font-weight: 500;
margin: 6px 22px;
}
.setting-panel-parent {
@@ -28,27 +28,27 @@
overflow-y: scroll;
padding-right: 17px; /* Increase/decrease this value for cross-browser compatibility */
box-sizing: content-box;
/* display: none; */
}
.single-control-switch-container {
margin: 10px 0px 15px;
margin-left: 50px;
margin: 15px 20px 10px;
height: 20px;
display: flex;
justify-content: space-between;
cursor: pointer;
}
.single-control-switch-title {
font-size: 16px;
line-height: 16px;
color: #4b4b4b;
opacity: 1;
margin: 0px 10px 0px 30px;
position: relative;
bottom: 2px;
color: rgba(75, 75, 75, 1);
font-weight: 500;
}
.single-control-switch {
display: inline-block;
width: 40px;
height: 20px;
background: #000000;
background: rgba(75, 75, 75, 1);
opacity: 1;
border-radius: 10px;
position: relative;
@@ -60,6 +60,6 @@
height: 16px;
width: 16px;
border-radius: 50%;
border: 2px solid black;
background-color: white;
margin: 2px;
}

View File

@@ -88,15 +88,7 @@
color: rgba(75, 75, 75, 0.5);
opacity: 1;
}
.icon-more {
margin-left: 93px;
/* line-height: 29px; */
position: relative;
top: 6px;
}
.icon-shelf {
/* margin-right: 12px; */
}
.sidebar-dropdown {
font-size: 13px;
}

View File

@@ -154,23 +154,27 @@ class Manager extends React.Component<ManagerProps, ManagerState> {
)}
<Sidebar />
<Header {...{ handleDrag: this.handleDrag }} />
<div className="manager-dialog-container">
{this.props.isOpenDeleteDialog ? (
<DeleteDialog />
) : this.props.isOpenEditDialog ? (
<EditDialog />
) : this.props.isOpenAddDialog ? (
<AddDialog />
) : null}
</div>
{this.props.isMessage ? <MessageBox /> : null}
{this.props.isSortDisplay ? <SortDialog /> : null}
{this.props.isBackup ? <BackupDialog /> : null}
{this.props.isFirst === "yes" ? <WelcomeDialog /> : null}
{this.state.isUpdated && this.props.isFirst === "no" ? (
{this.props.isOpenDeleteDialog && <DeleteDialog />}
{this.props.isOpenEditDialog && <EditDialog />}
{this.props.isOpenAddDialog && <AddDialog />}
{(this.props.isSettingOpen ||
this.props.isBackup ||
this.props.isOpenDeleteDialog ||
this.props.isOpenEditDialog ||
this.props.isOpenAddDialog ||
this.props.isFirst === "yes" ||
(this.state.isUpdated && this.props.isFirst === "no")) && (
<div className="drag-background"></div>
)}
{this.props.isMessage && <MessageBox />}
{this.props.isSortDisplay && <SortDialog />}
{this.props.isBackup && <BackupDialog />}
{this.props.isFirst === "yes" && <WelcomeDialog />}
{this.state.isUpdated && this.props.isFirst === "no" && (
<UpdateDialog {...updateDialogProps} />
) : null}
{this.props.isSettingOpen ? <SettingDialog /> : null}
)}
{this.props.isSettingOpen && <SettingDialog />}
{(!books || books.length === 0) && this.state.totalBooks ? (
<Redirect to="/manager/loading" />
) : (

View File

@@ -36,7 +36,7 @@
height: 100%;
top: 0px;
left: 0px;
z-index: 10;
z-index: 9;
}
.drag-info {
width: 200px;
@@ -50,7 +50,7 @@
text-align: center;
margin: 50px 0px 20px;
font-size: 40px;
font-weight: bold;
font-weight: 600;
}
.waring-pic {
width: 100vw;