Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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,13 +163,16 @@ 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),
viewModel.shouldRefreshTimelineSilently,
readingHistoryState = viewModel.readingHistoryState.collectAsState().value,
donationUiState = viewModel.donationUiState.collectAsState().value,
wikiGamesUiState = viewModel.wikiGamesUiState.collectAsState().value,
impactUiState = viewModel.impactUiState.collectAsState().value,
totalEditsUiState = viewModel.totalEditsUiState.collectAsState().value,
timelineFlow = viewModel.timelineFlow
)
}
Expand All @@ -192,13 +197,16 @@ 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>,
totalEditsUiState: UiState<Int>,
timelineFlow: Flow<PagingData<TimelineDisplayItem>>
) {
val timelineItems = timelineFlow.collectAsLazyPagingItems()
Expand Down Expand Up @@ -414,13 +422,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 @@ -475,6 +504,15 @@ class ActivityTabFragment : Fragment() {
}
)
)
TotalEditsCard(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 16.dp),
uiState = totalEditsUiState,
onClickListener = {
startActivity(UserContribListActivity.newIntent(requireContext(), userName))
},
)
}

if (modules.isModuleVisible(ModuleType.GAMES, areGamesAvailable = areGamesAvailable) || modules.isModuleVisible(ModuleType.DONATIONS)) {
Expand Down Expand Up @@ -548,7 +586,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 +595,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 +668,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 Down Expand Up @@ -660,6 +700,7 @@ class ActivityTabFragment : Fragment() {
bestStreak = 25
)),
impactUiState = UiState.Success(GrowthUserImpact(totalEditsCount = 12345)),
totalEditsUiState = UiState.Success(123456),
timelineFlow = emptyFlow()
)
}
Expand All @@ -672,9 +713,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 @@ -688,6 +731,7 @@ class ActivityTabFragment : Fragment() {
donationUiState = UiState.Success("Unknown"),
wikiGamesUiState = UiState.Success(null),
impactUiState = UiState.Success(GrowthUserImpact()),
totalEditsUiState = UiState.Success(0),
timelineFlow = emptyFlow()
)
}
Expand All @@ -700,9 +744,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 @@ -716,6 +762,7 @@ class ActivityTabFragment : Fragment() {
donationUiState = UiState.Success("Unknown"),
wikiGamesUiState = UiState.Success(null),
impactUiState = UiState.Success(GrowthUserImpact()),
totalEditsUiState = UiState.Success(0),
timelineFlow = emptyFlow()
)
}
Expand All @@ -728,6 +775,7 @@ class ActivityTabFragment : Fragment() {
ActivityTabScreen(
isLoggedIn = true,
userName = "User",
languageCode = "zh",
modules = ActivityTabModules(
isTimeSpentEnabled = false,
isReadingInsightsEnabled = false,
Expand All @@ -739,6 +787,7 @@ class ActivityTabFragment : Fragment() {
),
haveAtLeastOneDonation = true,
areGamesAvailable = true,
refreshSilently = false,
readingHistoryState = UiState.Success(ActivityTabViewModel.ReadingHistory(
timeSpentThisWeek = 0,
articlesReadThisMonth = 0,
Expand All @@ -752,7 +801,8 @@ class ActivityTabFragment : Fragment() {
donationUiState = UiState.Success("Unknown"),
wikiGamesUiState = UiState.Success(null),
impactUiState = UiState.Success(GrowthUserImpact()),
timelineFlow = emptyFlow()
totalEditsUiState = UiState.Success(0),
timelineFlow = emptyFlow()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ class ActivityTabViewModel() : ViewModel() {

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

var shouldRefreshTimelineSilently: Boolean = false

Expand Down Expand Up @@ -225,9 +227,10 @@ 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 = "|")
)
_totalEditsUiState.value = UiState.Success(pagesResponse.query?.globalUserInfo?.editCount ?: 0)

// Transform the response to a map of PageTitle to ArticleViews
val pageMap = pagesResponse.query?.pages?.associate { page ->
Expand Down
73 changes: 73 additions & 0 deletions app/src/main/java/org/wikipedia/activitytab/ImpactModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,66 @@ fun AllTimeImpactCard(
}
}

@Composable
fun TotalEditsCard(
modifier: Modifier = Modifier,
uiState: UiState<Int>,
onClickListener: () -> Unit = {}
) {
val formatter = remember { NumberFormat.getNumberInstance(Locale.getDefault()) }
when (uiState) {
UiState.Loading -> { ActivityTabShimmerView() }
is UiState.Success -> {
WikiCard(
modifier = modifier,
elevation = 0.dp,
border = BorderStroke(width = 1.dp, color = WikipediaTheme.colors.borderColor),
onClick = onClickListener
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
) {
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
modifier = Modifier.size(16.dp),
painter = painterResource(R.drawable.ic_public_24),
tint = WikipediaTheme.colors.primaryColor,
contentDescription = null
)
Text(
text = stringResource(R.string.activity_tab_total_edits_all_projects),
style = MaterialTheme.typography.labelMedium,
color = WikipediaTheme.colors.primaryColor,
lineHeight = MaterialTheme.typography.labelMedium.lineHeight
)
}
Icon(
modifier = Modifier.size(24.dp),
painter = painterResource(R.drawable.ic_chevron_forward_white_24dp),
tint = WikipediaTheme.colors.secondaryColor,
contentDescription = null
)
}
Text(
modifier = Modifier.padding(top = 16.dp),
text = formatter.format(uiState.data),
style = MaterialTheme.typography.titleLarge,
color = WikipediaTheme.colors.primaryColor,
fontWeight = FontWeight.Medium
)
}
}
}
is UiState.Error -> {}
}
}

@Composable
fun ImpactStatView(
modifier: Modifier,
Expand Down Expand Up @@ -392,3 +452,16 @@ private fun AllTimeImpactCardPreview() {
)
}
}

@Preview
@Composable
private fun TotalEditsCardPreview() {
BaseTheme(
currentTheme = Theme.LIGHT
) {
TotalEditsCard(
modifier = Modifier.fillMaxWidth(),
uiState = UiState.Success(1234)
)
}
}
3 changes: 3 additions & 0 deletions app/src/main/java/org/wikipedia/dataclient/Service.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ interface Service {
@GET(MW_API_PREFIX + "action=query&prop=info|description|pageimages&pilicense=any&inprop=varianttitles|displaytitle&redirects=1&pithumbsize=" + PREFERRED_THUMB_SIZE)
suspend fun getInfoByPageIdsOrTitles(@Query("pageids") pageIds: String? = null, @Query("titles") titles: String? = null): MwQueryResponse

@GET(MW_API_PREFIX + "action=query&meta=globaluserinfo&guiprop=editcount&prop=info|description|pageimages&pilicense=any&inprop=varianttitles|displaytitle&redirects=1&pithumbsize=" + PREFERRED_THUMB_SIZE)
suspend fun getInfoByTitlesWithGlobalUserInfo(@Query("titles") titles: String? = null): MwQueryResponse

@GET(MW_API_PREFIX + "action=query&meta=siteinfo&siprop=general|autocreatetempuser")
suspend fun getPageIds(@Query("titles") titles: String): MwQueryResponse

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_public_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM440,798L440,720Q407,720 383.5,696.5Q360,673 360,640L360,600L168,408Q165,426 162.5,444Q160,462 160,480Q160,601 239.5,692Q319,783 440,798ZM716,696Q757,651 778.5,595.5Q800,540 800,480Q800,382 745.5,301Q691,220 600,184L600,200Q600,233 576.5,256.5Q553,280 520,280L440,280L440,360Q440,377 428.5,388.5Q417,400 400,400L320,400L320,480L560,480Q577,480 588.5,491.5Q600,503 600,520L600,640L640,640Q666,640 687,655.5Q708,671 716,696Z"/>

</vector>
1 change: 1 addition & 0 deletions app/src/main/res/values-qq/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,7 @@
<string name="activity_tab_discover_encourage">Label encouraging the user to discover new articles.</string>
<string name="activity_tab_donation_unknown">Label on card that shows the last donation time.</string>
<string name="activity_tab_donation_last_donation">Subtitle of the donation card that indicates last donation.</string>
<string name="activity_tab_total_edits_all_projects">Title of card indicating the total edits across all Wikimedia projects.</string>
<string name="activity_tab_game_stats">Title of the game stats card.</string>
<string name="activity_tab_game_stats_best_streak">Label of the game stats that indicates the best streak.</string>
<string name="activity_tab_play_wiki_games">Button label to go to the WikiGames.</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,7 @@
<string name="activity_tab_discover_encourage">Looking for something new to read?</string>
<string name="activity_tab_donation_unknown">Unknown</string>
<string name="activity_tab_donation_last_donation"><![CDATA[<b>Last donation</b> in app]]></string>
<string name="activity_tab_total_edits_all_projects">Total edits across projects</string>
<string name="activity_tab_game_stats">Game stats</string>
<string name="activity_tab_game_stats_best_streak">Best streak</string>
<string name="activity_tab_play_wiki_games">Play WikiGames</string>
Expand Down
Loading