Skip to content

Commit

Permalink
Add report violation option (#1723)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashiagr authored Jan 22, 2024
1 parent 8600639 commit 6d3b280
Show file tree
Hide file tree
Showing 18 changed files with 114 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import au.com.shiftyjelly.pocketcasts.repositories.playback.PlaybackManager
import au.com.shiftyjelly.pocketcasts.settings.onboarding.OnboardingFlow
import au.com.shiftyjelly.pocketcasts.settings.onboarding.OnboardingLauncher
import au.com.shiftyjelly.pocketcasts.settings.onboarding.OnboardingUpgradeSource
import au.com.shiftyjelly.pocketcasts.ui.extensions.openUrl
import au.com.shiftyjelly.pocketcasts.ui.helper.FragmentHostListener
import au.com.shiftyjelly.pocketcasts.ui.images.PodcastImageLoaderThemed
import au.com.shiftyjelly.pocketcasts.ui.images.ThemedImageTintTransformation
Expand Down Expand Up @@ -155,6 +156,7 @@ class PlayerHeaderFragment : BaseFragment(), PlayerClickListener {
ShelfItem.Archive.id to binding.archive,
ShelfItem.Download.id to binding.download,
ShelfItem.Bookmark.id to binding.bookmark,
ShelfItem.Report.id to binding.report,
)
viewModel.trimmedShelfLive.observe(viewLifecycleOwner) {
val visibleItems = it.first.subList(0, 4).map { it.id }
Expand Down Expand Up @@ -190,6 +192,10 @@ class PlayerHeaderFragment : BaseFragment(), PlayerClickListener {
trackShelfAction(ShelfItem.Bookmark.analyticsValue)
onAddBookmarkClick(OnboardingUpgradeSource.BOOKMARKS_SHELF_ACTION)
}
binding.report?.setOnClickListener {
trackShelfAction(ShelfItem.Report.analyticsValue)
openUrl(settings.getReportViolationUrl())
}
binding.videoView.playbackManager = playbackManager
binding.videoView.setOnClickListener { onFullScreenVideoClick() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import au.com.shiftyjelly.pocketcasts.analytics.SourceView
import au.com.shiftyjelly.pocketcasts.player.databinding.FragmentShelfBottomSheetBinding
import au.com.shiftyjelly.pocketcasts.player.view.ShelfFragment.Companion.AnalyticsProp
import au.com.shiftyjelly.pocketcasts.player.viewmodel.PlayerViewModel
import au.com.shiftyjelly.pocketcasts.preferences.Settings
import au.com.shiftyjelly.pocketcasts.repositories.chromecast.CastManager
import au.com.shiftyjelly.pocketcasts.repositories.chromecast.ChromeCastAnalytics
import au.com.shiftyjelly.pocketcasts.repositories.playback.PlaybackManager
import au.com.shiftyjelly.pocketcasts.settings.onboarding.OnboardingUpgradeSource
import au.com.shiftyjelly.pocketcasts.ui.R
import au.com.shiftyjelly.pocketcasts.ui.extensions.getThemeColor
import au.com.shiftyjelly.pocketcasts.ui.extensions.openUrl
import au.com.shiftyjelly.pocketcasts.ui.helper.FragmentHostListener
import au.com.shiftyjelly.pocketcasts.ui.helper.StatusBarColor
import au.com.shiftyjelly.pocketcasts.views.extensions.applyColor
Expand All @@ -42,6 +44,8 @@ class ShelfBottomSheet : BaseDialogFragment() {

@Inject lateinit var playbackManager: PlaybackManager

@Inject lateinit var settings: Settings

override val statusBarColor: StatusBarColor? = null

private val playerViewModel: PlayerViewModel by activityViewModels()
Expand Down Expand Up @@ -172,6 +176,9 @@ class ShelfBottomSheet : BaseDialogFragment() {
ShelfItem.Download -> {
Timber.e("Unexpected click on ShelfItem.Download")
}
is ShelfItem.Report -> {
openUrl(settings.getReportViolationUrl())
}
}
analyticsTracker.track(
AnalyticsEvent.PLAYER_SHELF_ACTION_TAPPED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import au.com.shiftyjelly.pocketcasts.models.entity.UserEpisode
import au.com.shiftyjelly.pocketcasts.models.type.EpisodeStatusEnum
import au.com.shiftyjelly.pocketcasts.models.type.SubscriptionTier
import au.com.shiftyjelly.pocketcasts.player.R
import au.com.shiftyjelly.pocketcasts.utils.featureflag.Feature
import au.com.shiftyjelly.pocketcasts.utils.featureflag.FeatureFlag
import au.com.shiftyjelly.pocketcasts.images.R as IR
import au.com.shiftyjelly.pocketcasts.localization.R as LR
import au.com.shiftyjelly.pocketcasts.views.R as VR
Expand All @@ -22,6 +24,9 @@ object ShelfItems {
add(ShelfItem.Played)
add(ShelfItem.Bookmark)
add(ShelfItem.Archive)
if (FeatureFlag.isEnabled(Feature.REPORT_VIOLATION)) {
add(ShelfItem.Report)
}
}
private val items = itemsList.associateBy { it.id }

Expand Down Expand Up @@ -145,4 +150,13 @@ sealed class ShelfItem(
tier = SubscriptionTier.NONE,
analyticsValue = "download",
)

object Report : ShelfItem(
id = "report",
title = { LR.string.report },
subtitle = LR.string.report_subtitle,
iconRes = { IR.drawable.ic_flag },
shownWhen = Shown.Always,
analyticsValue = "report",
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import au.com.shiftyjelly.pocketcasts.repositories.podcast.UserEpisodeManager
import au.com.shiftyjelly.pocketcasts.repositories.user.UserManager
import au.com.shiftyjelly.pocketcasts.ui.theme.Theme
import au.com.shiftyjelly.pocketcasts.utils.Util
import au.com.shiftyjelly.pocketcasts.utils.featureflag.Feature
import au.com.shiftyjelly.pocketcasts.utils.featureflag.FeatureFlag
import au.com.shiftyjelly.pocketcasts.utils.log.LogBuffer
import au.com.shiftyjelly.pocketcasts.views.dialog.ConfirmationDialog
import au.com.shiftyjelly.pocketcasts.views.helper.CloudDeleteHelper
Expand Down Expand Up @@ -202,15 +204,19 @@ class PlayerViewModel @Inject constructor(
if (list.isEmpty()) {
ShelfItems.itemsList
} else {
// Add missing bookmark item if the feature flag is enabled
val updatedList = when {
list.contains(ShelfItem.Bookmark.id) -> list
else -> {
!list.contains(ShelfItem.Bookmark.id) -> {
list.toMutableList().apply {
add(list.size - 1, ShelfItem.Bookmark.id)
}
}
FeatureFlag.isEnabled(Feature.REPORT_VIOLATION) &&
!list.contains(ShelfItem.Report.id) -> {
list.toMutableList().apply { add(ShelfItem.Bookmark.id) }
}
else -> list
}

updatedList.mapNotNull { id ->
ShelfItems.itemForId(id)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,13 @@
app:tint="?attr/player_contrast_03"
style="@style/shelf_item" />

<ImageButton
android:id="@+id/report"
android:contentDescription="@string/report"
app:srcCompat="@drawable/ic_flag"
app:tint="?attr/player_contrast_03"
style="@style/shelf_item" />

<ImageButton
android:id="@+id/playerActions"
android:layout_width="0dp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@ import au.com.shiftyjelly.pocketcasts.servers.ServerManager
import au.com.shiftyjelly.pocketcasts.settings.HeadphoneControlsSettingsFragment
import au.com.shiftyjelly.pocketcasts.settings.SettingsFragment
import au.com.shiftyjelly.pocketcasts.ui.extensions.getThemeColor
import au.com.shiftyjelly.pocketcasts.ui.extensions.openUrl
import au.com.shiftyjelly.pocketcasts.ui.helper.FragmentHostListener
import au.com.shiftyjelly.pocketcasts.ui.helper.StatusBarColor
import au.com.shiftyjelly.pocketcasts.ui.images.CoilManager
import au.com.shiftyjelly.pocketcasts.ui.theme.ThemeColor
import au.com.shiftyjelly.pocketcasts.utils.extensions.dpToPx
import au.com.shiftyjelly.pocketcasts.utils.featureflag.Feature
import au.com.shiftyjelly.pocketcasts.utils.featureflag.FeatureFlag
import au.com.shiftyjelly.pocketcasts.utils.log.LogBuffer
import au.com.shiftyjelly.pocketcasts.views.dialog.ConfirmationDialog
import au.com.shiftyjelly.pocketcasts.views.dialog.OptionsDialog
Expand Down Expand Up @@ -565,6 +568,10 @@ class PodcastFragment : BaseFragment(), Toolbar.OnMenuItemClickListener {
binding.toolbar.let {
it.inflateMenu(R.menu.podcast_menu)
it.setOnMenuItemClickListener(this)

val reportMenuItem = it.menu.findItem(R.id.report)
reportMenuItem.isVisible = FeatureFlag.isEnabled(Feature.REPORT_VIOLATION)

it.setNavigationOnClickListener {
@Suppress("DEPRECATION")
activity?.onBackPressed()
Expand Down Expand Up @@ -887,6 +894,10 @@ class PodcastFragment : BaseFragment(), Toolbar.OnMenuItemClickListener {
override fun onMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.share -> share()
R.id.report -> {
analyticsTracker.track(AnalyticsEvent.PODCAST_SCREEN_REPORT_TAPPED)
openUrl(settings.getReportViolationUrl())
}
}
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
android:minHeight="?android:attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:navigationIcon="@drawable/ic_arrow_back_24dp"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
app:popupTheme="@style/LightPopupTheme" />

<au.com.shiftyjelly.pocketcasts.views.multiselect.MultiSelectToolbar
android:id="@+id/multiSelectEpisodesToolbar"
Expand Down
6 changes: 6 additions & 0 deletions modules/features/podcasts/src/main/res/menu/podcast_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@
app:showAsAction="ifRoom"
android:title="@string/share_podcast" />

<item
android:id="@+id/report"
android:icon="@drawable/ic_flag"
app:showAsAction="never"
android:title="@string/report" />

</menu>
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ enum class AnalyticsEvent(val key: String) {
PODCASTS_SCREEN_SORT_ORDER_CHANGED("podcasts_screen_sort_order_changed"),
PODCASTS_SCREEN_EPISODE_GROUPING_CHANGED("podcasts_screen_episode_grouping_changed"),
PODCASTS_SCREEN_TAB_TAPPED("podcasts_screen_tab_tapped"),
PODCAST_SCREEN_REPORT_TAPPED("podcast_screen_report_tapped"),

/* Podcast Settings */
PODCAST_SETTINGS_FEED_ERROR_TAPPED("podcast_settings_feed_error_tapped"),
Expand Down
9 changes: 9 additions & 0 deletions modules/services/images/src/main/res/drawable/ic_flag.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M15,6a2,2 0,0 0,-2 -2H5v17h2v-7h5a2,2 0,0 0,2 2h6V6h-5z"/>
</vector>
2 changes: 2 additions & 0 deletions modules/services/localization/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@
<string name="go_to_top">Go to top</string>
<string name="go_to_bottom">Go to bottom</string>
<string name="submit">Submit</string>
<string name="report">Report</string>
<string name="report_subtitle">Report inappropriate content</string>
<string name="widget">Widget</string>

<string name="multiselect_actions_shown">Shortcut in toolbar</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ interface Settings {
fun getPeriodicSaveTimeMs(): Long
fun getPodcastSearchDebounceMs(): Long
fun getEpisodeSearchDebounceMs(): Long
fun getReportViolationUrl(): String
val podcastGroupingDefault: UserSetting<PodcastGrouping>

val marketingOptIn: UserSetting<Boolean>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,10 @@ class SettingsImpl @Inject constructor(
return getRemoteConfigLong(FirebaseConfig.EPISODE_SEARCH_DEBOUNCE_MS)
}

override fun getReportViolationUrl(): String {
return firebaseRemoteConfig.getString(FirebaseConfig.REPORT_VIOLATION_URL)
}

private fun getRemoteConfigLong(key: String): Long {
val value = firebaseRemoteConfig.getLong(key)
return if (value == 0L) (FirebaseConfig.defaults[key] as? Long ?: 0L) else value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package au.com.shiftyjelly.pocketcasts.ui.extensions

import android.content.Intent
import android.net.Uri
import androidx.fragment.app.Fragment
import timber.log.Timber

fun Fragment.openUrl(url: String) {
try {
this.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
} catch (e: Exception) {
Timber.e(e)
}
}
5 changes: 5 additions & 0 deletions modules/services/ui/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1880,4 +1880,9 @@
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>

<style name="LightPopupTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="android:backgroundTint">@android:color/white</item>
<item name="android:elevation">0dp</item>
</style>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ object FirebaseConfig {
const val PODCAST_SEARCH_DEBOUNCE_MS = "podcast_search_debounce_ms"
const val EPISODE_SEARCH_DEBOUNCE_MS = "episode_search_debounce_ms"
const val CLOUD_STORAGE_LIMIT = "custom_storage_limit_gb"
const val REPORT_VIOLATION_URL = "report_violation_url"
val defaults = mapOf(
PERIODIC_SAVE_TIME_MS to 60000L,
PODCAST_SEARCH_DEBOUNCE_MS to 2000L,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ enum class Feature(
hasFirebaseRemoteFlag = false,
hasDevToggle = true,
),
REPORT_VIOLATION(
key = "report_violation",
title = "Report Violation",
defaultValue = false,
tier = FeatureTier.Free,
hasFirebaseRemoteFlag = true,
hasDevToggle = false,
),
;

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package au.com.shiftyjelly.pocketcasts.utils.featureflag.providers

import au.com.shiftyjelly.pocketcasts.utils.config.FirebaseConfig
import au.com.shiftyjelly.pocketcasts.utils.featureflag.Feature
import au.com.shiftyjelly.pocketcasts.utils.featureflag.MAX_PRIORITY
import au.com.shiftyjelly.pocketcasts.utils.featureflag.RemoteFeatureProvider
Expand All @@ -12,8 +13,13 @@ class FirebaseRemoteFeatureProvider @Inject constructor(
) : RemoteFeatureProvider {
override val priority: Int = MAX_PRIORITY

override fun isEnabled(feature: Feature): Boolean =
firebaseRemoteConfig.getBoolean(feature.key)
override fun isEnabled(feature: Feature) = when (feature) {
Feature.REPORT_VIOLATION ->
firebaseRemoteConfig
.getString(FirebaseConfig.REPORT_VIOLATION_URL)
.isNotEmpty()
else -> firebaseRemoteConfig.getBoolean(feature.key)
}

override fun hasFeature(feature: Feature) =
feature.hasFirebaseRemoteFlag
Expand Down

0 comments on commit 6d3b280

Please sign in to comment.