mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
Achievement list renovation & Achievements API (#7904)
* pull apart achievements into different subcategories
* achievs previously hidden to others if unachieved are now always shown
* achievs previously always hidden if unachieved are now always shown
* pull apart ultimate gear achievs
* add achiev wrapper mixin
* add achiev mixin for simple counts
* add achiev mixin for singular/plural achievs
* add simpleAchiev mixin and support attributes
* always hide potentially unearnable achievs if unearned
* contributor achiev now uses string interpolation for readMore link
* transition to basic achiev grid layout
* fix npc achievement img bug introduced in c90f7e2
* move surveys and contributor achievs into special section so it is never empty
* double size of achievs in achievs grid
* achievs in grid are muted if unachieved (includes recompiled sprites)
* fix streak notification strings
* add counts to achievement badges for applicable achieved achievs
* list achievements by api
* fix achievement strings in new api
* unearned achievs now use dedicated (WIP) 'unearned' badge instead of muted versions of the normal badges
* fix & cleanup achievements api
* extract generation of the achievements result to a class
* clean up achievement counter css using existing classes
* simplify exports of new achievementBuilder lib
* remove class logic from achievementBuilder lib
* move achievs to common, add rebirth achiev logic, misc fixes
* replace achievs jade logic with results of api call
* fix linting errors
* achievs lib now returns achievs object subdivided by type (basic/seasonal/special
* add tests for new achievs lib
* fix linting errors
* update controllers and views for updated achievs lib
* add indices to achievements to preserve intended order
* move achiev popovers to left
* rename achievs lib to achievements
* adjust positioning of achieve popovers now that stats and achievs pages
are separate
* fix: achievements api correctly decides whether to append extra string for master and triadBingo achievs
* revert compiled sprites so they don't bog down the PR
* pull out achievs api integration tests
* parameterize ultimate gear achievements' text string
* break out static achievement data from user-specific data
* reorg content.achievements to add achiev data in related chunks
* cleanup, respond to feedback
* improve api documentation
* fix merge issues
* Helped Habit Grow --> Helped Habitica Grow
* achievement popovers are muted if the achiev is unearned
* fix singular achievement labels / achievement popover on click
* update apidoc for achievements (description, param-type, successExample, error-types)
* fix whitespace issues in members.js
* move html to a variable
* updated json example
* fix syntax after merge
This commit is contained in:
committed by
Keith Holliday
parent
97e1d75dce
commit
0817cf96e1
@@ -17,6 +17,7 @@ import {
|
||||
} from '../../libs/email';
|
||||
import Bluebird from 'bluebird';
|
||||
import { sendNotification as sendPushNotification } from '../../libs/pushNotifications';
|
||||
import { achievements } from '../../../../website/common/';
|
||||
|
||||
let api = {};
|
||||
|
||||
@@ -58,6 +59,113 @@ api.getMember = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @api {get} /api/v3/members/:memberId/achievements Get member achievements object
|
||||
* @apiName GetMemberAchievements
|
||||
* @apiGroup Member
|
||||
* @apiDescription Get a list of achievements of the requested member, grouped by basic / seasonal / special.
|
||||
*
|
||||
* @apiParam (Path) {UUID} memberId The member's id
|
||||
*
|
||||
* @apiSuccess {Object} data The achievements object
|
||||
*
|
||||
* @apiSuccess {Object} data.basic The basic achievements object
|
||||
* @apiSuccess {Object} data.seasonal The seasonal achievements object
|
||||
* @apiSuccess {Object} data.special The special achievements object
|
||||
*
|
||||
* @apiSuccess {String} data.*.label The label for that category
|
||||
* @apiSuccess {Object} data.*.achievements The achievements in that category
|
||||
*
|
||||
* @apiSuccess {String} data.*.achievements.title The localized title string
|
||||
* @apiSuccess {String} data.*.achievements.text The localized description string
|
||||
* @apiSuccess {Boolean} data.*.achievements.earned Whether the user has earned the achievement
|
||||
* @apiSuccess {Number} data.*.achievements.index The unique index assigned to the achievement (only for sorting purposes)
|
||||
* @apiSuccess {Anything} data.*.achievements.value The value related to the achievement (if applicable)
|
||||
* @apiSuccess {Number} data.*.achievements.optionalCount The count related to the achievement (if applicable)
|
||||
*
|
||||
* @apiSuccessExample {json} Successful Response
|
||||
* {
|
||||
* basic: {
|
||||
* label: "Basic",
|
||||
* achievements: {
|
||||
* streak: {
|
||||
* title: "0 Streak Achievements",
|
||||
* text: "Has performed 0 21-day streaks on Dailies",
|
||||
* icon: "achievement-thermometer",
|
||||
* earned: false,
|
||||
* value: 0,
|
||||
* index: 60,
|
||||
* optionalCount: 0
|
||||
* },
|
||||
* perfect: {
|
||||
* title: "5 Perfect Days",
|
||||
* text: "Completed all active Dailies on 5 days. With this achievement you get a +level/2 buff to all attributes for the next day. Levels greater than 100 don't have any additional effects on buffs.",
|
||||
* icon: "achievement-perfect",
|
||||
* earned: true,
|
||||
* value: 5,
|
||||
* index: 61,
|
||||
* optionalCount: 5
|
||||
* }
|
||||
* }
|
||||
* },
|
||||
* seasonal: {
|
||||
* label: "Seasonal",
|
||||
* achievements: {
|
||||
* habiticaDays: {
|
||||
* title: "Habitica Naming Day",
|
||||
* text: "Celebrated 0 Naming Days! Thanks for being a fantastic user.",
|
||||
* icon: "achievement-habiticaDay",
|
||||
* earned: false,
|
||||
* value: 0,
|
||||
* index: 72,
|
||||
* optionalCount: 0
|
||||
* }
|
||||
* }
|
||||
* },
|
||||
* special: {
|
||||
* label: "Special",
|
||||
* achievements: {
|
||||
* habitSurveys: {
|
||||
* title: "Helped Habitica Grow",
|
||||
* text: "Helped Habitica grow on 0 occasions, either by filling out a survey or helping with a major testing effort. Thank you!",
|
||||
* icon: "achievement-tree",
|
||||
* earned: false,
|
||||
* value: 0,
|
||||
* index: 88,
|
||||
* optionalCount: 0
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @apiError (400) {BadRequest} MemberIdRequired The `id` param is required and must be a valid `UUID`
|
||||
* @apiError (404) {NotFound} UserWithIdNotFound The `id` param did not belong to an existing member
|
||||
*/
|
||||
api.getMemberAchievements = {
|
||||
method: 'GET',
|
||||
url: '/members/:memberId/achievements',
|
||||
middlewares: [],
|
||||
async handler (req, res) {
|
||||
req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID();
|
||||
|
||||
let validationErrors = req.validationErrors();
|
||||
if (validationErrors) throw validationErrors;
|
||||
|
||||
let memberId = req.params.memberId;
|
||||
|
||||
let member = await User
|
||||
.findById(memberId)
|
||||
.select(memberFields)
|
||||
.exec();
|
||||
|
||||
if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId}));
|
||||
|
||||
let achievsObject = achievements.getAchievementsForProfile(member, req.language);
|
||||
|
||||
res.respond(200, achievsObject);
|
||||
},
|
||||
};
|
||||
|
||||
// Return a request handler for getMembersForGroup / getInvitesForGroup / getMembersForChallenge
|
||||
// type is `invites` or `members`
|
||||
function _getMembersForItem (type) {
|
||||
|
||||
Reference in New Issue
Block a user