compat(android): show button navigation bar on Android, closes #3466 (#3501)

This commit is contained in:
Huang Xin
2026-03-10 00:36:13 +08:00
committed by GitHub
parent 5fbbfa523b
commit fad27d74a0
8 changed files with 45 additions and 16 deletions
@@ -285,7 +285,7 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
}
if (visible) {
controller.show(WindowInsets.Type.statusBars())
controller.hide(WindowInsets.Type.navigationBars())
controller.show(WindowInsets.Type.navigationBars())
} else {
controller.hide(WindowInsets.Type.systemBars())
}
@@ -301,7 +301,7 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
}
if (visible) {
it.show(WindowInsetsCompat.Type.statusBars())
it.hide(WindowInsetsCompat.Type.navigationBars())
it.show(WindowInsetsCompat.Type.navigationBars())
} else {
it.hide(WindowInsetsCompat.Type.systemBars())
}
@@ -79,7 +79,14 @@ export const ColorPanel: React.FC<ColorPanelProps> = ({ actionTab, bottomOffset
);
return (
<div className={classes} style={{ bottom: bottomOffset }}>
<div
className={classes}
style={{
bottom: appService?.isAndroidApp
? `calc(env(safe-area-inset-bottom) + 64px)`
: bottomOffset,
}}
>
{appService?.hasScreenBrightness && (
<Slider
label={_('Screen Brightness')}
@@ -41,7 +41,7 @@ export const FontLayoutPanel: React.FC<FontLayoutPanelProps> = ({
marginIconSize,
}) => {
const _ = useTranslation();
const { envConfig } = useEnv();
const { envConfig, appService } = useEnv();
const { getView, getViewSettings } = useReaderStore();
const viewSettings = getViewSettings(bookKey);
const view = getView(bookKey);
@@ -98,7 +98,14 @@ export const FontLayoutPanel: React.FC<FontLayoutPanelProps> = ({
);
return (
<div className={classes} style={{ bottom: bottomOffset }}>
<div
className={classes}
style={{
bottom: appService?.isAndroidApp
? `calc(env(safe-area-inset-bottom) + 64px)`
: bottomOffset,
}}
>
<Slider
label={_('Font Size')}
initialValue={viewSettings?.defaultFontSize ?? FONT_SIZE_LIMITS.DEFAULT}
@@ -19,7 +19,6 @@ const MobileFooterBar: React.FC<FooterBarChildProps> = ({
const sliderHeight = useResponsiveSize(28);
const marginIconSize = useResponsiveSize(20);
const bottomOffset = isMobile ? `${gridInsets.bottom * 0.33 + 64}px` : '64px';
const navPadding = isMobile ? `${gridInsets.bottom * 0.33 + 16}px` : '0px';
return (
<>
@@ -42,7 +41,7 @@ const MobileFooterBar: React.FC<FooterBarChildProps> = ({
<NavigationBar
bookKey={bookKey}
actionTab={actionTab}
navPadding={navPadding}
gridInsets={gridInsets}
onSetActionTab={onSetActionTab!}
/>
</>
@@ -5,34 +5,43 @@ import { RxSlider as SliderIcon } from 'react-icons/rx';
import { RiFontFamily as FontIcon } from 'react-icons/ri';
import { PiSun as ColorIcon } from 'react-icons/pi';
import { MdOutlineHeadphones as TTSIcon } from 'react-icons/md';
import { useEnv } from '@/context/EnvContext';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import Button from '@/components/Button';
import { Insets } from '@/types/misc';
interface NavigationBarProps {
bookKey: string;
actionTab: string;
navPadding: string;
gridInsets: Insets;
onSetActionTab: (tab: string) => void;
}
export const NavigationBar: React.FC<NavigationBarProps> = ({
bookKey,
actionTab,
navPadding: mobileNavPadding,
gridInsets,
onSetActionTab,
}) => {
const isMobile = window.innerWidth < 640 || window.innerHeight < 640;
const _ = useTranslation();
const { appService } = useEnv();
const { getViewState } = useReaderStore();
const viewState = getViewState(bookKey);
const tocIconSize = useResponsiveSize(23);
const fontIconSize = useResponsiveSize(18);
const navPadding = isMobile ? `${gridInsets.bottom * 0.33 + 16}px` : '0px';
return (
<div
className={clsx('bg-base-200 z-30 mt-auto flex w-full justify-between px-8 py-4 sm:hidden')}
style={{ paddingBottom: mobileNavPadding }}
style={{
paddingBottom: appService?.isAndroidApp
? `calc(env(safe-area-inset-bottom) + 16px)`
: navPadding,
}}
>
<Button
label={_('Table of Contents')}
@@ -4,6 +4,7 @@ import { RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri';
import { RiArrowGoBackLine, RiArrowGoForwardLine } from 'react-icons/ri';
import { RiArrowLeftDoubleLine, RiArrowRightDoubleLine } from 'react-icons/ri';
import { getNavigationIcon, getNavigationLabel, getNavigationHandler } from './utils';
import { useEnv } from '@/context/EnvContext';
import { useReaderStore } from '@/store/readerStore';
import { useTranslation } from '@/hooks/useTranslation';
import { ViewSettings } from '@/types/book';
@@ -29,10 +30,11 @@ export const NavigationPanel: React.FC<NavigationPanelProps> = ({
progressValid,
navigationHandlers,
viewSettings,
bottomOffset: mobileBottomOffset,
bottomOffset,
sliderHeight,
}) => {
const _ = useTranslation();
const { appService } = useEnv();
const { getView } = useReaderStore();
const view = getView(bookKey);
@@ -63,7 +65,14 @@ export const NavigationPanel: React.FC<NavigationPanelProps> = ({
);
return (
<div className={classes} style={{ bottom: mobileBottomOffset }}>
<div
className={classes}
style={{
bottom: appService?.isAndroidApp
? `calc(env(safe-area-inset-bottom) + 64px)`
: bottomOffset,
}}
>
<div className='flex w-full items-center justify-between gap-x-6'>
<Slider
label={_('Reading Progress')}
@@ -2,7 +2,6 @@ import clsx from 'clsx';
import React, { useEffect, useState } from 'react';
import { BookDoc } from '@/libs/document';
import { useThemeStore } from '@/store/themeStore';
import { useReaderStore } from '@/store/readerStore';
import { useSidebarStore } from '@/store/sidebarStore';
import { useBookDataStore } from '@/store/bookDataStore';
@@ -19,7 +18,6 @@ const SidebarContent: React.FC<{
bookDoc: BookDoc;
sideBarBookKey: string;
}> = ({ bookDoc, sideBarBookKey }) => {
const { safeAreaInsets } = useThemeStore();
const { setHoveredBookKey } = useReaderStore();
const { setSideBarVisible } = useSidebarStore();
const { getConfig, setConfig } = useBookDataStore();
@@ -109,7 +107,7 @@ const SidebarContent: React.FC<{
<div
className='flex-shrink-0'
style={{
paddingBottom: `${(safeAreaInsets?.bottom || 0) / 2}px`,
paddingBottom: 'calc(env(safe-area-inset-bottom, 0px) / 2)',
}}
>
<TabNavigation activeTab={activeTab} onTabChange={handleTabChange} />
@@ -195,7 +195,7 @@ const TTSControl: React.FC<TTSControlProps> = ({ bookKey, gridInsets }) => {
)}
style={{
bottom: appService?.hasSafeAreaInset
? `${(safeAreaInsets?.bottom || 0) * 0.33 + (hoveredBookKey ? 70 : 52)}px`
? `calc(env(safe-area-inset-bottom, 0px) * ${appService?.isIOSApp ? 0.33 : 1} + ${hoveredBookKey ? 70 : 52}px)`
: undefined,
}}
>