From 59fa495a20dec53633b345165ef2cc5253dab329 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 2 Jun 2026 03:00:45 -0400 Subject: [PATCH] fix(gui): Resolve discussion compression error and improve entry tinting visibility - Implement missing format_discussion in project_manager.py. - Fix malformed escape characters in compression AI prompt. - Ensure discussion compression updates the entry list in-place for immediate GUI refresh. - Refactor discussion entry tinting using channels to draw backgrounds reliably behind text. - Standardize Files & Media inventory layout and management buttons. --- src/gui_2.py | 31 +++++++++++++++++++++++-------- src/project_manager.py | 6 ++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/gui_2.py b/src/gui_2.py index 05087445..3523587f 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -3114,15 +3114,20 @@ def render_discussion_hub(app: App) -> None: def render_discussion_entry(app: App, entry: dict, index: int) -> None: with imscope.id(f"disc_{index}"): role = entry.get("role", "User") - bg_col = vec4(20, 20, 20, 255) # default - if role == "User": bg_col = vec4(30, 40, 55, 200) - elif role == "AI": bg_col = vec4(35, 50, 40, 200) - elif role == "Vendor API": bg_col = vec4(45, 40, 30, 200) + # Subtle tints: User(Blue), AI(Green), Vendor(Orange), System(Dark) + bg_col = vec4(40, 50, 70, 0.25) if role == "User" else vec4(45, 60, 50, 0.25) if role == "AI" else vec4(60, 50, 40, 0.25) if role == "Vendor API" else vec4(30, 30, 30, 0.2) - with imscope.style_color(imgui.Col_.child_bg, bg_col): - collapsed, read_mode = entry.get("collapsed", False), entry.get("read_mode", False) - if imgui.button("+" if collapsed else "-"): entry["collapsed"] = not collapsed - imgui.same_line(); render_text_viewer(app, f"Entry #{index+1}", entry["content"], id_suffix=f"disc_btn_{index}"); imgui.same_line(); imgui.set_next_item_width(120) + draw_list = imgui.get_window_draw_list() + p_min = imgui.get_cursor_screen_pos() + full_width = imgui.get_content_region_avail().x + + draw_list.channels_split(2) + draw_list.channels_set_current(1) # Foreground + + imgui.begin_group() + collapsed, read_mode = entry.get("collapsed", False), entry.get("read_mode", False) + if imgui.button("+" if collapsed else "-"): entry["collapsed"] = not collapsed + imgui.same_line(); render_text_viewer(app, f"Entry #{index+1}", entry["content"], id_suffix=f"disc_btn_{index}"); imgui.same_line(); imgui.set_next_item_width(120) if imgui.begin_combo("##role", entry["role"]): for r in app.disc_roles: if imgui.selectable(r, r == entry["role"])[0]: entry["role"] = r @@ -3160,6 +3165,7 @@ def render_discussion_entry(app: App, entry: dict, index: int) -> None: imgui.same_line(); if imgui.button("Del"): if entry in app.disc_entries: app.disc_entries.remove(entry) + draw_list.channels_merge() # Must merge before return return imgui.same_line() if imgui.button("Branch"): app._branch_discussion(index) @@ -3175,6 +3181,15 @@ def render_discussion_entry(app: App, entry: dict, index: int) -> None: if read_mode: render_discussion_entry_read_mode(app, entry, index) else: if not (bool(thinking_segments) and not has_content): ch, entry["content"] = imgui.input_text_multiline("##content", entry["content"], imgui.ImVec2(-1, 150)) + imgui.end_group() + + draw_list.channels_set_current(0) # Background + p_max = imgui.get_item_rect_max() + p_max.x = p_min.x + full_width + draw_list.add_rect_filled(p_min, p_max, imgui.get_color_u32(bg_col), 4.0) + draw_list.channels_merge() + imgui.separator() + imgui.separator() imgui.separator() def render_discussion_entry_read_mode(app: App, entry: dict, index: int) -> None: diff --git a/src/project_manager.py b/src/project_manager.py index b0f9bc40..bdc46835 100644 --- a/src/project_manager.py +++ b/src/project_manager.py @@ -49,6 +49,12 @@ def entry_to_str(entry: dict[str, Any]) -> str: return f"@{ts}\n{role}:\n{content}" return f"{role}:\n{content}" +def format_discussion(entries: list[dict[str, Any]]) -> str: + """ + Convert a list of discussion entry dicts into a single formatted string. + """ + return "\n\n".join([entry_to_str(e) for e in entries]) + def str_to_entry(raw: str, roles: list[str]) -> dict[str, Any]: """