Merge pull request #3284 from Smarshal21/Share

Implemented media/photo share functionality
This commit is contained in:
Marcel Hibbe 2023-09-05 13:56:20 +02:00 committed by GitHub
commit f172fcc006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 23 deletions

View File

@ -138,6 +138,7 @@ abstract class PreviewMessageViewHolder(itemView: View?, payload: Any?) :
message.selectedIndividualHashMap!![KEY_NAME]!!, message.selectedIndividualHashMap!![KEY_NAME]!!,
message.selectedIndividualHashMap!![KEY_ID]!!, message.selectedIndividualHashMap!![KEY_ID]!!,
message.selectedIndividualHashMap!![KEY_MIMETYPE], message.selectedIndividualHashMap!![KEY_MIMETYPE],
message.openWhenDownloaded,
ProgressUi(progressBar, messageText, image) ProgressUi(progressBar, messageText, image)
) )
} else if (message.getCalculateMessageType() === ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) { } else if (message.getCalculateMessageType() === ChatMessage.MessageType.SINGLE_LINK_GIPHY_MESSAGE) {

View File

@ -191,7 +191,7 @@ import com.nextcloud.talk.ui.dialog.ShowReactionsDialog
import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions import com.nextcloud.talk.ui.recyclerview.MessageSwipeActions
import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.AudioUtils import com.nextcloud.talk.utils.AudioUtils.audioFileToFloatArray
import com.nextcloud.talk.utils.ContactUtils import com.nextcloud.talk.utils.ContactUtils
import com.nextcloud.talk.utils.ConversationUtils import com.nextcloud.talk.utils.ConversationUtils
import com.nextcloud.talk.utils.DateConstants import com.nextcloud.talk.utils.DateConstants
@ -201,6 +201,7 @@ import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.FileViewerUtils import com.nextcloud.talk.utils.FileViewerUtils
import com.nextcloud.talk.utils.ImageEmojiEditText import com.nextcloud.talk.utils.ImageEmojiEditText
import com.nextcloud.talk.utils.MagicCharPolicy import com.nextcloud.talk.utils.MagicCharPolicy
import com.nextcloud.talk.utils.Mimetype
import com.nextcloud.talk.utils.NotificationUtils import com.nextcloud.talk.utils.NotificationUtils
import com.nextcloud.talk.utils.ParticipantPermissions import com.nextcloud.talk.utils.ParticipantPermissions
import com.nextcloud.talk.utils.VibrationUtils import com.nextcloud.talk.utils.VibrationUtils
@ -316,6 +317,7 @@ class ChatActivity :
var voiceOnly: Boolean = true var voiceOnly: Boolean = true
var isFirstMessagesProcessing = true var isFirstMessagesProcessing = true
private var emojiPopup: EmojiPopup? = null private var emojiPopup: EmojiPopup? = null
private lateinit var path: String
var myFirstMessage: CharSequence? = null var myFirstMessage: CharSequence? = null
var checkingLobbyStatus: Boolean = false var checkingLobbyStatus: Boolean = false
@ -887,7 +889,9 @@ class ChatActivity :
} }
} else { } else {
Log.d(TAG, "Downloaded to cache") Log.d(TAG, "Downloaded to cache")
downloadFileToCache(message) downloadFileToCache(message, true) {
setUpWaveform(message)
}
} }
} }
} }
@ -899,7 +903,7 @@ class ChatActivity :
message.isDownloadingVoiceMessage = true message.isDownloadingVoiceMessage = true
adapter?.update(message) adapter?.update(message)
CoroutineScope(Dispatchers.Default).launch { CoroutineScope(Dispatchers.Default).launch {
val r = AudioUtils.audioFileToFloatArray(file) val r = audioFileToFloatArray(file)
message.voiceMessageFloatArray = r message.voiceMessageFloatArray = r
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
startPlayback(message) startPlayback(message)
@ -1933,8 +1937,13 @@ class ChatActivity :
} }
@SuppressLint("LongLogTag") @SuppressLint("LongLogTag")
private fun downloadFileToCache(message: ChatMessage) { private fun downloadFileToCache(
message: ChatMessage,
openWhenDownloaded: Boolean,
funToCallWhenDownloadSuccessful: (() -> Unit)
) {
message.isDownloadingVoiceMessage = true message.isDownloadingVoiceMessage = true
message.openWhenDownloaded = openWhenDownloaded
adapter?.update(message) adapter?.update(message)
val baseUrl = message.activeUser!!.baseUrl val baseUrl = message.activeUser!!.baseUrl
@ -1985,8 +1994,7 @@ class ChatActivity :
WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.id) WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.id)
.observeForever { workInfo: WorkInfo -> .observeForever { workInfo: WorkInfo ->
if (workInfo.state == WorkInfo.State.SUCCEEDED) { if (workInfo.state == WorkInfo.State.SUCCEEDED) {
setUpWaveform(message) funToCallWhenDownloadSuccessful()
// startPlayback(message)
} }
} }
} }
@ -3997,6 +4005,37 @@ class ChatActivity :
startActivity(intent) startActivity(intent)
} }
fun share(message: ChatMessage) {
val filename = message.selectedIndividualHashMap!!["name"]
path = applicationContext.cacheDir.absolutePath + "/" + filename
val shareUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID,
File(path)
)
val shareIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
type = Mimetype.IMAGE_PREFIX_GENERIC
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
}
fun checkIfSharable(message: ChatMessage) {
val filename = message.selectedIndividualHashMap!!["name"]
path = applicationContext.cacheDir.absolutePath + "/" + filename
val file = File(context.cacheDir, filename!!)
if (file.exists()) {
share(message)
} else {
downloadFileToCache(message, false) {
share(message)
}
}
}
fun openInFilesApp(message: ChatMessage) { fun openInFilesApp(message: ChatMessage) {
val keyID = message.selectedIndividualHashMap!![PreviewMessageViewHolder.KEY_ID] val keyID = message.selectedIndividualHashMap!![PreviewMessageViewHolder.KEY_ID]
val link = message.selectedIndividualHashMap!!["link"] val link = message.selectedIndividualHashMap!!["link"]

View File

@ -145,7 +145,9 @@ data class ChatMessage(
var expandableChildrenAmount: Int = 0, var expandableChildrenAmount: Int = 0,
var hiddenByCollapse: Boolean = false var hiddenByCollapse: Boolean = false,
var openWhenDownloaded: Boolean = true
) : Parcelable, MessageContentType, MessageContentType.Image { ) : Parcelable, MessageContentType, MessageContentType.Image {

View File

@ -83,7 +83,8 @@ abstract class SharedItemsViewHolder(
progressBar, progressBar,
null, null,
image image
) ),
true
) )
} }
@ -91,7 +92,8 @@ abstract class SharedItemsViewHolder(
item.name, item.name,
item.id, item.id,
item.mimeType, item.mimeType,
FileViewerUtils.ProgressUi(progressBar, null, image) true,
FileViewerUtils.ProgressUi(progressBar, null, image),
) )
} }

View File

@ -114,6 +114,7 @@ class MessageActionsDialog(
message.previousMessageId > NO_PREVIOUS_MESSAGE_ID && message.previousMessageId > NO_PREVIOUS_MESSAGE_ID &&
ChatMessage.MessageType.SYSTEM_MESSAGE != message.getCalculateMessageType() ChatMessage.MessageType.SYSTEM_MESSAGE != message.getCalculateMessageType()
) )
initMenuShare(ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == message.getCalculateMessageType())
initMenuItemOpenNcApp( initMenuItemOpenNcApp(
ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == message.getCalculateMessageType() ChatMessage.MessageType.SINGLE_NC_ATTACHMENT_MESSAGE == message.getCalculateMessageType()
) )
@ -330,6 +331,15 @@ class MessageActionsDialog(
dialogMessageActionsBinding.menuTranslateMessage.visibility = getVisibility(visible) dialogMessageActionsBinding.menuTranslateMessage.visibility = getVisibility(visible)
} }
private fun initMenuShare(visible: Boolean) {
if (visible) {
dialogMessageActionsBinding.menuShare.setOnClickListener {
chatActivity.checkIfSharable(message)
dismiss()
}
}
dialogMessageActionsBinding.menuShare.visibility = getVisibility(visible)
}
private fun initMenuItemOpenNcApp(visible: Boolean) { private fun initMenuItemOpenNcApp(visible: Boolean) {
if (visible) { if (visible) {

View File

@ -95,7 +95,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
path, path,
link, link,
mimetype, mimetype,
progressUi progressUi,
message.openWhenDownloaded
) )
} }
@ -104,14 +105,16 @@ class FileViewerUtils(private val context: Context, private val user: User) {
path: String, path: String,
link: String?, link: String?,
mimetype: String?, mimetype: String?,
progressUi: ProgressUi progressUi: ProgressUi,
openWhenDownloaded: Boolean
) { ) {
if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileInfo.fileName)) { if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileInfo.fileName)) {
openOrDownloadFile( openOrDownloadFile(
fileInfo, fileInfo,
path, path,
mimetype, mimetype,
progressUi progressUi,
openWhenDownloaded
) )
} else if (!link.isNullOrEmpty()) { } else if (!link.isNullOrEmpty()) {
openFileInFilesApp(link, fileInfo.fileId) openFileInFilesApp(link, fileInfo.fileId)
@ -138,7 +141,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileInfo: FileInfo, fileInfo: FileInfo,
path: String, path: String,
mimetype: String?, mimetype: String?,
progressUi: ProgressUi progressUi: ProgressUi,
openWhenDownloaded: Boolean
) { ) {
val file = File(context.cacheDir, fileInfo.fileName) val file = File(context.cacheDir, fileInfo.fileName)
if (file.exists()) { if (file.exists()) {
@ -148,7 +152,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileInfo, fileInfo,
path, path,
mimetype, mimetype,
progressUi progressUi,
openWhenDownloaded
) )
} }
} }
@ -276,7 +281,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileInfo: FileInfo, fileInfo: FileInfo,
path: String, path: String,
mimetype: String?, mimetype: String?,
progressUi: ProgressUi progressUi: ProgressUi,
openWhenDownloaded: Boolean
) { ) {
// check if download worker is already running // check if download worker is already running
val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileInfo.fileId!!) val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileInfo.fileId!!)
@ -324,7 +330,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileInfo.fileName, fileInfo.fileName,
mimetype, mimetype,
workInfo!!, workInfo!!,
progressUi progressUi,
openWhenDownloaded
) )
} }
} }
@ -333,7 +340,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileName: String, fileName: String,
mimetype: String?, mimetype: String?,
workInfo: WorkInfo, workInfo: WorkInfo,
progressUi: ProgressUi progressUi: ProgressUi,
openWhenDownloaded: Boolean
) { ) {
when (workInfo.state) { when (workInfo.state) {
WorkInfo.State.RUNNING -> { WorkInfo.State.RUNNING -> {
@ -347,13 +355,12 @@ class FileViewerUtils(private val context: Context, private val user: User) {
} }
} }
WorkInfo.State.SUCCEEDED -> { WorkInfo.State.SUCCEEDED -> {
if (progressUi.previewImage.isShown) { if (progressUi.previewImage.isShown && openWhenDownloaded) {
openFileByMimetype(fileName, mimetype) openFileByMimetype(fileName, mimetype)
} else { } else {
Log.d( Log.d(TAG, "file " + fileName +
TAG, " was downloaded but it's not opened because view is not shown on screen or " +
"file " + fileName + "openWhenDownloaded is false"
" was downloaded but it's not opened because view is not shown on screen"
) )
} }
progressUi.messageText?.text = fileName progressUi.messageText?.text = fileName
@ -372,6 +379,7 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileName: String, fileName: String,
fileId: String, fileId: String,
mimeType: String?, mimeType: String?,
openWhenDownloaded: Boolean,
progressUi: ProgressUi progressUi: ProgressUi
) { ) {
val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId) val workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId)
@ -390,7 +398,8 @@ class FileViewerUtils(private val context: Context, private val user: User) {
fileName, fileName,
mimeType, mimeType,
info!!, info!!,
progressUi progressUi,
openWhenDownloaded
) )
} }
} }

View File

@ -353,6 +353,39 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/menu_share"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_item_height"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/menu_icon_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@null"
android:paddingStart="@dimen/standard_padding"
android:paddingEnd="@dimen/zero"
android:src="@drawable/ic_share_action"
app:tint="@color/high_emphasis_menu_icon" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/menu_text_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:paddingStart="@dimen/standard_double_padding"
android:paddingEnd="@dimen/standard_padding"
android:text="@string/share"
android:textAlignment="viewStart"
android:textColor="@color/high_emphasis_text"
android:textSize="@dimen/bottom_sheet_text_size" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/menu_open_in_nc_app" android:id="@+id/menu_open_in_nc_app"
android:layout_width="match_parent" android:layout_width="match_parent"