diff --git a/app/src/main/java/com/nextcloud/ui/component/FilenameView.kt b/app/src/main/java/com/nextcloud/ui/component/FilenameView.kt new file mode 100644 index 000000000000..031b9af369a6 --- /dev/null +++ b/app/src/main/java/com/nextcloud/ui/component/FilenameView.kt @@ -0,0 +1,75 @@ +/* + * Nextcloud - Android Client + * + * SPDX-FileCopyrightText: 2026 Alper Ozturk + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +package com.nextcloud.ui.component + +import android.content.Context +import android.text.TextUtils +import android.util.AttributeSet +import android.view.Gravity +import android.widget.LinearLayout +import android.widget.TextView +import androidx.core.widget.TextViewCompat +import com.nextcloud.utils.view.LocaleDirection +import com.owncloud.android.utils.FileStorageUtils +import com.google.android.material.R as MaterialR + +class FilenameView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + LinearLayout(context, attrs, defStyleAttr) { + + private val title = createTextView(TextUtils.TruncateAt.END, TITLE_MAX_LINES) + + private val extension = createTextView(TextUtils.TruncateAt.START, EXTENSION_MAX_LINES) + + var text: CharSequence + get() = title.text + set(value) { + title.text = value + removeView(extension) + } + + init { + orientation = HORIZONTAL + addView(title, LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, TITLE_WEIGHT)) + } + + fun setFilename(filename: String, isFolder: Boolean) { + if (!FileStorageUtils.containsBidiControlCharacters(filename)) { + text = filename + return + } + + val (base, ext) = FileStorageUtils.getFilenameAndExtension(filename, isFolder, LocaleDirection.isRtl) + title.text = base + + if (ext.isNullOrEmpty()) { + removeView(extension) + return + } + + extension.text = ext + if (extension.parent == null) { + addView( + extension, + LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT).apply { gravity = Gravity.BOTTOM } + ) + } + } + + private fun createTextView(truncateAt: TextUtils.TruncateAt, lines: Int): TextView = TextView(context).apply { + TextViewCompat.setTextAppearance(this, MaterialR.style.TextAppearance_Material3_HeadlineSmall) + ellipsize = truncateAt + maxLines = lines + gravity = Gravity.START + } + + companion object { + private const val TITLE_WEIGHT = 1f + private const val TITLE_MAX_LINES = 3 + private const val EXTENSION_MAX_LINES = 1 + } +} diff --git a/app/src/main/java/com/nextcloud/ui/fileactions/FileActionsBottomSheet.kt b/app/src/main/java/com/nextcloud/ui/fileactions/FileActionsBottomSheet.kt index 9ea47476ce89..441152bcf3b5 100644 --- a/app/src/main/java/com/nextcloud/ui/fileactions/FileActionsBottomSheet.kt +++ b/app/src/main/java/com/nextcloud/ui/fileactions/FileActionsBottomSheet.kt @@ -36,12 +36,9 @@ import com.nextcloud.client.di.ViewModelFactory import com.nextcloud.utils.SnackbarUtil import com.nextcloud.utils.avatar.AvatarGenerationListener import com.nextcloud.utils.avatar.AvatarGenerator -import com.nextcloud.utils.extensions.setVisibleIf import com.nextcloud.utils.text.DisplayTextFormatter import com.nextcloud.utils.text.SpanFormatter import com.nextcloud.utils.thumbnail.ThumbnailArguments -import com.nextcloud.utils.view.LocaleDirection -import com.nextcloud.utils.view.ScreenMetrics import com.owncloud.android.R import com.owncloud.android.databinding.FileActionsBottomSheetBinding import com.owncloud.android.databinding.FileActionsBottomSheetItemBinding @@ -50,7 +47,6 @@ import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.lib.resources.files.model.FileLockType import com.owncloud.android.ui.activity.ComponentsGetter -import com.owncloud.android.utils.FileStorageUtils import com.nextcloud.utils.thumbnail.ThumbnailGenerator import com.owncloud.android.utils.theme.ViewThemeUtils import javax.inject.Inject @@ -238,25 +234,12 @@ class FileActionsBottomSheet : private fun displayTitle(titleFile: OCFile?) { val decryptedFileName = titleFile?.decryptedFileName - if (decryptedFileName != null) { - val isFolder = titleFile.isFolder - val isRTL = LocaleDirection.isRtl - val (base, ext) = FileStorageUtils.getFilenameAndExtension(decryptedFileName, isFolder, isRTL) - val titleMaxWidth = ScreenMetrics.dpToPx( - requireContext().resources.configuration.screenWidthDp.times(FILENAME_MAX_WIDTH_PERCENTAGE).toFloat(), - requireContext() - ) - - binding.title.maxWidth = titleMaxWidth - binding.title.text = base - binding.extension.setVisibleIf(!isFolder) - if (!isFolder) { - binding.extension.text = ext - } - } else { + if (decryptedFileName == null) { binding.title.isVisible = false - binding.extension.isVisible = false + return } + + binding.title.setFilename(decryptedFileName, titleFile.isFolder) } private fun displayLockInfo(lockInfo: FileActionsViewModel.LockInfo) { @@ -351,7 +334,6 @@ class FileActionsBottomSheet : companion object { private const val REQUEST_KEY = "REQUEST_KEY_ACTION" private const val RESULT_KEY_ACTION_ID = "RESULT_KEY_ACTION_ID" - private const val FILENAME_MAX_WIDTH_PERCENTAGE = 0.6 @JvmStatic @JvmOverloads diff --git a/app/src/main/res/layout/file_actions_bottom_sheet.xml b/app/src/main/res/layout/file_actions_bottom_sheet.xml index cf2c493069b9..1ed3129004d8 100644 --- a/app/src/main/res/layout/file_actions_bottom_sheet.xml +++ b/app/src/main/res/layout/file_actions_bottom_sheet.xml @@ -47,28 +47,17 @@ + android:layout_height="wrap_content" /> - - - + android:layout_gravity="center_vertical" + android:layout_marginEnd="@dimen/standard_margin" />