v3: allow users to edit dump title
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 2m54s
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 2m54s
This commit is contained in:
@@ -88,6 +88,9 @@ export function DumpCreateModal(
|
||||
const [mode, setMode] = useState<Mode>("url");
|
||||
const [url, setUrl] = useState(initialUrl);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [title, setTitle] = useState("");
|
||||
const [titleEditing, setTitleEditing] = useState(false);
|
||||
const titleInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [comment, setComment] = useState("");
|
||||
const [isPrivate, setIsPrivate] = useState(false);
|
||||
const [submitState, setSubmitState] = useState<SubmitState>({
|
||||
@@ -100,6 +103,12 @@ export function DumpCreateModal(
|
||||
const [memberships, setMemberships] = useState<PlaylistMembership[]>([]);
|
||||
const [playlistsLoading, setPlaylistsLoading] = useState(false);
|
||||
|
||||
const selectFile = (f: File | null) => {
|
||||
setFile(f);
|
||||
setTitle(f?.name ?? "");
|
||||
setTitleEditing(false);
|
||||
};
|
||||
|
||||
// Debounced URL preview
|
||||
useEffect(() => {
|
||||
if (debounceRef.current) clearTimeout(debounceRef.current);
|
||||
@@ -143,7 +152,7 @@ export function DumpCreateModal(
|
||||
setMode("file");
|
||||
setUrl("");
|
||||
setUrlPreview({ status: "idle" });
|
||||
setFile(pastedFile);
|
||||
selectFile(pastedFile);
|
||||
setSubmitState({ status: "idle" });
|
||||
return;
|
||||
}
|
||||
@@ -154,7 +163,7 @@ export function DumpCreateModal(
|
||||
const u = new URL(normalizeUrl(text));
|
||||
if (u.protocol === "http:" || u.protocol === "https:") {
|
||||
setMode("url");
|
||||
setFile(null);
|
||||
selectFile(null);
|
||||
setUrl(u.toString());
|
||||
setSubmitState({ status: "idle" });
|
||||
}
|
||||
@@ -206,6 +215,7 @@ export function DumpCreateModal(
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
if (comment.trim()) formData.append("comment", comment.trim());
|
||||
if (title.trim()) formData.append("title", title.trim());
|
||||
formData.append("isPrivate", String(isPrivate));
|
||||
res = await authFetch(`${API_URL}/api/dumps`, {
|
||||
method: "POST",
|
||||
@@ -287,7 +297,7 @@ export function DumpCreateModal(
|
||||
className={mode === "url" ? "active" : ""}
|
||||
onClick={() => {
|
||||
setMode("url");
|
||||
setFile(null);
|
||||
selectFile(null);
|
||||
setSubmitState({ status: "idle" });
|
||||
}}
|
||||
disabled={submitting}
|
||||
@@ -337,7 +347,7 @@ export function DumpCreateModal(
|
||||
setMode("file");
|
||||
setUrl("");
|
||||
setUrlPreview({ status: "idle" });
|
||||
setFile(pastedFile);
|
||||
selectFile(pastedFile);
|
||||
setSubmitState({ status: "idle" });
|
||||
}
|
||||
}}
|
||||
@@ -364,10 +374,46 @@ export function DumpCreateModal(
|
||||
<>
|
||||
<FileDropZone
|
||||
file={file}
|
||||
onChange={setFile}
|
||||
onChange={selectFile}
|
||||
disabled={submitting}
|
||||
/>
|
||||
{file && <LocalFilePreview file={file} />}
|
||||
{file && (
|
||||
<div className="form-group">
|
||||
<label htmlFor="dc-title">
|
||||
<Trans>Title</Trans>
|
||||
</label>
|
||||
<div className="dump-create-title-row">
|
||||
<input
|
||||
id="dc-title"
|
||||
ref={titleInputRef}
|
||||
type="text"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
disabled={submitting || !titleEditing}
|
||||
maxLength={VALIDATION.DUMP_TITLE_MAX}
|
||||
required
|
||||
/>
|
||||
{!titleEditing && (
|
||||
<button
|
||||
type="button"
|
||||
className="dump-create-title-edit-btn"
|
||||
onClick={() => {
|
||||
setTitleEditing(true);
|
||||
setTimeout(
|
||||
() => titleInputRef.current?.focus(),
|
||||
0,
|
||||
);
|
||||
}}
|
||||
disabled={submitting}
|
||||
aria-label={t`Edit title`}
|
||||
>
|
||||
✎
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user