Merge branch 'dev'
This commit is contained in:
@@ -178,14 +178,13 @@ const MyChores = () => {
|
|||||||
if (event.ctrlKey || event.metaKey) {
|
if (event.ctrlKey || event.metaKey) {
|
||||||
setShowKeyboardShortcuts(true)
|
setShowKeyboardShortcuts(true)
|
||||||
}
|
}
|
||||||
|
const isHoldingCmdOrCtrl = event.ctrlKey || event.metaKey
|
||||||
// Ctrl/Cmd + K to open task modal
|
// Ctrl/Cmd + K to open task modal
|
||||||
if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
|
if (isHoldingCmdOrCtrl && event.key === 'k') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
setAddTaskModalOpen(true)
|
setAddTaskModalOpen(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('addTaskModalOpen', addTaskModalOpen)
|
|
||||||
|
|
||||||
if (addTaskModalOpen) {
|
if (addTaskModalOpen) {
|
||||||
// we want to ignore anything in here until the modal close
|
// we want to ignore anything in here until the modal close
|
||||||
@@ -193,26 +192,26 @@ const MyChores = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ctrl/Cmd + J to navigate to create chore page
|
// Ctrl/Cmd + J to navigate to create chore page
|
||||||
if ((event.ctrlKey || event.metaKey) && event.key === 'j') {
|
if (isHoldingCmdOrCtrl && event.key === 'j') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
Navigate(`/chores/create`)
|
Navigate(`/chores/create`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctrl/Cmd + F to focus search input:
|
// Ctrl/Cmd + F to focus search input:
|
||||||
else if ((event.ctrlKey || event.metaKey) && event.key === 'f') {
|
else if (isHoldingCmdOrCtrl && event.key === 'f') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
searchInputRef.current?.focus()
|
searchInputRef.current?.focus()
|
||||||
return
|
return
|
||||||
// Ctrl/Cmd + X to close search input
|
// Ctrl/Cmd + X to close search input
|
||||||
} else if ((event.ctrlKey || event.metaKey) && event.key === 'x') {
|
} else if (isHoldingCmdOrCtrl && event.key === 'x') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (searchTerm?.length > 0) {
|
if (searchTerm?.length > 0) {
|
||||||
handleSearchClose()
|
handleSearchClose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ctrl/Cmd + S Toggle Multi-select mode
|
// Ctrl/Cmd + S Toggle Multi-select mode
|
||||||
else if ((event.ctrlKey || event.metaKey) && event.key === 's') {
|
else if (isHoldingCmdOrCtrl && event.key === 's') {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
toggleMultiSelectMode()
|
toggleMultiSelectMode()
|
||||||
return
|
return
|
||||||
@@ -220,7 +219,7 @@ const MyChores = () => {
|
|||||||
|
|
||||||
// Ctrl/Cmd + A to select all - works both in and out of multi-select mode
|
// Ctrl/Cmd + A to select all - works both in and out of multi-select mode
|
||||||
else if (
|
else if (
|
||||||
(event.ctrlKey || event.metaKey) &&
|
isHoldingCmdOrCtrl &&
|
||||||
event.key === 'a' &&
|
event.key === 'a' &&
|
||||||
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
||||||
) {
|
) {
|
||||||
@@ -314,25 +313,23 @@ const MyChores = () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete/Backspace key for bulk delete (with confirmation)
|
// Enter key for bulk complete
|
||||||
if (
|
if (
|
||||||
(event.key === 'Delete' || event.key === 'Backspace') &&
|
isHoldingCmdOrCtrl &&
|
||||||
|
event.key === 'Enter' &&
|
||||||
selectedChores.size > 0
|
selectedChores.size > 0
|
||||||
) {
|
) {
|
||||||
event.preventDefault()
|
|
||||||
handleBulkDelete()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enter key for bulk complete
|
|
||||||
if (event.key === 'Enter' && selectedChores.size > 0) {
|
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
handleBulkComplete()
|
handleBulkComplete()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// "/" key for bulk skip
|
// "/" key for bulk skip
|
||||||
if (event.key === '/' && selectedChores.size > 0) {
|
if (
|
||||||
|
isHoldingCmdOrCtrl &&
|
||||||
|
event.key === '/' &&
|
||||||
|
selectedChores.size > 0
|
||||||
|
) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
handleBulkSkip()
|
handleBulkSkip()
|
||||||
return
|
return
|
||||||
@@ -340,10 +337,8 @@ const MyChores = () => {
|
|||||||
|
|
||||||
// "x" key for bulk archive (without shift or modifiers)
|
// "x" key for bulk archive (without shift or modifiers)
|
||||||
if (
|
if (
|
||||||
event.key === 'x' &&
|
isHoldingCmdOrCtrl &&
|
||||||
!event.shiftKey &&
|
(event.key === 'x' || event.key === 'X') &&
|
||||||
!event.ctrlKey &&
|
|
||||||
!event.metaKey &&
|
|
||||||
selectedChores.size > 0 &&
|
selectedChores.size > 0 &&
|
||||||
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
||||||
) {
|
) {
|
||||||
@@ -351,79 +346,17 @@ const MyChores = () => {
|
|||||||
handleBulkArchive()
|
handleBulkArchive()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// "X" key (Shift + x) for bulk delete - without Ctrl/Cmd modifiers
|
|
||||||
if (
|
|
||||||
event.shiftKey &&
|
|
||||||
(event.key === 'X' || event.key === 'x') &&
|
|
||||||
!event.ctrlKey &&
|
|
||||||
!event.metaKey &&
|
|
||||||
selectedChores.size > 0 &&
|
|
||||||
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
|
||||||
) {
|
|
||||||
event.preventDefault()
|
|
||||||
handleBulkDelete()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global shortcuts (work outside multi-select mode)
|
|
||||||
// "o" key to show archived chores (when not in multi-select and archived chores not shown)
|
|
||||||
if (
|
if (
|
||||||
event.key === 'o' &&
|
isHoldingCmdOrCtrl &&
|
||||||
!isMultiSelectMode &&
|
(event.key === 'e' || event.key === 'E') &&
|
||||||
archivedChores === null &&
|
selectedChores.size > 0 &&
|
||||||
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
|
||||||
) {
|
|
||||||
event.preventDefault()
|
|
||||||
GetArchivedChores()
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
setArchivedChores(data.res)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ctrl/Cmd + X for bulk archive (works in both multi-select and normal mode)
|
|
||||||
if (
|
|
||||||
(event.ctrlKey || event.metaKey) &&
|
|
||||||
event.key === 'x' &&
|
|
||||||
!event.shiftKey &&
|
|
||||||
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
|
||||||
) {
|
|
||||||
event.preventDefault()
|
|
||||||
if (isMultiSelectMode && selectedChores.size > 0) {
|
|
||||||
handleBulkArchive()
|
|
||||||
} else if (!isMultiSelectMode) {
|
|
||||||
// Enable multi-select mode first, then show a message
|
|
||||||
setIsMultiSelectMode(true)
|
|
||||||
showSuccess({
|
|
||||||
title: '📦 Archive Mode',
|
|
||||||
message:
|
|
||||||
'Multi-select enabled. Select tasks to archive, or use Cmd+X again.',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ctrl/Cmd + Shift + X for bulk delete (works in both multi-select and normal mode)
|
|
||||||
if (
|
|
||||||
(event.ctrlKey || event.metaKey) &&
|
|
||||||
event.shiftKey &&
|
|
||||||
event.key === 'X' &&
|
|
||||||
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
!['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)
|
||||||
) {
|
) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (isMultiSelectMode && selectedChores.size > 0) {
|
if (isMultiSelectMode && selectedChores.size > 0) {
|
||||||
handleBulkDelete()
|
handleBulkDelete()
|
||||||
} else if (!isMultiSelectMode) {
|
|
||||||
// Enable multi-select mode first, then show a message
|
|
||||||
setIsMultiSelectMode(true)
|
|
||||||
showSuccess({
|
|
||||||
title: '🗑️ Delete Mode',
|
|
||||||
message:
|
|
||||||
'Multi-select enabled. Select tasks to delete, or use Cmd+Shift+X again.',
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1546,8 +1479,7 @@ const MyChores = () => {
|
|||||||
Delete
|
Delete
|
||||||
{showKeyboardShortcuts && selectedChores.size > 0 && (
|
{showKeyboardShortcuts && selectedChores.size > 0 && (
|
||||||
<KeyboardShortcutHint
|
<KeyboardShortcutHint
|
||||||
withShift={true}
|
shortcut='E'
|
||||||
shortcut='X'
|
|
||||||
sx={{
|
sx={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: -8,
|
top: -8,
|
||||||
|
|||||||
@@ -14,17 +14,21 @@ const NetworkBanner = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ position: 'relative' }}>
|
<Box sx={{}}>
|
||||||
{!isOnline && (
|
{!isOnline && (
|
||||||
<Alert
|
<Alert
|
||||||
variant='soft'
|
variant='soft'
|
||||||
color='warning'
|
color='warning'
|
||||||
sx={{
|
sx={{
|
||||||
zIndex: 1000,
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
zIndex: 10001,
|
||||||
|
padding: '4px',
|
||||||
|
pt: `calc( env(safe-area-inset-top, 0px))`,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
padding: '4px',
|
|
||||||
fontSize: '10px',
|
fontSize: '10px',
|
||||||
fontWeight: 'md',
|
fontWeight: 'md',
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user