Compare commits

...

2 Commits

4 changed files with 193 additions and 63 deletions

View File

@ -62,6 +62,7 @@ The frontend is a workspace package that builds separately:
cd packages/pastebar-app-ui cd packages/pastebar-app-ui
npm run dev # Development server on port 4422 npm run dev # Development server on port 4422
npm run build # Build to dist-ui/ npm run build # Build to dist-ui/
npm run build:ts # TypeScript check and build
``` ```
### Rust/Tauri Development (src-tauri/) ### Rust/Tauri Development (src-tauri/)
@ -72,6 +73,21 @@ cargo run --no-default-features # Development mode
cargo build --release # Production build cargo build --release # Production build
``` ```
### Code Quality Commands
```bash
# TypeScript type checking (no ESLint configured)
cd packages/pastebar-app-ui && npx tsc --noEmit
# Rust linting
cd src-tauri && cargo clippy
# Format all code
npm run format # Uses Prettier for JS/TS files
```
**Note**: The project currently has no test infrastructure. There are no unit tests, integration tests, or test commands configured.
## Architecture Overview ## Architecture Overview
### High-Level Structure ### High-Level Structure
@ -128,6 +144,26 @@ cargo build --release # Production build
- History window (clipboard history view) - History window (clipboard history view)
- QuickPaste window (contextual paste menu) - QuickPaste window (contextual paste menu)
### Tauri Command Patterns
Commands follow consistent patterns in `src-tauri/src/commands/`:
```rust
#[tauri::command]
pub fn command_name(
app_handle: tauri::AppHandle,
state: tauri::State<SomeState>,
params: Type
) -> Result<ReturnType, String> {
// Implementation
}
```
Common state types:
- `tauri::State<Mutex<HashMap<String, Setting>>>` - App settings
- `tauri::State<menu::DbItems>` - Database items
- `tauri::State<menu::DbRecentHistoryItems>` - Recent history
### Database Schema ### Database Schema
Main entities: Main entities:
@ -206,4 +242,16 @@ src-tauri/src/
- Use Diesel migrations for schema changes - Use Diesel migrations for schema changes
- Place migration files in `migrations/` directory - Place migration files in `migrations/` directory
- Run migrations with `npm run diesel:migration:run` - Run migrations with `npm run diesel:migration:run`
### TypeScript Configuration
- Strict mode enabled in `tsconfig.json`
- Path alias configured: `~/` maps to `packages/pastebar-app-ui/src/`
- Target: ESNext with React JSX transform
### Build Configuration
- Frontend build output: `packages/pastebar-app-ui/dist-ui/`
- Dev server runs on port 4422
- Tauri configs: `tauri.conf.json` (dev) and `tauri.release.conf.json` (production)

View File

@ -72,7 +72,7 @@ const useKeyboardDeleteConfirmation = ({
useHotkeys( useHotkeys(
['delete', 'backspace'], ['delete', 'backspace'],
async (e) => { async e => {
e.preventDefault() e.preventDefault()
// Only handle keyboard delete when there's a keyboard selected item and no multi-selection // Only handle keyboard delete when there's a keyboard selected item and no multi-selection

View File

@ -121,6 +121,7 @@ interface ClipboardHistoryRowProps {
clipboard?: ClipboardHistoryItem clipboard?: ClipboardHistoryItem
isDark: boolean isDark: boolean
setRowHeight?: (index: number, height: number) => void setRowHeight?: (index: number, height: number) => void
setKeyboardHistorySelectedItemId?: (id: UniqueIdentifier | null) => void
setHistoryFilters?: Dispatch<SetStateAction<string[]>> setHistoryFilters?: Dispatch<SetStateAction<string[]>>
setAppFilters?: Dispatch<SetStateAction<string[]>> setAppFilters?: Dispatch<SetStateAction<string[]>>
isSingleClickToCopyPaste?: boolean isSingleClickToCopyPaste?: boolean
@ -182,6 +183,7 @@ export function ClipboardHistoryRowComponent({
setRowHeight = () => {}, setRowHeight = () => {},
setHistoryFilters = () => {}, setHistoryFilters = () => {},
setAppFilters = () => {}, setAppFilters = () => {},
setKeyboardHistorySelectedItemId = () => {},
isSingleClickToCopyPaste = false, isSingleClickToCopyPaste = false,
historyPreviewLineLimit, historyPreviewLineLimit,
}: ClipboardHistoryRowProps) { }: ClipboardHistoryRowProps) {
@ -239,10 +241,12 @@ export function ClipboardHistoryRowComponent({
useEffect(() => { useEffect(() => {
if (isKeyboardSelected && rowKeyboardRef.current && !isScrolling) { if (isKeyboardSelected && rowKeyboardRef.current && !isScrolling) {
rowKeyboardRef.current.scrollIntoView({ if (!isScrolling) {
block: 'center', rowKeyboardRef.current.scrollIntoView({
}) block: 'nearest',
// rowKeyboardRef.current.focus() })
rowKeyboardRef.current.focus({ preventScroll: true })
}
} }
}, [isKeyboardSelected, isScrolling]) }, [isKeyboardSelected, isScrolling])
@ -430,7 +434,7 @@ export function ClipboardHistoryRowComponent({
} }
{...(isSelected || isHovering ? listeners : {})} {...(isSelected || isHovering ? listeners : {})}
> >
<Box ref={rowRef} tabIndex={0} role="option" aria-selected={isKeyboardSelected}> <Box ref={rowRef} tabIndex={-1} role="option" aria-selected={isKeyboardSelected}>
{showTimeAgo && ( {showTimeAgo && (
<Box <Box
className={`flex justify-center text-gray-400 text-xs ${ className={`flex justify-center text-gray-400 text-xs ${
@ -495,14 +499,14 @@ export function ClipboardHistoryRowComponent({
<Box <Box
className="relative select-none history-item focus:outline-none" className="relative select-none history-item focus:outline-none"
ref={rowKeyboardRef} ref={rowKeyboardRef}
tabIndex={0} tabIndex={-1}
role="option" role="option"
aria-selected={isKeyboardSelected} aria-selected={isKeyboardSelected}
> >
<Box <Box
className={`rounded-md justify-start duration-300 history-box relative px-3 py-1 hover:shadow-sm my-0.5 shadow-none border-2 flex flex-col ${ className={`rounded-md justify-start duration-300 history-box relative px-3 py-1 hover:shadow-sm my-0.5 shadow-none border-2 flex flex-col ${
isKeyboardSelected isKeyboardSelected
? 'ring-2 scale-[.98] ring-blue-400 dark:!ring-blue-600 ring-offset-1 !shadow-sm ring-offset-white dark:ring-offset-gray-800' ? 'ring-2 scale-[.98] ring-blue-400 dark:!ring-blue-600 ring-offset-1 !shadow-sm ring-offset-white dark:ring-offset-gray-800'
: '' : ''
} ${ } ${
index === 0 && index === 0 &&
@ -513,22 +517,22 @@ export function ClipboardHistoryRowComponent({
!isSelected !isSelected
? 'bg-teal-50 hover:border-slate-300 dark:bg-sky-900/40 dark:hover:border-slate-700 hover:bg-teal-50/90 hover:dark:bg-sky-950' ? 'bg-teal-50 hover:border-slate-300 dark:bg-sky-900/40 dark:hover:border-slate-700 hover:bg-teal-50/90 hover:dark:bg-sky-950'
: (isDeleting || isDeleteConfirmationFromContext.value) && : (isDeleting || isDeleteConfirmationFromContext.value) &&
!isDragPreview !isDragPreview
? 'border-red-400 bg-red-50 dark:bg-red-950/80 dark:border-red-900/80 dark:hover:border-red-800' ? 'border-red-400 bg-red-50 dark:bg-red-950/80 dark:border-red-900/80 dark:hover:border-red-800'
: isSelected : isSelected
? `bg-amber-50 border-amber-300 dark:bg-amber-950/80 dark:border-amber-900/80 hover:border-amber-300/80 dark:hover:border-amber-800 hover:bg-amber-50/80 ${ ? `bg-amber-50 border-amber-300 dark:bg-amber-950/80 dark:border-amber-900/80 hover:border-amber-300/80 dark:hover:border-amber-800 hover:bg-amber-50/80 ${
isPinnedTop ? '!border dark:!bg-amber-950' : '' isPinnedTop ? '!border dark:!bg-amber-950' : ''
}` }`
: isKeyboardSelected : isKeyboardSelected
? `bg-blue-50 border-blue-300 dark:bg-blue-950/80 dark:hover:border-blue-800 hover:bg-blue-50/80 ${ ? `bg-blue-50 !border-0 border-blue-300 dark:bg-blue-950/80 dark:hover:border-blue-800 hover:bg-blue-50/80 ${
isPinnedTop ? ' dark:!bg-amber-950' : '' isPinnedTop ? ' dark:!bg-amber-950' : ''
}` }`
: contextMenuOpen.value : contextMenuOpen.value
? 'bg-slate-100 dark:bg-slate-950/80 border-slate-300 dark:border-slate-600' ? 'bg-slate-100 dark:bg-slate-950/80 border-slate-300 dark:border-slate-600'
: isSaved && !isDragPreview : isSaved && !isDragPreview
? 'bg-sky-50 border-sky-600 dark:bg-sky-950/80 dark:border-sky-900/80 dark:hover:border-sky-800' ? 'bg-sky-50 border-sky-600 dark:bg-sky-950/80 dark:border-sky-900/80 dark:hover:border-sky-800'
: isCopiedOrPasted && !isDragPreview : isCopiedOrPasted && !isDragPreview
? `bg-green-50 border-green-600 dark:bg-green-950/80 dark:border-green-800` ? `bg-green-50 border-green-600 dark:bg-green-950/80 dark:border-green-800`
: `hover:bg-white dark:hover:bg-slate-950/80 ${ : `hover:bg-white dark:hover:bg-slate-950/80 ${
isLargeView isLargeView
? 'border-slate-500 bg-white dark:bg-slate-950 hover:dark:border-slate-500' ? 'border-slate-500 bg-white dark:bg-slate-950 hover:dark:border-slate-500'
@ -549,16 +553,20 @@ export function ClipboardHistoryRowComponent({
!getSelectedText().text && !getSelectedText().text &&
isWindows && isWindows &&
e.ctrlKey) || e.ctrlKey) ||
(e.metaKey && !isWindows) (e.metaKey &&
!isWindows &&
isSingleClickToCopyPaste &&
!getSelectedText().text)
) { ) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
onCopyPaste(clipboard.historyId) onCopyPaste(clipboard.historyId)
} else if ((isWindows && e.ctrlKey) || (e.metaKey && !isWindows)) { } else if (e.altKey) {
setSelectHistoryItem(clipboard.historyId) setSelectHistoryItem(clipboard.historyId)
} else if (e.ctrlKey || e.metaKey) { } else if (e.ctrlKey || e.metaKey) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
setKeyboardHistorySelectedItemId(clipboard.historyId)
} else if (e.shiftKey) { } else if (e.shiftKey) {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()

View File

@ -35,7 +35,6 @@ import {
showClipsMoveOnBoardId, showClipsMoveOnBoardId,
showDetailsClipId, showDetailsClipId,
showHistoryDeleteConfirmationId, showHistoryDeleteConfirmationId,
showHistoryMultiDeleteConfirmationIds,
showKeyboardNavContextMenuClipId, showKeyboardNavContextMenuClipId,
showKeyboardNavContextMenuHistoryId, showKeyboardNavContextMenuHistoryId,
showLargeViewClipId, showLargeViewClipId,
@ -221,8 +220,6 @@ export default function ClipboardHistoryPage() {
const [selectedHistoryItems, setSelectedHistoryItems] = useState<UniqueIdentifier[]>([]) const [selectedHistoryItems, setSelectedHistoryItems] = useState<UniqueIdentifier[]>([])
const [showSelectHistoryItems, setShowSelectHistoryItems] = useState(false) const [showSelectHistoryItems, setShowSelectHistoryItems] = useState(false)
const [isDragPinnedHistory, setIsDragPinnedHistory] = useState(false) const [isDragPinnedHistory, setIsDragPinnedHistory] = useState(false)
// Use global signal for keyboardSelectedItemId, aliased to avoid conflict if needed locally
// const keyboardSelectedItemId = useSignal<UniqueIdentifier | null>(null); // Removed local signal
const { const {
isScrolling, isScrolling,
setIsScrolling, setIsScrolling,
@ -278,37 +275,40 @@ export default function ClipboardHistoryPage() {
}, },
}) })
const { showConfirmation: showConfirmationKeyboardDelete, keyboardItemIdDelete, resetTimer: resetKeyboardDeleteTimer } = const {
useKeyboardDeleteConfirmation({ showConfirmation: showConfirmationKeyboardDelete,
keyboardSelectedItemId: keyboardSelectedItemId, keyboardItemIdDelete,
selectedHistoryItems, resetTimer: resetKeyboardDeleteTimer,
onConfirmedDelete: async () => { } = useKeyboardDeleteConfirmation({
if (keyboardSelectedItemId.value) { keyboardSelectedItemId: keyboardSelectedItemId,
// Calculate next selection before deletion selectedHistoryItems,
const currentIndex = clipboardHistory.findIndex( onConfirmedDelete: async () => {
item => item.historyId === keyboardSelectedItemId.value if (keyboardSelectedItemId.value) {
) // Calculate next selection before deletion
let nextSelectedId: UniqueIdentifier | null = null const currentIndex = clipboardHistory.findIndex(
if (currentIndex !== -1) { item => item.historyId === keyboardSelectedItemId.value
if (currentIndex < clipboardHistory.length - 1) { )
// Select next item let nextSelectedId: UniqueIdentifier | null = null
nextSelectedId = clipboardHistory[currentIndex + 1].historyId if (currentIndex !== -1) {
} else if (currentIndex > 0) { if (currentIndex < clipboardHistory.length - 1) {
// Select previous item // Select next item
nextSelectedId = clipboardHistory[currentIndex - 1].historyId nextSelectedId = clipboardHistory[currentIndex + 1].historyId
} } else if (currentIndex > 0) {
// If only one item, nextSelectedId remains null // Select previous item
nextSelectedId = clipboardHistory[currentIndex - 1].historyId
} }
// If only one item, nextSelectedId remains null
await deleteClipboardHistoryByIds({
historyIds: [keyboardSelectedItemId.value],
})
// Update selection to the calculated next item
keyboardSelectedItemId.value = nextSelectedId
} }
},
}) await deleteClipboardHistoryByIds({
historyIds: [keyboardSelectedItemId.value],
})
// Update selection to the calculated next item
keyboardSelectedItemId.value = nextSelectedId
}
},
})
const isPinnedPanelHoverOpen = useMemo(() => { const isPinnedPanelHoverOpen = useMemo(() => {
return isPinnedPanelKeepOpen.value || isPinnedPanelHovering.value return isPinnedPanelKeepOpen.value || isPinnedPanelHovering.value
@ -508,6 +508,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -698,7 +700,10 @@ export default function ClipboardHistoryPage() {
useHotkeys( useHotkeys(
['space'], ['space'],
() => { e => {
e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
if ( if (
currentNavigationContext.value === 'history' || currentNavigationContext.value === 'history' ||
currentNavigationContext.value === null currentNavigationContext.value === null
@ -706,7 +711,7 @@ export default function ClipboardHistoryPage() {
if (keyboardSelectedItemId.value) { if (keyboardSelectedItemId.value) {
// Reset keyboard delete confirmation when selecting // Reset keyboard delete confirmation when selecting
resetKeyboardDeleteTimer() resetKeyboardDeleteTimer()
setSelectHistoryItem(keyboardSelectedItemId.value) setSelectHistoryItem(keyboardSelectedItemId.value)
const currentItemIndex = clipboardHistory.findIndex( const currentItemIndex = clipboardHistory.findIndex(
item => item.historyId === keyboardSelectedItemId.value item => item.historyId === keyboardSelectedItemId.value
@ -723,6 +728,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -741,7 +748,7 @@ export default function ClipboardHistoryPage() {
// Reset delete confirmation on escape // Reset delete confirmation on escape
showHistoryDeleteConfirmationId.value = null showHistoryDeleteConfirmationId.value = null
// Reset keyboard delete confirmation on escape // Reset keyboard delete confirmation on escape
resetKeyboardDeleteTimer() resetKeyboardDeleteTimer()
@ -769,6 +776,8 @@ export default function ClipboardHistoryPage() {
['arrowdown'], ['arrowdown'],
e => { e => {
e.preventDefault() e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
// Clear any delete timeout when navigating away // Clear any delete timeout when navigating away
if (deleteTimeoutRef.current) { if (deleteTimeoutRef.current) {
@ -778,7 +787,7 @@ export default function ClipboardHistoryPage() {
// Reset delete confirmation when navigating to a different item // Reset delete confirmation when navigating to a different item
showHistoryDeleteConfirmationId.value = null showHistoryDeleteConfirmationId.value = null
// Reset keyboard delete confirmation when navigating // Reset keyboard delete confirmation when navigating
resetKeyboardDeleteTimer() resetKeyboardDeleteTimer()
@ -798,6 +807,8 @@ export default function ClipboardHistoryPage() {
(currentNavigationContext.value === 'history' || (currentNavigationContext.value === 'history' ||
currentNavigationContext.value === null) && currentNavigationContext.value === null) &&
!shouldKeyboardNavigationBeDisabled.value, !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -805,6 +816,8 @@ export default function ClipboardHistoryPage() {
['arrowup'], ['arrowup'],
e => { e => {
e.preventDefault() e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
// Clear any delete timeout when navigating away // Clear any delete timeout when navigating away
if (deleteTimeoutRef.current) { if (deleteTimeoutRef.current) {
@ -814,7 +827,7 @@ export default function ClipboardHistoryPage() {
// Reset delete confirmation when navigating to a different item // Reset delete confirmation when navigating to a different item
showHistoryDeleteConfirmationId.value = null showHistoryDeleteConfirmationId.value = null
// Reset keyboard delete confirmation when navigating // Reset keyboard delete confirmation when navigating
resetKeyboardDeleteTimer() resetKeyboardDeleteTimer()
@ -840,6 +853,8 @@ export default function ClipboardHistoryPage() {
(currentNavigationContext.value === 'history' || (currentNavigationContext.value === 'history' ||
currentNavigationContext.value === null) && currentNavigationContext.value === null) &&
!shouldKeyboardNavigationBeDisabled.value, !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -873,6 +888,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -906,6 +923,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -913,6 +932,8 @@ export default function ClipboardHistoryPage() {
['home'], ['home'],
e => { e => {
e.preventDefault() e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
if ( if (
currentNavigationContext.value === 'history' || currentNavigationContext.value === 'history' ||
currentNavigationContext.value === null currentNavigationContext.value === null
@ -958,6 +979,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -965,6 +988,8 @@ export default function ClipboardHistoryPage() {
['pageup'], ['pageup'],
e => { e => {
e.preventDefault() e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
if ( if (
currentNavigationContext.value === 'history' || currentNavigationContext.value === 'history' ||
currentNavigationContext.value === null currentNavigationContext.value === null
@ -1005,6 +1030,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -1012,6 +1039,8 @@ export default function ClipboardHistoryPage() {
['pagedown'], ['pagedown'],
e => { e => {
e.preventDefault() e.preventDefault()
e.stopPropagation()
e.stopImmediatePropagation()
if ( if (
currentNavigationContext.value === 'history' || currentNavigationContext.value === 'history' ||
currentNavigationContext.value === null currentNavigationContext.value === null
@ -1052,6 +1081,8 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
@ -1076,9 +1107,45 @@ export default function ClipboardHistoryPage() {
}, },
{ {
enabled: !shouldKeyboardNavigationBeDisabled.value, enabled: !shouldKeyboardNavigationBeDisabled.value,
enableOnFormTags: false,
preventDefault: true,
} }
) )
function setKeyboardHistorySelectedItemId(itemId: UniqueIdentifier | null) {
if (itemId) {
if (deleteTimeoutRef.current) {
clearTimeout(deleteTimeoutRef.current)
deleteTimeoutRef.current = null
}
if (itemId === keyboardSelectedItemId.value) {
resetKeyboardNavigation()
return
}
// Reset delete confirmation when navigating to a different item
showHistoryDeleteConfirmationId.value = null
// Reset keyboard delete confirmation when navigating
resetKeyboardDeleteTimer()
const currentItemIndex = clipboardHistory.findIndex(
item => item.historyId === itemId
)
if (currentItemIndex === -1) {
keyboardSelectedItemId.value = null
return
}
currentNavigationContext.value = 'history'
keyboardSelectedItemId.value = itemId
} else {
keyboardSelectedItemId.value = null
}
}
// Store timeout reference to clear it if needed // Store timeout reference to clear it if needed
const deleteTimeoutRef = useRef<NodeJS.Timeout | null>(null) const deleteTimeoutRef = useRef<NodeJS.Timeout | null>(null)
@ -1347,15 +1414,19 @@ export default function ClipboardHistoryPage() {
const hasIsDeleting = (historyId: UniqueIdentifier) => { const hasIsDeleting = (historyId: UniqueIdentifier) => {
return ( return (
// Keyboard delete confirmation - only for the specific keyboard selected item // Keyboard delete confirmation - only for the specific keyboard selected item
(showConfirmationKeyboardDelete && (showConfirmationKeyboardDelete &&
historyId === keyboardItemIdDelete && historyId === keyboardItemIdDelete &&
historyId === keyboardSelectedItemId.value) || historyId === keyboardSelectedItemId.value) ||
// Mouse delete confirmation - only when keyboard delete is NOT active // Mouse delete confirmation - only when keyboard delete is NOT active
(showConfirmation && !showConfirmationKeyboardDelete && selectedHistoryItems.includes(historyId)) || (showConfirmation &&
!showConfirmationKeyboardDelete &&
selectedHistoryItems.includes(historyId)) ||
// Single item delete confirmation // Single item delete confirmation
historyId === showHistoryDeleteConfirmationId.value || historyId === showHistoryDeleteConfirmationId.value ||
// Hovering delete confirmation - only when keyboard delete is NOT active // Hovering delete confirmation - only when keyboard delete is NOT active
(showConfirmation && !showConfirmationKeyboardDelete && historyId === hoveringHistoryIdDelete) || (showConfirmation &&
!showConfirmationKeyboardDelete &&
historyId === hoveringHistoryIdDelete) ||
// Drag over trash // Drag over trash
historyId === dragOverTrashId || historyId === dragOverTrashId ||
(Boolean(dragOverTrashId) && (Boolean(dragOverTrashId) &&
@ -2513,6 +2584,9 @@ export default function ClipboardHistoryPage() {
historyPreviewLineLimit historyPreviewLineLimit
} }
index={index} index={index}
setKeyboardHistorySelectedItemId={
setKeyboardHistorySelectedItemId
}
style={style} style={style}
/> />
) )