diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 1acc0e059..42f4f4269 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -42,6 +42,7 @@ import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.content.DownloadState import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.browser.thumbnails.BrowserThumbnails import mozilla.components.concept.engine.prompt.ShareData import mozilla.components.feature.accounts.FxaCapability import mozilla.components.feature.accounts.FxaWebChannelFeature @@ -132,6 +133,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session get() = _browserToolbarView!! protected val readerViewFeature = ViewBoundFeatureWrapper() + protected val thumbnailsFeature = ViewBoundFeatureWrapper() private val sessionFeature = ViewBoundFeatureWrapper() private val contextMenuFeature = ViewBoundFeatureWrapper() @@ -231,6 +233,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session tabCollectionStorage = requireComponents.core.tabCollectionStorage, topSiteStorage = requireComponents.core.topSiteStorage, onTabCounterClicked = { + thumbnailsFeature.get()?.requestScreenshot() findNavController().nav( R.id.browserFragment, BrowserFragmentDirections.actionGlobalTabTrayDialogFragment() diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 797a5c34d..251cec203 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -54,7 +54,6 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { private val windowFeature = ViewBoundFeatureWrapper() private val searchFeature = ViewBoundFeatureWrapper() - private val thumbnailsFeature = ViewBoundFeatureWrapper() private var readerModeAvailable = false diff --git a/app/src/main/java/org/mozilla/fenix/ext/DownloadItem.kt b/app/src/main/java/org/mozilla/fenix/ext/DownloadItem.kt new file mode 100644 index 000000000..93fa26aea --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/ext/DownloadItem.kt @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ext + +import org.mozilla.fenix.R +import org.mozilla.fenix.library.downloads.DownloadItem + +// While this looks complex, it's actually pretty simple. +@SuppressWarnings("ComplexMethod") +fun DownloadItem.getIcon(): Int { + fun getIconCornerCases(fileName: String?): Int { + return when { + fileName?.endsWith("apk") == true -> R.drawable.ic_file_type_apk + fileName?.endsWith("zip") == true -> R.drawable.ic_file_type_zip + else -> R.drawable.ic_file_type_default + } + } + + fun checkForApplicationArchiveSubtypes(contentType: String): Int? { + return when { + contentType.contains("rar") -> R.drawable.ic_file_type_zip + contentType.contains("zip") -> R.drawable.ic_file_type_zip + contentType.contains("7z") -> R.drawable.ic_file_type_zip + contentType.contains("tar") -> R.drawable.ic_file_type_zip + contentType.contains("freearc") -> R.drawable.ic_file_type_zip + contentType.contains("octet-stream") -> null + contentType.contains("vnd.android.package-archive") -> null + else -> R.drawable.ic_file_type_document + } + } + + fun getIconFromContentType(contentType: String): Int? { + return when { + contentType.contains("image/") -> R.drawable.ic_file_type_image + contentType.contains("audio/") -> R.drawable.ic_file_type_audio_note + contentType.contains("video/") -> R.drawable.ic_file_type_video + contentType.contains("application/") -> checkForApplicationArchiveSubtypes(contentType) + contentType.contains("text/") -> R.drawable.ic_file_type_document + else -> null + } + } + + return contentType?.let { contentType -> + getIconFromContentType(contentType) + } ?: getIconCornerCases(fileName) +} diff --git a/app/src/main/java/org/mozilla/fenix/library/downloads/viewholders/DownloadsListItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/library/downloads/viewholders/DownloadsListItemViewHolder.kt index 4126b2cd7..c367ca674 100644 --- a/app/src/main/java/org/mozilla/fenix/library/downloads/viewholders/DownloadsListItemViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/library/downloads/viewholders/DownloadsListItemViewHolder.kt @@ -14,6 +14,7 @@ import org.mozilla.fenix.library.SelectionHolder import org.mozilla.fenix.library.downloads.DownloadInteractor import org.mozilla.fenix.library.downloads.DownloadItem import mozilla.components.feature.downloads.toMegabyteString +import org.mozilla.fenix.ext.getIcon class DownloadsListItemViewHolder( view: View, @@ -34,7 +35,7 @@ class DownloadsListItemViewHolder( itemView.download_layout.changeSelected(item in selectionHolder.selectedItems) itemView.overflow_menu.hideAndDisable() - itemView.favicon.setImageResource(R.drawable.ic_download_default) + itemView.favicon.setImageResource(item.getIcon()) itemView.favicon.isClickable = false this.item = item diff --git a/app/src/main/java/org/mozilla/fenix/shortcut/CreateShortcutFragment.kt b/app/src/main/java/org/mozilla/fenix/shortcut/CreateShortcutFragment.kt index 9918a677e..836bfce84 100644 --- a/app/src/main/java/org/mozilla/fenix/shortcut/CreateShortcutFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/shortcut/CreateShortcutFragment.kt @@ -41,7 +41,7 @@ class CreateShortcutFragment : DialogFragment() { cancel_button.setOnClickListener { dismiss() } add_button.setOnClickListener { - val text = shortcut_text.text.toString() + val text = shortcut_text.text.toString().trim() requireActivity().lifecycleScope.launch { requireComponents.useCases.webAppUseCases.addToHomescreen(text) } @@ -57,8 +57,9 @@ class CreateShortcutFragment : DialogFragment() { } private fun updateAddButtonEnabledState() { - add_button.isEnabled = shortcut_text.text.isNotEmpty() - add_button.alpha = if (shortcut_text.text.isNotEmpty()) ENABLED_ALPHA else DISABLED_ALPHA + val text = shortcut_text.text + add_button.isEnabled = text.isNotBlank() + add_button.alpha = if (text.isNotBlank()) ENABLED_ALPHA else DISABLED_ALPHA } companion object { diff --git a/app/src/main/res/drawable/ic_file_type_apk.xml b/app/src/main/res/drawable/ic_file_type_apk.xml new file mode 100644 index 000000000..e68e42a68 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_apk.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_file_type_audio_note.xml b/app/src/main/res/drawable/ic_file_type_audio_note.xml new file mode 100644 index 000000000..0d1e65b73 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_audio_note.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_file_type_default.xml b/app/src/main/res/drawable/ic_file_type_default.xml new file mode 100644 index 000000000..f76b8b185 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_default.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_file_type_document.xml b/app/src/main/res/drawable/ic_file_type_document.xml new file mode 100644 index 000000000..5d1dd8325 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_document.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_file_type_image.xml b/app/src/main/res/drawable/ic_file_type_image.xml new file mode 100644 index 000000000..45fed07fe --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_image.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_file_type_video.xml b/app/src/main/res/drawable/ic_file_type_video.xml new file mode 100644 index 000000000..881a5c728 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_video.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_file_type_zip.xml b/app/src/main/res/drawable/ic_file_type_zip.xml new file mode 100644 index 000000000..75ad4adc0 --- /dev/null +++ b/app/src/main/res/drawable/ic_file_type_zip.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/test/java/org/mozilla/fenix/ext/DownloadItemKtTest.kt b/app/src/test/java/org/mozilla/fenix/ext/DownloadItemKtTest.kt new file mode 100644 index 000000000..d4881dddb --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/ext/DownloadItemKtTest.kt @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.ext + +import mozilla.components.browser.state.state.content.DownloadState +import org.junit.Test + +import org.junit.Assert.assertEquals +import org.mozilla.fenix.R +import org.mozilla.fenix.library.downloads.DownloadItem + +class DownloadItemKtTest { + @Test + fun getIcon() { + val downloadItem = DownloadItem("0", "MyAwesomeFile", "", "", "image/png", DownloadState.Status.COMPLETED) + + assertEquals(R.drawable.ic_file_type_image, downloadItem.getIcon()) + assertEquals(R.drawable.ic_file_type_audio_note, downloadItem.copy(contentType = "audio/mp3").getIcon()) + assertEquals(R.drawable.ic_file_type_video, downloadItem.copy(contentType = "video/mp4").getIcon()) + assertEquals(R.drawable.ic_file_type_document, downloadItem.copy(contentType = "text/csv").getIcon()) + assertEquals(R.drawable.ic_file_type_zip, downloadItem.copy(contentType = "application/gzip").getIcon()) + assertEquals(R.drawable.ic_file_type_apk, downloadItem.copy(contentType = null, fileName = "Fenix.apk").getIcon()) + assertEquals(R.drawable.ic_file_type_zip, downloadItem.copy(contentType = null, fileName = "Fenix.zip").getIcon()) + assertEquals(R.drawable.ic_file_type_default, downloadItem.copy(contentType = null, fileName = null).getIcon()) + } +} diff --git a/mozilla-lint-rules/src/main/java/org/mozilla/fenix/lintrules/TextViewAndroidSrcXmlDetector.kt b/mozilla-lint-rules/src/main/java/org/mozilla/fenix/lintrules/TextViewAndroidSrcXmlDetector.kt index e582df218..f6411fe2b 100644 --- a/mozilla-lint-rules/src/main/java/org/mozilla/fenix/lintrules/TextViewAndroidSrcXmlDetector.kt +++ b/mozilla-lint-rules/src/main/java/org/mozilla/fenix/lintrules/TextViewAndroidSrcXmlDetector.kt @@ -23,7 +23,7 @@ import com.android.tools.lint.detector.api.XmlContext import org.w3c.dom.Element /** - * A custom lint check that prohibits not using the app:srcCompat for ImageViews + * A custom lint check that prohibits not using the app:drawableXCompat to define drawables in TextViews */ class TextViewAndroidSrcXmlDetector : ResourceXmlDetector() { companion object {