mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
Merge branch 'develop' of https://github.com/Darklyter/stash into develop
This commit is contained in:
commit
7db01e15ac
6 changed files with 886 additions and 876 deletions
|
|
@ -192,7 +192,7 @@ func (me *contentDirectoryService) Handle(action string, argsXML []byte, r *http
|
||||||
|
|
||||||
obj, err := me.objectFromID(browse.ObjectID)
|
obj, err := me.objectFromID(browse.ObjectID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, upnp.Errorf(upnpav.NoSuchObjectErrorCode, err.Error())
|
return nil, upnp.Errorf(upnpav.NoSuchObjectErrorCode, "cannot find object with id %q: %v", browse.ObjectID, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch browse.BrowseFlag {
|
switch browse.BrowseFlag {
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ func (t *rawPluginTask) Start() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnf("error marshalling raw command input")
|
logger.Warnf("error marshalling raw command input")
|
||||||
}
|
}
|
||||||
if k, err := io.WriteString(stdin, string(inBytes)); err != nil {
|
if k, err := stdin.Write(inBytes); err != nil {
|
||||||
logger.Warnf("error writing input to plugins stdin (wrote %v bytes out of %v): %v", k, len(string(inBytes)), err)
|
logger.Warnf("error writing input to plugins stdin (wrote %v bytes out of %v): %v", k, len(string(inBytes)), err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -1338,7 +1338,7 @@ func (c *Client) submitDraft(ctx context.Context, query string, input interface{
|
||||||
return fmt.Errorf("failed to decode data %s: %w", string(responseBytes), err)
|
return fmt.Errorf("failed to decode data %s: %w", string(responseBytes), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if respGQL.Errors != nil && len(respGQL.Errors) > 0 {
|
if len(respGQL.Errors) > 0 {
|
||||||
// try to parse standard graphql error
|
// try to parse standard graphql error
|
||||||
errors := &client.GqlErrorList{}
|
errors := &client.GqlErrorList{}
|
||||||
if e := json.Unmarshal(responseBytes, errors); e != nil {
|
if e := json.Unmarshal(responseBytes, errors); e != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { BooleanSetting } from "../Inputs";
|
import { BooleanSetting } from "../Inputs";
|
||||||
|
import { PatchComponent } from "src/patch";
|
||||||
|
|
||||||
interface IItem {
|
interface IItem {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
@ -13,12 +14,9 @@ interface ICheckboxGroupProps {
|
||||||
onChange?: (ids: string[]) => void;
|
onChange?: (ids: string[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CheckboxGroup: React.FC<ICheckboxGroupProps> = ({
|
export const CheckboxGroup: React.FC<ICheckboxGroupProps> = PatchComponent(
|
||||||
groupId,
|
"CheckboxGroup",
|
||||||
items,
|
({ groupId, items, checkedIds = [], onChange }) => {
|
||||||
checkedIds = [],
|
|
||||||
onChange,
|
|
||||||
}) => {
|
|
||||||
function generateId(itemId: string) {
|
function generateId(itemId: string) {
|
||||||
return `${groupId}-${itemId}`;
|
return `${groupId}-${itemId}`;
|
||||||
}
|
}
|
||||||
|
|
@ -58,4 +56,5 @@ export const CheckboxGroup: React.FC<ICheckboxGroupProps> = ({
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ import {
|
||||||
defaultImageWallMargin,
|
defaultImageWallMargin,
|
||||||
} from "src/utils/imageWall";
|
} from "src/utils/imageWall";
|
||||||
import { defaultMaxOptionsShown } from "src/core/config";
|
import { defaultMaxOptionsShown } from "src/core/config";
|
||||||
|
import { PatchComponent } from "src/patch";
|
||||||
|
|
||||||
const allMenuItems = [
|
const allMenuItems = [
|
||||||
{ id: "scenes", headingID: "scenes" },
|
{ id: "scenes", headingID: "scenes" },
|
||||||
|
|
@ -55,7 +56,9 @@ const allMenuItems = [
|
||||||
{ id: "tags", headingID: "tags" },
|
{ id: "tags", headingID: "tags" },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const SettingsInterfacePanel: React.FC = () => {
|
export const SettingsInterfacePanel: React.FC = PatchComponent(
|
||||||
|
"SettingsInterfacePanel",
|
||||||
|
function SettingsInterfacePanel() {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -66,7 +69,6 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
loading,
|
loading,
|
||||||
error,
|
error,
|
||||||
} = useSettings();
|
} = useSettings();
|
||||||
|
|
||||||
// convert old movies menu item to groups
|
// convert old movies menu item to groups
|
||||||
const massageMenuItems = useCallback((menuItems: string[]) => {
|
const massageMenuItems = useCallback((menuItems: string[]) => {
|
||||||
return menuItems.map((item) => {
|
return menuItems.map((item) => {
|
||||||
|
|
@ -97,15 +99,13 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
|
|
||||||
function saveLightboxSettings(v: Partial<GQL.ConfigImageLightboxInput>) {
|
function saveLightboxSettings(v: Partial<GQL.ConfigImageLightboxInput>) {
|
||||||
// save in local forage as well for consistency
|
// save in local forage as well for consistency
|
||||||
setInterfaceLocalForage((prev) => {
|
setInterfaceLocalForage((prev) => ({
|
||||||
return {
|
|
||||||
...prev,
|
...prev,
|
||||||
imageLightbox: {
|
imageLightbox: {
|
||||||
...prev.imageLightbox,
|
...prev.imageLightbox,
|
||||||
...v,
|
...v,
|
||||||
},
|
},
|
||||||
};
|
}));
|
||||||
});
|
|
||||||
|
|
||||||
saveInterface({
|
saveInterface({
|
||||||
imageLightbox: {
|
imageLightbox: {
|
||||||
|
|
@ -189,6 +189,7 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
if (loading) return <LoadingIndicator />;
|
if (loading) return <LoadingIndicator />;
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/List_of_language_names
|
// https://en.wikipedia.org/wiki/List_of_language_names
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SettingSection headingID="config.ui.basic_settings">
|
<SettingSection headingID="config.ui.basic_settings">
|
||||||
|
|
@ -239,7 +240,9 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
})}
|
})}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="sub-heading">
|
<div className="sub-heading">
|
||||||
{intl.formatMessage({ id: "config.ui.menu_items.description" })}
|
{intl.formatMessage({
|
||||||
|
id: "config.ui.menu_items.description",
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div />
|
<div />
|
||||||
|
|
@ -248,7 +251,9 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
groupId="menu-items"
|
groupId="menu-items"
|
||||||
items={allMenuItems}
|
items={allMenuItems}
|
||||||
checkedIds={massagedMenuItems ?? undefined}
|
checkedIds={massagedMenuItems ?? undefined}
|
||||||
onChange={(v) => saveInterface({ menuItems: massageMenuItems(v) })}
|
onChange={(v) =>
|
||||||
|
saveInterface({ menuItems: massageMenuItems(v) })
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -301,7 +306,9 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
onChange={(v) => saveInterface({ wallPlayback: v })}
|
onChange={(v) => saveInterface({ wallPlayback: v })}
|
||||||
>
|
>
|
||||||
<option value="video">
|
<option value="video">
|
||||||
{intl.formatMessage({ id: "config.ui.preview_type.options.video" })}
|
{intl.formatMessage({
|
||||||
|
id: "config.ui.preview_type.options.video",
|
||||||
|
})}
|
||||||
</option>
|
</option>
|
||||||
<option value="animation">
|
<option value="animation">
|
||||||
{intl.formatMessage({
|
{intl.formatMessage({
|
||||||
|
|
@ -481,8 +488,15 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</SelectSetting>
|
</SelectSetting>
|
||||||
|
)}
|
||||||
|
<BooleanSetting
|
||||||
|
id="auto_convert_metric_measurements"
|
||||||
|
headingID="config.ui.editing.auto_convert_metric_measurements.heading"
|
||||||
|
subHeadingID="config.ui.editing.auto_convert_metric_measurements.description"
|
||||||
|
checked={ui.autoConvertMetricMeasurements ?? undefined}
|
||||||
|
onChange={(v) => saveUI({ autoConvertMetricMeasurements: v })}
|
||||||
|
/>
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
|
||||||
<SettingSection headingID="config.ui.image_lightbox.heading">
|
<SettingSection headingID="config.ui.image_lightbox.heading">
|
||||||
<NumberSetting
|
<NumberSetting
|
||||||
headingID="config.ui.slideshow_delay.heading"
|
headingID="config.ui.slideshow_delay.heading"
|
||||||
|
|
@ -533,7 +547,8 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
headingID="dialogs.lightbox.scroll_mode.label"
|
headingID="dialogs.lightbox.scroll_mode.label"
|
||||||
subHeadingID="dialogs.lightbox.scroll_mode.description"
|
subHeadingID="dialogs.lightbox.scroll_mode.description"
|
||||||
value={
|
value={
|
||||||
iface.imageLightbox?.scrollMode ?? GQL.ImageLightboxScrollMode.Zoom
|
iface.imageLightbox?.scrollMode ??
|
||||||
|
GQL.ImageLightboxScrollMode.Zoom
|
||||||
}
|
}
|
||||||
onChange={(v) =>
|
onChange={(v) =>
|
||||||
saveLightboxSettings({
|
saveLightboxSettings({
|
||||||
|
|
@ -730,13 +745,6 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
))}
|
))}
|
||||||
</SelectSetting>
|
</SelectSetting>
|
||||||
)}
|
)}
|
||||||
<BooleanSetting
|
|
||||||
id="auto_convert_metric_measurements"
|
|
||||||
headingID="config.ui.editing.auto_convert_metric_measurements.heading"
|
|
||||||
subHeadingID="config.ui.editing.auto_convert_metric_measurements.description"
|
|
||||||
checked={ui.autoConvertMetricMeasurements ?? undefined}
|
|
||||||
onChange={(v) => saveUI({ autoConvertMetricMeasurements: v })}
|
|
||||||
/>
|
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
|
||||||
<SettingSection headingID="config.ui.custom_css.heading">
|
<SettingSection headingID="config.ui.custom_css.heading">
|
||||||
|
|
@ -932,4 +940,5 @@ export const SettingsInterfacePanel: React.FC = () => {
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,15 @@ export const ScraperMenu: React.FC<{
|
||||||
<Dropdown.Toggle variant={variant}>{toggle}</Dropdown.Toggle>
|
<Dropdown.Toggle variant={variant}>{toggle}</Dropdown.Toggle>
|
||||||
|
|
||||||
<Dropdown.Menu>
|
<Dropdown.Menu>
|
||||||
|
<Dropdown.Item onClick={() => onReloadScrapers()}>
|
||||||
|
<span className="fa-icon">
|
||||||
|
<Icon icon={faSyncAlt} />
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<FormattedMessage id="actions.reload_scrapers" />
|
||||||
|
</span>
|
||||||
|
</Dropdown.Item>
|
||||||
|
|
||||||
{(stashBoxes?.length ?? 0) + scrapers.length > minFilteredScrapers && (
|
{(stashBoxes?.length ?? 0) + scrapers.length > minFilteredScrapers && (
|
||||||
<ClearableInput
|
<ClearableInput
|
||||||
placeholder={`${intl.formatMessage({ id: "filter" })}...`}
|
placeholder={`${intl.formatMessage({ id: "filter" })}...`}
|
||||||
|
|
@ -61,6 +70,7 @@ export const ScraperMenu: React.FC<{
|
||||||
setValue={setFilter}
|
setValue={setFilter}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{filteredStashboxes.map((s, index) => (
|
{filteredStashboxes.map((s, index) => (
|
||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
key={s.endpoint}
|
key={s.endpoint}
|
||||||
|
|
@ -86,14 +96,6 @@ export const ScraperMenu: React.FC<{
|
||||||
{s.name}
|
{s.name}
|
||||||
</Dropdown.Item>
|
</Dropdown.Item>
|
||||||
))}
|
))}
|
||||||
<Dropdown.Item onClick={() => onReloadScrapers()}>
|
|
||||||
<span className="fa-icon">
|
|
||||||
<Icon icon={faSyncAlt} />
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<FormattedMessage id="actions.reload_scrapers" />
|
|
||||||
</span>
|
|
||||||
</Dropdown.Item>
|
|
||||||
</Dropdown.Menu>
|
</Dropdown.Menu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue