Fix react warnings (#317)

* Remove unused imports

* Fix === warnings

* Remove unnecessary escape character

* Add alt text for images

* Add missing alt text

* Remove unused variable

* Change scrubber buttons from anchors

* Change folder select anchor to button

* Replace anchors with buttons

* Add missing useEffect dependencies

* Refactor filter debounce

* Throw error object

* Update dependencies

* Fix === warning
This commit is contained in:
WithoutPants
2020-01-17 05:36:38 +11:00
committed by Leopere
parent cf96cae4c8
commit 66b4f6db4f
46 changed files with 132 additions and 178 deletions

3
go.mod
View File

@@ -12,7 +12,6 @@ require (
github.com/golang-migrate/migrate/v4 v4.3.1
github.com/gorilla/websocket v1.4.0
github.com/h2non/filetype v1.0.8
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jmoiron/sqlx v1.2.0
github.com/mattn/go-sqlite3 v1.10.0
github.com/rs/cors v1.6.0
@@ -28,3 +27,5 @@ require (
)
replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999
go 1.11

1
go.sum
View File

@@ -258,6 +258,7 @@ github.com/gobuffalo/packr v1.15.0/go.mod h1:t5gXzEhIviQwVlNx/+3SfS07GS+cZ2hn76W
github.com/gobuffalo/packr v1.15.1/go.mod h1:IeqicJ7jm8182yrVmNbM6PR4g79SjN9tZLH8KduZZwE=
github.com/gobuffalo/packr v1.19.0/go.mod h1:MstrNkfCQhd5o+Ct4IJ0skWlxN8emOq8DsoT1G98VIU=
github.com/gobuffalo/packr v1.20.0/go.mod h1:JDytk1t2gP+my1ig7iI4NcVaXr886+N0ecUga6884zw=
github.com/gobuffalo/packr v1.21.0 h1:p2ujcDJQp2QTiYWcI0ByHbr/gMoCouok6M0vXs/yTYQ=
github.com/gobuffalo/packr v1.21.0/go.mod h1:H00jGfj1qFKxscFJSw8wcL4hpQtPe1PfU2wa6sg/SR0=
github.com/gobuffalo/packr/v2 v2.0.0-rc.8/go.mod h1:y60QCdzwuMwO2R49fdQhsjCPv7tLQFR0ayzxxla9zes=
github.com/gobuffalo/packr/v2 v2.0.0-rc.9/go.mod h1:fQqADRfZpEsgkc7c/K7aMew3n4aF1Kji7+lIZeR98Fc=

View File

@@ -1,7 +1,6 @@
import {
Spinner,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useEffect, useState } from "react";
import * as GQL from "../../core/generated-graphql";
import { StashService } from "../../core/StashService";
@@ -20,7 +19,7 @@ export const Gallery: FunctionComponent<IProps> = (props: IProps) => {
setIsLoading(loading);
if (!data || !data.findGallery || !!error) { return; }
setGallery(data.findGallery);
}, [data]);
}, [data, loading, error]);
if (!data || !data.findGallery || isLoading) { return <Spinner size={Spinner.SIZE_LARGE} />; }
if (!!error) { return <>{error.message}</>; }

View File

@@ -1,5 +1,4 @@
import { HTMLTable } from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent } from "react";
import { QueryHookResult } from "react-apollo-hooks";
import { Link } from "react-router-dom";
@@ -36,7 +35,7 @@ export const GalleryList: FunctionComponent<IProps> = (props: IProps) => {
<tr key={gallery.id}>
<td>
<Link to={`/galleries/${gallery.id}`}>
{gallery.files.length > 0 ? <img src={`${gallery.files[0].path}?thumb=true`} /> : undefined}
{gallery.files.length > 0 ? <img alt={gallery.title} src={`${gallery.files[0].path}?thumb=true`} /> : undefined}
</Link>
</td>
<td><Link to={`/galleries/${gallery.id}`}>{gallery.path}</Link></td>

View File

@@ -1,4 +1,3 @@
import _ from "lodash";
import React, { FunctionComponent, useState } from "react";
import Lightbox from "react-images";
import Gallery from "react-photo-gallery";

View File

@@ -23,7 +23,7 @@ export const Settings: FunctionComponent<IProps> = (props: IProps) => {
const location = Object.assign({}, props.history.location);
location.search = queryString.stringify({tab: tabId}, {encode: false});
props.history.replace(location);
}, [tabId]);
}, [tabId, props.history]);
function getTabId(): TabId {
const queryParams = queryString.parse(props.location.search);

View File

@@ -1,15 +1,10 @@
import {
Button,
H1,
H4,
H6,
HTMLTable,
Spinner,
Tag,
} from "@blueprintjs/core";
import React, { FunctionComponent } from "react";
import * as GQL from "../../core/generated-graphql";
import { TextUtils } from "../../utils/text";
import { StashService } from "../../core/StashService";
interface IProps { }
@@ -93,7 +88,7 @@ export const SettingsAboutPanel: FunctionComponent<IProps> = (props: IProps) =>
{!!error ? <span>{error.message}</span> : undefined}
{!!errorLatest ? <span>{errorLatest.message}</span> : undefined}
{renderVersion()}
{!dataLatest || loadingLatest || networkStatus == 4 ? <Spinner size={Spinner.SIZE_SMALL} /> : <>{renderLatestVersion()}</>}
{!dataLatest || loadingLatest || networkStatus === 4 ? <Spinner size={Spinner.SIZE_SMALL} /> : <>{renderLatestVersion()}</>}
</>
);

View File

@@ -3,12 +3,9 @@ import {
Button,
Divider,
FormGroup,
H1,
H4,
H6,
InputGroup,
Spinner,
Tag,
Checkbox,
HTMLSelect,
} from "@blueprintjs/core";
@@ -71,7 +68,7 @@ export const SettingsConfigurationPanel: FunctionComponent<IProps> = (props: IPr
setLogAccess(conf.general.logAccess);
setExcludes(conf.general.excludes);
}
}, [data]);
}, [data, error]);
function onStashesChanged(directories: string[]) {
setStashes(directories);

View File

@@ -8,7 +8,6 @@ import {
TextArea,
NumericInput
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useEffect, useState } from "react";
import { StashService } from "../../core/StashService";
import { ErrorUtils } from "../../utils/errors";
@@ -48,7 +47,7 @@ export const SettingsInterfacePanel: FunctionComponent<IProps> = () => {
setCSS(config.data.configuration.interface.css || "");
setCSSEnabled(config.data.configuration.interface.cssEnabled || false);
}
}, [config.data]);
}, [config.data, config.error]);
async function onSave() {
try {

View File

@@ -155,7 +155,7 @@ export const SettingsLogsPanel: FunctionComponent<IProps> = (props: IProps) => {
const logLevels = ["Debug", "Info", "Warning", "Error"];
function filterByLogLevel(logEntry : LogEntry) {
if (logLevel == "Debug") {
if (logLevel === "Debug") {
return true;
}

View File

@@ -5,7 +5,6 @@ import {
Divider,
FormGroup,
H4,
AnchorButton,
ProgressBar,
H5,
} from "@blueprintjs/core";

View File

@@ -8,7 +8,6 @@ import {
NavbarDivider,
Popover,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useState } from "react";
import { Link } from "react-router-dom";
import * as GQL from "../../core/generated-graphql";

View File

@@ -1,5 +1,5 @@
import React, { FunctionComponent, useState, useEffect } from "react";
import { InputGroup, ButtonGroup, Button, IInputGroupProps, HTMLInputProps, ControlGroup } from "@blueprintjs/core";
import { InputGroup, ButtonGroup, Button, HTMLInputProps, ControlGroup } from "@blueprintjs/core";
import { DurationUtils } from "../../utils/duration";
import { FIXED, NUMERIC_INPUT } from "@blueprintjs/core/lib/esm/common/classes";

View File

@@ -6,7 +6,6 @@ import {
Spinner,
FormGroup,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useEffect, useState } from "react";
import { StashService } from "../../../core/StashService";
@@ -29,7 +28,7 @@ export const FolderSelect: FunctionComponent<IProps> = (props: IProps) => {
useEffect(() => {
if (!data || !data.directories || !!error) { return; }
setSelectableDirectories(StashService.nullToUndefined(data.directories));
}, [data]);
}, [data, error]);
function onSelectDirectory() {
selectedDirectories.push(currentDirectory);
@@ -79,7 +78,7 @@ export const FolderSelect: FunctionComponent<IProps> = (props: IProps) => {
{renderDialog()}
<FormGroup>
{selectedDirectories.map((path) => {
return <div key={path}>{path} <a onClick={() => onRemoveDirectory(path)}>Remove</a></div>;
return <div key={path}>{path} <button className="button-link" onClick={() => onRemoveDirectory(path)}>Remove</button></div>;
})}
</FormGroup>

View File

@@ -2,7 +2,6 @@ import {
ITagProps,
Tag,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent } from "react";
import { Link } from "react-router-dom";
import { PerformerDataFragment, SceneMarkerDataFragment, TagDataFragment } from "../../core/generated-graphql";

View File

@@ -1,7 +1,6 @@
import {
MenuItem,
Menu,
IconName,
} from "@blueprintjs/core";
import React, { FunctionComponent } from "react";
import { IMenuItem } from "../App";

View File

@@ -1,4 +1,4 @@
import { H1, Spinner } from "@blueprintjs/core";
import { Spinner } from "@blueprintjs/core";
import React, { FunctionComponent } from "react";
import { StashService } from "../core/StashService";

View File

@@ -1,13 +1,8 @@
import {
Button,
Classes,
Dialog,
EditableText,
HTMLSelect,
HTMLTable,
Spinner,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useEffect, useState } from "react";
import * as GQL from "../../../core/generated-graphql";
import { StashService } from "../../../core/StashService";
@@ -52,7 +47,7 @@ export const Studio: FunctionComponent<IProps> = (props: IProps) => {
setIsLoading(loading);
if (!data || !data.findStudio || !!error) { return; }
setStudio(data.findStudio);
}, [data]);
}, [data, loading, error]);
useEffect(() => {
setImagePreview(studio.image_path);
@@ -61,7 +56,7 @@ export const Studio: FunctionComponent<IProps> = (props: IProps) => {
if (!isNew) {
setIsEditing(false);
}
}, [studio]);
}, [studio, isNew]);
function onImageLoad(this: FileReader) {
setImagePreview(this.result as string);
@@ -120,7 +115,7 @@ export const Studio: FunctionComponent<IProps> = (props: IProps) => {
async function onDelete() {
setIsLoading(true);
try {
const result = await deleteStudio();
await deleteStudio();
} catch (e) {
ErrorUtils.handle(e);
}
@@ -139,7 +134,7 @@ export const Studio: FunctionComponent<IProps> = (props: IProps) => {
<>
<div className="columns is-multiline no-spacing">
<div className="column is-half details-image-container">
<img className="studio" src={imagePreview} />
<img alt={name} className="studio" src={imagePreview} />
</div>
<div className="column is-half details-detail-container">
<DetailsEditNavbar

View File

@@ -1,4 +1,3 @@
import _ from "lodash";
import React, { FunctionComponent } from "react";
import { QueryHookResult } from "react-apollo-hooks";
import { FindStudiosQuery, FindStudiosVariables } from "../../core/generated-graphql";

View File

@@ -1,15 +1,9 @@
import { Alert, Button, Classes, Dialog, EditableText, FormGroup, HTMLTable, InputGroup, Spinner, Tag } from "@blueprintjs/core";
import _ from "lodash";
import { Alert, Button, Classes, Dialog, FormGroup, InputGroup, Spinner } from "@blueprintjs/core";
import React, { FunctionComponent, useEffect, useState } from "react";
import { QueryHookResult } from "react-apollo-hooks";
import { Link } from "react-router-dom";
import { FindGalleriesQuery, FindGalleriesVariables } from "../../core/generated-graphql";
import * as GQL from "../../core/generated-graphql";
import { StashService } from "../../core/StashService";
import { ListHook } from "../../hooks/ListHook";
import { IBaseProps } from "../../models/base-props";
import { ListFilterModel } from "../../models/list-filter/filter";
import { DisplayMode, FilterMode } from "../../models/list-filter/types";
import { ErrorUtils } from "../../utils/errors";
import { NavigationUtils } from "../../utils/navigation";
import { ToastUtils } from "../../utils/toasts";
@@ -36,7 +30,7 @@ export const TagList: FunctionComponent<IProps> = (props: IProps) => {
setIsLoading(loading);
if (!data || !data.allTags || !!error) { return; }
setTags(data.allTags);
}, [data]);
}, [data, loading, error]);
useEffect(() => {
if (!!editingTag) {

View File

@@ -116,7 +116,7 @@ export const WallItem: FunctionComponent<IWallItemProps> = (props: IWallItemProp
loop={true}
ref={videoHoverHook.videoEl}
/>
<img src={previewPath || screenshotPath} onError={() => previewNotFound()} />
<img alt={title} src={previewPath || screenshotPath} onError={() => previewNotFound()} />
{showTextContainer ?
<div className="scene-wall-item-text-container">
<div style={{lineHeight: 1}}>

View File

@@ -1,4 +1,3 @@
import _ from "lodash";
import React, { FunctionComponent, useState } from "react";
import * as GQL from "../../core/generated-graphql";
import "./Wall.scss";

View File

@@ -11,7 +11,7 @@ import {
Slider,
} from "@blueprintjs/core";
import { debounce } from "lodash";
import React, { FunctionComponent, SyntheticEvent, useEffect, useState } from "react";
import React, { FunctionComponent, SyntheticEvent, useState } from "react";
import { Criterion } from "../../models/list-filter/criteria/criterion";
import { ListFilterModel } from "../../models/list-filter/filter";
import { DisplayMode } from "../../models/list-filter/types";
@@ -41,22 +41,18 @@ interface IListFilterProps {
const PAGE_SIZE_OPTIONS = ["20", "40", "60", "120"];
export const ListFilter: FunctionComponent<IListFilterProps> = (props: IListFilterProps) => {
let searchCallback: any;
const [editingCriterion, setEditingCriterion] = useState<Criterion | undefined>(undefined);
useEffect(() => {
searchCallback = debounce((event: any) => {
props.onChangeQuery(event.target.value);
}, 500);
});
function onChangePageSize(event: SyntheticEvent<HTMLSelectElement>) {
const val = event!.currentTarget!.value;
props.onChangePageSize(parseInt(val, 10));
}
function onChangeQuery(event: SyntheticEvent<HTMLInputElement>) {
let searchCallback = debounce((event: any) => {
props.onChangeQuery(event.target.value);
}, 500);
event.persist();
searchCallback(event);
}

View File

@@ -6,7 +6,6 @@ import {
AnchorButton,
IconName,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useEffect, useState } from "react";
import * as GQL from "../../../core/generated-graphql";
import { StashService } from "../../../core/StashService";
@@ -40,7 +39,7 @@ export const Performer: FunctionComponent<IPerformerProps> = (props: IPerformerP
setIsLoading(loading);
if (!data || !data.findPerformer || !!error) { return; }
setPerformer(data.findPerformer);
}, [data]);
}, [data, error, loading]);
useEffect(() => {
setImagePreview(performer.image_path);
@@ -191,7 +190,7 @@ export const Performer: FunctionComponent<IPerformerProps> = (props: IPerformerP
return (
<div className="columns is-multiline no-spacing">
<div className="column is-half details-image-container">
<img className="performer" src={imagePreview} />
{!imagePreview ? undefined : <img alt="Performer" className="performer" src={imagePreview} />}
</div>
<div className="column is-half details-detail-container">
{renderTabs()}
@@ -218,7 +217,7 @@ export const Performer: FunctionComponent<IPerformerProps> = (props: IPerformerP
<>
<div id="performer-page">
<div className="details-image-container">
<img className="performer" src={imagePreview} onClick={openLightbox} />
<img alt={performer.name} className="performer" src={imagePreview} onClick={openLightbox} />
</div>
<div className="performer-head">
<h1 className="bp3-heading">

View File

@@ -2,10 +2,8 @@ import {
Button,
Classes,
Dialog,
EditableText,
HTMLTable,
Spinner,
FormGroup,
Menu,
MenuItem,
Popover,
@@ -19,7 +17,6 @@ import { StashService } from "../../../core/StashService";
import { ErrorUtils } from "../../../utils/errors";
import { TableUtils } from "../../../utils/table";
import { ScrapePerformerSuggest } from "../../select/ScrapePerformerSuggest";
import { ToastUtils } from "../../../utils/toasts";
import { EditableTextUtils } from "../../../utils/editabletext";
import { ImageUtils } from "../../../utils/image";

View File

@@ -1,7 +1,6 @@
import {
Button,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent } from "react";
import * as GQL from "../../../core/generated-graphql";
import { StashService } from "../../../core/StashService";

View File

@@ -1,4 +1,3 @@
import _ from "lodash";
import React, { FunctionComponent } from "react";
import * as GQL from "../../../core/generated-graphql";
import { IBaseProps } from "../../../models";

View File

@@ -7,16 +7,14 @@ import {
Elevation,
H4,
Popover,
Tag,
} from "@blueprintjs/core";
import React, { FunctionComponent, RefObject, useEffect, useRef, useState } from "react";
import React, { FunctionComponent, useState } from "react";
import { Link } from "react-router-dom";
import * as GQL from "../../core/generated-graphql";
import { VideoHoverHook } from "../../hooks/VideoHover";
import { ColorUtils } from "../../utils/color";
import { TextUtils } from "../../utils/text";
import { TagLink } from "../Shared/TagLink";
import { SceneHelpers } from "./helpers";
import { ZoomUtils } from "../../utils/zoom";
import { StashService } from "../../core/StashService";

View File

@@ -30,7 +30,7 @@ export const Scene: FunctionComponent<ISceneProps> = (props: ISceneProps) => {
setIsLoading(loading);
if (!data || !data.findScene || !!error) { return; }
setScene(StashService.nullToUndefined(data.findScene));
}, [data]);
}, [data, loading, error]);
useEffect(() => {
const queryParams = queryString.parse(props.location.search);
@@ -41,7 +41,7 @@ export const Scene: FunctionComponent<ISceneProps> = (props: ISceneProps) => {
if (queryParams.autoplay && typeof queryParams.autoplay === "string") {
setAutoplay(queryParams.autoplay === "true");
}
});
}, [props.location.search, timestamp]);
function onClickMarker(marker: GQL.SceneMarkerDataFragment) {
setTimestamp(marker.seconds);

View File

@@ -2,12 +2,9 @@ import {
H1,
H4,
H6,
Tag,
} from "@blueprintjs/core";
import React, { FunctionComponent } from "react";
import { Link } from "react-router-dom";
import * as GQL from "../../../core/generated-graphql";
import { NavigationUtils } from "../../../utils/navigation";
import { TextUtils } from "../../../utils/text";
import { TagLink } from "../../Shared/TagLink";
import { SceneHelpers } from "../helpers";

View File

@@ -15,7 +15,6 @@ import {
Popover,
MenuItem,
} from "@blueprintjs/core";
import _ from "lodash";
import React, { FunctionComponent, useEffect, useState } from "react";
import * as GQL from "../../../core/generated-graphql";
import { StashService } from "../../../core/StashService";
@@ -229,7 +228,7 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
}
function renderScraperMenu() {
if (!queryableScrapers || queryableScrapers.length == 0) {
if (!queryableScrapers || queryableScrapers.length === 0) {
return;
}
@@ -272,7 +271,7 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
setStudioId(scene.studio.id);
}
if ((!performerIds || performerIds.length == 0) && scene.performers && scene.performers.length > 0) {
if ((!performerIds || performerIds.length === 0) && scene.performers && scene.performers.length > 0) {
let idPerfs = scene.performers.filter((p) => {
return p.id !== undefined && p.id !== null;
});
@@ -283,7 +282,7 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
}
}
if ((!tagIds || tagIds.length == 0) && scene.tags && scene.tags.length > 0) {
if ((!tagIds || tagIds.length === 0) && scene.tags && scene.tags.length > 0) {
let idTags = scene.tags.filter((p) => {
return p.id !== undefined && p.id !== null;
});
@@ -395,7 +394,7 @@ export const SceneEditPanel: FunctionComponent<IProps> = (props: IProps) => {
<span>Cover Image</span>
</label>
<Collapse isOpen={isCoverImageOpen}>
<img className="scene-cover" src={coverImagePreview} />
<img alt="Scene cover" className="scene-cover" src={coverImagePreview} />
<FileInput text="Choose image..." onInputChange={onCoverImageChange} inputProps={{accept: ".jpg,.jpeg,.png"}} />
</Collapse>
</div>

View File

@@ -5,7 +5,6 @@ import {
Divider,
FormGroup,
H3,
NumericInput,
Tag,
} from "@blueprintjs/core";
import { Field, FieldProps, Form, Formik, FormikActions, FormikProps } from "formik";
@@ -63,8 +62,8 @@ export const SceneMarkersPanel: FunctionComponent<ISceneMarkersPanelProps> = (pr
<div key={marker.id}>
<Divider />
<div>
<a onClick={() => onClickMarker(marker)}>{marker.title}</a>
{!isEditorOpen ? <a style={{float: "right"}} onClick={() => onOpenEditor(marker)}>Edit</a> : undefined}
<button className="button-link" onClick={() => onClickMarker(marker)}>{marker.title}</button>
{!isEditorOpen ? <button className="button-link" style={{float: "right"}} onClick={() => onOpenEditor(marker)}>Edit</button> : undefined}
</div>
<div>
{TextUtils.secondsToTimestamp(marker.seconds)}

View File

@@ -14,7 +14,7 @@ import {
Tree,
ITreeNode,
} from "@blueprintjs/core";
import React, { FunctionComponent, useEffect, useState, useRef } from "react";
import React, { FunctionComponent, useEffect, useState } from "react";
import { IBaseProps } from "../../models";
import { StashService } from "../../core/StashService";
import * as GQL from "../../core/generated-graphql";
@@ -449,19 +449,19 @@ export const SceneFilenameParser: FunctionComponent<IProps> = (props: IProps) =>
return !r.studioId.set;
});
if (newAllTitleSet != allTitleSet) {
if (newAllTitleSet !== allTitleSet) {
setAllTitleSet(newAllTitleSet);
}
if (newAllDateSet != allDateSet) {
if (newAllDateSet !== allDateSet) {
setAllDateSet(newAllDateSet);
}
if (newAllPerformerSet != allPerformerSet) {
if (newAllPerformerSet !== allPerformerSet) {
setAllTagSet(newAllPerformerSet);
}
if (newAllTagSet != allTagSet) {
if (newAllTagSet !== allTagSet) {
setAllTagSet(newAllTagSet);
}
if (newAllStudioSet != allStudioSet) {
if (newAllStudioSet !== allStudioSet) {
setAllStudioSet(newAllStudioSet);
}
}, [parserResult]);
@@ -1071,7 +1071,7 @@ export const SceneFilenameParser: FunctionComponent<IProps> = (props: IProps) =>
}
function renderTable() {
if (parserResult.length == 0) { return undefined; }
if (parserResult.length === 0) { return undefined; }
return (
<>

View File

@@ -1,4 +1,3 @@
import _ from "lodash";
import React, { FunctionComponent } from "react";
import { IBaseProps } from "../../models/base-props";
import { SceneList } from "./SceneList";

View File

@@ -1,5 +1,5 @@
import { Hotkey, Hotkeys, HotkeysTarget } from "@blueprintjs/core";
import React, { Component, FunctionComponent } from "react";
import React, { FunctionComponent } from "react";
import ReactJWPlayer from "react-jw-player";
import * as GQL from "../../../core/generated-graphql";
import { SceneHelpers } from "../helpers";

View File

@@ -1,5 +1,5 @@
import axios from "axios";
import React, { CSSProperties, FunctionComponent, RefObject, useEffect, useRef, useState } from "react";
import React, { CSSProperties, FunctionComponent, useEffect, useRef, useState } from "react";
import * as GQL from "../../../core/generated-graphql";
import { TextUtils } from "../../../utils/text";
import "./ScenePlayerScrubber.scss";
@@ -55,7 +55,6 @@ export const ScenePlayerScrubber: FunctionComponent<IScenePlayerScrubberProps> =
}
const [spriteItems, setSpriteItems] = useState<ISceneSpriteItem[]>([]);
const [delayedRender, setDelayedRender] = useState(false);
useEffect(() => {
if (!scrubberSliderEl.current) { return; }
@@ -63,6 +62,47 @@ export const ScenePlayerScrubber: FunctionComponent<IScenePlayerScrubberProps> =
}, [scrubberSliderEl]);
useEffect(() => {
async function fetchSpriteInfo() {
if (!props.scene || !props.scene.paths.vtt) { return; }
const response = await axios.get<string>(props.scene.paths.vtt, {responseType: "text"});
if (response.status !== 200) {
console.log(response.statusText);
}
// TODO: This is gnarly
const lines = response.data.split("\n");
if (lines.shift() !== "WEBVTT") { return; }
if (lines.shift() !== "") { return; }
let item: ISceneSpriteItem = {start: 0, end: 0, x: 0, y: 0, w: 0, h: 0};
const newSpriteItems: ISceneSpriteItem[] = [];
while (lines.length) {
const line = lines.shift();
if (line === undefined) { continue; }
if (line.includes("#") && line.includes("=") && line.includes(",")) {
const size = line.split("#")[1].split("=")[1].split(",");
item.x = Number(size[0]);
item.y = Number(size[1]);
item.w = Number(size[2]);
item.h = Number(size[3]);
newSpriteItems.push(item);
item = {start: 0, end: 0, x: 0, y: 0, w: 0, h: 0};
} else if (line.includes(" --> ")) {
const times = line.split(" --> ");
const start = times[0].split(":");
item.start = (+start[0]) * 60 * 60 + (+start[1]) * 60 + (+start[2]);
const end = times[1].split(":");
item.end = (+end[0]) * 60 * 60 + (+end[1]) * 60 + (+end[2]);
}
}
setSpriteItems(newSpriteItems);
}
fetchSpriteInfo();
}, [props.scene]);
@@ -77,30 +117,20 @@ export const ScenePlayerScrubber: FunctionComponent<IScenePlayerScrubberProps> =
}, [props.position]);
useEffect(() => {
let element = contentEl.current;
if (!element) { return; }
element.addEventListener("mousedown", onMouseDown, false);
element.addEventListener("mousemove", onMouseMove, false);
window.addEventListener("mouseup", onMouseUp, false);
return () => {
if (!element) { return; }
element.removeEventListener("mousedown", onMouseDown);
element.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp);
};
});
useEffect(() => {
if (!contentEl.current) { return; }
contentEl.current.addEventListener("mousedown", onMouseDown, false);
return () => {
if (!contentEl.current) { return; }
contentEl.current.removeEventListener("mousedown", onMouseDown);
};
});
useEffect(() => {
if (!contentEl.current) { return; }
contentEl.current.addEventListener("mousemove", onMouseMove, false);
return () => {
if (!contentEl.current) { return; }
contentEl.current.removeEventListener("mousemove", onMouseMove);
};
});
function onMouseUp(this: Window, event: MouseEvent) {
if (!startMouseEvent.current || !scrubberSliderEl.current) { return; }
mouseDown.current = false;
@@ -170,51 +200,6 @@ export const ScenePlayerScrubber: FunctionComponent<IScenePlayerScrubberProps> =
setPosition(newPosition);
}
async function fetchSpriteInfo() {
if (!props.scene || !props.scene.paths.vtt) { return; }
const response = await axios.get<string>(props.scene.paths.vtt, {responseType: "text"});
if (response.status !== 200) {
console.log(response.statusText);
}
// TODO: This is gnarly
const lines = response.data.split("\n");
if (lines.shift() !== "WEBVTT") { return; }
if (lines.shift() !== "") { return; }
let item: ISceneSpriteItem = {start: 0, end: 0, x: 0, y: 0, w: 0, h: 0};
const newSpriteItems: ISceneSpriteItem[] = [];
while (lines.length) {
const line = lines.shift();
if (line === undefined) { continue; }
if (line.includes("#") && line.includes("=") && line.includes(",")) {
const size = line.split("#")[1].split("=")[1].split(",");
item.x = Number(size[0]);
item.y = Number(size[1]);
item.w = Number(size[2]);
item.h = Number(size[3]);
newSpriteItems.push(item);
item = {start: 0, end: 0, x: 0, y: 0, w: 0, h: 0};
} else if (line.includes(" --> ")) {
const times = line.split(" --> ");
const start = times[0].split(":");
item.start = (+start[0]) * 60 * 60 + (+start[1]) * 60 + (+start[2]);
const end = times[1].split(":");
item.end = (+end[0]) * 60 * 60 + (+end[1]) * 60 + (+end[2]);
}
}
setSpriteItems(newSpriteItems);
// TODO: Very hacky. Need to wait for the scroll width to update from the image loading.
setTimeout(() => {
setDelayedRender(true);
}, 100);
}
function renderTags() {
function getTagStyle(i: number): CSSProperties {
if (!scrubberSliderEl.current ||
@@ -296,7 +281,7 @@ export const ScenePlayerScrubber: FunctionComponent<IScenePlayerScrubberProps> =
return (
<div className="scrubber-wrapper">
<a className="scrubber-button" id="scrubber-back" onClick={() => goBack()}>&lt;</a>
<button className="scrubber-button" id="scrubber-back" onClick={() => goBack()}>&lt;</button>
<div ref={contentEl} className="scrubber-content">
<div className="scrubber-tags-background" />
<div ref={positionIndicatorEl} id="scrubber-position-indicator" />
@@ -310,7 +295,7 @@ export const ScenePlayerScrubber: FunctionComponent<IScenePlayerScrubberProps> =
</div>
</div>
</div>
<a className="scrubber-button" id="scrubber-forward" onClick={() => goForward()}>&gt;</a>
<button className="scrubber-button" id="scrubber-forward" onClick={() => goForward()}>&gt;</button>
</div>
);
};

View File

@@ -1,19 +1,12 @@
import _ from "lodash";
import {
AnchorButton,
Button,
ButtonGroup,
ControlGroup,
FormGroup,
HTMLSelect,
InputGroup,
Menu,
MenuItem,
Popover,
Spinner,
Tag,
} from "@blueprintjs/core";
import React, { FunctionComponent, SyntheticEvent, useEffect, useRef, useState } from "react";
import React, { FunctionComponent, useEffect, useState } from "react";
import { FilterSelect } from "../select/FilterSelect";
import { FilterMultiSelect } from "../select/FilterMultiSelect";
import { StashService } from "../../core/StashService";
@@ -106,7 +99,7 @@ export const SceneSelectedOptions: FunctionComponent<IListOperationProps> = (pro
async function onSave() {
setIsLoading(true);
try {
const result = await updateScenes();
await updateScenes();
ToastUtils.success("Updated scenes");
} catch (e) {
ErrorUtils.handle(e);
@@ -143,7 +136,7 @@ export const SceneSelectedOptions: FunctionComponent<IListOperationProps> = (pro
first = false;
} else {
var studioId = scene.studio ? scene.studio.id : undefined;
if (ret != studioId) {
if (ret !== studioId) {
ret = undefined;
}
}
@@ -221,7 +214,7 @@ export const SceneSelectedOptions: FunctionComponent<IListOperationProps> = (pro
if (rating !== thisRating) {
rating = "";
}
if (studioId != thisStudio) {
if (studioId !== thisStudio) {
studioId = undefined;
}
const perfIds = !!scene.performers ? scene.performers.map(toId).sort() : [];

View File

@@ -120,7 +120,7 @@ export const FilterMultiSelect: React.FunctionComponent<IProps> = (props: IProps
break;
}
default: {
throw "Unhandled case in FilterMultiSelect";
throw new Error("Unhandled case in FilterMultiSelect");
}
}

View File

@@ -91,7 +91,7 @@ export const FilterSelect: React.FunctionComponent<IProps> = (props: IProps) =>
};
function onItemSelect(item: ValidTypes | undefined) {
if (item && item.id == "0") {
if (item && item.id === "0") {
item = undefined;
}

View File

@@ -1,7 +1,7 @@
import * as React from "react";
import { MenuItem } from "@blueprintjs/core";
import { ItemPredicate, ItemRenderer, Suggest } from "@blueprintjs/select";
import { ItemRenderer, Suggest } from "@blueprintjs/select";
import * as GQL from "../../core/generated-graphql";
import { StashService } from "../../core/StashService";
import { HTMLInputProps } from "../../models";

View File

@@ -50,7 +50,7 @@ export const ValidGalleriesSelect: React.FunctionComponent<IProps> = (props: IPr
};
function onItemSelect(item: GQL.ValidGalleriesForSceneValidGalleriesForScene | undefined) {
if (item && item.id == "0") {
if (item && item.id === "0") {
item = undefined;
}

View File

@@ -280,6 +280,28 @@ video.preview.portrait {
}
}
.button-link {
background-color: transparent;
color: #48aff0;
border-width: 0;
cursor: pointer;
display: inline;
padding: 0;
}
.button-link:hover {
text-decoration: underline;
}
.scrubber-button {
background-color: transparent;
color: #48aff0;
}
.scrubber-button:hover {
text-decoration: underline;
}
#jwplayer-container {
margin: 10px auto;
width: 75%;

View File

@@ -30,7 +30,7 @@ export class DurationUtils {
let factor = 1;
while(splits.length > 0) {
let thisSplit = splits.pop();
if (thisSplit == undefined) {
if (thisSplit === undefined) {
return 0;
}

View File

@@ -15,7 +15,7 @@ export class ImageUtils {
}
public static pasteImage(e : any, onLoadEnd: (this: FileReader) => any) {
if (e.clipboardData.files.length == 0) {
if (e.clipboardData.files.length === 0) {
return;
}

View File

@@ -1,4 +1,4 @@
import { EditableText, HTMLSelect, InputGroup, IOptionProps, TextArea } from "@blueprintjs/core";
import { EditableText, IOptionProps } from "@blueprintjs/core";
import React from "react";
import { EditableTextUtils } from "./editabletext";
import { FilterMultiSelect } from "../components/select/FilterMultiSelect";

View File

@@ -33,7 +33,7 @@ export class TextUtils {
public static fileNameFromPath(path: string): string {
if (!!path === false) { return "No File Name"; }
return path.replace(/^.*[\\\/]/, "");
return path.replace(/^.*[\\/]/, "");
}
public static age(dateString?: string, fromDateString?: string): number {