feat: add email format validation and improve sync record reset instructions

- Added email format validation in login and account settings.
- Enhanced user feedback for resetting sync records with detailed instructions in the sync settings.
- Introduced a version comparison utility function for better version handling in update checks.
- Updated Chinese translations for improved clarity on sync issues.
This commit is contained in:
troyeguo
2025-12-16 17:45:31 +08:00
parent 0b8e76785b
commit 3dc74a41fa
10 changed files with 72 additions and 18 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "koodo-reader",
"main": "main.js",
"version": "2.2.4",
"version": "2.2.2",
"description": "Koodo Reader is a cross-platform ebook reader",
"author": {
"name": "App by Troye",

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long

View File

@@ -210,6 +210,7 @@
"Change": "更改",
"We have two server regions(Global and China). To change the server region, you need to log out first. Do you want to log out now?": "我们有两个服务器地区:全球和中国。要更改服务器地区,您需要先退出登录。是否现在退出?",
"Tasks failed after multiple retries, please check the network connection": "多次重试后任务失败,请检查网络连接",
"There are some unwanted books, notes, highlights show up in other devices after sync is done. But the data in this device is normal. You can reset the sync record in this device, delete the KoodoReader folder in the data source(Turn off Koodo Sync if necessary), and sync again. This should resolve the issue.": "同步完成后,其他设备上出现了一些不需要的图书、笔记和高亮。但此设备中的数据是正常的。您可以在此设备中重置同步记录,删除数据源中的 KoodoReader 文件夹(如有必要,请关闭 Koodo Sync然后重新同步。这应该可以解决问题。",
"Tasks failed after multiple retries, please check the network connection or reauthorize the data source in the settings": "多次重试后任务失败,请检查网络连接或在设置中重新授权数据源",
"This data source already contains a library. If you need to merge local and cloud data, please turn off Koodo Sync and resync.": "此数据源已经存在了一个图书库,如果需要将本地和云端的数据合并。请关闭 Koodo Sync 后重新同步。",
"Render PDF from even page": "从偶数页开始渲染 PDF",

View File

@@ -5,7 +5,11 @@ import packageInfo from "../../../../package.json";
import { Trans } from "react-i18next";
import Lottie from "react-lottie";
import animationNew from "../../../assets/lotties/new.json";
import { getWebsiteUrl, openExternalUrl } from "../../../utils/common";
import {
compareVersions,
getWebsiteUrl,
openExternalUrl,
} from "../../../utils/common";
import { isElectron } from "react-device-detect";
import { sleep } from "../../../utils/common";
import {
@@ -60,7 +64,12 @@ class UpdateInfo extends React.Component<UpdateInfoProps, UpdateInfoState> {
if ((process as any).windowsStore) {
return;
}
if (packageInfo.version.localeCompare(newVersion) < 0) {
console.log(
packageInfo.version,
newVersion,
compareVersions(packageInfo.version, newVersion)
);
if (compareVersions(newVersion, packageInfo.version) > 0) {
if (
ConfigService.getReaderConfig("isDisableUpdate") !== "yes" ||
this.props.isAuthed

View File

@@ -387,6 +387,11 @@ class AccountSetting extends React.Component<
toast.error(this.props.t("Enter your email"));
return;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(this.state.loginConfig.email)) {
toast.error(this.props.t("Invalid email format"));
return;
}
if (this.state.isSendingCode || this.state.countdown) {
return;
}

View File

@@ -702,19 +702,28 @@ class SyncSetting extends React.Component<SettingInfoProps, SettingInfoState> {
{this.props.isAuthed && this.renderSwitchOption(syncSettingList)}
{this.props.isAuthed && (
<div className="setting-dialog-new-title">
<Trans>Reset sync records</Trans>
<>
<div className="setting-dialog-new-title">
<Trans>Reset sync records</Trans>
<span
className="change-location-button"
onClick={async () => {
await generateSyncRecord();
toast.success(this.props.t("Reset successful"));
}}
>
<Trans>Reset</Trans>
</span>
</div>
<span
className="change-location-button"
onClick={async () => {
await generateSyncRecord();
toast.success(this.props.t("Reset successful"));
}}
>
<Trans>Reset</Trans>
</span>
</div>
<p className="setting-option-subtitle">
<Trans>
{
"There are some unwanted books, notes, highlights show up in other devices after sync is done. But the data in this device is normal. You can reset the sync record in this device, delete the KoodoReader folder in the data source(Turn off Koodo Sync if necessary), and sync again. This should resolve the issue."
}
</Trans>
</p>
</>
)}
</>
);

View File

@@ -692,6 +692,11 @@ class Login extends React.Component<LoginProps, LoginState> {
toast.error(this.props.t("Enter your email"));
return;
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(this.state.loginConfig.email)) {
toast.error(this.props.t("Invalid email format"));
return;
}
if (this.state.isSendingCode || this.state.countdown) {
return;
}

View File

@@ -867,6 +867,7 @@ export const showTaskProgress = async (
),
{
id: "syncing",
duration: 6000,
}
);
clearInterval(timer);
@@ -906,6 +907,7 @@ export const showTaskProgress = async (
),
{
id: "syncing",
duration: 6000,
}
);
clearInterval(timer);
@@ -938,6 +940,29 @@ export const showTaskProgress = async (
}, 1000);
return timer;
};
export const compareVersions = (version1: string, version2: string) => {
// Split strings by '.' and convert segments to numbers
const parts1 = version1.split(".").map(Number);
const parts2 = version2.split(".").map(Number);
// Determine the maximum length to handle unequal segment counts
const maxLength = Math.max(parts1.length, parts2.length);
for (let i = 0; i < maxLength; i++) {
// Use 0 for missing segments in shorter versions
const part1 = parts1[i] || 0;
const part2 = parts2[i] || 0;
if (part1 > part2) {
return 1; // version1 is greater
}
if (part1 < part2) {
return -1; // version2 is greater
}
}
return 0; // Versions are equal
};
export const clearAllData = async () => {
localStorage.clear();
sessionStorage.clear();