rtl: support rtl for more widgets in sidebar (#504)

This commit is contained in:
Huang Xin
2025-03-06 22:38:29 +08:00
committed by GitHub
parent 0f44fff7cd
commit 8c3f49de25
7 changed files with 26 additions and 10 deletions
@@ -81,11 +81,16 @@ const FooterBar: React.FC<FooterBarProps> = ({
isHoveredAnim && 'hover-bar-anim',
hoveredBookKey === bookKey ? `opacity-100` : `opacity-0`,
)}
dir={viewSettings?.rtl ? 'rtl' : 'ltr'}
onMouseEnter={() => setHoveredBookKey(bookKey)}
onMouseLeave={() => setHoveredBookKey('')}
>
<div className='hidden sm:flex'>
<Button icon={<RiArrowLeftWideLine />} onClick={handleGoPrev} tooltip={_('Go Left')} />
<Button
icon={viewSettings?.rtl ? <RiArrowRightWideLine /> : <RiArrowLeftWideLine />}
onClick={viewSettings?.rtl ? handleGoNext : handleGoPrev}
tooltip={viewSettings?.rtl ? _('Go Right') : _('Go Left')}
/>
</div>
<Button
icon={<RiArrowGoBackLine />}
@@ -104,7 +109,7 @@ const FooterBar: React.FC<FooterBarProps> = ({
</span>
<input
type='range'
className={clsx('text-base-content mx-2 w-full', viewSettings?.rtl && 'direction-rtl')}
className='text-base-content mx-2 w-full'
min={0}
max={100}
value={progressValid ? progressFraction * 100 : 0}
@@ -112,7 +117,11 @@ const FooterBar: React.FC<FooterBarProps> = ({
/>
<Button icon={<FaHeadphones />} onClick={handleSpeakText} tooltip={_('Speak')} />
<div className='hidden sm:flex'>
<Button icon={<RiArrowRightWideLine />} onClick={handleGoNext} tooltip={_('Go Right')} />
<Button
icon={viewSettings?.rtl ? <RiArrowLeftWideLine /> : <RiArrowRightWideLine />}
onClick={viewSettings?.rtl ? handleGoPrev : handleGoNext}
tooltip={viewSettings?.rtl ? _('Go Left') : _('Go Right')}
/>
</div>
</div>
);
@@ -7,6 +7,7 @@ import { HighlightColor, HighlightStyle } from '@/types/book';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
interface AnnotationPopupProps {
dir: 'ltr' | 'rtl';
buttons: Array<{ tooltipText: string; Icon: React.ElementType; onClick: () => void }>;
position: Position;
trianglePosition: Position;
@@ -22,6 +23,7 @@ const OPTIONS_HEIGHT_PIX = 28;
const OPTIONS_PADDING_PIX = 16;
const AnnotationPopup: React.FC<AnnotationPopupProps> = ({
dir,
buttons,
position,
trianglePosition,
@@ -35,7 +37,7 @@ const AnnotationPopup: React.FC<AnnotationPopupProps> = ({
const highlightOptionsHeightPx = useResponsiveSize(OPTIONS_HEIGHT_PIX);
const highlightOptionsPaddingPx = useResponsiveSize(OPTIONS_PADDING_PIX);
return (
<div>
<div dir={dir}>
<Popup
width={popupWidth}
height={popupHeight}
@@ -76,7 +76,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
const dictPopupHeight = Math.min(300, maxHeight);
const transPopupWidth = Math.min(480, maxWidth);
const transPopupHeight = Math.min(360, maxHeight);
const annotPopupWidth = useResponsiveSize(280);
const annotPopupWidth = useResponsiveSize(300);
const annotPopupHeight = useResponsiveSize(44);
const androidSelectionHandlerHeight = 8;
@@ -487,6 +487,7 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
)}
{showAnnotPopup && trianglePosition && annotPopupPosition && (
<AnnotationPopup
dir={viewSettings.rtl ? 'rtl' : 'ltr'}
buttons={buttons}
position={annotPopupPosition}
trianglePosition={trianglePosition}
@@ -23,7 +23,7 @@ const BookCard = ({ book }: { book: Book }) => {
alt={_('Book Cover')}
width={56}
height={80}
className='mr-4 aspect-auto max-h-16 w-[15%] max-w-12 rounded-sm object-cover shadow-md'
className='me-4 aspect-auto max-h-16 w-[15%] max-w-12 rounded-sm object-cover shadow-md'
onError={(e) => {
(e.target as HTMLImageElement).style.display = 'none';
}}
@@ -26,9 +26,10 @@ const SidebarHeader: React.FC<{
return (
<div
className={clsx(
'sidebar-header flex h-11 items-center justify-between pr-2',
isTrafficLightVisible ? 'pl-20' : 'pl-1.5',
'sidebar-header flex h-11 items-center justify-between pe-2',
isTrafficLightVisible ? 'pl-20' : 'ps-1.5',
)}
dir='ltr'
>
<div className='flex items-center gap-x-8'>
<button
@@ -32,7 +32,7 @@ const SideBar: React.FC<{
const { settings } = useSettingsStore();
const { sideBarBookKey } = useSidebarStore();
const { getBookData } = useBookDataStore();
const { getView } = useReaderStore();
const { getView, getViewSettings } = useReaderStore();
const [isSearchBarVisible, setIsSearchBarVisible] = useState(false);
const [searchResults, setSearchResults] = useState<BookSearchResult[] | null>(null);
const [searchTerm, setSearchTerm] = useState('');
@@ -162,6 +162,7 @@ const SideBar: React.FC<{
if (!sideBarBookKey) return null;
const viewSettings = getViewSettings(sideBarBookKey);
const bookData = getBookData(sideBarBookKey);
if (!bookData || !bookData.book || !bookData.bookDoc) {
return null;
@@ -178,6 +179,7 @@ const SideBar: React.FC<{
appService?.hasRoundedWindow && 'rounded-window-top-left rounded-window-bottom-left',
!isSideBarPinned && 'shadow-2xl',
)}
dir={viewSettings?.rtl ? 'rtl' : 'ltr'}
style={{
width: `${sideBarWidth}`,
maxWidth: `${MAX_SIDEBAR_WIDTH * 100}%`,
@@ -15,10 +15,11 @@ const TabNavigation: React.FC<{
return (
<div
className={clsx('bottom-tab border-base-300/50 bg-base-200 relative flex w-full border-t')}
dir='ltr'
>
<div
className={clsx(
'bg-base-300 absolute bottom-1.5 left-1 h-[calc(100%-12px)] w-[calc(33.3%-8px)] rounded-lg',
'bg-base-300 absolute bottom-1.5 start-1 h-[calc(100%-12px)] w-[calc(33.3%-8px)] rounded-lg',
'transform transition-transform duration-300',
activeTab === 'toc' && 'translate-x-0',
activeTab === 'annotations' && 'translate-x-[calc(100%+8px)]',