@@ -334,8 +334,10 @@ export default function AuthPage() {
|
||||
return isTauriAppPlatform() ? (
|
||||
<div
|
||||
className={clsx(
|
||||
'fixed inset-0 z-0 flex select-none flex-col items-center overflow-y-auto',
|
||||
'bg-base-100 border-base-200 border',
|
||||
'bg-base-100 fixed inset-0 flex select-none flex-col items-center overflow-hidden overflow-y-auto',
|
||||
appService?.isIOSApp ? 'h-[100vh]' : 'h-dvh',
|
||||
appService?.isLinuxApp && 'window-border',
|
||||
appService?.hasRoundedWindow && 'rounded-window',
|
||||
appService?.hasSafeAreaInset && 'pt-[env(safe-area-inset-top)]',
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -669,6 +669,7 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
|
||||
className={clsx(
|
||||
'library-page bg-base-200 text-base-content flex select-none flex-col overflow-hidden',
|
||||
appService?.isIOSApp ? 'h-[100vh]' : 'h-dvh',
|
||||
appService?.isLinuxApp && 'window-border',
|
||||
appService?.hasRoundedWindow && 'rounded-window',
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -31,7 +31,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
|
||||
const { getConfig, getBookData } = useBookDataStore();
|
||||
const { getProgress, getViewState, getViewSettings } = useReaderStore();
|
||||
const { setGridInsets, hoveredBookKey } = useReaderStore();
|
||||
const { isSideBarVisible, sideBarBookKey } = useSidebarStore();
|
||||
const { sideBarBookKey } = useSidebarStore();
|
||||
const { isFontLayoutSettingsDialogOpen, setFontLayoutSettingsDialogOpen } = useSettingsStore();
|
||||
|
||||
const screenInsets = useSafeAreaInsets();
|
||||
@@ -106,7 +106,7 @@ const BooksGrid: React.FC<BooksGridProps> = ({ bookKeys, onCloseBook }) => {
|
||||
key={bookKey}
|
||||
className={clsx(
|
||||
'relative h-full w-full overflow-hidden',
|
||||
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window',
|
||||
appService?.hasRoundedWindow && 'rounded-window',
|
||||
)}
|
||||
>
|
||||
{isBookmarked && !hoveredBookKey && <Ribbon width={`${horizontalGapPercent}%`} />}
|
||||
|
||||
@@ -92,6 +92,7 @@ const HeaderBar: React.FC<HeaderBarProps> = ({
|
||||
<div
|
||||
className={clsx(
|
||||
'bg-base-100 absolute left-0 right-0 top-0 z-10',
|
||||
appService?.hasRoundedWindow && 'rounded-window-top-right',
|
||||
isVisible ? 'visible' : 'hidden',
|
||||
)}
|
||||
style={{
|
||||
|
||||
@@ -111,8 +111,9 @@ const Reader: React.FC<{ ids?: string }> = ({ ids }) => {
|
||||
settings.globalReadSettings && (
|
||||
<div
|
||||
className={clsx(
|
||||
`reader-page bg-base-100 text-base-content select-none`,
|
||||
!isSideBarVisible && appService?.hasRoundedWindow && 'rounded-window',
|
||||
`reader-page bg-base-100 text-base-content select-none overflow-hidden`,
|
||||
appService?.isLinuxApp && 'window-border',
|
||||
appService?.hasRoundedWindow && 'rounded-window',
|
||||
)}
|
||||
>
|
||||
<Suspense>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { MdBookmarkBorder as BookmarkIcon } from 'react-icons/md';
|
||||
import { IoIosList as TOCIcon } from 'react-icons/io';
|
||||
import { PiNotePencil as NoteIcon } from 'react-icons/pi';
|
||||
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
|
||||
const TabNavigation: React.FC<{
|
||||
@@ -11,12 +12,16 @@ const TabNavigation: React.FC<{
|
||||
onTabChange: (tab: string) => void;
|
||||
}> = ({ activeTab, onTabChange }) => {
|
||||
const _ = useTranslation();
|
||||
const { appService } = useEnv();
|
||||
|
||||
const tabs = ['toc', 'annotations', 'bookmarks'];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx('bottom-tab border-base-300/50 bg-base-200 relative flex w-full border-t')}
|
||||
className={clsx(
|
||||
'bottom-tab border-base-300/50 bg-base-200 relative flex w-full border-t',
|
||||
appService?.hasRoundedWindow && 'rounded-window-bottom-left',
|
||||
)}
|
||||
dir='ltr'
|
||||
>
|
||||
<div
|
||||
|
||||
@@ -69,7 +69,7 @@ const ProfilePage = () => {
|
||||
|
||||
useTheme({ systemUIVisible: false });
|
||||
|
||||
const { quotas, userPlan } = useQuotaStats();
|
||||
const { quotas, userPlan = 'free' } = useQuotaStats();
|
||||
|
||||
const handleGoBack = () => {
|
||||
if (showEmbeddedCheckout) {
|
||||
@@ -219,62 +219,66 @@ const ProfilePage = () => {
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'fixed inset-0 z-0 flex select-none flex-col items-center overflow-y-auto',
|
||||
'bg-base-100 border-base-200 border',
|
||||
'bg-base-100 fixed inset-0 select-none overflow-hidden',
|
||||
appService?.isIOSApp ? 'h-[100vh]' : 'h-dvh',
|
||||
appService?.isLinuxApp && 'window-border',
|
||||
appService?.hasRoundedWindow && 'rounded-window',
|
||||
appService?.hasSafeAreaInset && 'pt-[env(safe-area-inset-top)]',
|
||||
)}
|
||||
>
|
||||
<ProfileHeader onGoBack={handleGoBack} />
|
||||
<div className='w-full min-w-60 max-w-4xl py-10'>
|
||||
{loading && (
|
||||
<div className='fixed inset-0 z-50 flex items-center justify-center'>
|
||||
<Spinner loading />
|
||||
</div>
|
||||
)}
|
||||
{showEmbeddedCheckout ? (
|
||||
<div className='bg-base-100 rounded-lg p-4'>
|
||||
<Checkout
|
||||
clientSecret={checkoutState.clientSecret}
|
||||
sessionId={checkoutState.sessionId}
|
||||
planName={checkoutState.planName}
|
||||
onSuccess={handleCheckoutSuccess}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className='sm:bg-base-200 overflow-hidden rounded-lg sm:p-6 sm:shadow-md'>
|
||||
<div className='flex flex-col gap-y-8'>
|
||||
<div className='flex flex-col gap-y-8 px-6'>
|
||||
<UserInfo
|
||||
avatarUrl={avatarUrl}
|
||||
userFullName={userFullName}
|
||||
userEmail={userEmail}
|
||||
planDetails={planDetails}
|
||||
/>
|
||||
<div className='flex h-full w-full flex-col items-center overflow-y-auto'>
|
||||
<ProfileHeader onGoBack={handleGoBack} />
|
||||
<div className='w-full min-w-60 max-w-4xl py-10'>
|
||||
{loading && (
|
||||
<div className='fixed inset-0 z-50 flex items-center justify-center'>
|
||||
<Spinner loading />
|
||||
</div>
|
||||
)}
|
||||
{showEmbeddedCheckout ? (
|
||||
<div className='bg-base-100 rounded-lg p-4'>
|
||||
<Checkout
|
||||
clientSecret={checkoutState.clientSecret}
|
||||
sessionId={checkoutState.sessionId}
|
||||
planName={checkoutState.planName}
|
||||
onSuccess={handleCheckoutSuccess}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className='sm:bg-base-200 overflow-hidden rounded-lg sm:p-6 sm:shadow-md'>
|
||||
<div className='flex flex-col gap-y-8'>
|
||||
<div className='flex flex-col gap-y-8 px-6'>
|
||||
<UserInfo
|
||||
avatarUrl={avatarUrl}
|
||||
userFullName={userFullName}
|
||||
userEmail={userEmail}
|
||||
planDetails={planDetails}
|
||||
/>
|
||||
|
||||
<UsageStats quotas={quotas} />
|
||||
</div>
|
||||
<UsageStats quotas={quotas} />
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-y-8 sm:px-6'>
|
||||
<PlansComparison
|
||||
availablePlans={availablePlans}
|
||||
userPlan={userPlan}
|
||||
onSubscribe={handleSubscribe}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex flex-col gap-y-8 sm:px-6'>
|
||||
<PlansComparison
|
||||
availablePlans={availablePlans}
|
||||
userPlan={userPlan}
|
||||
onSubscribe={handleSubscribe}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-y-8 px-6'>
|
||||
<AccountActions
|
||||
userPlan={userPlan}
|
||||
onLogout={handleLogout}
|
||||
onConfirmDelete={handleConfirmDelete}
|
||||
onManageSubscription={handleManageSubscription}
|
||||
/>
|
||||
<div className='flex flex-col gap-y-8 px-6'>
|
||||
<AccountActions
|
||||
userPlan={userPlan}
|
||||
onLogout={handleLogout}
|
||||
onConfirmDelete={handleConfirmDelete}
|
||||
onManageSubscription={handleManageSubscription}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
<Toast />
|
||||
</div>
|
||||
<Toast />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -160,7 +160,11 @@ const Dialog: React.FC<DialogProps> = ({
|
||||
dir={isRtl ? 'rtl' : undefined}
|
||||
>
|
||||
<div
|
||||
className={clsx('overlay fixed inset-0 z-10 bg-black/50 sm:bg-black/20', bgClassName)}
|
||||
className={clsx(
|
||||
'overlay fixed inset-0 z-10 bg-black/50 sm:bg-black/20',
|
||||
appService?.hasRoundedWindow && 'rounded-window',
|
||||
bgClassName,
|
||||
)}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<div
|
||||
|
||||
@@ -8,7 +8,7 @@ export const useQuotaStats = () => {
|
||||
const _ = useTranslation();
|
||||
const { token, user } = useAuth();
|
||||
const [quotas, setQuotas] = useState<QuotaType[]>([]);
|
||||
const [userPlan, setUserPlan] = useState<UserPlan>('free');
|
||||
const [userPlan, setUserPlan] = useState<UserPlan | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
if (!user || !token) return;
|
||||
|
||||
@@ -220,7 +220,7 @@ export class NativeAppService extends BaseAppService {
|
||||
override hasWindow = !(OS_TYPE === 'ios' || OS_TYPE === 'android');
|
||||
override hasWindowBar = !(OS_TYPE === 'ios' || OS_TYPE === 'android');
|
||||
override hasContextMenu = !(OS_TYPE === 'ios' || OS_TYPE === 'android');
|
||||
override hasRoundedWindow = !(OS_TYPE === 'ios' || OS_TYPE === 'android') && !!window.IS_ROUNDED;
|
||||
override hasRoundedWindow = OS_TYPE === 'linux';
|
||||
override hasSafeAreaInset = OS_TYPE === 'ios' || OS_TYPE === 'android';
|
||||
override hasHaptics = OS_TYPE === 'ios' || OS_TYPE === 'android';
|
||||
override hasUpdater =
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
border-radius: 10px;
|
||||
scrollbar-gutter: auto !important;
|
||||
overscroll-behavior: none;
|
||||
background-color: transparent;
|
||||
|
||||
--safe-area-inset-top: env(safe-area-inset-top);
|
||||
--safe-area-inset-right: env(safe-area-inset-right);
|
||||
@@ -97,6 +98,25 @@ foliate-view {
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
|
||||
.window-border {
|
||||
border-radius: 10px;
|
||||
z-index: 999;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.window-border::before {
|
||||
content: '';
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border: 1px solid theme('colors.base-300');
|
||||
border-radius: 10px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
position: relative;
|
||||
@apply bg-base-100;
|
||||
|
||||
Reference in New Issue
Block a user