Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions app/src/main/java/com/nextcloud/ui/fileDetail/FileDetailPreview.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2026 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

package com.nextcloud.ui.fileDetail

import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.widget.ImageView
import com.nextcloud.utils.extensions.getSmallThumbnail
import com.nextcloud.utils.thumbnail.FolderThumbnailGenerator
import com.nextcloud.utils.thumbnail.VideoOverlayGenerator
import com.owncloud.android.R
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.ui.activity.ToolbarActivity
import com.owncloud.android.utils.MimeTypeUtil
import com.owncloud.android.utils.theme.ViewThemeUtils

class FileDetailPreview(
private val toolbarActivity: ToolbarActivity,
private val folderThumbnailGenerator: FolderThumbnailGenerator,
private val viewThemeUtils: ViewThemeUtils
) {
private val previewImageView: ImageView? = toolbarActivity.previewImageView

fun show(file: OCFile) {
if (file.isFolder) {
setIcon(folderThumbnailGenerator.getFolderIcon(file))
return
}

val thumbnail = file.getSmallThumbnail()
if (thumbnail == null) {
setIcon(MimeTypeUtil.getFileTypeIcon(file.mimeType, file.fileName, toolbarActivity, viewThemeUtils))
} else {
setImage(thumbnail.withVideoOverlay(file))
}
}

private fun Bitmap.withVideoOverlay(file: OCFile): Bitmap = if (MimeTypeUtil.isVideo(file)) {
VideoOverlayGenerator.addOverlay(this, toolbarActivity)
} else {
this
}

private fun setImage(bitmap: Bitmap) {
previewImageView?.setImageBitmap(bitmap)
applyScaling(ImageView.ScaleType.CENTER_CROP, 0)
}

private fun setIcon(icon: Drawable) {
previewImageView?.setImageDrawable(icon)
val padding = toolbarActivity.resources.getDimensionPixelSize(R.dimen.standard_double_padding)
applyScaling(ImageView.ScaleType.FIT_CENTER, padding)
}

private fun applyScaling(scaleType: ImageView.ScaleType, padding: Int) {
previewImageView?.run {
this.scaleType = scaleType
setPadding(padding, padding, padding, padding)
}
toolbarActivity.setPreviewImageVisibility(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.nextcloud.utils.thumbnail

import android.content.Context
import android.graphics.drawable.LayerDrawable
import android.view.View
import android.widget.ImageView
import androidx.core.content.ContextCompat
Expand Down Expand Up @@ -52,13 +53,15 @@ class FolderThumbnailGenerator @Inject constructor(
if (folder == null || !folder.isFolder) return

imageView.stopShimmer(loaderImageView)
imageView.setImageDrawable(getFolderIcon(folder))
}

fun getFolderIcon(folder: OCFile): LayerDrawable {
val isAutoUploadFolder =
SyncedFolderObserver.isAutoUploadFolder(folder, accountManager.user)
val isDarkModeActive = preferences.isDarkModeEnabled()

val overlayIconId = folder.getFileOverlayIconId(isAutoUploadFolder)
val icon = MimeTypeUtil.getFolderIcon(isDarkModeActive, overlayIconId, context, viewThemeUtils)
imageView.setImageDrawable(icon)
return MimeTypeUtil.getFolderIcon(isDarkModeActive, overlayIconId, context, viewThemeUtils)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@

import android.animation.AnimatorInflater;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
Expand Down Expand Up @@ -381,41 +379,13 @@ public boolean sortListGroupVisibility(){

return view.getVisibility() == View.VISIBLE;
}
/**
* Change the bitmap for the toolbar's preview image.
*
* @param bitmap bitmap of the preview image
*/
public void setPreviewImageBitmap(Bitmap bitmap) {
if (mPreviewImage != null) {
mPreviewImage.setImageBitmap(bitmap);
setPreviewImageVisibility(true);
}
}

/**
* Change the drawable for the toolbar's preview image.
*
* @param drawable drawable of the preview image
*/
public void setPreviewImageDrawable(Drawable drawable) {
if (mPreviewImage != null) {
mPreviewImage.setImageDrawable(drawable);
setPreviewImageVisibility(true);
}
}

/**
* get the toolbar's preview image view.
*/
public ImageView getPreviewImageView() {
return mPreviewImage;
}

public FrameLayout getPreviewImageContainer() {
return mPreviewImageContainer;
}

public void updateToolbarSubtitle(@NonNull String subtitle) {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
Expand All @@ -30,24 +29,22 @@
import com.nextcloud.client.jobs.download.FileDownloadHelper;
import com.nextcloud.client.jobs.upload.FileUploadHelper;
import com.nextcloud.client.network.ClientFactory;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.preferences.AppPreferences;
import com.nextcloud.ui.fileactions.FileAction;
import com.nextcloud.ui.fileDetail.FileDetailPreview;
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
import com.nextcloud.ui.tags.TagManagementBottomSheet;
import com.nextcloud.utils.HumanReadableFormatter;
import com.nextcloud.utils.MenuUtils;
import com.nextcloud.utils.SnackbarUtil;
import com.nextcloud.utils.extensions.BundleExtensionsKt;
import com.nextcloud.utils.extensions.FileExtensionsKt;
import com.nextcloud.utils.mdm.MDMConfig;
import com.nextcloud.utils.text.DisplayTextFormatter;
import com.owncloud.android.MainApp;
import com.nextcloud.utils.thumbnail.FolderThumbnailGenerator;
import com.owncloud.android.R;
import com.owncloud.android.databinding.FileDetailsFragmentBinding;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
Expand Down Expand Up @@ -110,12 +107,12 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
private int activeTab;

@Inject AppPreferences preferences;
@Inject ConnectivityService connectivityService;
@Inject UserAccountManager accountManager;
@Inject ClientFactory clientFactory;
@Inject FileDataStorageManager storageManager;
@Inject ViewThemeUtils viewThemeUtils;
@Inject BackgroundJobManager backgroundJobManager;
@Inject FolderThumbnailGenerator folderThumbnailGenerator;

/**
* Public factory method to create new FileDetailFragment instances.
Expand Down Expand Up @@ -605,17 +602,14 @@ public void updateFileDetails(boolean transferring, boolean refresh) {
OCFile file = getFile();

// set file details
if (MimeTypeUtil.isImage(file)) {
binding.filename.setText(file.getFileName());
} else {
binding.filename.setVisibility(View.GONE);
}
binding.filename.setText(file.getFileName());
binding.size.setText(HumanReadableFormatter.formatBytes(file.getFileLength()));

boolean showDetailedTimestamp = preferences.isShowDetailedTimestampEnabled();
setFileModificationTimestamp(file, showDetailedTimestamp);

setFilePreview(file);
binding.filename.setVisibility(previewLoaded ? View.VISIBLE : View.GONE);
setFavoriteIconStatus(file.isFavorite());

// configure UI for depending upon local state of the file
Expand Down Expand Up @@ -705,56 +699,13 @@ private boolean readyToShow() {
* @param file a {@link OCFile} to be previewed
*/
private void setFilePreview(OCFile file) {
Bitmap resizedImage;

if (toolbarActivity != null && MimeTypeUtil.isImage(file)) {
resizedImage = FileExtensionsKt.getBigThumbnail(file);

if (resizedImage != null && !file.isUpdateThumbnailNeeded()) {
toolbarActivity.setPreviewImageBitmap(resizedImage);
previewLoaded = true;
} else {
// show thumbnail while loading resized image
Bitmap thumbnail = FileExtensionsKt.getSmallThumbnail(file);
if (thumbnail != null) {
toolbarActivity.setPreviewImageBitmap(thumbnail);
} else {
thumbnail = ThumbnailsCacheManager.mDefaultImg;
}

// generate new resized image
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(getFile(), toolbarActivity.getPreviewImageView()) &&
containerActivity.getStorageManager() != null) {
final ThumbnailsCacheManager.ResizedImageGenerationTask task =
new ThumbnailsCacheManager.ResizedImageGenerationTask(this,
toolbarActivity.getPreviewImageView(),
toolbarActivity.getPreviewImageContainer(),
containerActivity.getStorageManager(),
connectivityService,
containerActivity.getStorageManager().getUser(),
getResources().getColor(R.color.background_color_inverse,
requireContext().getTheme())
);

if (resizedImage == null) {
resizedImage = thumbnail;
}

final ThumbnailsCacheManager.AsyncResizedImageDrawable asyncDrawable =
new ThumbnailsCacheManager.AsyncResizedImageDrawable(
MainApp.getAppContext().getResources(),
resizedImage,
task
);

toolbarActivity.setPreviewImageDrawable(asyncDrawable);
previewLoaded = true;
task.execute(getFile());
}
}
} else {
if (toolbarActivity == null) {
previewLoaded = false;
return;
}

new FileDetailPreview(toolbarActivity, folderThumbnailGenerator, viewThemeUtils).show(file);
previewLoaded = true;
}

/**
Expand Down
Loading