feat: add fullscreen option for desktop app, closes #493 (#534)

This commit is contained in:
Huang Xin
2025-03-08 22:36:25 +08:00
committed by GitHub
parent 89f1c43984
commit 7f24081205
22 changed files with 69 additions and 30 deletions
@@ -232,5 +232,6 @@
"RTL Direction": "الاتجاه من اليمين إلى اليسار",
"Maximum Column Height": "الارتفاع الأقصى للعمود",
"Maximum Column Width": "العرض الأقصى للعمود",
"Continuous Scroll": "التمرير المستمر"
"Continuous Scroll": "التمرير المستمر",
"Fullscreen": "ملء الشاشة"
}
@@ -232,5 +232,6 @@
"RTL Direction": "RTL-Richtung",
"Maximum Column Height": "Maximale Spaltenhöhe",
"Maximum Column Width": "Maximale Spaltenbreite",
"Continuous Scroll": "Kontinuierliches Scrollen"
"Continuous Scroll": "Kontinuierliches Scrollen",
"Fullscreen": "Vollbild"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Κατεύθυνση RTL",
"Maximum Column Height": "Μέγιστο ύψος στήλης",
"Maximum Column Width": "Μέγιστο πλάτος στήλης",
"Continuous Scroll": "Συνεχής κύλιση"
"Continuous Scroll": "Συνεχής κύλιση",
"Fullscreen": "Πλήρης οθόνη"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Dirección RTL",
"Maximum Column Height": "Altura máxima de columna",
"Maximum Column Width": "Ancho máximo de columna",
"Continuous Scroll": "Desplazamiento continuo"
"Continuous Scroll": "Desplazamiento continuo",
"Fullscreen": "Pantalla completa"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Direction RTL",
"Maximum Column Height": "Hauteur maximale de colonne",
"Maximum Column Width": "Largeur maximale de colonne",
"Continuous Scroll": "Défilement continu"
"Continuous Scroll": "Défilement continu",
"Fullscreen": "Plein écran"
}
@@ -232,5 +232,6 @@
"RTL Direction": "RTL दिशा",
"Maximum Column Height": "कॉलम की अधिकतम ऊँचाई",
"Maximum Column Width": "कॉलम की अधिकतम चौड़ाई",
"Continuous Scroll": "निरंतर स्क्रॉल"
"Continuous Scroll": "निरंतर स्क्रॉल",
"Fullscreen": "पूर्णस्क्रीन"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Arah RTL",
"Maximum Column Height": "Tinggi Kolom Maksimum",
"Maximum Column Width": "Lebar Kolom Maksimum",
"Continuous Scroll": "Gulir Terus"
"Continuous Scroll": "Gulir Terus",
"Fullscreen": "Layar Penuh"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Direzione RTL",
"Maximum Column Height": "Altezza massima colonna",
"Maximum Column Width": "Larghezza massima colonna",
"Continuous Scroll": "Scorrimento continuo"
"Continuous Scroll": "Scorrimento continuo",
"Fullscreen": "Schermo intero"
}
@@ -232,5 +232,6 @@
"RTL Direction": "RTL方向",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列幅",
"Continuous Scroll": "連続スクロール"
"Continuous Scroll": "連続スクロール",
"Fullscreen": "全画面"
}
@@ -232,5 +232,6 @@
"RTL Direction": "RTL 방향",
"Maximum Column Height": "최대 열 높이",
"Maximum Column Width": "최대 열 너비",
"Continuous Scroll": "연속 스크롤"
"Continuous Scroll": "연속 스크롤",
"Fullscreen": "전체 화면"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Kierunek RTL",
"Maximum Column Height": "Maksymalna wysokość kolumny",
"Maximum Column Width": "Maksymalna szerokość kolumny",
"Continuous Scroll": "Przewijanie ciągłe"
"Continuous Scroll": "Przewijanie ciągłe",
"Fullscreen": "Pełny ekran"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Direção RTL",
"Maximum Column Height": "Altura Máxima da Coluna",
"Maximum Column Width": "Largura Máxima da Coluna",
"Continuous Scroll": "Rolagem Contínua"
"Continuous Scroll": "Rolagem Contínua",
"Fullscreen": "Tela Cheia"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Направление RTL",
"Maximum Column Height": "Максимальная высота колонки",
"Maximum Column Width": "Максимальная ширина колонки",
"Continuous Scroll": "Непрерывная прокрутка"
"Continuous Scroll": "Непрерывная прокрутка",
"Fullscreen": "Полноэкранный режим"
}
@@ -232,5 +232,6 @@
"RTL Direction": "RTL Yönü",
"Maximum Column Height": "Maksimum Sütun Yüksekliği",
"Maximum Column Width": "Maksimum Sütun Genişliği",
"Continuous Scroll": "Sürekli Kaydırma"
"Continuous Scroll": "Sürekli Kaydırma",
"Fullscreen": "Tam Ekran"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Напрямок RTL",
"Maximum Column Height": "Максимальна висота колонки",
"Maximum Column Width": "Максимальна ширина колонки",
"Continuous Scroll": "Постійна прокрутка"
"Continuous Scroll": "Постійна прокрутка",
"Fullscreen": "Повноекранний"
}
@@ -232,5 +232,6 @@
"RTL Direction": "Hướng RTL",
"Maximum Column Height": "Chiều cao cột tối đa",
"Maximum Column Width": "Chiều rộng cột tối đa",
"Continuous Scroll": "Cuộn liên tục"
"Continuous Scroll": "Cuộn liên tục",
"Fullscreen": "Toàn màn hình"
}
@@ -232,5 +232,6 @@
"RTL Direction": "从右向左",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列宽",
"Continuous Scroll": "连续滚动"
"Continuous Scroll": "连续滚动",
"Fullscreen": "全屏"
}
@@ -232,5 +232,6 @@
"RTL Direction": "從右向左",
"Maximum Column Height": "最大列高",
"Maximum Column Width": "最大列寬",
"Continuous Scroll": "連續滾動"
"Continuous Scroll": "連續滾動",
"Fullscreen": "全螢幕"
}
@@ -62,6 +62,7 @@
"core:window:allow-is-maximized",
"core:window:allow-start-dragging",
"core:window:allow-toggle-maximize",
"core:window:allow-set-fullscreen",
"shell:default",
"process:default",
"process:allow-exit",
@@ -14,6 +14,7 @@ import { useSettingsStore } from '@/store/settingsStore';
import { useTranslation } from '@/hooks/useTranslation';
import { getStoragePlanData } from '@/utils/access';
import { navigateToLogin, navigateToProfile } from '@/utils/nav';
import { tauriHandleToggleFullScreen } from '@/utils/window';
import { QuotaType } from '@/types/user';
import MenuItem from '@/components/MenuItem';
import Quota from '@/components/Quota';
@@ -25,7 +26,7 @@ interface BookMenuProps {
const SettingsMenu: React.FC<BookMenuProps> = ({ setIsDropdownOpen }) => {
const _ = useTranslation();
const router = useRouter();
const { envConfig } = useEnv();
const { envConfig, appService } = useEnv();
const { token, user } = useAuth();
const { settings, setSettings, saveSettings } = useSettingsStore();
const [quotas, setQuotas] = React.useState<QuotaType[]>([]);
@@ -57,6 +58,11 @@ const SettingsMenu: React.FC<BookMenuProps> = ({ setIsDropdownOpen }) => {
setIsDropdownOpen?.(false);
};
const handleFullScreen = () => {
tauriHandleToggleFullScreen();
setIsDropdownOpen?.(false);
};
const toggleAutoUploadBooks = () => {
settings.autoUpload = !settings.autoUpload;
setSettings(settings);
@@ -157,6 +163,9 @@ const SettingsMenu: React.FC<BookMenuProps> = ({ setIsDropdownOpen }) => {
onClick={toggleScreenWakeLock}
/>
<hr className='border-base-200 my-1' />
{appService?.hasRoundedWindow && (
<MenuItem label={_('Fullscreen')} onClick={handleFullScreen} />
)}
<MenuItem label={_('Reload Page')} onClick={handleReloadPage} />
<hr className='border-base-200 my-1' />
{isWebApp && <MenuItem label={_('Download Readest')} onClick={downloadReadest} />}
@@ -6,13 +6,15 @@ import { TbSunMoon } from 'react-icons/tb';
import { MdZoomOut, MdZoomIn, MdCheck } from 'react-icons/md';
import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL, ZOOM_STEP } from '@/services/constants';
import MenuItem from '@/components/MenuItem';
import { useEnv } from '@/context/EnvContext';
import { useThemeStore } from '@/store/themeStore';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { ThemeMode } from '@/styles/themes';
import { getStyles } from '@/utils/style';
import { getMaxInlineSize } from '@/utils/config';
import { tauriHandleToggleFullScreen } from '@/utils/window';
import MenuItem from '@/components/MenuItem';
interface ViewMenuProps {
bookKey: string;
@@ -26,6 +28,7 @@ const ViewMenu: React.FC<ViewMenuProps> = ({
onSetSettingsDialogOpen,
}) => {
const _ = useTranslation();
const { appService } = useEnv();
const { getView, getViews, getViewSettings, setViewSettings } = useReaderStore();
const viewSettings = getViewSettings(bookKey)!;
@@ -51,6 +54,11 @@ const ViewMenu: React.FC<ViewMenuProps> = ({
setThemeMode(nextMode);
};
const handleFullScreen = () => {
tauriHandleToggleFullScreen();
setIsDropdownOpen?.(false);
};
useEffect(() => {
getViews().forEach((view) => {
view.renderer.setStyles?.(getStyles(viewSettings!));
@@ -132,6 +140,9 @@ const ViewMenu: React.FC<ViewMenuProps> = ({
<hr className='border-base-300 my-1' />
{appService?.hasRoundedWindow && (
<MenuItem label={_('Fullscreen')} onClick={handleFullScreen} />
)}
<MenuItem
label={
themeMode === 'dark'
+10 -10
View File
@@ -1,7 +1,9 @@
import { getCurrentWindow } from '@tauri-apps/api/window';
import { TauriEvent } from '@tauri-apps/api/event';
import { exit } from '@tauri-apps/plugin-process';
import { eventDispatcher } from './event';
export const tauriGetWindowLogicalPosition = async () => {
const { getCurrentWindow } = await import('@tauri-apps/api/window');
const currentWindow = getCurrentWindow();
const factor = await currentWindow.scaleFactor();
const physicalPos = await currentWindow.outerPosition();
@@ -9,24 +11,18 @@ export const tauriGetWindowLogicalPosition = async () => {
};
export const tauriHandleMinimize = async () => {
const { getCurrentWindow } = await import('@tauri-apps/api/window');
getCurrentWindow().minimize();
};
export const tauriHandleToggleMaximize = async () => {
const { getCurrentWindow } = await import('@tauri-apps/api/window');
getCurrentWindow().toggleMaximize();
};
export const tauriHandleClose = async () => {
const { getCurrentWindow } = await import('@tauri-apps/api/window');
getCurrentWindow().close();
};
export const tauriHandleOnCloseWindow = async (callback: () => void) => {
const { TauriEvent } = await import('@tauri-apps/api/event');
const { getCurrentWindow } = await import('@tauri-apps/api/window');
const { exit } = await import('@tauri-apps/plugin-process');
const currentWindow = getCurrentWindow();
return currentWindow.listen(TauriEvent.WINDOW_CLOSE_REQUESTED, async () => {
await callback();
@@ -35,9 +31,14 @@ export const tauriHandleOnCloseWindow = async (callback: () => void) => {
});
};
export const tauriHandleToggleFullScreen = async () => {
const currentWindow = getCurrentWindow();
const isFullscreen = await currentWindow.isFullscreen();
const newIsFullscreen = !isFullscreen;
await currentWindow.setFullscreen(newIsFullscreen);
};
export const tauriHandleOnWindowFocus = async (callback: () => void) => {
const { TauriEvent } = await import('@tauri-apps/api/event');
const { getCurrentWindow } = await import('@tauri-apps/api/window');
const currentWindow = getCurrentWindow();
return currentWindow.listen(TauriEvent.WINDOW_FOCUS, async () => {
await callback();
@@ -46,6 +47,5 @@ export const tauriHandleOnWindowFocus = async (callback: () => void) => {
export const tauriQuitApp = async () => {
await eventDispatcher.dispatch('quit-app');
const { exit } = await import('@tauri-apps/plugin-process');
await exit(0);
};