mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Show imperial units for height and weight (#3097)
* Show imperial units for height and weight * Fix migration note index
This commit is contained in:
@@ -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} />
|
||||||
|
|||||||
@@ -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")}
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -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: ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
This migration changes performer height values from strings to numbers. Non-numeric performer height values **will be erased during this migration**.
|
|
||||||
1
ui/v2.5/src/docs/en/MigrationNotes/39.md
Normal file
1
ui/v2.5/src/docs/en/MigrationNotes/39.md
Normal 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**.
|
||||||
@@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
11
ui/v2.5/src/utils/units.ts
Normal file
11
ui/v2.5/src/utils/units.ts
Normal 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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user