Skip to content

Commit

Permalink
Implement badge modal mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
XanderZhu committed Aug 2, 2023
1 parent 5b1cbd8 commit d6044cb
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,12 @@ interface ProfileFeature {
object Success : ShowStreakFreezeBuyingStatus
}

data class ShowBadgeDetailsModal(val badge: Badge) : ViewAction
data class ShowBadgeDetailsModal(val details: BadgeDetails) : ViewAction

sealed interface BadgeDetails {
data class Badge(val badge: org.hyperskill.app.badges.domain.model.Badge) : BadgeDetails
data class Kind(val badgeKind: BadgeKind) : BadgeDetails
}

sealed interface NavigateTo : ViewAction {
object HomeScreen : NavigateTo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,15 @@ class ProfileReducer : StateReducer<State, Message, Action> {
): ReducerResult =
if (state is State.Content) {
val clickedBadge = state.badgesState.badges.firstOrNull { it.kind == message.badgeKind }
state to setOfNotNull(
clickedBadge?.let { badge ->
Action.ViewAction.ShowBadgeDetailsModal(badge)
},
val showAction = Action.ViewAction.ShowBadgeDetailsModal(
if (clickedBadge == null) {
Action.ViewAction.BadgeDetails.Kind(message.badgeKind)
} else {
Action.ViewAction.BadgeDetails.Badge(clickedBadge)
}
)
state to setOf(
showAction,
Action.LogAnalyticEvent(
ProfileClickedBadgeCardHyperskillAnalyticsEvent(
badgeKind = message.badgeKind,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.hyperskill.app.profile.view

import org.hyperskill.app.badges.domain.model.BadgeKind

data class BadgeDetailsViewState(
val kind: BadgeKind,
val title: String,
val rank: String,
val badgeDescription: String?,
val levelDescription: String?,
val formattedCurrentLevel: String,
val formattedNextLevel: String?,
val isLocked: Boolean
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.hyperskill.app.profile.view
import org.hyperskill.app.SharedResources
import org.hyperskill.app.badges.domain.model.Badge
import org.hyperskill.app.badges.domain.model.BadgeKind
import org.hyperskill.app.badges.domain.model.BadgeRank
import org.hyperskill.app.core.view.mapper.ResourceProvider
import org.hyperskill.app.profile.presentation.ProfileFeature

Expand Down Expand Up @@ -45,7 +46,7 @@ class BadgesViewStateMapper(
},
badge.level
),
nextLevel = if (badge.isMaxLevel) null else badge.level + 1,
nextLevel = getNextLevel(badge),
progress = if (badge.nextLevelValue != null && badge.isMaxLevel) {
val totalCount = badge.nextLevelValue - badge.currentLevelValue
val currentCount = badge.value - badge.currentLevelValue
Expand All @@ -58,31 +59,131 @@ class BadgesViewStateMapper(
private fun mapLockedBadge(badgeKind: BadgeKind): BadgesViewState.BadgeViewState =
BadgesViewState.BadgeViewState(
kind = badgeKind,
title = getBadgeTitle(badgeKind),
title = getBadgeTitle(badgeKind) ?: "",
image = BadgesViewState.BadgeImage.Locked,
formattedCurrentLevel = resourceProvider.getString(SharedResources.strings.badge_level, 0),
nextLevel = 1,
progress = 0f
)

private fun getBadgeTitle(badgeKind: BadgeKind): String =
fun mapToDetails(badge: Badge): BadgeDetailsViewState =
BadgeDetailsViewState(
kind = badge.kind,
title = badge.title,
rank = getBadgeRankName(badge.rank) ?: "",
badgeDescription = if (!badge.isMaxLevel) {
getBadgeDescription(badge.kind)
} else {
null
},
levelDescription = when {
badge.level == 0 ->
badge.nextLevelValue?.let { nextLevelValue ->
getBadgeUnlockDescription(badge.kind, nextLevelValue)
}
!badge.isMaxLevel ->
badge.nextLevelValue?.let { nextLevelValue ->
getBadgeUpgradeDescription(badge.kind, nextLevelValue)
}
badge.isMaxLevel ->
resourceProvider.getString(SharedResources.strings.badge_max_level_description)
else -> null
},
formattedCurrentLevel = if (badge.level == 0) {
resourceProvider.getString(SharedResources.strings.badge_locked)
} else {
resourceProvider.getString(SharedResources.strings.badge_level, badge.level)
},
formattedNextLevel = getNextLevel(badge)?.let { nextLevel ->
resourceProvider.getString(SharedResources.strings.badge_level, nextLevel)
},
isLocked = false // TODO: replace with `badge.rank == BadgeRank.LOCKED`
)

fun mapToDetails(badgeKind: BadgeKind): BadgeDetailsViewState =
BadgeDetailsViewState(
kind = badgeKind,
title = getBadgeTitle(badgeKind) ?: "",
rank = "", // TODO: replace with `getBadgeRankName(BadgeRank.LOCKED)`
badgeDescription = getBadgeDescription(badgeKind),
levelDescription = getBadgeUnlockDescription(badgeKind, countToUnlock = 1),
formattedNextLevel = resourceProvider.getString(SharedResources.strings.badge_locked),
formattedCurrentLevel = resourceProvider.getString(SharedResources.strings.badge_level, 1),
isLocked = true
)

private fun getBadgeTitle(badgeKind: BadgeKind): String? =
when (badgeKind) {
BadgeKind.ProjectMaster ->
resourceProvider.getString(SharedResources.strings.badge_project_mastery_title)
SharedResources.strings.badge_project_mastery_title
BadgeKind.TopicMaster ->
resourceProvider.getString(SharedResources.strings.badge_project_topic_mastery)
SharedResources.strings.badge_topic_mastery
BadgeKind.CommittedLearner ->
resourceProvider.getString(SharedResources.strings.badge_project_committed_learning)
SharedResources.strings.badge_committed_learning
BadgeKind.BrilliantMind ->
resourceProvider.getString(SharedResources.strings.badge_project_brilliant_mind)
SharedResources.strings.badge_brilliant_mind
BadgeKind.HelpingHand ->
resourceProvider.getString(SharedResources.strings.badge_project_helping_hand)
SharedResources.strings.badge_helping_hand
BadgeKind.Sweetheart ->
resourceProvider.getString(SharedResources.strings.badge_project_sweetheart)
SharedResources.strings.badge_sweetheart
BadgeKind.Benefactor ->
resourceProvider.getString(SharedResources.strings.badge_project_benefactor)
SharedResources.strings.badge_benefactor
BadgeKind.BountyHunter ->
resourceProvider.getString(SharedResources.strings.badge_project_bounty_hunter)
BadgeKind.UNKNOWN -> ""
}
SharedResources.strings.badge_bounty_hunter
BadgeKind.UNKNOWN -> null
}?.let(resourceProvider::getString)

private fun getBadgeRankName(badgeRank: BadgeRank): String? =
when (badgeRank) {
BadgeRank.APPRENTICE ->
SharedResources.strings.badge_apprentice_level
BadgeRank.EXPERT ->
SharedResources.strings.badge_expert_level
BadgeRank.MASTER -> SharedResources.strings.badge_master_level
BadgeRank.LEGENDARY ->
SharedResources.strings.badge_legendary_level
BadgeRank.UNKNOWN -> null
}?.let { res -> resourceProvider.getString(res) }

private fun getBadgeDescription(badgeKind: BadgeKind): String? =
when (badgeKind) {
BadgeKind.ProjectMaster -> SharedResources.strings.badge_project_master_description
BadgeKind.TopicMaster -> SharedResources.strings.badge_topic_master_description
BadgeKind.CommittedLearner -> SharedResources.strings.badge_committed_learner_description
BadgeKind.BrilliantMind -> SharedResources.strings.badge_brilliant_mind_description
BadgeKind.HelpingHand -> SharedResources.strings.badge_helping_hand_description
BadgeKind.Sweetheart -> SharedResources.strings.badge_sweetheart_description
BadgeKind.Benefactor -> SharedResources.strings.badge_benefactor_description
BadgeKind.BountyHunter -> SharedResources.strings.badge_bounty_hunter_description
BadgeKind.UNKNOWN -> null
}?.let(resourceProvider::getString)

private fun getBadgeUnlockDescription(badgeKind: BadgeKind, countToUnlock: Int): String? =
when (badgeKind) {
BadgeKind.ProjectMaster -> SharedResources.plurals.badge_project_master_unlock_description
BadgeKind.TopicMaster -> SharedResources.plurals.badge_topic_master_unlock_description
BadgeKind.CommittedLearner -> SharedResources.plurals.badge_committed_learner_unlock_description
BadgeKind.BrilliantMind -> SharedResources.plurals.badge_brilliant_mind_unlock_description
BadgeKind.HelpingHand -> SharedResources.plurals.badge_helping_hand_unlock_description
BadgeKind.Sweetheart -> SharedResources.plurals.badge_sweetheart_unlock_description
BadgeKind.Benefactor -> SharedResources.plurals.badge_benefactor_unlock_description
BadgeKind.BountyHunter -> SharedResources.plurals.badge_bounty_hunter_unlock_description
BadgeKind.UNKNOWN -> null
}?.let { res -> resourceProvider.getQuantityString(res, countToUnlock) }

private fun getBadgeUpgradeDescription(badgeKind: BadgeKind, countToUpgrade: Int): String? =
when (badgeKind) {
BadgeKind.ProjectMaster -> SharedResources.plurals.badge_project_master_upgrade_description
BadgeKind.TopicMaster -> SharedResources.plurals.badge_topic_master_upgrade_description
BadgeKind.CommittedLearner -> SharedResources.plurals.badge_committed_learner_upgrade_description
BadgeKind.BrilliantMind -> SharedResources.plurals.badge_brilliant_mind_upgrade_description
BadgeKind.HelpingHand -> SharedResources.plurals.badge_helping_hand_upgrade_description
BadgeKind.Sweetheart -> SharedResources.plurals.badge_sweetheart_upgrade_description
BadgeKind.Benefactor -> SharedResources.plurals.badge_benefactor_upgrade_description
BadgeKind.BountyHunter -> SharedResources.plurals.badge_bounty_hunter_upgrade_description
BadgeKind.UNKNOWN -> null
}?.let { res -> resourceProvider.getQuantityString(res, countToUpgrade) }

private fun getNextLevel(badge: Badge): Int? =
if (badge.isMaxLevel) null else badge.level + 1
}
64 changes: 64 additions & 0 deletions shared/src/commonMain/resources/MR/base/plurals.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,68 @@
<item quantity="one">+%d gem</item>
<item quantity="other">+%d gems</item>
</plural>
<plural name="badge_project_master_unlock_description">
<item quantity="one">Complete %d project to unlock this badge</item>
<item quantity="other">Complete %d projects to unlock this badge</item>
</plural>
<plural name="badge_project_master_upgrade_description">
<item quantity="one">Complete %d project to upgrade this badge</item>
<item quantity="other">Complete %d projects to upgrade this badge</item>
</plural>
<plural name="badge_topic_master_unlock_description">
<item quantity="one">Complete %d topic to unlock this badge</item>
<item quantity="other">Complete %d topics to unlock this badge</item>
</plural>
<plural name="badge_topic_master_upgrade_description">
<item quantity="one">Complete %d topic to upgrade this badge</item>
<item quantity="other">Complete %d topics to upgrade this badge</item>
</plural>
<plural name="badge_committed_learner_unlock_description">
<item quantity="one">Achieve %d-day streak to unlock this badge</item>
<item quantity="other">Achieve %d-days streak to unlock this badge</item>
</plural>
<plural name="badge_committed_learner_upgrade_description">
<item quantity="one">Achieve %d-day streak to upgrade this badge</item>
<item quantity="other">Achieve %d-days streak to upgrade this badge</item>
</plural>
<plural name="badge_brilliant_mind_unlock_description">
<item quantity="one">Post %d solution to unlock this badge</item>
<item quantity="other">Post %d solutions to unlock this badge</item>
</plural>
<plural name="badge_brilliant_mind_upgrade_description">
<item quantity="one">Post %d solution to upgrade this badge</item>
<item quantity="other">Post %d solutions to upgrade this badge</item>
</plural>
<plural name="badge_helping_hand_unlock_description">
<item quantity="one">Post %d useful hint to unlock this badge</item>
<item quantity="other">Post %d useful hints to unlock this badge</item>
</plural>
<plural name="badge_helping_hand_upgrade_description">
<item quantity="one">Post %d useful hint to upgrade this badge</item>
<item quantity="other">Post %d useful hints to upgrade this badge</item>
</plural>
<plural name="badge_sweetheart_unlock_description">
<item quantity="one">Receive %d upvote to unlock this badge</item>
<item quantity="other">Receive %d upvotes to unlock this badge</item>
</plural>
<plural name="badge_sweetheart_upgrade_description">
<item quantity="one">Receive %d upvote to upgrade this badge</item>
<item quantity="other">Receive %d upvotes to upgrade this badge</item>
</plural>
<plural name="badge_benefactor_unlock_description">
<item quantity="one">Give %d bounty to unlock this badge</item>
<item quantity="other">Give %d bounties to unlock this badge</item>
</plural>
<plural name="badge_benefactor_upgrade_description">
<item quantity="one">Give %d bounty to upgrade this badge</item>
<item quantity="other">Give %d bounties to upgrade this badge</item>
</plural>
<plural name="badge_bounty_hunter_unlock_description">
<item quantity="one">Win %d bounty to unlock this badge</item>
<item quantity="other">Win %d bounties to unlock this badge</item>
</plural>
<plural name="badge_bounty_hunter_upgrade_description">
<item quantity="one">Win %d bounty to upgrade this badge</item>
<item quantity="other">Win %d bounties to upgrade this badge</item>
</plural>
</resources>
28 changes: 21 additions & 7 deletions shared/src/commonMain/resources/MR/base/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -469,13 +469,27 @@

<!--Badges-->
<string name="badge_project_mastery_title">Project Mastery</string>
<string name="badge_project_topic_mastery">Topic Mastery</string>
<string name="badge_project_committed_learning">Committed Learning</string>
<string name="badge_project_brilliant_mind">Brilliant Mind</string>
<string name="badge_project_helping_hand">Helping Hand</string>
<string name="badge_project_sweetheart">Sweetheart</string>
<string name="badge_project_benefactor">Benefactor</string>
<string name="badge_project_bounty_hunter">Bounty Hunter</string>
<string name="badge_topic_mastery">Topic Mastery</string>
<string name="badge_committed_learning">Committed Learning</string>
<string name="badge_brilliant_mind">Brilliant Mind</string>
<string name="badge_helping_hand">Helping Hand</string>
<string name="badge_sweetheart">Sweetheart</string>
<string name="badge_benefactor">Benefactor</string>
<string name="badge_bounty_hunter">Bounty Hunter</string>
<string name="badge_level">Level %d</string>
<string name="badge_max_level">Level %d (Max)</string>
<string name="badge_max_level_description">Hooray! You’ve reached the maximum level!</string>
<string name="badge_project_master_description">Complete projects to upgrade this badge</string>
<string name="badge_topic_master_description">Complete topics to upgrade this badge</string>
<string name="badge_committed_learner_description">Achieve streaks to upgrade this badge</string>
<string name="badge_brilliant_mind_description">Post solutions to upgrade this badge</string>
<string name="badge_helping_hand_description">Post useful hints to upgrade this badge</string>
<string name="badge_sweetheart_description">Receive upvotes to upgrade this badge</string>
<string name="badge_benefactor_description">Give bounties to upgrade this badge</string>
<string name="badge_bounty_hunter_description">Win bounties to upgrade this badge</string>
<string name="badge_apprentice_level">Apprentice</string>
<string name="badge_expert_level">Expert</string>
<string name="badge_master_level">Master</string>
<string name="badge_legendary_level">Legendary</string>
<string name="badge_locked">Locked</string>
</resources>

0 comments on commit d6044cb

Please sign in to comment.