forked from akai/readest
@@ -476,5 +476,6 @@
|
||||
"Failed to create checkout session": "فشل في إنشاء جلسة الدفع",
|
||||
"Storage": "التخزين",
|
||||
"Terms of Service": "شروط الخدمة",
|
||||
"Privacy Policy": "سياسة الخصوصية"
|
||||
"Privacy Policy": "سياسة الخصوصية",
|
||||
"Disable Double Click": "تعطيل النقر المزدوج"
|
||||
}
|
||||
|
||||
@@ -460,5 +460,6 @@
|
||||
"Failed to create checkout session": "Fehler beim Erstellen der Checkout-Sitzung",
|
||||
"Storage": "Speicher",
|
||||
"Terms of Service": "Allgemeine Geschäftsbedingungen",
|
||||
"Privacy Policy": "Datenschutzbestimmungen"
|
||||
"Privacy Policy": "Datenschutzbestimmungen",
|
||||
"Disable Double Click": "Doppelklick deaktivieren"
|
||||
}
|
||||
|
||||
@@ -460,5 +460,6 @@
|
||||
"Failed to create checkout session": "Αποτυχία δημιουργίας συνεδρίας πληρωμής",
|
||||
"Storage": "Αποθήκευση",
|
||||
"Terms of Service": "Όροι χρήσης",
|
||||
"Privacy Policy": "Πολιτική απορρήτου"
|
||||
"Privacy Policy": "Πολιτική απορρήτου",
|
||||
"Disable Double Click": "Απενεργοποίηση διπλού κλικ"
|
||||
}
|
||||
|
||||
@@ -464,5 +464,6 @@
|
||||
"Failed to create checkout session": "Error al crear la sesión de pago",
|
||||
"Storage": "Almacenamiento",
|
||||
"Terms of Service": "Condiciones del servicio",
|
||||
"Privacy Policy": "Política de privacidad"
|
||||
"Privacy Policy": "Política de privacidad",
|
||||
"Disable Double Click": "Deshabilitar Doble Clic"
|
||||
}
|
||||
|
||||
@@ -464,5 +464,6 @@
|
||||
"Failed to create checkout session": "Échec de la création de la session de paiement",
|
||||
"Storage": "Stockage",
|
||||
"Terms of Service": "Conditions d'utilisation",
|
||||
"Privacy Policy": "Politique de confidentialité"
|
||||
"Privacy Policy": "Politique de confidentialité",
|
||||
"Disable Double Click": "Désactiver le double-clic"
|
||||
}
|
||||
|
||||
@@ -460,5 +460,6 @@
|
||||
"Failed to create checkout session": "चेकआउट सत्र बनाने में विफल",
|
||||
"Storage": "भंडारण",
|
||||
"Terms of Service": "सेवा की शर्तें",
|
||||
"Privacy Policy": "गोपनीयता नीति"
|
||||
"Privacy Policy": "गोपनीयता नीति",
|
||||
"Disable Double Click": "डबल क्लिक अक्षम करें"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "Gagal membuat sesi checkout",
|
||||
"Storage": "Penyimpanan",
|
||||
"Terms of Service": "Ketentuan Layanan",
|
||||
"Privacy Policy": "Kebijakan Privasi"
|
||||
"Privacy Policy": "Kebijakan Privasi",
|
||||
"Disable Double Click": "Nonaktifkan Klik Ganda"
|
||||
}
|
||||
|
||||
@@ -464,5 +464,6 @@
|
||||
"Failed to create checkout session": "Impossibile creare la sessione di checkout",
|
||||
"Storage": "Archiviazione",
|
||||
"Terms of Service": "Termini di servizio",
|
||||
"Privacy Policy": "Informativa sulla privacy"
|
||||
"Privacy Policy": "Informativa sulla privacy",
|
||||
"Disable Double Click": "Disabilita Doppio Clic"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "チェックアウトセッションの作成に失敗しました",
|
||||
"Storage": "ストレージ",
|
||||
"Terms of Service": "利用規約",
|
||||
"Privacy Policy": "プライバシーポリシー"
|
||||
"Privacy Policy": "プライバシーポリシー",
|
||||
"Disable Double Click": "ダブルクリック無効"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "체크아웃 세션 생성 실패",
|
||||
"Storage": "저장소",
|
||||
"Terms of Service": "서비스 약관",
|
||||
"Privacy Policy": "개인정보 보호정책"
|
||||
"Privacy Policy": "개인정보 보호정책",
|
||||
"Disable Double Click": "더블 클릭 비활성화"
|
||||
}
|
||||
|
||||
@@ -460,5 +460,6 @@
|
||||
"Failed to create checkout session": "Kon de afreken sessie niet aanmaken",
|
||||
"Storage": "Opslag",
|
||||
"Terms of Service": "Gebruiksvoorwaarden",
|
||||
"Privacy Policy": "Privacybeleid"
|
||||
"Privacy Policy": "Privacybeleid",
|
||||
"Disable Double Click": "Dubbelklikken uitschakelen"
|
||||
}
|
||||
|
||||
@@ -468,5 +468,6 @@
|
||||
"Failed to create checkout session": "Nie udało się utworzyć sesji zakupu",
|
||||
"Storage": "Przechowywanie",
|
||||
"Terms of Service": "Warunki korzystania z usługi",
|
||||
"Privacy Policy": "Polityka prywatności"
|
||||
"Privacy Policy": "Polityka prywatności",
|
||||
"Disable Double Click": "Wyłącz podwójne kliknięcie"
|
||||
}
|
||||
|
||||
@@ -464,5 +464,6 @@
|
||||
"Failed to create checkout session": "Falha ao criar sessão de checkout",
|
||||
"Storage": "Armazenamento",
|
||||
"Terms of Service": "Termos de Serviço",
|
||||
"Privacy Policy": "Política de Privacidade"
|
||||
"Privacy Policy": "Política de Privacidade",
|
||||
"Disable Double Click": "Desativar Clique Duplo"
|
||||
}
|
||||
|
||||
@@ -468,5 +468,6 @@
|
||||
"Failed to create checkout session": "Не удалось создать сессию оформления заказа",
|
||||
"Storage": "Хранилище",
|
||||
"Terms of Service": "Условия использования",
|
||||
"Privacy Policy": "Политика конфиденциальности"
|
||||
"Privacy Policy": "Политика конфиденциальности",
|
||||
"Disable Double Click": "Отключить двойной клик"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "ไม่สามารถสร้างเซสชันการชำระเงินได้",
|
||||
"Storage": "พื้นที่เก็บข้อมูล",
|
||||
"Terms of Service": "ข้อกำหนดในการให้บริการ",
|
||||
"Privacy Policy": "นโยบายความเป็นส่วนตัว"
|
||||
"Privacy Policy": "นโยบายความเป็นส่วนตัว",
|
||||
"Disable Double Click": "ปิดการคลิกสองครั้ง"
|
||||
}
|
||||
|
||||
@@ -460,5 +460,6 @@
|
||||
"Failed to create checkout session": "Ödeme oturumu oluşturma başarısız oldu",
|
||||
"Storage": "Depolama",
|
||||
"Terms of Service": "Hizmet Şartları",
|
||||
"Privacy Policy": "Gizlilik Politikası"
|
||||
"Privacy Policy": "Gizlilik Politikası",
|
||||
"Disable Double Click": "Çift Tıklamayı Devre Dışı Bırak"
|
||||
}
|
||||
|
||||
@@ -468,5 +468,6 @@
|
||||
"Failed to create checkout session": "Не вдалося створити сесію оформлення замовлення",
|
||||
"Storage": "Сховище",
|
||||
"Terms of Service": "Умови обслуговування",
|
||||
"Privacy Policy": "Політика конфіденційності"
|
||||
"Privacy Policy": "Політика конфіденційності",
|
||||
"Disable Double Click": "Вимкнути подвійне клацання"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "Không thể tạo phiên làm việc thanh toán",
|
||||
"Storage": "Lưu trữ",
|
||||
"Terms of Service": "Điều khoản dịch vụ",
|
||||
"Privacy Policy": "Chính sách bảo mật"
|
||||
"Privacy Policy": "Chính sách bảo mật",
|
||||
"Disable Double Click": "Tắt Nhấp Đôi"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "创建结账会话失败",
|
||||
"Storage": "云同步空间",
|
||||
"Terms of Service": "服务条款",
|
||||
"Privacy Policy": "隐私政策"
|
||||
"Privacy Policy": "隐私政策",
|
||||
"Disable Double Click": "禁用双击"
|
||||
}
|
||||
|
||||
@@ -456,5 +456,6 @@
|
||||
"Failed to create checkout session": "創建結帳會話失敗",
|
||||
"Storage": "雲同步空間",
|
||||
"Terms of Service": "服務條款",
|
||||
"Privacy Policy": "隱私政策"
|
||||
"Privacy Policy": "隱私政策",
|
||||
"Disable Double Click": "禁用雙擊"
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ const FoliateViewer: React.FC<{
|
||||
const viewRef = useRef<FoliateView | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const isViewCreated = useRef(false);
|
||||
const doubleClickDisabled = useRef(!!viewSettings?.disableDoubleClick);
|
||||
const [toastMessage, setToastMessage] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
@@ -159,7 +160,7 @@ const FoliateViewer: React.FC<{
|
||||
detail.doc.addEventListener('keydown', handleKeydown.bind(null, bookKey));
|
||||
detail.doc.addEventListener('mousedown', handleMousedown.bind(null, bookKey));
|
||||
detail.doc.addEventListener('mouseup', handleMouseup.bind(null, bookKey));
|
||||
detail.doc.addEventListener('click', handleClick.bind(null, bookKey));
|
||||
detail.doc.addEventListener('click', handleClick.bind(null, bookKey, doubleClickDisabled));
|
||||
detail.doc.addEventListener('wheel', handleWheel.bind(null, bookKey));
|
||||
detail.doc.addEventListener('touchstart', handleTouchStart.bind(null, bookKey));
|
||||
detail.doc.addEventListener('touchmove', handleTouchMove.bind(null, bookKey));
|
||||
@@ -256,6 +257,7 @@ const FoliateViewer: React.FC<{
|
||||
view.renderer.setStyles?.(getStyles(viewSettings));
|
||||
applyTranslationStyle(viewSettings);
|
||||
|
||||
doubleClickDisabled.current = viewSettings.disableDoubleClick!;
|
||||
const animated = viewSettings.animated!;
|
||||
const maxColumnCount = viewSettings.maxColumnCount!;
|
||||
const maxInlineSize = getMaxInlineSize(viewSettings);
|
||||
@@ -325,6 +327,12 @@ const FoliateViewer: React.FC<{
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [themeCode, isDarkMode, viewSettings?.overrideColor, viewSettings?.invertImgColorInDark]);
|
||||
|
||||
useEffect(() => {
|
||||
if (viewRef.current && viewRef.current.renderer) {
|
||||
doubleClickDisabled.current = !!viewSettings?.disableDoubleClick;
|
||||
}
|
||||
}, [viewSettings?.disableDoubleClick]);
|
||||
|
||||
useEffect(() => {
|
||||
if (viewRef.current && viewRef.current.renderer && viewSettings) {
|
||||
applyMarginAndGap();
|
||||
|
||||
@@ -27,6 +27,9 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
|
||||
const [volumeKeysToFlip, setVolumeKeysToFlip] = useState(viewSettings.volumeKeysToFlip!);
|
||||
const [isDisableClick, setIsDisableClick] = useState(viewSettings.disableClick!);
|
||||
const [swapClickArea, setSwapClickArea] = useState(viewSettings.swapClickArea!);
|
||||
const [isDisableDoubleClick, setIsDisableDoubleClick] = useState(
|
||||
viewSettings.disableDoubleClick!,
|
||||
);
|
||||
const [animated, setAnimated] = useState(viewSettings.animated!);
|
||||
const [allowScript, setAllowScript] = useState(viewSettings.allowScript!);
|
||||
|
||||
@@ -90,6 +93,11 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isDisableClick]);
|
||||
|
||||
useEffect(() => {
|
||||
saveViewSettings(envConfig, bookKey, 'disableDoubleClick', isDisableDoubleClick, false, false);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isDisableDoubleClick]);
|
||||
|
||||
useEffect(() => {
|
||||
saveViewSettings(envConfig, bookKey, 'swapClickArea', swapClickArea, false, false);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -172,6 +180,15 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
|
||||
onChange={() => setSwapClickArea(!swapClickArea)}
|
||||
/>
|
||||
</div>
|
||||
<div className='config-item'>
|
||||
<span className=''>{_('Disable Double Click')}</span>
|
||||
<input
|
||||
type='checkbox'
|
||||
className='toggle'
|
||||
checked={isDisableDoubleClick}
|
||||
onChange={() => setIsDisableDoubleClick(!isDisableDoubleClick)}
|
||||
/>
|
||||
</div>
|
||||
{appService?.isMobileApp && (
|
||||
<div className='config-item'>
|
||||
<span className=''>{_('Volume Keys for Page Flip')}</span>
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
import {
|
||||
DISABLE_DOUBLE_CLICK_ON_MOBILE,
|
||||
DOUBLE_CLICK_INTERVAL_THRESHOLD_MS,
|
||||
LONG_HOLD_THRESHOLD,
|
||||
} from '@/services/constants';
|
||||
import { DOUBLE_CLICK_INTERVAL_THRESHOLD_MS, LONG_HOLD_THRESHOLD } from '@/services/constants';
|
||||
import { eventDispatcher } from '@/utils/event';
|
||||
import { getOSPlatform } from '@/utils/misc';
|
||||
|
||||
const doubleClickEnabled =
|
||||
!DISABLE_DOUBLE_CLICK_ON_MOBILE || !['android', 'ios'].includes(getOSPlatform());
|
||||
|
||||
let lastClickTime = 0;
|
||||
let longHoldTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
@@ -93,10 +85,14 @@ export const handleWheel = (bookKey: string, event: WheelEvent) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const handleClick = (bookKey: string, event: MouseEvent) => {
|
||||
export const handleClick = (
|
||||
bookKey: string,
|
||||
doubleClickDisabled: React.MutableRefObject<boolean>,
|
||||
event: MouseEvent,
|
||||
) => {
|
||||
const now = Date.now();
|
||||
|
||||
if (doubleClickEnabled && now - lastClickTime < DOUBLE_CLICK_INTERVAL_THRESHOLD_MS) {
|
||||
if (!doubleClickDisabled.current && now - lastClickTime < DOUBLE_CLICK_INTERVAL_THRESHOLD_MS) {
|
||||
lastClickTime = now;
|
||||
window.postMessage(
|
||||
{
|
||||
@@ -156,7 +152,7 @@ export const handleClick = (bookKey: string, event: MouseEvent) => {
|
||||
'*',
|
||||
);
|
||||
};
|
||||
if (doubleClickEnabled) {
|
||||
if (!doubleClickDisabled.current) {
|
||||
setTimeout(() => {
|
||||
if (Date.now() - lastClickTime >= DOUBLE_CLICK_INTERVAL_THRESHOLD_MS) {
|
||||
postSingleClick();
|
||||
|
||||
@@ -105,6 +105,7 @@ export const DEFAULT_BOOK_LAYOUT: BookLayout = {
|
||||
scrolled: false,
|
||||
disableClick: false,
|
||||
swapClickArea: false,
|
||||
disableDoubleClick: false,
|
||||
volumeKeysToFlip: false,
|
||||
continuousScroll: false,
|
||||
maxColumnCount: 2,
|
||||
@@ -143,6 +144,7 @@ export const DEFAULT_MOBILE_VIEW_SETTINGS: Partial<ViewSettings> = {
|
||||
animated: true,
|
||||
defaultFont: 'Sans-serif',
|
||||
marginBottomPx: 16,
|
||||
disableDoubleClick: true,
|
||||
};
|
||||
|
||||
export const DEFAULT_CJK_VIEW_SETTINGS: Partial<ViewSettings> = {
|
||||
|
||||
@@ -92,6 +92,7 @@ export interface BookLayout {
|
||||
scrolled: boolean;
|
||||
disableClick: boolean;
|
||||
swapClickArea: boolean;
|
||||
disableDoubleClick: boolean;
|
||||
volumeKeysToFlip: boolean;
|
||||
continuousScroll: boolean;
|
||||
maxColumnCount: number;
|
||||
|
||||
Reference in New Issue
Block a user