extract logic for downloading and opening files to helper class

this is done because in a next step this logic should also be used by the SharedItemsAdapter

extracting is not yet done in a clean way. in a next step some better architecture patterns must be used to separate layers

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2022-04-26 14:18:40 +02:00 committed by Tim Krüger
parent cf91e2390e
commit 3a5a3cebfb
No known key found for this signature in database
GPG Key ID: FECE3A7222C52A4E
3 changed files with 354 additions and 317 deletions

View File

@ -1,6 +1,7 @@
package com.nextcloud.talk.adapters
import android.net.Uri
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -9,11 +10,16 @@ import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.interfaces.DraweeController
import com.facebook.imagepipeline.common.RotationOptions
import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.nextcloud.talk.activities.SharedItemsActivity
import com.nextcloud.talk.databinding.AttachmentItemBinding
import com.nextcloud.talk.repositories.SharedItem
class SharedItemsAdapter : RecyclerView.Adapter<SharedItemsAdapter.ViewHolder>() {
companion object {
private val TAG = SharedItemsAdapter::class.simpleName
}
class ViewHolder(val binding: AttachmentItemBinding, itemView: View) : RecyclerView.ViewHolder(itemView)
var authHeader: Map<String, String> = emptyMap()
@ -42,6 +48,10 @@ class SharedItemsAdapter : RecyclerView.Adapter<SharedItemsAdapter.ViewHolder>()
.setImageRequest(imageRequest)
.build()
holder.binding.image.controller = draweeController
holder.binding.image.setOnClickListener {
Log.d(TAG, "clicked " + currentItem.name)
}
}
}

View File

@ -27,13 +27,11 @@
package com.nextcloud.talk.adapters.messages;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.util.Base64;
import android.util.Log;
@ -45,27 +43,20 @@ import android.widget.ProgressBar;
import com.facebook.drawee.view.SimpleDraweeView;
import com.google.common.util.concurrent.ListenableFuture;
import com.nextcloud.talk.R;
import com.nextcloud.talk.activities.FullScreenImageActivity;
import com.nextcloud.talk.activities.FullScreenMediaActivity;
import com.nextcloud.talk.activities.FullScreenTextViewerActivity;
import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.components.filebrowser.models.BrowserFile;
import com.nextcloud.talk.components.filebrowser.models.DavResponse;
import com.nextcloud.talk.components.filebrowser.webdav.ReadFilesystemOperation;
import com.nextcloud.talk.databinding.ReactionsInsideMessageBinding;
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker;
import com.nextcloud.talk.models.database.CapabilitiesUtil;
import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.chat.ChatMessage;
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet;
import com.nextcloud.talk.utils.AccountUtils;
import com.nextcloud.talk.utils.DisplayUtils;
import com.nextcloud.talk.utils.DrawableUtils;
import com.nextcloud.talk.utils.bundle.BundleKeys;
import com.nextcloud.talk.utils.FileViewerUtils;
import com.stfalcon.chatkit.messages.MessageHolders;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Callable;
@ -75,10 +66,7 @@ import javax.inject.Inject;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.emoji.widget.EmojiTextView;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;
import autodagger.AutoInjector;
@ -114,6 +102,8 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
ReactionsInsideMessageBinding reactionsBinding;
FileViewerUtils fileViewerUtils;
View clickView;
ReactionsInterface reactionsInterface;
@ -122,6 +112,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
public MagicPreviewMessageViewHolder(View itemView, Object payload) {
super(itemView, payload);
NextcloudTalkApplication.Companion.getSharedApplication().getComponentApplication().inject(this);
fileViewerUtils = new FileViewerUtils(context);
}
@SuppressLint("SetTextI18n")
@ -199,12 +190,7 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
.replace("http://", "");
clickView.setOnClickListener(v -> {
String mimetype = message.getSelectedIndividualHashMap().get(KEY_MIMETYPE);
if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileName)) {
openOrDownloadFile(message);
} else {
openFileInFilesApp(message, accountString);
}
fileViewerUtils.openFile(message, progressBar, getMessageText(), image);
});
clickView.setOnLongClickListener(l -> {
@ -231,7 +217,13 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
WorkManager
.getInstance(context)
.getWorkInfoByIdLiveData(workInfo.getId())
.observeForever(info -> updateViewsByProgress(fileName, mimetype, info));
.observeForever(info -> fileViewerUtils.updateViewsByProgress(
fileName,
mimetype,
info,
progressBar,
getMessageText(),
image));
}
}
} catch (ExecutionException | InterruptedException e) {
@ -287,151 +279,8 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
return drawable;
}
public abstract EmojiTextView getMessageText();
public abstract ProgressBar getProgressBar();
public abstract SimpleDraweeView getImage();
public abstract View getPreviewContainer();
public abstract View getPreviewContactContainer();
public abstract SimpleDraweeView getPreviewContactPhoto();
public abstract EmojiTextView getPreviewContactName();
public abstract ProgressBar getPreviewContactProgressBar();
public abstract ReactionsInsideMessageBinding getReactionsBinding();
private void openOrDownloadFile(ChatMessage message) {
String filename = message.getSelectedIndividualHashMap().get(KEY_NAME);
String mimetype = message.getSelectedIndividualHashMap().get(KEY_MIMETYPE);
File file = new File(context.getCacheDir(), filename);
if (file.exists()) {
openFile(filename, mimetype);
} else {
downloadFileToCache(message);
}
}
public boolean isSupportedForInternalViewer(String mimetype){
switch (mimetype) {
case "image/png":
case "image/jpeg":
case "image/gif":
case "audio/mpeg":
case "audio/wav":
case "audio/ogg":
case "video/mp4":
case "video/quicktime":
case "video/ogg":
case "text/markdown":
case "text/plain":
return true;
default:
return false;
}
}
private void openFile(String filename, String mimetype) {
switch (mimetype) {
case "audio/mpeg":
case "audio/wav":
case "audio/ogg":
case "video/mp4":
case "video/quicktime":
case "video/ogg":
openMediaView(filename, mimetype);
break;
case "image/png":
case "image/jpeg":
case "image/gif":
openImageView(filename, mimetype);
break;
case "text/markdown":
case "text/plain":
openTextView(filename, mimetype);
break;
default:
openFileByExternalApp(filename, mimetype);
}
}
private void openFileByExternalApp(String fileName, String mimetype) {
String path = context.getCacheDir().getAbsolutePath() + "/" + fileName;
File file = new File(path);
Intent intent;
if (Build.VERSION.SDK_INT < 24) {
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), mimetype);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
} else {
intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri pdfURI = FileProvider.getUriForFile(context, context.getPackageName(), file);
intent.setDataAndType(pdfURI, mimetype);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
try {
if (intent.resolveActivity(context.getPackageManager()) != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
Log.e(TAG, "No Application found to open the file. This should have been handled beforehand!");
}
} catch (Exception e) {
Log.e(TAG, "Error while opening file", e);
}
}
private boolean canBeHandledByExternalApp(String mimetype, String fileName) {
String path = context.getCacheDir().getAbsolutePath() + "/" + fileName;
File file = new File(path);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), mimetype);
return intent.resolveActivity(context.getPackageManager()) != null;
}
private void openImageView(String filename, String mimetype) {
Intent fullScreenImageIntent = new Intent(context, FullScreenImageActivity.class);
fullScreenImageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
fullScreenImageIntent.putExtra("FILE_NAME", filename);
fullScreenImageIntent.putExtra("IS_GIF", isGif(mimetype));
context.startActivity(fullScreenImageIntent);
}
private void openFileInFilesApp(ChatMessage message, String accountString) {
if (AccountUtils.INSTANCE.canWeOpenFilesApp(context, accountString)) {
Intent filesAppIntent = new Intent(Intent.ACTION_VIEW, null);
final ComponentName componentName = new ComponentName(
context.getString(R.string.nc_import_accounts_from),
"com.owncloud.android.ui.activity.FileDisplayActivity"
);
filesAppIntent.setComponent(componentName);
filesAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
filesAppIntent.setPackage(context.getString(R.string.nc_import_accounts_from));
filesAppIntent.putExtra(BundleKeys.INSTANCE.getKEY_ACCOUNT(), accountString);
filesAppIntent.putExtra(
BundleKeys.INSTANCE.getKEY_FILE_ID(),
message.getSelectedIndividualHashMap().get(KEY_ID)
);
context.startActivity(filesAppIntent);
} else {
Intent browserIntent = new Intent(
Intent.ACTION_VIEW,
Uri.parse(message.getSelectedIndividualHashMap().get("link"))
);
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(browserIntent);
}
}
private void onMessageViewLongClick(ChatMessage message, String accountString) {
if (isSupportedForInternalViewer(message.getSelectedIndividualHashMap().get(KEY_MIMETYPE))) {
if (fileViewerUtils.isSupportedForInternalViewer(message.getSelectedIndividualHashMap().get(KEY_MIMETYPE))) {
previewMessageInterface.onPreviewMessageLongClick(message);
return;
}
@ -452,132 +301,13 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
popupMenu.inflate(R.menu.chat_preview_message_menu);
popupMenu.setOnMenuItemClickListener(item -> {
openFileInFilesApp(message, accountString);
fileViewerUtils.openFileInFilesApp(message, accountString);
return true;
});
popupMenu.show();
}
@SuppressLint("LongLogTag")
private void downloadFileToCache(ChatMessage message) {
String baseUrl = message.activeUser.getBaseUrl();
String userId = message.activeUser.getUserId();
String attachmentFolder = CapabilitiesUtil.getAttachmentFolder(message.activeUser);
String fileName = message.getSelectedIndividualHashMap().get(KEY_NAME);
String mimetype = message.getSelectedIndividualHashMap().get(KEY_MIMETYPE);
String size = message.getSelectedIndividualHashMap().get("size");
if (size == null) {
size = "-1";
}
Integer fileSize = Integer.valueOf(size);
String fileId = message.getSelectedIndividualHashMap().get(KEY_ID);
String path = message.getSelectedIndividualHashMap().get(KEY_PATH);
// check if download worker is already running
ListenableFuture<List<WorkInfo>> workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId);
try {
for (WorkInfo workInfo : workers.get()) {
if (workInfo.getState() == WorkInfo.State.RUNNING || workInfo.getState() == WorkInfo.State.ENQUEUED) {
Log.d(TAG, "Download worker for " + fileId + " is already running or " +
"scheduled");
return;
}
}
} catch (ExecutionException | InterruptedException e) {
Log.e(TAG, "Error when checking if worker already exsists", e);
}
Data data;
OneTimeWorkRequest downloadWorker;
data = new Data.Builder()
.putString(DownloadFileToCacheWorker.KEY_BASE_URL, baseUrl)
.putString(DownloadFileToCacheWorker.KEY_USER_ID, userId)
.putString(DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER, attachmentFolder)
.putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileName)
.putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
.putInt(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileSize)
.build();
downloadWorker = new OneTimeWorkRequest.Builder(DownloadFileToCacheWorker.class)
.setInputData(data)
.addTag(fileId)
.build();
WorkManager.getInstance().enqueue(downloadWorker);
progressBar.setVisibility(View.VISIBLE);
WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.getId()).observeForever(workInfo -> {
updateViewsByProgress(fileName, mimetype, workInfo);
});
}
private void updateViewsByProgress(String fileName, String mimetype, WorkInfo workInfo) {
switch (workInfo.getState()) {
case RUNNING:
int progress = workInfo.getProgress().getInt(DownloadFileToCacheWorker.PROGRESS, -1);
if (progress > -1) {
getMessageText().setText(String.format(context.getResources().getString(R.string.filename_progress), fileName, progress));
}
break;
case SUCCEEDED:
if (image.isShown()) {
openFile(fileName, mimetype);
} else {
Log.d(TAG, "file " + fileName +
" was downloaded but it's not opened because view is not shown on screen");
}
getMessageText().setText(fileName);
progressBar.setVisibility(View.GONE);
break;
case FAILED:
getMessageText().setText(fileName);
progressBar.setVisibility(View.GONE);
break;
default:
// do nothing
break;
}
}
private void openMediaView(String filename, String mimetype) {
Intent fullScreenMediaIntent = new Intent(context, FullScreenMediaActivity.class);
fullScreenMediaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
fullScreenMediaIntent.putExtra("FILE_NAME", filename);
fullScreenMediaIntent.putExtra("AUDIO_ONLY", isAudioOnly(mimetype));
context.startActivity(fullScreenMediaIntent);
}
private void openTextView(String filename, String mimetype) {
Intent fullScreenTextViewerIntent = new Intent(context, FullScreenTextViewerActivity.class);
fullScreenTextViewerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
fullScreenTextViewerIntent.putExtra("FILE_NAME", filename);
fullScreenTextViewerIntent.putExtra("IS_MARKDOWN", isMarkdown(mimetype));
context.startActivity(fullScreenTextViewerIntent);
}
private boolean isGif(String mimetype) {
return ("image/gif").equals(mimetype);
}
private boolean isMarkdown(String mimetype) {
return ("text/markdown").equals(mimetype);
}
private boolean isAudioOnly(String mimetype) {
return mimetype.startsWith("audio");
}
private void fetchFileInformation(String url, UserEntity activeUser) {
Single.fromCallable(new Callable<ReadFilesystemOperation>() {
@Override
@ -622,4 +352,22 @@ public abstract class MagicPreviewMessageViewHolder extends MessageHolders.Incom
public void assignPreviewMessageInterface(PreviewMessageInterface previewMessageInterface) {
this.previewMessageInterface = previewMessageInterface;
}
public abstract EmojiTextView getMessageText();
public abstract ProgressBar getProgressBar();
public abstract SimpleDraweeView getImage();
public abstract View getPreviewContainer();
public abstract View getPreviewContactContainer();
public abstract SimpleDraweeView getPreviewContactPhoto();
public abstract EmojiTextView getPreviewContactName();
public abstract ProgressBar getPreviewContactProgressBar();
public abstract ReactionsInsideMessageBinding getReactionsBinding();
}

View File

@ -0,0 +1,279 @@
package com.nextcloud.talk.utils
import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.Log
import android.view.View
import android.widget.ProgressBar
import androidx.core.content.FileProvider
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
import com.nextcloud.talk.R
import com.nextcloud.talk.activities.FullScreenImageActivity
import com.nextcloud.talk.activities.FullScreenMediaActivity
import com.nextcloud.talk.activities.FullScreenTextViewerActivity
import com.nextcloud.talk.adapters.messages.MagicPreviewMessageViewHolder
import com.nextcloud.talk.jobs.DownloadFileToCacheWorker
import com.nextcloud.talk.models.database.CapabilitiesUtil
import com.nextcloud.talk.models.json.chat.ChatMessage
import com.nextcloud.talk.utils.AccountUtils.canWeOpenFilesApp
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACCOUNT
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FILE_ID
import androidx.emoji.widget.EmojiTextView
import com.facebook.drawee.view.SimpleDraweeView
import java.io.File
import java.util.concurrent.ExecutionException
class FileViewerUtils(private val context: Context) {
fun openFile(message: ChatMessage, progressBar: ProgressBar, messageText: EmojiTextView, previewImage: SimpleDraweeView) {
val accountString = message.activeUser.username + "@" +
message.activeUser.baseUrl
.replace("https://", "")
.replace("http://", "")
val fileName = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]!!
val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]!!
if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileName)) {
openOrDownloadFile(message, progressBar, messageText, previewImage)
} else {
openFileInFilesApp(message, accountString)
}
}
private fun canBeHandledByExternalApp(mimetype: String, fileName: String): Boolean {
val path: String = context.cacheDir.absolutePath + "/" + fileName
val file = File(path)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(Uri.fromFile(file), mimetype)
return intent.resolveActivity(context.packageManager) != null
}
private fun openOrDownloadFile(message: ChatMessage, progressBar: ProgressBar, messageText: EmojiTextView, previewImage: SimpleDraweeView) {
val filename = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]
val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]
val file = File(context.cacheDir, filename)
if (file.exists()) {
openFile(filename!!, mimetype!!)
} else {
downloadFileToCache(message, progressBar, messageText, previewImage)
}
}
private fun openFile(filename: String, mimetype: String) {
when (mimetype) {
"audio/mpeg", "audio/wav", "audio/ogg", "video/mp4", "video/quicktime", "video/ogg" -> openMediaView(
filename,
mimetype
)
"image/png", "image/jpeg", "image/gif" -> openImageView(filename, mimetype)
"text/markdown", "text/plain" -> openTextView(filename, mimetype)
else -> openFileByExternalApp(filename, mimetype)
}
}
private fun openFileByExternalApp(fileName: String, mimetype: String) {
val path = context.cacheDir.absolutePath + "/" + fileName
val file = File(path)
val intent: Intent
if (Build.VERSION.SDK_INT < 24) {
intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(Uri.fromFile(file), mimetype)
intent.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
} else {
intent = Intent()
intent.action = Intent.ACTION_VIEW
val pdfURI = FileProvider.getUriForFile(context, context.packageName, file)
intent.setDataAndType(pdfURI, mimetype)
intent.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
try {
if (intent.resolveActivity(context.packageManager) != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
} else {
Log.e(TAG, "No Application found to open the file. This should have been handled beforehand!")
}
} catch (e: Exception) {
Log.e(TAG, "Error while opening file", e)
}
}
fun openFileInFilesApp(message: ChatMessage, accountString: String) {
if (canWeOpenFilesApp(context, accountString)) {
val filesAppIntent = Intent(Intent.ACTION_VIEW, null)
val componentName = ComponentName(
context.getString(R.string.nc_import_accounts_from),
"com.owncloud.android.ui.activity.FileDisplayActivity"
)
filesAppIntent.component = componentName
filesAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
filesAppIntent.setPackage(context.getString(R.string.nc_import_accounts_from))
filesAppIntent.putExtra(KEY_ACCOUNT, accountString)
filesAppIntent.putExtra(
KEY_FILE_ID,
message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_ID]
)
context.startActivity(filesAppIntent)
} else {
val browserIntent = Intent(
Intent.ACTION_VIEW,
Uri.parse(message.getSelectedIndividualHashMap()["link"])
)
browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(browserIntent)
}
}
private fun openImageView(filename: String, mimetype: String) {
val fullScreenImageIntent = Intent(context, FullScreenImageActivity::class.java)
fullScreenImageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
fullScreenImageIntent.putExtra("FILE_NAME", filename)
fullScreenImageIntent.putExtra("IS_GIF", isGif(mimetype))
context.startActivity(fullScreenImageIntent)
}
private fun openMediaView(filename: String, mimetype: String) {
val fullScreenMediaIntent = Intent(context, FullScreenMediaActivity::class.java)
fullScreenMediaIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
fullScreenMediaIntent.putExtra("FILE_NAME", filename)
fullScreenMediaIntent.putExtra("AUDIO_ONLY", isAudioOnly(mimetype))
context.startActivity(fullScreenMediaIntent)
}
private fun openTextView(filename: String, mimetype: String) {
val fullScreenTextViewerIntent = Intent(context, FullScreenTextViewerActivity::class.java)
fullScreenTextViewerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
fullScreenTextViewerIntent.putExtra("FILE_NAME", filename)
fullScreenTextViewerIntent.putExtra("IS_MARKDOWN", isMarkdown(mimetype))
context.startActivity(fullScreenTextViewerIntent)
}
fun isSupportedForInternalViewer(mimetype: String?): Boolean {
return when (mimetype) {
"image/png", "image/jpeg", "image/gif", "audio/mpeg", "audio/wav", "audio/ogg", "video/mp4", "video/quicktime", "video/ogg", "text/markdown", "text/plain" -> true
else -> false
}
}
private fun isGif(mimetype: String): Boolean {
return "image/gif" == mimetype
}
private fun isMarkdown(mimetype: String): Boolean {
return "text/markdown" == mimetype
}
private fun isAudioOnly(mimetype: String): Boolean {
return mimetype.startsWith("audio")
}
@SuppressLint("LongLogTag")
private fun downloadFileToCache(message: ChatMessage, progressBar: ProgressBar, messageText: EmojiTextView, previewImage: SimpleDraweeView) {
val baseUrl = message.activeUser.baseUrl
val userId = message.activeUser.userId
val attachmentFolder = CapabilitiesUtil.getAttachmentFolder(message.activeUser)
val fileName = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_NAME]!!
val mimetype = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_MIMETYPE]!!
var size = message.getSelectedIndividualHashMap()["size"]
if (size == null) {
size = "-1"
}
val fileSize = Integer.valueOf(size)
val fileId = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_ID]
val path = message.getSelectedIndividualHashMap()[MagicPreviewMessageViewHolder.KEY_PATH]
// check if download worker is already running
val workers = WorkManager.getInstance(context).getWorkInfosByTag(
fileId!!
)
try {
for (workInfo in workers.get()) {
if (workInfo.state == WorkInfo.State.RUNNING || workInfo.state == WorkInfo.State.ENQUEUED) {
Log.d(TAG, "Download worker for $fileId is already running or scheduled")
return
}
}
} catch (e: ExecutionException) {
Log.e(TAG, "Error when checking if worker already exsists", e)
} catch (e: InterruptedException) {
Log.e(TAG, "Error when checking if worker already exsists", e)
}
val downloadWorker: OneTimeWorkRequest
val data: Data = Data.Builder()
.putString(DownloadFileToCacheWorker.KEY_BASE_URL, baseUrl)
.putString(DownloadFileToCacheWorker.KEY_USER_ID, userId)
.putString(DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER, attachmentFolder)
.putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileName)
.putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
.putInt(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileSize)
.build()
downloadWorker = OneTimeWorkRequest.Builder(DownloadFileToCacheWorker::class.java)
.setInputData(data)
.addTag(fileId)
.build()
WorkManager.getInstance().enqueue(downloadWorker)
progressBar.visibility = View.VISIBLE
WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.id)
.observeForever { workInfo: WorkInfo? ->
updateViewsByProgress(
fileName,
mimetype,
workInfo!!,
progressBar,
messageText,
previewImage
)
}
}
fun updateViewsByProgress(
fileName: String,
mimetype: String,
workInfo: WorkInfo,
progressBar: ProgressBar,
messageText: EmojiTextView,
previewImage: SimpleDraweeView
) {
when (workInfo.state) {
WorkInfo.State.RUNNING -> {
val progress = workInfo.progress.getInt(DownloadFileToCacheWorker.PROGRESS, -1)
if (progress > -1) {
messageText.text = String.format(
context.resources.getString(R.string.filename_progress),
fileName,
progress
)
}
}
WorkInfo.State.SUCCEEDED -> {
if (previewImage.isShown) {
openFile(fileName, mimetype)
} else {
Log.d(TAG, "file " + fileName +
" was downloaded but it's not opened because view is not shown on screen"
)
}
messageText.text = fileName
progressBar.visibility = View.GONE
}
WorkInfo.State.FAILED -> {
messageText.text = fileName
progressBar.visibility = View.GONE
}
else -> {
}
}
}
companion object {
private val TAG = FileViewerUtils::class.simpleName
}
}