210 lines
7.0 KiB
TypeScript
210 lines
7.0 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import Image from 'next/image';
|
|
import { useRouter } from 'next/navigation';
|
|
import { PiUserCircle } from 'react-icons/pi';
|
|
import { PiUserCircleCheck } from 'react-icons/pi';
|
|
import { MdCheck } from 'react-icons/md';
|
|
|
|
import { setAboutDialogVisible } from '@/components/AboutWindow';
|
|
import { isTauriAppPlatform, isWebAppPlatform } from '@/services/environment';
|
|
import { DOWNLOAD_READEST_URL } from '@/services/constants';
|
|
import { useAuth } from '@/context/AuthContext';
|
|
import { useEnv } from '@/context/EnvContext';
|
|
import { useSettingsStore } from '@/store/settingsStore';
|
|
import { useTranslation } from '@/hooks/useTranslation';
|
|
import { getStoragePlanData } from '@/utils/access';
|
|
import { navigateToLogin, navigateToProfile } from '@/utils/nav';
|
|
import { tauriHandleSetAlwaysOnTop, tauriHandleToggleFullScreen } from '@/utils/window';
|
|
import { QuotaType } from '@/types/user';
|
|
import MenuItem from '@/components/MenuItem';
|
|
import Quota from '@/components/Quota';
|
|
|
|
interface SettingsMenuProps {
|
|
setIsDropdownOpen?: (isOpen: boolean) => void;
|
|
}
|
|
|
|
const SettingsMenu: React.FC<SettingsMenuProps> = ({ setIsDropdownOpen }) => {
|
|
const _ = useTranslation();
|
|
const router = useRouter();
|
|
const { envConfig, appService } = useEnv();
|
|
const { token, user } = useAuth();
|
|
const { settings, setSettings, saveSettings } = useSettingsStore();
|
|
const [quotas, setQuotas] = React.useState<QuotaType[]>([]);
|
|
const [isAutoUpload, setIsAutoUpload] = useState(settings.autoUpload);
|
|
const [isAutoCheckUpdates, setIsAutoCheckUpdates] = useState(settings.autoCheckUpdates);
|
|
const [isAlwaysOnTop, setIsAlwaysOnTop] = useState(settings.alwaysOnTop);
|
|
const [isScreenWakeLock, setIsScreenWakeLock] = useState(settings.screenWakeLock);
|
|
const [isAutoImportBooksOnOpen, setIsAutoImportBooksOnOpen] = useState(
|
|
settings.autoImportBooksOnOpen,
|
|
);
|
|
|
|
const showAboutReadest = () => {
|
|
setAboutDialogVisible(true);
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
const downloadReadest = () => {
|
|
window.open(DOWNLOAD_READEST_URL, '_blank');
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
|
|
const handleUserLogin = () => {
|
|
navigateToLogin(router);
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
|
|
const handleUserProfile = () => {
|
|
navigateToProfile(router);
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
|
|
const handleReloadPage = () => {
|
|
window.location.reload();
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
|
|
const handleFullScreen = () => {
|
|
tauriHandleToggleFullScreen();
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
|
|
const toggleAlwaysOnTop = () => {
|
|
settings.alwaysOnTop = !settings.alwaysOnTop;
|
|
setSettings(settings);
|
|
saveSettings(envConfig, settings);
|
|
setIsAlwaysOnTop(settings.alwaysOnTop);
|
|
tauriHandleSetAlwaysOnTop(settings.alwaysOnTop);
|
|
setIsDropdownOpen?.(false);
|
|
};
|
|
|
|
const toggleAutoUploadBooks = () => {
|
|
settings.autoUpload = !settings.autoUpload;
|
|
setSettings(settings);
|
|
saveSettings(envConfig, settings);
|
|
setIsAutoUpload(settings.autoUpload);
|
|
|
|
if (settings.autoUpload && !user) {
|
|
navigateToLogin(router);
|
|
}
|
|
};
|
|
|
|
const toggleAutoImportBooksOnOpen = () => {
|
|
settings.autoImportBooksOnOpen = !settings.autoImportBooksOnOpen;
|
|
setSettings(settings);
|
|
saveSettings(envConfig, settings);
|
|
setIsAutoImportBooksOnOpen(settings.autoImportBooksOnOpen);
|
|
};
|
|
|
|
const toggleAutoCheckUpdates = () => {
|
|
settings.autoCheckUpdates = !settings.autoCheckUpdates;
|
|
setSettings(settings);
|
|
saveSettings(envConfig, settings);
|
|
setIsAutoCheckUpdates(settings.autoCheckUpdates);
|
|
};
|
|
|
|
const toggleScreenWakeLock = () => {
|
|
settings.screenWakeLock = !settings.screenWakeLock;
|
|
setSettings(settings);
|
|
saveSettings(envConfig, settings);
|
|
setIsScreenWakeLock(settings.screenWakeLock);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!user || !token) return;
|
|
const storagPlan = getStoragePlanData(token);
|
|
const storageQuota: QuotaType = {
|
|
name: _('Storage'),
|
|
tooltip: _('{{percentage}}% of Cloud Storage Used.', {
|
|
percentage: Math.round((storagPlan.usage / storagPlan.quota) * 100),
|
|
}),
|
|
used: Math.round(storagPlan.usage / 1024 / 1024),
|
|
total: Math.round(storagPlan.quota / 1024 / 1024),
|
|
unit: 'MB',
|
|
};
|
|
setQuotas([storageQuota]);
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [token]);
|
|
|
|
const isWebApp = isWebAppPlatform();
|
|
const avatarUrl = user?.user_metadata?.['picture'] || user?.user_metadata?.['avatar_url'];
|
|
const userFullName = user?.user_metadata?.['full_name'];
|
|
const userDisplayName = userFullName ? userFullName.split(' ')[0] : null;
|
|
|
|
return (
|
|
<div
|
|
tabIndex={0}
|
|
className='settings-menu dropdown-content no-triangle border-base-100 z-20 mt-2 shadow-2xl'
|
|
>
|
|
{user ? (
|
|
<MenuItem
|
|
label={
|
|
userDisplayName
|
|
? _('Logged in as {{userDisplayName}}', { userDisplayName })
|
|
: _('Logged in')
|
|
}
|
|
labelClass='!max-w-40'
|
|
Icon={
|
|
avatarUrl ? (
|
|
<Image
|
|
src={avatarUrl}
|
|
alt={_('User avatar')}
|
|
className='h-5 w-5 rounded-full'
|
|
referrerPolicy='no-referrer'
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
) : (
|
|
PiUserCircleCheck
|
|
)
|
|
}
|
|
>
|
|
<ul>
|
|
<Quota quotas={quotas} className='h-10 pl-3 pr-2' />
|
|
<MenuItem label={_('Account')} noIcon onClick={handleUserProfile} />
|
|
</ul>
|
|
</MenuItem>
|
|
) : (
|
|
<MenuItem label={_('Sign In')} Icon={PiUserCircle} onClick={handleUserLogin}></MenuItem>
|
|
)}
|
|
<MenuItem
|
|
label={_('Auto Upload Books to Cloud')}
|
|
Icon={isAutoUpload ? MdCheck : undefined}
|
|
onClick={toggleAutoUploadBooks}
|
|
/>
|
|
{isTauriAppPlatform() && !appService?.isMobile && (
|
|
<MenuItem
|
|
label={_('Auto Import on File Open')}
|
|
Icon={isAutoImportBooksOnOpen ? MdCheck : undefined}
|
|
onClick={toggleAutoImportBooksOnOpen}
|
|
/>
|
|
)}
|
|
{appService?.hasUpdater && (
|
|
<MenuItem
|
|
label={_('Check Updates on Start')}
|
|
Icon={isAutoCheckUpdates ? MdCheck : undefined}
|
|
onClick={toggleAutoCheckUpdates}
|
|
/>
|
|
)}
|
|
<hr className='border-base-200 my-1' />
|
|
{appService?.hasWindow && <MenuItem label={_('Fullscreen')} onClick={handleFullScreen} />}
|
|
{appService?.hasWindow && (
|
|
<MenuItem
|
|
label={_('Always on Top')}
|
|
Icon={isAlwaysOnTop ? MdCheck : undefined}
|
|
onClick={toggleAlwaysOnTop}
|
|
/>
|
|
)}
|
|
<MenuItem
|
|
label={_('Keep Screen Awake')}
|
|
Icon={isScreenWakeLock ? MdCheck : undefined}
|
|
onClick={toggleScreenWakeLock}
|
|
/>
|
|
<MenuItem label={_('Reload Page')} onClick={handleReloadPage} />
|
|
<hr className='border-base-200 my-1' />
|
|
{isWebApp && <MenuItem label={_('Download Readest')} onClick={downloadReadest} />}
|
|
<MenuItem label={_('About Readest')} onClick={showAboutReadest} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SettingsMenu;
|