diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index b3c728a7e..503fe7bdd 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -3659,6 +3659,20 @@ script_mod! { flow: Overlay align: Align{x: 0, y: 0} + translation_lang_backdrop := Button { + width: Fill + height: Fill + text: "" + draw_bg +: { + color: #00000000 + color_hover: #00000000 + color_down: #00000000 + } + draw_text +: { + color: #00000000 + } + } + translation_lang_popup := RoundedView { width: 220 height: Fit @@ -4607,6 +4621,13 @@ impl Widget for RoomScreen { let room_info_sliding_pane = self.room_info_sliding_pane(cx, ids!(room_info_sliding_pane)); let room_info_sliding_pane_widget_uid = room_info_sliding_pane.widget_uid(); let loading_pane = self.loading_pane(cx, ids!(loading_pane)); + let translation_lang_modal = self.view.modal(cx, ids!(translation_lang_modal)); + if translation_lang_modal.is_open() + && !translation::get_global_config().as_ref().is_some_and(|config| config.enabled) + { + translation_lang_modal.close(cx); + } + let translation_lang_modal_open = translation_lang_modal.is_open(); set_room_info_action_modal_open( self.view.modal(cx, ids!(report_room_modal)).is_open() || self.view.modal(cx, ids!(leave_room_confirm_modal)).is_open() @@ -5164,7 +5185,10 @@ impl Widget for RoomScreen { || self.view.modal(cx, ids!(leave_room_confirm_modal)).is_open(); let is_interactive_hit = utils::is_interactive_hit_event(event); let is_pane_shown: bool; - if room_info_action_modal_open { + if translation_lang_modal_open { + is_pane_shown = true; + } + else if room_info_action_modal_open { is_pane_shown = true; } else if loading_pane.is_currently_shown(cx) { @@ -5200,7 +5224,7 @@ impl Widget for RoomScreen { // Makepad already delivers most events to all views regardless of visibility, // so the only thing we'd need here is the conditional below. - if room_info_action_modal_open || !is_pane_shown || !is_interactive_hit { + if translation_lang_modal_open || room_info_action_modal_open || !is_pane_shown || !is_interactive_hit { let Some(room_props) = self.build_room_screen_props(cx, scope, room_screen_widget_uid) else { if !is_pane_shown || !is_interactive_hit { return; @@ -5221,9 +5245,13 @@ impl Widget for RoomScreen { // Forward the event to the inner timeline view, but capture any actions it produces // such that we can handle the ones relevant to only THIS RoomScreen widget right here and now, // ensuring they are not mistakenly handled by other RoomScreen widget instances. - let mut actions_generated_within_this_room_screen = cx.capture_actions(|cx| - self.view.handle_event(cx, event, &mut room_scope) - ); + let mut actions_generated_within_this_room_screen = cx.capture_actions(|cx| { + if translation_lang_modal_open && is_interactive_hit { + translation_lang_modal.handle_event(cx, event, &mut room_scope); + } else { + self.view.handle_event(cx, event, &mut room_scope); + } + }); // Here, we handle and remove any general actions that are relevant to only this RoomScreen. // Removing the handled actions ensures they are not mistakenly handled by other RoomScreen widget instances. actions_generated_within_this_room_screen.retain(|action| { @@ -7800,6 +7828,14 @@ impl RoomScreen { if !translation_lang_modal.is_open() { return; } + if self + .button(cx, ids!(translation_lang_modal.content.translation_lang_backdrop)) + .clicked(actions) + || actions.iter().any(|a| matches!(a.downcast_ref(), Some(ModalAction::Dismissed))) + { + translation_lang_modal.close(cx); + return; + } let lang_ids: &[(&str, &[LiveId])] = &[ ("en", &[live_id!(translation_lang_modal), live_id!(content), live_id!(translation_lang_popup), live_id!(translation_lang_scroll), live_id!(lang_en)]), diff --git a/src/room/room_input_bar.rs b/src/room/room_input_bar.rs index d6d9cb4bb..5f741ac32 100644 --- a/src/room/room_input_bar.rs +++ b/src/room/room_input_bar.rs @@ -1181,6 +1181,11 @@ impl Widget for RoomInputBar { // Always read the latest translation config from global state. // Settings may update it at any time via set_global_config(). self.translation_config = translation::get_global_config(); + if !self.translation_config.as_ref().is_some_and(|config| config.enabled) + && (self.translation_active || self.translation_preview_text.is_some() || self.is_lang_popup_visible) + { + self.deactivate_translation(cx); + } if let Event::Actions(actions) = event { self.handle_actions(cx, scope, actions); @@ -1317,8 +1322,11 @@ impl Widget for RoomInputBar { } let width = self.view.area().rect(cx).size.x as f32; + self.translation_config = translation::get_global_config(); let show_room_info_card = !(width > 1.0 && width < ROOM_INFO_CARD_MOBILE_BREAKPOINT); + let show_translate_button = self.translation_config.as_ref().is_some_and(|config| config.enabled); self.button(cx, ids!(room_info_card_button)).set_visible(cx, show_room_info_card); + self.button(cx, ids!(translate_button)).set_visible(cx, show_translate_button); self.button(cx, ids!(bot_menu_button)) .set_visible(cx, room_screen_props.is_some_and(is_management_bot_room)); @@ -1363,6 +1371,17 @@ impl RoomInputBar { self.view.redraw(cx); } + fn deactivate_translation(&mut self, cx: &mut Cx) { + self.translation_active = false; + self.translation_preview_text = None; + self.translation_request_pending = false; + self.translation_last_source.clear(); + self.view.view(cx, ids!(translation_preview)).set_visible(cx, false); + self.view.view(cx, ids!(translation_lang_wrapper)).set_visible(cx, false); + self.is_lang_popup_visible = false; + self.redraw(cx); + } + /// Handles a language being selected from the popup. fn on_language_selected(&mut self, cx: &mut Cx, code: &str) { self.translation_target_code = code.to_string(); @@ -1486,14 +1505,7 @@ impl RoomInputBar { if self.button(cx, ids!(translate_button)).clicked(actions) { if self.translation_active { // Turn off translation - self.translation_active = false; - self.translation_preview_text = None; - self.translation_request_pending = false; - self.translation_last_source.clear(); - self.view.view(cx, ids!(translation_preview)).set_visible(cx, false); - self.view.view(cx, ids!(translation_lang_wrapper)).set_visible(cx, false); - self.is_lang_popup_visible = false; - self.redraw(cx); + self.deactivate_translation(cx); } else { self.view.view(cx, ids!(translation_lang_wrapper)).set_visible(cx, false); self.is_lang_popup_visible = false; @@ -1524,14 +1536,7 @@ impl RoomInputBar { // Handle close button on translation preview. if self.button(cx, ids!(translation_close_button)).clicked(actions) { - self.translation_active = false; - self.translation_preview_text = None; - self.translation_request_pending = false; - self.translation_last_source.clear(); - self.view.view(cx, ids!(translation_preview)).set_visible(cx, false); - self.view.view(cx, ids!(translation_lang_wrapper)).set_visible(cx, false); - self.is_lang_popup_visible = false; - self.redraw(cx); + self.deactivate_translation(cx); } // Handle the location card being clicked.