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
@@ -101,7 +101,7 @@ export const AboutWindow = () => {
<div className='my-1 h-5'>
{!updateStatus && (
<button
className='badge badge-primary cursor-pointer p-2'
className='btn btn-sm btn-primary cursor-pointer p-1 text-xs'
onClick={appService?.hasUpdater ? handleCheckUpdate : handleShowRecentUpdates}
>
{_('Check Update')}
+1 -1
View File
@@ -191,7 +191,7 @@ const Dialog: React.FC<DialogProps> = ({
>
<Overlay
className={clsx(
'z-10 bg-black/50 sm:bg-black/50',
'dialog-overlay z-10 bg-black/50 sm:bg-black/50',
appService?.hasRoundedWindow && 'rounded-window',
bgClassName,
)}
+4 -1
View File
@@ -29,7 +29,10 @@ const Menu: React.FC<MenuProps> = ({ children, className, style, onCancel }) =>
<div
ref={menuRef}
role='none'
className={clsx('max-h-[calc(100vh-96px)] overflow-y-auto', className)}
className={clsx(
'menu-container max-h-[calc(100vh-96px)] overflow-y-auto border-0',
className,
)}
style={style}
>
{children}
+55 -45
View File
@@ -4,6 +4,49 @@ import { useEffect, useRef, useState } from 'react';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import { useKeyDownActions } from '@/hooks/useKeyDownActions';
const getTriangleStyles = (
trianglePosition: Position | undefined,
size: number,
offset: number,
): React.CSSProperties => {
if (!trianglePosition) {
return { left: '-999px', top: '-999px' };
}
const { dir, point } = trianglePosition;
let topOffset = 0;
let leftOffset = 0;
switch (dir) {
case 'up':
topOffset = offset;
break;
case 'down':
topOffset = -offset;
break;
case 'left':
leftOffset = offset;
break;
case 'right':
leftOffset = -offset;
break;
}
return {
left: `${point.x + leftOffset}px`,
top: `${point.y + topOffset}px`,
borderLeft:
dir === 'right' ? 'none' : dir === 'left' ? `${size}px solid` : `${size}px solid transparent`,
borderRight:
dir === 'left' ? 'none' : dir === 'right' ? `${size}px solid` : `${size}px solid transparent`,
borderTop:
dir === 'down' ? 'none' : dir === 'up' ? `${size}px solid` : `${size}px solid transparent`,
borderBottom:
dir === 'up' ? 'none' : dir === 'down' ? `${size}px solid` : `${size}px solid transparent`,
transform: dir === 'left' || dir === 'right' ? 'translateY(-50%)' : 'translateX(-50%)',
};
};
const Popup = ({
width,
height,
@@ -82,14 +125,22 @@ const Popup = ({
setAdjustedPosition(newPosition);
}, [position, trianglePosition, popupPadding, childrenHeight]);
const outerTriangleStyles = getTriangleStyles(trianglePosition, 7, 0);
const innerTriangleStyles = getTriangleStyles(trianglePosition, 7, -1);
return (
<div>
<div
className={clsx('popup-triangle-outer text-base-300 absolute z-50', triangleClassName)}
style={outerTriangleStyles}
/>
<div
id='popup-container'
ref={containerRef}
className={clsx(
'bg-base-300 absolute z-50 rounded-lg font-sans',
trianglePosition?.dir !== 'up' && 'shadow-xl',
'popup-container bg-base-300 absolute z-50 rounded-lg font-sans',
'eink:border eink:border-base-content',
trianglePosition?.dir !== 'up' && 'not-eink:shadow-xl',
className,
)}
style={{
@@ -105,49 +156,8 @@ const Popup = ({
{children}
</div>
<div
className={`triangle text-base-300 absolute z-50 ${triangleClassName}`}
style={{
left:
trianglePosition?.dir === 'left'
? `${trianglePosition.point.x}px`
: trianglePosition?.dir === 'right'
? `${trianglePosition.point.x}px`
: `${trianglePosition ? trianglePosition.point.x : -999}px`,
top:
trianglePosition?.dir === 'up'
? `${trianglePosition.point.y}px`
: trianglePosition?.dir === 'down'
? `${trianglePosition.point.y}px`
: `${trianglePosition ? trianglePosition.point.y : -999}px`,
borderLeft:
trianglePosition?.dir === 'right'
? 'none'
: trianglePosition?.dir === 'left'
? `7px solid`
: '7px solid transparent',
borderRight:
trianglePosition?.dir === 'left'
? 'none'
: trianglePosition?.dir === 'right'
? `7px solid`
: '7px solid transparent',
borderTop:
trianglePosition?.dir === 'down'
? 'none'
: trianglePosition?.dir === 'up'
? `7px solid`
: '7px solid transparent',
borderBottom:
trianglePosition?.dir === 'up'
? 'none'
: trianglePosition?.dir === 'down'
? `7px solid`
: '7px solid transparent',
transform:
trianglePosition?.dir === 'left' || trianglePosition?.dir === 'right'
? 'translateY(-50%)'
: 'translateX(-50%)',
}}
className={clsx('popup-triangle-inner text-base-300 absolute z-50', triangleClassName)}
style={innerTriangleStyles}
/>
</div>
);
+4 -2
View File
@@ -19,8 +19,10 @@ const Spinner: React.FC<{
}}
role='status'
>
<span className={clsx('loading loading-dots loading-lg', className)}></span>
<span className='hidden'>{_('Loading...')}</span>
<span
className={clsx('loading loading-lg not-eink:loading-dots eink:loading-spinner', className)}
></span>
<span className='sr-only'>{_('Loading...')}</span>
</div>
);
};
+5 -3
View File
@@ -23,9 +23,9 @@ export const Toast = () => {
const alertClassMap = {
info: 'alert-primary border-base-300',
success: 'alert-success border-0 bg-gradient-to-r from-green-500 to-emerald-500',
warning: 'alert-warning border-0 bg-gradient-to-r from-amber-500 to-orange-500',
error: 'alert-error border-0 bg-gradient-to-r from-red-500 to-rose-500',
success: 'alert-success not-eink:from-green-500 not-eink:to-emerald-500',
warning: 'alert-warning not-eink:from-amber-500 not-eink:to-orange-500',
error: 'alert-error not-eink:from-red-500 not-eink:to-rose-500',
};
const iconMap = {
@@ -132,7 +132,9 @@ export const Toast = () => {
className={clsx(
'alert flex items-center gap-3 shadow-2xl backdrop-blur-sm',
'min-h-0 rounded-2xl px-5 py-4',
'not-eink:bg-gradient-to-r border-0',
alertClassMap[toastType],
'eink:bg-base-100 eink:border eink:border-base-content',
toastType !== 'info' && 'text-white',
)}
>
@@ -402,7 +402,7 @@ export const UpdaterContent = ({
</div>
<div className='text-base-content text-sm'>
<h3 className='mb-2 font-bold'>{_('Changelog')}</h3>
<div className='bg-base-200 mb-4 rounded-lg px-4 pb-2 pt-4'>
<div className='not-eink:bg-base-200 not-eink:px-4 mb-4 rounded-lg pb-2 pt-4'>
{changelogs.length > 0 ? (
changelogs.map((entry: Changelog) => (
<div key={entry.version} className='mb-4'>
@@ -186,7 +186,7 @@ const ControlPanel: React.FC<SettingsPanelPanelProp> = ({ bookKey, onRegisterRes
},
...annotationToolQuickActions.map((button) => ({
value: button.type,
label: button.label,
label: _(button.label),
})),
];
};