Show imperial units for height and weight (#3097)

* Show imperial units for height and weight
* Fix migration note index
This commit is contained in:
WithoutPants
2022-11-09 11:10:57 +11:00
committed by GitHub
parent 30a7482ddf
commit 3bc0de3f3a
9 changed files with 141 additions and 19 deletions

View File

@@ -4,6 +4,7 @@ import { TagLink } from "src/components/Shared";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
import { TextUtils, getStashboxBase, getCountryByISO } from "src/utils"; import { TextUtils, getStashboxBase, getCountryByISO } from "src/utils";
import { TextField, URLField } from "src/utils/field"; import { TextField, URLField } from "src/utils/field";
import { cmToImperial, kgToLbs } from "src/utils/units";
interface IPerformerDetails { interface IPerformerDetails {
performer: GQL.PerformerDataFragment; performer: GQL.PerformerDataFragment;
@@ -75,22 +76,59 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
if (!height) { if (!height) {
return ""; return "";
} }
return intl.formatNumber(height, {
style: "unit", const [feet, inches] = cmToImperial(height);
unit: "centimeter",
unitDisplay: "narrow", return (
}); <span className="performer-height">
<span className="height-metric">
{intl.formatNumber(height, {
style: "unit",
unit: "centimeter",
unitDisplay: "short",
})}
</span>
<span className="height-imperial">
{intl.formatNumber(feet, {
style: "unit",
unit: "foot",
unitDisplay: "narrow",
})}
{intl.formatNumber(inches, {
style: "unit",
unit: "inch",
unitDisplay: "narrow",
})}
</span>
</span>
);
}; };
const formatWeight = (weight?: number | null) => { const formatWeight = (weight?: number | null) => {
if (!weight) { if (!weight) {
return ""; return "";
} }
return intl.formatNumber(weight, {
style: "unit", const lbs = kgToLbs(weight);
unit: "kilogram",
unitDisplay: "narrow", return (
}); <span className="performer-weight">
<span className="weight-metric">
{intl.formatNumber(weight, {
style: "unit",
unit: "kilogram",
unitDisplay: "short",
})}
</span>
<span className="weight-imperial">
{intl.formatNumber(lbs, {
style: "unit",
unit: "pound",
unitDisplay: "short",
})}
</span>
</span>
);
}; };
return ( return (
@@ -120,8 +158,25 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
getCountryByISO(performer.country, intl.locale) ?? performer.country getCountryByISO(performer.country, intl.locale) ?? performer.country
} }
/> />
<TextField id="height" value={formatHeight(performer.height_cm)} />
<TextField id="weight" value={formatWeight(performer.weight)} /> {!!performer.height_cm && (
<>
<dt>
<FormattedMessage id="height" />
</dt>
<dd>{formatHeight(performer.height_cm)}</dd>
</>
)}
{!!performer.weight && (
<>
<dt>
<FormattedMessage id="weight" />
</dt>
<dd>{formatWeight(performer.weight)}</dd>
</>
)}
<TextField id="measurements" value={performer.measurements} /> <TextField id="measurements" value={performer.measurements} />
<TextField id="fake_tits" value={performer.fake_tits} /> <TextField id="fake_tits" value={performer.fake_tits} />
<TextField id="career_length" value={performer.career_length} /> <TextField id="career_length" value={performer.career_length} />

View File

@@ -909,12 +909,10 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
{renderField("eye_color")} {renderField("eye_color")}
{renderField("height_cm", { {renderField("height_cm", {
type: "number", type: "number",
messageID: "height",
placeholder: intl.formatMessage({ id: "height_cm" }),
})} })}
{renderField("weight", { {renderField("weight", {
type: "number", type: "number",
placeholder: intl.formatMessage({ id: "weight_kg" }), messageID: "weight_kg",
})} })}
{renderField("measurements")} {renderField("measurements")}
{renderField("fake_tits")} {renderField("fake_tits")}

View File

@@ -8,6 +8,7 @@ import * as GQL from "src/core/generated-graphql";
import { Icon } from "src/components/Shared"; import { Icon } from "src/components/Shared";
import { NavUtils } from "src/utils"; import { NavUtils } from "src/utils";
import { faHeart } from "@fortawesome/free-solid-svg-icons"; import { faHeart } from "@fortawesome/free-solid-svg-icons";
import { cmToImperial } from "src/utils/units";
interface IPerformerListTableProps { interface IPerformerListTableProps {
performers: GQL.PerformerDataFragment[]; performers: GQL.PerformerDataFragment[];
@@ -18,6 +19,38 @@ export const PerformerListTable: React.FC<IPerformerListTableProps> = (
) => { ) => {
const intl = useIntl(); const intl = useIntl();
const formatHeight = (height?: number | null) => {
if (!height) {
return "";
}
const [feet, inches] = cmToImperial(height);
return (
<span className="performer-height">
<span className="height-metric">
{intl.formatNumber(height, {
style: "unit",
unit: "centimeter",
unitDisplay: "short",
})}
</span>
<span className="height-imperial">
{intl.formatNumber(feet, {
style: "unit",
unit: "foot",
unitDisplay: "narrow",
})}
{intl.formatNumber(inches, {
style: "unit",
unit: "inch",
unitDisplay: "narrow",
})}
</span>
</span>
);
};
const renderPerformerRow = (performer: GQL.PerformerDataFragment) => ( const renderPerformerRow = (performer: GQL.PerformerDataFragment) => (
<tr key={performer.id}> <tr key={performer.id}>
<td> <td>
@@ -58,7 +91,7 @@ export const PerformerListTable: React.FC<IPerformerListTableProps> = (
</Link> </Link>
</td> </td>
<td>{performer.birthdate}</td> <td>{performer.birthdate}</td>
<td>{performer.height_cm}</td> <td>{!!performer.height_cm && formatHeight(performer.height_cm)}</td>
</tr> </tr>
); );

View File

@@ -146,3 +146,27 @@
.fa-transgender-alt { .fa-transgender-alt {
color: #c8a2c8; color: #c8a2c8;
} }
.performer-height {
.height-imperial {
&::before {
content: " (";
}
&::after {
content: ")";
}
}
}
.performer-weight {
.weight-imperial {
&::before {
content: " (";
}
&::after {
content: ")";
}
}
}

View File

@@ -4,6 +4,7 @@
* Added tag description filter criterion. ([#3011](https://github.com/stashapp/stash/pull/3011)) * Added tag description filter criterion. ([#3011](https://github.com/stashapp/stash/pull/3011))
### 🎨 Improvements ### 🎨 Improvements
* Also show imperial units for performer height and weight. ([#3097](https://github.com/stashapp/stash/pull/3097))
* Limit number of items in selector drop-downs to 200. ([#3062](https://github.com/stashapp/stash/pull/3062)) * Limit number of items in selector drop-downs to 200. ([#3062](https://github.com/stashapp/stash/pull/3062))
* Changed Performer height to be numeric, and changed filtering accordingly. ([#3060](https://github.com/stashapp/stash/pull/3060)) * Changed Performer height to be numeric, and changed filtering accordingly. ([#3060](https://github.com/stashapp/stash/pull/3060))

View File

@@ -1 +0,0 @@
This migration changes performer height values from strings to numbers. Non-numeric performer height values **will be erased during this migration**.

View File

@@ -0,0 +1 @@
This migration changes performer height values from strings to numbers. The migration converts the _first number in the string_ to an integer value. Height values that cannot be converted this way **will be erased during this migration**.

View File

@@ -1,9 +1,9 @@
import migration32 from "./32.md"; import migration32 from "./32.md";
import migration38 from "./38.md"; import migration39 from "./39.md";
type Module = typeof migration32; type Module = typeof migration32;
export const migrationNotes: Record<number, Module> = { export const migrationNotes: Record<number, Module> = {
32: migration32, 32: migration32,
38: migration38, 39: migration39,
}; };

View File

@@ -0,0 +1,11 @@
export function cmToImperial(cm: number) {
const cmInInches = 0.393700787;
const inchesInFeet = 12;
const inches = Math.floor(cm * cmInInches);
const feet = Math.floor(inches / inchesInFeet);
return [feet, inches % inchesInFeet];
}
export function kgToLbs(kg: number) {
return Math.floor(kg * 2.20462262185);
}