Commit de94ddbf authored by Lucio Maciel's avatar Lucio Maciel

Use a temporary file for uploading.

parent c8efc00b
...@@ -5,8 +5,12 @@ import android.net.Uri ...@@ -5,8 +5,12 @@ import android.net.Uri
import chat.rocket.android.util.extensions.getFileName import chat.rocket.android.util.extensions.getFileName
import chat.rocket.android.util.extensions.getMimeType import chat.rocket.android.util.extensions.getMimeType
import chat.rocket.android.util.extensions.getRealPathFromURI import chat.rocket.android.util.extensions.getRealPathFromURI
import okio.Okio
import java.io.File
import javax.inject.Inject import javax.inject.Inject
class UriInteractor @Inject constructor(private val context: Context) { class UriInteractor @Inject constructor(private val context: Context) {
/** /**
...@@ -23,4 +27,27 @@ class UriInteractor @Inject constructor(private val context: Context) { ...@@ -23,4 +27,27 @@ class UriInteractor @Inject constructor(private val context: Context) {
* Gets the real path of an [Uri] * Gets the real path of an [Uri]
*/ */
fun getRealPath(uri: Uri): String? = uri.getRealPathFromURI(context) fun getRealPath(uri: Uri): String? = uri.getRealPathFromURI(context)
/**
* Save the contents of an [Uri] to a temp file named after uri.getFileName()
*/
fun tempFile(uri: Uri): File? {
try {
val outputDir = context.cacheDir // context being the Activity pointer
val outputFile = File(outputDir, uri.getFileName(context))
val from = context.contentResolver.openInputStream(uri)
Okio.source(from).use { a ->
Okio.buffer(Okio.sink(outputFile)).use{ b ->
b.writeAll(a)
b.close()
}
a.close()
}
return outputFile
} catch (ex: Exception) {
ex.printStackTrace()
return null
}
}
} }
\ No newline at end of file
...@@ -7,9 +7,6 @@ import chat.rocket.android.chatroom.viewmodel.MessageViewModelMapper ...@@ -7,9 +7,6 @@ import chat.rocket.android.chatroom.viewmodel.MessageViewModelMapper
import chat.rocket.android.core.lifecycle.CancelStrategy import chat.rocket.android.core.lifecycle.CancelStrategy
import chat.rocket.android.server.domain.* import chat.rocket.android.server.domain.*
import chat.rocket.android.server.infraestructure.RocketChatClientFactory import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extensions.getFileName
import chat.rocket.android.util.extensions.getMimeType
import chat.rocket.android.util.extensions.getRealPathFromURI
import chat.rocket.android.util.extensions.launchUI import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
...@@ -19,17 +16,11 @@ import chat.rocket.core.internal.realtime.State ...@@ -19,17 +16,11 @@ import chat.rocket.core.internal.realtime.State
import chat.rocket.core.internal.realtime.connect import chat.rocket.core.internal.realtime.connect
import chat.rocket.core.internal.realtime.subscribeRoomMessages import chat.rocket.core.internal.realtime.subscribeRoomMessages
import chat.rocket.core.internal.realtime.unsubscibre import chat.rocket.core.internal.realtime.unsubscibre
import chat.rocket.core.internal.rest.messages import chat.rocket.core.internal.rest.*
import chat.rocket.core.internal.rest.sendMessage
import chat.rocket.core.internal.rest.updateMessage
import chat.rocket.core.internal.rest.uploadFile
import chat.rocket.core.internal.rest.pinMessage
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.unpinMessage
import chat.rocket.core.internal.rest.deleteMessage
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.Value import chat.rocket.core.model.Value
import kotlinx.coroutines.experimental.CommonPool import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.channels.Channel import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import timber.log.Timber import timber.log.Timber
...@@ -83,11 +74,10 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -83,11 +74,10 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
launchUI(strategy) { launchUI(strategy) {
view.disableMessageInput() view.disableMessageInput()
try { try {
val message: Message val message = if (messageId == null) {
if (messageId == null) { client.sendMessage(chatRoomId, text)
message = client.sendMessage(chatRoomId, text)
} else { } else {
message = client.updateMessage(chatRoomId, messageId, text) client.updateMessage(chatRoomId, messageId, text)
} }
// ignore message for now, will receive it on the stream // ignore message for now, will receive it on the stream
view.enableMessageInput(clear = true) view.enableMessageInput(clear = true)
...@@ -106,23 +96,39 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -106,23 +96,39 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
fun uploadFile(roomId: String, uri: Uri, msg: String) { fun uploadFile(roomId: String, uri: Uri, msg: String) {
launchUI(strategy) { launchUI(strategy) {
view.showLoading() view.showLoading()
var tempFile: File? = null
try { try {
val fileName = uriInteractor.getFileName(uri) val fileName = async { uriInteractor.getFileName(uri) }.await()
val mimeType = uriInteractor.getMimeType(uri) val mimeType = async { uriInteractor.getMimeType(uri) }.await()
val fileRealPath = uriInteractor.getRealPath(uri) /* FIXME - this is a workaround for uploading files with the SDK
*
* https://developer.android.com/guide/topics/providers/document-provider.html
*
* We need to use contentResolver.openInputStream(uri) to open this file.
* Since the SDK is not Android specific we cannot pass the Uri and let the
* SDK handle the file.
*
* As a temporary workaround we are saving the contents to a temp file.
*
* A proper solution is to implement some interface to open the InputStream
* and use a RequestBody based on https://github.com/square/okhttp/issues/3585
*/
tempFile = async { uriInteractor.tempFile(uri) }.await()
if (fileName == null || fileRealPath == null) { if (fileName == null || tempFile == null) {
view.showInvalidFileMessage() view.showInvalidFileMessage()
} else { } else {
client.uploadFile(roomId, File(fileRealPath), mimeType, msg, fileName) client.uploadFile(roomId, tempFile, mimeType, msg, fileName)
} }
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
Timber.d(ex)
ex.message?.let { ex.message?.let {
view.showMessage(it) view.showMessage(it)
}.ifNull { }.ifNull {
view.showGenericErrorMessage() view.showGenericErrorMessage()
} }
} finally { } finally {
tempFile?.delete()
view.hideLoading() view.hideLoading()
} }
} }
......
...@@ -13,9 +13,9 @@ import chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter ...@@ -13,9 +13,9 @@ import chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter
import chat.rocket.android.chatroom.viewmodel.AttachmentType import chat.rocket.android.chatroom.viewmodel.AttachmentType
import chat.rocket.android.chatroom.viewmodel.MessageViewModel import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.player.PlayerActivity import chat.rocket.android.player.PlayerActivity
import chat.rocket.android.util.extensions.content
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.content
import com.facebook.drawee.view.SimpleDraweeView import com.facebook.drawee.view.SimpleDraweeView
import com.stfalcon.frescoimageviewer.ImageViewer import com.stfalcon.frescoimageviewer.ImageViewer
import kotlinx.android.synthetic.main.avatar.view.* import kotlinx.android.synthetic.main.avatar.view.*
......
package chat.rocket.android.chatroom.ui package chat.rocket.android.chatroom.ui
import android.app.Activity import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
...@@ -18,12 +18,8 @@ import chat.rocket.android.chatroom.presentation.ChatRoomPresenter ...@@ -18,12 +18,8 @@ import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import chat.rocket.android.chatroom.presentation.ChatRoomView import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.viewmodel.MessageViewModel import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.util.extensions.*
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.*
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_chat_room.* import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_attachment_options.*
...@@ -66,7 +62,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView { ...@@ -66,7 +62,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
private val max by lazy { Math.max(layout_message_attachment_options.width.toDouble(), layout_message_attachment_options.height.toDouble()).toFloat() } private val max by lazy { Math.max(layout_message_attachment_options.width.toDouble(), layout_message_attachment_options.height.toDouble()).toFloat() }
private val centerX by lazy { recycler_view.right } private val centerX by lazy { recycler_view.right }
private val centerY by lazy { recycler_view.bottom } private val centerY by lazy { recycler_view.bottom }
private lateinit var handler: Handler val handler = Handler()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -89,7 +85,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView { ...@@ -89,7 +85,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
presenter.loadMessages(chatRoomId, chatRoomType) presenter.loadMessages(chatRoomId, chatRoomType)
handler = Handler()
setupComposer() setupComposer()
setupActionSnackbar() setupActionSnackbar()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment