import { BSVersion } from "shared/bs-version.interface"; import { useRef, useState } from "react"; import { ModelsGrid } from "./models-grid.component"; import { MSModelType } from "shared/models/models/model-saber.model"; import { BsmDropdownButton, DropDownItem } from "../shared/bsm-dropdown-button.component"; import { ModelsManagerService } from "renderer/services/models-management/models-manager.service"; import { BsmLocalModel } from "shared/models/models/bsm-local-model.interface"; import { BsmButton } from "../shared/bsm-button.component"; import { useService } from "renderer/hooks/use-service.hook"; import { ModelsDownloaderService } from "renderer/services/models-management/models-downloader.service"; import { useOnUpdate } from "renderer/hooks/use-on-update.hook"; import { NotificationService } from "renderer/services/notification.service"; import { ConfigurationService } from "renderer/services/configuration.service"; import { useTranslation } from "renderer/hooks/use-translation.hook"; import { lt } from "semver"; import { lastValueFrom, of, take } from "rxjs"; import { FolderLinkState } from "renderer/services/version-folder-linker.service"; import { BsContentTabItemProps } from "../shared/bs-content-tab-panel/bs-content-tab-item.component"; import { BsContentTabPanel } from "../shared/bs-content-tab-panel/bs-content-tab-panel.component"; import { ModelTypeAvatarIcon } from "../svgs/icons/model-type-avatar-icon.component"; import { SvgIcon } from "../svgs/svg-icon.type"; import { ModelTypeSaberIcon } from "../svgs/icons/model-type-saber-icon.component"; import { ModelTypePlatformIcon } from "../svgs/icons/model-type-platform-icon.component"; import { ModelTypeBloqIcon } from "../svgs/icons/model-type-bloq-icon.component"; import { useObservable } from "renderer/hooks/use-observable.hook"; export function ModelsPanel({ version, isActive, goToMods }: { version?: BSVersion; isActive: boolean; goToMods?: () => void }) { const modelsManager = useService(ModelsManagerService); const modelDownloader = useService(ModelsDownloaderService); const notification = useService(NotificationService); const config = useService(ConfigurationService); const t = useTranslation(); const ref = useRef(); const modelsGridRefs = [useRef(null), useRef(null), useRef(null), useRef(null)]; const [modelTypeTab, setModelTypeTab] = useState(MSModelType.Avatar); const [currentTabIndex, setCurrentTabIndex] = useState(0); const [search, setSearch] = useState(""); const modelsLinkStats = { [MSModelType.Avatar]: useObservable(() => version ? modelsManager.$modelsLinkingState(version, MSModelType.Avatar) : of(null), FolderLinkState.Unlinked, [version]), [MSModelType.Saber]: useObservable(() => version ? modelsManager.$modelsLinkingState(version, MSModelType.Saber) : of(null), FolderLinkState.Unlinked, [version]), [MSModelType.Platfrom]: useObservable(() => version ? modelsManager.$modelsLinkingState(version, MSModelType.Platfrom) : of(null), FolderLinkState.Unlinked, [version]), [MSModelType.Bloq]: useObservable(() => version ? modelsManager.$modelsLinkingState(version, MSModelType.Bloq) : of(null), FolderLinkState.Unlinked, [version]), } useOnUpdate(() => { if (!isActive || !goToMods) { return; } if (config.get("not-remind-mods-models")) { return; } notification .notifyWarning({ title: "models.notifications.prevent-for-mods.title", desc: "models.notifications.prevent-for-mods.desc", actions: [ { id: "0", title: "models.notifications.prevent-for-mods.go-to-mods" }, { id: "1", title: "models.notifications.prevent-for-mods.not-remind", cancel: true }, ], duration: 12_000, }) .then(res => { if (res === "0") { return goToMods(); } if (res === "1") { config.set("not-remind-mods-models", true); } }); }, [isActive]); useOnUpdate(() => { if (!isActive || !version || lt(version.BSVersion, "1.29.4")) { return; } if (config.get("not-remind-models-breaks")) { return; } notification.notifyInfo({ title: "models.notifications.prevent-for-models-breaks.title", desc: "models.notifications.prevent-for-models-breaks.desc", actions: [{ id: "0", title: "models.notifications.prevent-for-mods.not-remind", cancel: true }], duration: 12_000 }).then(res => { if (res === "0") { config.set("not-remind-models-breaks", true); } }); }, [isActive, version]); const exportModels = () => { const selectedModels = modelsGridRefs.map(ref => ref.current?.getSelectedModels() as BsmLocalModel[]).flat(); modelsManager.exportModels(selectedModels, version); }; const deleteModels = () => { const activeTab = modelsGridRefs[currentTabIndex]; activeTab.current?.deleteSelectedModels(); }; const openDownloadModal = () => { const allLoadedModels = modelsGridRefs.map(ref => ref.current?.getModels() as BsmLocalModel[]).flat(); modelDownloader.openDownloadModelsModal(version, modelTypeTab, allLoadedModels); }; const threeDotsItems: DropDownItem[] = [ { text: "models.panel.actions.drop-down.export", onClick: exportModels, icon: "export" }, { text: "models.panel.actions.drop-down.delete", onClick: deleteModels, icon: "trash" }, ]; const getModelTabProps = (model: MSModelType): BsContentTabItemProps => { const onClick = async () => { const state = await lastValueFrom(modelsManager.$modelsLinkingState(version, model).pipe(take(1))); if (state === FolderLinkState.Pending || state === FolderLinkState.Processing) { return; } if (state === FolderLinkState.Linked) { modelsManager.unlinkModels(model, version); } else { modelsManager.linkModels(model, version); } } const getModelIcon = (model: MSModelType): SvgIcon => { switch (model) { case MSModelType.Avatar: return ModelTypeAvatarIcon; case MSModelType.Saber: return ModelTypeSaberIcon; case MSModelType.Platfrom: return ModelTypePlatformIcon; case MSModelType.Bloq: return ModelTypeBloqIcon; default: return ModelTypeAvatarIcon; } } return { text: `models.types.plural.${model}`, icon: getModelIcon(model), onClick: () => setModelTypeTab(model), linkProps: version ? { onClick, state: modelsLinkStats[model], } : null } }; return (
{ e.preventDefault(); openDownloadModal(); }} />
setSearch(e.target.value)} tabIndex={-1} />
setCurrentTabIndex(index)} tabs={[ getModelTabProps(MSModelType.Avatar), getModelTabProps(MSModelType.Saber), getModelTabProps(MSModelType.Platfrom), getModelTabProps(MSModelType.Bloq), ]} > <>
); }