Skip to content
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 @@ -9,9 +9,11 @@ import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -161,9 +163,11 @@ class ActivityTabFragment : Fragment() {
ActivityTabScreen(
isLoggedIn = AccountUtil.isLoggedIn && !AccountUtil.isTemporaryAccount,
userName = AccountUtil.userName,
languageCode = WikipediaApp.instance.wikiSite.languageCode,
modules = Prefs.activityTabModules,
haveAtLeastOneDonation = Prefs.donationResults.isNotEmpty(),
areGamesAvailable = OnThisDayGameViewModel.isLangSupported(WikipediaApp.instance.wikiSite.languageCode),
refreshSilently = viewModel.shouldRefreshTimelineSilently,
readingHistoryState = viewModel.readingHistoryState.collectAsState().value,
donationUiState = viewModel.donationUiState.collectAsState().value,
wikiGamesUiState = viewModel.wikiGamesUiState.collectAsState().value,
Expand Down Expand Up @@ -192,13 +196,15 @@ class ActivityTabFragment : Fragment() {
fun ActivityTabScreen(
isLoggedIn: Boolean,
userName: String,
languageCode: String,
modules: ActivityTabModules,
haveAtLeastOneDonation: Boolean,
areGamesAvailable: Boolean,
refreshSilently: Boolean,
readingHistoryState: UiState<ActivityTabViewModel.ReadingHistory>,
donationUiState: UiState<String?>,
wikiGamesUiState: UiState<OnThisDayGameViewModel.GameStatistics?>,
impactUiState: UiState<GrowthUserImpact>,
impactUiState: UiState<Pair<GrowthUserImpact, Int>>,
timelineFlow: Flow<PagingData<TimelineDisplayItem>>
) {
val timelineItems = timelineFlow.collectAsLazyPagingItems()
Expand Down Expand Up @@ -414,13 +420,34 @@ class ActivityTabFragment : Fragment() {
)
) {
if (modules.isModuleVisible(ModuleType.EDITING_INSIGHTS) || modules.isModuleVisible(ModuleType.IMPACT)) {
Text(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 24.dp),
text = stringResource(R.string.activity_tab_impact),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Medium,
color = WikipediaTheme.colors.primaryColor
)
Row(
modifier = Modifier.fillMaxWidth(),
) {
Text(
modifier = Modifier
.padding(start = 16.dp, end = 16.dp, top = 24.dp)
.weight(1f),
text = stringResource(R.string.activity_tab_impact),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Medium,
color = WikipediaTheme.colors.primaryColor
)
Box(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 24.dp)
.background(color = WikipediaTheme.colors.paperColor).border(
0.5.dp,
WikipediaTheme.colors.borderColor,
RoundedCornerShape(4.dp)
)
) {
Text(
modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp),
text = languageCode.uppercase(),
style = MaterialTheme.typography.bodyLarge,
color = WikipediaTheme.colors.primaryColor
)
}
}
}

if (modules.isModuleVisible(ModuleType.EDITING_INSIGHTS)) {
Expand Down Expand Up @@ -469,6 +496,9 @@ class ActivityTabFragment : Fragment() {
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 16.dp),
uiState = impactUiState,
onTotalEditsClick = {
startActivity(UserContribListActivity.newIntent(requireContext(), userName))
},
wikiErrorClickEvents = WikiErrorClickEvents(
retryClickListener = {
viewModel.loadImpact()
Expand Down Expand Up @@ -548,7 +578,7 @@ class ActivityTabFragment : Fragment() {
val isEmpty = timelineItems.itemCount == 0
when {
// Show loading for fresh navigation or explicit refresh, User came from tab navigation OR pulled to refresh
isRefreshing && !viewModel.shouldRefreshTimelineSilently -> {
isRefreshing && !refreshSilently -> {
item {
ActivityTabShimmerView()
}
Expand All @@ -557,7 +587,7 @@ class ActivityTabFragment : Fragment() {
// Show loading UI during silent refresh transition
// User clicked timeline item (shouldRefreshTimelineSilently = true) and returned,
// but timeline data is still loading/empty. Without this case, user would see empty state briefly before data loads instead of loading UI.
isEmpty && viewModel.shouldRefreshTimelineSilently -> {
isEmpty && refreshSilently -> {
item {
ActivityTabShimmerView()
}
Expand Down Expand Up @@ -630,9 +660,11 @@ class ActivityTabFragment : Fragment() {
ActivityTabScreen(
isLoggedIn = true,
userName = "User",
languageCode = "en",
modules = ActivityTabModules(isDonationsEnabled = true),
haveAtLeastOneDonation = true,
areGamesAvailable = true,
refreshSilently = false,
readingHistoryState = UiState.Success(ActivityTabViewModel.ReadingHistory(
timeSpentThisWeek = 12345,
articlesReadThisMonth = 123,
Expand All @@ -659,7 +691,7 @@ class ActivityTabFragment : Fragment() {
currentStreak = 15,
bestStreak = 25
)),
impactUiState = UiState.Success(GrowthUserImpact(totalEditsCount = 12345)),
impactUiState = UiState.Success(Pair(GrowthUserImpact(totalEditsCount = 12345), 123456)),
timelineFlow = emptyFlow()
)
}
Expand All @@ -672,9 +704,11 @@ class ActivityTabFragment : Fragment() {
ActivityTabScreen(
isLoggedIn = true,
userName = "User",
languageCode = "ru",
modules = ActivityTabModules(isDonationsEnabled = true),
haveAtLeastOneDonation = false,
areGamesAvailable = false,
refreshSilently = false,
readingHistoryState = UiState.Success(ActivityTabViewModel.ReadingHistory(
timeSpentThisWeek = 0,
articlesReadThisMonth = 0,
Expand All @@ -687,7 +721,7 @@ class ActivityTabFragment : Fragment() {
)),
donationUiState = UiState.Success("Unknown"),
wikiGamesUiState = UiState.Success(null),
impactUiState = UiState.Success(GrowthUserImpact()),
impactUiState = UiState.Success(Pair(GrowthUserImpact(), 0)),
timelineFlow = emptyFlow()
)
}
Expand All @@ -700,9 +734,11 @@ class ActivityTabFragment : Fragment() {
ActivityTabScreen(
isLoggedIn = false,
userName = "User",
languageCode = "he",
modules = ActivityTabModules(),
haveAtLeastOneDonation = false,
areGamesAvailable = false,
refreshSilently = false,
readingHistoryState = UiState.Success(ActivityTabViewModel.ReadingHistory(
timeSpentThisWeek = 0,
articlesReadThisMonth = 0,
Expand All @@ -715,7 +751,7 @@ class ActivityTabFragment : Fragment() {
)),
donationUiState = UiState.Success("Unknown"),
wikiGamesUiState = UiState.Success(null),
impactUiState = UiState.Success(GrowthUserImpact()),
impactUiState = UiState.Success(Pair(GrowthUserImpact(), 0)),
timelineFlow = emptyFlow()
)
}
Expand All @@ -728,6 +764,7 @@ class ActivityTabFragment : Fragment() {
ActivityTabScreen(
isLoggedIn = true,
userName = "User",
languageCode = "zh",
modules = ActivityTabModules(
isTimeSpentEnabled = false,
isReadingInsightsEnabled = false,
Expand All @@ -739,6 +776,7 @@ class ActivityTabFragment : Fragment() {
),
haveAtLeastOneDonation = true,
areGamesAvailable = true,
refreshSilently = false,
readingHistoryState = UiState.Success(ActivityTabViewModel.ReadingHistory(
timeSpentThisWeek = 0,
articlesReadThisMonth = 0,
Expand All @@ -751,8 +789,8 @@ class ActivityTabFragment : Fragment() {
)),
donationUiState = UiState.Success("Unknown"),
wikiGamesUiState = UiState.Success(null),
impactUiState = UiState.Success(GrowthUserImpact()),
timelineFlow = emptyFlow()
impactUiState = UiState.Success(Pair(GrowthUserImpact(), 0)),
timelineFlow = emptyFlow()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ class ActivityTabViewModel() : ViewModel() {
}
}

private val _impactUiState = MutableStateFlow<UiState<GrowthUserImpact>>(UiState.Loading)
val impactUiState: StateFlow<UiState<GrowthUserImpact>> = _impactUiState.asStateFlow()
private val _impactUiState = MutableStateFlow<UiState<Pair<GrowthUserImpact, Int>>>(UiState.Loading)
val impactUiState: StateFlow<UiState<Pair<GrowthUserImpact, Int>>> = _impactUiState.asStateFlow()

var shouldRefreshTimelineSilently: Boolean = false

Expand Down Expand Up @@ -225,10 +225,9 @@ class ActivityTabViewModel() : ViewModel() {
impact = JsonUtil.decodeFromString(impactResponse)!!
}

val pagesResponse = ServiceFactory.get(wikiSite).getInfoByPageIdsOrTitles(
val pagesResponse = ServiceFactory.get(wikiSite).getInfoByTitlesWithGlobalUserInfo(
titles = impact.topViewedArticles.keys.joinToString(separator = "|")
)

// Transform the response to a map of PageTitle to ArticleViews
val pageMap = pagesResponse.query?.pages?.associate { page ->
val pageTitle = PageTitle(
Expand All @@ -243,7 +242,7 @@ class ActivityTabViewModel() : ViewModel() {

impact.topViewedArticlesWithPageTitle = pageMap

_impactUiState.value = UiState.Success(impact)
_impactUiState.value = UiState.Success(Pair(impact, (pagesResponse.query?.globalUserInfo?.editCount ?: 0)))
}
}

Expand All @@ -260,7 +259,7 @@ class ActivityTabViewModel() : ViewModel() {

fun getTotalEditsCount(): Int {
return when (val currentState = _impactUiState.value) {
is UiState.Success -> currentState.data.totalEditsCount
is UiState.Success -> currentState.data.first.totalEditsCount
else -> 0
}
}
Expand All @@ -285,7 +284,7 @@ class ActivityTabViewModel() : ViewModel() {
fun hasNoImpactData(): Boolean {
return when (val currentState = _impactUiState.value) {
is UiState.Success -> {
val data = currentState.data
val data = currentState.data.first
data.totalEditsCount <= 0 && data.receivedThanksCount <= 0 && data.totalPageviewsCount <= 0
}
else -> true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ import java.util.Locale
@Composable
fun EditingInsightsModule(
modifier: Modifier = Modifier,
uiState: UiState<GrowthUserImpact>,
uiState: UiState<Pair<GrowthUserImpact, Int>>,
onPageItemClick: (PageTitle) -> Unit,
onContributionClick: (() -> Unit),
onSuggestedEditsClick: (() -> Unit),
Expand All @@ -78,20 +78,21 @@ fun EditingInsightsModule(
}
}
is UiState.Success -> {
val impact = uiState.data.first
MostViewedCard(
modifier = modifier
.fillMaxWidth(),
data = uiState.data.topViewedArticlesWithPageTitle,
data = impact.topViewedArticlesWithPageTitle,
onClick = {
onPageItemClick(it)
}
)
ContributionCard(
modifier = modifier
.fillMaxWidth(),
lastEditRelativeTime = uiState.data.lastEditRelativeTime,
editsThisMonth = uiState.data.editsThisMonth,
editsLastMonth = uiState.data.editsLastMonth,
lastEditRelativeTime = impact.lastEditRelativeTime,
editsThisMonth = impact.editsThisMonth,
editsLastMonth = impact.editsLastMonth,
onContributionClick = {
onContributionClick()
},
Expand Down
Loading
Loading