Update frontend packages (#836)

This commit is contained in:
InfiniteStash
2024-11-20 23:05:10 +01:00
committed by GitHub
parent e5cf3e2e2f
commit 86c86d9c72
78 changed files with 3622 additions and 4187 deletions

View File

@@ -1,60 +0,0 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"@typescript-eslint",
"jsx-a11y"
],
"extends": [
"airbnb-typescript",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:import/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"plugin:react/jsx-runtime",
"prettier",
"prettier/prettier"
],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"react/prop-types": "off",
"@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": true }],
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/ban-types": [
"warn",
{
"types": {
"String": {
"message": "Use string instead",
"fixWith": "string"
},
"{}": {
"message": "Use object instead",
"fixWith": "object"
},
"Function": {
"message": "Use arrow notation instead"
}
}
}
],
"prefer-destructuring": ["error", {"object": true, "array": false}],
"import/named": "off",
"import/namespace": "off",
"import/no-unresolved": "off",
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": false
}
]
}
}

View File

@@ -0,0 +1,70 @@
import tseslint from 'typescript-eslint';
import reactRecommendedConfig from "eslint-plugin-react/configs/recommended.js"
import reactJSXConfig from "eslint-plugin-react/configs/jsx-runtime.js"
import reactHooks from "eslint-plugin-react-hooks";
import importPlugin from 'eslint-plugin-import';
import jsxA11y from 'eslint-plugin-jsx-a11y';
import eslintConfigPrettier from "eslint-config-prettier";
export default tseslint.config(
tseslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
reactRecommendedConfig,
reactJSXConfig,
importPlugin.flatConfigs.recommended,
jsxA11y.flatConfigs.recommended,
eslintConfigPrettier,
{
ignores: ["**/vite.config.js"],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
plugins: {
"react-hooks": reactHooks,
},
settings: {
react: {
version: "detect",
},
},
rules: {
...reactHooks.configs.recommended.rules,
"react/prop-types": "off",
"@typescript-eslint/no-use-before-define": ["error", {
functions: false,
classes: true,
}],
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
}],
"prefer-destructuring": ["error", {
object: true,
array: false,
}],
"import/named": "off",
"import/namespace": "off",
"import/no-unresolved": "off",
"@typescript-eslint/no-misused-promises": ["error", {
checksVoidReturn: false,
}],
"jsx-a11y/no-autofocus": "off",
},
});

View File

@@ -20,67 +20,65 @@
"yarn": ">=1.15.2"
},
"devDependencies": {
"@graphql-codegen/cli": "^3.2.1",
"@graphql-codegen/typed-document-node": "^3.0.1",
"@graphql-codegen/typescript": "^3.0.1",
"@graphql-codegen/typescript-operations": "^3.0.1",
"@rollup/plugin-graphql": "^2.0.3",
"@types/apollo-upload-client": "^17.0.2",
"@types/lodash-es": "^4.17.6",
"@graphql-codegen/cli": "^5.0.3",
"@graphql-codegen/typed-document-node": "^5.0.11",
"@graphql-codegen/typescript": "^4.1.1",
"@graphql-codegen/typescript-operations": "^4.3.1",
"@graphql-typed-document-node/core": "^3.2.0",
"@rollup/plugin-graphql": "^2.0.5",
"@types/apollo-upload-client": "^18.0.0",
"@types/lodash-es": "^4.17.12",
"@types/node": "^18.14.2",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/react-helmet": "^6.1.6",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
"@vitejs/plugin-react-swc": "^3.2.0",
"eslint": "^8.35.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
"@types/react-helmet": "^6.1.11",
"@vitejs/plugin-react-swc": "^3.7.1",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"globule": "^1.3.4",
"prettier": "2.8.4",
"prettier": "3.3.3",
"rollup-plugin-analyzer": "^4.0.0",
"sass": "~1.63.6",
"stylelint": "^15.10.1",
"stylelint-config-standard": "^34.0.0",
"stylelint-config-standard-scss": "^10.0.0",
"stylelint-scss": "^5.0.1",
"typescript": "~4.9.5",
"vite": "^4.5.2",
"vite-tsconfig-paths": "^4.0.5"
"sass": "~1.77.6",
"stylelint": "^16.10.0",
"stylelint-config-standard": "^36.0.1",
"stylelint-config-standard-scss": "^13.1.0",
"stylelint-scss": "^6.9.0",
"typescript": "~5.6.3",
"typescript-eslint": "^8.15.0",
"vite": "^5.4.11",
"vite-tsconfig-paths": "^5.1.3"
},
"dependencies": {
"@apollo/client": "^3.7.9",
"@fortawesome/fontawesome-svg-core": "^6.3.0",
"@fortawesome/free-regular-svg-icons": "^6.3.0",
"@fortawesome/free-solid-svg-icons": "6.3.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@graphql-typed-document-node/core": "^3.1.2",
"@apollo/client": "3.11.10",
"@fortawesome/fontawesome-svg-core": "^6.7.0",
"@fortawesome/free-regular-svg-icons": "^6.7.0",
"@fortawesome/free-solid-svg-icons": "^6.7.1",
"@fortawesome/react-fontawesome": "^0.2.2",
"@hookform/resolvers": "2.9.11",
"apollo-upload-client": "^17.0.0",
"bootstrap": "^5.2.3",
"classnames": "^2.3.2",
"apollo-upload-client": "^18.0.1",
"bootstrap": "5.2.3",
"classnames": "^2.5.1",
"date-fns": "^2.29.3",
"graphql": "^16.8.1",
"graphql": "^16.9.0",
"graphql-tag": "^2.12.6",
"i18n-iso-countries": "^7.5.0",
"i18n-iso-countries": "^7.13.0",
"lodash-es": "^4.17.21",
"p-debounce": "^4.0.0",
"query-string": "^8.1.0",
"react": "^18.2.0",
"react-bootstrap": "^2.8.0",
"react-bootstrap-typeahead": "^6.0.2",
"react-dom": "^18.2.0",
"query-string": "^9.1.1",
"react": "^18.3.1",
"react-bootstrap": "^2.10.5",
"react-bootstrap-typeahead": "^6.3.2",
"react-dom": "^18.3.1",
"react-helmet": "^6.1.0",
"react-hook-form": "7.43.2",
"react-markdown": "^8.0.5",
"react-responsive-carousel": "^3.2.23",
"react-router-dom": "^6.8.1",
"react-select": "^5.7.0",
"react-select": "5.8.3",
"rehype-external-links": "1.0.1",
"remark-breaks": "^3.0.1",
"remark-gfm": "^3.0.1",

View File

@@ -28,7 +28,7 @@ const CheckboxSelect: FC<MultiSelectProps> = ({
const handleChange = (vals: OnChangeValue<IOptionType, true>) => {
const selected = uniq(
vals.map((v) => [v.value, ...(v.subValues ?? [])]).flat()
vals.map((v) => [v.value, ...(v.subValues ?? [])]).flat(),
);
setUnselected(selected);
@@ -37,7 +37,7 @@ const CheckboxSelect: FC<MultiSelectProps> = ({
const formatLabel = (
option: IOptionType,
meta: { context: "menu" | "value" }
meta: { context: "menu" | "value" },
) => {
if (meta.context === "menu")
return option.subValues === null ? (
@@ -63,7 +63,7 @@ const CheckboxSelect: FC<MultiSelectProps> = ({
};
const defaultValue = values.filter((val) =>
initialSelected.includes(val.value)
initialSelected.includes(val.value),
);
return (

View File

@@ -1,6 +1,6 @@
import { FC, useContext, useState } from "react";
import { Button, Form } from "react-bootstrap";
import { GraphQLError } from "graphql";
import { GraphQLFormattedError } from "graphql";
import { useEditComment } from "src/graphql";
import cx from "classnames";
@@ -15,7 +15,7 @@ interface IProps {
const AddComment: FC<IProps> = ({ editID }) => {
const auth = useContext(AuthContext);
const [showInput, setShowInput] = useState(false);
const [errors, setErrors] = useState<readonly GraphQLError[]>([]);
const [errors, setErrors] = useState<readonly GraphQLFormattedError[]>([]);
const [comment, setComment] = useState("");
const [saveComment, { loading: saving }] = useEditComment();

View File

@@ -61,7 +61,7 @@ export type OldTagDetails = TargetOldDetails<TagDetails>;
export const renderTagDetails = (
tagDetails: TagDetails,
oldTagDetails: OldTagDetails | undefined,
showDiff: boolean
showDiff: boolean,
) => (
<>
<ChangeRow
@@ -138,7 +138,7 @@ export const renderPerformerDetails = (
performerDetails: PerformerDetails,
oldPerformerDetails: OldPerformerDetails | undefined,
showDiff: boolean,
setModifyAliases = false
setModifyAliases = false,
) => (
<>
{performerDetails.name && (
@@ -301,7 +301,7 @@ type ScenePerformance = {
as?: string | null;
performer: Pick<
PerformerFragment,
"name" | "id" | "gender" | "name" | "disambiguation" | "deleted"
"name" | "id" | "gender" | "disambiguation" | "deleted"
>;
};
@@ -358,7 +358,7 @@ export type OldSceneDetails = TargetOldDetails<SceneDetails>;
export const renderSceneDetails = (
sceneDetails: SceneDetails,
oldSceneDetails: OldSceneDetails | undefined,
showDiff: boolean
showDiff: boolean,
) => (
<>
{sceneDetails.title && (
@@ -475,7 +475,7 @@ export type OldStudioDetails = TargetOldDetails<StudioDetails>;
export const renderStudioDetails = (
studioDetails: StudioDetails,
oldStudioDetails: OldStudioDetails | undefined,
showDiff: boolean
showDiff: boolean,
) => (
<>
<ChangeRow
@@ -535,7 +535,7 @@ const ModifyEdit: FC<ModifyEditProps> = ({ details, oldDetails, options }) => {
details,
oldDetails,
showDiff,
options?.set_modify_aliases
options?.set_modify_aliases,
);
}

View File

@@ -25,7 +25,7 @@ interface Props {
const VoteBar: FC<Props> = ({ edit }) => {
const auth = useContext(AuthContext);
const userVote = (edit.votes ?? []).find(
(v) => v.user?.id && v.user.id === auth.user?.id
(v) => v.user?.id && v.user.id === auth.user?.id,
);
const [vote, setVote] = useState<VoteTypeEnum | null>(userVote?.vote ?? null);
const [submitVote, { loading: savingVote }] = useVote();

View File

@@ -36,7 +36,7 @@ const Votes: FC<VotesProps> = ({ edit }) => (
<span className="mx-2">&bull;</span>
{VoteTypes[v.vote]}
</div>
)
),
)}
</div>
</>

View File

@@ -15,7 +15,7 @@ export const renderPerformer = (appearance: {
as?: string | null;
performer: Pick<
Appearance["performer"],
"name" | "id" | "gender" | "name" | "disambiguation" | "deleted"
"name" | "id" | "gender" | "disambiguation" | "deleted"
>;
}) => (
<Link key={appearance.performer.id} to={performerHref(appearance.performer)}>

View File

@@ -19,8 +19,8 @@ const GenderIcon: FC<IconProps> = ({ gender }) => {
gender.toLowerCase() === "male"
? faMars
: gender.toLowerCase() === "female"
? faVenus
: faTransgender;
? faVenus
: faTransgender;
return <Icon icon={icon} title={GenderTypes[gender]} />;
}
return <Icon icon={faVenusMars} />;

View File

@@ -21,7 +21,7 @@ const Image: FC<Props> = ({
? getImage(images, orientation)
: images.url;
const [imageState, setImageState] = useState<"loading" | "error" | "done">(
"loading"
"loading",
);
if (!url) return <div className={`${CLASSNAME}-missing`}>{emptyMessage}</div>;

View File

@@ -32,7 +32,7 @@ const Images: FC<{
{image.width} x {image.height}
</div>
</div>
)
),
)}
</>
);

View File

@@ -89,8 +89,8 @@ const EditListComponent: FC<EditsProps> = ({
selectedBot === "only"
? true
: selectedBot === "exclude"
? false
: undefined,
? false
: undefined,
page,
per_page: PER_PAGE,
sort: selectedSort,

View File

@@ -115,7 +115,7 @@ const SceneList: FC<Props> = ({
"dir",
direction === SortDirectionEnum.DESC
? SortDirectionEnum.ASC
: SortDirectionEnum.DESC
: SortDirectionEnum.DESC,
)
}
>
@@ -138,7 +138,7 @@ const SceneList: FC<Props> = ({
onChange={(e) =>
setParams(
"favorite",
e.currentTarget.checked ? favoriteFilter.toUpperCase() : "NONE"
e.currentTarget.checked ? favoriteFilter.toUpperCase() : "NONE",
)
}
/>

View File

@@ -35,11 +35,11 @@ const MultiSelect: FC<MultiSelectProps> = ({
/** Allow creating a new option with a different casing. */
const isValidNewOption = (
inputValue: string,
selectValue: OnChangeValue<IOptionType, true>
selectValue: OnChangeValue<IOptionType, true>,
): boolean =>
!!inputValue &&
!selectValue.some(
({ value }) => value.toLowerCase() === inputValue.toLowerCase()
({ value }) => value.toLowerCase() === inputValue.toLowerCase(),
);
return (

View File

@@ -23,7 +23,7 @@ const PaginationComponent: FC<PaginationProps> = ({
const maxVal = Math.max(
Math.min(active + 2, totalPages),
Math.min(totalPages, 5)
Math.min(totalPages, 5),
);
const minVal = Math.max(maxVal - 4, 1);
const totalItems = maxVal - minVal + 1;

View File

@@ -57,7 +57,7 @@ interface SearchResult {
}
const valueIsPerformer = (
arg?: SceneResult | PerformerResult
arg?: SceneResult | PerformerResult,
): arg is PerformerResult => arg?.__typename === "Performer";
const formatOptionLabel = ({ label, sublabel, value }: SearchResult) => (
@@ -80,7 +80,7 @@ const formatOptionLabel = ({ label, sublabel, value }: SearchResult) => (
);
const resultIsSearchAll = (
arg: SearchAllQuery | SearchPerformersQuery
arg: SearchAllQuery | SearchPerformersQuery,
): arg is SearchAllQuery =>
(arg as SearchAllQuery).searchPerformer !== undefined &&
(arg as SearchAllQuery).searchScene !== undefined;
@@ -88,7 +88,7 @@ const resultIsSearchAll = (
function handleResult(
result: SearchAllQuery | SearchPerformersQuery,
excludeIDs: string[],
showAllLink: boolean
showAllLink: boolean,
): (SearchGroup | SearchResult)[] {
let performers: SearchResult[] = [];
let scenes: SearchResult[] = [];

View File

@@ -69,7 +69,7 @@ const TagFilter: FC<TagFilterProps> = ({
(tag) =>
!excludeTags.includes(tag.id) &&
(allowDeleted || !tag.deleted) &&
tag.id !== exact?.id
tag.id !== exact?.id,
)
.map((tag) => ({
label: tag.name,

View File

@@ -106,7 +106,7 @@ const TagSelect: FC<TagSelectProps> = ({
(tag) =>
!excluded.includes(tag.id) &&
(allowDeleted || !tag.deleted) &&
tag.id !== exact?.id
tag.id !== exact?.id,
)
.map((tag) => ({
label: tag.name,

View File

@@ -56,12 +56,12 @@ const URLInput: FC<URLInputProps> = ({ control, type, errors }) => {
if (loading) return <></>;
const sites = (data?.querySites.sites ?? []).filter((s) =>
s.valid_types.includes(type)
s.valid_types.includes(type),
);
const cleanURL = (
regexStr: string | undefined | null,
url: string
url: string,
): string | undefined => {
if (!regexStr) return;

View File

@@ -87,271 +87,289 @@ import {
ConfirmChangeEmailMutation,
ConfirmChangeEmailMutationVariables,
RequestChangeEmailMutation,
ActivateNewUserDocument,
AddUserDocument,
NewUserDocument,
UpdateUserDocument,
DeleteUserDocument,
AddTagCategoryDocument,
DeleteTagCategoryDocument,
UpdateTagCategoryDocument,
AddImageDocument,
PerformerEditDocument,
TagEditDocument,
StudioEditDocument,
SceneEditDocument,
PerformerEditUpdateDocument,
TagEditUpdateDocument,
StudioEditUpdateDocument,
SceneEditUpdateDocument,
AddSceneDocument,
DeleteSceneDocument,
UpdateSceneDocument,
AddStudioDocument,
DeleteStudioDocument,
UpdateStudioDocument,
ApplyEditDocument,
CancelEditDocument,
ChangePasswordDocument,
ResetPasswordDocument,
RegenerateApiKeyDocument,
GenerateInviteCodesDocument,
GrantInviteDocument,
RescindInviteCodeDocument,
RevokeInviteDocument,
EditCommentDocument,
VoteDocument,
AddSiteDocument,
DeleteSiteDocument,
UpdateSiteDocument,
FavoritePerformerDocument,
FavoriteStudioDocument,
DeleteDraftDocument,
UnmatchFingerprintDocument,
ValidateChangeEmailDocument,
ConfirmChangeEmailDocument,
RequestChangeEmailDocument,
RequestChangeEmailMutationVariables,
} from "../types";
import ActivateUserGQL from "./ActivateNewUser.gql";
import AddUserGQL from "./AddUser.gql";
import NewUserGQL from "./NewUser.gql";
import UpdateUserGQL from "./UpdateUser.gql";
import DeleteUserGQL from "./DeleteUser.gql";
import AddTagCategoryGQL from "./AddTagCategory.gql";
import DeleteTagCategoryGQL from "./DeleteTagCategory.gql";
import UpdateTagCategoryGQL from "./UpdateTagCategory.gql";
import AddImageGQL from "./AddImage.gql";
import PerformerEditGQL from "./PerformerEdit.gql";
import TagEditGQL from "./TagEdit.gql";
import StudioEditGQL from "./StudioEdit.gql";
import SceneEditGQL from "./SceneEdit.gql";
import PerformerEditUpdateGQL from "./PerformerEditUpdate.gql";
import TagEditUpdateGQL from "./TagEditUpdate.gql";
import StudioEditUpdateGQL from "./StudioEditUpdate.gql";
import SceneEditUpdateGQL from "./SceneEditUpdate.gql";
import AddSceneGQL from "./AddScene.gql";
import DeleteSceneGQL from "./DeleteScene.gql";
import UpdateSceneGQL from "./UpdateScene.gql";
import AddStudioGQL from "./AddStudio.gql";
import DeleteStudioGQL from "./DeleteStudio.gql";
import UpdateStudioGQL from "./UpdateStudio.gql";
import ApplyEditGQL from "./ApplyEdit.gql";
import CancelEditGQL from "./CancelEdit.gql";
import ChangePasswordGQL from "./ChangePassword.gql";
import ResetPasswordGQL from "./ResetPassword.gql";
import RegenerateAPIKeyGQL from "./RegenerateAPIKey.gql";
import GenerateInviteCodesGQL from "./GenerateInviteCode.gql";
import GrantInviteGQL from "./GrantInvite.gql";
import RescindInviteCodeGQL from "./RescindInviteCode.gql";
import RevokeInviteGQL from "./RevokeInvite.gql";
import EditCommentGQL from "./EditComment.gql";
import VoteGQL from "./Vote.gql";
import AddSiteGQL from "./AddSite.gql";
import DeleteSiteGQL from "./DeleteSite.gql";
import UpdateSiteGQL from "./UpdateSite.gql";
import FavoriteStudioGQL from "./FavoriteStudio.gql";
import FavoritePerformerGQL from "./FavoritePerformer.gql";
import DeleteDraftGQL from "./DeleteDraft.gql";
import UnmatchFingerprintGQL from "./UnmatchFingerprint.gql";
import ValidateChangeEmailGQL from "./ValidateChangeEmail.gql";
import ConfirmChangeEmailGQL from "./ConfirmChangeEmail.gql";
import RequestChangeEmailGQL from "./RequestChangeEmail.gql";
export const useActivateUser = (
options?: MutationHookOptions<
ActivateNewUserMutation,
ActivateNewUserMutationVariables
>
) => useMutation(ActivateUserGQL, options);
>,
) => useMutation(ActivateNewUserDocument, options);
export const useAddUser = (
options?: MutationHookOptions<AddUserMutation, AddUserMutationVariables>
) => useMutation(AddUserGQL, options);
options?: MutationHookOptions<AddUserMutation, AddUserMutationVariables>,
) => useMutation(AddUserDocument, options);
export const useNewUser = (
options?: MutationHookOptions<NewUserMutation, NewUserMutationVariables>
) => useMutation(NewUserGQL, options);
options?: MutationHookOptions<NewUserMutation, NewUserMutationVariables>,
) => useMutation(NewUserDocument, options);
export const useUpdateUser = (
options?: MutationHookOptions<UpdateUserMutation, UpdateUserMutationVariables>
) => useMutation(UpdateUserGQL, options);
options?: MutationHookOptions<
UpdateUserMutation,
UpdateUserMutationVariables
>,
) => useMutation(UpdateUserDocument, options);
export const useDeleteUser = (
options?: MutationHookOptions<DeleteUserMutation, DeleteUserMutationVariables>
) => useMutation(DeleteUserGQL, options);
options?: MutationHookOptions<
DeleteUserMutation,
DeleteUserMutationVariables
>,
) => useMutation(DeleteUserDocument, options);
export const useAddCategory = (
options?: MutationHookOptions<
AddTagCategoryMutation,
AddTagCategoryMutationVariables
>
) => useMutation(AddTagCategoryGQL, options);
>,
) => useMutation(AddTagCategoryDocument, options);
export const useDeleteCategory = (
options?: MutationHookOptions<
DeleteTagCategoryMutation,
DeleteTagCategoryMutationVariables
>
) => useMutation(DeleteTagCategoryGQL, options);
>,
) => useMutation(DeleteTagCategoryDocument, options);
export const useUpdateCategory = (
options?: MutationHookOptions<
UpdateTagCategoryMutation,
UpdateTagCategoryMutationVariables
>
) => useMutation(UpdateTagCategoryGQL, options);
>,
) => useMutation(UpdateTagCategoryDocument, options);
export const useAddImage = (
options?: MutationHookOptions<AddImageMutation, AddImageMutationVariables>
) => useMutation(AddImageGQL, options);
options?: MutationHookOptions<AddImageMutation, AddImageMutationVariables>,
) => useMutation(AddImageDocument, options);
export const usePerformerEdit = (
options?: MutationHookOptions<
PerformerEditMutation,
PerformerEditMutationVariables
>
) => useMutation(PerformerEditGQL, options);
>,
) => useMutation(PerformerEditDocument, options);
export const usePerformerEditUpdate = (
options?: MutationHookOptions<
PerformerEditUpdateMutation,
PerformerEditUpdateMutationVariables
>
) => useMutation(PerformerEditUpdateGQL, options);
>,
) => useMutation(PerformerEditUpdateDocument, options);
export const useAddScene = (
options?: MutationHookOptions<AddSceneMutation, AddSceneMutationVariables>
) => useMutation(AddSceneGQL, options);
options?: MutationHookOptions<AddSceneMutation, AddSceneMutationVariables>,
) => useMutation(AddSceneDocument, options);
export const useDeleteScene = (
options?: MutationHookOptions<
DeleteSceneMutation,
DeleteSceneMutationVariables
>
) => useMutation(DeleteSceneGQL, options);
>,
) => useMutation(DeleteSceneDocument, options);
export const useUpdateScene = (
options?: MutationHookOptions<
UpdateSceneMutation,
UpdateSceneMutationVariables
>
) => useMutation(UpdateSceneGQL, options);
>,
) => useMutation(UpdateSceneDocument, options);
export const useAddStudio = (
options?: MutationHookOptions<AddStudioMutation, AddStudioMutationVariables>
) => useMutation(AddStudioGQL, options);
options?: MutationHookOptions<AddStudioMutation, AddStudioMutationVariables>,
) => useMutation(AddStudioDocument, options);
export const useDeleteStudio = (
options?: MutationHookOptions<
DeleteStudioMutation,
DeleteStudioMutationVariables
>
) => useMutation(DeleteStudioGQL, options);
>,
) => useMutation(DeleteStudioDocument, options);
export const useUpdateStudio = (
options?: MutationHookOptions<
UpdateStudioMutation,
UpdateStudioMutationVariables
>
) => useMutation(UpdateStudioGQL, options);
>,
) => useMutation(UpdateStudioDocument, options);
export const useTagEdit = (
options?: MutationHookOptions<TagEditMutation, TagEditMutationVariables>
) => useMutation(TagEditGQL, options);
options?: MutationHookOptions<TagEditMutation, TagEditMutationVariables>,
) => useMutation(TagEditDocument, options);
export const useTagEditUpdate = (
options?: MutationHookOptions<
TagEditUpdateMutation,
TagEditUpdateMutationVariables
>
) => useMutation(TagEditUpdateGQL, options);
>,
) => useMutation(TagEditUpdateDocument, options);
export const useStudioEdit = (
options?: MutationHookOptions<StudioEditMutation, StudioEditMutationVariables>
) => useMutation(StudioEditGQL, options);
options?: MutationHookOptions<
StudioEditMutation,
StudioEditMutationVariables
>,
) => useMutation(StudioEditDocument, options);
export const useStudioEditUpdate = (
options?: MutationHookOptions<
StudioEditUpdateMutation,
StudioEditUpdateMutationVariables
>
) => useMutation(StudioEditUpdateGQL, options);
>,
) => useMutation(StudioEditUpdateDocument, options);
export const useSceneEdit = (
options?: MutationHookOptions<SceneEditMutation, SceneEditMutationVariables>
) => useMutation(SceneEditGQL, options);
options?: MutationHookOptions<SceneEditMutation, SceneEditMutationVariables>,
) => useMutation(SceneEditDocument, options);
export const useSceneEditUpdate = (
options?: MutationHookOptions<
SceneEditUpdateMutation,
SceneEditUpdateMutationVariables
>
) => useMutation(SceneEditUpdateGQL, options);
>,
) => useMutation(SceneEditUpdateDocument, options);
export const useApplyEdit = (
options?: MutationHookOptions<ApplyEditMutation, ApplyEditMutationVariables>
) => useMutation(ApplyEditGQL, options);
options?: MutationHookOptions<ApplyEditMutation, ApplyEditMutationVariables>,
) => useMutation(ApplyEditDocument, options);
export const useCancelEdit = (
options?: MutationHookOptions<CancelEditMutation, CancelEditMutationVariables>
) => useMutation(CancelEditGQL, options);
options?: MutationHookOptions<
CancelEditMutation,
CancelEditMutationVariables
>,
) => useMutation(CancelEditDocument, options);
export const useChangePassword = (
options?: MutationHookOptions<
ChangePasswordMutation,
ChangePasswordMutationVariables
>
) => useMutation(ChangePasswordGQL, options);
>,
) => useMutation(ChangePasswordDocument, options);
export const useResetPassword = (
options?: MutationHookOptions<
ResetPasswordMutation,
ResetPasswordMutationVariables
>
) => useMutation(ResetPasswordGQL, options);
>,
) => useMutation(ResetPasswordDocument, options);
export const useRegenerateAPIKey = (
options?: MutationHookOptions<
RegenerateApiKeyMutation,
RegenerateApiKeyMutationVariables
>
) => useMutation(RegenerateAPIKeyGQL, options);
>,
) => useMutation(RegenerateApiKeyDocument, options);
export const useGenerateInviteCodes = (
options?: MutationHookOptions<GenerateInviteCodesMutation>
) => useMutation(GenerateInviteCodesGQL, options);
options?: MutationHookOptions<GenerateInviteCodesMutation>,
) => useMutation(GenerateInviteCodesDocument, options);
export const useGrantInvite = (
options?: MutationHookOptions<
GrantInviteMutation,
GrantInviteMutationVariables
>
) => useMutation(GrantInviteGQL, options);
>,
) => useMutation(GrantInviteDocument, options);
export const useRescindInviteCode = (
options?: MutationHookOptions<
RescindInviteCodeMutation,
RescindInviteCodeMutationVariables
>
) => useMutation(RescindInviteCodeGQL, options);
>,
) => useMutation(RescindInviteCodeDocument, options);
export const useRevokeInvite = (
options?: MutationHookOptions<
RevokeInviteMutation,
RevokeInviteMutationVariables
>
) => useMutation(RevokeInviteGQL, options);
>,
) => useMutation(RevokeInviteDocument, options);
export const useEditComment = (
options?: MutationHookOptions<
EditCommentMutation,
EditCommentMutationVariables
>
) => useMutation(EditCommentGQL, options);
>,
) => useMutation(EditCommentDocument, options);
export const useVote = (
options?: MutationHookOptions<VoteMutation, VoteMutationVariables>
) => useMutation(VoteGQL, options);
options?: MutationHookOptions<VoteMutation, VoteMutationVariables>,
) => useMutation(VoteDocument, options);
export const useAddSite = (
options?: MutationHookOptions<AddSiteMutation, AddSiteMutationVariables>
) => useMutation(AddSiteGQL, options);
options?: MutationHookOptions<AddSiteMutation, AddSiteMutationVariables>,
) => useMutation(AddSiteDocument, options);
export const useDeleteSite = (
options?: MutationHookOptions<DeleteSiteMutation, DeleteSiteMutationVariables>
) => useMutation(DeleteSiteGQL, options);
options?: MutationHookOptions<
DeleteSiteMutation,
DeleteSiteMutationVariables
>,
) => useMutation(DeleteSiteDocument, options);
export const useUpdateSite = (
options?: MutationHookOptions<UpdateSiteMutation, UpdateSiteMutationVariables>
) => useMutation(UpdateSiteGQL, options);
options?: MutationHookOptions<
UpdateSiteMutation,
UpdateSiteMutationVariables
>,
) => useMutation(UpdateSiteDocument, options);
export const useSetFavorite = <T extends "performer" | "studio">(
type: T,
id: string
id: string,
) =>
useMutation<
T extends "performer" ? FavoritePerformerMutation : FavoriteStudioMutation,
T extends "performer"
? FavoritePerformerMutationVariables
: FavoriteStudioMutationVariables
>(type === "performer" ? FavoritePerformerGQL : FavoriteStudioGQL, {
>(type === "performer" ? FavoritePerformerDocument : FavoriteStudioDocument, {
update: (cache, { errors }) => {
if (errors === undefined) {
const identity = cache.identify({
@@ -372,16 +390,16 @@ export const useDeleteDraft = (
options?: MutationHookOptions<
DeleteDraftMutation,
DeleteDraftMutationVariables
>
) => useMutation(DeleteDraftGQL, options);
>,
) => useMutation(DeleteDraftDocument, options);
export const useUnmatchFingerprint = (
options?: MutationHookOptions<
UnmatchFingerprintMutation,
UnmatchFingerprintMutationVariables
>
>,
) =>
useMutation(UnmatchFingerprintGQL, {
useMutation(UnmatchFingerprintDocument, {
update(cache, { data }, { variables }) {
if (data?.unmatchFingerprint)
cache.evict({
@@ -396,16 +414,19 @@ export const useValidateChangeEmail = (
options?: MutationHookOptions<
ValidateChangeEmailMutation,
ValidateChangeEmailMutationVariables
>
) => useMutation(ValidateChangeEmailGQL, options);
>,
) => useMutation(ValidateChangeEmailDocument, options);
export const useConfirmChangeEmail = (
options?: MutationHookOptions<
ConfirmChangeEmailMutation,
ConfirmChangeEmailMutationVariables
>
) => useMutation(ConfirmChangeEmailGQL, options);
>,
) => useMutation(ConfirmChangeEmailDocument, options);
export const useRequestChangeEmail = (
options?: MutationHookOptions<RequestChangeEmailMutation>
) => useMutation(RequestChangeEmailGQL, options);
options?: MutationHookOptions<
RequestChangeEmailMutation,
RequestChangeEmailMutationVariables
>,
) => useMutation(RequestChangeEmailDocument, options);

View File

@@ -103,7 +103,7 @@ export const useMe = (options?: QueryHookOptions<MeQuery, MeQueryVariables>) =>
export const usePerformer = (
variables: PerformerQueryVariables,
skip = false
skip = false,
) =>
useQuery(PerformerDocument, {
variables,
@@ -112,7 +112,7 @@ export const usePerformer = (
export const useFullPerformer = (
variables: PerformerQueryVariables,
skip = false
skip = false,
) =>
useQuery(FullPerformerDocument, {
variables,
@@ -138,7 +138,7 @@ export const useScenes = (variables: ScenesQueryVariables, skip = false) =>
export const useScenesWithoutCount = (
variables: ScenesQueryVariables,
skip = false
skip = false,
) =>
useQuery(ScenesWithoutCountDocument, {
variables,
@@ -147,7 +147,7 @@ export const useScenesWithoutCount = (
export const useSearchAll = (
variables: SearchAllQueryVariables,
skip = false
skip = false,
) =>
useQuery(SearchAllDocument, {
variables,
@@ -155,21 +155,21 @@ export const useSearchAll = (
});
export const useSearchPerformers = (
variables: SearchPerformersQueryVariables
variables: SearchPerformersQueryVariables,
) =>
useQuery(SearchPerformersDocument, {
variables,
});
export const useLazySearchAll = (
options?: LazyQueryHookOptions<SearchAllQuery, SearchAllQueryVariables>
options?: LazyQueryHookOptions<SearchAllQuery, SearchAllQueryVariables>,
) => useLazyQuery(SearchAllDocument, options);
export const useLazySearchPerformers = (
options?: LazyQueryHookOptions<
SearchPerformersQuery,
SearchPerformersQueryVariables
>
>,
) => useLazyQuery(SearchPerformersDocument, options);
export const useSearchTags = (variables: SearchTagsQueryVariables) =>
@@ -189,7 +189,7 @@ export const useStudios = (variables: StudiosQueryVariables) =>
});
export const useLazyStudios = (
options?: LazyQueryHookOptions<StudiosQuery, StudiosQueryVariables>
options?: LazyQueryHookOptions<StudiosQuery, StudiosQueryVariables>,
) => useLazyQuery(StudiosDocument, options);
export const useTag = (variables: TagQueryVariables, skip = false) =>
@@ -203,7 +203,7 @@ export const useTags = (variables: TagsQueryVariables) =>
variables,
});
export const useLazyTags = (
options?: LazyQueryHookOptions<TagsQuery, TagsQueryVariables>
options?: LazyQueryHookOptions<TagsQuery, TagsQueryVariables>,
) => useLazyQuery(TagsDocument, options);
export const usePrivateUser = (variables: UserQueryVariables, skip = false) =>
@@ -213,7 +213,7 @@ export const usePrivateUser = (variables: UserQueryVariables, skip = false) =>
});
export const usePublicUser = (
variables: PublicUserQueryVariables,
skip = false
skip = false,
) =>
useQuery(PublicUserDocument, {
variables,
@@ -241,7 +241,7 @@ export const useConfig = () => useQuery(ConfigDocument);
export const useVersion = () => useQuery(VersionDocument);
export const usePendingEditsCount = (
variables: PendingEditsCountQueryVariables
variables: PendingEditsCountQueryVariables,
) => useQuery(PendingEditsCountDocument, { variables });
export const useSite = (variables: SiteQueryVariables, skip = false) =>
@@ -262,7 +262,7 @@ export const useDrafts = () => useQuery(DraftsDocument);
export const useQueryExistingScene = (
variables: QueryExistingSceneQueryVariables,
skip = false
skip = false,
) =>
useQuery(QueryExistingSceneDocument, {
variables,
@@ -275,7 +275,7 @@ export const useScenePairings = (variables: ScenePairingsQueryVariables) =>
});
export const useStudioPerformers = (
variables: StudioPerformersQueryVariables
variables: StudioPerformersQueryVariables,
) =>
useQuery(StudioPerformersDocument, {
variables,

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ const useAuth = (): AuthResult => {
onError: () => setCachedUser(),
});
return { loading, user: loading ? getCachedUser() : data?.me ?? undefined };
return { loading, user: loading ? getCachedUser() : (data?.me ?? undefined) };
};
export default useAuth;

View File

@@ -148,7 +148,7 @@ const useEditFilter = ({
"direction",
selectedDirection === SortDirectionEnum.DESC
? SortDirectionEnum.ASC
: SortDirectionEnum.DESC
: SortDirectionEnum.DESC,
)
}
>

View File

@@ -38,19 +38,19 @@ export type QueryParams<T extends QueryParamConfig> = {
[Property in keyof T]: T[Property] extends StringParamConfig
? string
: T[Property] extends StringArrayParamConfig
? string[]
: T[Property] extends NumberParamConfig
? number
: T[Property] extends NumberArrayParamConfig
? number[]
: T[Property] extends BooleanParamConfig
? boolean
: never;
? string[]
: T[Property] extends NumberParamConfig
? number
: T[Property] extends NumberArrayParamConfig
? number[]
: T[Property] extends BooleanParamConfig
? boolean
: never;
};
type SetParams<T extends QueryParamConfig, K extends keyof T> = (
name: K,
value: QueryParams<T>[K] | undefined
value: QueryParams<T>[K] | undefined,
) => void;
export type SetParamsCallback<T extends QueryParamConfig> = SetParams<
T,
@@ -60,19 +60,19 @@ export type SetParamsCallback<T extends QueryParamConfig> = SetParams<
export const ensureArray = (param?: string | (string | null)[]): string[] => {
if (!param) return [];
return (Array.isArray(param) ? param : [param]).filter(
(val) => val
(val) => val,
) as string[];
};
export const ensureNumberArray = (
param?: string | (string | null)[]
param?: string | (string | null)[],
): number[] => {
return ensureArray(param).map((val) => Number.parseInt(val, 10));
};
const getParamValue = (
config: ParamConfig,
value: string | (string | null)[]
value: string | (string | null)[],
) => {
if (config.default && !value) return config.default;
if (config.type === "number[]") return ensureNumberArray(value);
@@ -83,7 +83,7 @@ const getParamValue = (
};
export const useQueryParams = <T extends QueryParamConfig>(
queryParams: T
queryParams: T,
): [QueryParams<T>, SetParamsCallback<T>] => {
const navigate = useNavigate();
const location = useLocation();
@@ -107,7 +107,7 @@ export const useQueryParams = <T extends QueryParamConfig>(
const setParams: SetParamsCallback<T> = useCallback(
(key, param) => {
const rawQueryParams = querystring.parse(
location.search.replace("?", "")
location.search.replace("?", ""),
);
const config = queryParams[key];
const updatedParams = {
@@ -130,7 +130,7 @@ export const useQueryParams = <T extends QueryParamConfig>(
: paramConfig.default;
isDefault = isEqual(
values.map((val) => val?.toString()?.toLowerCase()),
defaultValues.map((val) => val?.toString()?.toLowerCase())
defaultValues.map((val) => val?.toString()?.toLowerCase()),
);
}
@@ -139,17 +139,17 @@ export const useQueryParams = <T extends QueryParamConfig>(
[paramConfig?.name || paramKey]: isDefault ? undefined : paramValue,
};
},
{}
{},
);
const hash = location.hash ?? "";
navigate(
`${location.pathname}?${querystring
.stringify(finalParams)
.toLowerCase()}${hash}`,
{ replace: true }
{ replace: true },
);
},
[navigate, location.hash, location.pathname, location.search, queryParams]
[navigate, location.hash, location.pathname, location.search, queryParams],
);
return [allParams, setParams];

View File

@@ -11,7 +11,7 @@ const DISPLAY_TIME = 5000;
const ANIMATION_TIME = 1000;
const ToastContext = createContext<(item: Omit<Message, "id">) => void>(
() => {}
() => {},
);
const ToastMessage: React.FC<Message> = ({ id, content, variant }) => {
@@ -45,7 +45,7 @@ const Toasts: React.FC<ToastsProps> = ({ messages, setMessages }) => {
if (messages.length)
timer.current = setTimeout(
() => setMessages?.([]),
DISPLAY_TIME + ANIMATION_TIME
DISPLAY_TIME + ANIMATION_TIME,
);
}, [messages, setMessages]);

View File

@@ -15,7 +15,7 @@ const CategoryList: FC = () => {
const categoryGroups = groupBy(
sortBy(data?.queryTagCategories?.tag_categories ?? [], (cat) => cat.name),
(cat) => cat.group
(cat) => cat.group,
);
const categories = Object.keys(categoryGroups).map((group) => (

View File

@@ -31,7 +31,7 @@ const AddPerformerDraft: FC<Props> = ({ draft }) => {
});
const { data: performer, loading: loadingPerformer } = usePerformer(
{ id: draft.data.id ?? "" },
!isUpdate
!isUpdate,
);
if (loadingPerformer) return <LoadingIndicator />;
@@ -39,7 +39,7 @@ const AddPerformerDraft: FC<Props> = ({ draft }) => {
const doInsert = (
updateData: PerformerEditDetailsInput,
editNote: string,
setModifyAliases: boolean
setModifyAliases: boolean,
) => {
const details: PerformerEditDetailsInput = {
...updateData,
@@ -65,7 +65,7 @@ const AddPerformerDraft: FC<Props> = ({ draft }) => {
const [initialPerformer, unparsed] = parsePerformerDraft(
draft.data,
performer?.findPerformer ?? undefined
performer?.findPerformer ?? undefined,
);
const remainder = Object.entries(unparsed)
.filter(([, val]) => !!val)

View File

@@ -37,15 +37,13 @@ const SceneDraftAdd: FC<Props> = ({ draft }) => {
});
const { data: scene, loading: loadingScene } = useScene(
{ id: draft.data.id ?? "" },
!isUpdate
!isUpdate,
);
const doInsert = (updateData: SceneEditDetailsInput, editNote: string) => {
const details: SceneEditDetailsInput = {
...updateData,
fingerprints: !isUpdate
? draft.data.fingerprints.map(({ __typename, ...rest }) => rest)
: undefined,
fingerprints: !isUpdate ? draft.data.fingerprints : undefined,
draft_id: draft.id,
};
@@ -67,7 +65,7 @@ const SceneDraftAdd: FC<Props> = ({ draft }) => {
const [initialScene, unparsed] = parseSceneDraft(
draft.data,
scene?.findScene ?? undefined
scene?.findScene ?? undefined,
);
const remainder = Object.entries(unparsed)
.filter(([, val]) => !!val)
@@ -81,7 +79,7 @@ const SceneDraftAdd: FC<Props> = ({ draft }) => {
const phashMissing =
!isUpdate &&
draft.data.fingerprints.filter(
(f) => f.algorithm === FingerprintAlgorithm.PHASH
(f) => f.algorithm === FingerprintAlgorithm.PHASH,
).length === 0;
return (

View File

@@ -24,45 +24,45 @@ type ScenePerformer = NonNullable<
type URL = { url: string; site: { id: string } };
const joinURLs = <T extends URL>(
newURL: T | undefined | null,
existingURLs: T[] | undefined
existingURLs: T[] | undefined,
) =>
uniqBy(
[...(newURL ? [newURL] : []), ...(existingURLs ?? [])],
(u) => `${u.url}-${u.site.id}`
(u) => `${u.url}-${u.site.id}`,
);
type Entity = { id: string };
const joinImages = <T extends Entity>(
newImage: T | null | undefined,
existingImages: T[] | undefined
existingImages: T[] | undefined,
) =>
uniqBy(
[...(newImage ? [newImage] : []), ...(existingImages ?? [])],
(i) => i.id
(i) => i.id,
);
const joinTags = <T extends Entity>(
newTags: T[] | null,
existingTags: T[] | undefined
existingTags: T[] | undefined,
) => uniqBy([...(newTags ?? []), ...(existingTags ?? [])], (t) => t.id);
type Performer = { performer: { id: string }; as?: string | null };
const joinPerformers = <T extends Performer>(
newPerformers: T[] | null,
existingPerformers: T[] | undefined
existingPerformers: T[] | undefined,
) => [
...(existingPerformers ?? []),
...(newPerformers ?? []).filter(
(p) =>
!(existingPerformers ?? []).some(
(ep) => ep.performer.id === p.performer.id
)
(ep) => ep.performer.id === p.performer.id,
),
),
];
export const parseSceneDraft = (
draft: SceneDraft,
existingScene: SceneFragment | undefined
existingScene: SceneFragment | undefined,
): [InitialScene, Record<string, string | null>] => {
const scene: InitialScene = {
date: draft.date,
@@ -77,9 +77,9 @@ export const parseSceneDraft = (
tags: joinTags(
(draft.tags ?? []).reduce<Tag[]>(
(res, t) => (t.__typename === "Tag" ? [...res, t] : res),
[]
[],
),
existingScene?.tags
existingScene?.tags,
),
performers: joinPerformers(
(draft.performers ?? []).reduce<ScenePerformer[]>(
@@ -90,9 +90,9 @@ export const parseSceneDraft = (
{ performer: p, as: "", __typename: "PerformerAppearance" },
]
: res,
[]
[],
),
existingScene?.performers
existingScene?.performers,
),
};
@@ -100,16 +100,14 @@ export const parseSceneDraft = (
Studio:
draft.studio?.__typename === "DraftEntity" ? draft.studio.name : null,
Performers: (draft.performers ?? [])
.reduce<string[]>(
(res, p) => (p.__typename === "DraftEntity" ? [...res, p.name] : res),
[]
)
.reduce<
string[]
>((res, p) => (p.__typename === "DraftEntity" ? [...res, p.name] : res), [])
.join(", "),
Tags: (draft.tags ?? [])
.reduce<string[]>(
(res, t) => (t.__typename === "DraftEntity" ? [...res, t.name] : res),
[]
)
.reduce<
string[]
>((res, t) => (t.__typename === "DraftEntity" ? [...res, t.name] : res), [])
.join(", "),
};
@@ -118,10 +116,10 @@ export const parseSceneDraft = (
const parseEnum = (
value: string | null | undefined,
enumObj: Record<string, string>
enumObj: Record<string, string>,
) =>
Object.entries(enumObj).find(
([, objVal]) => value?.toLowerCase() === objVal.toLowerCase()
([, objVal]) => value?.toLowerCase() === objVal.toLowerCase(),
)?.[0] ?? null;
const parseBreastType = (value: string | null | undefined) => {
@@ -138,7 +136,7 @@ const parseBreastType = (value: string | null | undefined) => {
const parseMeasurements = (value: string | null | undefined) => {
const parsedMeasurements = value?.match(
/^(\d\d)([a-zA-Z]+)(?:-|\s)(\d\d)(?:-|\s)(\d\d)$/
/^(\d\d)([a-zA-Z]+)(?:-|\s)(\d\d)(?:-|\s)(\d\d)$/,
);
if (!parsedMeasurements || parsedMeasurements?.length != 5) return null;
@@ -160,7 +158,7 @@ const parseAliases = (value: string | null | undefined) => {
export const parsePerformerDraft = (
draft: PerformerDraft,
existingPerformer: PerformerFragment | undefined
existingPerformer: PerformerFragment | undefined,
): [InitialPerformer, Record<string, string | null>] => {
const measurements = parseMeasurements(draft?.measurements);
const draftAliases = parseAliases(draft?.aliases);
@@ -172,12 +170,12 @@ export const parsePerformerDraft = (
gender: parseEnum(draft.gender, GenderEnum) as GenderEnum | null,
ethnicity: parseEnum(
draft.ethnicity,
EthnicityEnum
EthnicityEnum,
) as EthnicityEnum | null,
eye_color: parseEnum(draft.eye_color, EyeColorEnum) as EyeColorEnum | null,
hair_color: parseEnum(
draft.hair_color,
HairColorEnum
HairColorEnum,
) as HairColorEnum | null,
birthdate: draft.birthdate,
height: Number.parseInt(draft.height ?? "") || null,
@@ -199,9 +197,9 @@ export const parsePerformerDraft = (
};
const remainder = {
Aliases: draftAliases ? null : draft?.aliases ?? null,
Aliases: draftAliases ? null : (draft?.aliases ?? null),
Height: draft.height && !performer.height ? draft.height : null,
Country: draft?.country?.length !== 2 ? draft?.country ?? null : null,
Country: draft?.country?.length !== 2 ? (draft?.country ?? null) : null,
URLs: (draft?.urls ?? []).join(", "),
Measurements:
draft?.measurements && !measurements ? draft.measurements : null,

View File

@@ -66,7 +66,7 @@ const ForgotPassword: FC = () => {
);
const errorList = [errors.email?.message, submitError].filter(
(err): err is string => err !== undefined
(err): err is string => err !== undefined,
);
return (

View File

@@ -47,7 +47,7 @@ const ScenesComponent: FC = () => {
<Col key={scene.id}>
<SceneCard scene={scene} />
</Col>
)
),
);
return (

View File

@@ -44,7 +44,7 @@ const PerformerComponent: FC<Props> = ({ performer }) => {
const studios = keyBy(performer.studios, (s) => s.studio.id);
const studioGroups = groupBy(
performer.studios,
(s) => s.studio.parent?.id ?? "none"
(s) => s.studio.parent?.id ?? "none",
);
const obj = sortBy(
[
@@ -73,12 +73,12 @@ const PerformerComponent: FC<Props> = ({ performer }) => {
value: s.studio.id,
subValues: null,
})),
(s) => s.label
(s) => s.label,
),
};
}),
],
(s) => s.label
(s) => s.label,
)
.map((s) => [
{ ...s, subValues: s.subValues.map((v) => v.value) },

View File

@@ -23,7 +23,7 @@ const PerformerAdd: FC = () => {
const doInsert = (
updateData: PerformerEditDetailsInput,
editNote: string
editNote: string,
) => {
submitPerformerEdit({
variables: {

View File

@@ -31,7 +31,7 @@ const PerformerModify: FC<Props> = ({ performer }) => {
const doUpdate = (
updateData: PerformerEditDetailsInput,
editNote: string,
setModifyAliases: boolean
setModifyAliases: boolean,
) => {
submitPerformerEdit({
variables: {

View File

@@ -35,7 +35,7 @@ export const PerformerEditUpdate: FC<{ edit: EditUpdate }> = ({ edit }) => {
const doUpdate = (
updateData: PerformerEditDetailsInput,
editNote: string,
setModifyAliases: boolean
setModifyAliases: boolean,
) => {
if (!isPerformerEdit(edit.details)) return;

View File

@@ -49,7 +49,7 @@ const PerformerMerge: FC<Props> = ({ performer }) => {
const toggleMerge = () => {
setMergeActive(true);
const sameName = mergeSources.every(
({ name }) => name.trim() === performer.name.trim()
({ name }) => name.trim() === performer.name.trim(),
);
// Don't update aliases by default if the names match
setAliasUpdating(!sameName);
@@ -58,7 +58,7 @@ const PerformerMerge: FC<Props> = ({ performer }) => {
const doUpdate = (
insertData: PerformerEditDetailsInput,
editNote: string,
setModifyAliases: boolean
setModifyAliases: boolean,
) => {
insertPerformerEdit({
variables: {
@@ -84,11 +84,11 @@ const PerformerMerge: FC<Props> = ({ performer }) => {
...performer.aliases,
...mergeSources.map((p) => p.name.trim()),
...flatMap(mergeSources, (p) => p.aliases),
].filter((name) => name !== performer.name.trim())
].filter((name) => name !== performer.name.trim()),
);
const images = uniqBy(
[...performer.images, ...flatMap(mergeSources, (i) => i.images)],
(image) => image.id
(image) => image.id,
);
return (

View File

@@ -24,9 +24,9 @@ import { ROUTE_PERFORMER_ADD, GenderFilterTypes } from "src/constants";
const PER_PAGE = 25;
const genderOptions = Object.keys(GenderFilterEnum).map((g) => ({
value: g,
label: GenderFilterTypes[g as GenderFilterEnum],
const genderOptions = Object.entries(GenderFilterEnum).map(([, value]) => ({
value,
label: GenderFilterTypes[value],
}));
const sortOptions = [
{ value: PerformerSortEnum.NAME, label: "Name" },
@@ -72,7 +72,7 @@ const PerformersComponent: FC = () => {
<Col xs="auto" key={performer.id}>
<PerformerCard performer={performer} />
</Col>
)
),
);
const debouncedHandler = debounce(setParams, 200);
@@ -116,7 +116,7 @@ const PerformersComponent: FC = () => {
"direction",
direction === SortDirectionEnum.ASC
? SortDirectionEnum.DESC
: undefined
: undefined,
)
}
>

View File

@@ -89,7 +89,7 @@ const Actions: FC<Props> = ({ performer }) => {
export const PerformerInfo: FC<Props> = ({ performer }) => {
const { data: mergedInto } = usePerformer(
{ id: performer.merged_into_id ?? "" },
!performer.merged_into_id
!performer.merged_into_id,
);
return (
<div className={CLASSNAME}>
@@ -128,7 +128,7 @@ export const PerformerInfo: FC<Props> = ({ performer }) => {
<td>
{formatCareer(
performer.career_start_year,
performer.career_end_year
performer.career_end_year,
)}
</td>
</tr>

View File

@@ -23,9 +23,9 @@ import { List } from "src/components/list";
const PER_PAGE = 25;
const genderOptions = Object.keys(GenderFilterEnum).map((g) => ({
value: g,
label: GenderFilterTypes[g as GenderFilterEnum],
const genderOptions = Object.entries(GenderFilterEnum).map(([, value]) => ({
value,
label: GenderFilterTypes[value],
}));
const sortOptions = [
{ value: PerformerSortEnum.NAME, label: "Name" },
@@ -111,7 +111,7 @@ export const ScenePairings: FC<Props> = ({ id }) => {
"direction",
direction === SortDirectionEnum.ASC
? SortDirectionEnum.DESC
: undefined
: undefined,
)
}
>

View File

@@ -119,7 +119,7 @@ interface PerformerProps {
data: PerformerEditDetailsInput,
note: string,
updateAliases: boolean,
id?: string
id?: string,
) => void;
initial?: InitialPerformer;
options?: PerformerEditOptionsInput | null;
@@ -152,27 +152,27 @@ const PerformerForm: FC<PerformerProps> = ({
birthdate: initial?.birthdate ?? performer?.birth_date ?? undefined,
eye_color: getEnumValue(
EYE,
initial?.eye_color ?? performer?.eye_color ?? null
initial?.eye_color ?? performer?.eye_color ?? null,
),
hair_color: getEnumValue(
HAIR,
initial?.hair_color ?? performer?.hair_color ?? null
initial?.hair_color ?? performer?.hair_color ?? null,
),
height: initial?.height || performer?.height,
breastType: getEnumValue(
BREAST,
initial?.breast_type ?? performer?.breast_type ?? null
initial?.breast_type ?? performer?.breast_type ?? null,
),
braSize: getBraSize(
initial?.cup_size ?? performer?.cup_size,
initial?.band_size ?? performer?.band_size
initial?.band_size ?? performer?.band_size,
),
waistSize: initial?.waist_size ?? performer?.waist_size,
hipSize: initial?.hip_size ?? performer?.hip_size,
country: initial?.country ?? performer?.country ?? "",
ethnicity: getEnumValue(
ETHNICITY,
initial?.ethnicity ?? performer?.ethnicity ?? null
initial?.ethnicity ?? performer?.ethnicity ?? null,
),
career_start_year:
initial?.career_start_year ?? performer?.career_start_year,
@@ -186,7 +186,7 @@ const PerformerForm: FC<PerformerProps> = ({
const [activeTab, setActiveTab] = useState("personal");
const [updateAliases, setUpdateAliases] = useState<boolean>(
options?.set_modify_aliases ?? true
options?.set_modify_aliases ?? true,
);
const [file, setFile] = useState<File | undefined>();
@@ -197,9 +197,9 @@ const PerformerForm: FC<PerformerProps> = ({
PerformerSchema.cast(fieldData, {
assert: "ignore-optionality",
}) as PerformerFormData,
performer
performer,
),
[fieldData, performer]
[fieldData, performer],
);
const changedName =
@@ -273,16 +273,13 @@ const PerformerForm: FC<PerformerProps> = ({
const countryObj = [
{ label: "Unknown", value: "" },
...sortBy(
Object.keys(CountryList).map((name: string) => {
const countryName: string = Array.isArray(CountryList[name])
? CountryList[name][0]
: CountryList[name];
Object.entries(CountryList).map(([, countryName]) => {
return {
label: countryName,
value: Countries.getAlpha2Code(countryName, "en"),
};
}),
"label"
"label",
),
];
@@ -379,7 +376,6 @@ const PerformerForm: FC<PerformerProps> = ({
<Form.Label>Gender</Form.Label>
<Form.Select
className={cx({ "is-invalid": errors.gender })}
placeholder="Select gender..."
{...register("gender")}
>
{enumOptions(GENDER)}
@@ -522,7 +518,7 @@ const PerformerForm: FC<PerformerProps> = ({
onChange={(option) => onChange(option?.value)}
options={countryObj}
defaultValue={countryObj.find(
(country) => country.value === value
(country) => country.value === value,
)}
/>
)}
@@ -660,7 +656,7 @@ const PerformerForm: FC<PerformerProps> = ({
newChanges,
oldChanges,
!!performer,
updateAliases
updateAliases,
)}
<Row className="my-4">
<Col md={{ span: 8, offset: 4 }}>

View File

@@ -19,7 +19,7 @@ import { PerformerFormData } from "./schema";
const diffBodyMods = (
newMods: { location?: string; description?: string | null }[] | undefined,
oldMods: { location: string; description?: string | null }[] | null
oldMods: { location: string; description?: string | null }[] | null,
) =>
diffArray(
(newMods ?? []).flatMap((m) =>
@@ -30,36 +30,36 @@ const diffBodyMods = (
description: m.description ?? null,
},
]
: []
: [],
),
oldMods ?? [],
(mod) => `${mod.location}|${mod.description}`
(mod) => `${mod.location}|${mod.description}`,
);
const selectPerformerDetails = (
data: PerformerFormData,
original: PerformerFragment | null | undefined
original: PerformerFragment | null | undefined,
): [
Required<OldPerformerDetails>,
Required<Omit<PerformerDetails, "draft_id">>
Required<Omit<PerformerDetails, "draft_id">>,
] => {
const [addedImages, removedImages] = diffImages(
data.images,
original?.images ?? []
original?.images ?? [],
);
const [addedUrls, removedUrls] = diffURLs(data.urls, original?.urls ?? []);
const [addedTattoos, removedTattoos] = diffBodyMods(
data.tattoos,
original?.tattoos ?? []
original?.tattoos ?? [],
);
const [addedPiercings, removedPiercings] = diffBodyMods(
data.piercings,
original?.piercings ?? []
original?.piercings ?? [],
);
const [addedAliases, removedAliases] = diffArray(
data.aliases,
original?.aliases ?? [],
(a) => a
(a) => a,
);
const [newCupSize, newBandSize] = parseBraSize(data.braSize ?? "");
@@ -71,11 +71,11 @@ const selectPerformerDetails = (
birthdate: diffValue(original?.birth_date, data.birthdate),
career_start_year: diffValue(
original?.career_start_year,
data.career_start_year
data.career_start_year,
),
career_end_year: diffValue(
original?.career_end_year,
data.career_end_year
data.career_end_year,
),
height: diffValue(original?.height, data.height),
band_size: diffValue(original?.band_size, newBandSize),
@@ -84,7 +84,7 @@ const selectPerformerDetails = (
hip_size: diffValue(original?.hip_size, data.hipSize),
breast_type: diffValue(
original?.breast_type,
breastType(data.breastType)
breastType(data.breastType),
),
country: diffValue(original?.country, data.country),
ethnicity: diffValue(original?.ethnicity, ethnicityEnum(data.ethnicity)),
@@ -98,11 +98,11 @@ const selectPerformerDetails = (
birthdate: diffValue(data.birthdate, original?.birth_date),
career_start_year: diffValue(
data.career_start_year,
original?.career_start_year
original?.career_start_year,
),
career_end_year: diffValue(
data.career_end_year,
original?.career_end_year
original?.career_end_year,
),
height: diffValue(data.height, original?.height),
band_size: diffValue(newBandSize, original?.band_size),
@@ -111,7 +111,7 @@ const selectPerformerDetails = (
hip_size: diffValue(data.hipSize, original?.hip_size),
breast_type: diffValue(
breastType(data.breastType),
original?.breast_type
original?.breast_type,
),
country: diffValue(data.country, original?.country),
ethnicity: diffValue(ethnicityEnum(data.ethnicity), original?.ethnicity),

View File

@@ -34,7 +34,7 @@ export const PerformerSchema = yup.object({
})
.test("valid-date", "Invalid date", isValidDate)
.test("date-outside-range", "Outside of range", (date) =>
dateWithinRange(date, "1900-01-01", addYears(new Date(), -18))
dateWithinRange(date, "1900-01-01", addYears(new Date(), -18)),
)
.nullable(),
career_start_year: yup
@@ -61,7 +61,7 @@ export const PerformerSchema = yup.object({
.transform(nullCheck)
.matches(
/\d{2,3}[a-zA-Z]{1,4}/,
"Invalid cup size. Only american sizes are accepted."
"Invalid cup size. Only american sizes are accepted.",
)
.nullable(),
waistSize: yup
@@ -98,7 +98,7 @@ export const PerformerSchema = yup.object({
location: yup.string().trim().required("Location is required"),
description: yup.string().trim().transform(nullCheck).nullable(),
})
.noUnknown()
.noUnknown(),
),
piercings: yup.array().of(
yup
@@ -106,7 +106,7 @@ export const PerformerSchema = yup.object({
location: yup.string().trim().required("Location is required"),
description: yup.string().trim().transform(nullCheck).nullable(),
})
.noUnknown()
.noUnknown(),
),
aliases: yup.array().of(yup.string().ensure().trim()).ensure().default([]),
images: yup
@@ -117,7 +117,7 @@ export const PerformerSchema = yup.object({
url: yup.string().required(),
width: yup.number().default(0),
height: yup.number().default(0),
})
}),
)
.required(),
urls: yup
@@ -132,7 +132,7 @@ export const PerformerSchema = yup.object({
icon: yup.string().required(),
})
.required(),
})
}),
)
.ensure(),
note: yup.string().required("Edit note is required"),

View File

@@ -55,8 +55,8 @@ const Register: FC<Props> = ({ config }) => {
if (response.data?.newUser) {
navigate(
`${ROUTE_ACTIVATE}?email=${encodeURIComponent(
formData.email
)}&key=${response.data.newUser}`
formData.email,
)}&key=${response.data.newUser}`,
);
} else {
setAwaitingActivation(true);

View File

@@ -26,9 +26,9 @@ const schema = yup.object({
value
.split("")
.filter(
(item: string, i: number, ar: string[]) => ar.indexOf(item) === i
(item: string, i: number, ar: string[]) => ar.indexOf(item) === i,
)
.join("").length >= 5
.join("").length >= 5,
)
.required("Password is required"),
confirmNewPassword: yup
@@ -79,7 +79,7 @@ const ResetPassword: FC = () => {
(error: unknown) =>
error instanceof Error &&
isApolloError(error) &&
setSubmitError(error.message)
setSubmitError(error.message),
);
};

View File

@@ -106,10 +106,12 @@ const SceneComponent: FC<Props> = ({ scene }) => {
function maybeRenderSubmitted(fingerprint: Fingerprint) {
if (fingerprint.user_submitted) {
return (
<span
<Button
className="user-submitted"
title="Submitted by you - click to remove submission"
onKeyDown={() => handleFingerprintUnmatch(fingerprint)}
onClick={() => handleFingerprintUnmatch(fingerprint)}
variant="link"
>
{!unmatching ? (
<>
@@ -119,7 +121,7 @@ const SceneComponent: FC<Props> = ({ scene }) => {
) : (
<Icon icon={faSpinner} className="fa-spin" />
)}
</span>
</Button>
);
}
}

View File

@@ -108,9 +108,9 @@ const SceneForm: FC<SceneProps> = ({
SceneSchema.cast(fieldData, {
assert: "ignore-optionality",
}) as SceneFormData,
scene
scene,
),
[fieldData, scene]
[fieldData, scene],
);
const [isChanging, setChange] = useState<number | undefined>();
@@ -215,7 +215,7 @@ const SceneForm: FC<SceneProps> = ({
res.__typename === "Performer" && handleChange(res, index)
}
excludeIDs={currentPerformerIds.filter(
(id) => id !== p.performerId
(id) => id !== p.performerId,
)}
searchType={SearchType.Performer}
/>
@@ -264,10 +264,11 @@ const SceneForm: FC<SceneProps> = ({
options={p.aliases ?? []}
defaultInputValue={p.alias ?? ""}
emptyLabel={""}
renderMenu={(results, { id }) => {
if (!results.length) {
renderMenu={(options, { id }) => {
if (!options.length) {
return <></>;
}
const results = options as string[];
return (
<Menu id={id}>
<MenuItem
@@ -282,9 +283,9 @@ const SceneForm: FC<SceneProps> = ({
<MenuItem
option={result}
position={idx + 1}
key={`${result}-idx`}
key={result}
>
{result as string}
{result}
</MenuItem>
))}
</Menu>

View File

@@ -33,7 +33,7 @@ type Tag = {
const selectSceneDetails = (
data: SceneFormData,
original: SceneFragment | null | undefined
original: SceneFragment | null | undefined,
): [Required<OldSceneDetails>, Required<Omit<SceneDetails, OmittedKeys>>] => {
const [addedPerformers, removedPerformers] = diffArray<Performer>(
(data.performers ?? []).flatMap((p) =>
@@ -50,10 +50,10 @@ const selectSceneDetails = (
as: p.alias ?? null,
},
]
: []
: [],
),
original?.performers ?? [],
(s) => `${s.performer.id}${s.as}`
(s) => `${s.performer.id}${s.as}`,
);
const [addedTags, removedTags] = diffArray<Tag>(
@@ -66,15 +66,15 @@ const selectSceneDetails = (
description: t.description ?? null,
},
]
: []
: [],
),
original?.tags ?? [],
(t) => t.id
(t) => t.id,
);
const [addedImages, removedImages] = diffImages(
data.images,
original?.images ?? []
original?.images ?? [],
);
const [addedUrls, removedUrls] = diffURLs(data.urls, original?.urls ?? []);

View File

@@ -20,7 +20,7 @@ export const SceneSchema = yup.object({
})
.test("valid-date", "Invalid date", isValidDate)
.test("date-outside-range", "Outside of range", (date) =>
dateWithinRange(date, "1900-01-01", addYears(new Date(), 1))
dateWithinRange(date, "1900-01-01", addYears(new Date(), 1)),
)
.nullable()
.required("Release date is required"),
@@ -61,7 +61,7 @@ export const SceneSchema = yup.object({
...s,
alias: s.name === s?.alias?.trim() ? undefined : s?.alias?.trim(),
}))
.required()
.required(),
)
.ensure(),
tags: yup
@@ -72,7 +72,7 @@ export const SceneSchema = yup.object({
name: yup.string().required(),
description: yup.string().nullable().optional(),
aliases: yup.array().of(yup.string().required()).defined(),
})
}),
)
.ensure(),
images: yup
@@ -83,7 +83,7 @@ export const SceneSchema = yup.object({
url: yup.string().required(),
width: yup.number().required(),
height: yup.number().required(),
})
}),
)
.required(),
urls: yup
@@ -98,7 +98,7 @@ export const SceneSchema = yup.object({
icon: yup.string().required(),
})
.required(),
})
}),
)
.ensure(),
note: yup.string().required("Edit note is required"),

View File

@@ -50,6 +50,8 @@
.user-submitted {
color: $success;
margin-left: 0.5rem;
padding: 0;
vertical-align: baseline;
.fa-circle-xmark {
display: none;

View File

@@ -132,7 +132,7 @@ const Search: FC = () => {
term: term ?? "",
limit: 10,
},
!term
!term,
);
const debouncedSearch = useMemo(
@@ -143,11 +143,11 @@ const Search: FC = () => {
searchTerm
? createHref(ROUTE_SEARCH, { term: searchTerm })
: ROUTE_SEARCH_INDEX,
{ replace: true }
{ replace: true },
),
200
200,
),
[navigate]
[navigate],
);
return (

View File

@@ -14,7 +14,7 @@ const SiteList: FC = () => {
const { loading, data } = useSites();
const sites = sortBy(data?.querySites.sites ?? [], (s) =>
s.name.toLowerCase()
s.name.toLowerCase(),
);
return (

View File

@@ -45,7 +45,7 @@ const StudioComponent: FC<Props> = ({ studio }) => {
const studioImage = getImage(studio.images, "landscape");
const subStudios = sortBy(studio.child_studios, (s) =>
s.name.toLowerCase()
s.name.toLowerCase(),
).map((s) => (
<li key={s.id}>
<Link to={studioHref(s)}>{s.name}</Link>

View File

@@ -23,9 +23,9 @@ import { List } from "src/components/list";
const PER_PAGE = 25;
const genderOptions = Object.keys(GenderFilterEnum).map((g) => ({
value: g,
label: GenderFilterTypes[g as GenderFilterEnum],
const genderOptions = Object.entries(GenderFilterEnum).map(([, value]) => ({
value,
label: GenderFilterTypes[value],
}));
const sortOptions = [
{ value: PerformerSortEnum.LAST_SCENE, label: "Latest Scene" },
@@ -111,7 +111,7 @@ export const StudioPerformers: FC<Props> = ({ id }) => {
"direction",
direction === SortDirectionEnum.DESC
? SortDirectionEnum.ASC
: undefined
: undefined,
)
}
>

View File

@@ -61,9 +61,9 @@ const StudioForm: FC<StudioProps> = ({
StudioSchema.cast(fieldData, {
assert: "ignore-optionality",
}) as StudioFormData,
studio
studio,
),
[fieldData, studio]
[fieldData, studio],
);
const [activeTab, setActiveTab] = useState("details");

View File

@@ -8,11 +8,11 @@ import { diffValue, diffImages, diffURLs } from "src/utils";
const selectStudioDetails = (
data: StudioFormData,
original: StudioFragment | null | undefined
original: StudioFragment | null | undefined,
): [Required<OldStudioDetails>, Required<StudioDetails>] => {
const [addedImages, removedImages] = diffImages(
data.images,
original?.images ?? []
original?.images ?? [],
);
const [addedUrls, removedUrls] = diffURLs(data.urls, original?.urls ?? []);

View File

@@ -14,7 +14,7 @@ export const StudioSchema = yup.object({
icon: yup.string().required(),
})
.required(),
})
}),
)
.ensure(),
images: yup
@@ -25,7 +25,7 @@ export const StudioSchema = yup.object({
url: yup.string().required(),
width: yup.number().required(),
height: yup.number().required(),
})
}),
)
.required(),
parent: yup

View File

@@ -5,12 +5,12 @@ import { diffValue, diffArray } from "src/utils";
const selectTagDetails = (
data: TagFormData,
original: Tag
original: Tag,
): [Required<OldTagDetails>, Required<TagDetails>] => {
const [addedAliases, removedAliases] = diffArray(
data?.aliases,
original.aliases,
(a) => a
(a) => a,
);
return [

View File

@@ -200,7 +200,7 @@ const UserComponent: FC<Props> = ({ user, refetch }) => {
rescindInviteCode({ variables: { code: showRescindCode ?? "" } }).then(
() => {
refetch();
}
},
);
}

View File

@@ -22,7 +22,7 @@ const AddUserComponent: FC = () => {
(error: unknown) =>
error instanceof Error &&
isApolloError(error) &&
setQueryError(error.message)
setQueryError(error.message),
);
};

View File

@@ -8,7 +8,7 @@ import { useQueryParams, useToast } from "src/hooks";
import { userHref } from "src/utils";
import { ErrorMessage } from "src/components/fragments";
import Title from "src/components/title";
import { useConfirmChangeEmail } from "src/graphql";
import { useConfirmChangeEmail, UserChangeEmailStatus } from "src/graphql";
const ConfirmChangeEmail: FC<{ user: User }> = ({ user }) => {
const navigate = useNavigate();
@@ -28,7 +28,7 @@ const ConfirmChangeEmail: FC<{ user: User }> = ({ user }) => {
confirmChangeEmail({ variables: { token } })
.then((res) => {
const status = res.data?.confirmChangeEmail;
if (status === "SUCCESS") {
if (status === UserChangeEmailStatus.SUCCESS) {
toast({
variant: "success",
content: (
@@ -38,13 +38,13 @@ const ConfirmChangeEmail: FC<{ user: User }> = ({ user }) => {
),
});
navigate(userHref(user));
} else if (status === "INVALID_TOKEN")
} else if (status === UserChangeEmailStatus.INVALID_TOKEN)
setSubmitError(
"Invalid or expired token, please restart the process."
"Invalid or expired token, please restart the process.",
);
else if (status === "EXPIRED")
else if (status === UserChangeEmailStatus.EXPIRED)
setSubmitError(
"Email change token expired, please restart the process."
"Email change token expired, please restart the process.",
);
else setSubmitError("An unknown error occurred");
})
@@ -52,7 +52,7 @@ const ConfirmChangeEmail: FC<{ user: User }> = ({ user }) => {
(error: unknown) =>
error instanceof Error &&
isApolloError(error) &&
setSubmitError(error.message)
setSubmitError(error.message),
);
return false;
};

View File

@@ -29,7 +29,7 @@ const EditUserComponent: FC<Props> = ({ user }) => {
(error: unknown) =>
error instanceof Error &&
isApolloError(error) &&
setQueryError(error.message)
setQueryError(error.message),
);
};

View File

@@ -24,9 +24,9 @@ const schema = yup.object({
value
.split("")
.filter(
(item: string, i: number, ar: string[]) => ar.indexOf(item) === i
(item: string, i: number, ar: string[]) => ar.indexOf(item) === i,
)
.join("").length >= 5
.join("").length >= 5,
)
.required("Password is required"),
roles: yup.array().of(yup.string().required()).required(),

View File

@@ -24,7 +24,7 @@ const ChangePasswordComponent: FC = () => {
(error: unknown) =>
error instanceof Error &&
isApolloError(error) &&
setQueryError(error.message)
setQueryError(error.message),
);
};

View File

@@ -20,9 +20,9 @@ const schema = yup.object({
value
.split("")
.filter(
(item: string, i: number, ar: string[]) => ar.indexOf(item) === i
(item: string, i: number, ar: string[]) => ar.indexOf(item) === i,
)
.join("").length >= 5
.join("").length >= 5,
)
.required("Password is required"),
confirmNewPassword: yup

View File

@@ -10,7 +10,7 @@ import type { User } from "src/AuthContext";
import { useQueryParams } from "src/hooks";
import { ErrorMessage } from "src/components/fragments";
import Title from "src/components/title";
import { useValidateChangeEmail } from "src/graphql";
import { useValidateChangeEmail, UserChangeEmailStatus } from "src/graphql";
const schema = yup.object({
token: yup.string().required(),
@@ -52,14 +52,15 @@ const ValidateChangeEmail: FC<{ user: User }> = () => {
validateChangeEmail({ variables: { ...formData } })
.then((res) => {
const status = res.data?.validateChangeEmail;
if (status === "CONFIRM_NEW") setQueryParam("submitted", true);
else if (status === "INVALID_TOKEN")
if (status === UserChangeEmailStatus.CONFIRM_NEW)
setQueryParam("submitted", true);
else if (status === UserChangeEmailStatus.INVALID_TOKEN)
setSubmitError(
"Invalid or expired token, please restart the process."
"Invalid or expired token, please restart the process.",
);
else if (status === "EXPIRED")
else if (status === UserChangeEmailStatus.EXPIRED)
setSubmitError(
"Email change token expired, please restart the process."
"Email change token expired, please restart the process.",
);
else setSubmitError("An unknown error occurred");
})
@@ -67,7 +68,7 @@ const ValidateChangeEmail: FC<{ user: User }> = () => {
(error: unknown) =>
error instanceof Error &&
isApolloError(error) &&
setSubmitError(error.message)
setSubmitError(error.message),
);
};

View File

@@ -270,7 +270,9 @@ hr {
background-color: #30404d;
border: none;
border-radius: 3px;
box-shadow: 0 0 0 1px rgba(16 22 26 / 40%), 0 0 0 rgba(16 22 26 / 0%),
box-shadow:
0 0 0 1px rgba(16 22 26 / 40%),
0 0 0 rgba(16 22 26 / 0%),
0 0 0 rgba(16 22 26 / 0%);
overflow: hidden;
padding: 0;
@@ -321,15 +323,21 @@ hr {
.text-input,
.input-control {
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 / 30%),
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 / 30%),
inset 0 1px 1px rgba(16 22 26 / 40%);
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 / 30%), inset 0 0 0 1px rgba(16 22 26 / 30%),
box-shadow:
0 0 0 1px $primary,
0 0 0 1px $primary,
0 0 0 3px rgba(19 124 189 / 30%),
inset 0 0 0 1px rgba(16 22 26 / 30%),
inset 0 1px 1px rgba(16 22 26 / 40%);
color: $text-color;
}

View File

@@ -6,7 +6,8 @@ import {
} from "@apollo/client";
import { onError } from "@apollo/client/link/error";
import { setContext } from "@apollo/client/link/context";
import { createUploadLink } from "apollo-upload-client";
import { removeTypenameFromVariables } from "@apollo/client/link/remove-typename";
import createUploadLink from "apollo-upload-client/createUploadLink.mjs";
const typePolicies: TypePolicies = {
SceneDraft: {
@@ -29,7 +30,7 @@ export const getPlatformURL = () => {
if (isDevEnvironment()) {
platformUrl = new URL(
import.meta.env.VITE_SERVER_URL ?? window.location.origin
import.meta.env.VITE_SERVER_URL ?? window.location.origin,
);
platformUrl.port = import.meta.env.VITE_SERVER_PORT ?? "9998";
}
@@ -61,16 +62,15 @@ const createClient = () =>
link: ApolloLink.from([
authLink,
onError(({ graphQLErrors, networkError }) => {
/* eslint-disable no-console */
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) console.log(`[Network error]: ${networkError}`);
/* eslint-enable no-console */
}),
removeTypenameFromVariables(),
httpLink as unknown as ApolloLink,
]),
cache: new InMemoryCache({ typePolicies }),

View File

@@ -18,7 +18,7 @@ export const isValidDate = (date?: string) => !date || isValid(parseISO(date));
export const dateWithinRange = (
date: string | undefined,
start?: string | Date,
end?: string | Date
end?: string | Date,
) => {
if (!date || (!start && !end)) return true;

View File

@@ -2,7 +2,7 @@
export const diffArray = <T extends unknown>(
a: T[],
b: T[],
getKey: (t: T) => string
getKey: (t: T) => string,
) => [
a.filter((x) => !b.some((val) => getKey(val) === getKey(x))),
b.filter((x) => !a.some((val) => getKey(val) === getKey(x))),
@@ -11,7 +11,7 @@ export const diffArray = <T extends unknown>(
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
export const diffValue = <T extends unknown>(
a: T | undefined | null,
b: T | undefined | null
b: T | undefined | null,
): T | null => (a && a !== b ? a : null);
export const diffImages = (
@@ -23,7 +23,7 @@ export const diffImages = (
height: number | undefined;
}[]
| undefined,
oldImages: { id: string; url: string; width: number; height: number }[]
oldImages: { id: string; url: string; width: number; height: number }[],
) =>
diffArray(
(newImages ?? []).flatMap((i) =>
@@ -36,10 +36,10 @@ export const diffImages = (
height: i.height,
},
]
: []
: [],
),
oldImages,
(i) => i.id
(i) => i.id,
);
export const diffURLs = (
@@ -62,7 +62,7 @@ export const diffURLs = (
name: string;
icon: string;
};
}[]
}[],
) =>
diffArray(
(newURLs ?? []).map((u) => ({
@@ -81,5 +81,5 @@ export const diffURLs = (
icon: u.site.icon,
},
})),
(u) => `${u.site.name ?? "Unknown"}: ${u.url}`
(u) => `${u.site.name ?? "Unknown"}: ${u.url}`,
);

View File

@@ -17,47 +17,47 @@ interface TypeName {
}
export const isTag = (
entity: TypeName | null | undefined
entity: TypeName | null | undefined,
): entity is Tag | undefined =>
entity?.__typename === "Tag" || entity === undefined;
export const isPerformer = (
entity: TypeName | null | undefined
entity: TypeName | null | undefined,
): entity is Performer | undefined =>
entity?.__typename === "Performer" || entity === undefined;
export const isStudio = (
entity: TypeName | null | undefined
entity: TypeName | null | undefined,
): entity is Studio | undefined =>
entity?.__typename === "Studio" || entity === undefined;
export const isScene = (
entity: TypeName | null | undefined
entity: TypeName | null | undefined,
): entity is Scene | undefined =>
entity?.__typename === "Scene" || entity === undefined;
export const isTagEdit = <T extends TypeName>(
details?: T | null
details?: T | null,
): details is T & { __typename: "TagEdit" } =>
details?.__typename === "TagEdit";
export const isPerformerEdit = <T extends TypeName>(
details?: T | null
details?: T | null,
): details is T & { __typename: "PerformerEdit" } =>
details?.__typename === "PerformerEdit";
export const isStudioEdit = <T extends TypeName>(
details?: T | null
details?: T | null,
): details is T & { __typename: "StudioEdit" } =>
details?.__typename === "StudioEdit";
export const isSceneEdit = <T extends TypeName>(
details?: T | null
details?: T | null,
): details is T & { __typename: "SceneEdit" } =>
details?.__typename === "SceneEdit";
export const isValidEditTarget = (
target: Target | null | undefined
target: Target | null | undefined,
): target is Performer | Tag | Studio | Scene =>
(isPerformer(target) ||
isTag(target) ||

View File

@@ -6,24 +6,24 @@ import {
} from "src/graphql";
export const genderEnum = (
gender: string | undefined | null
gender: string | undefined | null,
): GenderEnum | null =>
gender === "MALE"
? GenderEnum.MALE
: gender === "FEMALE"
? GenderEnum.FEMALE
: gender === "NON_BINARY"
? GenderEnum.NON_BINARY
: gender === "TRANSGENDER_MALE"
? GenderEnum.TRANSGENDER_MALE
: gender === "TRANSGENDER_FEMALE"
? GenderEnum.TRANSGENDER_FEMALE
: gender === "INTERSEX"
? GenderEnum.INTERSEX
: null;
? GenderEnum.FEMALE
: gender === "NON_BINARY"
? GenderEnum.NON_BINARY
: gender === "TRANSGENDER_MALE"
? GenderEnum.TRANSGENDER_MALE
: gender === "TRANSGENDER_FEMALE"
? GenderEnum.TRANSGENDER_FEMALE
: gender === "INTERSEX"
? GenderEnum.INTERSEX
: null;
export const ethnicityEnum = (
ethnicity: string | undefined | null
ethnicity: string | undefined | null,
): EthnicityEnum | null => {
switch (ethnicity) {
case "ASIAN":
@@ -48,18 +48,18 @@ export const ethnicityEnum = (
};
export const fingerprintAlgorithm = (
algorithm: string | undefined | null
algorithm: string | undefined | null,
): FingerprintAlgorithm | null =>
algorithm === "MD5"
? FingerprintAlgorithm.MD5
: algorithm === "OSHASH"
? FingerprintAlgorithm.OSHASH
: algorithm === "PHASH"
? FingerprintAlgorithm.PHASH
: null;
? FingerprintAlgorithm.OSHASH
: algorithm === "PHASH"
? FingerprintAlgorithm.PHASH
: null;
export const breastType = (
type: string | undefined | null
type: string | undefined | null,
): BreastTypeEnum | null => {
switch (type) {
case "FAKE":
@@ -81,7 +81,7 @@ export const ensureEnum = <T>(enm: { [s: string]: T }, value: string): T =>
export const resolveEnum = <T>(
enm: { [s: string]: T },
value: string | null,
defaultValue?: T
defaultValue?: T,
): T | undefined =>
value &&
(Object.values(enm) as unknown as string[]).includes(value.toUpperCase())

View File

@@ -24,7 +24,7 @@ export const editHref = (obj: { id: string }, route: string = ROUTE_EDIT) =>
export const categoryHref = (
obj: { id: string },
route: string = ROUTE_CATEGORY
route: string = ROUTE_CATEGORY,
) => generatePath(route, obj);
export const tagHref = (obj: { id: string }, route: string = ROUTE_TAG) =>
@@ -32,7 +32,7 @@ export const tagHref = (obj: { id: string }, route: string = ROUTE_TAG) =>
export const performerHref = (
obj: { id: string },
route: string = ROUTE_PERFORMER
route: string = ROUTE_PERFORMER,
) => generatePath(route, obj);
export const siteHref = (obj: { id: string }, route: string = ROUTE_SITE) =>
@@ -41,5 +41,5 @@ export const siteHref = (obj: { id: string }, route: string = ROUTE_SITE) =>
export const createHref = (route: string, params: unknown = {}) =>
generatePath(
route,
params as Record<string, string | number | boolean | undefined>
params as Record<string, string | number | boolean | undefined>,
);

View File

@@ -2,7 +2,7 @@ import { ImageFragment, UrlFragment } from "src/graphql";
export const formatCareer = (
start?: number | null,
end?: number | null
end?: number | null,
): string | undefined =>
start || end ? `Active ${start ?? "????"}\u2013${end ?? ""}` : undefined;
@@ -26,13 +26,13 @@ export const formatMeasurements = ({
export const getBraSize = (
cup_size: string | null | undefined,
band_size: number | null | undefined
band_size: number | null | undefined,
): string | undefined =>
band_size && cup_size ? `${band_size}${cup_size}` : undefined;
export const sortImageURLs = (
urls: ImageFragment[],
orientation: "portrait" | "landscape"
orientation: "portrait" | "landscape",
) =>
urls
.map((u) => ({
@@ -54,7 +54,7 @@ export const sortImageURLs = (
export const getImage = (
urls: ImageFragment[],
orientation: "portrait" | "landscape"
orientation: "portrait" | "landscape",
) => {
const images = sortImageURLs(urls, orientation);
return images?.[0]?.url ?? "";
@@ -72,7 +72,7 @@ export const getUrlBySite = (urls: UrlFragment[], name: string) =>
urls.find((url) => url.site.name === name) ?? urls[0];
export const formatBodyModification = (
bodyMod?: { location: string; description?: string | null } | null
bodyMod?: { location: string; description?: string | null } | null,
) =>
bodyMod
? bodyMod.location +
@@ -80,7 +80,7 @@ export const formatBodyModification = (
: null;
export const formatBodyModifications = (
bodyMod?: { location: string; description?: string | null }[] | null
bodyMod?: { location: string; description?: string | null }[] | null,
) => (bodyMod ?? []).map(formatBodyModification).join(", ");
export const formatPendingEdits = (count?: number) =>
@@ -109,7 +109,7 @@ export const formatDuration = (dur?: number | null) => {
};
export const parseDuration = (
dur: string | null | undefined
dur: string | null | undefined,
): number | null => {
if (!dur) return null;
@@ -131,7 +131,7 @@ export const parseBraSize = (braSize = ""): [string | null, number | null] => {
const bandSize = band ? Number.parseInt(band, 10) : null;
const cup = bandSize ? braSize.replace(bandSize.toString(), "") : null;
const cupSize = cup
? /^[a-zA-Z]+/.exec(cup)?.[0]?.toUpperCase() ?? null
? (/^[a-zA-Z]+/.exec(cup)?.[0]?.toUpperCase() ?? null)
: null;
return [cupSize, bandSize];

View File

@@ -9,11 +9,11 @@ const cache = localStorage.getItem(USER_STORAGE);
const cachedUser = cache ? (JSON.parse(cache) as User) : undefined;
export const getCachedUser = () => cachedUser;
export const setCachedUser = (user?: User | undefined | null) => {
export const setCachedUser = (user?: User | null) => {
if (user) localStorage.setItem(USER_STORAGE, JSON.stringify(user));
else localStorage.removeItem(USER_STORAGE);
};
export const isPrivateUser = (
user: PublicUser | PrivateUser
user: PublicUser | PrivateUser,
): user is PrivateUser => !!(user as PrivateUser).email;

File diff suppressed because it is too large Load Diff