diff --git a/changelog.d/1010.misc b/changelog.d/1010.misc
new file mode 100644
index 0000000000..3cb6c1fcfa
--- /dev/null
+++ b/changelog.d/1010.misc
@@ -0,0 +1 @@
+Add VoIP bug report button
\ No newline at end of file
diff --git a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml
index 786923fc98..08d4bc0c15 100644
--- a/library/ui-strings/src/main/res/values-fr/strings_tchap.xml
+++ b/library/ui-strings/src/main/res/values-fr/strings_tchap.xml
@@ -57,7 +57,7 @@
Les externes ne sont pas autorisés à rejoindre ce salon
Les externes sont autorisés à rejoindre ce salon
Autoriser l’accès aux externes à ce salon
- Cette action est irréversible.\nVoulez-vous vraiment autoriser les externes à rejoindre ce salon ?
+ Cette action est irréversible.\nVoulez-vous vraiment autoriser les externes à rejoindre ce salon ?
Accès par lien
Ce salon n’est pas accessible par lien
Ce salon est accessible par lien
@@ -100,6 +100,7 @@
${app_name} ne supporte pas les appels
+ Signaler un problème
Inviter à rejoindre ${app_name}
diff --git a/library/ui-strings/src/main/res/values/strings_tchap.xml b/library/ui-strings/src/main/res/values/strings_tchap.xml
index 7e687b0c4d..635dd9b4ef 100644
--- a/library/ui-strings/src/main/res/values/strings_tchap.xml
+++ b/library/ui-strings/src/main/res/values/strings_tchap.xml
@@ -100,6 +100,7 @@
${app_name} does not support calls
+ Report an issue
Invite to join ${app_name}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt
index 478ed4a58d..c1e64f5f01 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt
@@ -71,6 +71,7 @@ sealed class RoomDetailAction : VectorViewModelAction {
data class StartCall(val isVideo: Boolean) : RoomDetailAction()
data class AcceptCall(val callId: String) : RoomDetailAction()
object EndCall : RoomDetailAction()
+ object SendCallFeedback : RoomDetailAction()
data class AcceptVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction()
data class DeclineVerificationRequest(val transactionId: String, val otherUserId: String) : RoomDetailAction()
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt
index 1183951b45..0799c3657b 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt
@@ -45,6 +45,7 @@ sealed class RoomDetailViewEvents : VectorViewEvents {
data class JoinJitsiConference(val widget: Widget, val withVideo: Boolean) : RoomDetailViewEvents()
object LeaveJitsiConference : RoomDetailViewEvents()
+ object SendCallFeedback : RoomDetailViewEvents()
object OpenInvitePeople : RoomDetailViewEvents()
object OpenSetRoomAvatarDialog : RoomDetailViewEvents()
object OpenRoomSettings : RoomDetailViewEvents()
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
index 708a2930f7..d284e9d054 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
@@ -174,6 +174,8 @@ import im.vector.app.features.permalink.NavigationInterceptor
import im.vector.app.features.permalink.PermalinkFactory
import im.vector.app.features.permalink.PermalinkHandler
import im.vector.app.features.poll.PollMode
+import im.vector.app.features.rageshake.BugReporter
+import im.vector.app.features.rageshake.ReportType
import im.vector.app.features.reactions.EmojiReactionPickerActivity
import im.vector.app.features.roomprofile.RoomProfileActivity
import im.vector.app.features.session.coroutineScope
@@ -230,6 +232,7 @@ class TimelineFragment :
CurrentCallsView.Callback,
VectorMenuProvider {
+ @Inject lateinit var bugReporter: BugReporter
@Inject lateinit var session: Session
@Inject lateinit var avatarRenderer: AvatarRenderer
@Inject lateinit var timelineEventController: TimelineEventController
@@ -380,6 +383,7 @@ class TimelineFragment :
timelineViewModel.observeViewEvents {
when (it) {
+ is RoomDetailViewEvents.SendCallFeedback -> bugReporter.openBugReportScreen(requireActivity(), ReportType.VOIP)
is RoomDetailViewEvents.Failure -> displayErrorMessage(it)
is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds)
is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
index 413c1ca502..3d1f9eb316 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt
@@ -498,6 +498,7 @@ class TimelineViewModel @AssistedInject constructor(
is RoomDetailAction.StartCall -> handleStartCall(action)
is RoomDetailAction.AcceptCall -> handleAcceptCall(action)
is RoomDetailAction.EndCall -> handleEndCall()
+ is RoomDetailAction.SendCallFeedback -> handleSendCallFeedback()
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
is RoomDetailAction.UpdateJoinJitsiCallStatus -> handleJitsiCallJoinStatus(action)
@@ -628,6 +629,10 @@ class TimelineViewModel @AssistedInject constructor(
callManager.endCallForRoom(initialState.roomId)
}
+ private fun handleSendCallFeedback() {
+ _viewEvents.post(RoomDetailViewEvents.SendCallFeedback)
+ }
+
private fun handleSelectStickerAttachment() {
viewModelScope.launch {
val viewEvent = stickerPickerActionHandler.handle()
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt
index 7d846a78aa..dfde57c835 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/CallTileTimelineItem.kt
@@ -31,6 +31,7 @@ import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.onClick
+import im.vector.app.core.extensions.clearDrawables
import im.vector.app.core.extensions.setLeftDrawable
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.features.displayname.getBestName
@@ -97,7 +98,15 @@ abstract class CallTileTimelineItem : AbsBaseMessageItem {
val endCallStatus = holder.resources.getString(R.string.call_tile_video_call_has_ended, attributes.formattedDuration)
diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt
index f9a578acc4..a4abfce415 100755
--- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt
+++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt
@@ -17,11 +17,17 @@
package im.vector.app.features.rageshake
import android.annotation.SuppressLint
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothHeadset
+import android.bluetooth.BluetoothManager
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
import android.os.Build
import android.view.View
+import androidx.core.content.getSystemService
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.squareup.moshi.Types
@@ -165,7 +171,7 @@ class BugReporter @Inject constructor(
/**
* Send a bug report.
*
- * @param reportType The report type (bug, suggestion, feedback)
+ * @param reportType The report type (bug, suggestion, feedback, voip)
* @param withDevicesLogs true to include the device log
* @param withCrashLogs true to include the crash logs
* @param withKeyRequestHistory true to include the crash logs
@@ -283,6 +289,7 @@ class BugReporter @Inject constructor(
val text = when (reportType) {
// Tchap: Use BuildConfig.FLAVOR_target instead of Element
ReportType.BUG_REPORT -> "[${BuildConfig.FLAVOR_target}] $bugDescription"
+ ReportType.VOIP -> "[${BuildConfig.FLAVOR_target}] [voip-feedback] $bugDescription" // Tchap: add VoIP report type
ReportType.SUGGESTION -> "[${BuildConfig.FLAVOR_target}] [Suggestion] $bugDescription"
ReportType.SPACE_BETA_FEEDBACK -> "[${BuildConfig.FLAVOR_target}] [spaces-feedback] $bugDescription"
ReportType.THREADS_BETA_FEEDBACK -> "[${BuildConfig.FLAVOR_target}] [threads-feedback] $bugDescription"
@@ -370,6 +377,13 @@ class BugReporter @Inject constructor(
ReportType.BUG_REPORT -> {
/* nop */
}
+ // Tchap: add VoIP report type
+ ReportType.VOIP -> {
+ builder.addFormDataPart("label", "voip-feedback")
+ builder.addFormDataPart("context", "voip")
+ builder.addFormDataPart("connection", getConnectionType())
+ builder.addFormDataPart("audio_input", getAudioInterface())
+ }
ReportType.SUGGESTION -> builder.addFormDataPart("label", "[Suggestion]")
ReportType.SPACE_BETA_FEEDBACK -> builder.addFormDataPart("label", "spaces-feedback")
ReportType.THREADS_BETA_FEEDBACK -> builder.addFormDataPart("label", "threads-feedback")
@@ -545,6 +559,38 @@ class BugReporter @Inject constructor(
}
)
}
+
+ // Tchap: add connection type in VoIP report
+ private fun getConnectionType(): String {
+ val connectivityManager = context.getSystemService()!!
+ return if (sdkIntProvider.isAtLeast(Build.VERSION_CODES.M)) {
+ val networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
+ when {
+ networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true -> "vpn"
+ networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true -> "wifi"
+ networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == true -> "mobile"
+ else -> "unknown"
+ }
+ } else {
+ @Suppress("DEPRECATION")
+ when (connectivityManager.activeNetworkInfo?.type) {
+ ConnectivityManager.TYPE_VPN -> "vpn"
+ ConnectivityManager.TYPE_WIFI -> "wifi"
+ ConnectivityManager.TYPE_MOBILE -> "mobile"
+ else -> "unknown"
+ }
+ }
+ }
+
+ // Tchap: check if a headset is connected
+ private fun getAudioInterface() = if (isBluetoothHeadsetConnected()) "headset_bluetooth" else "device"
+
+ private fun isBluetoothHeadsetConnected(): Boolean {
+ val bm: BluetoothManager? = context.getSystemService()
+ return bm?.adapter?.let {
+ it.isEnabled && it.getProfileConnectionState(BluetoothHeadset.HEADSET) == BluetoothAdapter.STATE_CONNECTED
+ } ?: false
+ }
// ==============================================================================================================
// crash report management
// ==============================================================================================================
diff --git a/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt b/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt
index f75420ea55..226a48c353 100644
--- a/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt
+++ b/vector/src/main/java/im/vector/app/features/rageshake/ReportType.kt
@@ -23,4 +23,5 @@ enum class ReportType {
THREADS_BETA_FEEDBACK,
AUTO_UISI,
AUTO_UISI_SENDER,
+ VOIP,
}