Fixed minor issues with the Archetypes
This commit is contained in:
@@ -459,12 +459,12 @@ export default function MelodyDetail() {
|
||||
const binaryFilename = `${binaryPid}.bsm`;
|
||||
|
||||
// Derive a display name: for firebase URLs extract the filename portion
|
||||
let displayName = binaryFilename;
|
||||
let downloadName = binaryFilename;
|
||||
if (!files.binary_url && melody.url) {
|
||||
try {
|
||||
const urlPath = decodeURIComponent(new URL(melody.url).pathname);
|
||||
const parts = urlPath.split("/");
|
||||
displayName = parts[parts.length - 1] || binaryFilename;
|
||||
downloadName = parts[parts.length - 1] || binaryFilename;
|
||||
} catch { /* keep binaryFilename */ }
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ export default function MelodyDetail() {
|
||||
const objectUrl = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = objectUrl;
|
||||
a.download = displayName;
|
||||
a.download = downloadName;
|
||||
a.click();
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
} catch (err) {
|
||||
@@ -493,18 +493,37 @@ export default function MelodyDetail() {
|
||||
};
|
||||
|
||||
return (
|
||||
<span className="inline-flex items-center gap-2">
|
||||
<a
|
||||
href={binaryUrl}
|
||||
onClick={handleDownload}
|
||||
className="underline"
|
||||
style={{ color: "var(--accent)" }}
|
||||
>
|
||||
{displayName}
|
||||
</a>
|
||||
{!files.binary_url && melody.url && (
|
||||
<span className="text-xs px-1.5 py-0.5 rounded" style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-muted)" }}>
|
||||
via URL
|
||||
<span className="inline-flex flex-col gap-0.5">
|
||||
<span className="inline-flex items-center gap-2">
|
||||
{builtMelody?.name ? (
|
||||
<strong style={{ color: "var(--text-heading)" }}>{builtMelody.name}</strong>
|
||||
) : (
|
||||
<a
|
||||
href={binaryUrl}
|
||||
onClick={handleDownload}
|
||||
className="underline"
|
||||
style={{ color: "var(--accent)" }}
|
||||
>
|
||||
{downloadName}
|
||||
</a>
|
||||
)}
|
||||
{!files.binary_url && melody.url && (
|
||||
<span className="text-xs px-1.5 py-0.5 rounded" style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-muted)" }}>
|
||||
via URL
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
{builtMelody?.name && (
|
||||
<span className="text-xs" style={{ color: "var(--text-muted)" }}>
|
||||
file:{" "}
|
||||
<a
|
||||
href={binaryUrl}
|
||||
onClick={handleDownload}
|
||||
className="underline font-mono"
|
||||
style={{ color: "var(--accent)" }}
|
||||
>
|
||||
{downloadName}
|
||||
</a>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
|
||||
@@ -93,6 +93,7 @@ export default function MelodyForm() {
|
||||
const [showPlayback, setShowPlayback] = useState(false);
|
||||
const [builtMelody, setBuiltMelody] = useState(null);
|
||||
const [assignedBinaryName, setAssignedBinaryName] = useState(null);
|
||||
const [assignedBinaryPid, setAssignedBinaryPid] = useState(null);
|
||||
|
||||
// Metadata / Admin Notes
|
||||
const [adminNotes, setAdminNotes] = useState([]);
|
||||
@@ -145,6 +146,7 @@ export default function MelodyForm() {
|
||||
const bm = await api.get(`/builder/melodies/for-melody/${id}`);
|
||||
setBuiltMelody(bm || null);
|
||||
setAssignedBinaryName(bm?.name || null);
|
||||
setAssignedBinaryPid(bm?.pid || null);
|
||||
} catch {
|
||||
setBuiltMelody(null);
|
||||
}
|
||||
@@ -391,7 +393,12 @@ export default function MelodyForm() {
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate("/melodies")}
|
||||
onClick={async () => {
|
||||
if (savedMelodyId) {
|
||||
try { await api.delete(`/melodies/${savedMelodyId}`); } catch { /* best-effort */ }
|
||||
}
|
||||
navigate("/melodies");
|
||||
}}
|
||||
className="px-4 py-2 text-sm rounded-md transition-colors"
|
||||
style={{ backgroundColor: "var(--btn-neutral)", color: "var(--text-white)" }}
|
||||
>
|
||||
@@ -648,11 +655,20 @@ export default function MelodyForm() {
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1" style={labelStyle}>Binary File (.bsm / .bin)</label>
|
||||
{existingFiles.binary_url && (
|
||||
<p className="text-xs mb-1" style={{ color: "var(--success)" }}>
|
||||
{assignedBinaryName
|
||||
? <><strong>{assignedBinaryName}.bsm</strong> is set. Selecting a new file will replace it.</>
|
||||
: "Current file uploaded. Selecting a new file will replace it."}
|
||||
</p>
|
||||
<div className="text-xs mb-1" style={{ color: "var(--success)" }}>
|
||||
{assignedBinaryName ? (
|
||||
<>
|
||||
<p><strong>{assignedBinaryName}</strong> has been assigned. Selecting a new file will replace it.</p>
|
||||
{assignedBinaryPid && (
|
||||
<p className="mt-0.5" style={{ color: "var(--text-muted)" }}>
|
||||
filename: <span className="font-mono">{assignedBinaryPid}.bsm</span>
|
||||
</p>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<p>Current file uploaded. Selecting a new file will replace it.</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<input type="file" accept=".bin,.bsm" onChange={(e) => setBinaryFile(e.target.files[0] || null)} className="w-full text-sm" style={mutedStyle} />
|
||||
<div className="flex gap-2 mt-2">
|
||||
@@ -806,6 +822,7 @@ export default function MelodyForm() {
|
||||
onSuccess={(archetype) => {
|
||||
setShowSelectBuilt(false);
|
||||
setAssignedBinaryName(archetype.name);
|
||||
setAssignedBinaryPid(archetype.pid || null);
|
||||
if (!pid.trim() && archetype.pid) setPid(archetype.pid);
|
||||
if (archetype.steps != null) updateInfo("steps", archetype.steps);
|
||||
if (archetype.totalNotes != null) updateInfo("totalNotes", archetype.totalNotes);
|
||||
@@ -838,6 +855,7 @@ export default function MelodyForm() {
|
||||
onSuccess={(archetype) => {
|
||||
setShowBuildOnTheFly(false);
|
||||
setAssignedBinaryName(archetype.name);
|
||||
setAssignedBinaryPid(archetype.pid || null);
|
||||
if (!pid.trim() && archetype.pid) setPid(archetype.pid);
|
||||
if (archetype.steps != null) updateInfo("steps", archetype.steps);
|
||||
if (archetype.totalNotes != null) updateInfo("totalNotes", archetype.totalNotes);
|
||||
|
||||
@@ -54,7 +54,7 @@ export default function SelectArchetypeModal({ open, melodyId, currentMelody, cu
|
||||
});
|
||||
if (!res.ok) throw new Error(`Failed to download binary: ${res.statusText}`);
|
||||
const blob = await res.blob();
|
||||
const file = new File([blob], `${archetype.name}.bsm`, { type: "application/octet-stream" });
|
||||
const file = new File([blob], `${archetype.pid || archetype.name}.bsm`, { type: "application/octet-stream" });
|
||||
|
||||
await api.upload(`/melodies/${melodyId}/upload/binary`, file);
|
||||
await api.post(`/builder/melodies/${archetype.id}/assign?firestore_melody_id=${melodyId}`);
|
||||
|
||||
Reference in New Issue
Block a user