Update prettier to v2.0.1 and enable for SCSS (#420)

This commit is contained in:
InfiniteTF
2020-04-03 01:29:33 +02:00
committed by GitHub
parent ad7bfb8dbf
commit 66cb7f4928
98 changed files with 1365 additions and 1299 deletions

View File

@@ -21,6 +21,16 @@
"warn",
{ "prefixWithI": "always" }
],
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
],
"import/named": "off",
"import/namespace": "off",
"import/default": "off",

View File

@@ -2,6 +2,7 @@
"plugins": [
"stylelint-order"
],
"extends": "stylelint-config-prettier",
"rules": {
"indentation": 2,
"at-rule-empty-line-before": [ "always", {
@@ -33,7 +34,6 @@
"declaration-block-semicolon-space-before": "never",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-trailing-semicolon": "always",
"declaration-colon-newline-after": "always-multi-line",
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"declaration-no-important": true,
@@ -61,7 +61,6 @@
"no-descending-specificity": null,
"no-invalid-double-slash-comments": true,
"no-missing-end-of-source-newline": true,
"number-leading-zero": "never",
"number-max-precision": 2,
"number-no-trailing-zeros": true,
"order/order": [
@@ -87,7 +86,6 @@
"string-quotes": "double",
"time-min-milliseconds": 100,
"unit-blacklist": ["em"],
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
"value-no-vendor-prefix": true

View File

@@ -11,7 +11,7 @@
"lint": "yarn lint:css && yarn lint:js",
"lint:js": "eslint --cache src/**/*.{ts,tsx}",
"lint:css": "stylelint 'src/**/*.scss'",
"format": "prettier --write \"src/**/!(generated-graphql).{js,jsx,ts,tsx}\"",
"format": "prettier --write \"src/**/!(generated-graphql).{js,jsx,ts,tsx,scss}\"",
"gqlgen": "gql-gen --config codegen.yml",
"extract": "NODE_ENV=development extract-messages -l=en,de -o src/locale -d en --flat false 'src/**/!(*.test).tsx'"
},
@@ -80,7 +80,7 @@
"@typescript-eslint/parser": "^2.16.0",
"eslint": "^6.7.2",
"eslint-config-airbnb-typescript": "^6.3.1",
"eslint-config-prettier": "^6.9.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-import": "^2.20.0",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.18.0",
@@ -88,9 +88,10 @@
"extract-react-intl-messages": "^2.3.5",
"node-sass": "4.13.1",
"postcss-safe-parser": "^4.0.1",
"prettier": "1.19.1",
"prettier": "2.0.2",
"react-scripts": "^3.3.1",
"stylelint": "^13.0.0",
"stylelint-config-prettier": "^8.0.1",
"stylelint-order": "^4.0.0",
"typescript": "^3.7.5"
}

View File

@@ -25,7 +25,7 @@ export class ErrorBoundary extends React.Component<
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
this.setState({
error,
errorInfo
errorInfo,
});
}

View File

@@ -8,7 +8,7 @@ import { DisplayMode } from "src/models/list-filter/types";
export const GalleryList: React.FC = () => {
const listData = useGalleriesList({
renderContent
renderContent,
});
function renderContent(
@@ -31,7 +31,7 @@ export const GalleryList: React.FC = () => {
</tr>
</thead>
<tbody>
{result.data.findGalleries.galleries.map(gallery => (
{result.data.findGalleries.galleries.map((gallery) => (
<tr key={gallery.id}>
<td>
<Link to={`/galleries/${gallery.id}`}>
@@ -41,9 +41,7 @@ export const GalleryList: React.FC = () => {
className="w-100 w-sm-auto"
src={`${gallery.files[0].path}?thumb=true`}
/>
) : (
undefined
)}
) : undefined}
</Link>
</td>
<td className="d-none d-sm-block">

View File

@@ -29,14 +29,14 @@ export const GalleryViewer: FunctionComponent<IProps> = ({ gallery }) => {
setCurrentImage(currentImage + 1);
}
const photos = gallery.files.map(file => ({
const photos = gallery.files.map((file) => ({
src: file.path ?? "",
caption: file.name ?? ""
caption: file.name ?? "",
}));
const thumbs = gallery.files.map(file => ({
const thumbs = gallery.files.map((file) => ({
src: `${file.path}?thumb=true` || "",
width: 1,
height: 1
height: 1,
}));
return (

View File

@@ -7,7 +7,7 @@ import {
Criterion,
CriterionType,
DurationCriterion,
CriterionValue
CriterionValue,
} from "src/models/list-filter/criteria/criterion";
import { NoneCriterion } from "src/models/list-filter/criteria/none";
import { makeCriteria } from "src/models/list-filter/criteria/utils";
@@ -118,7 +118,7 @@ export const AddFilter: React.FC<IAddFilterProps> = (
onChange={onChangedModifierSelect}
value={criterion.modifier}
>
{criterion.modifierOptions.map(c => (
{criterion.modifierOptions.map((c) => (
<option key={c.value} value={c.value}>
{c.label}
</option>
@@ -149,15 +149,15 @@ export const AddFilter: React.FC<IAddFilterProps> = (
<FilterSelect
type={criterion.type}
isMulti
onSelect={items => {
onSelect={(items) => {
const newCriterion = _.cloneDeep(criterion);
newCriterion.value = items.map(i => ({
newCriterion.value = items.map((i) => ({
id: i.id,
label: i.name!
label: i.name!,
}));
setCriterion(newCriterion);
}}
ids={criterion.value.map(labeled => labeled.id)}
ids={criterion.value.map((labeled) => labeled.id)}
/>
);
}
@@ -169,7 +169,7 @@ export const AddFilter: React.FC<IAddFilterProps> = (
onChange={onChangedSingleSelect}
value={criterion.value.toString()}
>
{criterion.options.map(c => (
{criterion.options.map((c) => (
<option key={c.toString()} value={c.toString()}>
{c}
</option>
@@ -215,7 +215,7 @@ export const AddFilter: React.FC<IAddFilterProps> = (
onChange={onChangedCriteriaType}
value={criterion.type}
>
{props.filter.criterionOptions.map(c => (
{props.filter.criterionOptions.map((c) => (
<option key={c.value} value={c.value}>
{c.label}
</option>

View File

@@ -9,7 +9,7 @@ import {
Form,
OverlayTrigger,
Tooltip,
SafeAnchor
SafeAnchor,
} from "react-bootstrap";
import { Icon } from "src/components/Shared";
@@ -106,7 +106,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
}
function renderSortByOptions() {
return props.filter.sortByOptions.map(option => (
return props.filter.sortByOptions.map((option) => (
<Dropdown.Item
onClick={onChangeSortBy}
key={option}
@@ -138,7 +138,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
return "Wall";
}
}
return props.filter.displayModeOptions.map(option => (
return props.filter.displayModeOptions.map((option) => (
<OverlayTrigger
key={option}
overlay={
@@ -157,7 +157,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
}
function renderFilterTags() {
return props.filter.criteria.map(criterion => (
return props.filter.criteria.map((criterion) => (
<Badge
className="tag-item"
variant="secondary"
@@ -219,7 +219,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
const options = [renderSelectAll(), renderSelectNone()];
if (props.otherOperations) {
props.otherOperations.forEach(o => {
props.otherOperations.forEach((o) => {
options.push(
<Dropdown.Item
key={o.text}
@@ -285,7 +285,7 @@ export const ListFilter: React.FC<IListFilterProps> = (
value={props.filter.itemsPerPage.toString()}
className="btn-secondary filter-item col-1 d-none d-sm-inline"
>
{PAGE_SIZE_OPTIONS.map(s => (
{PAGE_SIZE_OPTIONS.map((s) => (
<option value={s} key={s}>
{s}
</option>

View File

@@ -12,7 +12,7 @@ export const Pagination: React.FC<IPaginationProps> = ({
itemsPerPage,
currentPage,
totalItems,
onChangePage
onChangePage,
}) => {
const totalPages = Math.ceil(totalItems / itemsPerPage);
@@ -34,7 +34,7 @@ export const Pagination: React.FC<IPaginationProps> = ({
}
const pages = [...Array(endPage + 1 - startPage).keys()].map(
i => startPage + i
(i) => startPage + i
);
const calculatePageClass = (buttonPage: number) => {

View File

@@ -17,38 +17,38 @@ const menuItems: IMenuItem[] = [
{
icon: "play-circle",
messageID: "scenes",
href: "/scenes"
href: "/scenes",
},
{
href: "/movies",
icon: "film",
messageID: "movies"
messageID: "movies",
},
{
href: "/scenes/markers",
icon: "map-marker-alt",
messageID: "markers"
messageID: "markers",
},
{
href: "/galleries",
icon: "image",
messageID: "galleries"
messageID: "galleries",
},
{
href: "/performers",
icon: "user",
messageID: "performers"
messageID: "performers",
},
{
href: "/studios",
icon: "video",
messageID: "studios"
messageID: "studios",
},
{
href: "/tags",
icon: "tag",
messageID: "tags"
}
messageID: "tags",
},
];
export const MainNavbar: React.FC = () => {
@@ -127,7 +127,7 @@ export const MainNavbar: React.FC = () => {
<Navbar.Toggle className="order-0" />
<Navbar.Collapse className="order-3 order-md-1">
<Nav className="mr-md-auto">
{menuItems.map(i => (
{menuItems.map((i) => (
<Nav.Link eventKey={i.href} as="div" key={i.href}>
<LinkContainer
activeClassName="active"

View File

@@ -7,7 +7,7 @@ import cx from "classnames";
import {
DetailsEditNavbar,
LoadingIndicator,
Modal
Modal,
} from "src/components/Shared";
import { useToast } from "src/hooks";
import { Table, Form } from "react-bootstrap";
@@ -117,7 +117,7 @@ export const Movie: React.FC = () => {
synopsis,
url,
front_image: frontImage,
back_image: backImage
back_image: backImage,
};
if (!isNew) {
@@ -183,7 +183,7 @@ export const Movie: React.FC = () => {
<div className="row">
<div
className={cx("movie-details", "col", {
"col ml-sm-5": !isNew
"col ml-sm-5": !isNew,
})}
>
{isNew && <h2>Add Movie</h2>}
@@ -198,38 +198,38 @@ export const Movie: React.FC = () => {
title: "Name",
value: movie.name ?? "",
isEditing: !!isEditing,
onChange: setName
onChange: setName,
})}
{TableUtils.renderInputGroup({
title: "Aliases",
value: aliases,
isEditing,
onChange: setAliases
onChange: setAliases,
})}
{TableUtils.renderInputGroup({
title: "Duration",
value: duration,
isEditing,
onChange: setDuration
onChange: setDuration,
})}
{TableUtils.renderInputGroup({
title: "Date (YYYY-MM-DD)",
value: date,
isEditing,
onChange: setDate
onChange: setDate,
})}
{TableUtils.renderInputGroup({
title: "Director",
value: director,
isEditing,
onChange: setDirector
onChange: setDirector,
})}
{TableUtils.renderHtmlSelect({
title: "Rating",
value: rating,
isEditing,
onChange: (value: string) => setRating(value),
selectOptions: ["", "1", "2", "3", "4", "5"]
selectOptions: ["", "1", "2", "3", "4", "5"],
})}
</tbody>
</Table>

View File

@@ -12,7 +12,7 @@ export const MovieScenesPanel: React.FC<IMovieScenesPanel> = ({ movie }) => {
function filterHook(filter: ListFilterModel) {
const movieValue = { id: movie.id!, label: movie.name! };
// if movie is already present, then we modify it, otherwise add
let movieCriterion = filter.criteria.find(c => {
let movieCriterion = filter.criteria.find((c) => {
return c.type === "movies";
}) as MoviesCriterion;
@@ -23,7 +23,7 @@ export const MovieScenesPanel: React.FC<IMovieScenesPanel> = ({ movie }) => {
) {
// add the movie if not present
if (
!movieCriterion.value.find(p => {
!movieCriterion.value.find((p) => {
return p.id === movie.id;
})
) {

View File

@@ -7,7 +7,7 @@ import { MovieCard } from "./MovieCard";
export const MovieList: React.FC = () => {
const listData = useMoviesList({
renderContent
renderContent,
});
function renderContent(
@@ -20,7 +20,7 @@ export const MovieList: React.FC = () => {
if (filter.displayMode === DisplayMode.Grid) {
return (
<div className="row justify-content-center">
{result.data.findMovies.movies.map(p => (
{result.data.findMovies.movies.map((p) => (
<MovieCard key={p.id} movie={p} />
))}
</div>

View File

@@ -11,7 +11,7 @@ interface IPerformerCardProps {
export const PerformerCard: React.FC<IPerformerCardProps> = ({
performer,
ageFromDate
ageFromDate,
}) => {
const age = TextUtils.age(performer.birthdate, ageFromDate);
const ageString = `${age} years old${ageFromDate ? " in this scene." : "."}`;

View File

@@ -62,13 +62,13 @@ export const Performer: React.FC = () => {
try {
if (!isNew) {
const result = await updatePerformer({
variables: performerInput as GQL.PerformerUpdateInput
variables: performerInput as GQL.PerformerUpdateInput,
});
if (result.data?.performerUpdate)
setPerformer(result.data?.performerUpdate);
} else {
const result = await createPerformer({
variables: performerInput as GQL.PerformerCreateInput
variables: performerInput as GQL.PerformerCreateInput,
});
if (result.data?.performerCreate) {
setPerformer(result.data.performerCreate);

View File

@@ -9,7 +9,7 @@ import {
Modal,
ImageInput,
ScrapePerformerSuggest,
LoadingIndicator
LoadingIndicator,
} from "src/components/Shared";
import { ImageUtils, TableUtils } from "src/utils";
import { useToast } from "src/hooks";
@@ -33,7 +33,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
isEditing,
onSave,
onDelete,
onImageChange
onImageChange,
}) => {
const Toast = useToast();
@@ -93,7 +93,11 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
setUrl(state.url ?? undefined);
setTwitter(state.twitter ?? undefined);
setInstagram(state.instagram ?? undefined);
setGender(StashService.genderToString((state as GQL.PerformerDataFragment).gender ?? undefined));
setGender(
StashService.genderToString(
(state as GQL.PerformerDataFragment).gender ?? undefined
)
);
}
function updatePerformerEditStateFromScraper(
@@ -128,7 +132,9 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
useEffect(() => {
const newQueryableScrapers = (
Scrapers?.data?.listPerformerScrapers ?? []
).filter(s => s.performer?.supported_scrapes.includes(GQL.ScrapeType.Name));
).filter((s) =>
s.performer?.supported_scrapes.includes(GQL.ScrapeType.Name)
);
setQueryableScrapers(newQueryableScrapers);
}, [Scrapers]);
@@ -156,7 +162,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
twitter,
instagram,
image,
gender: StashService.stringToGender(gender)
gender: StashService.stringToGender(gender),
};
if (!isNew) {
@@ -226,7 +232,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
value: ethnicity,
isEditing: !!isEditing,
placeholder: "Ethnicity",
onChange: setEthnicity
onChange: setEthnicity,
});
}
@@ -240,7 +246,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
<Popover.Content>
<div>
{queryableScrapers
? queryableScrapers.map(s => (
? queryableScrapers.map((s) => (
<div key={s.name}>
<Button
key={s.name}
@@ -278,7 +284,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
scraperId={
isDisplayingScraperDialog ? isDisplayingScraperDialog.id : ""
}
onSelectPerformer={query => setScrapePerformerDetails(query)}
onSelectPerformer={(query) => setScrapePerformerDetails(query)}
/>
</div>
</Modal>
@@ -288,8 +294,8 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
function urlScrapable(scrapedUrl: string) {
return (
!!scrapedUrl &&
(Scrapers?.data?.listPerformerScrapers ?? []).some(s =>
(s?.performer?.urls ?? []).some(u => scrapedUrl.includes(u))
(Scrapers?.data?.listPerformerScrapers ?? []).some((s) =>
(s?.performer?.urls ?? []).some((u) => scrapedUrl.includes(u))
)
);
}
@@ -383,7 +389,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
value: name,
isEditing: !!isEditing,
placeholder: "Name",
onChange: setName
onChange: setName,
});
}
}
@@ -395,7 +401,7 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
value: aliases,
isEditing: !!isEditing,
placeholder: "Aliases",
onChange: setAliases
onChange: setAliases,
});
}
}
@@ -424,69 +430,69 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
title: "Birthdate",
value: birthdate,
isEditing: !!isEditing,
onChange: setBirthdate
onChange: setBirthdate,
})}
{renderEthnicity()}
{TableUtils.renderInputGroup({
title: "Eye Color",
value: eyeColor,
isEditing: !!isEditing,
onChange: setEyeColor
onChange: setEyeColor,
})}
{TableUtils.renderInputGroup({
title: "Country",
value: country,
isEditing: !!isEditing,
onChange: setCountry
onChange: setCountry,
})}
{TableUtils.renderInputGroup({
title: "Height (cm)",
value: height,
isEditing: !!isEditing,
onChange: setHeight
onChange: setHeight,
})}
{TableUtils.renderInputGroup({
title: "Measurements",
value: measurements,
isEditing: !!isEditing,
onChange: setMeasurements
onChange: setMeasurements,
})}
{TableUtils.renderInputGroup({
title: "Fake Tits",
value: fakeTits,
isEditing: !!isEditing,
onChange: setFakeTits
onChange: setFakeTits,
})}
{TableUtils.renderInputGroup({
title: "Career Length",
value: careerLength,
isEditing: !!isEditing,
onChange: setCareerLength
onChange: setCareerLength,
})}
{TableUtils.renderInputGroup({
title: "Tattoos",
value: tattoos,
isEditing: !!isEditing,
onChange: setTattoos
onChange: setTattoos,
})}
{TableUtils.renderInputGroup({
title: "Piercings",
value: piercings,
isEditing: !!isEditing,
onChange: setPiercings
onChange: setPiercings,
})}
{renderURLField()}
{TableUtils.renderInputGroup({
title: "Twitter",
value: twitter,
isEditing: !!isEditing,
onChange: setTwitter
onChange: setTwitter,
})}
{TableUtils.renderInputGroup({
title: "Instagram",
value: instagram,
isEditing: !!isEditing,
onChange: setInstagram
onChange: setInstagram,
})}
</tbody>
</Table>

View File

@@ -9,7 +9,7 @@ interface IPerformerOperationsProps {
}
export const PerformerOperationsPanel: React.FC<IPerformerOperationsProps> = ({
performer
performer,
}) => {
const Toast = useToast();

View File

@@ -9,12 +9,12 @@ interface IPerformerDetailsProps {
}
export const PerformerScenesPanel: React.FC<IPerformerDetailsProps> = ({
performer
performer,
}) => {
function filterHook(filter: ListFilterModel) {
const performerValue = { id: performer.id!, label: performer.name! };
// if performers is already present, then we modify it, otherwise add
let performerCriterion = filter.criteria.find(c => {
let performerCriterion = filter.criteria.find((c) => {
return c.type === "performers";
}) as PerformersCriterion;
@@ -25,7 +25,7 @@ export const PerformerScenesPanel: React.FC<IPerformerDetailsProps> = ({
) {
// add the performer if not present
if (
!performerCriterion.value.find(p => {
!performerCriterion.value.find((p) => {
return p.id === performer.id;
})
) {

View File

@@ -14,13 +14,13 @@ export const PerformerList: React.FC = () => {
const otherOperations = [
{
text: "Open Random",
onClick: getRandom
}
onClick: getRandom,
},
];
const listData = usePerformersList({
otherOperations,
renderContent
renderContent,
});
async function getRandom(
@@ -56,7 +56,7 @@ export const PerformerList: React.FC = () => {
if (filter.displayMode === DisplayMode.Grid) {
return (
<div className="row justify-content-center">
{result.data.findPerformers.performers.map(p => (
{result.data.findPerformers.performers.map((p) => (
<PerformerCard key={p.id} performer={p} />
))}
</div>

View File

@@ -2,7 +2,7 @@
.scrape-url-button {
color: $text-color;
float: right;
margin-right: .5rem;
margin-right: 0.5rem;
}
}
@@ -29,7 +29,7 @@
margin-left: 10px;
.not-favorite {
color: rgba(191, 204, 214, .5);
color: rgba(191, 204, 214, 0.5);
}
.favorite {

View File

@@ -52,7 +52,7 @@ export class ParserField {
ParserField.DDMMYYYY,
ParserField.DDMMYY,
ParserField.MMDDYYYY,
ParserField.MMDDYY
ParserField.MMDDYY,
];
static fullDateFields = [
@@ -61,6 +61,6 @@ export class ParserField {
ParserField.DDMMYYYY,
ParserField.DDMMYY,
ParserField.MMDDYYYY,
ParserField.MMDDYY
ParserField.MMDDYY,
];
}

View File

@@ -4,7 +4,7 @@ import {
Dropdown,
DropdownButton,
Form,
InputGroup
InputGroup,
} from "react-bootstrap";
import { ParserField } from "./ParserField";
import { ShowFields } from "./ShowFields";
@@ -15,43 +15,43 @@ const builtInRecipes = [
ignoreWords: [],
whitespaceCharacters: "",
capitalizeTitle: false,
description: "Filename"
description: "Filename",
},
{
pattern: "{title}.{ext}",
ignoreWords: [],
whitespaceCharacters: "",
capitalizeTitle: false,
description: "Without extension"
description: "Without extension",
},
{
pattern: "{}.{yy}.{mm}.{dd}.{title}.XXX.{}.{ext}",
ignoreWords: [],
whitespaceCharacters: ".",
capitalizeTitle: true,
description: ""
description: "",
},
{
pattern: "{}.{yy}.{mm}.{dd}.{title}.{ext}",
ignoreWords: [],
whitespaceCharacters: ".",
capitalizeTitle: true,
description: ""
description: "",
},
{
pattern: "{title}.XXX.{}.{ext}",
ignoreWords: [],
whitespaceCharacters: ".",
capitalizeTitle: true,
description: ""
description: "",
},
{
pattern: "{}.{yy}.{mm}.{dd}.{title}.{i}.{ext}",
ignoreWords: ["cz", "fr"],
whitespaceCharacters: ".",
capitalizeTitle: true,
description: "Foreign language"
}
description: "Foreign language",
},
];
export interface IParserInput {
@@ -102,7 +102,7 @@ export const ParserInput: React.FC<IParserInputProps> = (
capitalizeTitle,
page: 1,
pageSize: props.input.pageSize,
findClicked: props.input.findClicked
findClicked: props.input.findClicked,
});
}
@@ -139,7 +139,7 @@ export const ParserInput: React.FC<IParserInputProps> = (
/>
<InputGroup.Append>
<DropdownButton id="parser-field-select" title="Add Field">
{validFields.map(item => (
{validFields.map((item) => (
<Dropdown.Item
key={item.field}
onSelect={() => addParserField(item)}
@@ -207,7 +207,7 @@ export const ParserInput: React.FC<IParserInputProps> = (
id="recipe-select"
title="Select Parser Recipe"
>
{builtInRecipes.map(item => (
{builtInRecipes.map((item) => (
<Dropdown.Item
key={item.pattern}
onSelect={() => setParserRecipe(item)}
@@ -222,7 +222,7 @@ export const ParserInput: React.FC<IParserInputProps> = (
<Form.Group>
<ShowFields
fields={props.showFields}
onShowFieldsChanged={fields => props.setShowFields(fields)}
onShowFieldsChanged={(fields) => props.setShowFields(fields)}
/>
</Form.Group>
@@ -239,7 +239,7 @@ export const ParserInput: React.FC<IParserInputProps> = (
defaultValue={props.input.pageSize}
className="col-1 filter-item"
>
{PAGE_SIZE_OPTIONS.map(val => (
{PAGE_SIZE_OPTIONS.map((val) => (
<option key={val} value={val}>
{val}
</option>

View File

@@ -19,7 +19,7 @@ const initialParserInput = {
capitalizeTitle: true,
page: 1,
pageSize: 20,
findClicked: false
findClicked: false,
};
const initialShowFieldsState = new Map<string, boolean>([
@@ -27,7 +27,7 @@ const initialShowFieldsState = new Map<string, boolean>([
["Date", true],
["Performers", true],
["Tags", true],
["Studio", true]
["Studio", true],
]);
export const SceneFilenameParser: React.FC = () => {
@@ -60,7 +60,7 @@ export const SceneFilenameParser: React.FC = () => {
const dateSet =
pattern.includes("{date}") ||
pattern.includes("{dd}") || // don't worry about other partial date fields since this should be implied
ParserField.fullDateFields.some(f => {
ParserField.fullDateFields.some((f) => {
return pattern.includes(`{${f.field}}`);
});
const performerSet = pattern.includes("{performer}");
@@ -72,7 +72,7 @@ export const SceneFilenameParser: React.FC = () => {
["Date", dateSet],
["Performers", performerSet],
["Tags", tagSet],
["Studio", studioSet]
["Studio", studioSet],
]);
setShowFields(newShowFields);
@@ -84,10 +84,10 @@ export const SceneFilenameParser: React.FC = () => {
) => {
if (results) {
const result = results
.map(r => {
.map((r) => {
return new SceneParserResult(r);
})
.filter(r => !!r) as SceneParserResult[];
.filter((r) => !!r) as SceneParserResult[];
setParserResult(result);
determineFieldsToHide();
@@ -106,24 +106,24 @@ export const SceneFilenameParser: React.FC = () => {
page: parserInput.page,
per_page: parserInput.pageSize,
sort: "path",
direction: GQL.SortDirectionEnum.Asc
direction: GQL.SortDirectionEnum.Asc,
};
const parserInputData = {
ignoreWords: parserInput.ignoreWords,
whitespaceCharacters: parserInput.whitespaceCharacters,
capitalizeTitle: parserInput.capitalizeTitle
capitalizeTitle: parserInput.capitalizeTitle,
};
StashService.queryParseSceneFilenames(parserFilter, parserInputData)
.then(response => {
.then((response) => {
const result = response.data.parseSceneFilenames;
if (result) {
parseResults(result.results);
setTotalItems(result.count);
}
})
.catch(err => Toast.error(err))
.catch((err) => Toast.error(err))
.finally(() => setIsLoading(false));
}
}, [parserInput, parseResults, Toast]);
@@ -152,8 +152,8 @@ export const SceneFilenameParser: React.FC = () => {
function getScenesUpdateData() {
return parserResult
.filter(result => result.isChanged())
.map(result => result.toSceneUpdateInput());
.filter((result) => result.isChanged())
.map((result) => result.toSceneUpdateInput());
}
async function onApply() {
@@ -170,19 +170,19 @@ export const SceneFilenameParser: React.FC = () => {
}
useEffect(() => {
const newAllTitleSet = !parserResult.some(r => {
const newAllTitleSet = !parserResult.some((r) => {
return !r.title.isSet;
});
const newAllDateSet = !parserResult.some(r => {
const newAllDateSet = !parserResult.some((r) => {
return !r.date.isSet;
});
const newAllPerformerSet = !parserResult.some(r => {
const newAllPerformerSet = !parserResult.some((r) => {
return !r.performers.isSet;
});
const newAllTagSet = !parserResult.some(r => {
const newAllTagSet = !parserResult.some((r) => {
return !r.tags.isSet;
});
const newAllStudioSet = !parserResult.some(r => {
const newAllStudioSet = !parserResult.some((r) => {
return !r.studio.isSet;
});
@@ -196,7 +196,7 @@ export const SceneFilenameParser: React.FC = () => {
function onSelectAllTitleSet(selected: boolean) {
const newResult = [...parserResult];
newResult.forEach(r => {
newResult.forEach((r) => {
r.title.isSet = selected;
});
@@ -207,7 +207,7 @@ export const SceneFilenameParser: React.FC = () => {
function onSelectAllDateSet(selected: boolean) {
const newResult = [...parserResult];
newResult.forEach(r => {
newResult.forEach((r) => {
r.date.isSet = selected;
});
@@ -218,7 +218,7 @@ export const SceneFilenameParser: React.FC = () => {
function onSelectAllPerformerSet(selected: boolean) {
const newResult = [...parserResult];
newResult.forEach(r => {
newResult.forEach((r) => {
r.performers.isSet = selected;
});
@@ -229,7 +229,7 @@ export const SceneFilenameParser: React.FC = () => {
function onSelectAllTagSet(selected: boolean) {
const newResult = [...parserResult];
newResult.forEach(r => {
newResult.forEach((r) => {
r.tags.isSet = selected;
});
@@ -240,7 +240,7 @@ export const SceneFilenameParser: React.FC = () => {
function onSelectAllStudioSet(selected: boolean) {
const newResult = [...parserResult];
newResult.forEach(r => {
newResult.forEach((r) => {
r.studio.isSet = selected;
});
@@ -305,11 +305,11 @@ export const SceneFilenameParser: React.FC = () => {
</tr>
</thead>
<tbody>
{parserResult.map(scene => (
{parserResult.map((scene) => (
<SceneParserRow
scene={scene}
key={scene.id}
onChange={changedScene => onChange(scene, changedScene)}
onChange={(changedScene) => onChange(scene, changedScene)}
showFields={showFields}
/>
))}
@@ -320,7 +320,7 @@ export const SceneFilenameParser: React.FC = () => {
currentPage={parserInput.page}
itemsPerPage={parserInput.pageSize}
totalItems={totalItems}
onChangePage={page => onPageChanged(page)}
onChangePage={(page) => onPageChanged(page)}
/>
<Button variant="primary" onClick={onApply}>
Apply
@@ -334,7 +334,7 @@ export const SceneFilenameParser: React.FC = () => {
<h4>Scene Filename Parser</h4>
<ParserInput
input={parserInput}
onFind={input => onFindClicked(input)}
onFind={(input) => onFindClicked(input)}
onPageSizeChanged={onPageSizeChanged}
showFields={showFields}
setShowFields={setShowFields}

View File

@@ -3,12 +3,12 @@ import _ from "lodash";
import { Form } from "react-bootstrap";
import {
ParseSceneFilenamesQuery,
SlimSceneDataFragment
SlimSceneDataFragment,
} from "src/core/generated-graphql";
import {
PerformerSelect,
TagSelect,
StudioSelect
StudioSelect,
} from "src/components/Shared";
import { TextUtils } from "src/utils";
@@ -51,8 +51,8 @@ export class SceneParserResult {
this.filename = TextUtils.fileNameFromPath(this.scene.path);
this.title.setOriginalValue(this.scene.title ?? undefined);
this.date.setOriginalValue(this.scene.date ?? undefined);
this.performers.setOriginalValue(this.scene.performers.map(p => p.id));
this.tags.setOriginalValue(this.scene.tags.map(t => t.id));
this.performers.setOriginalValue(this.scene.performers.map((p) => p.id));
this.tags.setOriginalValue(this.scene.tags.map((t) => t.id));
this.studio.setOriginalValue(this.scene.studio?.id);
this.title.setValue(result.title ?? undefined);
@@ -82,10 +82,10 @@ export class SceneParserResult {
studio_id: this.studio.isSet ? this.studio.value : this.scene.studio?.id,
performer_ids: this.performers.isSet
? this.performers.value
: this.scene.performers.map(performer => performer.id),
: this.scene.performers.map((performer) => performer.id),
tag_ids: this.tags.isSet
? this.tags.value
: this.scene.tags.map(tag => tag.id)
: this.scene.tags.map((tag) => tag.id),
};
}
}
@@ -165,8 +165,8 @@ function SceneParserPerformerField(props: ISceneParserFieldProps<string[]>) {
<PerformerSelect isDisabled isMulti ids={originalPerformers} />
<PerformerSelect
isMulti
onSelect={items => {
maybeValueChanged(items.map(i => i.id));
onSelect={(items) => {
maybeValueChanged(items.map((i) => i.id));
}}
ids={newPerformers}
/>
@@ -201,8 +201,8 @@ function SceneParserTagField(props: ISceneParserFieldProps<string[]>) {
<TagSelect isDisabled isMulti ids={originalTags} />
<TagSelect
isMulti
onSelect={items => {
maybeValueChanged(items.map(i => i.id));
onSelect={(items) => {
maybeValueChanged(items.map((i) => i.id));
}}
ids={newTags}
/>
@@ -238,7 +238,7 @@ function SceneParserStudioField(props: ISceneParserFieldProps<string>) {
<Form.Group className={props.className}>
<StudioSelect isDisabled ids={originalStudio} />
<StudioSelect
onSelect={items => {
onSelect={(items) => {
maybeValueChanged(items[0].id);
}}
ids={newStudio}
@@ -304,10 +304,10 @@ export const SceneParserRow = (props: ISceneParserRowProps) => {
fieldName="Title"
className="parser-field-title"
parserResult={props.scene.title}
onSetChanged={isSet =>
onSetChanged={(isSet) =>
onTitleChanged(isSet, props.scene.title.value ?? "")
}
onValueChanged={value =>
onValueChanged={(value) =>
onTitleChanged(props.scene.title.isSet, value)
}
/>
@@ -318,10 +318,12 @@ export const SceneParserRow = (props: ISceneParserRowProps) => {
fieldName="Date"
className="parser-field-date"
parserResult={props.scene.date}
onSetChanged={isSet =>
onSetChanged={(isSet) =>
onDateChanged(isSet, props.scene.date.value ?? "")
}
onValueChanged={value => onDateChanged(props.scene.date.isSet, value)}
onValueChanged={(value) =>
onDateChanged(props.scene.date.isSet, value)
}
/>
)}
{props.showFields.get("Performers") && (
@@ -331,10 +333,10 @@ export const SceneParserRow = (props: ISceneParserRowProps) => {
className="parser-field-performers"
parserResult={props.scene.performers}
originalParserResult={props.scene.performers}
onSetChanged={set =>
onSetChanged={(set) =>
onPerformerIdsChanged(set, props.scene.performers.value ?? [])
}
onValueChanged={value =>
onValueChanged={(value) =>
onPerformerIdsChanged(props.scene.performers.isSet, value)
}
/>
@@ -346,10 +348,10 @@ export const SceneParserRow = (props: ISceneParserRowProps) => {
className="parser-field-tags"
parserResult={props.scene.tags}
originalParserResult={props.scene.tags}
onSetChanged={isSet =>
onSetChanged={(isSet) =>
onTagIdsChanged(isSet, props.scene.tags.value ?? [])
}
onValueChanged={value =>
onValueChanged={(value) =>
onTagIdsChanged(props.scene.tags.isSet, value)
}
/>
@@ -361,10 +363,10 @@ export const SceneParserRow = (props: ISceneParserRowProps) => {
className="parser-field-studio"
parserResult={props.scene.studio}
originalParserResult={props.scene.studio}
onSetChanged={set =>
onSetChanged={(set) =>
onStudioIdChanged(set, props.scene.studio.value ?? "")
}
onValueChanged={value =>
onValueChanged={(value) =>
onStudioIdChanged(props.scene.studio.isSet, value)
}
/>

View File

@@ -35,11 +35,11 @@
}
.form-control + .form-control {
margin-top: .5rem;
margin-top: 0.5rem;
}
.badge-items {
background-color: #e9ecef;
margin-bottom: .25rem;
margin-bottom: 0.25rem;
}
}

View File

@@ -25,7 +25,7 @@ const KeyMap = {
NUM0: "0",
NUM1: "1",
NUM2: "2",
SPACE: " "
SPACE: " ",
};
export class ScenePlayerImpl extends React.Component<
@@ -49,7 +49,7 @@ export class ScenePlayerImpl extends React.Component<
},
SPACE: () => {
this.onPause();
}
},
};
constructor(props: IScenePlayerProps) {
@@ -63,15 +63,15 @@ export class ScenePlayerImpl extends React.Component<
this.state = {
scrubberPosition: 0,
config: this.makeJWPlayerConfig(props.scene)
config: this.makeJWPlayerConfig(props.scene),
};
}
public UNSAFE_componentWillReceiveProps(props: IScenePlayerProps) {
if (props.scene !== this.props.scene) {
this.setState(state => ({
this.setState((state) => ({
...state,
config: this.makeJWPlayerConfig(this.props.scene)
config: this.makeJWPlayerConfig(this.props.scene),
}));
}
}
@@ -177,17 +177,17 @@ export class ScenePlayerImpl extends React.Component<
tracks: [
{
file: scene.paths.vtt,
kind: "thumbnails"
kind: "thumbnails",
},
{
file: scene.paths.chapters_vtt,
kind: "chapters"
}
kind: "chapters",
},
],
aspectratio: "16:9",
width: "100%",
floating: {
dismissible: true
dismissible: true,
},
cast: {},
primary: "html5",
@@ -199,7 +199,7 @@ export class ScenePlayerImpl extends React.Component<
playbackRates: [0.75, 1, 1.5, 2, 3, 4],
getDurationHook,
seekHook,
getCurrentTimeHook
getCurrentTimeHook,
};
return ret;

View File

@@ -5,7 +5,7 @@ import React, {
useEffect,
useRef,
useState,
useCallback
useCallback,
} from "react";
import { Button } from "react-bootstrap";
import axios from "axios";
@@ -45,10 +45,7 @@ async function fetchSpriteInfo(vttPath: string) {
const line = lines.shift();
if (line !== undefined) {
if (line.includes("#") && line.includes("=") && line.includes(",")) {
const size = line
.split("#")[1]
.split("=")[1]
.split(",");
const size = line.split("#")[1].split("=")[1].split(",");
item.x = Number(size[0]);
item.y = Number(size[1]);
item.w = Number(size[2]);
@@ -120,13 +117,14 @@ export const ScenePlayerScrubber: React.FC<IScenePlayerScrubberProps> = (
if (!scrubberSliderEl.current) {
return;
}
scrubberSliderEl.current.style.transform = `translateX(${scrubberSliderEl
.current.clientWidth / 2}px)`;
scrubberSliderEl.current.style.transform = `translateX(${
scrubberSliderEl.current.clientWidth / 2
}px)`;
}, [scrubberSliderEl]);
useEffect(() => {
if (!props.scene.paths.vtt) return;
fetchSpriteInfo(props.scene.paths.vtt).then(sprites => {
fetchSpriteInfo(props.scene.paths.vtt).then((sprites) => {
if (sprites) setSpriteItems(sprites);
});
}, [props.scene]);
@@ -297,13 +295,13 @@ export const ScenePlayerScrubber: React.FC<IScenePlayerScrubberProps> = (
tag!.clientWidth / 2;
return {
left: `${left}px`,
height: 20
height: 20,
};
}
return props.scene.scene_markers.map((marker, index) => {
const dataAttrs = {
"data-marker-id": index
"data-marker-id": index,
};
return (
<div
@@ -332,13 +330,13 @@ export const ScenePlayerScrubber: React.FC<IScenePlayerScrubberProps> = (
margin: "0px auto",
backgroundPosition: `${-sprite.x}px ${-sprite.y}px`,
backgroundImage: `url(${path})`,
left: `${left}px`
left: `${left}px`,
};
}
return spriteItems.map((spriteItem, index) => {
const dataAttrs = {
"data-sprite-item-id": index
"data-sprite-item-id": index,
};
return (
<div

View File

@@ -34,7 +34,7 @@
cursor: grab;
display: inline-block;
height: 120px;
margin: 0 .5%;
margin: 0 0.5%;
overflow: hidden;
-webkit-overflow-scrolling: touch;
position: relative;

View File

@@ -20,7 +20,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
) => {
const [previewPath, setPreviewPath] = useState<string>();
const videoHoverHook = VideoHoverHook.useVideoHover({
resetOnMouseLeave: false
resetOnMouseLeave: false,
});
const config = StashService.useConfiguration();
@@ -83,7 +83,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
function maybeRenderTagPopoverButton() {
if (props.scene.tags.length <= 0) return;
const popoverContent = props.scene.tags.map(tag => (
const popoverContent = props.scene.tags.map((tag) => (
<TagLink key={tag.id} tag={tag} />
));
@@ -100,7 +100,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
function maybeRenderPerformerPopoverButton() {
if (props.scene.performers.length <= 0) return;
const popoverContent = props.scene.performers.map(performer => (
const popoverContent = props.scene.performers.map((performer) => (
<div className="performer-tag-container row" key="performer">
<Link
to={`/performers/${performer.id}`}
@@ -129,7 +129,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
function maybeRenderMoviePopoverButton() {
if (props.scene.movies.length <= 0) return;
const popoverContent = props.scene.movies.map(sceneMovie => (
const popoverContent = props.scene.movies.map((sceneMovie) => (
<div className="movie-tag-container row" key="movie">
<Link
to={`/movies/${sceneMovie.movie.id}`}
@@ -162,7 +162,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
function maybeRenderSceneMarkerPopoverButton() {
if (props.scene.scene_markers.length <= 0) return;
const popoverContent = props.scene.scene_markers.map(marker => {
const popoverContent = props.scene.scene_markers.map((marker) => {
const markerPopover = { ...marker, scene: { id: props.scene.id } };
return <TagLink key={marker.id} marker={markerPopover} />;
});

View File

@@ -12,13 +12,13 @@ interface IPrimaryTags {
export const PrimaryTags: React.FC<IPrimaryTags> = ({
sceneMarkers,
onClickMarker,
onEdit
onEdit,
}) => {
if (!sceneMarkers?.length) return <div />;
const primaries: Record<string, GQL.Tag> = {};
const primaryTags: Record<string, GQL.SceneMarkerDataFragment[]> = {};
sceneMarkers.forEach(m => {
sceneMarkers.forEach((m) => {
if (primaryTags[m.primary_tag.id]) primaryTags[m.primary_tag.id].push(m);
else {
primaryTags[m.primary_tag.id] = [m];
@@ -26,9 +26,9 @@ export const PrimaryTags: React.FC<IPrimaryTags> = ({
}
});
const primaryCards = Object.keys(primaryTags).map(id => {
const markers = primaryTags[id].map(marker => {
const tags = marker.tags.map(tag => (
const primaryCards = Object.keys(primaryTags).map((id) => {
const markers = primaryTags[id].map((marker) => {
const tags = marker.tags.map((tag) => (
<Badge key={tag.id} variant="secondary" className="tag-item">
{tag.name}
</Badge>

View File

@@ -149,7 +149,7 @@ export const Scene: React.FC = () => {
<Tab eventKey="scene-edit-panel" title="Edit">
<SceneEditPanel
scene={scene}
onUpdate={newScene => setScene(newScene)}
onUpdate={(newScene) => setScene(newScene)}
onDelete={() => history.push("/scenes")}
/>
</Tab>

View File

@@ -8,7 +8,7 @@ interface ISceneDetailProps {
scene: GQL.SceneDataFragment;
}
export const SceneDetailPanel: React.FC<ISceneDetailProps> = props => {
export const SceneDetailPanel: React.FC<ISceneDetailProps> = (props) => {
function renderDetails() {
if (!props.scene.details || props.scene.details === "") return;
return (
@@ -21,7 +21,7 @@ export const SceneDetailPanel: React.FC<ISceneDetailProps> = props => {
function renderTags() {
if (props.scene.tags.length === 0) return;
const tags = props.scene.tags.map(tag => (
const tags = props.scene.tags.map((tag) => (
<TagLink key={tag.id} tag={tag} />
));
return (

View File

@@ -12,7 +12,7 @@ import {
Modal,
Icon,
LoadingIndicator,
ImageInput
ImageInput,
} from "src/components/Shared";
import { useToast } from "src/hooks";
import { ImageUtils, TableUtils } from "src/utils";
@@ -60,7 +60,9 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
useEffect(() => {
const newQueryableScrapers = (
Scrapers?.data?.listSceneScrapers ?? []
).filter(s => s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment));
).filter((s) =>
s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
);
setQueryableScrapers(newQueryableScrapers);
}, [Scrapers]);
@@ -69,7 +71,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
let changed = false;
const newMap: MovieSceneIndexMap = new Map();
if (movieIds) {
movieIds.forEach(id => {
movieIds.forEach((id) => {
if (!movieSceneIndexes.has(id)) {
changed = true;
newMap.set(id, undefined);
@@ -94,14 +96,14 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
}, [movieIds, movieSceneIndexes]);
function updateSceneEditState(state: Partial<GQL.SceneDataFragment>) {
const perfIds = state.performers?.map(performer => performer.id);
const tIds = state.tags ? state.tags.map(tag => tag.id) : undefined;
const perfIds = state.performers?.map((performer) => performer.id);
const tIds = state.tags ? state.tags.map((tag) => tag.id) : undefined;
const moviIds = state.movies
? state.movies.map(sceneMovie => sceneMovie.movie.id)
? state.movies.map((sceneMovie) => sceneMovie.movie.id)
: undefined;
const movieSceneIdx: MovieSceneIndexMap = new Map();
if (state.movies) {
state.movies.forEach(m => {
state.movies.forEach((m) => {
movieSceneIdx.set(m.movie.id, m.scene_index ?? undefined);
});
}
@@ -140,7 +142,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
performer_ids: performerIds,
movies: makeMovieInputs(),
tag_ids: tagIds,
cover_image: coverImage
cover_image: coverImage,
};
}
@@ -149,14 +151,14 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
return undefined;
}
let ret = movieIds.map(id => {
let ret = movieIds.map((id) => {
const r: GQL.SceneMovieInput = {
movie_id: id
movie_id: id,
};
return r;
});
ret = ret.map(r => {
ret = ret.map((r) => {
return { scene_index: movieSceneIndexes.get(r.movie_id), ...r };
});
@@ -181,7 +183,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
return {
id: props.scene.id,
delete_file: deleteFile,
delete_generated: deleteGenerated
delete_generated: deleteGenerated,
};
}
@@ -202,7 +204,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
return (
<SceneMovieTable
movieSceneIndexes={movieSceneIndexes}
onUpdate={items => {
onUpdate={(items) => {
setMovieSceneIndexes(items);
}}
/>
@@ -272,7 +274,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
return (
<DropdownButton id="scene-scrape" title="Scrape with...">
{queryableScrapers.map(s => (
{queryableScrapers.map((s) => (
<Dropdown.Item key={s.name} onClick={() => onScrapeClicked(s)}>
{s.name}
</Dropdown.Item>
@@ -282,8 +284,8 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
}
function urlScrapable(scrapedUrl: string): boolean {
return (Scrapers?.data?.listSceneScrapers ?? []).some(s =>
(s?.scene?.urls ?? []).some(u => scrapedUrl.includes(u))
return (Scrapers?.data?.listSceneScrapers ?? []).some((s) =>
(s?.scene?.urls ?? []).some((u) => scrapedUrl.includes(u))
);
}
@@ -313,12 +315,12 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
scene.performers &&
scene.performers.length > 0
) {
const idPerfs = scene.performers.filter(p => {
const idPerfs = scene.performers.filter((p) => {
return p.id !== undefined && p.id !== null;
});
if (idPerfs.length > 0) {
const newIds = idPerfs.map(p => p.id);
const newIds = idPerfs.map((p) => p.id);
setPerformerIds(newIds as string[]);
}
}
@@ -328,23 +330,23 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
scene.movies &&
scene.movies.length > 0
) {
const idMovis = scene.movies.filter(p => {
const idMovis = scene.movies.filter((p) => {
return p.id !== undefined && p.id !== null;
});
if (idMovis.length > 0) {
const newIds = idMovis.map(p => p.id);
const newIds = idMovis.map((p) => p.id);
setMovieIds(newIds as string[]);
}
}
if (!tagIds?.length && scene?.tags?.length) {
const idTags = scene.tags.filter(p => {
const idTags = scene.tags.filter((p) => {
return p.id !== undefined && p.id !== null;
});
if (idTags.length > 0) {
const newIds = idTags.map(p => p.id);
const newIds = idTags.map((p) => p.id);
setTagIds(newIds as string[]);
}
}
@@ -396,7 +398,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
title: "Title",
value: title,
onChange: setTitle,
isEditing: true
isEditing: true,
})}
<tr>
<td>URL</td>
@@ -417,7 +419,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
value: date,
isEditing: true,
onChange: setDate,
placeholder: "YYYY-MM-DD"
placeholder: "YYYY-MM-DD",
})}
{TableUtils.renderHtmlSelect({
title: "Rating",
@@ -425,7 +427,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
isEditing: true,
onChange: (value: string) =>
setRating(Number.parseInt(value, 10)),
selectOptions: ["", 1, 2, 3, 4, 5]
selectOptions: ["", 1, 2, 3, 4, 5],
})}
<tr>
<td>Gallery</td>
@@ -433,7 +435,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
<SceneGallerySelect
sceneId={props.scene.id}
initialId={galleryId}
onSelect={item => setGalleryId(item ? item.id : undefined)}
onSelect={(item) => setGalleryId(item ? item.id : undefined)}
/>
</td>
</tr>
@@ -441,7 +443,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
<td>Studio</td>
<td>
<StudioSelect
onSelect={items =>
onSelect={(items) =>
setStudioId(items.length > 0 ? items[0]?.id : undefined)
}
ids={studioId ? [studioId] : []}
@@ -453,8 +455,8 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
<td>
<PerformerSelect
isMulti
onSelect={items =>
setPerformerIds(items.map(item => item.id))
onSelect={(items) =>
setPerformerIds(items.map((item) => item.id))
}
ids={performerIds}
/>
@@ -465,7 +467,9 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
<td>
<MovieSelect
isMulti
onSelect={items => setMovieIds(items.map(item => item.id))}
onSelect={(items) =>
setMovieIds(items.map((item) => item.id))
}
ids={movieIds}
/>
{renderTableMovies()}
@@ -476,7 +480,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
<td>
<TagSelect
isMulti
onSelect={items => setTagIds(items.map(item => item.id))}
onSelect={(items) => setTagIds(items.map((item) => item.id))}
ids={tagIds}
/>
</td>

View File

@@ -20,7 +20,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
function renderPath() {
const {
scene: { path }
scene: { path },
} = props;
return (
<div className="row">

View File

@@ -6,7 +6,7 @@ import { StashService } from "src/core/StashService";
import {
DurationInput,
TagSelect,
MarkerTitleSuggest
MarkerTitleSuggest,
} from "src/components/Shared";
import { useToast } from "src/hooks";
import { JWUtils } from "src/utils";
@@ -27,7 +27,7 @@ interface ISceneMarkerForm {
export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
sceneID,
editingMarker,
onClose
onClose,
}) => {
const [sceneMarkerCreate] = StashService.useSceneMarkerCreate();
const [sceneMarkerUpdate] = StashService.useSceneMarkerUpdate();
@@ -40,18 +40,18 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
seconds: parseFloat(values.seconds),
scene_id: sceneID,
primary_tag_id: values.primaryTagId,
tag_ids: values.tagIds
tag_ids: values.tagIds,
};
if (!editingMarker) {
sceneMarkerCreate({ variables })
.then(onClose)
.catch(err => Toast.error(err));
.catch((err) => Toast.error(err));
} else {
const updateVariables = variables as GQL.SceneMarkerUpdateInput;
updateVariables.id = editingMarker!.id;
sceneMarkerUpdate({ variables: updateVariables })
.then(onClose)
.catch(err => Toast.error(err));
.catch((err) => Toast.error(err));
}
};
@@ -60,7 +60,7 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
sceneMarkerDestroy({ variables: { id: editingMarker.id } })
.then(onClose)
.catch(err => Toast.error(err));
.catch((err) => Toast.error(err));
};
const renderTitleField = (fieldProps: FieldProps<string>) => (
<div className="col-10">
@@ -76,7 +76,7 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
const renderSecondsField = (fieldProps: FieldProps<string>) => (
<div className="col-3">
<DurationInput
onValueChange={s => fieldProps.form.setFieldValue("seconds", s)}
onValueChange={(s) => fieldProps.form.setFieldValue("seconds", s)}
onReset={() =>
fieldProps.form.setFieldValue(
"seconds",
@@ -90,7 +90,7 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
const renderPrimaryTagField = (fieldProps: FieldProps<string>) => (
<TagSelect
onSelect={tags =>
onSelect={(tags) =>
fieldProps.form.setFieldValue("primaryTagId", tags[0]?.id)
}
ids={fieldProps.field.value ? [fieldProps.field.value] : []}
@@ -101,10 +101,10 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
const renderTagsField = (fieldProps: FieldProps<string[]>) => (
<TagSelect
isMulti
onSelect={tags =>
onSelect={(tags) =>
fieldProps.form.setFieldValue(
"tagIds",
tags.map(tag => tag.id)
tags.map((tag) => tag.id)
)
}
ids={fieldProps.field.value}
@@ -119,7 +119,7 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
Math.round(JWUtils.getPlayer()?.getPosition() ?? 0)
).toString(),
primaryTagId: editingMarker?.primary_tag.id ?? "",
tagIds: editingMarker?.tags.map(tag => tag.id) ?? []
tagIds: editingMarker?.tags.map((tag) => tag.id) ?? [],
};
return (

View File

@@ -54,7 +54,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
<div className="row">
<WallPanel
sceneMarkers={props.scene.scene_markers}
clickHandler={marker => {
clickHandler={(marker) => {
window.scrollTo(0, 0);
onClickMarker(marker as GQL.SceneMarkerDataFragment);
}}

View File

@@ -9,7 +9,7 @@ interface ISceneMoviePanelProps {
export const SceneMoviePanel: FunctionComponent<ISceneMoviePanelProps> = (
props: ISceneMoviePanelProps
) => {
const cards = props.scene.movies.map(sceneMovie => (
const cards = props.scene.movies.map((sceneMovie) => (
<MovieCard
key={sceneMovie.movie.id}
movie={sceneMovie.movie}

View File

@@ -22,11 +22,11 @@ export const SceneMovieTable: React.FunctionComponent<IProps> = (
if (!!props.movieSceneIndexes && !!items) {
props.movieSceneIndexes.forEach((index, movieId) => {
itemsFilter = itemsFilter.concat(items.filter(x => x.id === movieId));
itemsFilter = itemsFilter.concat(items.filter((x) => x.id === movieId));
});
}
const storeIdx = itemsFilter.map(movie => {
const storeIdx = itemsFilter.map((movie) => {
return props.movieSceneIndexes.get(movie.id);
});
@@ -54,7 +54,7 @@ export const SceneMovieTable: React.FunctionComponent<IProps> = (
}
>
{["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"].map(
opt => (
(opt) => (
<option value={opt} key={opt}>
{opt}
</option>

View File

@@ -19,8 +19,8 @@ export const SceneOperationsPanel: FunctionComponent<IOperationsPanelProps> = (
await generateScreenshot({
variables: {
id: props.scene.id,
at
}
at,
},
});
Toast.success({ content: "Generating screenshot" });
}

View File

@@ -9,7 +9,7 @@ interface IScenePerformerPanelProps {
export const ScenePerformerPanel: FunctionComponent<IScenePerformerPanelProps> = (
props: IScenePerformerPanelProps
) => {
const cards = props.scene.performers.map(performer => (
const cards = props.scene.performers.map((performer) => (
<PerformerCard
key={performer.id}
performer={performer}

View File

@@ -3,7 +3,7 @@ import _ from "lodash";
import { useHistory } from "react-router-dom";
import {
FindScenesQueryResult,
SlimSceneDataFragment
SlimSceneDataFragment,
} from "src/core/generated-graphql";
import { StashService } from "src/core/StashService";
import { useScenesList } from "src/hooks";
@@ -21,14 +21,14 @@ interface ISceneList {
export const SceneList: React.FC<ISceneList> = ({
subComponent,
filterHook
filterHook,
}) => {
const history = useHistory();
const otherOperations = [
{
text: "Play Random",
onClick: playRandom
}
onClick: playRandom,
},
];
const listData = useScenesList({
@@ -37,7 +37,7 @@ export const SceneList: React.FC<ISceneList> = ({
renderContent,
renderSelectedOptions,
subComponent,
filterHook
filterHook,
});
async function playRandom(
@@ -78,8 +78,8 @@ export const SceneList: React.FC<ISceneList> = ({
const { scenes } = result.data.findScenes;
const selectedScenes: SlimSceneDataFragment[] = [];
selectedIds.forEach(id => {
const scene = scenes.find(s => s.id === id);
selectedIds.forEach((id) => {
const scene = scenes.find((s) => s.id === id);
if (scene) {
selectedScenes.push(scene);
@@ -126,7 +126,7 @@ export const SceneList: React.FC<ISceneList> = ({
if (filter.displayMode === DisplayMode.Grid) {
return (
<div className="row justify-content-center">
{result.data.findScenes.scenes.map(scene =>
{result.data.findScenes.scenes.map((scene) =>
renderSceneCard(scene, selectedIds, zoomIndex)
)}
</div>

View File

@@ -13,24 +13,22 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
props: ISceneListTableProps
) => {
const renderTags = (tags: GQL.Tag[]) =>
tags.map(tag => (
tags.map((tag) => (
<Link key={tag.id} to={NavUtils.makeTagScenesUrl(tag)}>
<h6>{tag.name}</h6>
</Link>
));
const renderPerformers = (performers: Partial<GQL.Performer>[]) =>
performers.map(performer => (
performers.map((performer) => (
<Link key={performer.id} to={NavUtils.makePerformerScenesUrl(performer)}>
<h6>{performer.name}</h6>
</Link>
));
const renderMovies = (movies: Partial<GQL.SceneMovie>[]) => {
return movies.map(sceneMovie =>
!sceneMovie.movie ? (
undefined
) : (
return movies.map((sceneMovie) =>
!sceneMovie.movie ? undefined : (
<Link to={NavUtils.makeMovieScenesUrl(sceneMovie.movie)}>
<h6>{sceneMovie.movie.name}</h6>
</Link>

View File

@@ -14,13 +14,13 @@ export const SceneMarkerList: React.FC = () => {
const otherOperations = [
{
text: "Play Random",
onClick: playRandom
}
onClick: playRandom,
},
];
const listData = useSceneMarkersList({
otherOperations,
renderContent
renderContent,
});
async function playRandom(

View File

@@ -3,10 +3,7 @@ import { Button, Form } from "react-bootstrap";
import _ from "lodash";
import { StashService } from "src/core/StashService";
import * as GQL from "src/core/generated-graphql";
import {
StudioSelect,
LoadingIndicator
} from "src/components/Shared";
import { StudioSelect, LoadingIndicator } from "src/components/Shared";
import { useToast } from "src/hooks";
import MultiSet from "../Shared/MultiSet";
@@ -21,9 +18,13 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
const Toast = useToast();
const [rating, setRating] = useState<string>("");
const [studioId, setStudioId] = useState<string>();
const [performerMode, setPerformerMode] = React.useState<GQL.BulkUpdateIdMode>(GQL.BulkUpdateIdMode.Add);
const [performerMode, setPerformerMode] = React.useState<
GQL.BulkUpdateIdMode
>(GQL.BulkUpdateIdMode.Add);
const [performerIds, setPerformerIds] = useState<string[]>();
const [tagMode, setTagMode] = React.useState<GQL.BulkUpdateIdMode>(GQL.BulkUpdateIdMode.Add);
const [tagMode, setTagMode] = React.useState<GQL.BulkUpdateIdMode>(
GQL.BulkUpdateIdMode.Add
);
const [tagIds, setTagIds] = useState<string[]>();
const [updateScenes] = StashService.useBulkSceneUpdate(getSceneInput());
@@ -31,10 +32,13 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
// Network state
const [isLoading, setIsLoading] = useState(true);
function makeBulkUpdateIds(ids: string[], mode: GQL.BulkUpdateIdMode) : GQL.BulkUpdateIds {
function makeBulkUpdateIds(
ids: string[],
mode: GQL.BulkUpdateIdMode
): GQL.BulkUpdateIds {
return {
mode,
ids
ids,
};
}
@@ -46,9 +50,9 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
const aggregateTagIds = getTagIds(props.selected);
const sceneInput: GQL.BulkSceneUpdateInput = {
ids: props.selected.map(scene => {
ids: props.selected.map((scene) => {
return scene.id;
})
}),
};
// if rating is undefined
@@ -78,19 +82,31 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
}
// if performerIds are empty
if (performerMode === GQL.BulkUpdateIdMode.Set && (!performerIds || performerIds.length === 0)) {
if (
performerMode === GQL.BulkUpdateIdMode.Set &&
(!performerIds || performerIds.length === 0)
) {
// and all scenes have the same ids,
if (aggregatePerformerIds.length > 0) {
// then unset the performerIds, otherwise ignore
sceneInput.performer_ids = makeBulkUpdateIds(performerIds || [], performerMode);
sceneInput.performer_ids = makeBulkUpdateIds(
performerIds || [],
performerMode
);
}
} else {
// if performerIds non-empty, then we are setting them
sceneInput.performer_ids = makeBulkUpdateIds(performerIds || [], performerMode);
sceneInput.performer_ids = makeBulkUpdateIds(
performerIds || [],
performerMode
);
}
// if tagIds non-empty, then we are setting them
if (tagMode === GQL.BulkUpdateIdMode.Set && (!tagIds || tagIds.length === 0)) {
if (
tagMode === GQL.BulkUpdateIdMode.Set &&
(!tagIds || tagIds.length === 0)
) {
// and all scenes have the same ids,
if (aggregateTagIds.length > 0) {
// then unset the tagIds, otherwise ignore
@@ -157,11 +173,11 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
state.forEach((scene: GQL.SlimSceneDataFragment) => {
if (first) {
ret = scene.performers ? scene.performers.map(p => p.id).sort() : [];
ret = scene.performers ? scene.performers.map((p) => p.id).sort() : [];
first = false;
} else {
const perfIds = scene.performers
? scene.performers.map(p => p.id).sort()
? scene.performers.map((p) => p.id).sort()
: [];
if (!_.isEqual(ret, perfIds)) {
@@ -179,10 +195,10 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
state.forEach((scene: GQL.SlimSceneDataFragment) => {
if (first) {
ret = scene.tags ? scene.tags.map(t => t.id).sort() : [];
ret = scene.tags ? scene.tags.map((t) => t.id).sort() : [];
first = false;
} else {
const tIds = scene.tags ? scene.tags.map(t => t.id).sort() : [];
const tIds = scene.tags ? scene.tags.map((t) => t.id).sort() : [];
if (!_.isEqual(ret, tIds)) {
ret = [];
@@ -204,8 +220,10 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
state.forEach((scene: GQL.SlimSceneDataFragment) => {
const sceneRating = scene.rating?.toString() ?? "";
const sceneStudioID = scene?.studio?.id;
const scenePerformerIDs = (scene.performers ?? []).map(p => p.id).sort();
const sceneTagIDs = (scene.tags ?? []).map(p => p.id).sort();
const scenePerformerIDs = (scene.performers ?? [])
.map((p) => p.id)
.sort();
const sceneTagIDs = (scene.tags ?? []).map((p) => p.id).sort();
if (first) {
updateRating = sceneRating;
@@ -248,15 +266,19 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
) {
let mode = GQL.BulkUpdateIdMode.Add;
switch (type) {
case "performers": mode = performerMode; break;
case "tags": mode = tagMode; break;
case "performers":
mode = performerMode;
break;
case "tags":
mode = tagMode;
break;
}
return (
<MultiSet
type={type}
onUpdate={items => {
const itemIDs = items.map(i => i.id);
onUpdate={(items) => {
const itemIDs = items.map((i) => i.id);
switch (type) {
case "performers":
setPerformerIds(itemIDs);
@@ -266,10 +288,14 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
break;
}
}}
onSetMode={(mode) => {
onSetMode={(newMode) => {
switch (type) {
case "performers": setPerformerMode(mode); break;
case "tags": setTagMode(mode); break;
case "performers":
setPerformerMode(newMode);
break;
case "tags":
setTagMode(newMode);
break;
}
}}
ids={ids ?? []}
@@ -296,7 +322,7 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
setRating(event.currentTarget.value)
}
>
{["", "1", "2", "3", "4", "5"].map(opt => (
{["", "1", "2", "3", "4", "5"].map((opt) => (
<option key={opt} value={opt}>
{opt}
</option>
@@ -307,7 +333,7 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
<Form.Group controlId="studio" className="operation-item">
<Form.Label>Studio</Form.Label>
<StudioSelect
onSelect={items => setStudioId(items[0]?.id)}
onSelect={(items) => setStudioId(items[0]?.id)}
ids={studioId ? [studioId] : []}
/>
</Form.Group>

View File

@@ -15,7 +15,7 @@
.card-section {
margin-bottom: 0;
padding: .5rem 1rem 0 1rem;
padding: 0.5rem 1rem 0 1rem;
&-title {
overflow: hidden;
@@ -25,12 +25,12 @@
}
.scene-card-check {
left: .5rem;
left: 0.5rem;
margin-top: -12px;
opacity: .5;
opacity: 0.5;
padding-left: 15px;
position: absolute;
top: .7rem;
top: 0.7rem;
width: 1.2rem;
z-index: 1;
}
@@ -95,7 +95,7 @@
.file-info-panel {
div {
margin-bottom: .5rem;
margin-bottom: 0.5rem;
}
}
@@ -113,7 +113,7 @@
}
.studio-card {
padding: .5rem;
padding: 0.5rem;
&-header {
height: 150px;
@@ -138,9 +138,9 @@
color: $text-color;
display: block;
font-weight: 400;
letter-spacing: -.03rem;
letter-spacing: -0.03rem;
position: absolute;
right: .7rem;
right: 0.7rem;
text-shadow: 0 0 3px #000;
}
@@ -149,10 +149,10 @@
font-weight: 900;
height: 10%;
max-width: 40%;
opacity: .75;
opacity: 0.75;
position: absolute;
right: .7rem;
top: .7rem;
right: 0.7rem;
top: 0.7rem;
z-index: 9;
.image-thumbnail {
@@ -164,7 +164,7 @@
a {
color: $text-color;
display: inline-block;
letter-spacing: -.03rem;
letter-spacing: -0.03rem;
text-align: right;
text-decoration: none;
text-shadow: 0 0 3px #000;
@@ -173,7 +173,7 @@
.overlay-resolution {
font-weight: 900;
margin-right: .3rem;
margin-right: 0.3rem;
text-transform: uppercase;
}
@@ -190,7 +190,7 @@
.scene-specs-overlay,
.rating-banner,
.scene-studio-overlay {
transition: opacity .5s;
transition: opacity 0.5s;
}
&:hover {
@@ -198,12 +198,12 @@
.rating-banner,
.scene-studio-overlay {
opacity: 0;
transition: opacity .5s;
transition: opacity 0.5s;
}
.scene-studio-overlay:hover {
opacity: .75;
transition: opacity .5s;
opacity: 0.75;
transition: opacity 0.5s;
}
}
}

View File

@@ -10,7 +10,7 @@ export const SettingsAboutPanel: React.FC = () => {
error: errorLatest,
loading: loadingLatest,
refetch,
networkStatus
networkStatus,
} = StashService.useLatestVersion();
function maybeRenderTag() {

View File

@@ -48,7 +48,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
logLevel,
logAccess,
excludes,
scraperUserAgent
scraperUserAgent,
});
useEffect(() => {
@@ -116,7 +116,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
GQL.StreamingResolutionEnum.StandardHd,
GQL.StreamingResolutionEnum.FullHd,
GQL.StreamingResolutionEnum.FourK,
GQL.StreamingResolutionEnum.Original
GQL.StreamingResolutionEnum.Original,
].map(resolutionToString);
function resolutionToString(r: GQL.StreamingResolutionEnum | undefined) {
@@ -258,7 +258,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
}
value={resolutionToString(maxTranscodeSize)}
>
{transcodeQualities.map(q => (
{transcodeQualities.map((q) => (
<option key={q} value={q}>
{q}
</option>
@@ -280,7 +280,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
}
value={resolutionToString(maxStreamingTranscodeSize)}
>
{transcodeQualities.map(q => (
{transcodeQualities.map((q) => (
<option key={q} value={q}>
{q}
</option>
@@ -382,7 +382,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
}
value={logLevel}
>
{["Debug", "Info", "Warning", "Error"].map(o => (
{["Debug", "Info", "Warning", "Error"].map((o) => (
<option key={o} value={o}>
{o}
</option>

View File

@@ -24,7 +24,7 @@ export const SettingsInterfacePanel: React.FC = () => {
showStudioAsText,
css,
cssEnabled,
language
language,
});
useEffect(() => {
@@ -119,7 +119,7 @@ export const SettingsInterfacePanel: React.FC = () => {
<DurationInput
className="row col col-4"
numericValue={maximumLoopDuration}
onValueChange={duration => setMaximumLoopDuration(duration)}
onValueChange={(duration) => setMaximumLoopDuration(duration)}
/>
<Form.Text className="text-muted">
Maximum scene duration where scene player will loop the video - 0 to

View File

@@ -73,8 +73,8 @@ export const SettingsLogsPanel: React.FC = () => {
const { data: existingData } = StashService.useLogs();
const [logLevel, setLogLevel] = useState<string>("Info");
const oldData = (existingData?.logs ?? []).map(e => new LogEntry(e));
const newData = (data?.loggingSubscribe ?? []).map(e => new LogEntry(e));
const oldData = (existingData?.logs ?? []).map((e) => new LogEntry(e));
const newData = (data?.loggingSubscribe ?? []).map((e) => new LogEntry(e));
const filteredLogEntries = [...newData.reverse(), ...oldData]
.filter(filterByLogLevel)
@@ -104,9 +104,9 @@ export const SettingsLogsPanel: React.FC = () => {
className="col-6 col-sm-2 input-control"
as="select"
defaultValue={logLevel}
onChange={event => setLogLevel(event.currentTarget.value)}
onChange={(event) => setLogLevel(event.currentTarget.value)}
>
{logLevels.map(level => (
{logLevels.map((level) => (
<option key={level} value={level}>
{level}
</option>
@@ -115,7 +115,7 @@ export const SettingsLogsPanel: React.FC = () => {
</Form.Row>
<div className="logs">
{maybeRenderError}
{filteredLogEntries.map(logEntry => (
{filteredLogEntries.map((logEntry) => (
<LogElement logEntry={logEntry} key={logEntry.id} />
))}
</div>

View File

@@ -16,7 +16,7 @@ export const GenerateButton: React.FC = () => {
sprites,
previews,
markers,
transcodes
transcodes,
});
Toast.success({ content: "Started generating" });
} catch (e) {

View File

@@ -128,7 +128,7 @@ export const SettingsTasksPanel: React.FC = () => {
return {
performers: autoTagPerformers ? wildcard : [],
studios: autoTagStudios ? wildcard : [],
tags: autoTagTags ? wildcard : []
tags: autoTagTags ? wildcard : [],
};
}

View File

@@ -1,5 +1,6 @@
.logs {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
font-size: smaller;
max-height: 100vh;
overflow-x: hidden;

View File

@@ -32,7 +32,7 @@ export const FolderSelect: React.FC<IProps> = (props: IProps) => {
function onRemoveDirectory(directory: string) {
const newSelectedDirectories = selectedDirectories.filter(
dir => dir !== directory
(dir) => dir !== directory
);
setSelectedDirectories(newSelectedDirectories);
props.onDirectoriesChanged(newSelectedDirectories);
@@ -66,7 +66,7 @@ export const FolderSelect: React.FC<IProps> = (props: IProps) => {
</InputGroup.Append>
</InputGroup>
<ul className="folder-list">
{selectableDirectories.map(path => {
{selectableDirectories.map((path) => {
return (
<li key={path} className="folder-item">
<Button
@@ -96,7 +96,7 @@ export const FolderSelect: React.FC<IProps> = (props: IProps) => {
{error ? <h1>{error.message}</h1> : ""}
{renderDialog()}
<Form.Group>
{selectedDirectories.map(path => {
{selectedDirectories.map((path) => {
return (
<div key={path}>
{path}{" "}

View File

@@ -19,7 +19,7 @@ export const HoverPopover: React.FC<IHoverPopover> = ({
className,
placement = "top",
onOpen,
onClose
onClose,
}) => {
const [show, setShow] = useState(false);
const triggerRef = useRef<HTMLDivElement>(null);

View File

@@ -12,7 +12,7 @@ export const ImageInput: React.FC<IImageInput> = ({
isEditing,
text,
onImageChange,
acceptSVG = false
acceptSVG = false,
}) => {
if (!isEditing) return <div />;

View File

@@ -12,7 +12,7 @@ const CLASSNAME_MESSAGE = `${CLASSNAME}-message`;
const LoadingIndicator: React.FC<ILoadingProps> = ({
message,
inline = false
inline = false,
}) => (
<div className={cx(CLASSNAME, { inline })}>
<Spinner animation="border" role="status">

View File

@@ -25,7 +25,7 @@ const ModalComponent: React.FC<IModal> = ({
header,
cancel,
accept,
onHide
onHide,
}) => (
<Modal keyboard={false} onHide={onHide} show={show}>
<Modal.Header>

View File

@@ -1,9 +1,9 @@
import * as React from "react";
import * as GQL from "src/core/generated-graphql";
import { FilterSelect } from "./Select";
import { Button, InputGroup } from "react-bootstrap";
import { Icon } from "src/components/Shared";
import { FilterSelect } from "./Select";
type ValidTypes =
| GQL.SlimPerformerDataFragment
@@ -18,13 +18,15 @@ interface IMultiSetProps {
onSetMode: (mode: GQL.BulkUpdateIdMode) => void;
}
const MultiSet: React.FunctionComponent<IMultiSetProps> = (props: IMultiSetProps) => {
const MultiSet: React.FunctionComponent<IMultiSetProps> = (
props: IMultiSetProps
) => {
function onUpdate(items: ValidTypes[]) {
props.onUpdate(items);
}
function getModeIcon() {
switch(props.mode) {
switch (props.mode) {
case GQL.BulkUpdateIdMode.Set:
return "pencil-alt";
case GQL.BulkUpdateIdMode.Add:
@@ -35,7 +37,7 @@ const MultiSet: React.FunctionComponent<IMultiSetProps> = (props: IMultiSetProps
}
function getModeText() {
switch(props.mode) {
switch (props.mode) {
case GQL.BulkUpdateIdMode.Set:
return "Set";
case GQL.BulkUpdateIdMode.Add:
@@ -46,7 +48,7 @@ const MultiSet: React.FunctionComponent<IMultiSetProps> = (props: IMultiSetProps
}
function nextMode() {
switch(props.mode) {
switch (props.mode) {
case GQL.BulkUpdateIdMode.Set:
return GQL.BulkUpdateIdMode.Add;
case GQL.BulkUpdateIdMode.Add:

View File

@@ -57,11 +57,11 @@ interface ISceneGallerySelect {
const getSelectedValues = (selectedItems: ValueType<Option>) =>
selectedItems
? (Array.isArray(selectedItems) ? selectedItems : [selectedItems]).map(
item => item.value
(item) => item.value
)
: [];
export const SceneGallerySelect: React.FC<ISceneGallerySelect> = props => {
export const SceneGallerySelect: React.FC<ISceneGallerySelect> = (props) => {
const { data, loading } = StashService.useValidGalleriesForScene(
props.sceneId
);
@@ -69,17 +69,17 @@ export const SceneGallerySelect: React.FC<ISceneGallerySelect> = props => {
const items = (galleries.length > 0
? [{ path: "None", id: "0" }, ...galleries]
: []
).map(g => ({ label: g.path, value: g.id }));
).map((g) => ({ label: g.path, value: g.id }));
const onChange = (selectedItems: ValueType<Option>) => {
const selectedItem = getSelectedValues(selectedItems)[0];
props.onSelect(
selectedItem ? galleries.find(g => g.id === selectedItem) : undefined
selectedItem ? galleries.find((g) => g.id === selectedItem) : undefined
);
};
const selectedOptions: Option[] = props.initialId
? items.filter(item => props.initialId?.indexOf(item.value) !== -1)
? items.filter((item) => props.initialId?.indexOf(item.value) !== -1)
: [];
return (
@@ -98,7 +98,9 @@ interface IScrapePerformerSuggestProps {
onSelectPerformer: (performer: GQL.ScrapedPerformerDataFragment) => void;
placeholder?: string;
}
export const ScrapePerformerSuggest: React.FC<IScrapePerformerSuggestProps> = props => {
export const ScrapePerformerSuggest: React.FC<IScrapePerformerSuggestProps> = (
props
) => {
const [query, setQuery] = React.useState<string>("");
const { data, loading } = StashService.useScrapePerformerList(
props.scraperId,
@@ -106,9 +108,9 @@ export const ScrapePerformerSuggest: React.FC<IScrapePerformerSuggestProps> = pr
);
const performers = data?.scrapePerformerList ?? [];
const items = performers.map(item => ({
const items = performers.map((item) => ({
label: item.name ?? "",
value: item.name ?? ""
value: item.name ?? "",
}));
const onInputChange = useCallback(
@@ -119,7 +121,7 @@ export const ScrapePerformerSuggest: React.FC<IScrapePerformerSuggestProps> = pr
);
const onChange = (selectedItems: ValueType<Option>) => {
const name = getSelectedValues(selectedItems)[0];
const performer = performers.find(p => p.name === name);
const performer = performers.find((p) => p.name === name);
if (performer) props.onSelectPerformer(performer);
};
@@ -141,16 +143,16 @@ interface IMarkerSuggestProps {
initialMarkerTitle?: string;
onChange: (title: string) => void;
}
export const MarkerTitleSuggest: React.FC<IMarkerSuggestProps> = props => {
export const MarkerTitleSuggest: React.FC<IMarkerSuggestProps> = (props) => {
const { data, loading } = StashService.useMarkerStrings();
const suggestions = data?.markerStrings ?? [];
const onChange = (selectedItems: ValueType<Option>) =>
props.onChange(getSelectedValues(selectedItems)[0]);
const items = suggestions.map(item => ({
const items = suggestions.map((item) => ({
label: item?.title ?? "",
value: item?.title ?? ""
value: item?.title ?? "",
}));
const initialIds = props.initialMarkerTitle ? [props.initialMarkerTitle] : [];
return (
@@ -167,7 +169,7 @@ export const MarkerTitleSuggest: React.FC<IMarkerSuggestProps> = props => {
/>
);
};
export const FilterSelect: React.FC<IFilterProps & ITypeProps> = props =>
export const FilterSelect: React.FC<IFilterProps & ITypeProps> = (props) =>
props.type === "performers" ? (
<PerformerSelect {...(props as IFilterProps)} />
) : props.type === "studios" ? (
@@ -178,23 +180,23 @@ export const FilterSelect: React.FC<IFilterProps & ITypeProps> = props =>
<TagSelect {...(props as IFilterProps)} />
);
export const PerformerSelect: React.FC<IFilterProps> = props => {
export const PerformerSelect: React.FC<IFilterProps> = (props) => {
const { data, loading } = StashService.useAllPerformersForFilter();
const normalizedData = data?.allPerformers ?? [];
const items: Option[] = normalizedData.map(item => ({
const items: Option[] = normalizedData.map((item) => ({
value: item.id,
label: item.name ?? ""
label: item.name ?? "",
}));
const placeholder = props.noSelectionString ?? "Select performer...";
const selectedOptions: Option[] = props.ids
? items.filter(item => props.ids?.indexOf(item.value) !== -1)
? items.filter((item) => props.ids?.indexOf(item.value) !== -1)
: [];
const onChange = (selectedItems: ValueType<Option>) => {
const selectedIds = getSelectedValues(selectedItems);
props.onSelect?.(
normalizedData.filter(item => selectedIds.indexOf(item.id) !== -1)
normalizedData.filter((item) => selectedIds.indexOf(item.id) !== -1)
);
};
@@ -211,7 +213,7 @@ export const PerformerSelect: React.FC<IFilterProps> = props => {
);
};
export const StudioSelect: React.FC<IFilterProps> = props => {
export const StudioSelect: React.FC<IFilterProps> = (props) => {
const { data, loading } = StashService.useAllStudiosForFilter();
const normalizedData = data?.allStudios ?? [];
@@ -219,20 +221,20 @@ export const StudioSelect: React.FC<IFilterProps> = props => {
const items = (normalizedData.length > 0
? [{ name: "None", id: "0" }, ...normalizedData]
: []
).map(item => ({
).map((item) => ({
value: item.id,
label: item.name
label: item.name,
}));
const placeholder = props.noSelectionString ?? "Select studio...";
const selectedOptions: Option[] = props.ids
? items.filter(item => props.ids?.indexOf(item.value) !== -1)
? items.filter((item) => props.ids?.indexOf(item.value) !== -1)
: [];
const onChange = (selectedItems: ValueType<Option>) => {
const selectedIds = getSelectedValues(selectedItems);
props.onSelect?.(
normalizedData.filter(item => selectedIds.indexOf(item.id) !== -1)
normalizedData.filter((item) => selectedIds.indexOf(item.id) !== -1)
);
};
@@ -249,7 +251,7 @@ export const StudioSelect: React.FC<IFilterProps> = props => {
);
};
export const MovieSelect: React.FC<IFilterProps> = props => {
export const MovieSelect: React.FC<IFilterProps> = (props) => {
const { data, loading } = StashService.useAllMoviesForFilter();
const normalizedData = data?.allMovies ?? [];
@@ -257,20 +259,20 @@ export const MovieSelect: React.FC<IFilterProps> = props => {
const items = (normalizedData.length > 0
? [{ name: "None", id: "0" }, ...normalizedData]
: []
).map(item => ({
).map((item) => ({
value: item.id,
label: item.name
label: item.name,
}));
const placeholder = props.noSelectionString ?? "Select movie...";
const selectedOptions: Option[] = props.ids
? items.filter(item => props.ids?.indexOf(item.value) !== -1)
? items.filter((item) => props.ids?.indexOf(item.value) !== -1)
: [];
const onChange = (selectedItems: ValueType<Option>) => {
const selectedIds = getSelectedValues(selectedItems);
props.onSelect?.(
normalizedData.filter(item => selectedIds.indexOf(item.id) !== -1)
normalizedData.filter((item) => selectedIds.indexOf(item.id) !== -1)
);
};
@@ -287,7 +289,7 @@ export const MovieSelect: React.FC<IFilterProps> = props => {
);
};
export const TagSelect: React.FC<IFilterProps> = props => {
export const TagSelect: React.FC<IFilterProps> = (props) => {
const [loading, setLoading] = useState(false);
const [selectedIds, setSelectedIds] = useState<string[]>(props.ids ?? []);
const { data, loading: dataLoading } = StashService.useAllTagsForFilter();
@@ -299,25 +301,25 @@ export const TagSelect: React.FC<IFilterProps> = props => {
const tags = data?.allTags ?? [];
const selected = tags
.filter(tag => selectedTags.indexOf(tag.id) !== -1)
.map(tag => ({ value: tag.id, label: tag.name }));
const items: Option[] = tags.map(item => ({
.filter((tag) => selectedTags.indexOf(tag.id) !== -1)
.map((tag) => ({ value: tag.id, label: tag.name }));
const items: Option[] = tags.map((item) => ({
value: item.id,
label: item.name
label: item.name,
}));
const onCreate = async (tagName: string) => {
try {
setLoading(true);
const result = await createTag({
variables: { name: tagName }
variables: { name: tagName },
});
if (result?.data?.tagCreate) {
setSelectedIds([...selectedIds, result.data.tagCreate.id]);
props.onSelect?.(
[...tags, result.data.tagCreate].filter(
item => selectedIds.indexOf(item.id) !== -1
(item) => selectedIds.indexOf(item.id) !== -1
)
);
setLoading(false);
@@ -327,7 +329,7 @@ export const TagSelect: React.FC<IFilterProps> = props => {
<span>
Created tag: <b>{tagName}</b>
</span>
)
),
});
}
} catch (e) {
@@ -339,7 +341,7 @@ export const TagSelect: React.FC<IFilterProps> = props => {
const selectedValues = getSelectedValues(selectedItems);
setSelectedIds(selectedValues);
props.onSelect?.(
tags.filter(item => selectedValues.indexOf(item.id) !== -1)
tags.filter((item) => selectedValues.indexOf(item.id) !== -1)
);
};
@@ -374,35 +376,35 @@ const SelectComponent: React.FC<ISelectProps & ITypeProps> = ({
onInputChange,
placeholder,
showDropdown = true,
groupHeader
groupHeader,
}) => {
const defaultValue =
items.filter(item => initialIds?.indexOf(item.value) !== -1) ?? null;
items.filter((item) => initialIds?.indexOf(item.value) !== -1) ?? null;
const options = groupHeader
? [
{
label: groupHeader,
options: items
}
options: items,
},
]
: items;
const styles = {
option: (base: CSSProperties) => ({
...base,
color: "#000"
color: "#000",
}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
container: (base: CSSProperties, state: any) => ({
...base,
zIndex: state.isFocused ? 10 : base.zIndex
zIndex: state.isFocused ? 10 : base.zIndex,
}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
multiValueRemove: (base: CSSProperties, state: any) => ({
...base,
color: state.isFocused ? base.color : "#333333"
})
color: state.isFocused ? base.color : "#333333",
}),
};
const props = {
@@ -423,8 +425,8 @@ const SelectComponent: React.FC<ISelectProps & ITypeProps> = ({
components: {
IndicatorSeparator: () => null,
...((!showDropdown || isDisabled) && { DropdownIndicator: () => null }),
...(isDisabled && { MultiValueRemove: () => null })
}
...(isDisabled && { MultiValueRemove: () => null }),
},
};
return creatable ? (

View File

@@ -5,7 +5,7 @@ import {
PerformerDataFragment,
SceneMarkerDataFragment,
TagDataFragment,
MovieDataFragment
MovieDataFragment,
} from "src/core/generated-graphql";
import { NavUtils, TextUtils } from "src/utils";

View File

@@ -5,7 +5,7 @@ export {
FilterSelect,
PerformerSelect,
StudioSelect,
TagSelect
TagSelect,
} from "./Select";
export { default as Icon } from "./Icon";

View File

@@ -25,7 +25,7 @@
justify-content: left;
.btn {
margin-right: .5rem;
margin-right: 0.5rem;
}
.delete,
@@ -58,7 +58,7 @@
}
.folder-list {
margin-top: .5rem 0 0 0;
margin-top: 0.5rem 0 0 0;
max-height: 30vw;
overflow-x: auto;
}
@@ -69,9 +69,9 @@
}
}
.multi-set > div.input-group-prepend + div {
position: relative;
.multi-set > div.input-group-prepend + div {
flex: 1 1;
min-width: 0;
margin-bottom: 0;
min-width: 0;
position: relative;
}

View File

@@ -11,7 +11,7 @@ import { ImageUtils, TableUtils } from "src/utils";
import {
DetailsEditNavbar,
Modal,
LoadingIndicator
LoadingIndicator,
} from "src/components/Shared";
import { useToast } from "src/hooks";
import { StudioScenesPanel } from "./StudioScenesPanel";
@@ -83,7 +83,7 @@ export const Studio: React.FC = () => {
const input: Partial<GQL.StudioCreateInput | GQL.StudioUpdateInput> = {
name,
url,
image
image,
};
if (!isNew) {
@@ -155,7 +155,7 @@ export const Studio: React.FC = () => {
<div
className={cx("studio-details", {
"col ml-sm-5": !isNew,
"col-8": isNew
"col-8": isNew,
})}
>
{isNew && <h2>Add Studio</h2>}
@@ -166,13 +166,13 @@ export const Studio: React.FC = () => {
title: "Name",
value: studio.name ?? "",
isEditing: !!isEditing,
onChange: setName
onChange: setName,
})}
{TableUtils.renderInputGroup({
title: "URL",
value: url,
isEditing: !!isEditing,
onChange: setUrl
onChange: setUrl,
})}
</tbody>
</Table>

View File

@@ -12,7 +12,7 @@ export const StudioScenesPanel: React.FC<IStudioScenesPanel> = ({ studio }) => {
function filterHook(filter: ListFilterModel) {
const studioValue = { id: studio.id!, label: studio.name! };
// if studio is already present, then we modify it, otherwise add
let studioCriterion = filter.criteria.find(c => {
let studioCriterion = filter.criteria.find((c) => {
return c.type === "studios";
}) as StudiosCriterion;
@@ -23,7 +23,7 @@ export const StudioScenesPanel: React.FC<IStudioScenesPanel> = ({ studio }) => {
) {
// add the studio if not present
if (
!studioCriterion.value.find(p => {
!studioCriterion.value.find((p) => {
return p.id === studio.id;
})
) {

View File

@@ -7,7 +7,7 @@ import { StudioCard } from "./StudioCard";
export const StudioList: React.FC = () => {
const listData = useStudiosList({
renderContent
renderContent,
});
function renderContent(
@@ -19,7 +19,7 @@ export const StudioList: React.FC = () => {
if (filter.displayMode === DisplayMode.Grid) {
return (
<div className="row px-xl-5 justify-content-center">
{result.data.findStudios.studios.map(studio => (
{result.data.findStudios.studios.map((studio) => (
<StudioCard key={studio.id} studio={studio} />
))}
</div>

View File

@@ -96,7 +96,7 @@ export const TagList: React.FC = () => {
if (!data?.allTags) return <LoadingIndicator />;
if (error) return <div>{error.message}</div>;
const tagElements = data.allTags.map(tag => {
const tagElements = data.allTags.map((tag) => {
return (
<div key={tag.id} className="tag-list-row row">
<Button variant="link" onClick={() => setEditingTag(tag)}>
@@ -154,7 +154,7 @@ export const TagList: React.FC = () => {
accept={{
onClick: onEdit,
variant: "danger",
text: editingTag?.id ? "Update" : "Create"
text: editingTag?.id ? "Update" : "Create",
}}
>
<Form.Group controlId="tag-name">

View File

@@ -1,10 +1,10 @@
.tag-list {
&-row {
margin: .5rem 0;
margin: 0.5rem 0;
}
&-button {
margin: 0 .5rem;
margin: 0 0.5rem;
width: 8rem;
}
@@ -14,7 +14,7 @@
&-count {
display: inline-block;
margin: 0 .5rem;
margin: 0 0.5rem;
min-width: 6rem;
}
}

View File

@@ -24,7 +24,7 @@ export const WallItem: React.FC<IWallItemProps> = (props: IWallItemProps) => {
const [tags, setTags] = useState<JSX.Element[]>([]);
const config = StashService.useConfiguration();
const videoHoverHook = VideoHoverHook.useVideoHover({
resetOnMouseLeave: true
resetOnMouseLeave: true,
});
const showTextContainer =
config.data?.configuration.interface.wallShowTitle ?? true;
@@ -86,7 +86,7 @@ export const WallItem: React.FC<IWallItemProps> = (props: IWallItemProps) => {
props.sceneMarker.seconds
)}`
);
const thisTags = props.sceneMarker.tags.map(tag => (
const thisTags = props.sceneMarker.tags.map((tag) => (
<span key={tag.id} className="wall-tag">
{tag.name}
</span>

View File

@@ -1,23 +1,23 @@
.wall-overlay {
background-color: rgba(0, 0, 0, .8);
background-color: rgba(0, 0, 0, 0.8);
bottom: 0;
left: 0;
pointer-events: none;
position: fixed;
right: 0;
top: 0;
transition: transform .5s ease-in-out;
transition: transform 0.5s ease-in-out;
z-index: 1;
}
.visible {
opacity: 1;
transition: opacity .5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
.hidden {
opacity: 0;
transition: opacity .5s ease-in-out;
transition: opacity 0.5s ease-in-out;
}
.visible-unanimated {
@@ -52,7 +52,7 @@
justify-content: center;
max-height: 253px;
position: relative;
transition: transform .5s;
transition: transform 0.5s;
width: 100%;
}
@@ -64,7 +64,10 @@
}
.scene-wall-item-text-container {
background: linear-gradient(rgba(255, 255, 255, .25), rgba(255, 255, 255, .65));
background: linear-gradient(
rgba(255, 255, 255, 0.25),
rgba(255, 255, 255, 0.65)
);
bottom: 0;
color: #444;
font-weight: 700;

View File

@@ -41,14 +41,14 @@ export class StashService {
const wsUrl = `${wsPlatformUrl.toString().slice(0, -1)}/graphql`;
const httpLink = new HttpLink({
uri: url
uri: url,
});
const wsLink = new WebSocketLink({
uri: wsUrl,
options: {
reconnect: true
}
reconnect: true,
},
});
const link = split(
@@ -66,7 +66,7 @@ export class StashService {
StashService.cache = new InMemoryCache();
StashService.client = new ApolloClient({
link,
cache: StashService.cache
cache: StashService.cache,
});
return StashService.client;
@@ -77,14 +77,14 @@ export class StashService {
if (StashService.cache) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const cache = StashService.cache as any;
const keyMatchers = queries.map(query => {
const keyMatchers = queries.map((query) => {
return new RegExp(`^${query}`);
});
const rootQuery = cache.data.data.ROOT_QUERY;
Object.keys(rootQuery).forEach(key => {
Object.keys(rootQuery).forEach((key) => {
if (
keyMatchers.some(matcher => {
keyMatchers.some((matcher) => {
return !!key.match(matcher);
})
) {
@@ -97,8 +97,8 @@ export class StashService {
public static useFindGalleries(filter: ListFilterModel) {
return GQL.useFindGalleriesQuery({
variables: {
filter: filter.makeFindFilter()
}
filter: filter.makeFindFilter(),
},
});
}
@@ -116,8 +116,8 @@ export class StashService {
return GQL.useFindScenesQuery({
variables: {
filter: filter.makeFindFilter(),
scene_filter: sceneFilter
}
scene_filter: sceneFilter,
},
});
}
@@ -129,8 +129,8 @@ export class StashService {
query: GQL.FindScenesDocument,
variables: {
filter: filter.makeFindFilter(),
scene_filter: sceneFilter
}
scene_filter: sceneFilter,
},
});
}
@@ -148,8 +148,8 @@ export class StashService {
return GQL.useFindSceneMarkersQuery({
variables: {
filter: filter.makeFindFilter(),
scene_marker_filter: sceneMarkerFilter
}
scene_marker_filter: sceneMarkerFilter,
},
});
}
@@ -161,24 +161,24 @@ export class StashService {
query: GQL.FindSceneMarkersDocument,
variables: {
filter: filter.makeFindFilter(),
scene_marker_filter: sceneMarkerFilter
}
scene_marker_filter: sceneMarkerFilter,
},
});
}
public static useFindStudios(filter: ListFilterModel) {
return GQL.useFindStudiosQuery({
variables: {
filter: filter.makeFindFilter()
}
filter: filter.makeFindFilter(),
},
});
}
public static useFindMovies(filter: ListFilterModel) {
return GQL.useFindMoviesQuery({
variables: {
filter: filter.makeFindFilter()
}
filter: filter.makeFindFilter(),
},
});
}
@@ -196,8 +196,8 @@ export class StashService {
return GQL.useFindPerformersQuery({
variables: {
filter: filter.makeFindFilter(),
performer_filter: performerFilter
}
performer_filter: performerFilter,
},
});
}
@@ -209,8 +209,8 @@ export class StashService {
query: GQL.FindPerformersDocument,
variables: {
filter: filter.makeFindFilter(),
performer_filter: performerFilter
}
performer_filter: performerFilter,
},
});
}
@@ -238,7 +238,7 @@ export class StashService {
"findSceneMarkers",
"findScenes",
"markerStrings",
"sceneMarkerTags"
"sceneMarkerTags",
];
public static useSceneMarkerCreate() {
@@ -257,7 +257,7 @@ export class StashService {
public static useScrapePerformerList(scraperId: string, q: string) {
return GQL.useScrapePerformerListQuery({
variables: { scraper_id: scraperId, query: q },
skip: q === ""
skip: q === "",
});
}
public static useScrapePerformer(
@@ -265,7 +265,7 @@ export class StashService {
scrapedPerformer: GQL.ScrapedPerformerInput
) {
return GQL.useScrapePerformerQuery({
variables: { scraper_id: scraperId, scraped_performer: scrapedPerformer }
variables: { scraper_id: scraperId, scraped_performer: scrapedPerformer },
});
}
@@ -296,7 +296,7 @@ export class StashService {
}
public static useValidGalleriesForScene(sceneId: string) {
return GQL.useValidGalleriesForSceneQuery({
variables: { scene_id: sceneId }
variables: { scene_id: sceneId },
});
}
public static useStats() {
@@ -308,7 +308,7 @@ export class StashService {
public static useLatestVersion() {
return GQL.useLatestVersionQuery({
notifyOnNetworkStatusChange: true,
errorPolicy: "ignore"
errorPolicy: "ignore",
});
}
@@ -323,7 +323,7 @@ export class StashService {
"findPerformers",
"findScenes",
"findSceneMarkers",
"allPerformers"
"allPerformers",
];
public static usePerformerCreate() {
@@ -331,7 +331,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.performerMutationImpactedQueries
)
),
});
}
public static usePerformerUpdate() {
@@ -339,7 +339,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.performerMutationImpactedQueries
)
),
});
}
public static usePerformerDestroy() {
@@ -347,7 +347,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.performerMutationImpactedQueries
)
),
});
}
@@ -357,7 +357,7 @@ export class StashService {
"findSceneMarkers",
"findStudios",
"findMovies",
"allTags"
"allTags",
// TODO - add "findTags" when it is implemented
];
@@ -368,7 +368,7 @@ export class StashService {
StashService.invalidateQueries(
StashService.sceneMutationImpactedQueries
),
refetchQueries: ["AllTagsForFilter"]
refetchQueries: ["AllTagsForFilter"],
});
}
@@ -379,7 +379,7 @@ export class StashService {
"findSceneMarkers",
"findStudios",
"findMovies",
"allTags"
"allTags",
];
public static useBulkSceneUpdate(input: GQL.BulkSceneUpdateInput) {
@@ -388,7 +388,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.sceneBulkMutationImpactedQueries
)
),
});
}
@@ -398,19 +398,19 @@ export class StashService {
public static useSceneIncrementO(id: string) {
return GQL.useSceneIncrementOMutation({
variables: { id }
variables: { id },
});
}
public static useSceneDecrementO(id: string) {
return GQL.useSceneDecrementOMutation({
variables: { id }
variables: { id },
});
}
public static useSceneResetO(id: string) {
return GQL.useSceneResetOMutation({
variables: { id }
variables: { id },
});
}
@@ -420,20 +420,20 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.sceneMutationImpactedQueries
)
),
});
}
public static useSceneGenerateScreenshot() {
return GQL.useSceneGenerateScreenshotMutation({
update: () => StashService.invalidateQueries(["findScenes"])
update: () => StashService.invalidateQueries(["findScenes"]),
});
}
private static studioMutationImpactedQueries = [
"findStudios",
"findScenes",
"allStudios"
"allStudios",
];
public static useStudioCreate(input: GQL.StudioCreateInput) {
@@ -442,7 +442,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.studioMutationImpactedQueries
)
),
});
}
@@ -452,7 +452,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.studioMutationImpactedQueries
)
),
});
}
@@ -462,14 +462,14 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.studioMutationImpactedQueries
)
),
});
}
private static movieMutationImpactedQueries = [
"findMovies",
"findScenes",
"allMovies"
"allMovies",
];
public static useMovieCreate(input: GQL.MovieCreateInput) {
@@ -478,7 +478,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.movieMutationImpactedQueries
)
),
});
}
@@ -488,7 +488,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.movieMutationImpactedQueries
)
),
});
}
@@ -498,7 +498,7 @@ export class StashService {
update: () =>
StashService.invalidateQueries(
StashService.movieMutationImpactedQueries
)
),
});
}
@@ -506,20 +506,20 @@ export class StashService {
"findScenes",
"findSceneMarkers",
"sceneMarkerTags",
"allTags"
"allTags",
];
public static useTagCreate(input: GQL.TagCreateInput) {
return GQL.useTagCreateMutation({
variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"]
refetchQueries: ["AllTags", "AllTagsForFilter"],
// update: () => StashService.invalidateQueries(StashService.tagMutationImpactedQueries)
});
}
public static useTagUpdate(input: GQL.TagUpdateInput) {
return GQL.useTagUpdateMutation({
variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"]
refetchQueries: ["AllTags", "AllTagsForFilter"],
});
}
public static useTagDestroy(input: GQL.TagDestroyInput) {
@@ -527,21 +527,21 @@ export class StashService {
variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"],
update: () =>
StashService.invalidateQueries(StashService.tagMutationImpactedQueries)
StashService.invalidateQueries(StashService.tagMutationImpactedQueries),
});
}
public static useConfigureGeneral(input: GQL.ConfigGeneralInput) {
return GQL.useConfigureGeneralMutation({
variables: { input },
refetchQueries: ["Configuration"]
refetchQueries: ["Configuration"],
});
}
public static useConfigureInterface(input: GQL.ConfigInterfaceInput) {
return GQL.useConfigureInterfaceMutation({
variables: { input },
refetchQueries: ["Configuration"]
refetchQueries: ["Configuration"],
});
}
@@ -555,19 +555,19 @@ export class StashService {
public static useLogs() {
return GQL.useLogsQuery({
fetchPolicy: "no-cache"
fetchPolicy: "no-cache",
});
}
public static useJobStatus() {
return GQL.useJobStatusQuery({
fetchPolicy: "no-cache"
fetchPolicy: "no-cache",
});
}
public static mutateStopJob() {
return StashService.client.mutate<GQL.StopJobMutation>({
mutation: GQL.StopJobDocument
mutation: GQL.StopJobDocument,
});
}
@@ -575,8 +575,8 @@ export class StashService {
return StashService.client.query<GQL.ScrapeFreeonesQuery>({
query: GQL.ScrapeFreeonesDocument,
variables: {
performer_name: performerName
}
performer_name: performerName,
},
});
}
@@ -588,8 +588,8 @@ export class StashService {
query: GQL.ScrapePerformerDocument,
variables: {
scraper_id: scraperId,
scraped_performer: scrapedPerformer
}
scraped_performer: scrapedPerformer,
},
});
}
@@ -597,8 +597,8 @@ export class StashService {
return StashService.client.query<GQL.ScrapePerformerUrlQuery>({
query: GQL.ScrapePerformerUrlDocument,
variables: {
url
}
url,
},
});
}
@@ -606,8 +606,8 @@ export class StashService {
return StashService.client.query<GQL.ScrapeSceneUrlQuery>({
query: GQL.ScrapeSceneUrlDocument,
variables: {
url
}
url,
},
});
}
@@ -619,54 +619,54 @@ export class StashService {
query: GQL.ScrapeSceneDocument,
variables: {
scraper_id: scraperId,
scene
}
scene,
},
});
}
public static mutateMetadataScan(input: GQL.ScanMetadataInput) {
return StashService.client.mutate<GQL.MetadataScanMutation>({
mutation: GQL.MetadataScanDocument,
variables: { input }
variables: { input },
});
}
public static mutateMetadataAutoTag(input: GQL.AutoTagMetadataInput) {
return StashService.client.mutate<GQL.MetadataAutoTagMutation>({
mutation: GQL.MetadataAutoTagDocument,
variables: { input }
variables: { input },
});
}
public static mutateMetadataGenerate(input: GQL.GenerateMetadataInput) {
return StashService.client.mutate<GQL.MetadataGenerateMutation>({
mutation: GQL.MetadataGenerateDocument,
variables: { input }
variables: { input },
});
}
public static mutateMetadataClean() {
return StashService.client.mutate<GQL.MetadataCleanMutation>({
mutation: GQL.MetadataCleanDocument
mutation: GQL.MetadataCleanDocument,
});
}
public static mutateMetadataExport() {
return StashService.client.mutate<GQL.MetadataExportMutation>({
mutation: GQL.MetadataExportDocument
mutation: GQL.MetadataExportDocument,
});
}
public static mutateMetadataImport() {
return StashService.client.mutate<GQL.MetadataImportMutation>({
mutation: GQL.MetadataImportDocument
mutation: GQL.MetadataImportDocument,
});
}
public static querySceneByPathRegex(filter: GQL.FindFilterType) {
return StashService.client.query<GQL.FindScenesByPathRegexQuery>({
query: GQL.FindScenesByPathRegexDocument,
variables: { filter }
variables: { filter },
});
}
@@ -677,26 +677,28 @@ export class StashService {
return StashService.client.query<GQL.ParseSceneFilenamesQuery>({
query: GQL.ParseSceneFilenamesDocument,
variables: { filter, config },
fetchPolicy: "network-only"
fetchPolicy: "network-only",
});
}
private static stringGenderMap = new Map<string, GQL.GenderEnum>(
[["Male", GQL.GenderEnum.Male],
private static stringGenderMap = new Map<string, GQL.GenderEnum>([
["Male", GQL.GenderEnum.Male],
["Female", GQL.GenderEnum.Female],
["Transgender Male", GQL.GenderEnum.TransgenderMale],
["Transgender Female", GQL.GenderEnum.TransgenderFemale],
["Intersex", GQL.GenderEnum.Intersex]]
);
["Intersex", GQL.GenderEnum.Intersex],
]);
public static genderToString(value?: GQL.GenderEnum) {
if (!value) {
return undefined;
}
const foundEntry = Array.from(StashService.stringGenderMap.entries()).find((e) => {
return e[1] === value;
});
const foundEntry = Array.from(StashService.stringGenderMap.entries()).find(
(e) => {
return e[1] === value;
}
);
if (foundEntry) {
return foundEntry[0];

View File

@@ -16,11 +16,11 @@ import {
FindStudiosQueryResult,
FindPerformersQueryResult,
FindMoviesQueryResult,
MovieDataFragment
MovieDataFragment,
} from "src/core/generated-graphql";
import {
useInterfaceLocalForage,
IInterfaceConfig
IInterfaceConfig,
} from "src/hooks/LocalForage";
import { LoadingIndicator } from "src/components/Shared";
import { ListFilter } from "src/components/List/ListFilter";
@@ -100,14 +100,14 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
const updateInterfaceConfig = useCallback(
(updatedFilter: ListFilterModel) => {
setInterfaceState(config => {
setInterfaceState((config) => {
const data = { ...config } as IInterfaceConfig;
data.queries = {
[options.filterMode]: {
filter: updatedFilter.makeQueryParameters(),
itemsPerPage: updatedFilter.itemsPerPage,
currentPage: updatedFilter.currentPage
}
currentPage: updatedFilter.currentPage,
},
};
return data;
});
@@ -133,7 +133,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
sortdir: storedFilter.sortdir,
disp: storedFilter.disp,
perPage: storedFilter.perPage,
...queryFilter
...queryFilter,
}
: storedFilter;
@@ -161,7 +161,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
options.subComponent,
options.filterMode,
forageInitialised,
updateInterfaceConfig
updateInterfaceConfig,
]);
function getFilter() {
@@ -221,7 +221,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
const newFilter = _.cloneDeep(filter);
// Find if we are editing an existing criteria, then modify that. Or create a new one.
const existingIndex = newFilter.criteria.findIndex(c => {
const existingIndex = newFilter.criteria.findIndex((c) => {
// If we modified an existing criterion, then look for the old id.
const id = oldId || criterion.getId();
return c.getId() === id;
@@ -234,7 +234,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
// Remove duplicate modifiers
newFilter.criteria = newFilter.criteria.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj.getId()).indexOf(obj.getId()) === pos;
return arr.map((mapObj) => mapObj.getId()).indexOf(obj.getId()) === pos;
});
newFilter.currentPage = 1;
@@ -244,7 +244,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
function onRemoveCriterion(removedCriterion: Criterion) {
const newFilter = _.cloneDeep(filter);
newFilter.criteria = newFilter.criteria.filter(
criterion => criterion.getId() !== removedCriterion.getId()
(criterion) => criterion.getId() !== removedCriterion.getId()
);
newFilter.currentPage = 1;
updateQueryParams(newFilter);
@@ -281,7 +281,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
const subset = items.slice(start, end + 1);
const newSelectedIds: Set<string> = new Set();
subset.forEach(item => {
subset.forEach((item) => {
newSelectedIds.add(item.id);
});
@@ -293,12 +293,12 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
let thisIndex = -1;
if (lastClickedId) {
startIndex = items.findIndex(item => {
startIndex = items.findIndex((item) => {
return item.id === lastClickedId;
});
}
thisIndex = items.findIndex(item => {
thisIndex = items.findIndex((item) => {
return item.id === id;
});
@@ -315,7 +315,7 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
function onSelectAll() {
const newSelectedIds: Set<string> = new Set();
items.forEach(item => {
items.forEach((item) => {
newSelectedIds.add(item.id);
});
@@ -334,12 +334,12 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
}
const otherOperations = options.otherOperations
? options.otherOperations.map(o => {
? options.otherOperations.map((o) => {
return {
text: o.text,
onClick: () => {
o.onClick(result, filter, selectedIds);
}
},
};
})
: undefined;
@@ -401,7 +401,7 @@ export const useScenesList = (props: IListHookOptions<FindScenesQueryResult>) =>
getData: (result: FindScenesQueryResult) =>
result?.data?.findScenes?.scenes ?? [],
getCount: (result: FindScenesQueryResult) =>
result?.data?.findScenes?.count ?? 0
result?.data?.findScenes?.count ?? 0,
});
export const useSceneMarkersList = (
@@ -414,7 +414,7 @@ export const useSceneMarkersList = (
getData: (result: FindSceneMarkersQueryResult) =>
result?.data?.findSceneMarkers?.scene_markers ?? [],
getCount: (result: FindSceneMarkersQueryResult) =>
result?.data?.findSceneMarkers?.count ?? 0
result?.data?.findSceneMarkers?.count ?? 0,
});
export const useGalleriesList = (
@@ -427,7 +427,7 @@ export const useGalleriesList = (
getData: (result: FindGalleriesQueryResult) =>
result?.data?.findGalleries?.galleries ?? [],
getCount: (result: FindGalleriesQueryResult) =>
result?.data?.findGalleries?.count ?? 0
result?.data?.findGalleries?.count ?? 0,
});
export const useStudiosList = (
@@ -440,7 +440,7 @@ export const useStudiosList = (
getData: (result: FindStudiosQueryResult) =>
result?.data?.findStudios?.studios ?? [],
getCount: (result: FindStudiosQueryResult) =>
result?.data?.findStudios?.count ?? 0
result?.data?.findStudios?.count ?? 0,
});
export const usePerformersList = (
@@ -453,7 +453,7 @@ export const usePerformersList = (
getData: (result: FindPerformersQueryResult) =>
result?.data?.findPerformers?.performers ?? [],
getCount: (result: FindPerformersQueryResult) =>
result?.data?.findPerformers?.count ?? 0
result?.data?.findPerformers?.count ?? 0,
});
export const useMoviesList = (props: IListHookOptions<FindMoviesQueryResult>) =>
@@ -464,5 +464,5 @@ export const useMoviesList = (props: IListHookOptions<FindMoviesQueryResult>) =>
getData: (result: FindMoviesQueryResult) =>
result?.data?.findMovies?.movies ?? [],
getCount: (result: FindMoviesQueryResult) =>
result?.data?.findMovies?.count ?? 0
result?.data?.findMovies?.count ?? 0,
});

View File

@@ -18,9 +18,9 @@ export const ToastProvider: React.FC = ({ children }) => {
const [toasts, setToasts] = useState<IActiveToast[]>([]);
const removeToast = (id: number) =>
setToasts(toasts.filter(item => item.id !== id));
setToasts(toasts.filter((item) => item.id !== id));
const toastItems = toasts.map(toast => (
const toastItems = toasts.map((toast) => (
<Toast
autohide
key={toast.id}
@@ -55,9 +55,9 @@ function createHookObject(toastFunc: (toast: IToast) => void) {
toastFunc({
variant: "danger",
header: "Error",
content: error.message ?? error.toString()
content: error.message ?? error.toString(),
});
}
},
};
}

View File

@@ -64,7 +64,7 @@ export class VideoHoverHook {
return;
}
if (videoTag.paused && !data.isPlaying.current) {
videoTag.play().catch(error => {
videoTag.play().catch((error) => {
console.log(error.message);
});
}

View File

@@ -6,5 +6,5 @@ export {
useSceneMarkersList,
useGalleriesList,
useStudiosList,
usePerformersList
usePerformersList,
} from "./ListHook";

View File

@@ -32,18 +32,23 @@ a {
code,
.code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
.input-control,
.text-input {
border: 0;
box-shadow: 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, .3), inset 0 1px 1px rgba(16, 22, 26, .4);
box-shadow: 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0),
0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3),
inset 0 1px 1px rgba(16, 22, 26, 0.4);
color: $text-color;
&:focus {
border: 0;
box-shadow: 0 0 0 1px $primary, 0 0 0 1px $primary, 0 0 0 3px rgba(19, 124, 189, .3), inset 0 0 0 1px rgba(16, 22, 26, .3), inset 0 1px 1px rgba(16, 22, 26, .4);
box-shadow: 0 0 0 1px $primary, 0 0 0 1px $primary,
0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3),
inset 0 1px 1px rgba(16, 22, 26, 0.4);
color: $text-color;
}
}
@@ -207,7 +212,7 @@ div.react-select__menu {
}
.react-select__option--is-focused {
background-color: rgba(167, 182, 194, .3);
background-color: rgba(167, 182, 194, 0.3);
}
}
}
@@ -251,8 +256,8 @@ div.react-select__menu {
color: $dark-text;
font-size: 12px;
line-height: 1rem;
margin-left: .5rem;
opacity: .5;
margin-left: 0.5rem;
opacity: 0.5;
padding: 0;
position: relative;
@@ -308,7 +313,7 @@ div.react-select__menu {
.rating-banner {
color: #fff;
display: block;
font-size: .86rem;
font-size: 0.86rem;
font-weight: 400;
left: -46px;
letter-spacing: 1px;
@@ -324,7 +329,8 @@ div.react-select__menu {
.card {
background-color: #30404d;
border-radius: 3px;
box-shadow: 0 0 0 1px rgba(16, 22, 26, .4), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0);
box-shadow: 0 0 0 1px rgba(16, 22, 26, 0.4), 0 0 0 rgba(16, 22, 26, 0),
0 0 0 rgba(16, 22, 26, 0);
padding: 20px;
}
@@ -368,12 +374,13 @@ div.react-select__menu {
overflow: hidden;
position: relative;
input[type=file], /* FF, IE7+, chrome (except button) */
input[type=file]::-webkit-file-upload-button { /* chromes and blink button */
input[type="file"], /* FF, IE7+, chrome (except button) */
input[type="file"]::-webkit-file-upload-button {
/* chromes and blink button */
cursor: pointer;
}
[type=file] {
[type="file"] {
display: block;
filter: alpha(opacity=0);
font-size: 999px;
@@ -388,7 +395,7 @@ div.react-select__menu {
}
.fa-icon {
margin: 0 .4rem;
margin: 0 0.4rem;
}
.btn .fa-icon {
@@ -406,7 +413,7 @@ div.react-select__menu {
}
.top-nav {
padding: .25rem 1rem;
padding: 0.25rem 1rem;
.nav-link {
padding: 0;
@@ -439,7 +446,7 @@ div.react-select__menu {
.stats {
&-element {
flex-grow: 1;
margin: auto .5rem;
margin: auto 0.5rem;
}
.title {

View File

@@ -3,5 +3,5 @@ import de from "./de.json";
export default {
en,
de
de,
};

View File

@@ -129,7 +129,7 @@ export abstract class Criterion {
public getLabelValue(): string {
if (typeof this.value === "string") return this.value;
if (typeof this.value === "number") return this.value.toString();
return this.value.map(v => v.label).join(", ");
return this.value.map((v) => v.label).join(", ");
}
public getLabel(): string {
@@ -221,7 +221,7 @@ export class StringCriterion extends Criterion {
Criterion.getModifierOption(CriterionModifier.Equals),
Criterion.getModifierOption(CriterionModifier.NotEquals),
Criterion.getModifierOption(CriterionModifier.IsNull),
Criterion.getModifierOption(CriterionModifier.NotNull)
Criterion.getModifierOption(CriterionModifier.NotNull),
];
public options: string[] | undefined;
public value: string = "";
@@ -255,7 +255,7 @@ export class NumberCriterion extends Criterion {
Criterion.getModifierOption(CriterionModifier.GreaterThan),
Criterion.getModifierOption(CriterionModifier.LessThan),
Criterion.getModifierOption(CriterionModifier.IsNull),
Criterion.getModifierOption(CriterionModifier.NotNull)
Criterion.getModifierOption(CriterionModifier.NotNull),
];
public options: number[] | undefined;
public value: number = 0;
@@ -287,7 +287,7 @@ export class DurationCriterion extends Criterion {
Criterion.getModifierOption(CriterionModifier.Equals),
Criterion.getModifierOption(CriterionModifier.NotEquals),
Criterion.getModifierOption(CriterionModifier.GreaterThan),
Criterion.getModifierOption(CriterionModifier.LessThan)
Criterion.getModifierOption(CriterionModifier.LessThan),
];
public options: number[] | undefined;
public value: number = 0;

View File

@@ -1,10 +1,6 @@
import { CriterionModifier } from "src/core/generated-graphql";
import { StashService } from "src/core/StashService";
import {
Criterion,
CriterionType,
ICriterionOption,
} from "./criterion";
import { Criterion, CriterionType, ICriterionOption } from "./criterion";
export class GenderCriterion extends Criterion {
public type: CriterionType = "gender";

View File

@@ -13,7 +13,7 @@ export class IsMissingCriterion extends Criterion {
"gallery",
"studio",
"movie",
"performers"
"performers",
];
public value: string = "";
}

View File

@@ -14,13 +14,13 @@ export class MoviesCriterion extends Criterion {
public modifier = CriterionModifier.Includes;
public modifierOptions = [
Criterion.getModifierOption(CriterionModifier.Includes),
Criterion.getModifierOption(CriterionModifier.Excludes)
Criterion.getModifierOption(CriterionModifier.Excludes),
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map(o => {
return this.value.map((o) => {
return encodeILabeledId(o);
});
}

View File

@@ -9,13 +9,13 @@ export class PerformersCriterion extends Criterion {
public modifierOptions = [
Criterion.getModifierOption(CriterionModifier.IncludesAll),
Criterion.getModifierOption(CriterionModifier.Includes),
Criterion.getModifierOption(CriterionModifier.Excludes)
Criterion.getModifierOption(CriterionModifier.Excludes),
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map(o => {
return this.value.map((o) => {
return encodeILabeledId(o);
});
}

View File

@@ -11,7 +11,7 @@ export class RatingCriterion extends Criterion {
Criterion.getModifierOption(CriterionModifier.GreaterThan),
Criterion.getModifierOption(CriterionModifier.LessThan),
Criterion.getModifierOption(CriterionModifier.IsNull),
Criterion.getModifierOption(CriterionModifier.NotNull)
Criterion.getModifierOption(CriterionModifier.NotNull),
];
public options: number[] = [1, 2, 3, 4, 5];
public value: number = 0;

View File

@@ -8,13 +8,13 @@ export class StudiosCriterion extends Criterion {
public modifier = CriterionModifier.Includes;
public modifierOptions = [
Criterion.getModifierOption(CriterionModifier.Includes),
Criterion.getModifierOption(CriterionModifier.Excludes)
Criterion.getModifierOption(CriterionModifier.Excludes),
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map(o => {
return this.value.map((o) => {
return encodeILabeledId(o);
});
}

View File

@@ -9,7 +9,7 @@ export class TagsCriterion extends Criterion {
public modifierOptions = [
Criterion.getModifierOption(GQL.CriterionModifier.IncludesAll),
Criterion.getModifierOption(GQL.CriterionModifier.Includes),
Criterion.getModifierOption(GQL.CriterionModifier.Excludes)
Criterion.getModifierOption(GQL.CriterionModifier.Excludes),
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
@@ -24,7 +24,7 @@ export class TagsCriterion extends Criterion {
}
public encodeValue() {
return this.value.map(o => {
return this.value.map((o) => {
return encodeILabeledId(o);
});
}

View File

@@ -5,7 +5,7 @@ import {
CriterionType,
StringCriterion,
NumberCriterion,
DurationCriterion
DurationCriterion,
} from "./criterion";
import { FavoriteCriterion } from "./favorite";
import { HasMarkersCriterion } from "./has-markers";
@@ -57,7 +57,7 @@ export function makeCriteria(type: CriterionType = "none") {
Criterion.getModifierOption(CriterionModifier.Equals),
Criterion.getModifierOption(CriterionModifier.NotEquals),
Criterion.getModifierOption(CriterionModifier.GreaterThan),
Criterion.getModifierOption(CriterionModifier.LessThan)
Criterion.getModifierOption(CriterionModifier.LessThan),
];
return ret;
}

View File

@@ -5,8 +5,9 @@ import {
ResolutionEnum,
SceneFilterType,
SceneMarkerFilterType,
SortDirectionEnum
SortDirectionEnum,
} from "src/core/generated-graphql";
import { StashService } from "src/core/StashService";
import {
Criterion,
ICriterionOption,
@@ -14,40 +15,39 @@ import {
CriterionOption,
NumberCriterion,
StringCriterion,
DurationCriterion
DurationCriterion,
} from "./criteria/criterion";
import {
FavoriteCriterion,
FavoriteCriterionOption
FavoriteCriterionOption,
} from "./criteria/favorite";
import {
HasMarkersCriterion,
HasMarkersCriterionOption
HasMarkersCriterionOption,
} from "./criteria/has-markers";
import {
IsMissingCriterion,
IsMissingCriterionOption
IsMissingCriterionOption,
} from "./criteria/is-missing";
import { NoneCriterionOption } from "./criteria/none";
import {
PerformersCriterion,
PerformersCriterionOption
PerformersCriterionOption,
} from "./criteria/performers";
import { RatingCriterion, RatingCriterionOption } from "./criteria/rating";
import {
ResolutionCriterion,
ResolutionCriterionOption
ResolutionCriterionOption,
} from "./criteria/resolution";
import { StudiosCriterion, StudiosCriterionOption } from "./criteria/studios";
import {
SceneTagsCriterionOption,
TagsCriterion,
TagsCriterionOption
TagsCriterionOption,
} from "./criteria/tags";
import { makeCriteria } from "./criteria/utils";
import { DisplayMode, FilterMode } from "./types";
import { GenderCriterionOption, GenderCriterion } from "./criteria/gender";
import { StashService } from "src/core/StashService";
import { MoviesCriterionOption, MoviesCriterion } from "./criteria/movies";
interface IQueryParameters {
@@ -64,7 +64,7 @@ const DEFAULT_PARAMS = {
sortDirection: SortDirectionEnum.Asc,
displayMode: DisplayMode.Grid,
currentPage: 1,
itemsPerPage: 40
itemsPerPage: 40,
};
// TODO: handle customCriteria
@@ -101,12 +101,12 @@ export class ListFilterModel {
"duration",
"framerate",
"bitrate",
"random"
"random",
];
this.displayModeOptions = [
DisplayMode.Grid,
DisplayMode.List,
DisplayMode.Wall
DisplayMode.Wall,
];
this.criterionOptions = [
new NoneCriterionOption(),
@@ -119,7 +119,7 @@ export class ListFilterModel {
new TagsCriterionOption(),
new PerformersCriterionOption(),
new StudiosCriterionOption(),
new MoviesCriterionOption()
new MoviesCriterionOption(),
];
break;
case FilterMode.Performers: {
@@ -138,7 +138,7 @@ export class ListFilterModel {
"career_length",
"tattoos",
"piercings",
"aliases"
"aliases",
];
this.criterionOptions = [
@@ -148,7 +148,7 @@ export class ListFilterModel {
];
this.criterionOptions = this.criterionOptions.concat(
numberCriteria.concat(stringCriteria).map(c => {
numberCriteria.concat(stringCriteria).map((c) => {
return ListFilterModel.createCriterionOption(c);
})
);
@@ -179,14 +179,14 @@ export class ListFilterModel {
"seconds",
"scene_id",
"random",
"scenes_updated_at"
"scenes_updated_at",
];
this.displayModeOptions = [DisplayMode.Wall];
this.criterionOptions = [
new NoneCriterionOption(),
new TagsCriterionOption(),
new SceneTagsCriterionOption(),
new PerformersCriterionOption()
new PerformersCriterionOption(),
];
break;
default:
@@ -244,7 +244,7 @@ export class ListFilterModel {
jsonParameters = [params.c];
}
jsonParameters.forEach(jsonString => {
jsonParameters.forEach((jsonString) => {
const encodedCriterion = JSON.parse(jsonString);
const criterion = makeCriteria(encodedCriterion.type);
// it's possible that we have unsupported criteria. Just skip if so.
@@ -281,7 +281,7 @@ export class ListFilterModel {
public makeQueryParameters(): string {
const encodedCriteria: string[] = [];
this.criteria.forEach(criterion => {
this.criteria.forEach((criterion) => {
const encodedCriterion: Partial<Criterion> = {
type: criterion.type,
// #394 - the presence of a # symbol results in the query URL being
@@ -289,7 +289,7 @@ export class ListFilterModel {
// call below, but this results in a URL that gets pretty long and ugly.
// Instead, we'll encode the criteria values.
value: criterion.encodeValue(),
modifier: criterion.modifier
modifier: criterion.modifier,
};
const jsonCriterion = JSON.stringify(encodedCriterion);
encodedCriteria.push(jsonCriterion);
@@ -312,7 +312,7 @@ export class ListFilterModel {
this.currentPage !== DEFAULT_PARAMS.currentPage
? this.currentPage
: undefined,
c: encodedCriteria
c: encodedCriteria,
};
return queryString.stringify(result, { encode: false });
}
@@ -325,19 +325,19 @@ export class ListFilterModel {
page: this.currentPage,
per_page: this.itemsPerPage,
sort: this.getSortBy(),
direction: this.sortDirection
direction: this.sortDirection,
};
}
public makeSceneFilter(): SceneFilterType {
const result: SceneFilterType = {};
this.criteria.forEach(criterion => {
this.criteria.forEach((criterion) => {
switch (criterion.type) {
case "rating": {
const ratingCrit = criterion as RatingCriterion;
result.rating = {
value: ratingCrit.value,
modifier: ratingCrit.modifier
modifier: ratingCrit.modifier,
};
break;
}
@@ -345,7 +345,7 @@ export class ListFilterModel {
const oCounterCrit = criterion as NumberCriterion;
result.o_counter = {
value: oCounterCrit.value,
modifier: oCounterCrit.modifier
modifier: oCounterCrit.modifier,
};
break;
}
@@ -374,7 +374,7 @@ export class ListFilterModel {
const durationCrit = criterion as DurationCriterion;
result.duration = {
value: durationCrit.value,
modifier: durationCrit.modifier
modifier: durationCrit.modifier,
};
break;
}
@@ -387,32 +387,32 @@ export class ListFilterModel {
case "tags": {
const tagsCrit = criterion as TagsCriterion;
result.tags = {
value: tagsCrit.value.map(tag => tag.id),
modifier: tagsCrit.modifier
value: tagsCrit.value.map((tag) => tag.id),
modifier: tagsCrit.modifier,
};
break;
}
case "performers": {
const perfCrit = criterion as PerformersCriterion;
result.performers = {
value: perfCrit.value.map(perf => perf.id),
modifier: perfCrit.modifier
value: perfCrit.value.map((perf) => perf.id),
modifier: perfCrit.modifier,
};
break;
}
case "studios": {
const studCrit = criterion as StudiosCriterion;
result.studios = {
value: studCrit.value.map(studio => studio.id),
modifier: studCrit.modifier
value: studCrit.value.map((studio) => studio.id),
modifier: studCrit.modifier,
};
break;
}
case "movies": {
const movCrit = criterion as MoviesCriterion;
result.movies = {
value: movCrit.value.map(movie => movie.id),
modifier: movCrit.modifier
value: movCrit.value.map((movie) => movie.id),
modifier: movCrit.modifier,
};
break;
}
@@ -424,7 +424,7 @@ export class ListFilterModel {
public makePerformerFilter(): PerformerFilterType {
const result: PerformerFilterType = {};
this.criteria.forEach(criterion => {
this.criteria.forEach((criterion) => {
switch (criterion.type) {
case "favorite":
result.filter_favorites =
@@ -434,7 +434,7 @@ export class ListFilterModel {
const byCrit = criterion as NumberCriterion;
result.birth_year = {
value: byCrit.value,
modifier: byCrit.modifier
modifier: byCrit.modifier,
};
break;
}
@@ -447,7 +447,7 @@ export class ListFilterModel {
const ethCrit = criterion as StringCriterion;
result.ethnicity = {
value: ethCrit.value,
modifier: ethCrit.modifier
modifier: ethCrit.modifier,
};
break;
}
@@ -455,7 +455,7 @@ export class ListFilterModel {
const cntryCrit = criterion as StringCriterion;
result.country = {
value: cntryCrit.value,
modifier: cntryCrit.modifier
modifier: cntryCrit.modifier,
};
break;
}
@@ -473,7 +473,7 @@ export class ListFilterModel {
const mCrit = criterion as StringCriterion;
result.measurements = {
value: mCrit.value,
modifier: mCrit.modifier
modifier: mCrit.modifier,
};
break;
}
@@ -486,7 +486,7 @@ export class ListFilterModel {
const clCrit = criterion as StringCriterion;
result.career_length = {
value: clCrit.value,
modifier: clCrit.modifier
modifier: clCrit.modifier,
};
break;
}
@@ -507,7 +507,10 @@ export class ListFilterModel {
}
case "gender": {
const gCrit = criterion as GenderCriterion;
result.gender = { value: StashService.stringToGender(gCrit.value), modifier: gCrit.modifier };
result.gender = {
value: StashService.stringToGender(gCrit.value),
modifier: gCrit.modifier,
};
break;
}
// no default
@@ -518,29 +521,29 @@ export class ListFilterModel {
public makeSceneMarkerFilter(): SceneMarkerFilterType {
const result: SceneMarkerFilterType = {};
this.criteria.forEach(criterion => {
this.criteria.forEach((criterion) => {
switch (criterion.type) {
case "tags": {
const tagsCrit = criterion as TagsCriterion;
result.tags = {
value: tagsCrit.value.map(tag => tag.id),
modifier: tagsCrit.modifier
value: tagsCrit.value.map((tag) => tag.id),
modifier: tagsCrit.modifier,
};
break;
}
case "sceneTags": {
const sceneTagsCrit = criterion as TagsCriterion;
result.scene_tags = {
value: sceneTagsCrit.value.map(tag => tag.id),
modifier: sceneTagsCrit.modifier
value: sceneTagsCrit.value.map((tag) => tag.id),
modifier: sceneTagsCrit.modifier,
};
break;
}
case "performers": {
const performersCrit = criterion as PerformersCriterion;
result.performers = {
value: performersCrit.value.map(performer => performer.id),
modifier: performersCrit.modifier
value: performersCrit.value.map((performer) => performer.id),
modifier: performersCrit.modifier,
};
break;
}

View File

@@ -3,7 +3,7 @@
export enum DisplayMode {
Grid,
List,
Wall
Wall,
}
export enum FilterMode {
@@ -12,7 +12,7 @@ export enum FilterMode {
Studios,
Galleries,
SceneMarkers,
Movies
Movies,
}
export interface ILabeledId {

View File

@@ -30,7 +30,7 @@ interface IConfig {
function registerValidSW(swUrl: string, config?: IConfig) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
.then((registration) => {
// eslint-disable-next-line no-param-reassign
registration.onupdatefound = () => {
const installingWorker = registration.installing;
@@ -67,7 +67,7 @@ function registerValidSW(swUrl: string, config?: IConfig) {
};
};
})
.catch(error => {
.catch((error) => {
console.error("Error during service worker registration:", error);
});
}
@@ -75,7 +75,7 @@ function registerValidSW(swUrl: string, config?: IConfig) {
function checkValidServiceWorker(swUrl: string, config?: IConfig) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
.then((response) => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get("content-type");
if (
@@ -83,7 +83,7 @@ function checkValidServiceWorker(swUrl: string, config?: IConfig) {
(contentType != null && contentType.indexOf("javascript") === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
navigator.serviceWorker.ready.then((registration) => {
registration.unregister().then(() => {
window.location.reload();
});
@@ -139,7 +139,7 @@ export function register(config?: IConfig) {
export function unregister() {
if ("serviceWorker" in navigator) {
navigator.serviceWorker.ready.then(registration => {
navigator.serviceWorker.ready.then((registration) => {
registration.unregister();
});
}

View File

@@ -1,4 +1,4 @@
input[type=range] {
input[type="range"] {
-webkit-appearance: none;
background-color: transparent;
border-color: transparent;
@@ -14,7 +14,7 @@ input[type=range] {
}
&::-webkit-slider-runnable-track {
animate: .2s;
animate: 0.2s;
background: #137cbd;
border: 0 solid #000101;
border-radius: 25px;
@@ -41,7 +41,7 @@ input[type=range] {
}
&::-moz-range-track {
animate: .2s;
animate: 0.2s;
background: #137cbd;
border: 0 solid #000101;
border-radius: 25px;
@@ -62,7 +62,7 @@ input[type=range] {
}
&::-ms-track {
animate: .2s;
animate: 0.2s;
background: transparent;
border-color: transparent;
color: transparent;

View File

@@ -11,7 +11,7 @@
textarea::selection,
input::selection {
background-color: rgba(100, 100, 100, .4);
background-color: rgba(100, 100, 100, 0.4);
color: $dark-text;
}
@@ -24,21 +24,21 @@ body ::-webkit-scrollbar {
}
body ::-webkit-scrollbar-track {
background: rgba(0, 0, 0, .1);
background: rgba(0, 0, 0, 0.1);
border-radius: 0;
}
body ::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, .25);
background: rgba(0, 0, 0, 0.25);
border-radius: 5px;
cursor: pointer;
transition: color .2s ease;
transition: color 0.2s ease;
}
body ::-webkit-scrollbar-thumb:window-inactive {
background: rgba(0, 0, 0, .15);
background: rgba(0, 0, 0, 0.15);
}
body ::-webkit-scrollbar-thumb:hover {
background: rgba(128, 135, 139, .8);
background: rgba(128, 135, 139, 0.8);
}

View File

@@ -1,4 +1,3 @@
/* Blueprint dark theme */
$secondary: #394b59;
@@ -13,7 +12,7 @@ $theme-colors: (
success: $success,
warning: $warning,
danger: $danger,
dark: #394b59
dark: #394b59,
);
$body-bg: #202b33;
@@ -25,7 +24,7 @@ $pre-color: $text-color;
$navbar-dark-color: rgb(245, 248, 250);
$popover-bg: $secondary;
$dark-text: #182026;
$textfield-bg: rgba(16, 22, 26, .3);
$textfield-bg: rgba(16, 22, 26, 0.3);
@import "node_modules/bootstrap/scss/bootstrap";
@@ -37,7 +36,7 @@ $dark-gray5: #394b59;
.btn.active:not(.disabled),
.btn.active.minimal:not(.disabled) {
background-color: rgba(138, 155, 168, .3);
background-color: rgba(138, 155, 168, 0.3);
color: $text-color;
}
@@ -49,12 +48,12 @@ button.minimal {
transition: none;
&:hover {
background: rgba(138, 155, 168, .15);
background: rgba(138, 155, 168, 0.15);
color: $text-color;
}
&:active {
background: rgba(138, 155, 168, .3);
background: rgba(138, 155, 168, 0.3);
color: $text-color;
}
}
@@ -74,7 +73,7 @@ hr {
.nav-tabs {
border: none;
margin: auto;
margin-bottom: .5rem;
margin-bottom: 0.5rem;
.nav-link {
border: none;
@@ -102,7 +101,7 @@ hr {
}
.table-striped tr:nth-child(odd) td {
background: rgba(92, 112, 128, .15);
background: rgba(92, 112, 128, 0.15);
}
.table {
@@ -120,7 +119,7 @@ hr {
td {
border: none;
border-color: #414c53;
padding: .25rem .75rem;
padding: 0.25rem 0.75rem;
&:first-child {
padding-left: 0;

View File

@@ -47,5 +47,5 @@ const stringToSeconds = (v: string) => {
export default {
secondsToString,
stringToSeconds
stringToSeconds,
};

View File

@@ -36,6 +36,6 @@ const usePasteImage = (onLoadEnd: (this: FileReader) => void) => {
const Image = {
onImageChange,
usePasteImage
usePasteImage,
};
export default Image;

View File

@@ -4,5 +4,5 @@ const getPlayer = () => (window as any).jwplayer(playerID);
export default {
playerID,
getPlayer
getPlayer,
};

View File

@@ -13,7 +13,7 @@ const makePerformerScenesUrl = (
const filter = new ListFilterModel(FilterMode.Scenes);
const criterion = new PerformersCriterion();
criterion.value = [
{ id: performer.id, label: performer.name || `Performer ${performer.id}` }
{ id: performer.id, label: performer.name || `Performer ${performer.id}` },
];
filter.criteria.push(criterion);
return `/scenes?${filter.makeQueryParameters()}`;
@@ -24,7 +24,7 @@ const makeStudioScenesUrl = (studio: Partial<GQL.StudioDataFragment>) => {
const filter = new ListFilterModel(FilterMode.Scenes);
const criterion = new StudiosCriterion();
criterion.value = [
{ id: studio.id, label: studio.name || `Studio ${studio.id}` }
{ id: studio.id, label: studio.name || `Studio ${studio.id}` },
];
filter.criteria.push(criterion);
return `/scenes?${filter.makeQueryParameters()}`;
@@ -35,7 +35,7 @@ const makeMovieScenesUrl = (movie: Partial<GQL.MovieDataFragment>) => {
const filter = new ListFilterModel(FilterMode.Scenes);
const criterion = new MoviesCriterion();
criterion.value = [
{ id: movie.id, label: movie.name || `Movie ${movie.id}` }
{ id: movie.id, label: movie.name || `Movie ${movie.id}` },
];
filter.criteria.push(criterion);
return `/scenes?${filter.makeQueryParameters()}`;
@@ -72,5 +72,5 @@ export default {
makeTagSceneMarkersUrl,
makeTagScenesUrl,
makeSceneMarkerUrl,
makeMovieScenesUrl
makeMovieScenesUrl,
};

View File

@@ -97,7 +97,7 @@ const renderHtmlSelect = (options: {
options.onChange(event.currentTarget.value)
}
>
{options.selectOptions.map(opt => (
{options.selectOptions.map((opt) => (
<option value={opt} key={opt}>
{opt}
</option>
@@ -119,7 +119,7 @@ const renderFilterSelect = (options: {
<td>
<FilterSelect
type={options.type}
onSelect={items => options.onChange(items[0]?.id)}
onSelect={(items) => options.onChange(items[0]?.id)}
initialIds={options.initialId ? [options.initialId] : []}
/>
</td>
@@ -139,7 +139,7 @@ const renderMultiSelect = (options: {
<FilterSelect
type={options.type}
isMulti
onSelect={items => options.onChange(items.map(i => i.id))}
onSelect={(items) => options.onChange(items.map((i) => i.id))}
initialIds={options.initialIds ?? []}
/>
</td>
@@ -152,6 +152,6 @@ const Table = {
renderInputGroup,
renderHtmlSelect,
renderFilterSelect,
renderMultiSelect
renderMultiSelect,
};
export default Table;

View File

@@ -90,7 +90,7 @@ const TextUtils = {
fileNameFromPath,
age: getAge,
bitRate,
resolution
resolution,
};
export default TextUtils;

View File

@@ -5438,10 +5438,10 @@ eslint-config-airbnb@^18.0.1:
object.assign "^4.1.0"
object.entries "^1.1.0"
eslint-config-prettier@^6.9.0:
version "6.9.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.9.0.tgz#430d24822e82f7deb1e22a435bfa3999fae4ad64"
integrity sha512-k4E14HBtcLv0uqThaI6I/n1LEqROp8XaPu6SO9Z32u5NlGRC07Enu1Bh2KEFw4FNHbekH8yzbIU9kUGxbiGmCA==
eslint-config-prettier@^6.10.1:
version "6.10.1"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz#129ef9ec575d5ddc0e269667bf09defcd898642a"
integrity sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ==
dependencies:
get-stdin "^6.0.0"
@@ -11027,6 +11027,11 @@ prettier@1.19.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
prettier@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08"
integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg==
pretty-bytes@^5.1.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2"
@@ -13145,6 +13150,11 @@ stylehacks@^4.0.0:
postcss "^7.0.0"
postcss-selector-parser "^3.0.0"
stylelint-config-prettier@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/stylelint-config-prettier/-/stylelint-config-prettier-8.0.1.tgz#ec7cdd7faabaff52ebfa56c28fed3d995ebb8cab"
integrity sha512-RcjNW7MUaNVqONhJH4+rtlAE3ow/9SsAM0YWV0Lgu3dbTKdWTa/pQXRdFWgoHWpzUKn+9oBKR5x8JdH+20wmgw==
stylelint-order@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/stylelint-order/-/stylelint-order-4.0.0.tgz#2a945c2198caac3ff44687d7c8582c81d044b556"