feat(web): file view auto-rename on title change(#1192)
This commit is contained in:
@@ -1,31 +1,32 @@
|
|||||||
import { ElementIds } from '@/Constants/ElementIDs'
|
import { ElementIds } from '@/Constants/ElementIDs'
|
||||||
import { observer } from 'mobx-react-lite'
|
import { observer } from 'mobx-react-lite'
|
||||||
import { ChangeEventHandler, FormEventHandler, useCallback, useEffect, useState } from 'react'
|
import { ChangeEventHandler, useCallback, useRef } from 'react'
|
||||||
import AttachedFilesButton from '@/Components/AttachedFilesPopover/AttachedFilesButton'
|
import AttachedFilesButton from '@/Components/AttachedFilesPopover/AttachedFilesButton'
|
||||||
import FileOptionsPanel from '@/Components/FileContextMenu/FileOptionsPanel'
|
import FileOptionsPanel from '@/Components/FileContextMenu/FileOptionsPanel'
|
||||||
import FilePreview from '@/Components/FilePreview/FilePreview'
|
import FilePreview from '@/Components/FilePreview/FilePreview'
|
||||||
import { FileViewProps } from './FileViewProps'
|
import { FileViewProps } from './FileViewProps'
|
||||||
|
|
||||||
|
const SyncTimeoutNoDebounceMs = 100
|
||||||
|
const SyncTimeoutDebounceMs = 350
|
||||||
|
|
||||||
const FileViewWithoutProtection = ({ application, viewControllerManager, file }: FileViewProps) => {
|
const FileViewWithoutProtection = ({ application, viewControllerManager, file }: FileViewProps) => {
|
||||||
const [name, setName] = useState(file.name)
|
const syncTimeoutRef = useRef<number>()
|
||||||
|
|
||||||
useEffect(() => {
|
const onTitleChange: ChangeEventHandler<HTMLInputElement> = useCallback(
|
||||||
setName(file.name)
|
|
||||||
}, [file.name])
|
|
||||||
|
|
||||||
const onTitleChange: ChangeEventHandler<HTMLInputElement> = useCallback(async (event) => {
|
|
||||||
setName(event.target.value)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onFormSubmit: FormEventHandler = useCallback(
|
|
||||||
async (event) => {
|
async (event) => {
|
||||||
event.preventDefault()
|
if (syncTimeoutRef.current) {
|
||||||
|
clearTimeout(syncTimeoutRef.current)
|
||||||
|
}
|
||||||
|
|
||||||
await application.items.renameFile(file, name)
|
const shouldNotDebounce = application.noAccount()
|
||||||
|
const syncDebounceMs = shouldNotDebounce ? SyncTimeoutNoDebounceMs : SyncTimeoutDebounceMs
|
||||||
|
|
||||||
void application.sync.sync()
|
syncTimeoutRef.current = window.setTimeout(async () => {
|
||||||
|
await application.items.renameFile(file, event.target.value)
|
||||||
|
void application.sync.sync()
|
||||||
|
}, syncDebounceMs)
|
||||||
},
|
},
|
||||||
[application.items, application.sync, file, name],
|
[application, file],
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -37,7 +38,7 @@ const FileViewWithoutProtection = ({ application, viewControllerManager, file }:
|
|||||||
>
|
>
|
||||||
<div className="flex h-8 items-center justify-between">
|
<div className="flex h-8 items-center justify-between">
|
||||||
<div className="flex-grow">
|
<div className="flex-grow">
|
||||||
<form onSubmit={onFormSubmit} className="title overflow-auto">
|
<div className="title overflow-auto">
|
||||||
<input
|
<input
|
||||||
className="input text-lg"
|
className="input text-lg"
|
||||||
id={ElementIds.FileTitleEditor}
|
id={ElementIds.FileTitleEditor}
|
||||||
@@ -46,10 +47,10 @@ const FileViewWithoutProtection = ({ application, viewControllerManager, file }:
|
|||||||
event.target.select()
|
event.target.select()
|
||||||
}}
|
}}
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
value={name}
|
defaultValue={file.name}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
/>
|
/>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<div className="mr-3">
|
<div className="mr-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user