Skip to content

ADFA-6214 | Polish Chat UX, Input Scroll, Shortcuts, and Data-Loss Fix - #109

Merged
jatezzz merged 5 commits into
mainfrom
fix/ADFA-6214-chat-ux-polish
Sep 29, 2026
Merged

jatezzz merged 5 commits into
mainfrom
fix/ADFA-6214-chat-ux-polish

Conversation

@jatezzz

@jatezzz jatezzz commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR addresses multiple UX pain points in the Agent chat interface to improve context visibility, interaction fluidity, and application reliability.

  • Chat Header Context: The active chat title now dynamically displays in the header, truncating properly and showing a long-press tooltip. Titles are automatically generated by the LLM after the first reply, with a "Naming chat…" progress state shown during generation.
  • Input Scrolling: Implemented PromptScrollGuard and PromptHeightCap to allow vertical scrolling inside a multiline chat input. This ensures the user can read long prompts without accidentally dragging the parent bottom sheet.
  • Keyboard Shortcuts: Introduced a custom KeyboardShortcutHandler that allows sending messages via Shift + Enter on hardware keyboards, while explicitly preserving Enter for inserting newlines.
  • Data-Loss Fix: The chat composer's sendPrompt logic now refuses the send and leaves the typed text intact if the API key is missing. Additionally, backend setup warnings (flagged via isSetupError) are automatically purged from the transcript once a valid API key is saved.
  • Styling Polish: Added Material Design dividers to the Gemini and OpenAI settings panes. User messages longer than four lines are now collapsible via a toggle button, and feature an updated max-width layout constraint.

Details

  • UI Updates: Added dynamic toolbar titles, fold/unfold toggles for user messages, and a new message copy action.
  • Settings Styling: Included visual dividers (1dp height, @color/plugin_outline_variant) to the API settings XML layouts.
  • Documentation: Updated the internal index.html guide to reflect the new shortcuts, collapsible messages, and automated chat naming behaviors.

DEMO:

https://drive.google.com/file/d/1V7wBrhiPVKrHgCcuPUDbV5aW_mWDBT7u/view?usp=sharing

Ticket

ADFA-6214

Observation

  • The KeyboardShortcutHandler logic is completely decoupled from KeyEvent and Android views, making the shortcut rules fully unit-testable without a device runtime.
  • Chat title generation runs asynchronously and includes a supersedeTitleRequest mechanism. If a user sends a new prompt rapidly, the system safely cancels the pending title generation so it doesn't hold up the next run.
  • ChatViewModel manages the expanded/folded state of user bubbles so that message states survive view rebuilds.

@jatezzz
jatezzz changed the base branch from main to fix/ADFA-6119-dropdown-chevron-openai-settings September 24, 2026 22:13
@jatezzz
jatezzz force-pushed the fix/ADFA-6214-chat-ux-polish branch from 1cc14f1 to 01dc347 Compare September 25, 2026 13:19
Base automatically changed from fix/ADFA-6119-dropdown-chevron-openai-settings to main September 25, 2026 14:47
@jatezzz
jatezzz force-pushed the fix/ADFA-6214-chat-ux-polish branch 2 times, most recently from bb4a36a to bba04ef Compare September 25, 2026 15:01
…214]

Title chats from the backend and queue prompts behind an in-flight title; grow the prompt with scrolling, Shift+Enter to send, folding right-aligned user bubbles, copy actions and a directional sidebar toggle. Gemini/OpenAI settings get Material 3 styling.
@jatezzz
jatezzz force-pushed the fix/ADFA-6214-chat-ux-polish branch from 94e119b to 1f8fe70 Compare September 25, 2026 18:41
@jatezzz
jatezzz marked this pull request as ready for review September 25, 2026 18:45
@jatezzz
jatezzz requested review from a team, Daniel-ADFA and itsaky-adfa September 25, 2026 18:45

@alome007 alome007 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMPORTANT

  • viewmodel/ChatViewModel.kt:1288 - title timeout cancels another plugin's generation
  • fragments/ChatFragment.kt:352 - "Naming chat…" survives a rename during the first run

MINOR

  • viewmodel/ChatViewModel.kt:1724 - cleared chat can still receive the old title (plausible, not reproduced)
  • adapters/ChatAdapter.kt:282 - copy action on tool-activity rows
  • plugin/AiCorePlugin.kt:268 - chat-title tooltip describes the pre-PR naming

Paths are under plugins/AI-Core/src/main/kotlin/com/itsaky/androidide/plugins/aicore/. Each finding was re-checked against 1f8fe70. This repo has no written approve/request-changes rule (CLAUDE.md covers the plugin-review skill only), so the default applied. Checked and clean: title settling across stop, session switch and retry; setup-notice clearing; the shortcut handler; the prompt height cap; removed resource and dependency references; Gemini/OpenAI pane styling.

@Daniel-ADFA Daniel-ADFA left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMPORTANT

  • viewmodel/ChatViewModel.kt:1288 - title timeout cancels another plugin's generation
  • fragments/ChatFragment.kt:352 - "Naming chat…" survives a rename during the first run

MINOR

  • viewmodel/ChatViewModel.kt:1724 - cleared chat can still receive the old title (plausible, not reproduced)
  • adapters/ChatAdapter.kt:282 - copy action on tool-activity rows
  • plugin/AiCorePlugin.kt:268 - chat-title tooltip describes the pre-PR naming

Paths are under plugins/AI-Core/src/main/kotlin/com/itsaky/androidide/plugins/aicore/. Each finding was re-checked against 1f8fe70. This repo has no written approve/request-changes rule (CLAUDE.md covers the plugin-review skill only), so the default applied. Checked and clean: title settling across stop, session switch and retry; setup-notice clearing; the shortcut handler; the prompt height cap; removed resource and dependency references; Gemini/OpenAI pane styling.

- Drop the global cancelGeneration() on title timeout; the timed-out
  await already cancels the title's own future, and the global cancel
  could kill another plugin's generation on the shared service.
- Settle the "Naming chat…" placeholder when the user renames the chat.
- Cancel an in-flight title request on Clear Chat, and let only the
  current request settle the placeholder.
- Show the copy action only on user and agent messages.
- Reword the chat-title tooltip for generated titles.
@jatezzz
jatezzz requested a review from Daniel-ADFA September 28, 2026 15:07

@Daniel-ADFA Daniel-ADFA left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2, verified against 1de3b03. Each prior finding was re-read at the new head, not taken from the replies.

IMPORTANT

  • viewmodel/ChatViewModel.kt:1294 - title timeout no longer stops the backend request (reply in its thread)
  • viewmodel/ChatViewModel.kt:1731 - Clear Chat strands another chat's "Naming chat…" (reply in its thread)

Re-check of round 1

  • Title timeout cancels other plugins' work: fixed as reported (no global cancel), but see the new IMPORTANT in that thread.
  • "Naming chat…" survives a rename: fixed. renameSession settles when the new name is non-empty (ChatViewModel.kt, if (trimmed != null) settleTitle).
  • clearMessages() leaves the title job running: fixed for the current chat, but see the new IMPORTANT in that thread.
  • Copy action on tool rows: fixed. copyable is USER || AGENT (ChatAdapter.kt:283).
  • Chat-title tooltip: fixed. Summary and detail describe the backend-written title and the fallback to it.

Both threads with live issues are unresolved. The CHANGES_REQUESTED from round 1 still stands for them.

@jatezzz
jatezzz requested a review from Daniel-ADFA September 28, 2026 16:59

@Daniel-ADFA Daniel-ADFA left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 3, verified against 9783fd8. Approving: what remains is MINOR.

MINOR

  • viewmodel/ChatViewModel.kt:1733 - clearing one chat still cancels another chat's title through the global cancel
  • viewmodel/ChatViewModel.kt:1253 - Stop on a prompt queued behind a title cancels the title

Both are graded MINOR, not IMPORTANT, because they end on this PR's own failure path: the placeholder settles, the chat keeps its prompt as its title, and nothing is stuck or lost. The one cost is that the chat is not re-asked until the process restarts. They share one cause: cancelGeneration() cannot tell a chat run from a title request, so a follow-up that gives titles their own cancel handle fixes both.

Re-check of round 2

  • Title timeout left the backend running: fixed. future.cancelJobOnCancel(job) is now wired in Gemini generate/generateWithHistory, OpenAI generate/generateWithHistory, and local runGeneration.
  • Clear Chat stranded another chat's "Naming chat…": fixed. clearMessages() cancels and nulls titleRequest only for its own session, so the other chat's finally settles its placeholder.

@jatezzz
jatezzz merged commit a31bf62 into main Sep 29, 2026
1 check passed
@jatezzz
jatezzz deleted the fix/ADFA-6214-chat-ux-polish branch September 29, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants