tmp/webapp-docs/src/components/Settings.js

/**
 * The Settings tab — the full settings form (provider / BYOK key, prompt knobs,
 * emphasis / editing / alternating, artists / fx / salt, image params, negative
 * prompt). (Hidden from the nav while the UI is reworked.)
 * @module web-app/components/Settings
 */
import { Text, Num, Toggle, Select, TextArea, Group } from "./Field.jsx";
import { getListNames } from "../lib/promptEngine.js";
import { availableProviders, getProvider } from "../lib/providers/index.js";
import { defaultSettings } from "../lib/settings.js";
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
const MODES = [{
  value: "StableDiffusion",
  label: "Stable Diffusion"
}, {
  value: "NovelAI",
  label: "NovelAI"
}, {
  value: "Midjourney",
  label: "Midjourney"
}];

// Source-list options: every list, plus "false" meaning fully random.
const listOptions = [{
  value: "false",
  label: "(fully random)"
}, ...getListNames()];

/**
 * The full settings form.
 * @param {object} props
 * @param {object} props.settings The current settings.
 * @param {Function} props.setSettings Update the settings.
 * @returns {JSX.Element}
 */
export default function Settings({
  settings,
  setSettings
}) {
  const set = patch => setSettings({
    ...settings,
    ...patch
  });
  const setKey = (id, value) => setSettings({
    ...settings,
    keys: {
      ...settings.keys,
      [id]: value
    }
  });
  const provider = getProvider(settings.provider);
  return /*#__PURE__*/_jsxDEV("div", {
    className: "settings",
    children: [/*#__PURE__*/_jsxDEV("div", {
      className: "settings-actions",
      children: /*#__PURE__*/_jsxDEV("button", {
        onClick: () => {
          if (confirm("Reset all settings to defaults?")) setSettings({
            ...defaultSettings
          });
        },
        children: "Reset to defaults"
      }, void 0, false)
    }, void 0, false), /*#__PURE__*/_jsxDEV(Group, {
      title: "Generation backend",
      children: [/*#__PURE__*/_jsxDEV(Select, {
        label: "Provider",
        value: settings.provider,
        onChange: v => set({
          provider: v
        }),
        options: availableProviders().map(p => ({
          value: p.id,
          label: p.label
        }))
      }, void 0, false), provider.local && /*#__PURE__*/_jsxDEV(Text, {
        label: "Local WebUI URL",
        value: settings.localWebuiUrl,
        onChange: v => set({
          localWebuiUrl: v
        })
      }, void 0, false), provider.needsKey && /*#__PURE__*/_jsxDEV("label", {
        className: "field",
        children: [/*#__PURE__*/_jsxDEV("span", {
          children: ["API key for ", provider.label]
        }, void 0, true), /*#__PURE__*/_jsxDEV("input", {
          type: "password",
          autoComplete: "off",
          placeholder: "kept only in this browser",
          value: settings.keys?.[provider.id] || "",
          onChange: e => setKey(provider.id, e.target.value)
        }, void 0, false)]
      }, void 0, true)]
    }, void 0, true), /*#__PURE__*/_jsxDEV(Group, {
      title: "Prompt",
      children: [/*#__PURE__*/_jsxDEV(Select, {
        label: "Mode",
        value: settings.mode,
        onChange: v => set({
          mode: v
        }),
        options: MODES
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Prompts per run",
        value: settings.promptCount,
        min: 1,
        max: 50,
        onChange: v => set({
          promptCount: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Keywords (min)",
        value: settings.keywordCount,
        min: 0,
        onChange: v => set({
          keywordCount: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Keywords (max)",
        value: settings.keywordMaxCount,
        min: 0,
        onChange: v => set({
          keywordMaxCount: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Select, {
        label: "Keyword list",
        value: settings.keywordsFilename,
        onChange: v => set({
          keywordsFilename: v
        }),
        options: listOptions
      }, void 0, false), /*#__PURE__*/_jsxDEV(Select, {
        label: "Artist list",
        value: settings.artistFilename,
        onChange: v => set({
          artistFilename: v
        }),
        options: listOptions
      }, void 0, false)]
    }, void 0, true), /*#__PURE__*/_jsxDEV(Group, {
      title: "Emphasis",
      children: [/*#__PURE__*/_jsxDEV(Toggle, {
        label: "Randomly emphasize keywords",
        value: settings.keywordEmphasis,
        onChange: v => set({
          keywordEmphasis: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Emphasis chance",
        step: 0.05,
        min: 0,
        max: 1,
        value: settings.emphasisChance,
        onChange: v => set({
          emphasisChance: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Extra-level chance",
        step: 0.05,
        min: 0,
        max: 1,
        value: settings.emphasisLevelChance,
        onChange: v => set({
          emphasisLevelChance: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Max levels",
        min: 0,
        value: settings.emphasisMaxLevels,
        onChange: v => set({
          emphasisMaxLevels: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "De-emphasis chance",
        step: 0.05,
        min: 0,
        max: 1,
        value: settings.deEmphasisChance,
        onChange: v => set({
          deEmphasisChance: v
        })
      }, void 0, false)]
    }, void 0, true), /*#__PURE__*/_jsxDEV(Group, {
      title: "Editing & alternating",
      children: [/*#__PURE__*/_jsxDEV(Toggle, {
        label: "Keyword editing",
        value: settings.keywordEditing,
        onChange: v => set({
          keywordEditing: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Editing min",
        value: settings.keywordEditingMin,
        onChange: v => set({
          keywordEditingMin: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Editing max",
        value: settings.keywordEditingMax,
        onChange: v => set({
          keywordEditingMax: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Keyword alternating",
        value: settings.keywordAlternating,
        onChange: v => set({
          keywordAlternating: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Alternating max levels",
        value: settings.keywordAlternatingMaxLevels,
        onChange: v => set({
          keywordAlternatingMaxLevels: v
        })
      }, void 0, false)]
    }, void 0, true), /*#__PURE__*/_jsxDEV(Group, {
      title: "Artists, fx & salt",
      children: [/*#__PURE__*/_jsxDEV(Toggle, {
        label: "Include artists",
        value: settings.includeArtist,
        onChange: v => set({
          includeArtist: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Min artists",
        min: 0,
        value: settings.minArtist,
        onChange: v => set({
          minArtist: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Max artists",
        min: 0,
        value: settings.maxArtist,
        onChange: v => set({
          maxArtist: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Auto-add artists",
        value: settings.autoAddArtists,
        onChange: v => set({
          autoAddArtists: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Auto-add fx",
        value: settings.autoAddFx,
        onChange: v => set({
          autoAddFx: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Prompt salt",
        value: settings.promptSalt,
        onChange: v => set({
          promptSalt: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Salt start (-1 = random)",
        value: settings.promptSaltStart,
        onChange: v => set({
          promptSaltStart: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Don't combine with AND",
        value: settings.noAnd,
        onChange: v => set({
          noAnd: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "List entries used once",
        value: settings.listEntriesUsedOnce,
        onChange: v => set({
          listEntriesUsedOnce: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Reload lists each prompt",
        value: settings.reloadListsOnPromptChange,
        onChange: v => set({
          reloadListsOnPromptChange: v
        })
      }, void 0, false)]
    }, void 0, true), /*#__PURE__*/_jsxDEV(Group, {
      title: "Image",
      children: [/*#__PURE__*/_jsxDEV(Text, {
        label: "Sampler",
        value: settings.sampler,
        onChange: v => set({
          sampler: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Steps",
        min: 1,
        value: settings.imageSteps,
        onChange: v => set({
          imageSteps: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Width",
        min: 64,
        step: 64,
        value: settings.imageWidth,
        onChange: v => set({
          imageWidth: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Height",
        min: 64,
        step: 64,
        value: settings.imageHeight,
        onChange: v => set({
          imageHeight: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "CFG",
        step: 0.5,
        value: settings.cfg,
        onChange: v => set({
          cfg: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Num, {
        label: "Seed (-1 = random)",
        value: settings.seed,
        onChange: v => set({
          seed: v
        })
      }, void 0, false), /*#__PURE__*/_jsxDEV(Toggle, {
        label: "Restore faces",
        value: settings.restoreFaces,
        onChange: v => set({
          restoreFaces: v
        })
      }, void 0, false)]
    }, void 0, true), /*#__PURE__*/_jsxDEV(Group, {
      title: "Negative prompt",
      children: /*#__PURE__*/_jsxDEV(TextArea, {
        label: "",
        rows: 4,
        value: settings.negativePrompt,
        onChange: v => set({
          negativePrompt: v
        })
      }, void 0, false)
    }, void 0, false)]
  }, void 0, true);
}