Source editor mouse wheel support (#620)

* Source editor mouse wheel support
This commit is contained in:
euzu
2026-02-27 16:52:13 +01:00
committed by GitHub
parent 49f882173e
commit 57f41bcedb
5 changed files with 34 additions and 8 deletions
+1 -1
View File
@@ -475,7 +475,7 @@
"CLIPBOARD_NOT_SUPPORTED": "Clipboard not supported.\nYour browser or current context does not allow clipboard access.\nPlease use HTTPS or localhost.",
"FAILED_TO_KICK_USER_STREAM": "Failed to kick user stream",
"FAILED_TO_RETRIEVE_WEBPLAYER_URL": "Failed to retrieve webplayer URL",
"CONFIRM_SOURCES_SAVE": "Warning: This is an experimental feature.\nUse at your own risk.\n\nProceed?",
"CONFIRM_SOURCES_SAVE": "Do you really want to save?.\n\nProceed?",
"DOWNLOAD": {
"SUCCESS": "Successfully downloaded",
"FAIL": "Failed to download!",
@@ -87,4 +87,9 @@ $form-width: 520px;
}
}
}
}
.tp__source-editor-form.disabled {
pointer-events: none;
opacity: 0.3;
}
@@ -22,7 +22,7 @@ use std::{
rc::Rc,
};
use wasm_bindgen::{prelude::Closure, JsCast};
use web_sys::{Element, HtmlElement, MouseEvent};
use web_sys::{Element, HtmlElement, MouseEvent, WheelEvent};
use yew::{platform::spawn_local, prelude::*};
const PENDING_LINE: &str = "pending-line";
@@ -1078,6 +1078,26 @@ pub fn SourceEditor(props: &SourceEditorProps) -> Html {
})
};
let handle_canvas_wheel = {
let editor_state_ref = editor_state_ref.clone();
let move_blocks = move_blocks.clone();
Callback::from(move |e: WheelEvent| {
e.prevent_default();
e.stop_propagation();
let mut editor_state = editor_state_ref.borrow_mut();
let delta_y = e.delta_y() as f32;
let (canvas_ox, canvas_oy) = editor_state.canvas_offset;
editor_state.canvas_offset = (canvas_ox, canvas_oy - delta_y);
let initial_positions: Vec<(BlockId, Position)> =
editor_state.blocks.iter().map(|b| (b.id, b.position)).collect();
// Use the move_blocks logic to update current positions in the DOM for smoothness
drop(editor_state);
move_blocks.emit((0.0, 0.0, (0.0, 0.0), initial_positions));
})
};
// Ensure interaction state is cleaned up even when mouseup happens outside the canvas.
{
let editor_state_ref = editor_state_ref.clone();
@@ -1332,6 +1352,7 @@ pub fn SourceEditor(props: &SourceEditorProps) -> Html {
ondragend={handle_drag_end.clone()}
ondragover={handle_drag_over.clone()}
onmousemove={handle_canvas_mouse_move.clone()}
onwheel={handle_canvas_wheel.clone()}
onmousedown={handle_canvas_mouse_down.clone()}
onmouseup={handle_canvas_mouse_up.clone()}
oncontextmenu={handle_canvas_right_click.clone()}>
@@ -808,9 +808,11 @@ pub fn ConfigInputView(props: &ConfigInputViewProps) -> Html {
}
};
let button_disabled = *show_alias_form_state || *show_epg_form_state;
let render_sidebar = || {
html! {
<div class="tp__source-editor-form__sidebar">
<div class={concat_string!("tp__source-editor-form__sidebar", if button_disabled {" disabled"} else {""})}>
<IconButton class={format!("tp__app-sidebar-menu--{}{}", InputFormPage::Main, if *view_visible == InputFormPage::Main { " active" } else {""})} icon="Settings" hint={translate.t(LABEL_MAIN)} name={InputFormPage::Main.to_string()} onclick={&handle_menu_click}></IconButton>
{html_if!(!library_input, {
<IconButton class={format!("tp__app-sidebar-menu--{}{}", InputFormPage::Alias, if *view_visible == InputFormPage::Alias { " active" } else {""})} icon="Alias" hint={translate.t(LABEL_ALIAS)} name={InputFormPage::Alias.to_string()} onclick={&handle_menu_click}></IconButton>
@@ -826,8 +828,6 @@ pub fn ConfigInputView(props: &ConfigInputViewProps) -> Html {
}
};
let button_disabled = *show_alias_form_state || *show_epg_form_state;
html! {
<div class="tp__source-editor-form tp__config-view-page">
<div class="tp__source-editor-form__toolbar tp__form-page__toolbar">
@@ -320,6 +320,8 @@ pub fn XtreamTargetOutputView(props: &XtreamTargetOutputViewProps) -> Html {
}
};
let button_disabled = *show_trakt_list_form_state;
let render_sidebar = || {
let main_class = format!(
"tp__app-sidebar-menu--{}{}",
@@ -332,7 +334,7 @@ pub fn XtreamTargetOutputView(props: &XtreamTargetOutputViewProps) -> Html {
if *view_visible == XtreamOutputFormPage::Trakt { " active" } else { "" }
);
html! {
<div class="tp__source-editor-form__sidebar">
<div class={concat_string!("tp__source-editor-form__sidebar", if button_disabled {" disabled"} else {""})}>
<IconButton class={main_class} icon="Settings" hint={translate.t(LABEL_MAIN)} name={XtreamOutputFormPage::Main.to_string()} onclick={&handle_menu_click}></IconButton>
<IconButton class={trakt_class} icon="Trakt" hint={translate.t(LABEL_TRAKT)} name={XtreamOutputFormPage::Trakt.to_string()} onclick={&handle_menu_click}></IconButton>
</div>
@@ -374,8 +376,6 @@ pub fn XtreamTargetOutputView(props: &XtreamTargetOutputViewProps) -> Html {
})
};
let button_disabled = *show_trakt_list_form_state;
html! {
<div class="tp__source-editor-form tp__config-view-page">
<div class="tp__source-editor-form__toolbar tp__form-page__toolbar">