Commit Graph

6 Commits

Author SHA1 Message Date
Tristan Katana
3e36fae751 feat(mobile): lock chat input while bot is responding + 20s timeout (#1538)
* feat(mobile): lock chat input while bot is responding + 20s timeout

- Add _isWaitingForResponse flag to ChatProvider; set in _startPolling,
  cleared in _stopPolling so it covers the full polling lifecycle not
  just the initial HTTP POST
- Add _pollingStartTime + 20s timeout in _pollForUpdates; if the bot
  never responds the flag resets, errorMessage is surfaced, and input
  unlocks automatically
- Gate send button and keyboard shortcut on isSendingMessage ||
  isWaitingForResponse so users cannot queue up multiple messages
  while a response is in flight

(adding an interrupt like with other chat bots would require a larger rewrite of the backend structure)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(mobile): make polling timeout measure inactivity not total duration

Reset _pollingStartTime whenever assistant content grows so the 20s
timeout only fires if no new content has arrived in that window.
Prevents cutting off a slow-but-streaming response mid-generation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(mobile): lock input for full polling duration, not just until first chunk

- Add isPolling getter to ChatProvider (true while _pollingTimer is active)
- Gate send button and intent on isPolling in addition to isWaitingForResponse
  so users cannot submit overlapping prompts while a response is still streaming
- Also auto-scroll while polling is active

* Fix chat polling timeout race and send re-entry guard

Polling timeout was evaluated before the network attempt, allowing it
to fire just as a response became ready. Timeout check now runs after
each poll attempt and only when no progress was made; network errors
fall through to the same check instead of silently swallowing the tick.

Added _isSendInFlight boolean to prevent rapid taps from re-entering
_sendMessage() during the async token fetch window before provider
flags are set. Guard is set synchronously at the top of the method and
cleared in a finally block.

* fix(mobile): prevent overlapping polls and empty-placeholder stop

Add _isPollingRequestInFlight guard so Timer.periodic ticks are
skipped if a getChat request is still in flight, preventing stale
results from resetting state out of order.

Fix empty assistant placeholder incorrectly triggering _stopPolling:
stable is only declared when a previously observed length exists and
hasn't grown. An initial empty message keeps polling until content
arrives or the timeout fires.

* fix(mobile): reset _lastAssistantContentLength in _stopPolling

Prevents stale content-length state from a prior polling session
bleeding into the next one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 21:48:28 +02:00
Tristan Katana
c9f4e8d3d8 feat(mobile): render assistant messages as markdown (#1405)
* feat(mobile): render assistant messages as markdown, keep user text plain

Add flutter_markdown dependency and conditionally render chat bubbles:
- User messages use plain Text to avoid formatting markdown characters
- Assistant messages use MarkdownBody with styled headings, bold, italic,
  lists and code blocks matching the existing color scheme
- Bump Dart SDK constraint to >=3.3.0 to satisfy flutter_markdown 0.7.2

* fix(mobile): address markdown rendering review comments

- Extract MarkdownStyleSheet into _markdownStyle() helper to avoid
  rebuilding TextStyles on every message render
- Replace deprecated imageBuilder with sizedImageBuilder; block http/https
  image URIs to prevent unsolicited remote fetches from AI-generated content
- Commit updated pubspec.lock with flutter_markdown 0.7.2 resolved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix tests

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
2026-04-08 23:52:40 +02:00
Tristan Katana
52b8a2a6fc Fix: Allow users to copy text from the chatbot responses (#1394) 2026-04-07 13:23:36 +02:00
Tristan Katana
6a6548de64 feat(mobile): Add animated TypingIndicator for AI chat responses (#1269)
* feat(mobile): Add animated TypingIndicator widget for AI chat responses

Replaces the static CircularProgressIndicator + "AI is thinking..." text
with an animated TypingIndicator showing pulsing dots while the AI generates
a response. Respects the app color scheme so it works in light and dark themes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix: Normalize stagger progress to [0,1) in TypingIndicator to prevent negative opacity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(mobile): fix typing indicator visibility and run pub get

The typing indicator was only visible for the duration of the HTTP
POST (~instant) because it was tied to `isSendingMessage`. It now
tracks the full AI response lifecycle via a new `isWaitingForResponse`
state that stays true through polling until the response stabilises.

- Add `isWaitingForResponse` to ChatProvider; set on poll start,
  clear on poll stop with notifyListeners so the UI reacts correctly
- Move TypingIndicator inside the ListView as an assistant bubble
  so it scrolls naturally with the conversation
- Add provider listener that auto-scrolls on every update while
  waiting for a response
- Redesign TypingIndicator: 3-dot sequential bounce animation
  (classic chat style) replacing the simultaneous fade

* feat(mobile): overhaul new-chat flow and fix typing indicator bugs
 chat is created lazily
  on first send, eliminating all pre-conversation flashes and crashes
- Inject user message locally into _currentChat immediately on createChat
  so it renders before the first poll completes
- Hide thinking indicator the moment the first assistant content arrives
  (was waiting one extra 2s poll cycle before disappearing)
- Fix double-spinner on new chat: remove manual showDialog spinner and
  use a local _isCreating flag on the FAB instead

* fix(mboile) : address PR review — widget lifecycle safety and new-chat regression

* Fic(mobile): Add mounted check in post-frame callback

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 22:57:46 +01:00
Juan José Mata
ad3087f1dd Improvements to Flutter client (#1042)
* Chat improvements

* Delete/reset account via API for Flutter app

* Fix tests.

* Add "contact us" to settings

* Update mobile/lib/screens/chat_conversation_screen.dart

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Juan José Mata <jjmata@jjmata.com>

* Improve LLM special token detection

* Deactivated user shouldn't have API working

* Fix tests

* API-Key usage

* Flutter app launch failure on no network

* Handle deletion/reset delays

* Local cached data may become stale

* Use X-Api-Key correctly!

---------

Signed-off-by: Juan José Mata <jjmata@jjmata.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-02-22 21:22:32 -05:00
Lazy Bone
f52b3fceb6 feat: implement mobile AI chat feature and fix duplicate response issue (#610)
Backend fixes:
- Fix duplicate AssistantResponseJob triggering causing duplicate AI responses
- UserMessage model already handles job triggering via after_create_commit callback
- Remove redundant job enqueue in chats_controller and messages_controller

Mobile app features:
- Implement complete AI chat interface and conversation management
- Add Chat, Message, and ToolCall data models
- Add ChatProvider for state management with polling mechanism
- Add ChatService to handle all chat-related API requests
- Add chat list screen (ChatListScreen)
- Add conversation detail screen (ChatConversationScreen)
- Refactor navigation structure with bottom navigation bar (MainNavigationScreen)
- Add settings screen (SettingsScreen)
- Optimize TransactionsProvider to support account filtering

Technical details:
- Implement message polling mechanism for real-time AI responses
- Support chat creation, deletion, retry and other operations
- Integrate Material Design 3 design language
- Improve user experience and error handling

Co-authored-by: dwvwdv <dwvwdv@protonmail.com>
2026-01-11 12:45:33 +01:00