-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CMM-839 odie link UI with wordpress rs #22285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
adalpari
wants to merge
64
commits into
trunk
Choose a base branch
from
feature/CMM-839-Odie-link-UI-with-wordpress-rs
base: trunk
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,407
−207
Open
Changes from all commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
ee9bde8
Creating library
adalpari df7aa44
Creating list screen
adalpari 488c373
Adding conversation screen
adalpari 1fee31d
Adding the + and the welcome items
adalpari 036fec7
Navigating to the new ai support
adalpari 817feb0
Renaming
adalpari b74f1ab
Some refactor
adalpari 77423c4
Extracting common methods
adalpari 5ac7784
Accessing the API
adalpari 6324b04
Modifying fields
adalpari d677ce0
Fixing message visibuil
adalpari e14fe06
Some styling
adalpari d804184
Extracting strings
adalpari 82f1da0
Improving previews in code
adalpari 54e8621
Previewing dark mode
adalpari 2b6c494
Removing unused func
adalpari 959072d
Some styling
adalpari 0195829
Extracting model classes
adalpari 368ea9a
Some refactoring
adalpari 8ecf787
Creating repository
adalpari a473461
Compile fix
adalpari e33a47a
Creating conversation
adalpari 15cb4b5
Removing userWantsToTalkToHuman
adalpari 9b7a67b
Add conversation request function
adalpari be0347f
Load real data
adalpari e4b81f6
Adding loading spinner
adalpari 53463e8
detekt
adalpari f17a90f
Username
adalpari e80af2d
manifest fix
adalpari 8cb5d72
Merge branch 'trunk' into feature/CMM-837-Oddie-bot-support-UI
adalpari 1ff9448
'feature/CMM-837-Oddie-bot-support-UI' into feature/CMM-839-Odie-lin…
adalpari 1687538
compile fix
adalpari 775794f
Updating rust lib version
adalpari 24c91f3
Handling send new messages
adalpari 4bdb8a5
Conversations loading spinner
adalpari b84074d
Handling new messages
adalpari f580498
Loading message bubble
adalpari 89ecd6f
Preventing send message when the bot hasn't answered
adalpari 45d0117
Using custom OkHttp
adalpari 180b985
Showing user/bot interaction
adalpari da2150a
Fixing new conversation creation
adalpari 7810fad
Merge branch 'trunk' into feature/CMM-839-Odie-link-UI-with-wordpress-rs
adalpari c9edfe2
Merge trunk and fixes
adalpari 59d6c50
Using proper plurals
adalpari 114c1f5
Theme fix
adalpari 910aac9
Initialization error
adalpari e2489a6
Basic error handling
adalpari 4284bbb
Error handling when loading conversations
adalpari 69bbe25
Handling empty list
adalpari 0546031
Sending message error handling
adalpari 865bbd3
Removing last message when error
adalpari ea53ca7
Better handling the can send
adalpari 5b4e4db
Adding pull to refresh
adalpari b729a0a
detekt and style
adalpari c0cffe1
Check fix
adalpari dbbf5e8
Small suggested changes and typos
adalpari 6617f08
Extracting WpComApiClient construction to WpComApiClientProvider to m…
adalpari fe7ff77
Adding tests for AIBotSupportRepository
adalpari 6358099
Creating tests for AIBotSupportViewModel
adalpari fc3eb5b
Injecting the IO dispatcher instead of using static reference
adalpari a1d6f81
Merge branch 'trunk' into feature/CMM-839-Odie-link-UI-with-wordpress-rs
adalpari a22e42e
Potential fix for scrllong issue
adalpari 9a2e2a0
Merge branch 'feature/CMM-839-Odie-link-UI-with-wordpress-rs' of http…
adalpari aaecb01
Merge branch 'trunk' into feature/CMM-839-Odie-link-UI-with-wordpress-rs
adalpari File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
WordPress/src/main/java/org/wordpress/android/networking/restapi/WpComApiClientProvider.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package org.wordpress.android.networking.restapi | ||
|
||
import okhttp3.OkHttpClient | ||
import rs.wordpress.api.kotlin.WpComApiClient | ||
import rs.wordpress.api.kotlin.WpHttpClient | ||
import rs.wordpress.api.kotlin.WpRequestExecutor | ||
import uniffi.wp_api.WpAuthentication | ||
import uniffi.wp_api.WpAuthenticationProvider | ||
import java.util.concurrent.TimeUnit | ||
import javax.inject.Inject | ||
|
||
private const val READ_WRITE_TIMEOUT = 60L | ||
private const val CONNECT_TIMEOUT = 30L | ||
|
||
class WpComApiClientProvider @Inject constructor() { | ||
fun getWpComApiClient(accessToken: String): WpComApiClient { | ||
val okHttpClient = OkHttpClient.Builder() | ||
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS) | ||
.readTimeout(READ_WRITE_TIMEOUT, TimeUnit.SECONDS) | ||
.writeTimeout(READ_WRITE_TIMEOUT, TimeUnit.SECONDS) | ||
.build() | ||
|
||
return WpComApiClient( | ||
requestExecutor = WpRequestExecutor(httpClient = WpHttpClient.CustomOkHttpClient(okHttpClient)), | ||
authProvider = WpAuthenticationProvider.staticWithAuth(WpAuthentication.Bearer(token = accessToken!!) | ||
) | ||
) | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
160 changes: 160 additions & 0 deletions
160
...ss/src/main/java/org/wordpress/android/support/aibot/repository/AIBotSupportRepository.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
package org.wordpress.android.support.aibot.repository | ||
|
||
import kotlinx.coroutines.CoroutineDispatcher | ||
import kotlinx.coroutines.withContext | ||
import org.wordpress.android.fluxc.utils.AppLogWrapper | ||
import org.wordpress.android.modules.IO_THREAD | ||
import org.wordpress.android.networking.restapi.WpComApiClientProvider | ||
import org.wordpress.android.support.aibot.model.BotConversation | ||
import org.wordpress.android.support.aibot.model.BotMessage | ||
import org.wordpress.android.util.AppLog | ||
import rs.wordpress.api.kotlin.WpComApiClient | ||
import rs.wordpress.api.kotlin.WpRequestResult | ||
import uniffi.wp_api.AddMessageToBotConversationParams | ||
import uniffi.wp_api.BotConversationSummary | ||
import uniffi.wp_api.CreateBotConversationParams | ||
import uniffi.wp_api.GetBotConversationParams | ||
import javax.inject.Inject | ||
import javax.inject.Named | ||
|
||
private const val BOT_ID = "jetpack-chat-mobile" | ||
|
||
class AIBotSupportRepository @Inject constructor( | ||
private val appLogWrapper: AppLogWrapper, | ||
private val wpComApiClientProvider: WpComApiClientProvider, | ||
@Named(IO_THREAD) private val ioDispatcher: CoroutineDispatcher, | ||
) { | ||
private var accessToken: String? = null | ||
private var userId: Long = 0 | ||
|
||
private val wpComApiClient: WpComApiClient by lazy { | ||
check(accessToken != null || userId != 0L) { "Repository not initialized" } | ||
wpComApiClientProvider.getWpComApiClient(accessToken!!) | ||
} | ||
|
||
fun init(accessToken: String, userId: Long) { | ||
this.accessToken = accessToken | ||
this.userId = userId | ||
} | ||
|
||
suspend fun loadConversations(): List<BotConversation> = withContext(ioDispatcher) { | ||
val response = wpComApiClient.request { requestBuilder -> | ||
requestBuilder.supportBots().getBotConverationList(BOT_ID) | ||
} | ||
when (response) { | ||
is WpRequestResult.Success -> { | ||
val conversations = response.response.data | ||
conversations.toBotConversations() | ||
} | ||
|
||
else -> { | ||
appLogWrapper.e(AppLog.T.SUPPORT, "Error loading conversations: $response") | ||
emptyList() | ||
} | ||
} | ||
} | ||
|
||
suspend fun loadConversation(chatId: Long): BotConversation? = withContext(ioDispatcher) { | ||
val response = wpComApiClient.request { requestBuilder -> | ||
requestBuilder.supportBots().getBotConversation( | ||
botId = BOT_ID, | ||
chatId = chatId.toULong(), | ||
params = GetBotConversationParams() | ||
) | ||
} | ||
when (response) { | ||
is WpRequestResult.Success -> { | ||
val conversation = response.response.data | ||
conversation.toBotConversation() | ||
} | ||
|
||
else -> { | ||
appLogWrapper.e(AppLog.T.SUPPORT, "Error loading conversation $chatId: $response") | ||
null | ||
} | ||
} | ||
} | ||
|
||
suspend fun createNewConversation(message: String): BotConversation? = withContext(ioDispatcher) { | ||
val response = wpComApiClient.request { requestBuilder -> | ||
requestBuilder.supportBots().createBotConversation( | ||
botId = BOT_ID, | ||
CreateBotConversationParams( | ||
message = message, | ||
userId = userId | ||
) | ||
) | ||
} | ||
|
||
when (response) { | ||
is WpRequestResult.Success -> { | ||
val conversation = response.response.data | ||
conversation.toBotConversation() | ||
} | ||
|
||
else -> { | ||
appLogWrapper.e(AppLog.T.SUPPORT, "Error creating new conversation $response") | ||
null | ||
} | ||
} | ||
} | ||
|
||
suspend fun sendMessageToConversation(chatId: Long, message: String): BotConversation? = | ||
withContext(ioDispatcher) { | ||
val response = wpComApiClient.request { requestBuilder -> | ||
requestBuilder.supportBots().addMessageToBotConversation( | ||
botId = BOT_ID, | ||
chatId = chatId.toULong(), | ||
params = AddMessageToBotConversationParams( | ||
message = message, | ||
context = mapOf() | ||
) | ||
) | ||
} | ||
|
||
when (response) { | ||
is WpRequestResult.Success -> { | ||
val conversation = response.response.data | ||
conversation.toBotConversation() | ||
} | ||
|
||
else -> { | ||
appLogWrapper.e( | ||
AppLog.T.SUPPORT, | ||
"Error sending message to conversation $chatId: $response" | ||
) | ||
null | ||
} | ||
} | ||
} | ||
|
||
private fun List<BotConversationSummary>.toBotConversations(): List<BotConversation> = | ||
map { it.toBotConversation() } | ||
|
||
|
||
private fun BotConversationSummary.toBotConversation(): BotConversation = | ||
BotConversation ( | ||
id = chatId.toLong(), | ||
createdAt = createdAt, | ||
mostRecentMessageDate = lastMessage.createdAt, | ||
lastMessage = lastMessage.content, | ||
messages = listOf() | ||
) | ||
|
||
private fun uniffi.wp_api.BotConversation.toBotConversation(): BotConversation = | ||
BotConversation ( | ||
id = chatId.toLong(), | ||
createdAt = createdAt, | ||
mostRecentMessageDate = messages.last().createdAt, | ||
lastMessage = messages.last().content, | ||
messages = messages.map { it.toBotMessage() } | ||
) | ||
|
||
private fun uniffi.wp_api.BotMessage.toBotMessage(): BotMessage = | ||
BotMessage( | ||
id = messageId.toLong(), | ||
text = content, | ||
date = createdAt, | ||
isWrittenByUser = role == "user" | ||
) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both accessToken and userId are required for the client; the OR condition allows initialization with only one set, leading to a possible NPE on accessToken!!. Change to logical AND: check(accessToken != null && userId != 0L) { "Repository not initialized" }.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emmm, that's not the way it works... It wull fail if "condition 1 OR condition 2" fail. So, it looks correct to me...