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

End of Year: Add retry action #597

Merged
merged 1 commit into from
Nov 21, 2022
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class StoriesFragment : BaseAppCompatDialogFragment() {
analyticsTracker.track(AnalyticsEvent.END_OF_YEAR_STORIES_DISMISSED, AnalyticsProp.StoriesDismissed.closeButton)
dismiss()
},
onRetryClicked = {
viewModel.onRetryClicked()
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Icon
Expand All @@ -43,6 +44,7 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.DpSize
Expand All @@ -51,7 +53,8 @@ import androidx.core.app.ShareCompat
import au.com.shiftyjelly.pocketcasts.compose.AppTheme
import au.com.shiftyjelly.pocketcasts.compose.bars.NavigationButton
import au.com.shiftyjelly.pocketcasts.compose.buttons.RowOutlinedButton
import au.com.shiftyjelly.pocketcasts.compose.components.TextP50
import au.com.shiftyjelly.pocketcasts.compose.components.TextH30
import au.com.shiftyjelly.pocketcasts.compose.components.TextP40
import au.com.shiftyjelly.pocketcasts.compose.preview.ThemePreviewParameterProvider
import au.com.shiftyjelly.pocketcasts.endofyear.ShareableTextProvider.ShareTextData
import au.com.shiftyjelly.pocketcasts.endofyear.StoriesViewModel.State
Expand Down Expand Up @@ -100,6 +103,7 @@ fun StoriesPage(
modifier: Modifier = Modifier,
viewModel: StoriesViewModel,
onCloseClicked: () -> Unit,
onRetryClicked: () -> Unit,
) {
val shareLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.StartActivityForResult()
Expand Down Expand Up @@ -148,7 +152,7 @@ fun StoriesPage(
)
State.Error -> {
viewModel.trackStoryFailedToLoad()
StoriesErrorView(onCloseClicked)
StoriesErrorView(onCloseClicked, onRetryClicked)
}
}
}
Expand Down Expand Up @@ -318,14 +322,35 @@ private fun StoriesLoadingView(
@Composable
private fun StoriesErrorView(
onCloseClicked: () -> Unit,
onRetryClicked: () -> Unit,
modifier: Modifier = Modifier,
) {
StoriesEmptyView(
content = {
TextP50(
text = stringResource(id = LR.string.end_of_year_stories_failed),
color = Color.White,
)
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
TextH30(
text = stringResource(id = LR.string.end_of_year_stories_failed),
textAlign = TextAlign.Center,
color = Color.White,
modifier = modifier.padding(horizontal = 40.dp)
)
Button(
onClick = { onRetryClicked.invoke() },
shape = RoundedCornerShape(20.dp),
colors = ButtonDefaults
.buttonColors(
backgroundColor = Color.White,
),
modifier = modifier.padding(top = 20.dp),
) {
TextP40(
text = stringResource(id = LR.string.retry),
color = Color.Black,
)
}
}
},
onCloseClicked = onCloseClicked,
modifier = modifier
Expand Down Expand Up @@ -508,7 +533,8 @@ private fun StoriesErrorViewPreview(
) {
AppTheme(themeType) {
StoriesErrorView(
onCloseClicked = {}
onCloseClicked = {},
onRetryClicked = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ class StoriesViewModel @Inject constructor(
private val mutableProgress = MutableStateFlow(0f)
val progress: StateFlow<Float> = mutableProgress

private val stories = mutableListOf<Story>()
private val stories = MutableStateFlow(emptyList<Story>())
private val numOfStories: Int
get() = stories.size
get() = stories.value.size

private var currentIndex: Int = 0
private val nextIndex
get() = (currentIndex.plus(1)).coerceAtMost(numOfStories.minus(1))
private val totalLengthInMs
get() = storyLengthsInMs.sum() + gapLengthsInMs
private val storyLengthsInMs: List<Long>
get() = stories.map { it.storyLength }
get() = stories.value.map { it.storyLength }
private val gapLengthsInMs: Long
get() = STORY_GAP_LENGTH_MS * numOfStories.minus(1).coerceAtLeast(0)

Expand All @@ -67,12 +67,12 @@ class StoriesViewModel @Inject constructor(
mutableState.value = State.Loading(progress)
}
endOfYearManager.downloadListeningHistory(onProgressChanged = onProgressChanged)
stories.addAll(endOfYearManager.loadStories())
val state = if (stories.isEmpty()) {
stories.value = endOfYearManager.loadStories()
val state = if (stories.value.isEmpty()) {
State.Error
} else {
State.Loaded(
currentStory = stories[currentIndex],
currentStory = stories.value[currentIndex],
segmentsData = SegmentsData(
xStartOffsets = List(numOfStories) { getXStartOffsetAtIndex(it) },
widths = storyLengthsInMs.map { it / totalLengthInMs.toFloat() },
Expand Down Expand Up @@ -104,7 +104,7 @@ class StoriesViewModel @Inject constructor(
if (newProgress.roundOff() == getXStartOffsetAtIndex(nextIndex).roundOff()) {
currentIndex = nextIndex
mutableState.value =
currentState.copy(currentStory = stories[currentIndex])
currentState.copy(currentStory = stories.value[currentIndex])
}

mutableProgress.value = newProgress
Expand Down Expand Up @@ -135,7 +135,13 @@ class StoriesViewModel @Inject constructor(
if (timer == null) start()
mutableProgress.value = getXStartOffsetAtIndex(index)
currentIndex = index
mutableState.value = (state.value as State.Loaded).copy(currentStory = stories[index])
mutableState.value = (state.value as State.Loaded).copy(currentStory = stories.value[index])
}

fun onRetryClicked() {
viewModelScope.launch {
loadStories()
}
}

fun onShareClicked(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1451,7 +1451,7 @@
<!-- Description to why the user needs to create an account to see their end of year stats. -->
<string name="end_of_year_create_account_to_see">Save your podcasts in the cloud, get your end of year review and sync your progress with other devices.</string>
<!-- When loading the End of Year stats stories fails. -->
<string name="end_of_year_stories_failed">Failed to load stories.</string>
<string name="end_of_year_stories_failed">Unable to load your end of year stories, check your internet connection.</string>

<!-- Onboarding -->

Expand Down