Skip to content

[Playback Errors] Display special text for episode access issues#5195

Open
sztomek wants to merge 1 commit intomainfrom
feat/episode-access-error-message
Open

[Playback Errors] Display special text for episode access issues#5195
sztomek wants to merge 1 commit intomainfrom
feat/episode-access-error-message

Conversation

@sztomek
Copy link
Copy Markdown
Contributor

@sztomek sztomek commented Apr 6, 2026

Description

In case of 401 and 403 errors, we have decided to show the "This episode can't be played. Learn about possible causes" text.

comms: p1775075776708869/1774342537.838119-slack-C05RR9P9RAT

Testing Instructions

  1. Apply this patch
    patch-debug-as-prod.patch
  2. Build debug version
  3. Sign in with your prod credentials
  4. Follow test podcast
  5. Play episodes with 401 and 403
  6. Verify that the new text is shown on the error bar
  7. Play other episodes
  8. Verify that error text is unchanged

Screenshots or Screencast

Screenshot_20260406_140626

Checklist

  • If this is a user-facing change, I have added an entry in CHANGELOG.md
  • Ensure the linter passes (./gradlew spotlessApply to automatically apply formatting/linting)
  • I have considered whether it makes sense to add tests for my changes
  • All strings that need to be localized are in modules/services/localization/src/main/res/values/strings.xml
  • Any jetpack compose components I added or changed are covered by compose previews
  • I have updated (or requested that someone edit) the spreadsheet to reflect any new or changed analytics.

@sztomek sztomek added this to the 8.10 milestone Apr 6, 2026
@sztomek sztomek requested a review from a team as a code owner April 6, 2026 12:24
@sztomek sztomek requested review from geekygecko and removed request for a team April 6, 2026 12:24
@sztomek sztomek added [Type] Enhancement Improve an existing feature. [Area] Playback Episode playback issue labels Apr 6, 2026
Copilot AI review requested due to automatic review settings April 6, 2026 12:24
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the playback error notice pipeline to show a distinct message (and a “learn more”-style link label) specifically for episode access issues (HTTP 401/403), and passes that link label through to the Compose info bar UI.

Changes:

  • Add linkText to PlaybackNoticeInfo and propagate it through mini-player/full-player error bars.
  • Update access-denied string copy and add a new action/link-label string resource.
  • Render message + link-label with different styling in PlaybackErrorInfoBar.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
modules/services/repositories/.../PlaybackNoticeManager.kt Sets special message/linkText for 401/403 playback issues.
modules/services/repositories/.../PlaybackErrorClassifier.kt Adds helper to classify link text resource for HTTP codes.
modules/services/localization/.../strings.xml Updates access-denied copy and adds link/action label string.
modules/services/compose/.../PlaybackErrorInfoBar.kt Adds linkText param and renders styled link text in the info bar.
modules/features/player/.../PlayerHeaderFragment.kt Passes linkText into the full-player error bar.
app/src/main/java/.../MainActivity.kt Passes linkText into the mini-player error bar.

Comment on lines +59 to 66
fun classifyLinkTextResId(responseCode: Int): Int? {
return when (responseCode) {
401, 403 -> LR.string.error_streaming_access_denied_action
else -> null
}
}

@StringRes
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

classifyLinkTextResId() is currently unused in the codebase, which adds dead code and duplicates the access-denied mapping already handled elsewhere. Either remove it, or wire it into PlaybackNoticeManager/UI creation so the link-text mapping lives in one place; if kept, add unit coverage alongside the existing PlaybackErrorClassificationTest cases for 401/403.

Suggested change
fun classifyLinkTextResId(responseCode: Int): Int? {
return when (responseCode) {
401, 403 -> LR.string.error_streaming_access_denied_action
else -> null
}
}
@StringRes

Copilot uses AI. Check for mistakes.
Comment on lines 126 to 135
val httpCode = (playbackState.playbackIssue as? PlaybackIssue.HttpError)?.statusCode
val isAccessDenied = httpCode == 401 || httpCode == 403
PlaybackNoticeInfo(
message = context.getString(LR.string.error_episode_not_available),
message = context.getString(
if (isAccessDenied) LR.string.error_streaming_access_denied else LR.string.error_episode_not_available,
),
type = PlaybackNoticeType.PLAYBACK,
supportUrl = errorClassifier.classifyHelpUrl(httpCode),
linkText = if (isAccessDenied) context.getString(LR.string.error_streaming_access_denied_action) else null,
)
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

This introduces a second 401/403 classification path (isAccessDenied + inline string lookups) in addition to PlaybackErrorClassifier. Consider delegating both the message and the optional link text to the classifier (e.g., via resource IDs) to avoid future divergence and keep HTTP-code mapping centralized.

Copilot uses AI. Check for mistakes.
Comment on lines +123 to +139
if (linkText != null) {
val annotatedString = buildAnnotatedString {
append("$message ")
withStyle(SpanStyle(color = linkColor, textDecoration = TextDecoration.Underline)) {
append(linkText)
}
}
Text(
text = annotatedString,
color = color,
fontSize = 14.sp,
lineHeight = 20.sp,
fontWeight = FontWeight.W500,
textAlign = TextAlign.Center,
maxLines = Int.MAX_VALUE,
overflow = TextOverflow.Ellipsis,
modifier = modifier,
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

In the linkText != null branch, Text uses regular sp sizing (so it will scale with system font size) while the non-link branch uses TextH50(disableAutoScale = true). With the fixed 48.dp bar height, larger font scales can cause clipping/truncation. Align the linked-text styling with the non-scaled typography (e.g., using nonScaledSp for fontSize/lineHeight) and set a realistic maxLines (or relax the fixed height) so overflow is handled predictably.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Area] Playback Episode playback issue [Type] Enhancement Improve an existing feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants