feat(eink): optimize color and layout for e-ink mode (#2887)

This commit is contained in:
Huang Xin
2026-01-08 17:29:33 +01:00
committed by GitHub
parent 93228c4b2a
commit 462ca46fee
47 changed files with 532 additions and 179 deletions
@@ -3,6 +3,7 @@ import React, { useState } from 'react';
import { FaCheckCircle } from 'react-icons/fa';
import { HighlightColor, HighlightStyle } from '@/types/book';
import { useEnv } from '@/context/EnvContext';
import { useThemeStore } from '@/store/themeStore';
import { useSettingsStore } from '@/store/settingsStore';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import { saveSysSettings } from '@/helpers/settings';
@@ -34,12 +35,15 @@ const HighlightOptions: React.FC<HighlightOptionsProps> = ({
}) => {
const { envConfig } = useEnv();
const { settings } = useSettingsStore();
const { isDarkMode } = useThemeStore();
const globalReadSettings = settings.globalReadSettings;
const isEink = settings.globalViewSettings.isEink;
const einkBgColor = isDarkMode ? '#000000' : '#ffffff';
const einkFgColor = isDarkMode ? '#ffffff' : '#000000';
const customColors = globalReadSettings.customHighlightColors;
const [selectedStyle, setSelectedStyle] = useState<HighlightStyle>(_selectedStyle);
const [selectedColor, setSelectedColor] = useState<HighlightColor>(_selectedColor);
const size16 = useResponsiveSize(16);
const size18 = useResponsiveSize(18);
const size28 = useResponsiveSize(28);
const highlightOptionsHeightPx = useResponsiveSize(OPTIONS_HEIGHT_PIX);
const highlightOptionsPaddingPx = useResponsiveSize(OPTIONS_PADDING_PIX);
@@ -93,16 +97,17 @@ const HighlightOptions: React.FC<HighlightOptionsProps> = ({
<button
key={style}
onClick={() => handleSelectStyle(style)}
className='flex items-center justify-center rounded-full bg-gray-700 p-0'
className='not-eink:bg-gray-700 eink-bordered flex items-center justify-center rounded-full p-0'
style={{ width: size28, height: size28, minHeight: size28 }}
>
<div
style={{
width: size16,
height: style === 'squiggly' ? size18 : size16,
height: size16,
...(style === 'highlight' &&
selectedStyle === 'highlight' && {
backgroundColor: customColors[selectedColor],
backgroundColor: isEink ? einkFgColor : customColors[selectedColor],
color: isEink ? einkBgColor : '#d1d5db',
paddingTop: '2px',
}),
...(style === 'highlight' &&
@@ -111,11 +116,15 @@ const HighlightOptions: React.FC<HighlightOptionsProps> = ({
paddingTop: '2px',
}),
...((style === 'underline' || style === 'squiggly') && {
color: '#d1d5db',
color: isEink ? einkFgColor : '#d1d5db',
textDecoration: 'underline',
textDecorationThickness: '2px',
textDecorationColor:
selectedStyle === style ? customColors[selectedColor] : '#d1d5db',
selectedStyle === style
? isEink
? einkFgColor
: customColors[selectedColor]
: '#d1d5db',
...(style === 'squiggly' && { textDecorationStyle: 'wavy' }),
}),
}}
@@ -129,27 +138,32 @@ const HighlightOptions: React.FC<HighlightOptionsProps> = ({
<div
className={clsx(
'flex items-center justify-center gap-2 rounded-3xl bg-gray-700',
'not-eink:bg-gray-700 eink-bordered flex items-center justify-center gap-2 rounded-3xl',
isVertical ? 'flex-col py-2' : 'flex-row px-2',
)}
style={isVertical ? { width: size28 } : { height: size28 }}
>
{colors.map((color) => (
<button
key={color}
onClick={() => handleSelectColor(color)}
style={{
width: size16,
height: size16,
backgroundColor: selectedColor !== color ? customColors[color] : 'transparent',
}}
className='rounded-full p-0'
>
{selectedColor === color && (
<FaCheckCircle size={size16} style={{ fill: customColors[color] }} />
)}
</button>
))}
{colors
.filter((c) => (isEink ? selectedColor === c : true))
.map((color) => (
<button
key={color}
onClick={() => handleSelectColor(color)}
style={{
width: size16,
height: size16,
backgroundColor: selectedColor !== color ? customColors[color] : 'transparent',
}}
className='rounded-full p-0'
>
{selectedColor === color && (
<FaCheckCircle
size={size16}
style={{ fill: isEink ? einkFgColor : customColors[color] }}
/>
)}
</button>
))}
</div>
</div>
);