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

2281 add badges to user dashboard #2297

Merged
merged 33 commits into from
Oct 23, 2020
Merged

Conversation

jonfroehlich
Copy link
Member

@jonfroehlich jonfroehlich commented Oct 3, 2020

Resolves #2281
Resolves #2178

This PR adds badges to the user dashboard. Note that none of the badge tracking or other achievements are implemented yet in the mission screens or mission sidebars. In addition, the backend knows nothing about achievements (not when they were earned, whether we displayed a 'congrats' message to the user, etc.). Finally, I think we should add some additional non-badge related achievements (like based on ranking), which should make mapathons more fun. All of that work is left to future PRs.

To work on this, I originally branched off of this, which I created a PR for here #2289 a few days ago. Note: I just ran a git origin to make sure everything is up to date from that branch and it is:

git pull origin 1680-give-users-more-feedback-on-dashboard
From https://github.com/ProjectSidewalk/SidewalkWebpage
 * branch              1680-give-users-more-feedback-on-dashboard -> FETCH_HEAD
Already up to date.

So, @misaugstad, you can either review this PR (which includes everything from this #2289 PR) or you review #2289 first and then come back to this PR. Not sure what your preferred process will be.

You can see lots of screenshots and discussions for this PR here: #2281

image

I've tested both English and Spanish translations.

The code is pretty straightforward. The achievement tracking happens in the new AchievementTracker.js. The most complicated part of the code is the language handling, especially for the dynamic language production of encouraging sentences and ensuring proper grammar for singular vs. plural statements. This is done through conditional logic and the use of the i18next library with json files en\dashboard.json and es\dashboard.json

had </img> on a <script>
userProfile.scala.html updated to dynamically show badges based on current values (on page load). Now uses AchivementTracker.js
…an 0.095

this ensures that first distance badge is earned after first auditing mission
@jonfroehlich jonfroehlich linked an issue Oct 5, 2020 that may be closed by this pull request
@misaugstad misaugstad self-requested a review October 13, 2020 20:56
Copy link
Member

@misaugstad misaugstad left a comment

Choose a reason for hiding this comment

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

Okay got it all cleaned up! There were a couple small bugs related to conversions/translations. But most of my changes were stylistic.

if (badgeType in this.mapBadges) {
let mapLevelsToBadge = this.mapBadges[badgeType]
let prevBadge = null;
for (let level of Object.keys(mapLevelsToBadge)) {
Copy link
Member

Choose a reason for hiding this comment

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

I changed your for..in loops to for..of loops, looping over the keys. I think that with the for..in loops you are supposed to do the hasOwnProperty() check that you don't need to do with this other method. I also think that for..in doesn't guarantee ordering, which it looks like you are relying on here.

<h3>@Messages("dashboard.missions")</h3>
<p id="missions-badge-encouragement" class="achievements-encouraging-statement">Just XX more missions until your next mission achievement.</p>
<div id="missions-badge-grid" class="achievements-badge-grid">
<img id="missions-badge1" src='@routes.Assets.at("images/badges/badge_missions_badge1.png")' alt="@Messages("dashboard.mission.badge", Messages("dashboard.first"))">
Copy link
Member

Choose a reason for hiding this comment

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

I added alt text with translations to the badges

@@ -84,12 +150,15 @@
}, function(err, t) {
var difficultRegionIds = @Json.toJson(RegionTable.difficultRegionIds);
window.progress = Progress(_, $, L, "@user.get.role", difficultRegionIds);

const achievementTracker = new AchievementTracker();
achievementTracker.updateBadgeAchievementGrid(
Copy link
Member

Choose a reason for hiding this comment

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

I removed the measurement system from the list of parameters, because you can get the measurement system in the Javascript using i18next.t('common:measurement-system')

} else if (fractionComplete > 0.85) {
htmlStatement += i18next.t('dashboard:wow-almost-there') + ' ' + i18next.t('dashboard:just') + ' ';
} else if (fractionComplete > 0.1 || curBadgeLevel > 0) {
let randStatement = encouragingStatements[Math.floor(Math.random() * encouragingStatements.length)];
Copy link
Member

Choose a reason for hiding this comment

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

I shortened this by choosing randomly from a list instead of having the 10 if cases.


// Convert to from miles to kilometers if using metric system.
const measurementSystem = i18next.t('common:measurement-system');
if (badgeType === BadgeTypes.Distance && measurementSystem === 'metric') diffValue *= 1.60934;
Copy link
Member

Choose a reason for hiding this comment

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

You had a bug here because you were dividing by 1.60934 instead of multiplying by it when converting from miles to kilometers.


// Add translation for how much is left before the next achievement. For example, "1 misión más hasta tu
// próximo logro." or "1.3 more miles until your next achievement."
htmlStatement += i18next.t('dashboard:more-unit-until-achievement', {
Copy link
Member

Choose a reason for hiding this comment

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

I reorganized this a bit. Instead of building each piece of the sentence up from translated fragments, I put the entire sentence into one translation, and the translation requires some parameters which do what you were doing.

"badge-labels-plural": "labels",
"badge-validations-singular": "validation",
"badge-validations-plural": "validations",
"more-unit-until-achievement": "<strong>{{n}} more $t({{unit}})</strong> until your $t({{firstOrNext}}) achievement.",
Copy link
Member

Choose a reason for hiding this comment

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

Here's the sentence where I combined your different fragments of a sentence together. You can reference other translations from within a translation using $t() and you can get the value of a parameter using {{}}. So we can even pass in a translation as a parameter, and then stick that into the current translation using $t({{}}).

@misaugstad misaugstad merged commit 04907bc into develop Oct 23, 2020
@misaugstad misaugstad deleted the 2281-add-badges-to-user-dashboard branch October 23, 2020 22:40
This was referenced Oct 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

User dashboard: add badges to dashboard Add badge system (gamification)
2 participants