1
0
Fork 0

fix(missions): accept plain-text mod lists and keep side op narrative collapsed

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jason Fraley 2026-09-10 16:13:59 -04:00
parent 0fa6d9abb5
commit c48fee4b4d
3 changed files with 16 additions and 5 deletions

View file

@ -234,6 +234,13 @@ export async function uploadSideOpModlist(
return { success: true, data: { modlistId: created.id, modlistName: created.modlistName } }; return { success: true, data: { modlistId: created.id, modlistName: created.modlistName } };
} catch (error) { } catch (error) {
const message = error instanceof Error ? error.message : "Unknown error"; const message = error instanceof Error ? error.message : "Unknown error";
if (/invalid: file/i.test(message)) {
return {
success: false,
error:
"That file type is not accepted. Please upload the .html file exported from the Arma 3 launcher, or a .txt mod list.",
};
}
return message === "Unauthorized" return message === "Unauthorized"
? { success: false, error: "You must be logged in." } ? { success: false, error: "You must be logged in." }
: { success: false, error: message }; : { success: false, error: message };

View file

@ -29,6 +29,6 @@ export const ModLists: CollectionConfig = {
}, },
], ],
upload: { upload: {
mimeTypes: ["text/html"], mimeTypes: ["text/html", "text/plain"],
}, },
}; };

View file

@ -144,7 +144,7 @@ export function CreateSideOpDialog({
useEffect(() => { useEffect(() => {
if (open) { if (open) {
setError(null); setError(null);
setNarrativeOpen(initial !== undefined); setNarrativeOpen(false);
if (initial) { if (initial) {
setName(initial.name); setName(initial.name);
setCodeName(initial.codeName); setCodeName(initial.codeName);
@ -174,6 +174,9 @@ export function CreateSideOpDialog({
}, [open, initial]); }, [open, initial]);
function narrativeInput() { function narrativeInput() {
if (!narrativeOpen) {
return {};
}
return { return {
briefing: narrative.briefing briefing: narrative.briefing
.filter((e) => e.sectionName.trim() !== "" || e.details.trim() !== "") .filter((e) => e.sectionName.trim() !== "" || e.details.trim() !== "")
@ -469,7 +472,7 @@ export function CreateSideOpDialog({
</Select> </Select>
<Input <Input
type="file" type="file"
accept=".html,.htm,text/html" accept=".html,.htm,.txt,text/html,text/plain"
disabled={modlistUploading} disabled={modlistUploading}
onChange={(e) => { onChange={(e) => {
const file = e.target.files?.[0]; const file = e.target.files?.[0];
@ -478,14 +481,15 @@ export function CreateSideOpDialog({
}} }}
/> />
<p className="text-xs text-muted-foreground"> <p className="text-xs text-muted-foreground">
Upload the HTML mod list exported from the Arma 3 launcher, or pick an existing one. Upload the mod list file exported from the Arma 3 launcher (.html) or a .txt mod
list, or pick an existing one.
</p> </p>
</div> </div>
<Collapsible open={narrativeOpen} onOpenChange={setNarrativeOpen}> <Collapsible open={narrativeOpen} onOpenChange={setNarrativeOpen}>
<CollapsibleTrigger asChild> <CollapsibleTrigger asChild>
<Button type="button" variant="outline" className="w-full justify-between"> <Button type="button" variant="outline" className="w-full justify-between">
Narrative &amp; logistics (briefing, objectives, infil/exfil) Narrative &amp; logistics (optional)
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">
{narrativeOpen ? "Hide" : "Show"} {narrativeOpen ? "Hide" : "Show"}
</span> </span>