Implement renaming files

This commit is contained in:
Misode
2024-11-19 03:26:00 +01:00
parent 14abe1ee52
commit b0963b1163
3 changed files with 48 additions and 14 deletions

View File

@@ -1,4 +1,4 @@
import { useState } from 'preact/hooks'
import { useCallback, useState } from 'preact/hooks'
import { Analytics } from '../../Analytics.js'
import { useLocale } from '../../contexts/index.js'
import { useModal } from '../../contexts/Modal.jsx'
@@ -7,33 +7,34 @@ import { TextInput } from '../forms/index.js'
import { Modal } from '../Modal.js'
interface Props {
uri: string,
oldId: string,
onRename: (newId: string) => void,
}
export function FileRenaming({ uri }: Props) {
export function FileRenaming({ oldId, onRename }: Props) {
const { locale } = useLocale()
const { hideModal } = useModal()
const [fileId, setFileId] = useState(uri) // TODO: get original file id
const [fileId, setFileId] = useState(oldId)
const [error, setError] = useState<string>()
const changeFileId = (str: string) => {
const changeFileId = useCallback((str: string) => {
setError(undefined)
setFileId(str)
}
}, [])
const doSave = () => {
const doRename = useCallback(() => {
if (!fileId.match(/^([a-z0-9_.-]+:)?[a-z0-9/_.-]+$/)) {
setError('Invalid resource location')
return
}
Analytics.renameProjectFile('menu')
// TODO: rename file
onRename(fileId)
hideModal()
}
}, [fileId, hideModal])
return <Modal class="file-modal">
<p>{locale('project.rename_file')}</p>
<TextInput autofocus class="btn btn-input" value={fileId} onChange={changeFileId} onEnter={doSave} onCancel={hideModal} placeholder={locale('resource_location')} spellcheck={false} />
<TextInput autofocus class="btn btn-input" value={fileId} onChange={changeFileId} onEnter={doRename} onCancel={hideModal} placeholder={locale('resource_location')} spellcheck={false} />
{error !== undefined && <span class="invalid">{error}</span>}
<Btn icon="pencil" label={locale('project.rename')} onClick={doSave} />
<Btn icon="pencil" label={locale('project.rename')} onClick={doRename} />
</Modal>
}

View File

@@ -1,3 +1,4 @@
import { Identifier } from 'deepslate'
import { route } from 'preact-router'
import { useCallback, useMemo, useRef } from 'preact/hooks'
import config from '../../Config.js'
@@ -59,7 +60,24 @@ export function ProjectPanel() {
icon: 'pencil',
label: locale('project.rename_file'),
onAction: (uri: string) => {
showModal(() => <FileRenaming uri={uri} />)
const res = service?.dissectUri(uri)
if (res?.ok) {
// This is pretty hacky, improve this in the future when spyglass has a "constructUri" function
const oldSuffix = `/${res.namespace}/${res.path}/${res.identifier}${res.ext}`
if (!uri.endsWith(oldSuffix)) {
console.warn(`Expected ${uri} to end with ${oldSuffix}`)
return
}
const onRename = (newId: string) => {
const prefix = uri.substring(0, uri.length - oldSuffix.length)
const { namespace, path } = Identifier.parse(newId)
const newUri = prefix + `/${namespace}/${res.path}/${path}${res.ext}`
service?.renameFile(uri, newUri).then(() => {
setProjectUri(newUri)
})
}
showModal(() => <FileRenaming oldId={`${res.namespace}:${res.identifier}`} onRename={onRename} />)
}
},
},
{
@@ -71,7 +89,7 @@ export function ProjectPanel() {
})
},
},
], [client, projectRoot, showModal])
], [client, service, projectRoot, showModal])
const FolderEntry: TreeViewGroupRenderer = useCallback(({ name, open, onClick }) => {
return <div class="entry" onClick={onClick} >