From de899b5678cbeee965f3f9d0ebf11ff1b9d13262 Mon Sep 17 00:00:00 2001 From: Tangem Date: Fri, 14 Jul 2023 11:37:10 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/tap/common/chat/ChatManager.kt | 8 +++- .../tap/common/chat/opener/ChatOpener.kt | 3 +- .../implementation/SprinklrChatOpener.kt | 5 +- .../implementation/ZendeskChatOpener.kt | 32 +++++++++---- .../tap/common/feedback/FeedbackManager.kt | 48 +++++++++++++++---- 5 files changed, 73 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt b/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt index 182aa7350b..56ded693ad 100644 --- a/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt +++ b/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt @@ -12,6 +12,7 @@ import com.tangem.tap.common.chat.opener.implementation.SprinklrChatOpener import com.tangem.tap.common.chat.opener.implementation.ZendeskChatOpener import com.tangem.tap.common.redux.AppState import org.rekotlin.Store +import java.io.File class ChatManager( private val preferencesStorage: PreferencesDataSource, @@ -20,7 +21,7 @@ class ChatManager( ) { private val openers = mutableMapOf() - fun open(config: ChatConfig, feedbackDataBuilder: (Context) -> String) { + fun open(config: ChatConfig, createLogsFile: (Context) -> File?, createFeedbackFile: (Context) -> File?) { val opener = openers.getOrPut(config) { when (config) { is SprinklrConfig -> SprinklrChatOpener(getSprinklrUserId(), config, store, foregroundActivityObserver) @@ -28,7 +29,10 @@ class ChatManager( } } - opener.open(feedbackDataBuilder) + opener.open( + createFeedbackFile = createFeedbackFile, + createLogsFile = createLogsFile, + ) } private fun getZendeskUserId(): String { diff --git a/app/src/main/java/com/tangem/tap/common/chat/opener/ChatOpener.kt b/app/src/main/java/com/tangem/tap/common/chat/opener/ChatOpener.kt index e3757286e7..aff21cad05 100644 --- a/app/src/main/java/com/tangem/tap/common/chat/opener/ChatOpener.kt +++ b/app/src/main/java/com/tangem/tap/common/chat/opener/ChatOpener.kt @@ -1,7 +1,8 @@ package com.tangem.tap.common.chat.opener import android.content.Context +import java.io.File internal interface ChatOpener { - fun open(feedbackDataBuilder: (Context) -> String) + fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt b/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt index c9b8fdb4f9..f8936d6abd 100644 --- a/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt +++ b/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt @@ -2,14 +2,15 @@ package com.tangem.tap.common.chat.opener.implementation import android.content.Context import android.content.Intent +import com.tangem.datasource.config.models.SprinklrConfig import com.tangem.tap.ForegroundActivityObserver import com.tangem.tap.common.chat.opener.ChatOpener -import com.tangem.datasource.config.models.SprinklrConfig import com.tangem.tap.common.redux.AppState import com.tangem.tap.features.sprinklr.redux.SprinklrAction import com.tangem.tap.features.sprinklr.ui.SprinklrActivity import com.tangem.tap.withForegroundActivity import org.rekotlin.Store +import java.io.File internal class SprinklrChatOpener( private val userId: String, @@ -17,7 +18,7 @@ internal class SprinklrChatOpener( private val store: Store, private val foregroundActivityObserver: ForegroundActivityObserver, ) : ChatOpener { - override fun open(feedbackDataBuilder: (Context) -> String) { + override fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) { store.dispatch(SprinklrAction.Init(userId, config)) foregroundActivityObserver.withForegroundActivity { activity -> val intent = Intent(activity, SprinklrActivity::class.java) diff --git a/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/ZendeskChatOpener.kt b/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/ZendeskChatOpener.kt index 0e5d38b0da..1c6198806c 100644 --- a/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/ZendeskChatOpener.kt +++ b/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/ZendeskChatOpener.kt @@ -2,34 +2,34 @@ package com.tangem.tap.common.chat.opener.implementation import android.content.Context import com.tangem.core.analytics.Analytics +import com.tangem.datasource.config.models.ZendeskConfig import com.tangem.domain.common.LogConfig import com.tangem.tap.ForegroundActivityObserver import com.tangem.tap.common.chat.opener.ChatOpener -import com.tangem.datasource.config.models.ZendeskConfig import com.tangem.tap.withForegroundActivity import com.tangem.wallet.R import com.zendesk.logger.Logger -import zendesk.chat.Chat -import zendesk.chat.ChatConfiguration -import zendesk.chat.ChatEngine -import zendesk.chat.ChatProvidersConfiguration -import zendesk.chat.VisitorInfo +import timber.log.Timber +import zendesk.chat.* import zendesk.configurations.Configuration import zendesk.messaging.MessagingActivity +import java.io.File internal class ZendeskChatOpener( private val userId: String, private val config: ZendeskConfig, private val foregroundActivityObserver: ForegroundActivityObserver, ) : ChatOpener { + private var isInitialized = false - override fun open(feedbackDataBuilder: (Context) -> String) { + override fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) { foregroundActivityObserver.withForegroundActivity { activity -> initZendeskIfNeeded(activity.applicationContext) setChatVisitorInfo() - setChatVisitorNote(feedbackDataBuilder(activity)) showMessagingActivity(activity) + sendFeedbackFile(createFeedbackFile(activity)) + sendLogsFile(createLogsFile(activity)) } } @@ -48,8 +48,20 @@ internal class ZendeskChatOpener( ChatProvidersConfiguration.builder().withVisitorInfo(visitorInfo).build() } - private fun setChatVisitorNote(note: String) { - Chat.INSTANCE.providers()?.profileProvider()?.setVisitorNote(note) + private fun sendFeedbackFile(feedbackFile: File?) { + if (isInitialized && feedbackFile != null) { + Chat.INSTANCE.providers()?.chatProvider()?.sendFile(feedbackFile) { _, bytesUploaded, _ -> + Timber.d("Log file sent", "bytesUploaded: $bytesUploaded") + } + } + } + + private fun sendLogsFile(logsFile: File?) { + if (isInitialized && logsFile != null) { + Chat.INSTANCE.providers()?.chatProvider()?.sendFile(logsFile) { _, bytesUploaded, _ -> + Timber.d("Log file sent", "bytesUploaded: $bytesUploaded") + } + } } private fun showMessagingActivity(context: Context) { diff --git a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt index 6fddf99607..c1e9ae43b1 100644 --- a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt @@ -1,9 +1,9 @@ package com.tangem.tap.common.feedback import android.content.Context +import com.tangem.datasource.config.models.ChatConfig import com.tangem.domain.common.TapWorkarounds import com.tangem.tap.common.chat.ChatManager -import com.tangem.datasource.config.models.ChatConfig import com.tangem.tap.common.extensions.sendEmail import com.tangem.tap.common.log.TangemLogCollector import com.tangem.tap.foregroundActivityObserver @@ -22,32 +22,61 @@ class FeedbackManager( private val chatManager: ChatManager, ) { + private var sessionFeedbackFile: File? = null + private var sessionLogsFile: File? = null + fun sendEmail(feedbackData: FeedbackData, onFail: ((Exception) -> Unit)? = null) { feedbackData.prepare(infoHolder) foregroundActivityObserver.withForegroundActivity { activity -> - val fileLog = createLogFile(activity) activity.sendEmail( email = getSupportEmail(), subject = activity.getString(feedbackData.subjectResId), message = feedbackData.joinTogether(activity, infoHolder), - file = fileLog, + file = getLogFile(activity), onFail = onFail, ) } } fun openChat(config: ChatConfig, feedbackData: FeedbackData) { - chatManager.open(config) { context -> - feedbackData.run { + chatManager.open( + config = config, + createLogsFile = ::getLogFile, + createFeedbackFile = { context -> getFeedbackFile(context, feedbackData) }, + ) + } + + private fun getFeedbackFile(context: Context, feedbackData: FeedbackData): File? { + return try { + if (sessionFeedbackFile != null) { + return sessionFeedbackFile + } + val file = File(context.filesDir, FEEDBACK_FILE) + file.delete() + file.createNewFile() + + val feedback = feedbackData.run { prepare(infoHolder) joinTogether(context, infoHolder) } + val fileWriter = FileWriter(file) + fileWriter.write(feedback) + fileWriter.close() + + sessionFeedbackFile = file + sessionFeedbackFile + } catch (ex: Exception) { + Timber.e(ex, "Can't create the logs file") + null } } - private fun createLogFile(context: Context): File? { + private fun getLogFile(context: Context): File? { return try { - val file = File(context.filesDir, "logs.txt") + if (sessionLogsFile != null) { + return sessionLogsFile + } + val file = File(context.filesDir, LOGS_FILE) file.delete() file.createNewFile() @@ -57,7 +86,8 @@ class FeedbackManager( fileWriter.write(stringWriter.toString()) fileWriter.close() logCollector.clearLogs() - file + sessionLogsFile = file + sessionLogsFile } catch (ex: Exception) { Timber.e(ex, "Can't create the logs file") null @@ -75,5 +105,7 @@ class FeedbackManager( companion object { const val DEFAULT_SUPPORT_EMAIL = "support@tangem.com" const val S2C_SUPPORT_EMAIL = "cardsupport@start2coin.com" + const val FEEDBACK_FILE = "feedback.txt" + const val LOGS_FILE = "logs.txt" } } \ No newline at end of file