Fix error when viewing scenes related to objects with illegal characters in name (#395)

* Fix gitattributes for v2.5
This commit is contained in:
WithoutPants 2020-03-14 08:06:55 +11:00 committed by GitHub
parent 6f5f3112e1
commit 1a6374fae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 88 additions and 24 deletions

2
.gitattributes vendored
View File

@ -1,3 +1,3 @@
go.mod text eol=lf
go.sum text eol=lf
ui/v2.5/** -text
ui/v2.5/**/*.ts* text eol=lf

View File

@ -146,9 +146,7 @@ export const Scene: React.FC = () => {
/>
</Tab>
<Tab eventKey="scene-operations-panel" title="Operations">
<SceneOperationsPanel
scene={scene}
/>
<SceneOperationsPanel scene={scene} />
</Tab>
</Tabs>
</div>

View File

@ -9,7 +9,9 @@ interface IOperationsPanelProps {
scene: GQL.SceneDataFragment;
}
export const SceneOperationsPanel: FunctionComponent<IOperationsPanelProps> = (props: IOperationsPanelProps) => {
export const SceneOperationsPanel: FunctionComponent<IOperationsPanelProps> = (
props: IOperationsPanelProps
) => {
const Toast = useToast();
const [generateScreenshot] = StashService.useSceneGenerateScreenshot();
@ -25,7 +27,10 @@ export const SceneOperationsPanel: FunctionComponent<IOperationsPanelProps> = (p
return (
<>
<Button className="edit-button" onClick={() => onGenerateScreenshot(JWUtils.getPlayer().getPosition())}>
<Button
className="edit-button"
onClick={() => onGenerateScreenshot(JWUtils.getPlayer().getPosition())}
>
Generate thumbnail from current
</Button>
<Button className="edit-button" onClick={() => onGenerateScreenshot()}>

View File

@ -408,8 +408,8 @@ export class StashService {
}
public static useSceneGenerateScreenshot() {
return GQL.useSceneGenerateScreenshotMutation({
update: () => StashService.invalidateQueries(["findScenes"]),
return GQL.useSceneGenerateScreenshotMutation({
update: () => StashService.invalidateQueries(["findScenes"])
});
}
@ -514,7 +514,7 @@ export class StashService {
public static mutateStopJob() {
return StashService.client.mutate<GQL.StopJobMutation>({
mutation: GQL.StopJobDocument,
mutation: GQL.StopJobDocument
});
}
@ -574,39 +574,39 @@ export class StashService {
public static mutateMetadataScan(input: GQL.ScanMetadataInput) {
return StashService.client.mutate<GQL.MetadataScanMutation>({
mutation: GQL.MetadataScanDocument,
variables: { input },
variables: { input }
});
}
public static mutateMetadataAutoTag(input: GQL.AutoTagMetadataInput) {
return StashService.client.mutate<GQL.MetadataAutoTagMutation>({
mutation: GQL.MetadataAutoTagDocument,
variables: { input },
variables: { input }
});
}
public static mutateMetadataGenerate(input: GQL.GenerateMetadataInput) {
return StashService.client.mutate<GQL.MetadataGenerateMutation>({
mutation: GQL.MetadataGenerateDocument,
variables: { input },
variables: { input }
});
}
public static mutateMetadataClean() {
return StashService.client.mutate<GQL.MetadataCleanMutation>({
mutation: GQL.MetadataCleanDocument,
mutation: GQL.MetadataCleanDocument
});
}
public static mutateMetadataExport() {
return StashService.client.mutate<GQL.MetadataExportMutation>({
mutation: GQL.MetadataExportDocument,
mutation: GQL.MetadataExportDocument
});
}
public static mutateMetadataImport() {
return StashService.client.mutate<GQL.MetadataImportMutation>({
mutation: GQL.MetadataImportDocument,
mutation: GQL.MetadataImportDocument
});
}

View File

@ -186,6 +186,10 @@ export abstract class Criterion {
}
}
*/
public encodeValue(): CriterionValue {
return this.value;
}
}
export interface ICriterionOption {

View File

@ -1,5 +1,5 @@
import { CriterionModifier } from "src/core/generated-graphql";
import { ILabeledId, IOptionType } from "../types";
import { ILabeledId, IOptionType, encodeILabeledId } from "../types";
import { Criterion, CriterionType, ICriterionOption } from "./criterion";
export class PerformersCriterion extends Criterion {
@ -13,6 +13,12 @@ export class PerformersCriterion extends Criterion {
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map(o => {
return encodeILabeledId(o);
});
}
}
export class PerformersCriterionOption implements ICriterionOption {

View File

@ -1,5 +1,5 @@
import { CriterionModifier } from "src/core/generated-graphql";
import { ILabeledId, IOptionType } from "../types";
import { ILabeledId, IOptionType, encodeILabeledId } from "../types";
import { Criterion, CriterionType, ICriterionOption } from "./criterion";
export class StudiosCriterion extends Criterion {
@ -12,6 +12,12 @@ export class StudiosCriterion extends Criterion {
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map(o => {
return encodeILabeledId(o);
});
}
}
export class StudiosCriterionOption implements ICriterionOption {

View File

@ -1,5 +1,5 @@
import * as GQL from "src/core/generated-graphql";
import { ILabeledId, IOptionType } from "../types";
import { ILabeledId, IOptionType, encodeILabeledId } from "../types";
import { Criterion, CriterionType, ICriterionOption } from "./criterion";
export class TagsCriterion extends Criterion {
@ -22,6 +22,12 @@ export class TagsCriterion extends Criterion {
this.parameterName = "scene_tags";
}
}
public encodeValue() {
return this.value.map(o => {
return encodeILabeledId(o);
});
}
}
export class TagsCriterionOption implements ICriterionOption {

View File

@ -270,7 +270,11 @@ export class ListFilterModel {
this.criteria.forEach(criterion => {
const encodedCriterion: Partial<Criterion> = {
type: criterion.type,
value: criterion.value,
// #394 - the presence of a # symbol results in the query URL being
// malformed. We could set encode: true in the queryString.stringify
// call below, but this results in a URL that gets pretty long and ugly.
// Instead, we'll encode the criteria values.
value: criterion.encodeValue(),
modifier: criterion.modifier
};
const jsonCriterion = JSON.stringify(encodedCriterion);

View File

@ -22,6 +22,10 @@ export interface ILabeledValue {
value: string;
}
export function encodeILabeledId(o: ILabeledId) {
return { ...o, label: encodeURIComponent(o.label) };
}
export interface IOptionType {
id: string;
name?: string;

View File

@ -136,6 +136,10 @@ export abstract class Criterion<Option = any, Value = any> {
this.value = value;
}
}
public encodeValue(): Value {
return this.value;
}
}
export interface ICriterionOption {

View File

@ -1,5 +1,5 @@
import { CriterionModifier } from "../../../core/generated-graphql";
import { ILabeledId } from "../types";
import { ILabeledId, encodeILabeledId } from "../types";
import {
Criterion,
CriterionType,
@ -22,6 +22,10 @@ export class MoviesCriterion extends Criterion<IOptionType, ILabeledId[]> {
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map((o) => { return encodeILabeledId(o); });
}
}
export class MoviesCriterionOption implements ICriterionOption {

View File

@ -1,5 +1,5 @@
import { CriterionModifier } from "../../../core/generated-graphql";
import { ILabeledId } from "../types";
import { ILabeledId, encodeILabeledId } from "../types";
import {
Criterion,
CriterionType,
@ -23,6 +23,10 @@ export class PerformersCriterion extends Criterion<IOptionType, ILabeledId[]> {
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map((o) => { return encodeILabeledId(o); });
}
}
export class PerformersCriterionOption implements ICriterionOption {

View File

@ -1,5 +1,5 @@
import { CriterionModifier } from "../../../core/generated-graphql";
import { ILabeledId } from "../types";
import { ILabeledId, encodeILabeledId } from "../types";
import {
Criterion,
CriterionType,
@ -22,6 +22,10 @@ export class StudiosCriterion extends Criterion<IOptionType, ILabeledId[]> {
];
public options: IOptionType[] = [];
public value: ILabeledId[] = [];
public encodeValue() {
return this.value.map((o) => { return encodeILabeledId(o); });
}
}
export class StudiosCriterionOption implements ICriterionOption {

View File

@ -1,6 +1,6 @@
import * as GQL from "../../../core/generated-graphql";
import { CriterionModifier } from "../../../core/generated-graphql";
import { ILabeledId } from "../types";
import { ILabeledId, encodeILabeledId } from "../types";
import {
Criterion,
CriterionType,
@ -27,6 +27,10 @@ export class TagsCriterion extends Criterion<GQL.AllTagsForFilterAllTags, ILabel
this.parameterName = "scene_tags";
}
}
public encodeValue() {
return this.value.map((o) => { return encodeILabeledId(o); });
}
}
export class TagsCriterionOption implements ICriterionOption {

View File

@ -271,7 +271,12 @@ export class ListFilterModel {
this.criteria.forEach((criterion) => {
const encodedCriterion: any = {};
encodedCriterion.type = criterion.type;
encodedCriterion.value = criterion.value;
// #394 - the presence of a # symbol results in the query URL being
// malformed. We could set encode: true in the queryString.stringify
// call below, but this results in a URL that gets pretty long and ugly.
// Instead, we'll encode the criteria values.
encodedCriterion.value = criterion.encodeValue();
encodedCriterion.modifier = criterion.modifier;
const jsonCriterion = JSON.stringify(encodedCriterion);
encodedCriteria.push(jsonCriterion);

View File

@ -20,6 +20,12 @@ export interface ILabeledId {
label: string;
}
export function encodeILabeledId(o: ILabeledId) {
let ret = Object.assign({}, o);
ret.label = encodeURIComponent(o.label);
return ret;
}
export interface ILabeledValue {
label: string;
value: string;