feat: implement useMarkAsRead hook for improved unread state management and update notification handling

This commit is contained in:
2026-02-28 00:10:35 +11:00
parent c890cce37a
commit 29c409fad8
16 changed files with 299 additions and 113 deletions

View File

@@ -1,6 +1,14 @@
import { style } from '@vanilla-extract/css';
import { color, config, toRem } from 'folds';
export const CheckButtonContainer = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '32px',
width: '32px',
});
export const CheckButton = style({
all: 'unset',
display: 'flex',
@@ -11,13 +19,19 @@ export const CheckButton = style({
cursor: 'pointer',
color: color.Secondary.Main,
backgroundColor: 'transparent',
transition: 'background-color 0.15s',
transition: 'opacity 0.2s, background-color 0.15s',
height: '32px',
width: '32px',
opacity: 0.7,
opacity: 0,
WebkitAppRegion: 'no-drag',
flexShrink: 0,
selectors: {
'&[data-visible="true"]': {
opacity: 0.7,
},
},
':hover': {
backgroundColor: color.Surface.ContainerHover,
opacity: 1,
@@ -30,6 +44,7 @@ export const CheckButton = style({
':focus-visible': {
outline: `2px solid ${color.Secondary.Main}`,
outlineOffset: '2px',
opacity: 1,
},
});

View File

@@ -21,6 +21,7 @@ export function UpdateNotification() {
const [downloadProgress, setDownloadProgress] = useState(0);
const [updateReady, setUpdateReady] = useState(false);
const [checking, setChecking] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const [menuAnchor, setMenuAnchor] = useState<{ x: number; y: number; width: number; height: number } | undefined>(undefined);
useEffect(() => {
@@ -118,29 +119,36 @@ export function UpdateNotification() {
// Show check button if no update status
if (!updateAvailable && !updateReady && !checking) {
return (
<button
className={css.CheckButton}
onClick={handleCheckForUpdates}
aria-label="Check for updates"
title="Check for updates"
type="button"
<div
className={css.CheckButtonContainer}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path
d="M8 2V10M8 10L5 7M8 10L11 7"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 14H13"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
</svg>
</button>
<button
className={css.CheckButton}
data-visible={isHovered}
onClick={handleCheckForUpdates}
aria-label="Check for updates"
title="Check for updates"
type="button"
>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path
d="M8 2V10M8 10L5 7M8 10L11 7"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 14H13"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
/>
</svg>
</button>
</div>
);
}