mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Prettier
This commit is contained in:
@@ -4,34 +4,38 @@ const readImage = (file: File, onLoadEnd: (this: FileReader) => void) => {
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.onloadend = onLoadEnd;
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const pasteImage = (event: ClipboardEvent, onLoadEnd: (this: FileReader) => void) => {
|
||||
const pasteImage = (
|
||||
event: ClipboardEvent,
|
||||
onLoadEnd: (this: FileReader) => void
|
||||
) => {
|
||||
const files = event?.clipboardData?.files;
|
||||
if(!files?.length)
|
||||
return;
|
||||
if (!files?.length) return;
|
||||
|
||||
const file = files[0];
|
||||
readImage(file, onLoadEnd);
|
||||
}
|
||||
};
|
||||
|
||||
const onImageChange = (event: React.FormEvent<HTMLInputElement>, onLoadEnd: (this: FileReader) => void) => {
|
||||
const onImageChange = (
|
||||
event: React.FormEvent<HTMLInputElement>,
|
||||
onLoadEnd: (this: FileReader) => void
|
||||
) => {
|
||||
const file = event?.currentTarget?.files?.[0];
|
||||
if(file)
|
||||
readImage(file, onLoadEnd);
|
||||
}
|
||||
if (file) readImage(file, onLoadEnd);
|
||||
};
|
||||
|
||||
const usePasteImage = (onLoadEnd: (this: FileReader) => void) => {
|
||||
useEffect(() => {
|
||||
const paste = (event: ClipboardEvent) => ( pasteImage(event, onLoadEnd) );
|
||||
const paste = (event: ClipboardEvent) => pasteImage(event, onLoadEnd);
|
||||
document.addEventListener("paste", paste);
|
||||
|
||||
return () => document.removeEventListener("paste", paste);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const Image = {
|
||||
onImageChange,
|
||||
usePasteImage
|
||||
}
|
||||
};
|
||||
export default Image;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { default as ImageUtils } from './image';
|
||||
export { default as NavUtils } from './navigation';
|
||||
export { default as TableUtils } from './table';
|
||||
export { default as TextUtils } from './text';
|
||||
export { default as ImageUtils } from "./image";
|
||||
export { default as NavUtils } from "./navigation";
|
||||
export { default as TableUtils } from "./table";
|
||||
export { default as TextUtils } from "./text";
|
||||
|
||||
@@ -5,51 +5,54 @@ import { TagsCriterion } from "../models/list-filter/criteria/tags";
|
||||
import { ListFilterModel } from "../models/list-filter/filter";
|
||||
import { FilterMode } from "../models/list-filter/types";
|
||||
|
||||
const makePerformerScenesUrl = (performer: Partial<GQL.PerformerDataFragment>) => {
|
||||
if (!performer.id)
|
||||
return "#";
|
||||
const makePerformerScenesUrl = (
|
||||
performer: Partial<GQL.PerformerDataFragment>
|
||||
) => {
|
||||
if (!performer.id) return "#";
|
||||
const filter = new ListFilterModel(FilterMode.Scenes);
|
||||
const criterion = new PerformersCriterion();
|
||||
criterion.value = [{ id: performer.id, label: performer.name || `Performer ${performer.id}` }];
|
||||
criterion.value = [
|
||||
{ id: performer.id, label: performer.name || `Performer ${performer.id}` }
|
||||
];
|
||||
filter.criteria.push(criterion);
|
||||
return `/scenes?${filter.makeQueryParameters()}`;
|
||||
}
|
||||
};
|
||||
|
||||
const makeStudioScenesUrl = (studio: Partial<GQL.StudioDataFragment>) => {
|
||||
if (!studio.id)
|
||||
return "#";
|
||||
if (!studio.id) return "#";
|
||||
const filter = new ListFilterModel(FilterMode.Scenes);
|
||||
const criterion = new StudiosCriterion();
|
||||
criterion.value = [{ id: studio.id, label: studio.name || `Studio ${studio.id}` }];
|
||||
criterion.value = [
|
||||
{ id: studio.id, label: studio.name || `Studio ${studio.id}` }
|
||||
];
|
||||
filter.criteria.push(criterion);
|
||||
return `/scenes?${filter.makeQueryParameters()}`;
|
||||
}
|
||||
};
|
||||
|
||||
const makeTagScenesUrl = (tag: Partial<GQL.TagDataFragment>) => {
|
||||
if (!tag.id)
|
||||
return "#";
|
||||
if (!tag.id) return "#";
|
||||
const filter = new ListFilterModel(FilterMode.Scenes);
|
||||
const criterion = new TagsCriterion("tags");
|
||||
criterion.value = [{ id: tag.id, label: tag.name || `Tag ${tag.id}` }];
|
||||
filter.criteria.push(criterion);
|
||||
return `/scenes?${filter.makeQueryParameters()}`;
|
||||
}
|
||||
};
|
||||
|
||||
const makeTagSceneMarkersUrl = (tag: Partial<GQL.TagDataFragment>) => {
|
||||
if (!tag.id)
|
||||
return "#";
|
||||
if (!tag.id) return "#";
|
||||
const filter = new ListFilterModel(FilterMode.SceneMarkers);
|
||||
const criterion = new TagsCriterion("tags");
|
||||
criterion.value = [{ id: tag.id, label: tag.name || `Tag ${tag.id}` }];
|
||||
filter.criteria.push(criterion);
|
||||
return `/scenes/markers?${filter.makeQueryParameters()}`;
|
||||
}
|
||||
};
|
||||
|
||||
const makeSceneMarkerUrl = (sceneMarker: Partial<GQL.SceneMarkerDataFragment>) => {
|
||||
if (!sceneMarker.id || !sceneMarker.scene)
|
||||
return "#";
|
||||
const makeSceneMarkerUrl = (
|
||||
sceneMarker: Partial<GQL.SceneMarkerDataFragment>
|
||||
) => {
|
||||
if (!sceneMarker.id || !sceneMarker.scene) return "#";
|
||||
return `/scenes/${sceneMarker.scene.id}?t=${sceneMarker.seconds}`;
|
||||
}
|
||||
};
|
||||
|
||||
const Nav = {
|
||||
makePerformerScenesUrl,
|
||||
@@ -57,5 +60,5 @@ const Nav = {
|
||||
makeTagSceneMarkersUrl,
|
||||
makeTagScenesUrl,
|
||||
makeSceneMarkerUrl
|
||||
}
|
||||
};
|
||||
export default Nav;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React from "react";
|
||||
import { Form } from 'react-bootstrap';
|
||||
import { Form } from "react-bootstrap";
|
||||
import { FilterSelect } from "src/components/Shared";
|
||||
|
||||
const renderEditableTextTableRow = (options: {
|
||||
title: string;
|
||||
value?: string | number;
|
||||
isEditing: boolean;
|
||||
onChange: ((value: string) => void);
|
||||
onChange: (value: string) => void;
|
||||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
@@ -14,19 +14,25 @@ const renderEditableTextTableRow = (options: {
|
||||
<Form.Control
|
||||
readOnly={!options.isEditing}
|
||||
plaintext={!options.isEditing}
|
||||
onChange={(event: React.FormEvent<HTMLInputElement>) => ( options.onChange(event.currentTarget.value) )}
|
||||
value={typeof options.value === 'number' ? options.value.toString() : options.value}
|
||||
onChange={(event: React.FormEvent<HTMLInputElement>) =>
|
||||
options.onChange(event.currentTarget.value)
|
||||
}
|
||||
value={
|
||||
typeof options.value === "number"
|
||||
? options.value.toString()
|
||||
: options.value
|
||||
}
|
||||
placeholder={options.title}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
const renderTextArea = (options: {
|
||||
title: string,
|
||||
value: string | undefined,
|
||||
isEditing: boolean,
|
||||
onChange: ((value: string) => void),
|
||||
title: string;
|
||||
value: string | undefined;
|
||||
isEditing: boolean;
|
||||
onChange: (value: string) => void;
|
||||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
@@ -35,19 +41,21 @@ const renderTextArea = (options: {
|
||||
as="textarea"
|
||||
readOnly={!options.isEditing}
|
||||
plaintext={!options.isEditing}
|
||||
onChange={(event: React.FormEvent<HTMLTextAreaElement>) => ( options.onChange(event.currentTarget.value) )}
|
||||
onChange={(event: React.FormEvent<HTMLTextAreaElement>) =>
|
||||
options.onChange(event.currentTarget.value)
|
||||
}
|
||||
value={options.value}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
const renderInputGroup = (options: {
|
||||
title: string,
|
||||
placeholder?: string,
|
||||
value: string | undefined,
|
||||
isEditing: boolean,
|
||||
onChange: ((value: string) => void),
|
||||
title: string;
|
||||
placeholder?: string;
|
||||
value: string | undefined;
|
||||
isEditing: boolean;
|
||||
onChange: (value: string) => void;
|
||||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
@@ -56,19 +64,21 @@ const renderInputGroup = (options: {
|
||||
readOnly={!options.isEditing}
|
||||
plaintext={!options.isEditing}
|
||||
defaultValue={options.value}
|
||||
placeholder={options.placeholder ?? options.title}
|
||||
onChange={(event: React.FormEvent<HTMLInputElement>) => ( options.onChange(event.currentTarget.value) )}
|
||||
placeholder={options.placeholder ?? options.title}
|
||||
onChange={(event: React.FormEvent<HTMLInputElement>) =>
|
||||
options.onChange(event.currentTarget.value)
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
const renderHtmlSelect = (options: {
|
||||
title: string,
|
||||
value?: string | number,
|
||||
isEditing: boolean,
|
||||
onChange: ((value: string) => void),
|
||||
selectOptions: Array<string | number>,
|
||||
title: string;
|
||||
value?: string | number;
|
||||
isEditing: boolean;
|
||||
onChange: (value: string) => void;
|
||||
selectOptions: Array<string | number>;
|
||||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
@@ -77,37 +87,39 @@ const renderHtmlSelect = (options: {
|
||||
as="select"
|
||||
readOnly={!options.isEditing}
|
||||
plaintext={!options.isEditing}
|
||||
onChange={(event: React.FormEvent<HTMLSelectElement>) => ( options.onChange(event.currentTarget.value) )}
|
||||
onChange={(event: React.FormEvent<HTMLSelectElement>) =>
|
||||
options.onChange(event.currentTarget.value)
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
// TODO: isediting
|
||||
const renderFilterSelect = (options: {
|
||||
title: string,
|
||||
type: "performers" | "studios" | "tags",
|
||||
initialId: string | undefined,
|
||||
onChange: ((id: string | undefined) => void),
|
||||
title: string;
|
||||
type: "performers" | "studios" | "tags";
|
||||
initialId: string | undefined;
|
||||
onChange: (id: string | undefined) => void;
|
||||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
<FilterSelect
|
||||
type={options.type}
|
||||
onSelect={(items) => options.onChange(items[0]?.id)}
|
||||
onSelect={items => options.onChange(items[0]?.id)}
|
||||
initialIds={options.initialId ? [options.initialId] : []}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
// TODO: isediting
|
||||
const renderMultiSelect = (options: {
|
||||
title: string,
|
||||
type: "performers" | "studios" | "tags",
|
||||
initialIds: string[] | undefined,
|
||||
onChange: ((ids: string[]) => void),
|
||||
title: string;
|
||||
type: "performers" | "studios" | "tags";
|
||||
initialIds: string[] | undefined;
|
||||
onChange: (ids: string[]) => void;
|
||||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
@@ -115,12 +127,12 @@ const renderMultiSelect = (options: {
|
||||
<FilterSelect
|
||||
type={options.type}
|
||||
isMulti
|
||||
onSelect={(items) => options.onChange(items.map((i) => i.id))}
|
||||
onSelect={items => options.onChange(items.map(i => i.id))}
|
||||
initialIds={options.initialIds ?? []}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
const Table = {
|
||||
renderEditableTextTableRow,
|
||||
@@ -129,5 +141,5 @@ const Table = {
|
||||
renderHtmlSelect,
|
||||
renderFilterSelect,
|
||||
renderMultiSelect
|
||||
}
|
||||
};
|
||||
export default Table;
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
const Units = [
|
||||
"bytes",
|
||||
"kB",
|
||||
"MB",
|
||||
"GB",
|
||||
"TB",
|
||||
"PB",
|
||||
];
|
||||
const Units = ["bytes", "kB", "MB", "GB", "TB", "PB"];
|
||||
|
||||
const truncate = (value?: string, limit: number = 100, tail: string = "...") => {
|
||||
if (!value)
|
||||
return "";
|
||||
return value.length > limit
|
||||
? value.substring(0, limit) + tail
|
||||
: value;
|
||||
}
|
||||
const truncate = (
|
||||
value?: string,
|
||||
limit: number = 100,
|
||||
tail: string = "..."
|
||||
) => {
|
||||
if (!value) return "";
|
||||
return value.length > limit ? value.substring(0, limit) + tail : value;
|
||||
};
|
||||
|
||||
const fileSize = (bytes: number = 0, precision: number = 2) => {
|
||||
if (Number.isNaN(parseFloat(String(bytes))) || !Number.isFinite(bytes))
|
||||
@@ -21,13 +15,13 @@ const fileSize = (bytes: number = 0, precision: number = 2) => {
|
||||
|
||||
let unit = 0;
|
||||
let count = bytes;
|
||||
while ( count >= 1024 ) {
|
||||
while (count >= 1024) {
|
||||
count /= 1024;
|
||||
unit++;
|
||||
}
|
||||
|
||||
return `${bytes.toFixed(+precision)} ${Units[unit]}`;
|
||||
}
|
||||
};
|
||||
|
||||
const secondsToTimestamp = (seconds: number) => {
|
||||
let ret = new Date(seconds * 1000).toISOString().substr(11, 8);
|
||||
@@ -41,34 +35,35 @@ const secondsToTimestamp = (seconds: number) => {
|
||||
ret = ret.substr(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
const fileNameFromPath = (path: string) => {
|
||||
if (!!path === false)
|
||||
return "No File Name";
|
||||
if (!!path === false) return "No File Name";
|
||||
return path.replace(/^.*[\\/]/, "");
|
||||
}
|
||||
};
|
||||
|
||||
const getAge = (dateString?: string, fromDateString?: string) => {
|
||||
if (!dateString)
|
||||
return 0;
|
||||
if (!dateString) return 0;
|
||||
|
||||
const birthdate = new Date(dateString);
|
||||
const fromDate = fromDateString ? new Date(fromDateString) : new Date();
|
||||
|
||||
let age = fromDate.getFullYear() - birthdate.getFullYear();
|
||||
if (birthdate.getMonth() > fromDate.getMonth() ||
|
||||
(birthdate.getMonth() >= fromDate.getMonth() && birthdate.getDay() > fromDate.getDay())) {
|
||||
if (
|
||||
birthdate.getMonth() > fromDate.getMonth() ||
|
||||
(birthdate.getMonth() >= fromDate.getMonth() &&
|
||||
birthdate.getDay() > fromDate.getDay())
|
||||
) {
|
||||
age -= 1;
|
||||
}
|
||||
|
||||
return age;
|
||||
}
|
||||
};
|
||||
|
||||
const bitRate = (bitrate: number) => {
|
||||
const megabits = bitrate / 1000000;
|
||||
return `${megabits.toFixed(2)} megabits per second`;
|
||||
}
|
||||
};
|
||||
|
||||
const resolution = (height: number) => {
|
||||
if (height >= 240 && height < 480) {
|
||||
@@ -86,7 +81,7 @@ const resolution = (height: number) => {
|
||||
if (height >= 2160) {
|
||||
return "4K";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const TextUtils = {
|
||||
truncate,
|
||||
@@ -96,6 +91,6 @@ const TextUtils = {
|
||||
age: getAge,
|
||||
bitRate,
|
||||
resolution
|
||||
}
|
||||
};
|
||||
|
||||
export default TextUtils;
|
||||
|
||||
Reference in New Issue
Block a user