From d6aeeb2decab19217af18ebc81a8dda9b3a63f70 Mon Sep 17 00:00:00 2001 From: Sawyer Blatz Date: Mon, 11 Nov 2019 14:08:51 -0800 Subject: [PATCH] For #5958: Adds in app download notifications (#6506) --- .../fenix/browser/BaseBrowserFragment.kt | 56 +++++++---- .../DownloadNotificationBottomSheetDialog.kt | 96 +++++++++++++++++++ .../layout/download_notification_layout.xml | 91 ++++++++++++++++++ 3 files changed, 222 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/downloads/DownloadNotificationBottomSheetDialog.kt create mode 100644 app/src/main/res/layout/download_notification_layout.xml 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 971cdf289..8382c79f6 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -39,6 +39,7 @@ import mozilla.components.feature.accounts.FxaWebChannelFeature import mozilla.components.feature.app.links.AppLinksFeature import mozilla.components.feature.contextmenu.ContextMenuCandidate import mozilla.components.feature.contextmenu.ContextMenuFeature +import mozilla.components.feature.downloads.AbstractFetchDownloadService import mozilla.components.feature.downloads.DownloadsFeature import mozilla.components.feature.downloads.manager.FetchDownloadManager import mozilla.components.feature.intent.ext.EXTRA_SESSION_ID @@ -72,10 +73,10 @@ import org.mozilla.fenix.components.toolbar.BrowserToolbarViewInteractor import org.mozilla.fenix.components.toolbar.DefaultBrowserToolbarController import org.mozilla.fenix.components.toolbar.QuickActionSheetState import org.mozilla.fenix.components.toolbar.ToolbarIntegration +import org.mozilla.fenix.downloads.DownloadNotificationBottomSheetDialog import org.mozilla.fenix.downloads.DownloadService import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.enterToImmersiveMode -import org.mozilla.fenix.ext.getDimenInDip import org.mozilla.fenix.ext.getRootView import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.nav @@ -256,27 +257,40 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler, SessionManager.Obs view = view ) - downloadsFeature.set( - feature = DownloadsFeature( + val downloadFeature = DownloadsFeature( + context.applicationContext, + store = store, + useCases = context.components.useCases.downloadUseCases, + fragmentManager = childFragmentManager, + customTabId = customTabSessionId, + downloadManager = FetchDownloadManager( context.applicationContext, - store = store, - useCases = context.components.useCases.downloadUseCases, - fragmentManager = childFragmentManager, - customTabId = customTabSessionId, - downloadManager = FetchDownloadManager( - context.applicationContext, - DownloadService::class - ), - promptsStyling = DownloadsFeature.PromptsStyling( - gravity = Gravity.BOTTOM, - shouldWidthMatchParent = true, - positiveButtonBackgroundColor = ThemeManager.resolveAttribute(R.attr.accent, context), - positiveButtonTextColor = ThemeManager.resolveAttribute(R.attr.contrastText, context), - positiveButtonRadius = context.getDimenInDip(R.dimen.tab_corner_radius) - ), - onNeedToRequestPermissions = { permissions -> - requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS) - }), + DownloadService::class + ), + promptsStyling = DownloadsFeature.PromptsStyling( + gravity = Gravity.BOTTOM, + shouldWidthMatchParent = true, + positiveButtonBackgroundColor = ThemeManager.resolveAttribute(R.attr.accent, context), + positiveButtonTextColor = ThemeManager.resolveAttribute(R.attr.contrastText, context), + positiveButtonRadius = (resources.getDimensionPixelSize(R.dimen.tab_corner_radius)).toFloat() + ), + onNeedToRequestPermissions = { permissions -> + requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS) + } + ) + + downloadFeature.onDownloadCompleted = { download, _, downloadJobStatus -> + val dialog = DownloadNotificationBottomSheetDialog( + context = context, + didFail = downloadJobStatus == AbstractFetchDownloadService.DownloadJobStatus.FAILED, + download = download, + tryAgain = downloadFeature::tryAgain + ) + dialog.show() + } + + downloadsFeature.set( + downloadFeature, owner = this, view = view ) diff --git a/app/src/main/java/org/mozilla/fenix/downloads/DownloadNotificationBottomSheetDialog.kt b/app/src/main/java/org/mozilla/fenix/downloads/DownloadNotificationBottomSheetDialog.kt new file mode 100644 index 000000000..c44a0ab99 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/downloads/DownloadNotificationBottomSheetDialog.kt @@ -0,0 +1,96 @@ +/* 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.downloads + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import com.google.android.material.bottomsheet.BottomSheetDialog +import kotlinx.android.synthetic.main.download_notification_layout.* +import mozilla.components.browser.state.state.content.DownloadState +import mozilla.components.feature.downloads.AbstractFetchDownloadService +import mozilla.components.feature.downloads.toMegabyteString +import org.mozilla.fenix.R +import org.mozilla.fenix.theme.ThemeManager + +class DownloadNotificationBottomSheetDialog( + context: Context, + private val download: DownloadState, + private val didFail: Boolean, + private val tryAgain: (Long) -> Unit + // We must pass in the BottomSheetDialog theme for the transparent window background to apply properly +) : BottomSheetDialog(context, R.style.Theme_MaterialComponents_BottomSheetDialog) { + override fun onCreate(savedInstanceState: Bundle?) { + setContentView(R.layout.download_notification_layout) + + if (didFail) { + download_notification_title.text = + context.getString(R.string.mozac_feature_downloads_failed_notification_text2) + + download_notification_icon.setImageDrawable(context.getDrawable( + mozilla.components.feature.downloads.R.drawable.mozac_feature_download_ic_download_failed + )) + + download_notification_action_button.apply { + text = context.getString( + mozilla.components.feature.downloads.R.string.mozac_feature_downloads_button_try_again + ) + setOnClickListener { + tryAgain(download.id) + dismiss() + } + } + } else { + val titleText = context.getString( + R.string.mozac_feature_downloads_completed_notification_text2 + ) + " (${download.contentLength?.toMegabyteString()})" + + download_notification_title.text = titleText + + download_notification_icon.setImageDrawable(context.getDrawable( + mozilla.components.feature.downloads.R.drawable.mozac_feature_download_ic_download_complete + )) + + download_notification_action_button.apply { + text = context.getString( + mozilla.components.feature.downloads.R.string.mozac_feature_downloads_button_open + ) + setOnClickListener { + AbstractFetchDownloadService.openFile( + context = context, + contentType = download.contentType, + filePath = download.filePath + ) + dismiss() + } + } + } + + download_notification_close_button.setOnClickListener { + dismiss() + } + + download_notification_filename.text = download.fileName + + setOnShowListener { + window?.apply { + // setBackgroundDrawableResource(android.R.color.transparent) + setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) + setLayout( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + navigationBarColor = ContextCompat.getColor( + context, + ThemeManager.resolveAttribute(R.attr.foundation, context + ) + ) + } + } + } +} diff --git a/app/src/main/res/layout/download_notification_layout.xml b/app/src/main/res/layout/download_notification_layout.xml new file mode 100644 index 000000000..5584a10ec --- /dev/null +++ b/app/src/main/res/layout/download_notification_layout.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + +