Rename widget emitSoundSpeed property
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// Maintainer-controlled web client version.
|
// Maintainer-controlled web client version.
|
||||||
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
// Format: YYYY.MM.DD Rn (example: 2026.02.20 R2)
|
||||||
window.CHGRID_WEB_VERSION = "2026.02.21 R129";
|
window.CHGRID_WEB_VERSION = "2026.02.22 R130";
|
||||||
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
// Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid.
|
||||||
window.CHGRID_TIME_ZONE = "America/Detroit";
|
window.CHGRID_TIME_ZONE = "America/Detroit";
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export class ItemEmitRuntime {
|
|||||||
const effect = normalizeRadioEffect(item.params.emitEffect);
|
const effect = normalizeRadioEffect(item.params.emitEffect);
|
||||||
const effectValue = normalizeRadioEffectValue(item.params.emitEffectValue);
|
const effectValue = normalizeRadioEffectValue(item.params.emitEffectValue);
|
||||||
const effectRuntime = connectEffectChain(audioCtx, effectInput, gain, effect, effectValue);
|
const effectRuntime = connectEffectChain(audioCtx, effectInput, gain, effect, effectValue);
|
||||||
element.playbackRate = resolveEmitPlaybackRate(item.params.emitSpeed);
|
element.playbackRate = resolveEmitPlaybackRate(item.params.emitSoundSpeed);
|
||||||
if (this.audio.supportsStereoPanner()) {
|
if (this.audio.supportsStereoPanner()) {
|
||||||
panner = audioCtx.createStereoPanner();
|
panner = audioCtx.createStereoPanner();
|
||||||
gain.connect(panner).connect(audioCtx.destination);
|
gain.connect(panner).connect(audioCtx.destination);
|
||||||
@@ -148,7 +148,7 @@ export class ItemEmitRuntime {
|
|||||||
output.effect = effect;
|
output.effect = effect;
|
||||||
output.effectValue = effectValue;
|
output.effectValue = effectValue;
|
||||||
}
|
}
|
||||||
const nextPlaybackRate = resolveEmitPlaybackRate(item.params.emitSpeed);
|
const nextPlaybackRate = resolveEmitPlaybackRate(item.params.emitSoundSpeed);
|
||||||
if (Math.abs(output.element.playbackRate - nextPlaybackRate) > 0.001) {
|
if (Math.abs(output.element.playbackRate - nextPlaybackRate) > 0.001) {
|
||||||
output.element.playbackRate = nextPlaybackRate;
|
output.element.playbackRate = nextPlaybackRate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const DEFAULT_ITEM_TYPE_EDITABLE_PROPERTIES: Record<ItemType, string[]> = {
|
|||||||
dice: ['title', 'sides', 'number'],
|
dice: ['title', 'sides', 'number'],
|
||||||
wheel: ['title', 'spaces'],
|
wheel: ['title', 'spaces'],
|
||||||
clock: ['title', 'timeZone', 'use24Hour'],
|
clock: ['title', 'timeZone', 'use24Hour'],
|
||||||
widget: ['title', 'enabled', 'directional', 'facing', 'emitRange', 'emitVolume', 'emitSpeed', 'emitEffect', 'emitEffectValue', 'useSound', 'emitSound'],
|
widget: ['title', 'enabled', 'directional', 'facing', 'emitRange', 'emitVolume', 'emitSoundSpeed', 'emitEffect', 'emitEffectValue', 'useSound', 'emitSound'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_ITEM_TYPE_GLOBAL_PROPERTIES: Record<ItemType, Record<string, string | number | boolean>> = {
|
const DEFAULT_ITEM_TYPE_GLOBAL_PROPERTIES: Record<ItemType, Record<string, string | number | boolean>> = {
|
||||||
@@ -196,7 +196,7 @@ export function itemPropertyLabel(key: string): string {
|
|||||||
if (key === 'emitRange') return 'emit range';
|
if (key === 'emitRange') return 'emit range';
|
||||||
if (key === 'mediaVolume') return 'media volume';
|
if (key === 'mediaVolume') return 'media volume';
|
||||||
if (key === 'emitVolume') return 'emit volume';
|
if (key === 'emitVolume') return 'emit volume';
|
||||||
if (key === 'emitSpeed') return 'emit speed';
|
if (key === 'emitSoundSpeed') return 'emit sound speed';
|
||||||
if (key === 'mediaChannel') return 'media channel';
|
if (key === 'mediaChannel') return 'media channel';
|
||||||
if (key === 'mediaEffect') return 'media effect';
|
if (key === 'mediaEffect') return 'media effect';
|
||||||
if (key === 'mediaEffectValue') return 'media effect value';
|
if (key === 'mediaEffectValue') return 'media effect value';
|
||||||
|
|||||||
@@ -753,7 +753,7 @@ function inferItemPropertyValueType(item: WorldItem, key: string): string | unde
|
|||||||
key === 'version' ||
|
key === 'version' ||
|
||||||
key === 'mediaVolume' ||
|
key === 'mediaVolume' ||
|
||||||
key === 'emitVolume' ||
|
key === 'emitVolume' ||
|
||||||
key === 'emitSpeed' ||
|
key === 'emitSoundSpeed' ||
|
||||||
key === 'mediaEffectValue' ||
|
key === 'mediaEffectValue' ||
|
||||||
key === 'emitEffectValue' ||
|
key === 'emitEffectValue' ||
|
||||||
key === 'facing' ||
|
key === 'facing' ||
|
||||||
@@ -2159,14 +2159,14 @@ function handleItemPropertyEditModeInput(code: string, key: string, ctrlKey: boo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
signaling.send({ type: 'item_update', itemId, params: { emitVolume: parsed.value } });
|
signaling.send({ type: 'item_update', itemId, params: { emitVolume: parsed.value } });
|
||||||
} else if (propertyKey === 'emitSpeed') {
|
} else if (propertyKey === 'emitSoundSpeed') {
|
||||||
const parsed = validateNumericItemPropertyInput(item, propertyKey, value, true);
|
const parsed = validateNumericItemPropertyInput(item, propertyKey, value, true);
|
||||||
if (!parsed.ok) {
|
if (!parsed.ok) {
|
||||||
updateStatus(parsed.message);
|
updateStatus(parsed.message);
|
||||||
audio.sfxUiCancel();
|
audio.sfxUiCancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
signaling.send({ type: 'item_update', itemId, params: { emitSpeed: parsed.value } });
|
signaling.send({ type: 'item_update', itemId, params: { emitSoundSpeed: parsed.value } });
|
||||||
} else if (propertyKey === 'mediaEffect' || propertyKey === 'emitEffect') {
|
} else if (propertyKey === 'mediaEffect' || propertyKey === 'emitEffect') {
|
||||||
const normalized = value.trim().toLowerCase() as EffectId;
|
const normalized = value.trim().toLowerCase() as EffectId;
|
||||||
if (!EFFECT_IDS.has(normalized)) {
|
if (!EFFECT_IDS.has(normalized)) {
|
||||||
|
|||||||
@@ -137,7 +137,7 @@
|
|||||||
"facing": 0,
|
"facing": 0,
|
||||||
"emitRange": 15,
|
"emitRange": 15,
|
||||||
"emitVolume": 100,
|
"emitVolume": 100,
|
||||||
"emitSpeed": 50,
|
"emitSoundSpeed": 50,
|
||||||
"emitEffect": "off",
|
"emitEffect": "off",
|
||||||
"emitEffectValue": 50,
|
"emitEffectValue": 50,
|
||||||
"useSound": "",
|
"useSound": "",
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
- `facing`: number, range `0-360`, precision `0.1`.
|
- `facing`: number, range `0-360`, precision `0.1`.
|
||||||
- `emitRange`: integer, range `1-20`, default `15`.
|
- `emitRange`: integer, range `1-20`, default `15`.
|
||||||
- `emitVolume`: integer, range `0-100`, default `100`.
|
- `emitVolume`: integer, range `0-100`, default `100`.
|
||||||
- `emitSpeed`: integer, range `0-100`, default `50`; maps to playback rate (`0=0.5x`, `50=1.0x`, `100=2.0x`).
|
- `emitSoundSpeed`: integer, range `0-100`, default `50`; maps to playback rate (`0=0.5x`, `50=1.0x`, `100=2.0x`).
|
||||||
- `emitEffect`: one of `reverb | echo | flanger | high_pass | low_pass | off`, default `off`.
|
- `emitEffect`: one of `reverb | echo | flanger | high_pass | low_pass | off`, default `off`.
|
||||||
- `emitEffectValue`: number, range `0-100`, precision `0.1`, default `50`.
|
- `emitEffectValue`: number, range `0-100`, precision `0.1`, default `50`.
|
||||||
- `useSound`: empty, filename (assumed under `sounds/`), or full URL.
|
- `useSound`: empty, filename (assumed under `sounds/`), or full URL.
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ This is behavior-focused documentation for item types and their defaults.
|
|||||||
- `facing=0`
|
- `facing=0`
|
||||||
- `emitRange=15`
|
- `emitRange=15`
|
||||||
- `emitVolume=100`
|
- `emitVolume=100`
|
||||||
- `emitSpeed=50`
|
- `emitSoundSpeed=50`
|
||||||
- `emitEffect="off"`
|
- `emitEffect="off"`
|
||||||
- `emitEffectValue=50`
|
- `emitEffectValue=50`
|
||||||
- `useSound=""`
|
- `useSound=""`
|
||||||
@@ -141,7 +141,7 @@ This is behavior-focused documentation for item types and their defaults.
|
|||||||
- `facing`: number `0..360` with `0.1` precision
|
- `facing`: number `0..360` with `0.1` precision
|
||||||
- `emitRange`: integer `1..20`
|
- `emitRange`: integer `1..20`
|
||||||
- `emitVolume`: integer `0..100`
|
- `emitVolume`: integer `0..100`
|
||||||
- `emitSpeed`: integer `0..100` (`0=0.5x`, `50=1.0x`, `100=2.0x`)
|
- `emitSoundSpeed`: integer `0..100` (`0=0.5x`, `50=1.0x`, `100=2.0x`)
|
||||||
- `emitEffect`: `reverb | echo | flanger | high_pass | low_pass | off`
|
- `emitEffect`: `reverb | echo | flanger | high_pass | low_pass | off`
|
||||||
- `emitEffectValue`: number `0..100` with `0.1` precision
|
- `emitEffectValue`: number `0..100` with `0.1` precision
|
||||||
- `useSound`: empty, filename (assumed under `sounds/`), or full URL
|
- `useSound`: empty, filename (assumed under `sounds/`), or full URL
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ EDITABLE_PROPERTIES: tuple[str, ...] = (
|
|||||||
"facing",
|
"facing",
|
||||||
"emitRange",
|
"emitRange",
|
||||||
"emitVolume",
|
"emitVolume",
|
||||||
"emitSpeed",
|
"emitSoundSpeed",
|
||||||
"emitEffect",
|
"emitEffect",
|
||||||
"emitEffectValue",
|
"emitEffectValue",
|
||||||
"useSound",
|
"useSound",
|
||||||
@@ -36,7 +36,7 @@ DEFAULT_PARAMS: dict = {
|
|||||||
"facing": 0,
|
"facing": 0,
|
||||||
"emitRange": 15,
|
"emitRange": 15,
|
||||||
"emitVolume": 100,
|
"emitVolume": 100,
|
||||||
"emitSpeed": 50,
|
"emitSoundSpeed": 50,
|
||||||
"emitEffect": "off",
|
"emitEffect": "off",
|
||||||
"emitEffectValue": 50,
|
"emitEffectValue": 50,
|
||||||
"useSound": "",
|
"useSound": "",
|
||||||
@@ -63,7 +63,7 @@ PROPERTY_METADATA: dict[str, dict[str, object]] = {
|
|||||||
"tooltip": "Emitted sound volume percent.",
|
"tooltip": "Emitted sound volume percent.",
|
||||||
"range": {"min": 0, "max": 100, "step": 1},
|
"range": {"min": 0, "max": 100, "step": 1},
|
||||||
},
|
},
|
||||||
"emitSpeed": {
|
"emitSoundSpeed": {
|
||||||
"valueType": "number",
|
"valueType": "number",
|
||||||
"tooltip": "Playback speed/pitch percent for emitted sound. 50 is normal, 0 is half, 100 is double.",
|
"tooltip": "Playback speed/pitch percent for emitted sound. 50 is normal, 0 is half, 100 is double.",
|
||||||
"range": {"min": 0, "max": 100, "step": 1},
|
"range": {"min": 0, "max": 100, "step": 1},
|
||||||
@@ -132,12 +132,12 @@ def validate_update(item: WorldItem, next_params: dict) -> dict:
|
|||||||
next_params["emitVolume"] = emit_volume
|
next_params["emitVolume"] = emit_volume
|
||||||
|
|
||||||
try:
|
try:
|
||||||
emit_speed = int(next_params.get("emitSpeed", item.params.get("emitSpeed", 50)))
|
emit_speed = int(next_params.get("emitSoundSpeed", item.params.get("emitSoundSpeed", 50)))
|
||||||
except (TypeError, ValueError) as exc:
|
except (TypeError, ValueError) as exc:
|
||||||
raise ValueError("emitSpeed must be an integer between 0 and 100.") from exc
|
raise ValueError("emitSoundSpeed must be an integer between 0 and 100.") from exc
|
||||||
if not (0 <= emit_speed <= 100):
|
if not (0 <= emit_speed <= 100):
|
||||||
raise ValueError("emitSpeed must be between 0 and 100.")
|
raise ValueError("emitSoundSpeed must be between 0 and 100.")
|
||||||
next_params["emitSpeed"] = emit_speed
|
next_params["emitSoundSpeed"] = emit_speed
|
||||||
|
|
||||||
emit_effect = str(next_params.get("emitEffect", item.params.get("emitEffect", "off"))).strip().lower()
|
emit_effect = str(next_params.get("emitEffect", item.params.get("emitEffect", "off"))).strip().lower()
|
||||||
if emit_effect not in EFFECT_OPTIONS:
|
if emit_effect not in EFFECT_OPTIONS:
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ async def test_widget_update_and_use(monkeypatch: pytest.MonkeyPatch) -> None:
|
|||||||
"facing": 123.4,
|
"facing": 123.4,
|
||||||
"emitRange": 7,
|
"emitRange": 7,
|
||||||
"emitVolume": 42,
|
"emitVolume": 42,
|
||||||
"emitSpeed": 25,
|
"emitSoundSpeed": 25,
|
||||||
"emitEffect": "reverb",
|
"emitEffect": "reverb",
|
||||||
"emitEffectValue": 63.2,
|
"emitEffectValue": 63.2,
|
||||||
"useSound": "ping.ogg",
|
"useSound": "ping.ogg",
|
||||||
@@ -306,7 +306,7 @@ async def test_widget_update_and_use(monkeypatch: pytest.MonkeyPatch) -> None:
|
|||||||
assert item.params.get("facing") == 123.4
|
assert item.params.get("facing") == 123.4
|
||||||
assert item.params.get("emitRange") == 7
|
assert item.params.get("emitRange") == 7
|
||||||
assert item.params.get("emitVolume") == 42
|
assert item.params.get("emitVolume") == 42
|
||||||
assert item.params.get("emitSpeed") == 25
|
assert item.params.get("emitSoundSpeed") == 25
|
||||||
assert item.params.get("emitEffect") == "reverb"
|
assert item.params.get("emitEffect") == "reverb"
|
||||||
assert item.params.get("emitEffectValue") == 63.2
|
assert item.params.get("emitEffectValue") == 63.2
|
||||||
assert item.params.get("useSound") == "sounds/ping.ogg"
|
assert item.params.get("useSound") == "sounds/ping.ogg"
|
||||||
@@ -326,7 +326,7 @@ async def test_widget_update_and_use(monkeypatch: pytest.MonkeyPatch) -> None:
|
|||||||
|
|
||||||
await server._handle_message(
|
await server._handle_message(
|
||||||
client,
|
client,
|
||||||
json.dumps({"type": "item_update", "itemId": item.id, "params": {"emitSpeed": 101}}),
|
json.dumps({"type": "item_update", "itemId": item.id, "params": {"emitSoundSpeed": 101}}),
|
||||||
)
|
)
|
||||||
assert send_payloads[-1].ok is False
|
assert send_payloads[-1].ok is False
|
||||||
assert "emitspeed must be between 0 and 100" in send_payloads[-1].message.lower()
|
assert "emitsoundspeed must be between 0 and 100" in send_payloads[-1].message.lower()
|
||||||
|
|||||||
Reference in New Issue
Block a user