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>
This commit is contained in:
Lazy Bone
2026-01-11 19:45:33 +08:00
committed by GitHub
parent 38f4c2222c
commit f52b3fceb6
13 changed files with 1869 additions and 8 deletions

View File

@@ -28,7 +28,12 @@ class Api::V1::ChatsController < Api::V1::BaseController
)
if @message.save
AssistantResponseJob.perform_later(@message)
# NOTE: Commenting out duplicate job enqueue to fix mobile app receiving duplicate AI responses
# UserMessage model already triggers AssistantResponseJob via after_create_commit callback
# in app/models/user_message.rb:10-12, so this manual enqueue causes the job to run twice,
# resulting in duplicate AI responses with different content and wasted tokens.
# See: https://github.com/dwvwdv/sure (mobile app integration issue)
# AssistantResponseJob.perform_later(@message)
render :show, status: :created
else
@chat.destroy

View File

@@ -13,7 +13,12 @@ class Api::V1::MessagesController < Api::V1::BaseController
)
if @message.save
AssistantResponseJob.perform_later(@message)
# NOTE: Commenting out duplicate job enqueue to fix mobile app receiving duplicate AI responses
# UserMessage model already triggers AssistantResponseJob via after_create_commit callback
# in app/models/user_message.rb:10-12, so this manual enqueue causes the job to run twice,
# resulting in duplicate AI responses with different content and wasted tokens.
# See: https://github.com/dwvwdv/sure (mobile app integration issue)
# AssistantResponseJob.perform_later(@message)
render :show, status: :created
else
render json: { error: "Failed to create message", details: @message.errors.full_messages }, status: :unprocessable_entity