From db30b206a23638d3f9a69dd5274dc7485b1d5db6 Mon Sep 17 00:00:00 2001 From: Eduarda Barbosa <42220351+mebarbosa@users.noreply.github.com> Date: Thu, 26 Dec 2024 09:47:17 -0300 Subject: [PATCH] [Manage Downloads] Allow users to dismiss low storage banner in download screen (#3385) Co-authored-by: Philip Simpson --- CHANGELOG.md | 3 + .../view/ProfileEpisodeListFragment.kt | 22 ++++++- .../view/ProfileManageDownloadsCard.kt | 65 ++++++++++++------- .../pocketcasts/analytics/AnalyticsEvent.kt | 2 + .../src/main/res/values/strings.xml | 2 + .../pocketcasts/preferences/Settings.kt | 4 ++ .../pocketcasts/preferences/SettingsImpl.kt | 16 +++++ 7 files changed, 88 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9106081ba81..abfdc7bd058 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ ([#3387](https://github.com/Automattic/pocket-casts-android/pull/3387)) * Fix sleep timer was not stopping as expected ([#3377](https://github.com/Automattic/pocket-casts-android/pull/3377)) +* Updates + * Add the ability to dismiss the low storage banner in download screen + ([#3385](https://github.com/Automattic/pocket-casts-android/pull/3385)) 7.79 ----- diff --git a/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListFragment.kt b/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListFragment.kt index 57066e50e5e..67c8da3e6e3 100644 --- a/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListFragment.kt +++ b/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileEpisodeListFragment.kt @@ -425,7 +425,7 @@ class ProfileEpisodeListFragment : BaseFragment(), Toolbar.OnMenuItemClickListen private suspend fun updateManageDownloadsCard(downloadedEpisodesSize: Long) { binding?.manageDownloadsCard?.apply { - isVisible = downloadedEpisodesSize != 0L && isDeviceRunningOnLowStorage() + isVisible = downloadedEpisodesSize != 0L && isDeviceRunningOnLowStorage() && settings.shouldShowLowStorageBannerAfterSnooze() if (isVisible) { setContent { AppTheme(theme.activeTheme) { @@ -443,6 +443,10 @@ class ProfileEpisodeListFragment : BaseFragment(), Toolbar.OnMenuItemClickListen analyticsTracker.track(AnalyticsEvent.FREE_UP_SPACE_MANAGE_DOWNLOADS_TAPPED, mapOf("source" to SourceView.DOWNLOADS.analyticsValue)) showFragment(ManualCleanupFragment.newInstance()) }, + onMoreOptionsClick = { + analyticsTracker.track(AnalyticsEvent.FREE_UP_SPACE_MANAGE_DOWNLOADS_MORE_OPTIONS_TAPPED, mapOf("source" to SourceView.DOWNLOADS.analyticsValue)) + onManageDownloadsMoreOptions() + }, ) } } @@ -451,6 +455,22 @@ class ProfileEpisodeListFragment : BaseFragment(), Toolbar.OnMenuItemClickListen } } + private fun onManageDownloadsMoreOptions() { + OptionsDialog() + .setTitle(resources.getString(LR.string.need_to_free_up_space)) + .addTextOption(LR.string.dismiss_manage_download_banner, click = this::onDismissManageDownloadTapped) + .show(parentFragmentManager, "manage_downloads_more_options") + } + + private fun onDismissManageDownloadTapped() { + analyticsTracker.track( + AnalyticsEvent.FREE_UP_SPACE_MANAGE_DOWNLOADS_MORE_OPTIONS_DISMISS_TAPPED, + mapOf("source" to SourceView.DOWNLOADS.analyticsValue), + ) + settings.setDismissLowStorageBannerTime(System.currentTimeMillis()) + binding?.manageDownloadsCard?.isVisible = false + } + override fun onMenuItemClick(item: MenuItem): Boolean { return if (item.itemId == R.id.more_options) { val dialog = OptionsDialog() diff --git a/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileManageDownloadsCard.kt b/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileManageDownloadsCard.kt index 758b794d282..107cc15d9f0 100644 --- a/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileManageDownloadsCard.kt +++ b/modules/features/podcasts/src/main/java/au/com/shiftyjelly/pocketcasts/podcasts/view/ProfileManageDownloadsCard.kt @@ -11,8 +11,11 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Icon +import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.TextButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -37,6 +40,7 @@ import au.com.shiftyjelly.pocketcasts.localization.R as LR fun ManageDownloadsCard( totalDownloadSize: Long, onManageDownloadsClick: () -> Unit, + onMoreOptionsClick: () -> Unit, modifier: Modifier = Modifier, ) { val formattedTotalDownloadSize = Util.formattedBytes(bytes = totalDownloadSize, context = LocalContext.current) @@ -52,36 +56,47 @@ fun ManageDownloadsCard( .padding(horizontal = 16.dp).padding(top = 16.dp), ) { - Icon( - painter = painterResource(id = IR.drawable.pencil_cleanup), - contentDescription = stringResource(LR.string.pencil_clean_up_icon_content_description), - modifier = Modifier - .padding(end = 12.dp) - .size(24.dp), - // The icon isn't clickable so the design matches the title color - tint = MaterialTheme.theme.colors.primaryText01, - ) - - Column( - modifier = Modifier.padding(end = 16.dp), - ) { - TextH40( - text = stringResource(LR.string.need_to_free_up_space), - fontWeight = FontWeight.Bold, - color = MaterialTheme.theme.colors.primaryText01, + Row(modifier = Modifier.weight(1f)) { + Icon( + painter = painterResource(id = IR.drawable.pencil_cleanup), + contentDescription = stringResource(LR.string.pencil_clean_up_icon_content_description), + modifier = Modifier + .padding(end = 12.dp) + .size(24.dp), + // The icon isn't clickable so the design matches the title color + tint = MaterialTheme.theme.colors.primaryText01, ) - Spacer(modifier = Modifier.height(2.dp)) + Column { + TextH40( + text = stringResource(LR.string.need_to_free_up_space), + fontWeight = FontWeight.Bold, + color = MaterialTheme.theme.colors.primaryText01, + ) - TextP50( - text = stringResource(LR.string.save_space_by_managing_downloaded_episodes, formattedTotalDownloadSize), - color = MaterialTheme.theme.colors.primaryText02, - ) + Spacer(modifier = Modifier.height(2.dp)) + + TextP50( + text = stringResource(LR.string.save_space_by_managing_downloaded_episodes, formattedTotalDownloadSize), + color = MaterialTheme.theme.colors.primaryText02, + ) - TextButton(onClick = { onManageDownloadsClick.invoke() }, contentPadding = PaddingValues()) { - TextH50(text = stringResource(LR.string.manage_downloads), color = MaterialTheme.theme.colors.primaryIcon01) + TextButton(onClick = { onManageDownloadsClick.invoke() }, contentPadding = PaddingValues()) { + TextH50(text = stringResource(LR.string.manage_downloads), color = MaterialTheme.theme.colors.primaryIcon01) + } } } + + IconButton( + onClick = { onMoreOptionsClick.invoke() }, + modifier = Modifier.size(24.dp), + ) { + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = stringResource(LR.string.manage_download_more_options_content_description), + tint = MaterialTheme.theme.colors.primaryIcon02, + ) + } } } @@ -91,6 +106,6 @@ fun ManageDownloadsCardPreview( @PreviewParameter(ThemePreviewParameterProvider::class) themeType: Theme.ThemeType, ) { AppThemeWithBackground(themeType) { - ManageDownloadsCard(totalDownloadSize = 15023232, onManageDownloadsClick = {}) + ManageDownloadsCard(totalDownloadSize = 15023232, onManageDownloadsClick = {}, onMoreOptionsClick = {}) } } diff --git a/modules/services/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/AnalyticsEvent.kt b/modules/services/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/AnalyticsEvent.kt index ef722857a95..02d279149e9 100644 --- a/modules/services/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/AnalyticsEvent.kt +++ b/modules/services/analytics/src/main/java/au/com/shiftyjelly/pocketcasts/analytics/AnalyticsEvent.kt @@ -668,5 +668,7 @@ enum class AnalyticsEvent(val key: String) { FREE_UP_SPACE_BANNER_SHOWN("free_up_space_banner_shown"), FREE_UP_SPACE_MODAL_SHOWN("free_up_space_modal_shown"), FREE_UP_SPACE_MANAGE_DOWNLOADS_TAPPED("free_up_space_manage_downloads_tapped"), + FREE_UP_SPACE_MANAGE_DOWNLOADS_MORE_OPTIONS_TAPPED("free_up_space_manage_downloads_more_options_tapped"), + FREE_UP_SPACE_MANAGE_DOWNLOADS_MORE_OPTIONS_DISMISS_TAPPED("free_up_space_manage_downloads_more_options_dismiss_tapped"), FREE_UP_SPACE_MAYBE_LATER_TAPPED("free_up_space_maybe_later_tapped"), } diff --git a/modules/services/localization/src/main/res/values/strings.xml b/modules/services/localization/src/main/res/values/strings.xml index 4cd9ad4697e..9910f9bb72b 100644 --- a/modules/services/localization/src/main/res/values/strings.xml +++ b/modules/services/localization/src/main/res/values/strings.xml @@ -2264,6 +2264,8 @@ Save %1$s – by managing downloaded episodes. Manage downloads Maybe Later + Dismiss + Manage Download Banner More Options Up Next shuffle diff --git a/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/Settings.kt b/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/Settings.kt index 83c6e70481a..c53461ae673 100644 --- a/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/Settings.kt +++ b/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/Settings.kt @@ -74,6 +74,7 @@ interface Settings { const val SYNC_API_MODEL = "mobile" const val LAST_UPDATE_TIME = "LastUpdateTime" const val LAST_DISMISS_LOW_STORAGE_MODAL_TIME = "LastDismissLowStorageModalTime" + const val LAST_DISMISS_LOW_STORAGE_BANNER_TIME = "LastDismissLowStorageBannerTime" const val PREFERENCE_SKIP_FORWARD = "skipForward" const val PREFERENCE_SKIP_BACKWARD = "skipBack" const val PREFERENCE_STORAGE_CHOICE = "storageChoice" @@ -327,6 +328,9 @@ interface Settings { fun setDismissLowStorageModalTime(lastUpdateTime: Long) fun shouldShowLowStorageModalAfterSnooze(): Boolean + fun setDismissLowStorageBannerTime(lastUpdateTime: Long) + fun shouldShowLowStorageBannerAfterSnooze(): Boolean + val hideNotificationOnPause: UserSetting val streamingMode: UserSetting diff --git a/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/SettingsImpl.kt b/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/SettingsImpl.kt index 0f54d0fc431..a39ef1e2b3a 100644 --- a/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/SettingsImpl.kt +++ b/modules/services/preferences/src/main/java/au/com/shiftyjelly/pocketcasts/preferences/SettingsImpl.kt @@ -339,6 +339,22 @@ class SettingsImpl @Inject constructor( return timeSinceDismiss >= 7.days } + override fun setDismissLowStorageBannerTime(lastUpdateTime: Long) { + sharedPreferences.edit { + putLong(Settings.LAST_DISMISS_LOW_STORAGE_BANNER_TIME, lastUpdateTime) + } + } + + override fun shouldShowLowStorageBannerAfterSnooze(): Boolean { + val lastSnoozeTime = sharedPreferences.getLong(Settings.LAST_DISMISS_LOW_STORAGE_BANNER_TIME, 0) + + if (lastSnoozeTime == 0L) return true + + val timeSinceDismiss = (System.currentTimeMillis() - lastSnoozeTime).milliseconds + + return timeSinceDismiss >= 14.days + } + override fun getRefreshState(): RefreshState? { return refreshStateObservable.value }