""" Summary Result Dialog and Error Dialog — fully theme-aware. """ from typing import Any, Optional from ..config import LONG_SUMMARY_THRESHOLD from ..localization import locali def _theme_color(key: str, fallback: int) -> int: try: from org.telegram.ui.ActionBar import Theme return Theme.getColor(getattr(Theme, key)) except Exception: return fallback def scroll_to_message_in_chat(chat_activity: Any, message_id: int, topic_id: int = 0) -> bool: """Scrolls the chat view to a specific message ID.""" if not chat_activity or not message_id: return False try: from android_utils import run_on_ui_thread except ImportError: def run_on_ui_thread(fn): fn() try: def _do_scroll(): for method_name in ("scrollToMessageId", "jumpToMessageId", "scrollToMessage"): if hasattr(chat_activity, method_name): fn = getattr(chat_activity, method_name) try: fn(message_id, topic_id, True, 0, False, 0) return except Exception: try: fn(message_id, topic_id, True) return except Exception: try: fn(message_id, True) return except Exception: pass chat_list = getattr(chat_activity, "chatListView", None) if chat_list and hasattr(chat_list, "scrollToPosition"): try: chat_list.scrollToPosition(0) except Exception: pass run_on_ui_thread(_do_scroll) return True except Exception: return False def show_summary_result_dialog( plugin: Any, chat_activity: Any, summary_text: str, provider_name: str, model_name: str, message_count: int, elapsed_time: float, dialog_id: int = 0, topic_id: int = 0, full_debug_data: str = "", latest_msg_id: int = 0, auto_jump: bool = False, ) -> None: """Renders formatted Markdown summary with theme-aware styling.""" try: from android.content.res import ColorStateList from android.util import TypedValue from android.view import Gravity from android.widget import Button, LinearLayout, ScrollView, TextView from android_utils import OnClickListener, copy_to_clipboard, run_on_ui_thread from client_utils import get_last_fragment from markdown_utils import parse_markdown from org.telegram.messenger import AndroidUtilities from ui.alert import AlertDialogBuilder frag = chat_activity or get_last_fragment() act = frag.getParentActivity() if hasattr(frag, "getParentActivity") else None if not act: return def dp(val: float) -> int: return AndroidUtilities.dp(val) dialog_bg = _theme_color("key_dialogBackground", -15395563) primary = _theme_color("key_dialogTextBlack", -14606047) secondary = _theme_color("key_dialogTextGray3", -7829368) accent = _theme_color("key_dialogTextBlue2", _theme_color("key_windowBackgroundWhiteBlueText", -14575885)) control_bg = _theme_color("key_dialogGrayLine", _theme_color("key_windowBackgroundWhite", dialog_bg)) if auto_jump and latest_msg_id: scroll_to_message_in_chat(frag, latest_msg_id, topic_id) builder = AlertDialogBuilder(act, AlertDialogBuilder.ALERT_TYPE_MESSAGE) builder.set_title(locali.get("RESULT_TITLE")) root = LinearLayout(act) root.setOrientation(LinearLayout.VERTICAL) root.setPadding(dp(20), dp(10), dp(20), dp(10)) root.setBackgroundColor(dialog_bg) header = TextView(act) header.setText(locali.get( "RESULT_HEADER_INFO", provider=provider_name, model=model_name, count=message_count, time=elapsed_time, )) header.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12) header.setTextColor(secondary) header.setPadding(0, 0, 0, dp(6)) root.addView(header) scroll = ScrollView(act) body = TextView(act) try: body.setText(parse_markdown(summary_text)) except Exception: body.setText(summary_text) body.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14) body.setTextColor(primary) body.setLineSpacing(dp(2), 1.0) scroll.addView(body) lp_scroll = LinearLayout.LayoutParams(-1, -2) if len(summary_text) > LONG_SUMMARY_THRESHOLD: lp_scroll = LinearLayout.LayoutParams(-1, dp(340)) root.addView(scroll, lp_scroll) if len(summary_text) > LONG_SUMMARY_THRESHOLD: hint = TextView(act) hint.setText(locali.get("RESULT_SCROLL_HINT")) hint.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11) hint.setGravity(Gravity.CENTER) hint.setTextColor(secondary) hint.setPadding(0, dp(4), 0, dp(4)) root.addView(hint) actions = LinearLayout(act) actions.setOrientation(LinearLayout.HORIZONTAL) actions.setPadding(0, dp(10), 0, 0) def add_action(text: str, callback): btn = Button(act) btn.setText(text) btn.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11) btn.setTextColor(accent) btn.setBackgroundTintList(ColorStateList.valueOf(control_bg)) btn.setOnClickListener(OnClickListener(callback)) actions.addView(btn, LinearLayout.LayoutParams(0, dp(40), 1.0)) add_action(locali.get("RESULT_BTN_SHARE"), lambda *_: _share(act, summary_text)) if latest_msg_id: add_action(locali.get("RESULT_BTN_JUMP"), lambda *_: _jump(frag, latest_msg_id, topic_id)) if full_debug_data: add_action(locali.get("RESULT_BTN_COPY_DATA"), lambda *_: _copy(full_debug_data, "RESULT_DATA_COPIED_NOTICE")) root.addView(actions) builder.set_view(root) def on_copy(dialog, _): copy_to_clipboard(summary_text) try: from ui.bulletin import BulletinHelper BulletinHelper.show_success(locali.get("RESULT_COPIED_NOTICE")) except Exception: pass dialog.dismiss() builder.set_positive_button(locali.get("RESULT_BTN_COPY"), on_copy) builder.set_negative_button("Close", lambda d, _: d.dismiss()) builder.show() except Exception: pass def _share(act: Any, text: str) -> None: try: from android.content import Intent intent = Intent(Intent.ACTION_SEND) intent.setType("text/plain") intent.putExtra(Intent.EXTRA_TEXT, text) act.startActivity(Intent.createChooser(intent, "Share Summary")) except Exception: pass def _jump(frag: Any, msg_id: int, topic_id: int) -> None: scroll_to_message_in_chat(frag, msg_id, topic_id) try: from ui.bulletin import BulletinHelper BulletinHelper.show_info(locali.get("RESULT_JUMPED_NOTICE", id=msg_id)) except Exception: pass def _copy(text: str, notice_key: str) -> None: try: from android_utils import copy_to_clipboard from ui.bulletin import BulletinHelper copy_to_clipboard(text) BulletinHelper.show_success(locali.get(notice_key)) except Exception: pass def show_error_dialog(title: str, error_text: str, debug_log: str = "") -> None: """Displays a theme-aware error dialog with a log-copy button.""" try: from android.content.res import ColorStateList from android.util import TypedValue from android.widget import Button, LinearLayout, TextView from android_utils import OnClickListener, copy_to_clipboard from client_utils import get_last_fragment from org.telegram.messenger import AndroidUtilities from ui.alert import AlertDialogBuilder frag = get_last_fragment() act = frag.getParentActivity() if frag else None if not act: return def dp(val: float) -> int: return AndroidUtilities.dp(val) dialog_bg = _theme_color("key_dialogBackground", -15395563) primary = _theme_color("key_dialogTextBlack", -14606047) danger = _theme_color("key_text_RedBold", -2937041) control_bg = _theme_color("key_dialogGrayLine", _theme_color("key_windowBackgroundWhite", dialog_bg)) builder = AlertDialogBuilder(act, AlertDialogBuilder.ALERT_TYPE_MESSAGE) builder.set_title(title or locali.get("ERROR_TITLE")) root = LinearLayout(act) root.setOrientation(LinearLayout.VERTICAL) root.setPadding(dp(20), dp(10), dp(20), dp(10)) root.setBackgroundColor(dialog_bg) err = TextView(act) err.setText(error_text) err.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14) err.setTextColor(danger) root.addView(err) if debug_log: btn = Button(act) btn.setText(locali.get("ERROR_COPY_LOG_BTN")) btn.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12) btn.setTextColor(primary) btn.setBackgroundTintList(ColorStateList.valueOf(control_bg)) def on_copy(*_): copy_to_clipboard(debug_log) try: from ui.bulletin import BulletinHelper BulletinHelper.show_success(locali.get("ERROR_LOG_COPIED")) except Exception: pass btn.setOnClickListener(OnClickListener(on_copy)) root.addView(btn) builder.set_view(root) builder.set_positive_button("Close", lambda d, _: d.dismiss()) builder.show() except Exception: pass