diff --git a/jami-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.kt b/jami-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.kt
index 54a58d33ab46a89902711b4d7e9f82202496ad0e..6ca106c1f5f465dbe616b9beffa8aceae916605f 100644
--- a/jami-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.kt
+++ b/jami-android/app/src/main/java/cx/ring/adapters/ConversationAdapter.kt
@@ -292,15 +292,27 @@ class ConversationAdapter(
 
             Interaction.InteractionType.DATA_TRANSFER -> {
                 val file = interaction as DataTransfer
-                val out = if (interaction.isIncoming) 0 else 4
                 if (file.isComplete) {
-                    when {
-                        file.isPicture -> return MessageType.INCOMING_IMAGE.ordinal + out
-                        file.isAudio -> return MessageType.INCOMING_AUDIO.ordinal + out
-                        file.isVideo -> return MessageType.INCOMING_VIDEO.ordinal + out
+                    if (interaction.isIncoming) {
+                        when {
+                            file.isPicture -> MessageType.INCOMING_IMAGE.ordinal
+                            file.isAudio -> MessageType.INCOMING_AUDIO.ordinal
+                            file.isVideo -> MessageType.INCOMING_VIDEO.ordinal
+                            else -> MessageType.INCOMING_FILE.ordinal
+                        }
+                    } else {
+                        when {
+                            file.isPicture -> MessageType.OUTGOING_IMAGE.ordinal
+                            file.isAudio -> MessageType.OUTGOING_AUDIO.ordinal
+                            file.isVideo -> MessageType.OUTGOING_VIDEO.ordinal
+                            else -> MessageType.OUTGOING_FILE.ordinal
+                        }
                     }
+                } else {
+                    if (interaction.isIncoming) {
+                        MessageType.INCOMING_FILE.ordinal
+                    } else MessageType.OUTGOING_FILE.ordinal
                 }
-                out
             }
 
             Interaction.InteractionType.INVALID -> MessageType.INVALID.ordinal
@@ -484,7 +496,6 @@ class ConversationAdapter(
         conversationViewHolder: ConversationViewHolder,
         interaction: Interaction
     ) {
-
         val context = conversationViewHolder.itemView.context
         val conversation = interaction.conversation
         if (conversation == null || conversation !is Conversation) {
@@ -757,9 +768,7 @@ class ConversationAdapter(
         val player = MediaPlayer.create(context, contentUri) ?: return
 
         viewHolder.player = player
-        val playBtn =
-            ContextCompat.getDrawable(cardLayout.context, R.drawable.baseline_play_arrow_24)!!
-                .mutate()
+        val playBtn = ContextCompat.getDrawable(cardLayout.context, R.drawable.baseline_play_arrow_24)!!.mutate()
         DrawableCompat.setTint(playBtn, Color.WHITE)
         cardLayout.foreground = playBtn
         player.setOnCompletionListener { mp: MediaPlayer ->
@@ -781,12 +790,14 @@ class ConversationAdapter(
             }
             video.layoutParams = p
         }
+
         if (video.isAvailable) {
             if (viewHolder.surface == null) {
                 viewHolder.surface = Surface(video.surfaceTexture)
             }
             player.setSurface(viewHolder.surface)
         }
+
         video.surfaceTextureListener = object : SurfaceTextureListener {
             override fun onSurfaceTextureAvailable(
                 surfaceTexture: SurfaceTexture,
@@ -808,8 +819,7 @@ class ConversationAdapter(
                 surface: SurfaceTexture,
                 width: Int,
                 height: Int
-            ) {
-            }
+            ) { }
 
             override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
                 try {
@@ -826,6 +836,7 @@ class ConversationAdapter(
 
             override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {}
         }
+
         video.setOnClickListener {
             try {
                 if (player.isPlaying) {
@@ -850,14 +861,15 @@ class ConversationAdapter(
             val history = interaction.historyObservable.blockingFirst()
             val lastElement = history.last()
             val isDeleted = lastElement is TextMessage && lastElement.body.isNullOrEmpty()
+            val isFileMenu = interaction is DataTransfer && interaction.isComplete
 
             // Configure what should be displayed
-            convActionFileOpen.isVisible = interaction is DataTransfer && interaction.isComplete
-            convActionFileSave.isVisible = interaction is DataTransfer && interaction.isComplete
-            convActionFileDelete.isVisible = false //interaction is DataTransfer && interaction.isComplete
+            convActionFileOpen.isVisible = isFileMenu
+            convActionFileSave.isVisible = isFileMenu
+            convActionFileDelete.isVisible = isFileMenu
             convActionCopyText.isVisible = !isDeleted && interaction !is DataTransfer
-            convActionEdit.isVisible = !isDeleted && !interaction.isIncoming && interaction !is DataTransfer
-            convActionDelete.isVisible = !isDeleted && !interaction.isIncoming
+            convActionEdit.isVisible = !isDeleted && !interaction.isIncoming && interaction is TextMessage
+            convActionDelete.isVisible = !isDeleted && !interaction.isIncoming && interaction is TextMessage
             convActionHistory.isVisible = !isDeleted && history.size > 1
             root.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
 
@@ -897,9 +909,10 @@ class ConversationAdapter(
                 if (convColor != 0 && (interaction.type == Interaction.InteractionType.TEXT
                             || type == MessageType.TransferType.FILE
                             || type == MessageType.TransferType.AUDIO ) && !interaction.isIncoming
-                ) view.background?.setTint(convColor)
-                else view.background?.setTintList(null)
-                // Remove disposable.
+                ) {
+                    view.background?.setTint(convColor)
+                } else view.background?.setTintList(null)
+
                 viewHolder.compositeDisposable.remove(disposable)
             }
 
@@ -965,6 +978,10 @@ class ConversationAdapter(
                 popupWindow.dismiss()
             }
 
+            convActionFileDelete.setOnClickListener {
+                presenter.deleteConversationFile(interaction)
+            }
+
             // Manage Edit and Delete actions
             if (!interaction.isIncoming) {
                 // Edit
@@ -1010,10 +1027,6 @@ class ConversationAdapter(
                 convActionDelete.setOnClickListener(null)
             }
 
-//            convActionFileDelete.setOnClickListener {
-//                TODO()
-//            }
-
             // Share
             convActionShare.setOnClickListener {
                 if (interaction is DataTransfer)
@@ -1067,6 +1080,7 @@ class ConversationAdapter(
                 else -> String.format(Formatter.formatFileSize(context, file.totalSize))
             }
         })
+
         val isDateShown = hasPermanentDateString(file, position)
         if (isDateShown) {
             viewHolder.compositeDisposable.add(timestampUpdateTimer.subscribe {
@@ -1077,6 +1091,7 @@ class ConversationAdapter(
         } else {
             viewHolder.mMsgDetailTxtPerm?.visibility = View.GONE
         }
+
         val contact = interaction.contact ?: return
         if (interaction.isIncoming && presenter.isGroup()) {
             viewHolder.mAvatar?.let { avatar ->
@@ -1132,6 +1147,7 @@ class ConversationAdapter(
                 }
                 configureImage(viewHolder, path, file.body)
             }
+
             MessageType.TransferType.VIDEO -> {
                 // Add margin if message need to be separated.
                 viewHolder.mAnswerLayout?.updateLayoutParams<MarginLayoutParams> {
@@ -1140,6 +1156,7 @@ class ConversationAdapter(
                 }
                 configureVideo(viewHolder, path)
             }
+
             MessageType.TransferType.AUDIO -> {
                 // Add margin if message need to be separated.
                 viewHolder.mAudioLayout?.updateLayoutParams<MarginLayoutParams> {
@@ -1152,17 +1169,19 @@ class ConversationAdapter(
                     viewHolder.mAudioInfoLayout?.background?.setTint(convColor)
                 } else {
                     viewHolder.mAudioInfoLayout?.background?.setTint(
-                        viewHolder.itemView.context.getColor(R.color.conversation_secondary_background)
+                        context.getColor(R.color.conversation_secondary_background)
                     )
                 }
                 configureAudio(viewHolder, path)
             }
+
             MessageType.TransferType.FILE -> {
                 // Add margin if message need to be separated.
                 viewHolder.mLayout?.updateLayoutParams<MarginLayoutParams> {
                     topMargin = if (!isMessageSeparationNeeded) 0 else context.resources
                         .getDimensionPixelSize(R.dimen.conversation_message_separation)
                 }
+
                 val status = file.status
                 viewHolder.mIcon?.setPadding(res.getDimensionPixelSize(R.dimen.padding_large))
                 viewHolder.mIcon?.setClipToOutline(true)
@@ -1184,6 +1203,7 @@ class ConversationAdapter(
                             it.setOnClickListener { presenter.acceptFile(file) }
                         }
                     }
+
                     else -> {
                         viewHolder.mFileDownloadButton?.visibility = View.GONE
                         if (status == InteractionStatus.TRANSFER_ONGOING) {
@@ -1224,8 +1244,7 @@ class ConversationAdapter(
         )
         if (presenter.isGroup()) {
             layoutParams.setMargins(
-                res.getDimensionPixelSize(R.dimen.margin_with_avatar), 0,
-                0, 0
+                res.getDimensionPixelSize(R.dimen.margin_with_avatar), 0, 0, 0
             )
         } else {
             layoutParams.setMargins(
@@ -1344,8 +1363,7 @@ class ConversationAdapter(
         // Manage the update of the timestamp
         if (isDateShown) {
             convViewHolder.compositeDisposable.add(timestampUpdateTimer.subscribe {
-                timePermanent?.text = TextUtils
-                    .timestampToDate(context, formatter, interaction.timestamp)
+                timePermanent?.text = TextUtils.timestampToDate(context, formatter, interaction.timestamp)
             })
             convViewHolder.mMsgDetailTxtPerm?.visibility = View.VISIBLE
         } else convViewHolder.mMsgDetailTxtPerm?.visibility = View.GONE
diff --git a/jami-android/app/src/main/java/cx/ring/fragments/ConversationFragment.kt b/jami-android/app/src/main/java/cx/ring/fragments/ConversationFragment.kt
index c9346f75def19df6f1d0dd6427df0618dcaeab62..4cdf4f307e892570f0b92578c508ad65b39e16e6 100644
--- a/jami-android/app/src/main/java/cx/ring/fragments/ConversationFragment.kt
+++ b/jami-android/app/src/main/java/cx/ring/fragments/ConversationFragment.kt
@@ -707,16 +707,6 @@ class ConversationFragment : BaseSupportFragment<ConversationPresenter, Conversa
         )
     }
 
-    override fun refuseFile(accountId: String, conversationUri: net.jami.model.Uri, transfer: DataTransfer) {
-        if (transfer.messageId == null && transfer.fileId == null)
-            return
-        requireActivity().startService(Intent(DRingService.ACTION_FILE_CANCEL, ConversationPath.toUri(accountId, conversationUri),
-            requireContext(), DRingService::class.java)
-            .putExtra(DRingService.KEY_MESSAGE_ID, transfer.messageId)
-            .putExtra(DRingService.KEY_TRANSFER_ID, transfer.fileId)
-        )
-    }
-
     override fun shareFile(path: File, displayName: String) {
         val c = context ?: return
         AndroidFileUtils.shareFile(c, path, displayName)
diff --git a/jami-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.kt b/jami-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.kt
index ccfdfb59a1ea6baa19f30ceae28fbdb962503aec..6be95c4552d60cdae6f5762fe55ade74623c4fef 100644
--- a/jami-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.kt
+++ b/jami-android/app/src/main/java/cx/ring/tv/conversation/TvConversationFragment.kt
@@ -716,14 +716,6 @@ class TvConversationFragment : BaseSupportFragment<ConversationPresenter, Conver
         }
     }
 
-    override fun refuseFile(accountId: String, conversationUri: net.jami.model.Uri, transfer: DataTransfer) {
-        requireActivity().startService(Intent(DRingService.ACTION_FILE_CANCEL)
-            .setClass(requireContext(), DRingService::class.java)
-            .setData(ConversationPath.toUri(accountId, conversationUri))
-            .putExtra(DRingService.KEY_MESSAGE_ID, transfer.messageId)
-            .putExtra(DRingService.KEY_TRANSFER_ID, transfer.fileId))
-    }
-
     private fun openVideoRecorder() {
         val intent = Intent(activity, CustomCameraActivity::class.java)
             .setAction(MediaStore.ACTION_VIDEO_CAPTURE)
@@ -848,7 +840,6 @@ class TvConversationFragment : BaseSupportFragment<ConversationPresenter, Conver
 
     companion object {
         private val TAG = TvConversationFragment::class.java.simpleName
-        private const val ARG_MODEL = "model"
         private const val KEY_AUDIOFILE = "audiofile"
         private const val REQUEST_CODE_PHOTO = 101
         private const val REQUEST_CODE_SAVE_FILE = 103
diff --git a/jami-android/app/src/main/java/cx/ring/views/MessageBubble.kt b/jami-android/app/src/main/java/cx/ring/views/MessageBubble.kt
index e87144ff55a3ceec82bd27c88f144599a0ef5d45..81f85e73d2490fff8ff7618d7afd37a29d80648b 100644
--- a/jami-android/app/src/main/java/cx/ring/views/MessageBubble.kt
+++ b/jami-android/app/src/main/java/cx/ring/views/MessageBubble.kt
@@ -112,10 +112,14 @@ class MessageBubble(context: Context, attrs: AttributeSet?) : ViewGroup(context,
     /**
      * Updates the view to display a standard message.
      */
-    fun updateStandard(text: Spanned, time: String, messageIsEdited: Boolean) {
+    fun updateStandard(message: Spanned, time: String, messageIsEdited: Boolean) {
         messageEdited.isVisible = messageIsEdited
-        messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize)
-        messageText.text = text
+        messageText.apply {
+            setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize)
+            setTypeface(null, Typeface.NORMAL)
+            setTextIsSelectable(true)
+            text = message
+        }
         messageTime.text = time
         updateTextColor(defaultTextColor)
     }
@@ -129,6 +133,7 @@ class MessageBubble(context: Context, attrs: AttributeSet?) : ViewGroup(context,
         messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize)
         messageText.setTypeface(null, Typeface.ITALIC)
         messageText.text = String.format(context.getString(R.string.conversation_message_deleted), username)
+        messageText.setTextIsSelectable(false)
 
         background.setTint(context.getColor(R.color.conversation_secondary_background))
         updateTextColor(context.getColor(R.color.msg_display_name))
@@ -140,7 +145,9 @@ class MessageBubble(context: Context, attrs: AttributeSet?) : ViewGroup(context,
     fun updateEmoji(text: String, time: String, messageIsEdited: Boolean) {
         messageEdited.isVisible = messageIsEdited
         messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, emojiOnlyTextSize)
+        messageText.setTypeface(null, Typeface.NORMAL)
         messageText.text = text
+        messageText.setTextIsSelectable(true)
         messageTime.text = time
         // Emoji is not in the bubble, so should be contrasted with conversation background.
         updateTextColor(contrastedDefaultTextColor)
diff --git a/jami-android/app/src/main/res/layout/item_conv_file_me.xml b/jami-android/app/src/main/res/layout/item_conv_file_me.xml
index 1dc04b1d06cc0b3ba6c66795d442d318c4b1a3a2..e275ff3c969123c5c0fe788ac996f2546b346549 100644
--- a/jami-android/app/src/main/res/layout/item_conv_file_me.xml
+++ b/jami-android/app/src/main/res/layout/item_conv_file_me.xml
@@ -57,6 +57,20 @@
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toBottomOf="@id/message_time_permanent">
 
+        <ImageButton
+            android:id="@+id/file_download_button"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:background="?selectableItemBackgroundBorderless"
+            android:contentDescription="@string/file_download_button"
+            app:layout_constraintBottom_toBottomOf="@id/fileInfoLayout"
+            app:layout_constraintEnd_toStartOf="@+id/fileInfoLayout"
+            app:layout_constraintHorizontal_bias="1.0"
+            app:layout_constraintHorizontal_chainStyle="packed"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="@id/fileInfoLayout"
+            app:srcCompat="@drawable/download_24px" />
+
         <androidx.constraintlayout.widget.ConstraintLayout
             android:id="@+id/fileInfoLayout"
             android:layout_width="wrap_content"
@@ -67,7 +81,7 @@
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintHorizontal_bias="1"
             app:layout_constraintHorizontal_chainStyle="packed"
-            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintStart_toStartOf="@id/file_download_button"
             app:layout_constraintTop_toTopOf="parent">
 
             <ImageView
diff --git a/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationPresenter.kt b/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationPresenter.kt
index c4e8064725cad6d1e081f1ce15b63078474a69ff..7ec6767810f3634fd29220c056b09f75c8581f13 100644
--- a/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationPresenter.kt
+++ b/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationPresenter.kt
@@ -72,17 +72,14 @@ class ConversationPresenter @Inject constructor(
                         }
                     else
                         Observable.just(conversation)
-                }.switchMapSingle { conversation ->
-                    conversationFacade.loadConversationHistory(conversation)
-                        .map { Pair(account, it) }
+                }.switchMapSingle { conv ->
+                    conversationFacade.loadConversationHistory(conv).map { Pair(account, it) }
                 }
             }
             .observeOn(uiScheduler)
-            .subscribe(
-                { (account, conversation) ->
-                    setConversation(account, conversation)
-                }
-            ) { error: Throwable ->
+            .subscribe({ (account, conversation) ->
+                setConversation(account, conversation)
+            }) { error: Throwable ->
                 view?.goToHome()
                 Log.e(TAG, "Error loading conversation", error)
             }
@@ -304,14 +301,15 @@ class ConversationPresenter @Inject constructor(
         view?.goToGroupCall(mConversation!!, mConversation!!.uri, media)
     }
 
-    fun refuseFile(transfer: DataTransfer) {
-        view?.refuseFile(mConversation!!.accountId, mConversationUri!!, transfer)
-    }
-
     fun deleteConversationItem(element: Interaction) {
         conversationFacade.deleteConversationItem(mConversation!!, element)
     }
 
+    fun deleteConversationFile(element: Interaction) {
+        if (element is DataTransfer)
+            conversationFacade.deleteConversationFile(mConversation!!, element)
+    }
+
     fun startReplyTo(interaction: Interaction) {
         view?.startReplyTo(interaction)
     }
diff --git a/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationView.kt b/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationView.kt
index a1a77d955113fa614a6bb22368dc19e2cc7ca4ca..fe6379545fe27726febdfe4caa9e72068ba4c4ba 100644
--- a/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationView.kt
+++ b/jami-android/libjamiclient/src/main/kotlin/net/jami/conversation/ConversationView.kt
@@ -42,13 +42,11 @@ interface ConversationView {
     fun switchToIncomingTrustRequestView(name: String)
     fun switchToConversationView()
     fun switchToBannedView()
-
     fun switchToSyncingView()
     fun switchToEndedView()
     fun openFilePicker()
     fun acceptFile(accountId: String, conversationUri: Uri, transfer: DataTransfer)
     fun goToGroupCall(conversation: Conversation, contactUri: net.jami.model.Uri, hasVideo: Boolean)
-    fun refuseFile(accountId: String, conversationUri: Uri, transfer: DataTransfer)
     fun shareFile(path: File, displayName: String)
     fun openFile(path: File, displayName: String)
     fun addElement(element: Interaction)
diff --git a/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Conversation.kt b/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Conversation.kt
index 5ed603cc8823bdd29c423d86fcb06bb463b5dde8..a934f7062b5863f73ae81bc629d7653944940e4d 100644
--- a/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Conversation.kt
+++ b/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Conversation.kt
@@ -435,9 +435,9 @@ class Conversation : ConversationHistory {
         }
     }
 
-
     val currentCall: Conference?
         get() = if (currentCalls.isEmpty()) null else currentCalls[0]
+
     private val callHistory: Collection<Call>
         get() {
             val result: MutableList<Call> = ArrayList()
@@ -448,6 +448,7 @@ class Conversation : ConversationHistory {
             }
             return result
         }
+
     val unreadTextMessages: TreeMap<Long, TextMessage>
         get() {
             val texts = TreeMap<Long, TextMessage>()
@@ -638,7 +639,7 @@ class Conversation : ConversationHistory {
     }
 
     fun updateFileTransfer(transfer: DataTransfer, eventCode: Interaction.InteractionStatus) {
-        val dataTransfer = (if (isSwarm) transfer else findConversationElement(transfer.id)) as DataTransfer?
+        val dataTransfer = (if (isSwarm) transfer else findConversationElement(transfer.id)) as? DataTransfer
         if (dataTransfer != null) {
             dataTransfer.status = eventCode
             updatedElementSubject.onNext(Pair(dataTransfer, ElementStatus.UPDATE))
diff --git a/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Interaction.kt b/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Interaction.kt
index 6044e27eb9db0b9b7da2b386e9454991942276ed..74e597162e2b6d267124f33ed2372f6fb7b812c1 100644
--- a/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Interaction.kt
+++ b/jami-android/libjamiclient/src/main/kotlin/net/jami/model/Interaction.kt
@@ -248,10 +248,10 @@ open class Interaction {
             get() = isError || this == TRANSFER_FINISHED
 
         companion object {
-            fun fromString(str: String): InteractionStatus = values().firstOrNull { it.name == str } ?: INVALID
+            fun fromString(str: String): InteractionStatus = entries.firstOrNull { it.name == str } ?: INVALID
 
             fun fromIntTextMessage(n: Int): InteractionStatus = try {
-                values()[n]
+                entries[n]
             } catch (e: ArrayIndexOutOfBoundsException) {
                 INVALID
             }
diff --git a/jami-android/libjamiclient/src/main/kotlin/net/jami/services/ConversationFacade.kt b/jami-android/libjamiclient/src/main/kotlin/net/jami/services/ConversationFacade.kt
index 52140761bb2400b4a758095696e608b4e5602988..6d8fe1ae959eab661ed4030dfa053495730976b0 100644
--- a/jami-android/libjamiclient/src/main/kotlin/net/jami/services/ConversationFacade.kt
+++ b/jami-android/libjamiclient/src/main/kotlin/net/jami/services/ConversationFacade.kt
@@ -158,42 +158,52 @@ class ConversationFacade(
         return Completable.complete()
     }
 
+    fun deleteConversationFile(conversation: Conversation, transfer: DataTransfer) {
+        if (transfer.status === InteractionStatus.TRANSFER_ONGOING) {
+            mAccountService.cancelDataTransfer(
+                conversation.accountId, conversation.uri.rawRingId, transfer.messageId, transfer.fileId!!
+            )
+        } else {
+            val file = mDeviceRuntimeService.getConversationPath(conversation.accountId, conversation.uri.rawRingId, transfer.storagePath)
+            if (conversation.isSwarm) {
+                mDisposableBag.add(Completable.fromAction {
+                    file.delete()
+                    transfer.bytesProgress = 0
+                }.subscribeOn(Schedulers.io())
+                .subscribe({
+                    transfer.status = InteractionStatus.FILE_AVAILABLE
+                    conversation.updateInteraction(transfer)
+                }) { e: Throwable -> Log.e(TAG, "Can't delete file", e) })
+            }
+//            else {
+//                // Remove item from conversation list
+//                mDisposableBag.add(Completable.mergeArrayDelayError(
+//                        mHistoryService.deleteInteraction(transfer.id, transfer.account!!),
+//                        Completable.fromAction { file.delete() }
+//                                .subscribeOn(Schedulers.io()))
+//                        .subscribe({ conversation.removeInteraction(transfer) }) { e: Throwable ->
+//                            Log.e(TAG, "Can't delete file transfer", e)
+//                        })
+//            }
+        }
+    }
+
     fun deleteConversationItem(conversation: Conversation, element: Interaction) {
         if (element.type === Interaction.InteractionType.DATA_TRANSFER) {
-            val transfer = element as DataTransfer
-            if (transfer.status === InteractionStatus.TRANSFER_ONGOING) {
-                mAccountService.cancelDataTransfer(conversation.accountId, conversation.uri.rawRingId, transfer.messageId, transfer.fileId!!)
-            } else {
-                val file = mDeviceRuntimeService.getConversationPath(conversation.accountId, conversation.uri.rawRingId, transfer.storagePath)
-                if (conversation.isSwarm) {
-                    mDisposableBag.add(Completable.fromAction {
-                        file.delete()
-                        transfer.bytesProgress = 0
-                    }
-                        .subscribeOn(Schedulers.io())
-                        .subscribe({
-                            transfer.status = InteractionStatus.FILE_AVAILABLE
-                            conversation.updateInteraction(transfer)
-                        })
-                        { e: Throwable -> Log.e(TAG, "Can't delete file transfer", e) })
-                } else {
-                    mDisposableBag.add(Completable.mergeArrayDelayError(
-                        mHistoryService.deleteInteraction(element.id, element.account!!),
-                        Completable.fromAction { file.delete() }
-                            .subscribeOn(Schedulers.io()))
-                        .subscribe({ conversation.removeInteraction(transfer) })
-                        { e: Throwable -> Log.e(TAG, "Can't delete file transfer", e) })
-                }
-            }
+            deleteConversationFile(conversation, element as DataTransfer)
         } else {
             // handling is the same for calls and texts
             if (conversation.isSwarm) {
+                if ((element as? DataTransfer)?.status === InteractionStatus.TRANSFER_ONGOING) {
+                    mAccountService.cancelDataTransfer(conversation.accountId, conversation.uri.rawRingId, element.messageId, element.fileId!!)
+                }
                 mAccountService.deleteConversationMessage(conversation.accountId, conversation.uri, element.messageId!!)
             } else {
                 mDisposableBag.add(mHistoryService.deleteInteraction(element.id, element.account!!)
                     .subscribeOn(Schedulers.io())
-                    .subscribe({ conversation.removeInteraction(element) })
-                    { e: Throwable -> Log.e(TAG, "Can't delete message", e) })
+                    .subscribe({ conversation.removeInteraction(element) }) { e: Throwable ->
+                        Log.e(TAG, "Can't delete message", e)
+                    })
             }
         }
     }
@@ -616,8 +626,7 @@ class ConversationFacade(
         if (incomingCall) {
             mNotificationService.handleCallNotification(conference!!, false)
             mHardwareService.setPreviewSettings()
-        } else if (newState === CallStatus.CURRENT
-            || newState === CallStatus.RINGING && !call.isIncoming) {
+        } else if (newState === CallStatus.CURRENT || newState === CallStatus.RINGING && !call.isIncoming) {
             mNotificationService.handleCallNotification(conference!!, false)
         } else if (newState.isOver) {
             if (conference != null)
@@ -711,8 +720,9 @@ class ConversationFacade(
     }
 
     init {
-        mDisposableBag.add(mCallService.callsUpdates
-            .subscribe { call: Call -> onCallStateChange(call) })
+        mDisposableBag.add(mCallService.callsUpdates.subscribe { call: Call ->
+            onCallStateChange(call)
+        })
 
         /*mDisposableBag.add(mCallService.getConnectionUpdates()
                     .subscribe(mNotificationService::onConnectionUpdate));*/
@@ -728,27 +738,28 @@ class ConversationFacade(
                     mNotificationService.showIncomingTrustRequestNotification(account)
                 })
 
-        mDisposableBag.add(mAccountService
-            .incomingMessages
+        mDisposableBag.add(mAccountService.incomingMessages
             .concatMapSingle { msg: TextMessage -> getAccountSubject(msg.account!!)
                     .map { a: Account -> a.addTextMessage(msg)
                         msg }
             }
             .subscribe({ txt: TextMessage -> parseNewMessage(txt) })
                 { e: Throwable -> Log.e(TAG, "Error adding text message", e) })
+
         mDisposableBag.add(mAccountService.incomingSwarmMessages
                 .subscribe({ txt: TextMessage -> parseNewMessage(txt) },
                     { e: Throwable -> Log.e(TAG, "Error adding text message", e) }))
+
         mDisposableBag.add(mAccountService.locationUpdates
             .concatMapSingle { location: AccountService.Location ->
-                getAccountSubject(location.account)
-                    .map { a: Account ->
-                        val expiration = a.onLocationUpdate(location)
-                        mDisposableBag.add(Completable.timer(expiration, TimeUnit.MILLISECONDS)
-                                .subscribe { a.maintainLocation() })
-                        location
-                    } }
-            .subscribe())
+                getAccountSubject(location.account).map { a: Account ->
+                    val expiration = a.onLocationUpdate(location)
+                    mDisposableBag.add(Completable.timer(expiration, TimeUnit.MILLISECONDS)
+                            .subscribe { a.maintainLocation() })
+                    location
+                }
+            }.subscribe())
+
         mDisposableBag.add(mAccountService.observableAccountList
             .switchMap { accounts -> Observable.merge(accounts.map { a -> a.locationUpdates.map { Pair(a, it) } }) }
             .distinctUntilChanged()
@@ -757,9 +768,10 @@ class ConversationFacade(
                 mNotificationService.showLocationNotification(t.first, t.second.contact, t.second.conversation)
                 mDisposableBag.add(t.second.location.doOnComplete {
                     mNotificationService.cancelLocationNotification(t.first, t.second.contact)
-                }.subscribe()) })
-        mDisposableBag.add(mAccountService
-            .messageStateChanges
+                }.subscribe())
+            })
+
+        mDisposableBag.add(mAccountService.messageStateChanges
             .concatMapMaybe { e: Interaction ->
                 getAccountSubject(e.account!!)
                     .flatMapMaybe { a: Account -> Maybe.fromCallable {
@@ -772,11 +784,14 @@ class ConversationFacade(
                     .doOnSuccess { conversation -> conversation.updateInteraction(e) }
             }
             .subscribe({}) { e: Throwable -> Log.e(TAG, "Error updating text message", e) })
+
         mDisposableBag.add(mAccountService.dataTransfers
                 .subscribe({ transfer: DataTransfer -> handleDataTransferEvent(transfer) },
                      { e: Throwable -> Log.e(TAG, "Error adding data transfer", e) }))
+
         mDisposableBag.add(mAccountService.incomingGroupCall
             .subscribe({ c -> mNotificationService.showGroupCallNotification(c) },
                 { e: Throwable -> Log.e(TAG, "Error showing group call notification", e) }))
     }
-}
+
+}
\ No newline at end of file