mirror of https://github.com/stashapp/stash.git
Remove hotkeys and fix tag selection (#505)
* Remove broken scene player hotkeys * Disable closing tag select menu after a select
This commit is contained in:
parent
52a1059380
commit
a0306bfbd2
|
@ -46,7 +46,6 @@
|
|||
"react-apollo": "^3.1.3",
|
||||
"react-bootstrap": "^1.0.0-beta.16",
|
||||
"react-dom": "16.12.0",
|
||||
"react-hotkeys": "^2.0.0",
|
||||
"react-images": "0.5.19",
|
||||
"react-intl": "^3.12.0",
|
||||
"react-jw-player": "1.19.0",
|
||||
|
|
|
@ -45,7 +45,10 @@ export const GalleryList: React.FC = () => {
|
|||
</Link>
|
||||
</td>
|
||||
<td className="d-none d-sm-block">
|
||||
<Link to={`/galleries/${gallery.id}`}>{gallery.path} ({gallery.files.length} {gallery.files.length === 1 ? 'image' : 'images'})</Link>
|
||||
<Link to={`/galleries/${gallery.id}`}>
|
||||
{gallery.path} ({gallery.files.length}{" "}
|
||||
{gallery.files.length === 1 ? "image" : "images"})
|
||||
</Link>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
|
|
@ -253,7 +253,7 @@ export const Movie: React.FC = () => {
|
|||
})}
|
||||
{TableUtils.renderHtmlSelect({
|
||||
title: "Rating",
|
||||
value: rating ? rating : "",
|
||||
value: rating ?? "",
|
||||
isEditing,
|
||||
onChange: (value: string) =>
|
||||
setRating(Number.parseInt(value, 10)),
|
||||
|
|
|
@ -189,7 +189,10 @@ export const Performer: React.FC = () => {
|
|||
{performer.twitter && (
|
||||
<Button className="minimal">
|
||||
<a
|
||||
href={TextUtils.sanitiseURL(performer.twitter, TextUtils.twitterURL)}
|
||||
href={TextUtils.sanitiseURL(
|
||||
performer.twitter,
|
||||
TextUtils.twitterURL
|
||||
)}
|
||||
className="twitter"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
@ -201,7 +204,10 @@ export const Performer: React.FC = () => {
|
|||
{performer.instagram && (
|
||||
<Button className="minimal">
|
||||
<a
|
||||
href={TextUtils.sanitiseURL(performer.instagram, TextUtils.instagramURL)}
|
||||
href={TextUtils.sanitiseURL(
|
||||
performer.instagram,
|
||||
TextUtils.instagramURL
|
||||
)}
|
||||
className="instagram"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
|
@ -215,18 +221,14 @@ export const Performer: React.FC = () => {
|
|||
|
||||
function renderPerformerImage() {
|
||||
if (imagePreview) {
|
||||
return (
|
||||
<img className="photo" src={imagePreview} alt="Performer" />
|
||||
);
|
||||
return <img className="photo" src={imagePreview} alt="Performer" />;
|
||||
}
|
||||
}
|
||||
|
||||
function renderNewView() {
|
||||
return (
|
||||
<div className="row new-view">
|
||||
<div className="col-4">
|
||||
{renderPerformerImage()}
|
||||
</div>
|
||||
<div className="col-4">{renderPerformerImage()}</div>
|
||||
<div className="col-6">
|
||||
<h2>Create Performer</h2>
|
||||
{renderTabs()}
|
||||
|
|
|
@ -11,7 +11,12 @@ import {
|
|||
ScrapePerformerSuggest,
|
||||
LoadingIndicator,
|
||||
} from "src/components/Shared";
|
||||
import { ImageUtils, TableUtils, TextUtils, EditableTextUtils } from "src/utils";
|
||||
import {
|
||||
ImageUtils,
|
||||
TableUtils,
|
||||
TextUtils,
|
||||
EditableTextUtils,
|
||||
} from "src/utils";
|
||||
import { useToast } from "src/hooks";
|
||||
|
||||
interface IPerformerDetails {
|
||||
|
@ -100,22 +105,22 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
|||
);
|
||||
}
|
||||
|
||||
function translateScrapedGender(gender?: string) {
|
||||
if (!gender) {
|
||||
function translateScrapedGender(scrapedGender?: string) {
|
||||
if (!scrapedGender) {
|
||||
return;
|
||||
}
|
||||
|
||||
let retEnum : GQL.GenderEnum | undefined;
|
||||
let retEnum: GQL.GenderEnum | undefined;
|
||||
|
||||
// try to translate from enum values first
|
||||
const upperGender = gender?.toUpperCase();
|
||||
const upperGender = scrapedGender?.toUpperCase();
|
||||
const asEnum = StashService.genderToString(upperGender as GQL.GenderEnum);
|
||||
if (asEnum) {
|
||||
retEnum = StashService.stringToGender(asEnum);
|
||||
} else {
|
||||
// try to match against gender strings
|
||||
const caseInsensitive = true;
|
||||
retEnum = StashService.stringToGender(gender, caseInsensitive);
|
||||
retEnum = StashService.stringToGender(scrapedGender, caseInsensitive);
|
||||
}
|
||||
|
||||
return StashService.genderToString(retEnum);
|
||||
|
@ -131,7 +136,10 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
|||
|
||||
// image is a base64 string
|
||||
// #404: don't overwrite image if it has been modified by the user
|
||||
if (image === undefined && (state as GQL.ScrapedPerformerDataFragment).image !== undefined) {
|
||||
if (
|
||||
image === undefined &&
|
||||
(state as GQL.ScrapedPerformerDataFragment).image !== undefined
|
||||
) {
|
||||
const imageStr = (state as GQL.ScrapedPerformerDataFragment).image;
|
||||
setImage(imageStr ?? undefined);
|
||||
if (onImageChange) {
|
||||
|
|
|
@ -145,7 +145,7 @@ export const ParserInput: React.FC<IParserInputProps> = (
|
|||
key={item.field}
|
||||
onSelect={() => addParserField(item)}
|
||||
>
|
||||
<span>{item.field || "{}"}</span>
|
||||
<span className="mr-2">{item.field || "{}"}</span>
|
||||
<span className="ml-auto text-muted">{item.helperText}</span>
|
||||
</Dropdown.Item>
|
||||
))}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from "react";
|
||||
import ReactJWPlayer from "react-jw-player";
|
||||
import { HotKeys } from "react-hotkeys";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
import { StashService } from "src/core/StashService";
|
||||
import { JWUtils } from "src/utils";
|
||||
|
@ -21,13 +20,6 @@ interface IScenePlayerState {
|
|||
config: Record<string, any>;
|
||||
}
|
||||
|
||||
const KeyMap = {
|
||||
NUM0: "0",
|
||||
NUM1: "1",
|
||||
NUM2: "2",
|
||||
SPACE: " ",
|
||||
};
|
||||
|
||||
export class ScenePlayerImpl extends React.Component<
|
||||
IScenePlayerProps,
|
||||
IScenePlayerState
|
||||
|
@ -37,21 +29,6 @@ export class ScenePlayerImpl extends React.Component<
|
|||
private player: any;
|
||||
private lastTime = 0;
|
||||
|
||||
private KeyHandlers = {
|
||||
NUM0: () => {
|
||||
this.onReset();
|
||||
},
|
||||
NUM1: () => {
|
||||
this.onDecrease();
|
||||
},
|
||||
NUM2: () => {
|
||||
this.onIncrease();
|
||||
},
|
||||
SPACE: () => {
|
||||
this.onPause();
|
||||
},
|
||||
};
|
||||
|
||||
constructor(props: IScenePlayerProps) {
|
||||
super(props);
|
||||
this.onReady = this.onReady.bind(this);
|
||||
|
@ -207,31 +184,25 @@ export class ScenePlayerImpl extends React.Component<
|
|||
|
||||
public render() {
|
||||
return (
|
||||
<HotKeys
|
||||
keyMap={KeyMap}
|
||||
handlers={this.KeyHandlers}
|
||||
className="row scene-player"
|
||||
<div
|
||||
id="jwplayer-container"
|
||||
className="w-100 col-sm-9 m-sm-auto no-gutter"
|
||||
>
|
||||
<div
|
||||
id="jwplayer-container"
|
||||
className="w-100 col-sm-9 m-sm-auto no-gutter"
|
||||
>
|
||||
<ReactJWPlayer
|
||||
playerId={JWUtils.playerID}
|
||||
playerScript="/jwplayer/jwplayer.js"
|
||||
customProps={this.state.config}
|
||||
onReady={this.onReady}
|
||||
onSeeked={this.onSeeked}
|
||||
onTime={this.onTime}
|
||||
/>
|
||||
<ScenePlayerScrubber
|
||||
scene={this.props.scene}
|
||||
position={this.state.scrubberPosition}
|
||||
onSeek={this.onScrubberSeek}
|
||||
onScrolled={this.onScrubberScrolled}
|
||||
/>
|
||||
</div>
|
||||
</HotKeys>
|
||||
<ReactJWPlayer
|
||||
playerId={JWUtils.playerID}
|
||||
playerScript="/jwplayer/jwplayer.js"
|
||||
customProps={this.state.config}
|
||||
onReady={this.onReady}
|
||||
onSeeked={this.onSeeked}
|
||||
onTime={this.onTime}
|
||||
/>
|
||||
<ScenePlayerScrubber
|
||||
scene={this.props.scene}
|
||||
position={this.state.scrubberPosition}
|
||||
onSeek={this.onScrubberSeek}
|
||||
onScrolled={this.onScrubberScrolled}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,7 +182,9 @@ export const SceneCard: React.FC<ISceneCardProps> = (
|
|||
return (
|
||||
<div>
|
||||
<Button className="minimal">
|
||||
<span className="fa-icon"><SweatDrops /></span>
|
||||
<span className="fa-icon">
|
||||
<SweatDrops />
|
||||
</span>
|
||||
<span>{props.scene.o_counter}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -151,9 +151,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
|
|||
<div className="row">
|
||||
<span className="col-4">Downloaded From</span>
|
||||
<span className="col-8 text-truncate">
|
||||
<a href={TextUtils.sanitiseURL(props.scene.url)}>
|
||||
{props.scene.url}
|
||||
</a>
|
||||
<a href={TextUtils.sanitiseURL(props.scene.url)}>{props.scene.url}</a>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -84,7 +84,7 @@ export const SceneMarkerForm: React.FC<ISceneMarkerForm> = ({
|
|||
)
|
||||
}
|
||||
numericValue={Number.parseInt(fieldProps.field.value ?? "0", 10)}
|
||||
mandatory={true}
|
||||
mandatory
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -307,7 +307,8 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||
onChange={() => setForceMkv(!forceMkv)}
|
||||
/>
|
||||
<Form.Text className="text-muted">
|
||||
Treat Matroska (MKV) as a supported container. Recommended for Chromium based browsers
|
||||
Treat Matroska (MKV) as a supported container. Recommended for
|
||||
Chromium based browsers
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
<Form.Group id="force-options-hevc">
|
||||
|
@ -318,7 +319,8 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||
onChange={() => setForceHevc(!forceHevc)}
|
||||
/>
|
||||
<Form.Text className="text-muted">
|
||||
Treat HEVC as a supported codec. Recommended for Safari or some Android based browsers
|
||||
Treat HEVC as a supported codec. Recommended for Safari or some
|
||||
Android based browsers
|
||||
</Form.Text>
|
||||
</Form.Group>
|
||||
</Form.Group>
|
||||
|
|
|
@ -68,9 +68,10 @@ class LogEntry {
|
|||
const MAX_LOG_ENTRIES = 200;
|
||||
const logLevels = ["Debug", "Info", "Warning", "Error"];
|
||||
|
||||
const logReducer = (existingEntries:LogEntry[], newEntries:LogEntry[]) => (
|
||||
[...newEntries.reverse(), ...existingEntries]
|
||||
);
|
||||
const logReducer = (existingEntries: LogEntry[], newEntries: LogEntry[]) => [
|
||||
...newEntries.reverse(),
|
||||
...existingEntries,
|
||||
];
|
||||
|
||||
export const SettingsLogsPanel: React.FC = () => {
|
||||
const { data, error } = StashService.useLoggingSubscribe();
|
||||
|
@ -78,10 +79,9 @@ export const SettingsLogsPanel: React.FC = () => {
|
|||
const [currentData, dispatchLogUpdate] = useReducer(logReducer, []);
|
||||
const [logLevel, setLogLevel] = useState<string>("Info");
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const newData = (data?.loggingSubscribe ?? []).map((e) => new LogEntry(e));
|
||||
dispatchLogUpdate(newData)
|
||||
dispatchLogUpdate(newData);
|
||||
}, [data]);
|
||||
|
||||
const oldData = (existingData?.logs ?? []).map((e) => new LogEntry(e));
|
||||
|
|
|
@ -105,9 +105,9 @@ export const SettingsTasksPanel: React.FC = () => {
|
|||
cancel={{ onClick: () => setIsCleanAlertOpen(false) }}
|
||||
>
|
||||
<p>
|
||||
Are you sure you want to Clean? This will delete database information and
|
||||
generated content for all scenes and galleries that are no longer found in the
|
||||
filesystem.
|
||||
Are you sure you want to Clean? This will delete database information
|
||||
and generated content for all scenes and galleries that are no longer
|
||||
found in the filesystem.
|
||||
</p>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -7,14 +7,19 @@ interface IProps {
|
|||
disabled?: boolean;
|
||||
numericValue: number | undefined;
|
||||
mandatory?: boolean;
|
||||
onValueChange(valueAsNumber: number | undefined, valueAsString?: string): void;
|
||||
onValueChange(
|
||||
valueAsNumber: number | undefined,
|
||||
valueAsString?: string
|
||||
): void;
|
||||
onReset?(): void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const DurationInput: React.FC<IProps> = (props: IProps) => {
|
||||
const [value, setValue] = useState<string | undefined>(
|
||||
props.numericValue !== undefined ? DurationUtils.secondsToString(props.numericValue) : undefined
|
||||
props.numericValue !== undefined
|
||||
? DurationUtils.secondsToString(props.numericValue)
|
||||
: undefined
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -22,7 +22,7 @@ export const ImageInput: React.FC<IImageInput> = ({
|
|||
<Form.Control
|
||||
type="file"
|
||||
onChange={onImageChange}
|
||||
accept={`.jpg,.jpeg,.png${acceptSVG ? ',.svg' : ''}`}
|
||||
accept={`.jpg,.jpeg,.png${acceptSVG ? ",.svg" : ""}`}
|
||||
/>
|
||||
</Form.Label>
|
||||
);
|
||||
|
|
|
@ -42,6 +42,7 @@ interface ISelectProps {
|
|||
placeholder?: string;
|
||||
showDropdown?: boolean;
|
||||
groupHeader?: string;
|
||||
closeMenuOnSelect?: boolean;
|
||||
}
|
||||
|
||||
interface ISceneGallerySelect {
|
||||
|
@ -355,6 +356,7 @@ export const TagSelect: React.FC<IFilterProps> = (props) => {
|
|||
items={items}
|
||||
onCreateOption={onCreate}
|
||||
selectedOptions={selected}
|
||||
closeMenuOnSelect={false}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -376,6 +378,7 @@ const SelectComponent: React.FC<ISelectProps & ITypeProps> = ({
|
|||
placeholder,
|
||||
showDropdown = true,
|
||||
groupHeader,
|
||||
closeMenuOnSelect = true,
|
||||
}) => {
|
||||
const defaultValue =
|
||||
items.filter((item) => initialIds?.indexOf(item.value) !== -1) ?? null;
|
||||
|
@ -421,6 +424,7 @@ const SelectComponent: React.FC<ISelectProps & ITypeProps> = ({
|
|||
isDisabled,
|
||||
isLoading,
|
||||
styles,
|
||||
closeMenuOnSelect,
|
||||
components: {
|
||||
IndicatorSeparator: () => null,
|
||||
...((!showDropdown || isDisabled) && { DropdownIndicator: () => null }),
|
||||
|
|
|
@ -10,7 +10,7 @@ export const Stats: React.FC = () => {
|
|||
|
||||
if (error) return <span>error.message</span>;
|
||||
|
||||
var size = data.stats.scene_size_count.split(" ")
|
||||
const size = data.stats.scene_size_count.split(" ");
|
||||
|
||||
return (
|
||||
<div className="mt-5">
|
||||
|
@ -18,7 +18,7 @@ export const Stats: React.FC = () => {
|
|||
<div className="stats-element">
|
||||
<p className="title">
|
||||
<FormattedNumber value={parseFloat(size[0])} />
|
||||
{" " + size[1]}
|
||||
{` ${size[1]}`}
|
||||
</p>
|
||||
<p className="heading">
|
||||
<FormattedMessage id="library-size" defaultMessage="Library size" />
|
||||
|
|
|
@ -196,14 +196,6 @@ div.dropdown-menu {
|
|||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
|
||||
& > * {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
& > :last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,8 +388,8 @@ div.dropdown-menu {
|
|||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
input[type=file], /* FF, IE7+, chrome (except button) */
|
||||
input[type=file]::-webkit-file-upload-button {
|
||||
input[type="file"], /* FF, IE7+, chrome (except button) */
|
||||
input[type="file"]::-webkit-file-upload-button {
|
||||
/* chromes and blink button */
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ export class PerformerIsMissingCriterion extends IsMissingCriterion {
|
|||
"piercings",
|
||||
"aliases",
|
||||
"gender",
|
||||
"scenes"
|
||||
"scenes",
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@ import {
|
|||
} from "./criterion";
|
||||
import { FavoriteCriterion } from "./favorite";
|
||||
import { HasMarkersCriterion } from "./has-markers";
|
||||
import {PerformerIsMissingCriterion, SceneIsMissingCriterion} from "./is-missing";
|
||||
import {
|
||||
PerformerIsMissingCriterion,
|
||||
SceneIsMissingCriterion,
|
||||
} from "./is-missing";
|
||||
import { NoneCriterion } from "./none";
|
||||
import { PerformersCriterion } from "./performers";
|
||||
import { RatingCriterion } from "./rating";
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
import {
|
||||
IsMissingCriterion,
|
||||
PerformerIsMissingCriterionOption,
|
||||
SceneIsMissingCriterionOption
|
||||
SceneIsMissingCriterionOption,
|
||||
} from "./criteria/is-missing";
|
||||
import { NoneCriterionOption } from "./criteria/none";
|
||||
import {
|
||||
|
@ -148,7 +148,9 @@ export class ListFilterModel {
|
|||
new FavoriteCriterionOption(),
|
||||
new GenderCriterionOption(),
|
||||
new PerformerIsMissingCriterionOption(),
|
||||
...numberCriteria.concat(stringCriteria).map(c => ListFilterModel.createCriterionOption(c))
|
||||
...numberCriteria
|
||||
.concat(stringCriteria)
|
||||
.map((c) => ListFilterModel.createCriterionOption(c)),
|
||||
];
|
||||
|
||||
break;
|
||||
|
|
|
@ -20,7 +20,7 @@ const renderTextArea = (options: {
|
|||
value={options.value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderEditableText = (options: {
|
||||
title?: string;
|
||||
|
@ -42,8 +42,8 @@ const renderEditableText = (options: {
|
|||
}
|
||||
placeholder={options.title}
|
||||
/>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const renderInputGroup = (options: {
|
||||
title?: string;
|
||||
|
@ -55,16 +55,12 @@ const renderInputGroup = (options: {
|
|||
}) => {
|
||||
if (options.url && !options.isEditing) {
|
||||
return (
|
||||
<a
|
||||
href={options.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<a href={options.url} target="_blank" rel="noopener noreferrer">
|
||||
{options.value}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<Form.Control
|
||||
className="text-input"
|
||||
|
@ -77,13 +73,13 @@ const renderInputGroup = (options: {
|
|||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderDurationInput = (options: {
|
||||
value: string | undefined;
|
||||
isEditing: boolean;
|
||||
url?: string;
|
||||
asString?: boolean
|
||||
asString?: boolean;
|
||||
onChange: (value: string | undefined) => void;
|
||||
}) => {
|
||||
let numericValue: number | undefined;
|
||||
|
@ -98,7 +94,7 @@ const renderDurationInput = (options: {
|
|||
numericValue = DurationUtils.stringToSeconds(options.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!options.isEditing) {
|
||||
let durationString;
|
||||
if (numericValue !== undefined) {
|
||||
|
@ -118,17 +114,18 @@ const renderDurationInput = (options: {
|
|||
<DurationInput
|
||||
disabled={!options.isEditing}
|
||||
numericValue={numericValue}
|
||||
onValueChange={(valueAsNumber: number, valueAsString? : string) => {
|
||||
onValueChange={(valueAsNumber: number, valueAsString?: string) => {
|
||||
let value = valueAsString;
|
||||
if (!options.asString) {
|
||||
value = valueAsNumber !== undefined ? valueAsNumber.toString() : undefined;
|
||||
value =
|
||||
valueAsNumber !== undefined ? valueAsNumber.toString() : undefined;
|
||||
}
|
||||
|
||||
options.onChange(value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderHtmlSelect = (options: {
|
||||
value?: string | number;
|
||||
|
@ -164,7 +161,7 @@ const renderHtmlSelect = (options: {
|
|||
))}
|
||||
</Form.Control>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: isediting
|
||||
const renderFilterSelect = (options: {
|
||||
|
@ -202,4 +199,4 @@ const EditableTextUtils = {
|
|||
renderFilterSelect,
|
||||
renderMultiSelect,
|
||||
};
|
||||
export default EditableTextUtils;
|
||||
export default EditableTextUtils;
|
||||
|
|
|
@ -9,9 +9,7 @@ const renderEditableTextTableRow = (options: {
|
|||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderEditableText(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderEditableText(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
|
@ -23,9 +21,7 @@ const renderTextArea = (options: {
|
|||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderTextArea(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderTextArea(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
|
@ -39,9 +35,7 @@ const renderInputGroup = (options: {
|
|||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderInputGroup(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderInputGroup(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
|
@ -56,9 +50,7 @@ const renderDurationInput = (options: {
|
|||
return (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderDurationInput(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderDurationInput(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
@ -72,9 +64,7 @@ const renderHtmlSelect = (options: {
|
|||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderHtmlSelect(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderHtmlSelect(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
|
@ -87,9 +77,7 @@ const renderFilterSelect = (options: {
|
|||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderFilterSelect(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderFilterSelect(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
|
@ -102,9 +90,7 @@ const renderMultiSelect = (options: {
|
|||
}) => (
|
||||
<tr>
|
||||
<td>{options.title}</td>
|
||||
<td>
|
||||
{EditableTextUtils.renderMultiSelect(options)}
|
||||
</td>
|
||||
<td>{EditableTextUtils.renderMultiSelect(options)}</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ const sanitiseURL = (url?: string, siteURL?: URL) => {
|
|||
if (!url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) {
|
||||
// just return the entire URL
|
||||
return url;
|
||||
|
@ -103,12 +103,12 @@ const sanitiseURL = (url?: string, siteURL?: URL) => {
|
|||
}
|
||||
|
||||
// otherwise, construct the url from the protocol, host and passed url
|
||||
return siteURL.protocol + siteURL.host + "/" + url;
|
||||
return `${siteURL.protocol}${siteURL.host}/${url}`;
|
||||
}
|
||||
|
||||
// just prepend the protocol - assume https
|
||||
return "https://" + url;
|
||||
}
|
||||
return `https://${url}`;
|
||||
};
|
||||
|
||||
const TextUtils = {
|
||||
truncate,
|
||||
|
|
Loading…
Reference in New Issue