Miscellaneous fixes (0.18 beta) (#23716)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions

* resolve zone friendly names against the correct camera

* Improve handling of zone names in chat prompt

* show a numeric keyboard for numeric config form fields on mobile

* Specify english only for semantic search tool when model is JinaV1

* resolve export hwaccel args global value against the correct config path

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
This commit is contained in:
Josh Hawkins
2026-07-14 08:42:26 -06:00
committed by GitHub
co-authored by Nicolas Mowen
parent c2e739b4bc
commit 81b53b7835
12 changed files with 155 additions and 30 deletions
@@ -17,3 +17,4 @@ export {
isSubtreeModified,
} from "./overrides";
export { getSizedFieldClassName } from "./fieldSizing";
export { getNumericInputMode } from "./inputMode";
@@ -0,0 +1,51 @@
import type { RJSFSchema } from "@rjsf/utils";
type NumericInputOptions = {
signed?: boolean;
};
/**
* Derive the on-screen keyboard hint for a schema field.
*
* Numeric config fields render as text inputs because RJSF's NumberField
* relies on the widget echoing raw strings back, so that trailing "." and "0"
* characters survive while a value is being typed. That means the numeric
* keypad has to be requested explicitly. Desktop browsers ignore inputMode, so
* this only affects virtual keyboards.
*
* Fields accepting negative values opt out, since the iOS numeric and decimal
* keypads have no minus key. Most numeric fields declare no minimum even
* though they are non-negative, so signed fields are marked explicitly with
* ui:options.signed.
*
* Args:
* schema: The JSON schema for the field being rendered
* options: The resolved ui:options for the field
*
* Returns:
* The inputMode to apply, or undefined to leave the keyboard alone
*/
export function getNumericInputMode(
schema: RJSFSchema,
options: unknown,
): "numeric" | "decimal" | undefined {
const types = Array.isArray(schema.type) ? schema.type : [schema.type];
const isInteger = types.includes("integer");
if (!isInteger && !types.includes("number")) {
return undefined;
}
const numericOptions =
typeof options === "object" && options !== null
? (options as NumericInputOptions)
: undefined;
const minimum = schema.minimum ?? schema.exclusiveMinimum;
if (numericOptions?.signed || (minimum ?? 0) < 0) {
return undefined;
}
return isInteger ? "numeric" : "decimal";
}
@@ -120,6 +120,12 @@ export function FfmpegArgsWidget(props: WidgetProps) {
id,
} = props;
const presetField = options?.ffmpegPresetField as PresetField | undefined;
// Path to this field within its config section. This is usually the same as
// the preset field, but the two diverge when the field sits below the
// section root: record.export.hwaccel_args uses the hwaccel_args preset list
// while living at export.hwaccel_args inside the record section.
const globalFieldPath =
(options?.ffmpegGlobalFieldPath as string | undefined) ?? presetField;
const allowInherit = options?.allowInherit === true;
const hideDescription = options?.hideDescription === true;
const useSplitLayout = options?.splitLayout !== false;
@@ -131,11 +137,18 @@ export function FfmpegArgsWidget(props: WidgetProps) {
// Extract the global value for this specific field to detect inheritance
const globalFieldValue = useMemo(() => {
if (!showUseGlobalSetting || !formContext?.globalValue || !presetField) {
if (
!showUseGlobalSetting ||
!formContext?.globalValue ||
!globalFieldPath
) {
return undefined;
}
return get(formContext.globalValue as Record<string, unknown>, presetField);
}, [showUseGlobalSetting, formContext?.globalValue, presetField]);
return get(
formContext.globalValue as Record<string, unknown>,
globalFieldPath,
);
}, [showUseGlobalSetting, formContext?.globalValue, globalFieldPath]);
const { data } = useSWR<FfmpegPresetResponse>("ffmpeg/presets");
@@ -2,7 +2,7 @@
import type { WidgetProps } from "@rjsf/utils";
import { Input } from "@/components/ui/input";
import { cn } from "@/lib/utils";
import { getSizedFieldClassName } from "../utils";
import { getNumericInputMode, getSizedFieldClassName } from "../utils";
export function TextWidget(props: WidgetProps) {
const {
@@ -28,6 +28,7 @@ export function TextWidget(props: WidgetProps) {
id={id}
className={cn(fieldClassName)}
type="text"
inputMode={getNumericInputMode(schema, options)}
value={value ?? ""}
disabled={disabled || readonly}
placeholder={placeholder || (options.placeholder as string) || ""}