fix(tcp): move vol/pan ruler wheel+dblclick handler to whole row
Scroll wheel giảm/tăng volume chỉ hoạt động trên input 4px; chuyển onWheel+onDoubleClick lên row div (label+dB span cũng ăn), giữ bubbling từ input. Áp dụng cho main TCP và sub-tab, cả app.jsx và precompiled.
This commit is contained in:
+36
-36
@@ -30855,7 +30855,15 @@ STRICT CONSTRAINTS:
|
||||
className: "flex flex-col gap-0.5 text-xs",
|
||||
onClick: e => e.stopPropagation()
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex items-center gap-1"
|
||||
className: "flex items-center gap-1",
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('vol:' + track.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const nv = Math.max(-50, Math.min(7, (track.volumeDb ?? 0) + steps * 0.5));
|
||||
updateTrackVolumeDb(track.id, nv);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackVolumeDb(track.id, 0); },
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "w-8 text-right text-zinc-500 text-xs"
|
||||
}, "Vol:"), /*#__PURE__*/React.createElement("input", {
|
||||
@@ -30865,14 +30873,6 @@ STRICT CONSTRAINTS:
|
||||
step: "0.5",
|
||||
value: track.volumeDb ?? 0,
|
||||
onChange: e => updateTrackVolumeDb(track.id, parseFloat(e.target.value)),
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('vol:' + track.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const nv = Math.max(-50, Math.min(7, (track.volumeDb ?? 0) + steps * 0.5));
|
||||
updateTrackVolumeDb(track.id, nv);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackVolumeDb(track.id, 0); },
|
||||
className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500",
|
||||
style: {
|
||||
height: '4px'
|
||||
@@ -30880,7 +30880,15 @@ STRICT CONSTRAINTS:
|
||||
}), /*#__PURE__*/React.createElement("span", {
|
||||
className: "w-12 text-right font-mono text-zinc-300 text-xs"
|
||||
}, track.volumeDb ?? 0, "dB")), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex items-center gap-1"
|
||||
className: "flex items-center gap-1",
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('pan:' + track.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const np = Math.max(-100, Math.min(100, (track.pan ?? 0) + steps * 5));
|
||||
updateTrackPan(track.id, np);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackPan(track.id, 0); },
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "w-8 text-right text-zinc-500 text-xs"
|
||||
}, "Pan:"), /*#__PURE__*/React.createElement("input", {
|
||||
@@ -30890,14 +30898,6 @@ STRICT CONSTRAINTS:
|
||||
step: "1",
|
||||
value: track.pan ?? 0,
|
||||
onChange: e => updateTrackPan(track.id, parseInt(e.target.value)),
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('pan:' + track.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const np = Math.max(-100, Math.min(100, (track.pan ?? 0) + steps * 5));
|
||||
updateTrackPan(track.id, np);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackPan(track.id, 0); },
|
||||
className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500",
|
||||
style: {
|
||||
height: '4px'
|
||||
@@ -31411,7 +31411,15 @@ STRICT CONSTRAINTS:
|
||||
}, "S"))), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex flex-col gap-2.5 text-[14px] mb-3"
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex items-center gap-1"
|
||||
className: "flex items-center gap-1",
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('vol:' + vTrack.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const nv = Math.max(-50, Math.min(7, (vTrack.volumeDb ?? 0) + steps * 0.5));
|
||||
updateTrackVolumeDb(vTrack.id, nv);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackVolumeDb(vTrack.id, 0); },
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "w-10 text-right text-zinc-500 text-[14px]"
|
||||
}, "Vol:"), /*#__PURE__*/React.createElement("input", {
|
||||
@@ -31422,14 +31430,6 @@ STRICT CONSTRAINTS:
|
||||
id: `tcp-vol-${st.id}`,
|
||||
value: vTrack.volumeDb ?? 0,
|
||||
onChange: e => updateTrackVolumeDb(vTrack.id, parseFloat(e.target.value)),
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('vol:' + vTrack.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const nv = Math.max(-50, Math.min(7, (vTrack.volumeDb ?? 0) + steps * 0.5));
|
||||
updateTrackVolumeDb(vTrack.id, nv);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackVolumeDb(vTrack.id, 0); },
|
||||
className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500",
|
||||
style: {
|
||||
height: '4px'
|
||||
@@ -31438,7 +31438,15 @@ STRICT CONSTRAINTS:
|
||||
className: "w-16 text-right font-mono text-zinc-300 text-[14px]",
|
||||
id: `tcp-vol-label-${st.id}`
|
||||
}, vTrack.volumeDb ?? 0, "dB")), /*#__PURE__*/React.createElement("div", {
|
||||
className: "flex items-center gap-1"
|
||||
className: "flex items-center gap-1",
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('pan:' + vTrack.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const np = Math.max(-100, Math.min(100, (vTrack.pan ?? 0) + steps * 5));
|
||||
updateTrackPan(vTrack.id, np);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackPan(vTrack.id, 0); },
|
||||
}, /*#__PURE__*/React.createElement("span", {
|
||||
className: "w-10 text-right text-zinc-500 text-[14px]"
|
||||
}, "Pan:"), /*#__PURE__*/React.createElement("input", {
|
||||
@@ -31449,14 +31457,6 @@ STRICT CONSTRAINTS:
|
||||
id: `tcp-pan-${st.id}`,
|
||||
value: vTrack.pan ?? 0,
|
||||
onChange: e => updateTrackPan(vTrack.id, parseInt(e.target.value)),
|
||||
onWheel: e => {
|
||||
e.preventDefault();
|
||||
const steps = wheelSteps('pan:' + vTrack.id, e.deltaY, e.deltaMode, 100);
|
||||
if (!steps) return;
|
||||
const np = Math.max(-100, Math.min(100, (vTrack.pan ?? 0) + steps * 5));
|
||||
updateTrackPan(vTrack.id, np);
|
||||
},
|
||||
onDoubleClick: e => { e.stopPropagation(); updateTrackPan(vTrack.id, 0); },
|
||||
className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500",
|
||||
style: {
|
||||
height: '4px'
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,99 @@
|
||||
# Patch TCP vol/pan: move onWheel+onDoubleClick from 4px input to whole row div
|
||||
# Áp dụng cho app.jsx (formatted, CRLF) và app.precompiled.js (minified)
|
||||
# Cách làm: (1) xóa wheel handlers khỏi input, (2) chèn chúng vào props của row div.
|
||||
# Row vol mở đầu "}, " (con đầu flex-col), row pan mở đầu "), " (con thứ hai).
|
||||
import io
|
||||
|
||||
def patch_file(path, spots):
|
||||
with io.open(path, 'r', encoding='utf-8', newline='') as f:
|
||||
s = f.read()
|
||||
for i, spot in enumerate(spots):
|
||||
anchor = spot['anchor']
|
||||
n = s.count(anchor)
|
||||
assert n == 1, f"{path}: anchor count {n} for {anchor[:60]}"
|
||||
p_anchor = s.index(anchor)
|
||||
p_wheel = s.rfind(spot['wheel_marker'], 0, p_anchor + len(anchor) + 1)
|
||||
assert p_wheel != -1, f"{path}: wheel_marker not found for {anchor[:40]}"
|
||||
p_class = s.index(spot['class_marker'], p_wheel)
|
||||
wheel_props = s[p_wheel:p_class].rstrip()
|
||||
|
||||
# (1) xóa handlers khỏi input (giữ dấu phẩy trước className)
|
||||
del_start = p_wheel - spot['pre_wheel']
|
||||
del_end = p_class - spot['pre_class']
|
||||
s = s[:del_start] + s[del_end:]
|
||||
|
||||
# (2) chèn handlers vào props row div
|
||||
p_row = s.rfind(spot['row_open'], 0, del_start)
|
||||
assert p_row != -1, f"{path}: row_open not found for spot {i} ({anchor[:40]})"
|
||||
p_insert = spot['insert_pos'](s, p_row)
|
||||
s = s[:p_insert] + spot['insert_prefix'] + wheel_props + s[p_insert:]
|
||||
with io.open(path, 'w', encoding='utf-8', newline='') as f:
|
||||
f.write(s)
|
||||
print(f"patched {path}")
|
||||
|
||||
def spots_formatted():
|
||||
NL = '\r\n'
|
||||
def row_open(pre):
|
||||
return (pre + '/*#__PURE__*/React.createElement("div", {' + NL +
|
||||
' className: "flex items-center gap-1"' + NL +
|
||||
' }, /*#__PURE__*/React.createElement("span", {')
|
||||
def spot(anchor, class_marker, pre):
|
||||
return dict(
|
||||
anchor=anchor,
|
||||
wheel_marker='onWheel: e => {',
|
||||
class_marker=class_marker,
|
||||
pre_wheel=10, # '\r\n' + 8 spaces trước onWheel (bỏ dấu phẩy trước nó? KHÔNG: giữ phẩy sau onChange)
|
||||
pre_class=10, # '\r\n' + 8 spaces trước className (xóa cả phẩy sau onDoubleClick)
|
||||
row_open=row_open(pre),
|
||||
insert_pos=lambda s, p_row: s.index('className: "flex items-center gap-1"', p_row) + len('className: "flex items-center gap-1"'),
|
||||
insert_prefix=',\r\n ',
|
||||
)
|
||||
return [
|
||||
spot("wheelSteps('vol:' + track.id,",
|
||||
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
|
||||
'}, '),
|
||||
spot("wheelSteps('pan:' + track.id,",
|
||||
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
|
||||
'), '),
|
||||
spot("wheelSteps('vol:' + vTrack.id,",
|
||||
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
|
||||
'}, '),
|
||||
spot("wheelSteps('pan:' + vTrack.id,",
|
||||
'className: "flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
|
||||
'), '),
|
||||
]
|
||||
|
||||
def spots_minified():
|
||||
def spot(anchor, wheel_marker, class_marker, row_open):
|
||||
return dict(
|
||||
anchor=anchor,
|
||||
wheel_marker=wheel_marker,
|
||||
class_marker=class_marker,
|
||||
pre_wheel=1, # ',' trước onWheel
|
||||
pre_class=1, # ',' trước className
|
||||
row_open=row_open,
|
||||
insert_pos=lambda s, p_row: s.index('},/*#__PURE__*/React.createElement("span",{', p_row),
|
||||
insert_prefix=',',
|
||||
)
|
||||
return [
|
||||
spot("wheelSteps('vol:'+track.id",
|
||||
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('vol:'+track.id",
|
||||
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
|
||||
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-8 text-right text-zinc-500 text-xs"},"Vol:"),'),
|
||||
spot("wheelSteps('pan:'+track.id",
|
||||
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('pan:'+track.id",
|
||||
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
|
||||
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-8 text-right text-zinc-500 text-xs"},"Pan:"),'),
|
||||
spot("wheelSteps('vol:'+vTrack.id",
|
||||
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('vol:'+vTrack.id",
|
||||
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-cyan-500"',
|
||||
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-10 text-right text-zinc-500 text-[14px]"},"Vol:"),'),
|
||||
spot("wheelSteps('pan:'+vTrack.id",
|
||||
"onWheel:e=>{e.preventDefault();const steps=wheelSteps('pan:'+vTrack.id",
|
||||
'className:"flex-1 h-1 bg-zinc-700 rounded-lg appearance-none cursor-pointer accent-purple-500"',
|
||||
'React.createElement("div",{className:"flex items-center gap-1"},/*#__PURE__*/React.createElement("span",{className:"w-10 text-right text-zinc-500 text-[14px]"},"Pan:"),'),
|
||||
]
|
||||
|
||||
if __name__ == '__main__':
|
||||
patch_file('app/static/js/app.jsx', spots_formatted())
|
||||
patch_file('app/static/js/app.precompiled.js', spots_minified())
|
||||
Reference in New Issue
Block a user