Skip to content

Commit 7119735

Browse files
committed
in merge packs options to load mods from existing merged pack and to hide already merged mods
1 parent 916f64d commit 7119735

File tree

3 files changed

+99
-12
lines changed

3 files changed

+99
-12
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "wh3mm",
33
"productName": "wh3mm",
4-
"version": "1.26.5",
4+
"version": "1.27.0",
55
"description": "WH3 Mod Manager",
66
"main": ".webpack/main",
77
"scripts": {

src/ModRows.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ export default function ModRows() {
474474
.filter((iterMod) => !hiddenMods.find((mod) => mod.name === iterMod.name))
475475
.map((mod) => (
476476
<ModRow
477+
key={mod.path}
477478
{...{
478479
mod,
479480
onRowHoverStart,

src/ModsMerger.tsx

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import { Modal } from "./flowbite/components/Modal/index";
3-
import { Spinner, Tabs } from "./flowbite";
3+
import { Spinner, Tabs, Tooltip } from "./flowbite";
44
import { getModsSortedByName, getModsSortedByHumanName, getModsSortedBySize } from "./modSortingHelpers";
55
import Select, { ActionMeta, SingleValue } from "react-select";
66
import selectStyle from "./styles/selectStyle";
@@ -16,13 +16,29 @@ const ModsMerger = React.memo(() => {
1616
);
1717
const mods = useSelector(modsNotInDataSelector);
1818

19+
const mergerModsSelector = createSelector(
20+
(state: { app: AppState }) => state.app.currentPreset.mods,
21+
(mods) => mods.filter((mod) => mod.mergedModsData)
22+
);
23+
const mergerMods = useSelector(mergerModsSelector);
24+
1925
const [useEnabledModsOnly, setUseEnabledModsOnly] = React.useState(true);
26+
const [isHidingAlreadyMergedMods, setIsHidingAlreadyMergedMods] = React.useState(true);
2027
const [isOpen, setIsOpen] = React.useState(false);
2128
const [modsToMerge, setModsToMerge] = React.useState<Set<Mod>>(new Set<Mod>());
2229
const [isSpinnerClosed, setIsSpinnerClosed] = React.useState(false);
2330
const [modsMergeSort, setModsMergeSort] = React.useState("Size" as ModsMergeSorts);
2431

2532
let modsToUse = [...mods];
33+
34+
if (isHidingAlreadyMergedMods) {
35+
modsToUse = modsToUse.filter((mod) =>
36+
mergerMods.every((mergerMod) =>
37+
mergerMod.mergedModsData?.every((mergedModData) => mergedModData.name != mod.name)
38+
)
39+
);
40+
}
41+
2642
switch (modsMergeSort) {
2743
case "Merge":
2844
modsToUse = modsToUse.sort((firstMod, secondMod) => {
@@ -72,23 +88,51 @@ const ModsMerger = React.memo(() => {
7288
setModsToMerge(new Set<Mod>(modsToMerge));
7389
};
7490

75-
type OptionType = {
91+
type NumModsOptionType = {
7692
value: number;
7793
label: number;
7894
};
95+
type ExistingMergerOptionType = {
96+
value: string;
97+
label: string;
98+
};
7999

80-
const onReplaceChange = (newValue: SingleValue<OptionType>, actionMeta: ActionMeta<OptionType>) => {
100+
const onSelectNumModsChange = (
101+
newValue: SingleValue<NumModsOptionType>,
102+
actionMeta: ActionMeta<NumModsOptionType>
103+
) => {
81104
if (!newValue) return;
82105
console.log(`label: ${newValue.label}, value: ${newValue.value}, action: ${actionMeta.action}`);
83106
if (actionMeta.action === "select-option") {
84107
setModsToMerge(new Set<Mod>(modsToUse.slice(0, newValue.value)));
85108
}
86109
};
110+
const onSelectExistingMergerChange = (
111+
newValue: SingleValue<ExistingMergerOptionType>,
112+
actionMeta: ActionMeta<ExistingMergerOptionType>
113+
) => {
114+
if (!newValue) return;
115+
console.log(`label: ${newValue.label}, value: ${newValue.value}, action: ${actionMeta.action}`);
116+
if (actionMeta.action === "select-option") {
117+
const mergerMod = mergerMods.find((mergerMod) => mergerMod.name == newValue.value);
118+
if (!mergerMod || !mergerMod.mergedModsData) return;
119+
const mergedData = mergerMod.mergedModsData;
120+
setModsToMerge(
121+
new Set<Mod>(
122+
modsToUse.filter((mod) => mergedData.some((mergedModData) => mergedModData.name == mod.name))
123+
)
124+
);
125+
}
126+
};
87127

88-
const options: OptionType[] = [5, 10, 15, 20, 25, 30, 35, 40, 50, 75, 100, 0].map((num) => {
128+
const options: NumModsOptionType[] = [5, 10, 15, 20, 25, 30, 35, 40, 50, 75, 100, 0].map((num) => {
89129
return { value: num, label: num };
90130
});
91131

132+
const mergerOptions: ExistingMergerOptionType[] = mergerMods.map((mod) => {
133+
return { value: mod.name, label: mod.name };
134+
});
135+
92136
const mergeMods = () => {
93137
if (modsToMerge.size < 1) return;
94138
window.api?.mergeMods(Array.from(modsToMerge));
@@ -112,6 +156,10 @@ const ModsMerger = React.memo(() => {
112156
else setModsMergeSort("Pack");
113157
};
114158

159+
const onMergeRightClick = () => {
160+
setModsToMerge(new Set<Mod>());
161+
};
162+
115163
return (
116164
<div>
117165
<div className="text-center mt-4">
@@ -136,31 +184,68 @@ const ModsMerger = React.memo(() => {
136184
..."scrollbar scrollbar-track-gray-700 scrollbar-thumb-blue-700".split(" "),
137185
]}
138186
>
139-
<Modal.Header>Merge Mods</Modal.Header>
187+
<Modal.Header>Merge Mods{modsToMerge.size > 0 && ` - ${modsToMerge.size} selected`}</Modal.Header>
140188
<Modal.Body>
141189
<Tabs.Group style="underline">
142190
<Tabs.Item active={true} title="Merge">
143191
<span className="absolute top-[6rem] right-0 flex items-center leading-relaxed dark:text-gray-300">
144-
<span className="mr-10">
192+
{mergerMods.length > 0 && (
193+
<>
194+
<span className="make-tooltip-inline">
195+
<Tooltip style={"light"} content={<p>Load mods that are in an existing merged mod.</p>}>
196+
<span className="text-center w-full">Load existing:</span>
197+
</Tooltip>
198+
</span>
199+
<Select
200+
options={mergerOptions}
201+
styles={selectStyle}
202+
onChange={onSelectExistingMergerChange}
203+
value={null}
204+
className="mx-2"
205+
></Select>
206+
</>
207+
)}
208+
209+
<span className="border-l-2 px-2 border-gray-600">
210+
<input
211+
type="checkbox"
212+
id="merge-hide-already-merged"
213+
checked={isHidingAlreadyMergedMods}
214+
onChange={() => {
215+
setIsHidingAlreadyMergedMods(!isHidingAlreadyMergedMods);
216+
}}
217+
></input>
218+
<label className="ml-2" htmlFor="merge-hide-already-merged">
219+
<span className="make-tooltip-inline">
220+
<Tooltip
221+
style={"light"}
222+
content={<p>Don't show a mod if it's inside an enabled merged pack.</p>}
223+
>
224+
<span className="text-center w-full">Hide Already Merged</span>
225+
</Tooltip>
226+
</span>
227+
</label>
228+
</span>
229+
230+
<span className="border-x-2 px-2 border-gray-600">
145231
<input
146232
type="checkbox"
147-
id="compat-enabled-mod-only"
233+
id="merge-enabled-mod-only"
148234
checked={useEnabledModsOnly}
149235
onChange={() => {
150236
if (!useEnabledModsOnly) setModsToMerge(new Set<Mod>());
151237
setUseEnabledModsOnly(!useEnabledModsOnly);
152238
}}
153239
></input>
154-
<label className="ml-2" htmlFor="compat-enabled-mod-only">
240+
<label className="ml-2" htmlFor="merge-enabled-mod-only">
155241
Enabled Mods Only
156242
</label>
157243
</span>
158-
<span>Select first</span>
244+
<span className="ml-2">Select first</span>
159245
<Select
160-
id="replacePreset"
161246
options={options}
162247
styles={selectStyle}
163-
onChange={onReplaceChange}
248+
onChange={onSelectNumModsChange}
164249
value={null}
165250
className="mx-2"
166251
></Select>
@@ -176,6 +261,7 @@ const ModsMerger = React.memo(() => {
176261
<div className="leading-relaxed dark:text-gray-300 relative gap-2 ">
177262
<div className="grid grid-cols-9">
178263
<div
264+
onContextMenu={() => onMergeRightClick()}
179265
className={
180266
"col-span-1 justify-center flex " +
181267
(((modsMergeSort == "Merge" || modsMergeSort == "MergeDesc") && "font-bold") || "")

0 commit comments

Comments
 (0)