mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-31 00:10:22 +08:00
feat: add pause and resume functionality to file watcher; enhance error handling in useInPlaceEdit hook
This commit is contained in:
parent
3093a9e5d0
commit
f8428df247
@ -151,6 +151,7 @@ class FileStorage {
|
||||
private currentWatchPath?: string
|
||||
private debounceTimer?: NodeJS.Timeout
|
||||
private watcherConfig: Required<FileWatcherConfig> = DEFAULT_WATCHER_CONFIG
|
||||
private isPaused = false
|
||||
|
||||
constructor() {
|
||||
this.initStorageDir()
|
||||
@ -1448,6 +1449,12 @@ class FileStorage {
|
||||
|
||||
private createChangeHandler() {
|
||||
return (eventType: string, filePath: string) => {
|
||||
// Skip processing if watcher is paused
|
||||
if (this.isPaused) {
|
||||
logger.debug('File change ignored (watcher paused)', { eventType, filePath })
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.shouldWatchFile(filePath, eventType)) {
|
||||
return
|
||||
}
|
||||
@ -1744,8 +1751,8 @@ class FileStorage {
|
||||
public pauseFileWatcher = async (): Promise<void> => {
|
||||
if (this.watcher) {
|
||||
logger.debug('Pausing file watcher')
|
||||
// Chokidar doesn't have pause, so we temporarily set a flag
|
||||
// We'll handle this by clearing the debounce timer
|
||||
this.isPaused = true
|
||||
// Clear any pending debounced notifications
|
||||
if (this.debounceTimer) {
|
||||
clearTimeout(this.debounceTimer)
|
||||
this.debounceTimer = undefined
|
||||
@ -1759,6 +1766,7 @@ class FileStorage {
|
||||
public resumeFileWatcher = async (): Promise<void> => {
|
||||
if (this.watcher && this.currentWatchPath) {
|
||||
logger.debug('Resuming file watcher')
|
||||
this.isPaused = false
|
||||
// Send a synthetic refresh event to trigger tree reload
|
||||
this.notifyChange('refresh', this.currentWatchPath)
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { loggerService } from '@logger'
|
||||
import { useCallback, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const logger = loggerService.withContext('useInPlaceEdit')
|
||||
export interface UseInPlaceEditOptions {
|
||||
onSave: ((value: string) => void) | ((value: string) => Promise<void>)
|
||||
onCancel?: () => void
|
||||
onError?: (error: unknown) => void
|
||||
autoSelectOnStart?: boolean
|
||||
trimOnSave?: boolean
|
||||
}
|
||||
@ -28,7 +30,8 @@ export interface UseInPlaceEditReturn {
|
||||
* @returns An object containing the editing state and handler functions
|
||||
*/
|
||||
export function useInPlaceEdit(options: UseInPlaceEditOptions): UseInPlaceEditReturn {
|
||||
const { onSave, onCancel, autoSelectOnStart = true, trimOnSave = true } = options
|
||||
const { onSave, onCancel, onError, autoSelectOnStart = true, trimOnSave = true } = options
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [isSaving, setIsSaving] = useState(false)
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
@ -68,9 +71,17 @@ export function useInPlaceEdit(options: UseInPlaceEditOptions): UseInPlaceEditRe
|
||||
setEditValue('')
|
||||
} catch (error) {
|
||||
logger.error('Error saving in-place edit', { error })
|
||||
|
||||
// Call custom error handler if provided, otherwise show default toast
|
||||
if (onError) {
|
||||
onError(error)
|
||||
} else {
|
||||
window.toast.error(t('common.save_failed') || 'Failed to save')
|
||||
}
|
||||
} finally {
|
||||
setIsSaving(false)
|
||||
}
|
||||
}, [isSaving, trimOnSave, editValue, onSave])
|
||||
}, [isSaving, trimOnSave, editValue, onSave, onError, t])
|
||||
|
||||
const cancelEdit = useCallback(() => {
|
||||
setIsEditing(false)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user