diff --git a/src/ModMan/Web/Binds/AssetBinds.cpp b/src/ModMan/Web/Binds/AssetBinds.cpp index 707482c5..926ff941 100644 --- a/src/ModMan/Web/Binds/AssetBinds.cpp +++ b/src/ModMan/Web/Binds/AssetBinds.cpp @@ -99,29 +99,47 @@ namespace { public: std::vector assets; + std::vector references; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneAssetsDto, assets); + NLOHMANN_DEFINE_TYPE_EXTENSION(ZoneAssetsDto, assets, references); ZoneAssetsDto CreateZoneAssetsDto(const Zone& zone) { std::vector assets; + std::vector references; + + // Reserve some entries already. Numbers are arbitrary. + const auto assetCount = zone.m_pools->GetTotalAssetCount(); + assets.reserve(assetCount / 2); + references.reserve(assetCount / 8); const auto& assetTypeMapper = *ICommonAssetTypeMapper::GetCommonAssetMapperByGame(zone.m_game_id); for (const auto& asset : *zone.m_pools) { - assets.emplace_back(AssetDto{ - .type = assetTypeMapper.GameToCommonAssetType(asset->m_type), - .name = asset->m_name, - }); + if (asset->IsReference()) + { + references.emplace_back(AssetDto{ + .type = assetTypeMapper.GameToCommonAssetType(asset->m_type), + .name = asset->ReferencedAssetName(), + }); + } + else + { + assets.emplace_back(AssetDto{ + .type = assetTypeMapper.GameToCommonAssetType(asset->m_type), + .name = asset->m_name, + }); + } } return ZoneAssetsDto{ .assets = std::move(assets), + .references = std::move(references), }; } - ZoneAssetsDto GetZonesForZone(const std::string& zoneName) + std::optional GetZonesForZone(const std::string& zoneName) { auto& context = ModManContext::Get().m_fast_file; @@ -138,7 +156,7 @@ namespace } } - return ZoneAssetsDto{.assets = std::vector()}; + return std::nullopt; } } // namespace @@ -146,11 +164,11 @@ namespace ui { void RegisterAssetBinds(webview::webview& wv) { - Bind(wv, - "getAssetsForZone", - [](const std::string& zoneName) - { - return GetZonesForZone(zoneName); - }); + Bind>(wv, + "getAssetsForZone", + [](const std::string& zoneName) + { + return GetZonesForZone(zoneName); + }); } } // namespace ui diff --git a/src/ModMan/main.cpp b/src/ModMan/main.cpp index cd0e838d..b7f82fa6 100644 --- a/src/ModMan/main.cpp +++ b/src/ModMan/main.cpp @@ -63,7 +63,7 @@ namespace newWindow.set_title("OpenAssetTools ModMan"); newWindow.set_size(1280, 640, WEBVIEW_HINT_NONE); - newWindow.set_size(480, 320, WEBVIEW_HINT_MIN); + newWindow.set_size(640, 480, WEBVIEW_HINT_MIN); InstallAssetHandler(newWindow); ui::RegisterAllBinds(newWindow); diff --git a/src/ModManUi/src/App.vue b/src/ModManUi/src/App.vue index 8e4f6e0f..308f9eba 100644 --- a/src/ModManUi/src/App.vue +++ b/src/ModManUi/src/App.vue @@ -1,30 +1,12 @@ diff --git a/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelector.vue b/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelector.vue new file mode 100644 index 00000000..02a85d85 --- /dev/null +++ b/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelector.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelectorDetails.vue b/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelectorDetails.vue new file mode 100644 index 00000000..100f4a04 --- /dev/null +++ b/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelectorDetails.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/src/ModManUi/src/components/ZoneSelector.vue b/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelectorZoneList.vue similarity index 51% rename from src/ModManUi/src/components/ZoneSelector.vue rename to src/ModManUi/src/components/unlinking/zone_selector/ZoneSelectorZoneList.vue index 2e4ab4b0..4a10814d 100644 --- a/src/ModManUi/src/components/ZoneSelector.vue +++ b/src/ModManUi/src/components/unlinking/zone_selector/ZoneSelectorZoneList.vue @@ -2,7 +2,7 @@ import Button from "primevue/button"; import ProgressBar from "primevue/progressbar"; import Listbox from "primevue/listbox"; -import { computed, ref, watch } from "vue"; +import { computed } from "vue"; import { useZoneStore } from "@/stores/ZoneStore"; import { webviewBinds } from "@/native"; @@ -12,7 +12,18 @@ interface SelectableZone { } const zoneStore = useZoneStore(); -const selectedZone = ref(null); +const selectedZone = defineModel("selectedZone"); + +async function openFastFileSelect() { + return await webviewBinds.openFileDialog({ filters: [{ name: "Fastfiles", filter: "*.ff" }] }); +} + +async function onOpenFastFileClick() { + const fastFilePath = await openFastFileSelect(); + if (!fastFilePath) return; + + zoneStore.loadFastFile(fastFilePath); +} const availableZones = computed(() => { const result = [ @@ -40,64 +51,48 @@ const availableZones = computed(() => { function onUnloadClicked() { if (!selectedZone.value) return; - webviewBinds.unloadZone(selectedZone.value.zoneName).catch((e: string) => { + webviewBinds.unloadZone(selectedZone.value).catch((e: string) => { console.error("Failed to unload zone:", e); }); } - -watch( - () => zoneStore.loadedZones, - (newValue) => { - // Reset selection if unloaded - if (!selectedZone.value) return; - if (newValue.findIndex((loadedZone) => loadedZone.name === selectedZone.value?.zoneName) >= 0) - return; - selectedZone.value = null; - }, - { deep: true }, -);