import 'package:flutter/material.dart'; import '../structs/mod.dart'; import '../structs/settings.dart'; class ModManager extends StatefulWidget { Settings settings; ModManager({super.key, required this.settings}); @override ModManagerState createState() => ModManagerState(settings: settings); } class ModManagerState extends State { Settings settings; ModManagerState({required this.settings}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Conan Exiles Server Manager - Mod Manager"), backgroundColor: Color.fromARGB(255, 100, 0, 0), ), body: ReorderableListView.builder( onReorder: (oldIndex, newIndex) { if (oldIndex < newIndex) { // From top to Bottom int end = newIndex - 1; Mod item = settings.inst!.mods[oldIndex]; int i = 0; int local = oldIndex; do { settings.inst!.mods[local] = settings.inst!.mods[++local]; i++; } while (i < end - oldIndex); settings.inst!.mods[end] = item; } else if (oldIndex > newIndex) { //From bottom to top Mod item = settings.inst!.mods[oldIndex]; for (int i = oldIndex; i > newIndex; i--) { settings.inst!.mods[i] = settings.inst!.mods[i - 1]; } settings.inst!.mods[newIndex] = item; } setState(() { settings.Write(); }); }, itemBuilder: (ctx, idx) { Mod mod = settings.inst!.mods[idx]; return Padding( key: Key(mod.mod_instance_id()), padding: EdgeInsets.all(12), child: ListTile( title: Text(mod.mod_name), subtitle: Text("ID: ${mod.mod_id}\nLoad Order: ${idx}"), onTap: () async { final reply = await Navigator.pushNamed( context, "/server/mods/edit", arguments: Mod( mod_id: mod.mod_id, mod_name: mod.mod_name, mod_pak: mod.mod_pak, mod_hash: mod.mod_hash, newMod: false)); if (reply != null) { if (reply is bool) { setState(() { settings.inst!.mods.removeAt(idx); }); } setState(() { settings.inst!.mods[idx] = reply as Mod; }); } }, ), ); }, itemCount: settings.inst!.mods.length, ), floatingActionButton: ElevatedButton( child: Icon(Icons.add), onPressed: () async { // Open new mod info screen final reply = await Navigator.pushNamed(context, "/server/mods/edit", arguments: Mod(newMod: true)); if (reply != null && reply is! bool) { Mod mod = reply as Mod; setState(() { settings.inst!.mods.add(mod); }); } }, ), ); } } class ModPage extends StatelessWidget { bool initDone = false; TextEditingController id = TextEditingController(); TextEditingController name = TextEditingController(); String instance = ""; bool isNewMod = false; bool willDelete = false; String pak = "Not initialized"; String hash = ""; @override Widget build(BuildContext context) { final args = ModalRoute.of(context)!.settings.arguments as Mod?; if (!initDone) { initDone = true; if (args != null) { id.text = args.mod_id.toString(); name.text = args.mod_name; isNewMod = args.newMod; instance = args.mod_instance_id(); pak = args.mod_pak; hash = args.mod_hash; } } return Scaffold( appBar: AppBar( title: Text("Mod Editor"), backgroundColor: Color.fromARGB(255, 100, 0, 0), ), floatingActionButton: ElevatedButton( child: Text("Save"), onPressed: () { int idVal = 0; try { idVal = int.parse(id.text); } catch (E) {} if (willDelete) { Navigator.pop(context, true); } else { Navigator.pop(context, Mod(mod_id: idVal, mod_name: name.text, newMod: false)); } }, ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column(children: [ Row( children: [ SizedBox( width: 150, child: ListTile( leading: Icon(Icons.abc_rounded), title: Text("Mod Name"), )), Expanded( child: TextField( controller: name, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(4)))), ) ], ), SizedBox( height: 16, ), Row( children: [ SizedBox( width: 150, child: ListTile( leading: Icon(Icons.perm_identity), title: Text("Mod ID")), ), Expanded( child: TextField( controller: id, keyboardType: TextInputType.number, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(4))), )) ], ), SizedBox( height: 16, ), ListTile( title: Text("Mod Instance ID"), subtitle: Text(instance), ), ListTile( title: Text("Mod Pak File: $pak"), subtitle: Text("Mod pak file name as detected during downloading"), ), ListTile( title: Text("Mod Hash"), subtitle: Text(hash), ), if (!isNewMod) ElevatedButton( onPressed: () { willDelete = true; Navigator.pop(context); }, child: Row( children: [ Icon(Icons.delete), SizedBox( width: 4, ), Text("Remove Mod") ], )) ]), ), ); } }