@@ -14,7 +14,7 @@ Three transforms do the work, all of them toggleable in the UI:
|
||||
|
||||
| Transform | What it does |
|
||||
| --- | --- |
|
||||
| **Merge duplicates** | Mutually exclusive wargear forces you to take a datasheet twice - one Skatros with a radium jezzail, another with a transuranic arquebus. Copies of the same unit are folded into one card carrying every option. Points are not summed; the card keeps the highest cost of the copies it absorbed. |
|
||||
| **Merge duplicates** | Mutually exclusive wargear forces you to take a datasheet twice - one Skatros with a radium jezzail, another with a transuranic arquebus. Copies of the same unit are folded into one card carrying every option. |
|
||||
| **Drop Leader/Support** | Removes the attachment rules. Once the army is built they say nothing you need mid-game, and they are long enough to push the rules you *do* need off the card. |
|
||||
| **Split choice abilities** | An ability like *Canticles of the Omnissiah* arrives as one blob of text. This splits it into the intro rule plus one titled row per option, which is how the datasheets print it. |
|
||||
|
||||
@@ -142,6 +142,21 @@ git merge upstream/main
|
||||
Conflicts should be confined to `src/App.jsx`, `index.html`, `vite.config.js` and
|
||||
`package.json`. `src/transforms/` is entirely new and will never conflict.
|
||||
|
||||
The fork also hides three things upstream shows, because a generic datasheet has
|
||||
nothing to say with them: the roster overview card and its charts, the unit
|
||||
composition, and the per-unit points cost. Those decisions live in
|
||||
[`src/fork.js`](src/fork.js) - another file upstream does not have - and
|
||||
`src/10th/Roster.jsx` reaches for them on as few lines as possible:
|
||||
|
||||
- it imports `ShortSummaryTable` from `../fork` instead of `./ShortSummaryTable`,
|
||||
a one-line change that leaves the render site untouched. The upstream
|
||||
component is still in the tree, unused, so its future diffs keep applying.
|
||||
- `hideModelCount` is pinned to `HIDE_UNIT_COMPOSITION` instead of being a piece
|
||||
of checkbox state.
|
||||
|
||||
Only the two checkboxes and the `pts` span are deleted outright, so a merge that
|
||||
touches them will say so rather than quietly bringing them back.
|
||||
|
||||
## Credit
|
||||
|
||||
All the hard parts - the parsing, the card layout, the print CSS - are
|
||||
|
||||
+2
-22
@@ -20,7 +20,7 @@ import { Weapons, hasDifferentProfiles } from "./Weapons";
|
||||
import { useIndexedDB } from "../helpers/useIndexedDB"; // New hook for IndexedDB
|
||||
import { ImgEditor } from "./ImgEditor";
|
||||
import { trySettingLocalStorage } from "../helpers/useLocalStorage";
|
||||
import { ShortSummaryTable } from "./ShortSummaryTable";
|
||||
import { HIDE_UNIT_COMPOSITION, ShortSummaryTable } from "../fork";
|
||||
|
||||
const getShortSummarySubtitle = (force) => {
|
||||
const details = [];
|
||||
@@ -183,7 +183,7 @@ const Force = ({ force, onePerPage, colorUserChoice }) => {
|
||||
|
||||
const Unit = ({ unit, catalog, onePerPage, forceRules, colorUserChoice }) => {
|
||||
const [hide, setHide] = useState(false);
|
||||
const [hideModelCount, setHideModelCount] = useState(false);
|
||||
const hideModelCount = HIDE_UNIT_COMPOSITION;
|
||||
const uploadRef = useRef();
|
||||
let {
|
||||
name,
|
||||
@@ -315,23 +315,6 @@ const Unit = ({ unit, catalog, onePerPage, forceRules, colorUserChoice }) => {
|
||||
}}
|
||||
>
|
||||
<div className="flex justify-end gap-3 pb-0.5">
|
||||
<label
|
||||
className="print-display-none"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
gap: 4,
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<input
|
||||
className="hide-model-selection"
|
||||
type="checkbox"
|
||||
onChange={(e) => setHideModelCount(e.target.checked)}
|
||||
/>
|
||||
<span className="print-display-none">Hide Unit Composition</span>
|
||||
</label>
|
||||
<label
|
||||
className="print-display-none"
|
||||
style={{
|
||||
@@ -424,9 +407,6 @@ const Unit = ({ unit, catalog, onePerPage, forceRules, colorUserChoice }) => {
|
||||
}}
|
||||
>
|
||||
{name}
|
||||
<span style={{ textTransform: "initial", fontSize: "1.2rem" }}>
|
||||
{cost.points}pts
|
||||
</span>
|
||||
</div>
|
||||
<div className="relative flex gap-4">
|
||||
<div
|
||||
|
||||
-36
@@ -86,24 +86,12 @@ function App() {
|
||||
const [onePerPage, setOnePerPage] = useState(false);
|
||||
const [primaryColor, setPrimaryColor] = useState("#536766");
|
||||
const [colorUserChoice, setColorUserChoice] = useState(false);
|
||||
const [hideModelSelections, setHideModelSelections] = useState(false);
|
||||
const uploadRef = useRef();
|
||||
|
||||
const throttledSetPrimaryColor = useRef(
|
||||
throttle((color) => setPrimaryColor(color), 50),
|
||||
).current;
|
||||
|
||||
const toggleHideModelSelections = (hide) => {
|
||||
const checkboxes = document.querySelectorAll(
|
||||
'input[type="checkbox"].hide-model-selection',
|
||||
);
|
||||
checkboxes.forEach((checkbox) => {
|
||||
if (checkbox.checked !== hide) {
|
||||
checkbox.click();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
async function handleFileSelect(event) {
|
||||
const files = event?.target?.files;
|
||||
|
||||
@@ -431,30 +419,6 @@ function App() {
|
||||
One Datacard per Page when Printing
|
||||
</span>
|
||||
</label>
|
||||
{
|
||||
// only show when 10th or 11th edition
|
||||
(edition === 10 || edition === 11) && (
|
||||
<label
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
minHeight: 26,
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
value={hideModelSelections}
|
||||
onChange={(e) => {
|
||||
setHideModelSelections(e.target.checked);
|
||||
toggleHideModelSelections(e.target.checked);
|
||||
}}
|
||||
className="hide-model-selection"
|
||||
/>
|
||||
<span className="select-none">Hide all Unit Compositions</span>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
<div style={{ display: "flex", alignItems: "center", gap: 4 }}>
|
||||
<label style={{ display: "flex", alignItems: "center", gap: 4 }}>
|
||||
<input
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Fork-local display decisions.
|
||||
//
|
||||
// BrevyScribe prints the generic datasheet for a unit rather than a record of
|
||||
// one particular list, so a few of the things FancyScribe shows have nothing
|
||||
// left to say here. They are switched off from this file - which upstream does
|
||||
// not have, and which therefore can never conflict - so that the components
|
||||
// upstream owns are touched on as few lines as possible.
|
||||
|
||||
// The roster overview table summarises the list that was uploaded: its total
|
||||
// cost, a unit-by-unit breakdown and the charts drawn from them. None of that
|
||||
// survives the transforms, so the card is not rendered at all.
|
||||
//
|
||||
// 10th/Roster.jsx imports this in place of ./ShortSummaryTable, which leaves the
|
||||
// render site there byte-identical to upstream. ShortSummaryTable.jsx itself is
|
||||
// kept in the tree, unused, so upstream changes to it keep merging cleanly (Vite
|
||||
// tree-shakes it, and chart.js with it, out of the build).
|
||||
export const ShortSummaryTable = () => null;
|
||||
|
||||
// The unit composition lists the models this particular list took, which is the
|
||||
// list-specific detail the fork exists to strip - and after duplicate units are
|
||||
// merged into one card it is misleading as well. It is always hidden, and the
|
||||
// checkboxes that used to toggle it are gone.
|
||||
export const HIDE_UNIT_COMPOSITION = true;
|
||||
Reference in New Issue
Block a user