Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable Private Feed Sharing #3395

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* Updates
* Add the ability to dismiss the low storage banner in download screen
([#3385](https://github.com/Automattic/pocket-casts-android/pull/3385))
* Disable Private Feed Sharing
([#3395](https://github.com/Automattic/pocket-casts-android/pull/3395))

7.79
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class AppDatabaseTest {
// 102 to 103 added via auto migration
AppDatabase.MIGRATION_103_104,
AppDatabase.MIGRATION_104_105,
AppDatabase.MIGRATION_105_106,
)
.build()
// close the database and release any stream resources when the test finishes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ class PlayerHeaderFragment : BaseFragment(), PlayerClickListener {
SnackbarMessage.EpisodeDownloadStarted -> LR.string.episode_queued_for_download
SnackbarMessage.EpisodeRemoved -> LR.string.episode_was_removed
SnackbarMessage.TranscriptNotAvailable -> LR.string.transcript_error_not_available
SnackbarMessage.ShareNotAvailable -> LR.string.sharing_is_not_available_for_private_podcasts
}
showSnackBar(text = getString(text))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,12 @@ fun PlayerShelf(
onShareClick = {
val podcast = playerViewModel.podcast ?: return@PlayerShelfContent
val episode = playerViewModel.episode as? PodcastEpisode ?: return@PlayerShelfContent
shelfSharedViewModel.onShareClick(podcast, episode, ShelfItemSource.Shelf)

if (podcast.canShare) {
shelfSharedViewModel.onShareClick(podcast, episode, ShelfItemSource.Shelf)
} else {
shelfSharedViewModel.onShareNotAvailable(ShelfItemSource.Shelf)
}
},
onShowPodcast = {
shelfSharedViewModel.onShowPodcastOrCloudFiles(playerViewModel.podcast, ShelfItemSource.Shelf)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ fun ShelfBottomSheetPage(
ShelfItem.Share -> {
val podcast = playerViewModel.podcast ?: return@MenuShelfItems
val episode = playerViewModel.episode as? PodcastEpisode ?: return@MenuShelfItems
shelfSharedViewModel.onShareClick(podcast, episode, ShelfItemSource.OverflowMenu)

if (podcast.canShare) {
shelfSharedViewModel.onShareClick(podcast, episode, ShelfItemSource.OverflowMenu)
} else {
shelfSharedViewModel.onShareNotAvailable(ShelfItemSource.OverflowMenu)
}
}

ShelfItem.Podcast -> shelfSharedViewModel.onShowPodcastOrCloudFiles(playerViewModel.podcast, ShelfItemSource.OverflowMenu)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ class ShelfSharedViewModel @Inject constructor(
}
}

fun onShareNotAvailable(source: ShelfItemSource) {
trackShelfAction(ShelfItem.Share, source)
viewModelScope.launch {
_snackbarMessages.emit(SnackbarMessage.ShareNotAvailable)
}
}

fun onEpisodeRemoveClick(source: ShelfItemSource) {
trackShelfAction(ShelfItem.Download, source)
viewModelScope.launch {
Expand Down Expand Up @@ -365,6 +372,7 @@ class ShelfSharedViewModel @Inject constructor(
data object EpisodeDownloadStarted : SnackbarMessage
data object EpisodeRemoved : SnackbarMessage
data object TranscriptNotAvailable : SnackbarMessage
data object ShareNotAvailable : SnackbarMessage
}

sealed class TransitionState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import au.com.shiftyjelly.pocketcasts.views.helper.UiUtil
import au.com.shiftyjelly.pocketcasts.views.multiselect.MultiSelectBookmarksHelper.NavigationState
import au.com.shiftyjelly.pocketcasts.views.multiselect.MultiSelectHelper
import au.com.shiftyjelly.pocketcasts.views.multiselect.MultiSelectToolbar
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
Expand Down Expand Up @@ -977,7 +978,16 @@ class PodcastFragment : BaseFragment(), Toolbar.OnMenuItemClickListener {

private fun share() {
val podcast = viewModel.podcast.value ?: return

analyticsTracker.track(AnalyticsEvent.PODCAST_SCREEN_SHARE_TAPPED)

if (!podcast.canShare) {
(activity as? FragmentHostListener)?.snackBarView()?.let { snackBarView ->
Snackbar.make(snackBarView, getString(LR.string.sharing_is_not_available_for_private_podcasts), Snackbar.LENGTH_LONG).show()
}
return
}

if (FeatureFlag.isEnabled(Feature.REIMAGINE_SHARING)) {
SharePodcastFragment
.newInstance(podcast, SourceView.PODCAST_SCREEN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class ShareListCreateViewModel @Inject constructor(
init {
viewModelScope.launch {
val podcasts = podcastManager.findPodcastsOrderByTitle()
mutableState.value = mutableState.value.copy(podcasts = podcasts)
mutableState.value = mutableState.value.copy(podcasts = podcasts.filter { it.canShare })
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to exclude private ones from this list. See: pdeCcb-7Yf-p2#comment-6356

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
<string name="error">Error</string>
<string name="error_generic_message">Something went wrong. Please try again later.</string>
<string name="are_you_sure">Are you sure?</string>
<string name="sharing_is_not_available_for_private_podcasts">Sharing is not available for private podcasts</string>
<string name="back">Back</string>
<string name="retry">Retry</string>
<string name="queue_for_later">Queue for later</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 105,
"identityHash": "5081aaece3489e97782187c7cb1ab7e4",
"identityHash": "10131517fd9b7d158e054ece972adb8f",
"entities": [
{
"tableName": "bump_stats",
Expand Down Expand Up @@ -696,7 +696,7 @@
},
{
"tableName": "podcasts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uuid` TEXT NOT NULL, `added_date` INTEGER, `thumbnail_url` TEXT, `title` TEXT NOT NULL, `podcast_url` TEXT, `podcast_description` TEXT NOT NULL, `podcast_html_description` TEXT NOT NULL, `podcast_category` TEXT NOT NULL, `podcast_language` TEXT NOT NULL, `media_type` TEXT, `latest_episode_uuid` TEXT, `author` TEXT NOT NULL, `sort_order` INTEGER NOT NULL, `episodes_sort_order` INTEGER NOT NULL, `episodes_sort_order_modified` INTEGER, `latest_episode_date` INTEGER, `episodes_to_keep` INTEGER NOT NULL, `override_global_settings` INTEGER NOT NULL, `override_global_effects` INTEGER NOT NULL, `override_global_effects_modified` INTEGER, `start_from` INTEGER NOT NULL, `start_from_modified` INTEGER, `playback_speed` REAL NOT NULL, `playback_speed_modified` INTEGER, `volume_boosted` INTEGER NOT NULL, `volume_boosted_modified` INTEGER, `is_folder` INTEGER NOT NULL, `subscribed` INTEGER NOT NULL, `show_notifications` INTEGER NOT NULL, `show_notifications_modified` INTEGER, `auto_download_status` INTEGER NOT NULL, `auto_add_to_up_next` INTEGER NOT NULL, `auto_add_to_up_next_modified` INTEGER, `most_popular_color` INTEGER NOT NULL, `primary_color` INTEGER NOT NULL, `secondary_color` INTEGER NOT NULL, `light_overlay_color` INTEGER NOT NULL, `fab_for_light_bg` INTEGER NOT NULL, `link_for_dark_bg` INTEGER NOT NULL, `link_for_light_bg` INTEGER NOT NULL, `color_version` INTEGER NOT NULL, `color_last_downloaded` INTEGER NOT NULL, `sync_status` INTEGER NOT NULL, `exclude_from_auto_archive` INTEGER NOT NULL, `override_global_archive` INTEGER NOT NULL, `override_global_archive_modified` INTEGER, `auto_archive_played_after` INTEGER NOT NULL, `auto_archive_played_after_modified` INTEGER, `auto_archive_inactive_after` INTEGER NOT NULL, `auto_archive_inactive_after_modified` INTEGER, `auto_archive_episode_limit` INTEGER NOT NULL, `auto_archive_episode_limit_modified` INTEGER, `estimated_next_episode` INTEGER, `episode_frequency` TEXT, `grouping` INTEGER NOT NULL, `grouping_modified` INTEGER, `skip_last` INTEGER NOT NULL, `skip_last_modified` INTEGER, `show_archived` INTEGER NOT NULL, `show_archived_modified` INTEGER, `trim_silence_level` INTEGER NOT NULL, `trim_silence_level_modified` INTEGER, `refresh_available` INTEGER NOT NULL, `folder_uuid` TEXT, `licensing` INTEGER NOT NULL, `isPaid` INTEGER NOT NULL, `bundleuuid` TEXT, `bundlebundleUrl` TEXT, `bundlepaymentUrl` TEXT, `bundledescription` TEXT, `bundlepodcastUuid` TEXT, `bundlepaidType` TEXT, PRIMARY KEY(`uuid`))",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uuid` TEXT NOT NULL, `added_date` INTEGER, `thumbnail_url` TEXT, `title` TEXT NOT NULL, `podcast_url` TEXT, `podcast_description` TEXT NOT NULL, `podcast_html_description` TEXT NOT NULL, `podcast_category` TEXT NOT NULL, `podcast_language` TEXT NOT NULL, `media_type` TEXT, `latest_episode_uuid` TEXT, `author` TEXT NOT NULL, `sort_order` INTEGER NOT NULL, `episodes_sort_order` INTEGER NOT NULL, `episodes_sort_order_modified` INTEGER, `latest_episode_date` INTEGER, `episodes_to_keep` INTEGER NOT NULL, `override_global_settings` INTEGER NOT NULL, `override_global_effects` INTEGER NOT NULL, `override_global_effects_modified` INTEGER, `start_from` INTEGER NOT NULL, `start_from_modified` INTEGER, `playback_speed` REAL NOT NULL, `playback_speed_modified` INTEGER, `volume_boosted` INTEGER NOT NULL, `volume_boosted_modified` INTEGER, `is_folder` INTEGER NOT NULL, `subscribed` INTEGER NOT NULL, `show_notifications` INTEGER NOT NULL, `show_notifications_modified` INTEGER, `auto_download_status` INTEGER NOT NULL, `auto_add_to_up_next` INTEGER NOT NULL, `auto_add_to_up_next_modified` INTEGER, `most_popular_color` INTEGER NOT NULL, `primary_color` INTEGER NOT NULL, `secondary_color` INTEGER NOT NULL, `light_overlay_color` INTEGER NOT NULL, `fab_for_light_bg` INTEGER NOT NULL, `link_for_dark_bg` INTEGER NOT NULL, `link_for_light_bg` INTEGER NOT NULL, `color_version` INTEGER NOT NULL, `color_last_downloaded` INTEGER NOT NULL, `sync_status` INTEGER NOT NULL, `exclude_from_auto_archive` INTEGER NOT NULL, `override_global_archive` INTEGER NOT NULL, `override_global_archive_modified` INTEGER, `auto_archive_played_after` INTEGER NOT NULL, `auto_archive_played_after_modified` INTEGER, `auto_archive_inactive_after` INTEGER NOT NULL, `auto_archive_inactive_after_modified` INTEGER, `auto_archive_episode_limit` INTEGER NOT NULL, `auto_archive_episode_limit_modified` INTEGER, `estimated_next_episode` INTEGER, `episode_frequency` TEXT, `grouping` INTEGER NOT NULL, `grouping_modified` INTEGER, `skip_last` INTEGER NOT NULL, `skip_last_modified` INTEGER, `show_archived` INTEGER NOT NULL, `show_archived_modified` INTEGER, `trim_silence_level` INTEGER NOT NULL, `trim_silence_level_modified` INTEGER, `refresh_available` INTEGER NOT NULL, `folder_uuid` TEXT, `licensing` INTEGER NOT NULL, `isPaid` INTEGER NOT NULL, `is_private` INTEGER NOT NULL, `bundleuuid` TEXT, `bundlebundleUrl` TEXT, `bundlepaymentUrl` TEXT, `bundledescription` TEXT, `bundlepodcastUuid` TEXT, `bundlepaidType` TEXT, PRIMARY KEY(`uuid`))",
"fields": [
{
"fieldPath": "uuid",
Expand Down Expand Up @@ -1094,6 +1094,12 @@
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "isPrivate",
"columnName": "is_private",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "singleBundle.uuid",
"columnName": "bundleuuid",
Expand Down Expand Up @@ -1859,7 +1865,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5081aaece3489e97782187c7cb1ab7e4')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '10131517fd9b7d158e054ece972adb8f')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,10 @@ abstract class AppDatabase : RoomDatabase() {
database.execSQL("ALTER TABLE podcasts ADD COLUMN podcast_html_description TEXT NOT NULL DEFAULT ''")
}

val MIGRATION_105_106 = addMigration(105, 106) { database ->
database.execSQL("ALTER TABLE podcasts ADD COLUMN is_private INTEGER NOT NULL DEFAULT 0")
}

fun addMigrations(databaseBuilder: Builder<AppDatabase>, context: Context) {
databaseBuilder.addMigrations(
addMigration(1, 2) { },
Expand Down Expand Up @@ -1271,6 +1275,7 @@ abstract class AppDatabase : RoomDatabase() {
// 102 to 103 added via auto migration
MIGRATION_103_104,
MIGRATION_104_105,
MIGRATION_105_106,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import au.com.shiftyjelly.pocketcasts.models.to.PlaybackEffects
import au.com.shiftyjelly.pocketcasts.models.to.PodcastGrouping
import au.com.shiftyjelly.pocketcasts.models.type.EpisodesSortType
import au.com.shiftyjelly.pocketcasts.models.type.TrimMode
import au.com.shiftyjelly.pocketcasts.utils.featureflag.Feature
import au.com.shiftyjelly.pocketcasts.utils.featureflag.FeatureFlag
import java.io.Serializable
import java.net.MalformedURLException
import java.net.URL
Expand Down Expand Up @@ -115,6 +117,7 @@ data class Podcast(
@ColumnInfo(name = "folder_uuid") internal var rawFolderUuid: String? = null,
@ColumnInfo(name = "licensing") var licensing: Licensing = Licensing.KEEP_EPISODES,
@ColumnInfo(name = "isPaid") var isPaid: Boolean = false,
@ColumnInfo(name = "is_private") var isPrivate: Boolean = false,
@Embedded(prefix = "bundle") var singleBundle: Bundle? = null,
@Ignore val episodes: MutableList<PodcastEpisode> = mutableListOf(),
) : Serializable {
Expand Down Expand Up @@ -171,6 +174,9 @@ data class Podcast(
val isSilenceRemoved: Boolean
get() = trimMode != TrimMode.OFF

val canShare: Boolean
get() = !FeatureFlag.isEnabled(Feature.SHARE_PODCAST_PRIVATE_NOT_AVAILABLE) || !isPrivate

val isUsingEffects: Boolean
get() = overrideGlobalEffects && (isSilenceRemoved || isVolumeBoosted || playbackSpeed != 1.0)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ data class PodcastInfo(
@field:Json(name = "category") val category: String?,
@field:Json(name = "audio") val audio: Boolean?,
@field:Json(name = "episodes") val episodes: List<EpisodeInfo>?,
@field:Json(name = "is_private") val isPrivate: Boolean?,
) {

fun toPodcast(): Podcast {
Expand All @@ -63,6 +64,7 @@ data class PodcastInfo(
episodes?.mapNotNull { it.toEpisode(uuid) }?.let { episodes ->
podcast.episodes.addAll(episodes)
}
podcast.isPrivate = isPrivate ?: false
return podcast
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ enum class Feature(
hasFirebaseRemoteFlag = true,
hasDevToggle = true,
),
SHARE_PODCAST_PRIVATE_NOT_AVAILABLE(
key = "share_podcast_private_not_available",
title = "Sharing is not available for private podcasts",
defaultValue = BuildConfig.DEBUG,
tier = FeatureTier.Free,
hasFirebaseRemoteFlag = false,
hasDevToggle = true,
),
;

companion object {
Expand Down