mirror of
https://github.com/stashapp/stash.git
synced 2025-12-25 17:53:23 +01:00
Add performer star ratings to main view (#1844)
* add performer star ratings to main view * remove ratings from details and edit tab. move ratings hotkeys from edit tab to main view
This commit is contained in:
parent
5ec70ac3e0
commit
cf43a825d8
4 changed files with 43 additions and 64 deletions
|
|
@ -4,6 +4,7 @@
|
|||
* Added interface options to disable creating performers/studios/tags from dropdown selectors. ([#1814](https://github.com/stashapp/stash/pull/1814))
|
||||
|
||||
### 🎨 Improvements
|
||||
* Moved Performer rating stars from details/edit tabs to heading section of performer page. ([#1844](https://github.com/stashapp/stash/pull/1844))
|
||||
* Optimised scanning process. ([#1816](https://github.com/stashapp/stash/pull/1816))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from "src/components/Shared";
|
||||
import { useLightbox, useToast } from "src/hooks";
|
||||
import { TextUtils } from "src/utils";
|
||||
import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars";
|
||||
import { PerformerDetailsPanel } from "./PerformerDetailsPanel";
|
||||
import { PerformerOperationsPanel } from "./PerformerOperationsPanel";
|
||||
import { PerformerScenesPanel } from "./PerformerScenesPanel";
|
||||
|
|
@ -97,6 +98,30 @@ export const Performer: React.FC = () => {
|
|||
Mousetrap.bind("o", () => setActiveTabKey("operations"));
|
||||
Mousetrap.bind("f", () => setFavorite(!performer.favorite));
|
||||
|
||||
// numeric keypresses get caught by jwplayer, so blur the element
|
||||
// if the rating sequence is started
|
||||
Mousetrap.bind("r", () => {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
Mousetrap.bind("0", () => setRating(NaN));
|
||||
Mousetrap.bind("1", () => setRating(1));
|
||||
Mousetrap.bind("2", () => setRating(2));
|
||||
Mousetrap.bind("3", () => setRating(3));
|
||||
Mousetrap.bind("4", () => setRating(4));
|
||||
Mousetrap.bind("5", () => setRating(5));
|
||||
|
||||
setTimeout(() => {
|
||||
Mousetrap.unbind("0");
|
||||
Mousetrap.unbind("1");
|
||||
Mousetrap.unbind("2");
|
||||
Mousetrap.unbind("3");
|
||||
Mousetrap.unbind("4");
|
||||
Mousetrap.unbind("5");
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
return () => {
|
||||
Mousetrap.unbind("a");
|
||||
Mousetrap.unbind("e");
|
||||
|
|
@ -209,6 +234,19 @@ export const Performer: React.FC = () => {
|
|||
}
|
||||
}
|
||||
|
||||
function setRating(v: number | null) {
|
||||
if (performer.id) {
|
||||
updatePerformer({
|
||||
variables: {
|
||||
input: {
|
||||
id: performer.id,
|
||||
rating: v,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const renderIcons = () => (
|
||||
<span className="name-icons">
|
||||
<Button
|
||||
|
|
@ -317,6 +355,10 @@ export const Performer: React.FC = () => {
|
|||
{performer.name}
|
||||
{renderIcons()}
|
||||
</h2>
|
||||
<RatingStars
|
||||
value={performer.rating ?? undefined}
|
||||
onSetRating={(value) => setRating(value ?? null)}
|
||||
/>
|
||||
{maybeRenderAliases()}
|
||||
{maybeRenderAge()}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { TagLink } from "src/components/Shared";
|
|||
import * as GQL from "src/core/generated-graphql";
|
||||
import { TextUtils } from "src/utils";
|
||||
import { TextField, URLField } from "src/utils/field";
|
||||
import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars";
|
||||
import { genderToString } from "src/utils/gender";
|
||||
|
||||
interface IPerformerDetails {
|
||||
|
|
@ -38,23 +37,6 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
|||
);
|
||||
}
|
||||
|
||||
function renderRating() {
|
||||
if (!performer.rating) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<dt>
|
||||
<FormattedMessage id="rating" />:
|
||||
</dt>
|
||||
<dd>
|
||||
<RatingStars value={performer.rating} />
|
||||
</dd>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function renderStashIDs() {
|
||||
if (!performer.stash_ids?.length) {
|
||||
return;
|
||||
|
|
@ -159,7 +141,6 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
|||
TextUtils.instagramURL
|
||||
)}
|
||||
/>
|
||||
{renderRating()}
|
||||
{renderTagsField()}
|
||||
{renderStashIDs()}
|
||||
</dl>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import { getCountryByISO } from "src/utils/country";
|
|||
import { useToast } from "src/hooks";
|
||||
import { Prompt, useHistory } from "react-router-dom";
|
||||
import { useFormik } from "formik";
|
||||
import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars";
|
||||
import {
|
||||
genderStrings,
|
||||
genderToString,
|
||||
|
|
@ -121,7 +120,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
tag_ids: yup.array(yup.string().required()).optional(),
|
||||
stash_ids: yup.mixed<GQL.StashIdInput>().optional(),
|
||||
image: yup.string().optional().nullable(),
|
||||
rating: yup.number().optional().nullable(),
|
||||
details: yup.string().optional(),
|
||||
death_date: yup.string().optional(),
|
||||
hair_color: yup.string().optional(),
|
||||
|
|
@ -148,7 +146,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
tag_ids: (performer.tags ?? []).map((t) => t.id),
|
||||
stash_ids: performer.stash_ids ?? undefined,
|
||||
image: undefined,
|
||||
rating: performer.rating ?? null,
|
||||
details: performer.details ?? "",
|
||||
death_date: performer.death_date ?? "",
|
||||
hair_color: performer.hair_color ?? "",
|
||||
|
|
@ -163,10 +160,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
onSubmit: (values) => onSave(values),
|
||||
});
|
||||
|
||||
function setRating(v: number) {
|
||||
formik.setFieldValue("rating", v);
|
||||
}
|
||||
|
||||
function translateScrapedGender(scrapedGender?: string) {
|
||||
if (!scrapedGender) {
|
||||
return;
|
||||
|
|
@ -416,30 +409,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
});
|
||||
}
|
||||
|
||||
// numeric keypresses get caught by jwplayer, so blur the element
|
||||
// if the rating sequence is started
|
||||
Mousetrap.bind("r", () => {
|
||||
if (document.activeElement instanceof HTMLElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
Mousetrap.bind("0", () => setRating(NaN));
|
||||
Mousetrap.bind("1", () => setRating(1));
|
||||
Mousetrap.bind("2", () => setRating(2));
|
||||
Mousetrap.bind("3", () => setRating(3));
|
||||
Mousetrap.bind("4", () => setRating(4));
|
||||
Mousetrap.bind("5", () => setRating(5));
|
||||
|
||||
setTimeout(() => {
|
||||
Mousetrap.unbind("0");
|
||||
Mousetrap.unbind("1");
|
||||
Mousetrap.unbind("2");
|
||||
Mousetrap.unbind("3");
|
||||
Mousetrap.unbind("4");
|
||||
Mousetrap.unbind("5");
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
return () => {
|
||||
Mousetrap.unbind("s s");
|
||||
|
||||
|
|
@ -478,7 +447,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
return {
|
||||
...values,
|
||||
gender: stringToGender(values.gender) ?? null,
|
||||
rating: values.rating ?? null,
|
||||
weight: Number(values.weight),
|
||||
id: performer.id ?? "",
|
||||
};
|
||||
|
|
@ -1022,19 +990,6 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
</Form.Group>
|
||||
{renderTagsField()}
|
||||
|
||||
<Form.Group controlId="rating" as={Row}>
|
||||
<Form.Label column xs={labelXS} xl={labelXL}>
|
||||
<FormattedMessage id="rating" />
|
||||
</Form.Label>
|
||||
<Col xs={fieldXS} xl={fieldXL}>
|
||||
<RatingStars
|
||||
value={formik.values.rating ?? undefined}
|
||||
onSetRating={(value) =>
|
||||
formik.setFieldValue("rating", value ?? null)
|
||||
}
|
||||
/>
|
||||
</Col>
|
||||
</Form.Group>
|
||||
{renderStashIDs()}
|
||||
|
||||
{renderButtons()}
|
||||
|
|
|
|||
Loading…
Reference in a new issue