Compare commits

..

265 Commits

Author SHA1 Message Date
Sabe Jones efe7ea52bc 4.161.0 2020-09-29 14:16:38 -05:00
Sabe Jones 938152edea chore(news): Bailey 2020-09-29 14:16:25 -05:00
Sabe Jones f47c243cb0 fix(potions): previously-available text 2020-09-28 09:52:49 -05:00
Sabe Jones 6d737330f2 chore(sprites): compile 2020-09-25 16:06:45 -05:00
Sabe Jones 910c49df4f feat(content): Mystery Items and avatar customizations 2020-09-25 16:06:37 -05:00
Sabe Jones dd4c9c2536 4.160.1 2020-09-25 14:46:14 -05:00
Sabe Jones 0a6b22fdd9 fix(potions): erroneous Ghost overbuy warnings 2020-09-25 14:45:56 -05:00
Sabe Jones 54ffe1d3b6 4.160.0 2020-09-24 14:13:36 -05:00
Sabe Jones ff77455b00 Merge branch 'sabrecat/vampotions' into release 2020-09-24 14:13:29 -05:00
Sabe Jones 701a6170a3 chore(sprites): compile 2020-09-23 14:09:49 -05:00
Sabe Jones ee70ed6146 feat(content): Vampire Hatching Potions 2020-09-23 14:09:38 -05:00
RaitheOfDureya d45a6f260d Removed unused I18N loginIncentives.json strings from all languages (#12566) 2020-09-23 17:44:39 +02:00
RaitheOfDureya de09e56f67 Removed unused I18N strings from all limited.json files (#12567)
Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-09-22 22:14:49 +02:00
Matteo Pagliazzi 17b520de12 Merge branch 'RaitheOfDureya-remove-unused-maintenance' into develop 2020-09-22 21:56:32 +02:00
Matteo Pagliazzi 0655e2e0a0 Merge branch 'remove-unused-maintenance' of https://github.com/RaitheOfDureya/habitica into RaitheOfDureya-remove-unused-maintenance 2020-09-22 21:56:20 +02:00
RaitheOfDureya bcf489f847 Removed unused I18N strings from the merch.json files (related to issue #9957) (#12564)
* Removed unused I18N strings from the `merch.json` file (locales\en)

* Removed unused I18N `merch.json` strings from all the other languages
2020-09-22 20:05:58 +02:00
RaitheOfDureya adc2207249 Removed unused I18N strings from the noscript.json files (related to issue #9957) (#12562)
* Removed unused I18N strings from the `nostring.json` file (locales\en)

* Removed unused I18N `noscript.json` strings from all the others languages
2020-09-22 20:03:41 +02:00
Matteo Pagliazzi 1c205a96fb Merge branch 'RaitheOfDureya-remove-unused-npc' into develop 2020-09-22 20:01:01 +02:00
Matteo Pagliazzi 8e2bbbd570 Merge branch 'remove-unused-npc' of https://github.com/RaitheOfDureya/habitica into RaitheOfDureya-remove-unused-npc 2020-09-22 20:00:51 +02:00
Matteo Pagliazzi 13d1f1b48b Merge #12553 - Removed unused I18N strings from the rebirth.json files
Squashed commit of the following:

commit 9de806e00296e9e8659ccde25085eb3b8a6639c4
Merge: 7c4faf8b7a 7361029289
Author: Matteo Pagliazzi <matteopagliazzi@gmail.com>
Date:   Tue Sep 22 19:52:09 2020 +0200

    Merge branch 'remove-unused-rebirth' of https://github.com/RaitheOfDureya/habitica into RaitheOfDureya-remove-unused-rebirth

commit 7361029289
Author: Raithe Of Dureya <raitheofdureya@gmail.com>
Date:   Fri Sep 11 13:43:59 2020 +0200

    Removed `rebirth.json`'s unused I18N strings from other languages

commit acd7786580
Author: Raithe Of Dureya <raitheofdureya@gmail.com>
Date:   Tue Sep 8 20:47:59 2020 +0200

    Removed unused I18N strings from the `rebirth.json` file (locales/en)
2020-09-22 19:52:55 +02:00
Bart Enkelaar 7c4faf8b7a fix(chat) - issue 12586 - can't put links without titles in message boxes (#12594) 2020-09-22 19:28:37 +02:00
Melior 82be621850 Merge branch 'origin/develop' into Weblate. 2020-09-22 17:07:35 +02:00
Sabe Jones 265fb7c5f6 Merge branch 'release' into develop 2020-09-22 09:49:49 -05:00
Sabe Jones cfa4d03e45 4.159.1 2020-09-22 09:49:16 -05:00
Sabe Jones f28c5a563a fix(news): missing Bailey paragraph 2020-09-22 09:48:58 -05:00
Matteo Pagliazzi 0455f08ec5 fix(gem icon): update gem icon 2020-09-22 16:46:27 +02:00
Matteo Pagliazzi 48193dce59 Revert "Revert "fix(gem icon in menu): add hover animation""
This reverts commit ffe8d34acb.
2020-09-22 16:39:01 +02:00
Matteo Pagliazzi ffe8d34acb Revert "fix(gem icon in menu): add hover animation"
This reverts commit 74428d0727.
2020-09-22 16:35:47 +02:00
Melior 29a278d0bc Merge branch 'origin/develop' into Weblate. 2020-09-22 16:17:25 +02:00
Melior 2fb9dfe909 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.5% (44 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/nb_NO/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 98.2% (55 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 71.4% (40 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 86.8% (622 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 88.0% (118 of 134 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (28 of 28 strings)

Translation: Habitica/Rebirth
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 86.8% (622 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (31 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (185 of 185 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (63 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (15 of 15 strings)

Translation: Habitica/Death
Translate-URL: https://translate.habitica.com/projects/habitica/death/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 84.8% (307 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 91.5% (194 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 93.0% (161 of 173 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 67.8% (38 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 86.8% (622 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 7.5% (11 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 90.7% (157 of 173 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 64.2% (36 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 88.0% (118 of 134 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 86.8% (622 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 86.4% (121 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 83.3% (5 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 99.8% (500 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.5% (1703 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/nb_NO/

Translated using Weblate (Spanish (Latin America))

Currently translated at 87.5% (7 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (28 of 28 strings)

Translation: Habitica/Rebirth
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 82.7% (1771 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (716 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 87.5% (7 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 82.7% (1771 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Korean)

Currently translated at 73.1% (68 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ko/

Translated using Weblate (Korean)

Currently translated at 73.1% (68 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ko/

Translated using Weblate (Spanish (Latin America))

Currently translated at 82.7% (1771 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Korean)

Currently translated at 95.3% (284 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ko/

Translated using Weblate (Korean)

Currently translated at 95.3% (284 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ko/

Translated using Weblate (Korean)

Currently translated at 97.3% (224 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/ko/

Translated using Weblate (Korean)

Currently translated at 96.3% (287 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ko/

Translated using Weblate (Korean)

Currently translated at 52.7% (77 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ko/

Translated using Weblate (Korean)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/ko/

Translated using Weblate (Korean)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/ko/

Translated using Weblate (Korean)

Currently translated at 67.7% (63 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ko/

Translated using Weblate (Spanish (Latin America))

Currently translated at 82.7% (1771 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 82.7% (1771 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (French)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (Swedish)

Currently translated at 66.4% (123 of 185 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/sv/

Translated using Weblate (Swedish)

Currently translated at 83.6% (1792 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/sv/

Translated using Weblate (Swedish)

Currently translated at 92.1% (513 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/sv/

Translated using Weblate (Spanish (Latin America))

Currently translated at 82.7% (1771 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/es_419/

Translated using Weblate (Hindi)

Currently translated at 97.8% (91 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hi/
2020-09-22 16:12:26 +02:00
Sabe Jones 8ca369f937 Merge branch 'release' into develop 2020-09-22 09:10:11 -05:00
Sabe Jones 12c7fb7b27 4.159.0 2020-09-22 09:09:51 -05:00
Sabe Jones 2428347836 chore(news): Bailey 2020-09-22 09:09:43 -05:00
Sabe Jones 5aab13b28b Merge branch 'sabrecat/fall-2020' into release 2020-09-22 09:00:21 -05:00
Matteo Pagliazzi caa02141b8 Merge branch 'release' into develop 2020-09-22 15:53:28 +02:00
Matteo Pagliazzi 74428d0727 fix(gem icon in menu): add hover animation 2020-09-22 15:53:05 +02:00
Sabe Jones 0a15c0f1d8 fix(event): various content corrections 2020-09-21 19:59:13 -05:00
Sabe Jones 3aa58398b7 chore(sprites): compile 2020-09-21 14:34:45 -05:00
Sabe Jones 9450f9ee1d feat(event): Fall Festival 2020 2020-09-21 14:34:38 -05:00
dependabot-preview[bot] a1cea3b584 build(deps): bump @google-cloud/trace-agent from 5.1.0 to 5.1.1 (#12595)
Bumps [@google-cloud/trace-agent](https://github.com/googleapis/cloud-trace-nodejs) from 5.1.0 to 5.1.1.
- [Release notes](https://github.com/googleapis/cloud-trace-nodejs/releases)
- [Changelog](https://github.com/googleapis/cloud-trace-nodejs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/googleapis/cloud-trace-nodejs/compare/v5.1.0...v5.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-21 17:19:12 +02:00
dependabot-preview[bot] 1b260aee52 build(deps): bump got from 11.6.2 to 11.7.0 (#12597)
Bumps [got](https://github.com/sindresorhus/got) from 11.6.2 to 11.7.0.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.6.2...v11.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-21 17:19:04 +02:00
dependabot-preview[bot] f2182428e5 build(deps): bump validator from 13.1.1 to 13.1.17 (#12598)
Bumps [validator](https://github.com/chriso/validator.js) from 13.1.1 to 13.1.17.
- [Release notes](https://github.com/chriso/validator.js/releases)
- [Changelog](https://github.com/validatorjs/validator.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/chriso/validator.js/compare/13.1.1...13.1.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-21 17:18:46 +02:00
dependabot-preview[bot] 996b8f67c5 build(deps): bump sass from 1.26.10 to 1.26.11 in /website/client (#12600)
Bumps [sass](https://github.com/sass/dart-sass) from 1.26.10 to 1.26.11.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.26.10...1.26.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-21 17:18:38 +02:00
dependabot-preview[bot] b297b2a48a build(deps): bump validator from 13.1.1 to 13.1.17 in /website/client (#12601)
Bumps [validator](https://github.com/chriso/validator.js) from 13.1.1 to 13.1.17.
- [Release notes](https://github.com/chriso/validator.js/releases)
- [Changelog](https://github.com/validatorjs/validator.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/chriso/validator.js/compare/13.1.1...13.1.17)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-21 17:18:24 +02:00
Matteo Pagliazzi 74eab5bba9 Merge pull request #12603 from HabitRPG/dependabot/npm_and_yarn/website/client/bootstrap-vue-2.17.3
build(deps): bump bootstrap-vue from 2.17.0 to 2.17.3 in /website/client
2020-09-21 17:17:59 +02:00
Matteo Pagliazzi 87504f4d76 Merge pull request #12602 from HabitRPG/dependabot/npm_and_yarn/website/client/webpack-4.44.2
build(deps): bump webpack from 4.44.1 to 4.44.2 in /website/client
2020-09-21 17:17:49 +02:00
Matteo Pagliazzi 58a73dd62a 4.158.0 2020-09-21 16:27:24 +02:00
Matteo Pagliazzi 83aca20ce5 Fall Festival Gem Promo (#138)
* content: add gems blocks

* gemsBlocks: include ios and android identifiers

* wip: promo code

* split common constants into multiple files

* add second promo part

* geCurrentEvent, refactor promo

* fix lint

* fix exports, use world state api

* start adding world state tests

* remove console.log

* use gems block for purchases

* remove comments

* fix most unit tests

* restore comment

* fix lint

* prevent apple/google gift tests from breaking other tests when stub is not reset

* fix unit tests, clarify tests names

* iap: use gift object when gifting gems

* allow gift object with less data

* fix iap tests, remove findById stubs

* iap: require less data from the mobile apps

* apply discounts

* add missing worldState file

* fix lint

* add test event

* start removing 20 gems option for web

* start adding support for all gems packages on web

* fix unit tests for apple, stripe and google

* amazon: support all gems blocks

* paypal: support all gems blocks

* fix payments unit tests, add tests for getGemsBlock

* web: add gems plans with discounts, update stripe

* fix amazon and paypal clients, payments success modals

* amazon pay: disabled state

* update icons, start abstracting payments buttons

* begin redesign

* redesign gems modal

* fix buttons

* fix hover color for gems modal close icon

* add key to world state current event

* extend test event length

* implement gems modals designs

* early test fall2020

* fix header banner position

* add missing files

* use iso 8601 for dates, minor ui fixes

* fix time zones

* events: fix ISO8601 format

* fix css indentation

* start abstracting banners

* refactor payments buttons

* test spooky, fix group plans box

* implement gems promo banners, refactor banners, fixes

* fix lint

* fix dates

* remove unused i18n strings

* fix stripe integration test

* fix world state integration tests

* the current active event

* add missing unit tests

* add storybook story for payments buttons component

* fix typo

* fix(stripe): correct label when gifting subscriptions
2020-09-21 16:22:13 +02:00
dependabot-preview[bot] cd11d4c179 build(deps): bump bootstrap-vue from 2.17.0 to 2.17.3 in /website/client
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.17.0 to 2.17.3.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.17.0...v2.17.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-21 08:25:12 +00:00
dependabot-preview[bot] e821fab4a3 build(deps): bump webpack from 4.44.1 to 4.44.2 in /website/client
Bumps [webpack](https://github.com/webpack/webpack) from 4.44.1 to 4.44.2.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v4.44.1...v4.44.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-21 08:24:14 +00:00
Matteo Pagliazzi 82e6d544c8 fix(i18n) restore missing strings 2020-09-21 09:42:18 +02:00
Matteo Pagliazzi 70661da94d fix(settings.json): add back resetAccount string 2020-09-19 15:45:23 +02:00
Melior 069a133546 Merge branch 'origin/develop' into Weblate. 2020-09-17 22:40:48 +02:00
Sabe Jones 6e49831ab3 4.157.1 2020-09-17 15:34:26 -05:00
Sabe Jones 81cd09d0f5 chore(news): Bailey 2020-09-17 15:33:46 -05:00
Melior 1aca81d15d Translated using Weblate (Dutch)
Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Czech)

Currently translated at 89.3% (1913 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Hindi)

Currently translated at 11.5% (38 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/hi/

Translated using Weblate (Hindi)

Currently translated at 98.2% (55 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/hi/

Translated using Weblate (Hindi)

Currently translated at 85.9% (311 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/hi/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (63 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (63 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 96.5% (538 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 93.6% (59 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 93.6% (59 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 74.6% (47 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 74.6% (47 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/es_419/

Translated using Weblate (Hindi)

Currently translated at 10.9% (36 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/hi/

Translated using Weblate (Hindi)

Currently translated at 10.3% (34 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/hi/

Translated using Weblate (French)

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/

Translated using Weblate (French)

Currently translated at 100.0% (504 of 504 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/

Translated using Weblate (French)

Currently translated at 100.0% (716 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/

Translated using Weblate (French)

Currently translated at 100.0% (179 of 179 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/fr/

Translated using Weblate (French)

Currently translated at 98.8% (708 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 98.8% (708 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 98.4% (705 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 98.4% (705 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 98.3% (704 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (Dutch)

Currently translated at 99.9% (2139 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Spanish (Latin America))

Currently translated at 98.4% (323 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/es_419/

Translated using Weblate (Japanese)

Currently translated at 98.2% (547 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/

Translated using Weblate (Hindi)

Currently translated at 96.7% (90 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hi/

Translated using Weblate (German)

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (German)

Currently translated at 100.0% (716 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Ukrainian)

Currently translated at 38.7% (36 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Ukrainian)

Currently translated at 38.7% (36 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Russian)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/

Translated using Weblate (Russian)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/

Translated using Weblate (German)

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (Ukrainian)

Currently translated at 29.0% (27 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Ukrainian)

Currently translated at 29.0% (27 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Ukrainian)

Currently translated at 27.9% (26 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Ukrainian)

Currently translated at 27.9% (26 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Ukrainian)

Currently translated at 24.7% (23 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Ukrainian)

Currently translated at 24.7% (23 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/

Translated using Weblate (Hindi)

Currently translated at 75.5% (421 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/hi/

Translated using Weblate (Hindi)

Currently translated at 85.7% (120 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/hi/

Translated using Weblate (Hindi)

Currently translated at 92.4% (86 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hi/

Translated using Weblate (Hindi)

Currently translated at 79.4% (1701 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/hi/

Translated using Weblate (Hindi)

Currently translated at 90.3% (84 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hi/

Translated using Weblate (Hindi)

Currently translated at 3.9% (13 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/hi/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.9% (1734 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Italian)

Currently translated at 100.0% (504 of 504 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (716 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/it/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 92.4% (160 of 173 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/

Translated using Weblate (Russian)

Currently translated at 97.8% (493 of 504 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ru/

Translated using Weblate (German)

Currently translated at 100.0% (504 of 504 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.0% (709 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (716 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/

Translated using Weblate (German)

Currently translated at 99.0% (709 of 716 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 99.7% (361 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/ru/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (179 of 179 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 100.0% (179 of 179 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (179 of 179 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/pt_BR/
2020-09-17 20:06:09 +02:00
Melior dc558df0b1 Translated using Weblate (French)
Currently translated at 99.4% (172 of 173 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (504 of 504 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (362 of 362 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Greek)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/el/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (28 of 28 strings)

Translation: Habitica/Rebirth
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (140 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/vi/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 93.6% (469 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/nb_NO/

Translated using Weblate (Norwegian Bokmål)

Currently translated at 91.5% (194 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/nb_NO/

Translated using Weblate (Italian)

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/

Translated using Weblate (Dutch)

Currently translated at 96.4% (135 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/nl/

Translated using Weblate (Danish)

Currently translated at 85.7% (120 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/da/

Translated using Weblate (Italian)

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/it/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.4% (1723 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 97.1% (206 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es_419/

Translated using Weblate (Swedish)

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/sv/

Translated using Weblate (Turkish)

Currently translated at 93.6% (469 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/tr/

Translated using Weblate (Dutch)

Currently translated at 99.8% (2137 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Slovak)

Currently translated at 91.0% (193 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/sk/

Translated using Weblate (Dutch)

Currently translated at 99.0% (210 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/nl/

Translated using Weblate (Czech)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/cs/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.3% (1720 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.3% (1720 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.2% (1719 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.2% (1718 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Polish)

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pl/

Translated using Weblate (Polish)

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pl/

Translated using Weblate (Polish)

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pl/

Translated using Weblate (Polish)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pl/

Translated using Weblate (Dutch)

Currently translated at 83.9% (47 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/

Translated using Weblate (Dutch)

Currently translated at 90.3% (84 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/

Translated using Weblate (Dutch)

Currently translated at 99.8% (2137 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Spanish (Latin America))

Currently translated at 78.9% (199 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 96.2% (178 of 185 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.1% (1717 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 78.9% (199 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 96.2% (178 of 185 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 80.1% (1717 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 69.6% (39 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es_419/

Translated using Weblate (Korean)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/ko/

Translated using Weblate (Chinese (Hong Kong))

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/zh_Hant_HK/

Translated using Weblate (Hindi)

Currently translated at 97.3% (290 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/hi/

Translated using Weblate (Vietnamese)

Currently translated at 82.2% (1760 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/vi/

Translated using Weblate (Spanish (Latin America))

Currently translated at 79.7% (1708 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/es_419/

Translated using Weblate (Polish)

Currently translated at 100.0% (31 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/pl/

Translated using Weblate (Russian)

Currently translated at 95.6% (2048 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Portuguese)

Currently translated at 81.2% (1739 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt/

Translated using Weblate (Polish)

Currently translated at 80.8% (1732 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/

Translated using Weblate (Dutch)

Currently translated at 99.7% (2135 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Indonesian)

Currently translated at 79.5% (1703 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/id/

Translated using Weblate (Spanish)

Currently translated at 88.3% (1891 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/

Translated using Weblate (Romanian)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/ro/

Translated using Weblate (Bulgarian)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/bg/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Dutch)

Currently translated at 99.7% (2135 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Spanish)

Currently translated at 88.3% (1891 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/

Translated using Weblate (German)

Currently translated at 100.0% (708 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Spanish (Latin America))

Currently translated at 96.2% (536 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es_419/

Translated using Weblate (Dutch)

Currently translated at 99.7% (2135 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/

Translated using Weblate (Spanish (Latin America))

Currently translated at 95.1% (176 of 185 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es_419/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/zh_Hans/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/

Translated using Weblate (French)

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/fr/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (French)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/fr/

Translated using Weblate (French)

Currently translated at 100.0% (78 of 78 strings)

Translation: Habitica/Contrib
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/fr/

Translated using Weblate (French)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/fr/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (French)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/fr/

Translated using Weblate (Vietnamese)

Currently translated at 85.7% (48 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/vi/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/
2020-09-15 22:13:29 +02:00
Sabe Jones da6f275adc Merge branch 'release' into develop 2020-09-15 14:41:25 -05:00
Sabe Jones 633961e8a7 4.157.0 2020-09-15 14:40:01 -05:00
Sabe Jones 284d67b385 fix(sprites): mystery set
and Turquoise Bailey
2020-09-15 14:39:47 -05:00
Sabe Jones 78fe87055c fix(sprites): filenam fix 2/2 2020-09-14 16:14:42 -05:00
Sabe Jones d47bd198ca fix(sprites): filename fix part 1/2 2020-09-14 16:12:43 -05:00
Sabe Jones e82d532f58 chore(sprites): compile 2020-09-14 16:06:00 -05:00
Sabe Jones 34e87c4b3f feat(content): Turquoise Potion Quest 2020-09-14 16:05:54 -05:00
Matteo Pagliazzi a3193c56c1 fix(i18n): temporarily restore two strings 2020-09-14 17:22:39 +02:00
Raithe Of Dureya bf014ad781 Removed all maintenance.json files since no I18N string is being used 2020-09-14 15:57:04 +02:00
Raithe Of Dureya b1fc88d330 Removed unused I18N npc.json strings from all the other languages 2020-09-14 15:08:51 +02:00
Raithe Of Dureya 1e54a474b1 Removed unused I18N strings from the npc.json file (locales\en) 2020-09-14 14:46:45 +02:00
Matteo Pagliazzi bff7d9bab3 fix(market): remove dead code 2020-09-14 12:40:08 +02:00
Matteo Pagliazzi 99d6ce5bdb Removed unused I18N strings from the settings.json files (related to issue #9957) (#12552)
* Removed unused I18N strings from the `settings.json` file (locales/en)

* Remove `couponText` (duplicated) from locales/en

Note: "...coupon codes..."

* Removed `settings.json`'s unused I18N strings from all the other languages

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-09-14 12:21:37 +02:00
RaitheOfDureya b0817d7f53 Removed unused I18N strings from the subscriber.json files (related to issue #9957) (#12548)
* Removed unused I18N strings from the `subscriber.json` file (locales/en)

* Remove gemsPurchaseNote and subscriptionAlreadySubscribedLeadIn from locales/en

@paglias: "They're going to be removed in an upcoming PR"

* Removed `subscriber.json`'s unused I18N strings in all other languages
2020-09-14 12:21:19 +02:00
dependabot-preview[bot] 09622df94a build(deps): bump @vue/cli-plugin-router in /website/client (#12577)
Bumps [@vue/cli-plugin-router](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-router) from 4.5.4 to 4.5.6.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.6/packages/@vue/cli-plugin-router)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:12:17 +02:00
dependabot-preview[bot] 7d0c97ae09 build(deps): bump @vue/cli-plugin-babel in /website/client (#12578)
Bumps [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel) from 4.5.4 to 4.5.6.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.6/packages/@vue/cli-plugin-babel)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:08:49 +02:00
dependabot-preview[bot] ac64ad63bb build(deps): bump @vue/cli-plugin-unit-mocha in /website/client (#12576)
Bumps [@vue/cli-plugin-unit-mocha](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-unit-mocha) from 4.5.4 to 4.5.6.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.6/packages/@vue/cli-plugin-unit-mocha)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:08:35 +02:00
dependabot-preview[bot] 166ed6e237 build(deps): [security] bump bl from 1.2.2 to 1.2.3 (#12568)
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3. **This update includes a security fix.**
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:06:23 +02:00
dependabot-preview[bot] 59d0ce1dfb build(deps): bump got from 11.6.0 to 11.6.2 (#12571)
Bumps [got](https://github.com/sindresorhus/got) from 11.6.0 to 11.6.2.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.6.0...v11.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:06:04 +02:00
dependabot-preview[bot] 1d44e0e6fa build(deps): bump moment from 2.27.0 to 2.28.0 (#12574)
Bumps [moment](https://github.com/moment/moment) from 2.27.0 to 2.28.0.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.27.0...2.28.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:05:43 +02:00
dependabot-preview[bot] 780c2857b1 build(deps): bump bootstrap-vue from 2.16.0 to 2.17.0 in /website/client (#12575)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.16.0 to 2.17.0.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.16.0...v2.17.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:05:36 +02:00
dependabot-preview[bot] ca995648f4 build(deps): bump moment from 2.27.0 to 2.28.0 in /website/client (#12579)
Bumps [moment](https://github.com/moment/moment) from 2.27.0 to 2.28.0.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.27.0...2.28.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:05:09 +02:00
dependabot-preview[bot] 0c03093173 build(deps): bump @vue/cli-plugin-eslint in /website/client (#12581)
Bumps [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) from 4.5.4 to 4.5.6.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.6/packages/@vue/cli-plugin-eslint)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:04:58 +02:00
dependabot-preview[bot] 4183cfb8a0 build(deps): bump @vue/cli-service in /website/client (#12582)
Bumps [@vue/cli-service](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-service) from 4.5.4 to 4.5.6.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.6/packages/@vue/cli-service)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-14 12:04:46 +02:00
Matteo Pagliazzi 0837d17616 fix(client): use correct interpolation format for strings 2020-09-12 19:08:42 +02:00
Matteo Pagliazzi 52667661c6 fix(overview): use correct indentation 2020-09-12 17:25:16 +02:00
Sabe Jones 9adf5160fe Merge branch 'release' into develop 2020-09-11 12:56:23 -05:00
Sabe Jones da796c305d 4.156.3 2020-09-11 12:56:06 -05:00
Matteo Pagliazzi 953c84260f fix(tasks and groupd): do not apply default due filter to challenges, fix edge case in group loading 2020-09-11 19:53:28 +02:00
Vipul Khandelwal c133445ff6 Fixed Privacy Policy anchor tag target attribute (#12554)
* Fixed Privacy Policy and terms anchor tag target attribute from blanck to blank

* Fixed one more Privacy Policy anchor tag target attribute from blanck to blank
2020-09-11 12:32:59 +02:00
RaitheOfDureya f311fe201b Removed unused I18N strings from the tasks.json file (related to issue #9957) (#12526)
* Remove sureDeleteCompletedTodos

* Remove lotOfToDos

* Remove deleteToDosExplanation

* Remove addsingle

* Remove newHabit and newHabitBulk

* Remove habitsDesc

* Remove checklistText

\bchecklistText\b - No Results

* Remove expandChecklist

* Remove extraNotes

* Remove direction/Actions

* Remove attributeAllocation and attributeAllocationHelp

* Remove newDaily, newDailyBulk and dailysDesc

* Remove repeatHelpTitle

* Remove dailyRepeatHelpContent and weeklyRepeatHelpContent

* Remove repeatDays and repeatDaysWeek

* Remove newTodo

\bnewTodo\b

* Remove newTodoBulk and todosDesc

* Remove dated

* Remove rewardsDesc

\brewardsDesc\b - No Results

* Remove ingamerewards

* Remove newReward and newRewardBulk

* Remove clearTags, hideTags and showTags

* Remove startDateHelpTitle and startDateHelp

* Remove streakerAchievement

* Remove fortifyText

* Remove confirmFortify

* Remove emptyTask

* Remove dailiesRestingInInn

* Remove habitHelp1, habitHelp2 and habitHelp3

* Remove newbieGuild

* Remove dailyHelp1 to dailyHelp5

* Remove toDoHelp1 to toDoHelp4

* Remove rewardHelp1 to rewardHelp4

* Remove clickForHelp

* Remove strengthExample, intelligenceExample, perceptionExample and constitutionExample

* Remove counterPeriod, counterPeriodDay, counterPeriodWeek and counterPeriodMonth

* Remove habitCounter, habitCounterUp and habitCounterDown

* Remove repeatZero, repeatType, repeatTypeHelpTitle and repeatTypeHelp

* Remove onDays

* Remove groupTasksByChallenge

* Remove taskNotes

\btaskNotes\b - No Results

* Remove monthlyRepeatHelpContent and yearlyRepeatHelpContent

* Remove summaryStart

* Remove yesterDailiesTitle, yesterDailiesOptionTitle and yesterDailiesDescription

* Remove repeatDayError and searchTasks

* Revert "Remove habitsDesc"

This reverts commit a9d8f4089c526bc7e7d0fdc90b1b911d19dff9c2.

* Revert "Remove todosDesc"

* Revert "Remove dailysDesc"

* Revert "Remove rewardsDesc"

* Revert "Remove expandChecklist"

This reverts commit 62f3bbea2dc8340018c01efdc7ffcf4c6b3d46ae.

* Remove taskAlias, taskAliasPopover, taskAliasPlaceholder and taskAliasPopoverWarning

> @paglias: "regarding the alias-related keys you can remove them"

* Removed unused I18N strings from the `tasks.json` file in all other languages

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-09-11 12:31:47 +02:00
Scott 5716b4eb72 Frontend support and adjustments of current banned words blocking code to support new implementation (Fixes #12405) (#12496)
* Added the "Allow banned words" checkbox to create/update guild forms

Added the "Allow banned words" checkbox to guild create/update forms which are only visible to Admins

* Updated create/update group API to include bannedWordsAllowed property

Added logic to set bannedWordsAllowed depending on conditions

* Updated word banning logic to use bannedWordsAllowed guild value instead

Updated word banning logic to use bannedWordsAllowed guild value and deleted hardcoded guild file & import

* Updated banned words test

* Pull Request amends

Removed the setting of bannedWordsAllowed during group creation
Added v-once to elements
Updated existing test and added tests related to bannedWordsAllowed functionality

* Small amend

* Small amend

Removed leftover code that was left during testing
2020-09-11 10:29:30 +02:00
dependabot-preview[bot] c89f66e4b8 build(deps): [security] bump node-fetch from 2.6.0 to 2.6.1 (#12557)
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. **This update includes a security fix.**
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-11 10:07:02 +02:00
Melior 503d79b320 Merge branch 'origin/develop' into Weblate. 2020-09-10 22:16:40 +02:00
Sabe Jones be58c8193e 4.156.2 2020-09-10 15:14:14 -05:00
Sabe Jones 60ce16bf08 chore(news): bailey 2020-09-10 15:14:04 -05:00
Sabe Jones 83ec53c614 Merge branch 'develop' into release 2020-09-10 15:06:51 -05:00
Melior d7b251c5eb Translated using Weblate (French)
Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/fr/

Translated using Weblate (Latin)

Currently translated at 81.6% (455 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/la/

Translated using Weblate (French)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/fr/

Translated using Weblate (French)

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (Czech)

Currently translated at 89.0% (1907 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (French)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/fr/

Translated using Weblate (French)

Currently translated at 100.0% (230 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/fr/

Translated using Weblate (French)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 99.6% (555 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 99.6% (555 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 99.2% (553 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 99.2% (553 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 98.9% (551 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (Latin)

Currently translated at 98.2% (226 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/la/

Translated using Weblate (Latin)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/la/

Translated using Weblate (Polish)

Currently translated at 90.7% (196 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pl/

Translated using Weblate (Polish)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/pl/

Translated using Weblate (German)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/

Translated using Weblate (Italian)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/it/

Translated using Weblate (Dutch)

Currently translated at 99.6% (2133 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Italian)

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (German)

Currently translated at 100.0% (2141 of 2141 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (Russian)

Currently translated at 99.1% (552 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (557 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/

Translated using Weblate (German)

Currently translated at 99.8% (556 of 557 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
2020-09-10 21:43:17 +02:00
Sabe Jones 5fa140376e fix(sprites): pixel scoot 2020-09-10 09:33:47 -05:00
Matteo Pagliazzi 79b218ecf0 Merge branch 'release' of github.com:HabitRPG/habitica into develop 2020-09-10 11:40:25 +02:00
Matteo Pagliazzi e2442fe56d fix(test): tag.challenge is a boolean 2020-09-10 11:39:19 +02:00
Matteo Pagliazzi d9e85b329f 4.156.1 2020-09-10 11:17:54 +02:00
Matteo Pagliazzi 05f22ababc fix(challenge tags); change type to Mixed in preparation for migration 2020-09-10 11:14:09 +02:00
Matteo Pagliazzi 405ef7a3ba Merge branch 'develop' into remove-unused-settings 2020-09-09 12:05:32 +02:00
Melior b61162e475 Merge branch 'origin/develop' into Weblate. 2020-09-08 23:16:12 +02:00
Sabe Jones d7cc317208 Merge branch 'release' into develop 2020-09-08 16:11:29 -05:00
Sabe Jones 9f988acb55 4.156.0 2020-09-08 16:10:36 -05:00
Sabe Jones eec57cb9b8 chore(sprites): compile 2020-09-08 16:10:17 -05:00
Sabe Jones f5eb868763 feat(content): Backgrounds and Armoire items 2020-09-08 16:10:01 -05:00
Raithe Of Dureya 7f67d5a8a6 Removed settings.json's unused I18N strings from all the other languages 2020-09-08 19:38:11 +02:00
Raithe Of Dureya 731b241b46 Remove couponText (duplicated) from locales/en
Note: "...coupon codes..."
2020-09-08 19:18:28 +02:00
Raithe Of Dureya 912fef88a0 Removed unused I18N strings from the settings.json file (locales/en) 2020-09-08 19:12:51 +02:00
Matteo Pagliazzi 96d22e54f8 fix(task creation): correctly clone selected tags array, fixes #12447 2020-09-08 12:52:09 +02:00
Melior 03bf7b7d59 Translated using Weblate (Dutch)
Currently translated at 99.8% (2131 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Czech)

Currently translated at 89.0% (1902 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Dutch)

Currently translated at 99.7% (2129 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Japanese)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (708 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 99.4% (704 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/

Translated using Weblate (German)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/de/

Translated using Weblate (English (Pirate))

Currently translated at 96.4% (483 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/en@pirate/

Translated using Weblate (Italian)

Currently translated at 100.0% (2135 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (English (Pirate))

Currently translated at 99.6% (297 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/en@pirate/

Translated using Weblate (Italian)

Currently translated at 100.0% (708 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/vi/

Translated using Weblate (German)

Currently translated at 100.0% (2135 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (German)

Currently translated at 94.6% (53 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/de/

Translated using Weblate (German)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/vi/

Translated using Weblate (Spanish)

Currently translated at 93.9% (665 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/es/

Translated using Weblate (Spanish)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/

Translated using Weblate (Spanish)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/

Translated using Weblate (Spanish)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es/

Translated using Weblate (Italian)

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (708 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (2135 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/

Translated using Weblate (Italian)

Currently translated at 99.5% (705 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 98.6% (144 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 97.1% (206 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es_419/

Translated using Weblate (French)

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/

Translated using Weblate (German)

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/

Translated using Weblate (Spanish (Latin America))

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/es_419/

Translated using Weblate (Spanish (Latin America))

Currently translated at 93.8% (199 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/es_419/

Translated using Weblate (German)

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/

Translated using Weblate (French)

Currently translated at 100.0% (2135 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (German)

Currently translated at 99.8% (2131 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (French)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/fr/

Translated using Weblate (Russian)

Currently translated at 98.7% (699 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (708 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (German)

Currently translated at 99.5% (705 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/de/

Translated using Weblate (Russian)

Currently translated at 99.7% (360 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/fr/

Translated using Weblate (German)

Currently translated at 100.0% (361 of 361 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/de/

Translated using Weblate (Russian)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/

Translated using Weblate (French)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/

Translated using Weblate (German)

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
2020-09-08 10:44:22 +02:00
Matteo Pagliazzi 78016c0aeb fix(modals): apply base styles everywhere, fixes #12524 2020-09-07 21:24:58 +02:00
tsukimi2 b0786647ed Bugfix challenge tags to normal tags after a challenge has ended/deleted (#12341)
* Fix bug in challenge tags not converted to normal tags after challenge ended/deleted

* Added test cases to test bug fix

* Set tag.challenge from String to Boolean in tag model schema

* Update existing test with tag challenge set to boolean instead of string

* Added migration file for converting tag challenge field from string to bool

* Implement suggestions from ilnt

* Use mongoose instead of Mock in migration

* Change from update to bulkwrite

* update users individually

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-09-07 16:48:22 +02:00
Kirsty 1b25d30ac6 Correctly filter tasks in challenges and remove filters where unhelpful (#12522)
* Correctly filter tasks in challenges and remove filters where unhelpful

* update isDue property on the client as soon as challenges are created or edited

* change method of update for task on receiving data

* try different assign method

* fix lint

* fix issue with data reactivity

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-09-07 16:11:28 +02:00
Matteo Pagliazzi 362677acb8 fix(checklists): correctly hide original input in disabled state, fixes #12528 2020-09-07 15:42:04 +02:00
Kirsty d37c156fa0 Filter challenge by owned (#12527)
* when filtering by owned challenges, challenges that a user owns but has not joined will be included

* add tests for filtering challenges by owned

* fix lint
2020-09-07 15:30:01 +02:00
dependabot-preview[bot] e5ccb634e0 build(deps): bump @babel/core from 7.11.4 to 7.11.6 (#12536)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.11.4 to 7.11.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.6/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:59:03 +02:00
dependabot-preview[bot] cea6cbad50 build(deps): bump image-size from 0.8.3 to 0.9.1 (#12538)
Bumps [image-size](https://github.com/image-size/image-size) from 0.8.3 to 0.9.1.
- [Release notes](https://github.com/image-size/image-size/releases)
- [Commits](https://github.com/image-size/image-size/compare/v0.8.3...v0.9.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:57:00 +02:00
dependabot-preview[bot] 68584e25c1 build(deps): bump @babel/preset-env from 7.11.0 to 7.11.5 (#12534)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.11.0 to 7.11.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.5/packages/babel-preset-env)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:55:31 +02:00
dependabot-preview[bot] fbab46eab0 build(deps-dev): bump monk from 7.3.1 to 7.3.2 (#12533)
Bumps [monk](https://github.com/Automattic/monk) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/Automattic/monk/releases)
- [Changelog](https://github.com/Automattic/monk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/monk/compare/v7.3.1...v7.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:55:25 +02:00
dependabot-preview[bot] 2740c02f35 build(deps): bump mongoose from 5.10.2 to 5.10.3 (#12532)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.10.2 to 5.10.3.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.10.2...5.10.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:55:16 +02:00
dependabot-preview[bot] ffb51fc18b build(deps): bump habitica-markdown from 2.0.2 to 3.0.0 (#12537)
Bumps [habitica-markdown](https://github.com/HabitRPG/habitica-markdown) from 2.0.2 to 3.0.0.
- [Release notes](https://github.com/HabitRPG/habitica-markdown/releases)
- [Commits](https://github.com/HabitRPG/habitica-markdown/compare/v2.0.2...v3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:53:58 +02:00
dependabot-preview[bot] d19fb4f489 build(deps): bump got from 11.5.2 to 11.6.0 (#12539)
Bumps [got](https://github.com/sindresorhus/got) from 11.5.2 to 11.6.0.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.5.2...v11.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:53:42 +02:00
dependabot-preview[bot] 49bfe386a6 build(deps): [security] bump serialize-javascript in /website/client (#12542)
Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) from 3.0.0 to 3.1.0. **This update includes a security fix.**
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v3.0.0...v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:53:32 +02:00
dependabot-preview[bot] 93ee579bbf build(deps): bump @babel/register from 7.10.5 to 7.11.5 (#12541)
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.10.5 to 7.11.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.5/packages/babel-register)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:52:48 +02:00
dependabot-preview[bot] f9ed36a9f2 build(deps): bump habitica-markdown in /website/client (#12545)
Bumps [habitica-markdown](https://github.com/HabitRPG/habitica-markdown) from 2.0.2 to 3.0.0.
- [Release notes](https://github.com/HabitRPG/habitica-markdown/releases)
- [Commits](https://github.com/HabitRPG/habitica-markdown/compare/v2.0.2...v3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-09-07 11:52:29 +02:00
Matteo Pagliazzi e965f6a28f Merge branch 'release' into develop 2020-09-05 13:10:57 +02:00
Sabe Jones d98932e183 4.155.2 2020-09-04 17:30:54 -05:00
Sabe Jones a91c2f7c7c fix(settings): revert axios version due to account delete issue 2020-09-04 17:30:46 -05:00
Mike-Antonacci 5122d137b0 Change spellRogueStealthMaxedOut and spellAlreadyCast to a clearer wo… (#12497)
* Change spellRogueStealthMaxedOut and spellAlreadyCast to a clearer wording

* Restore package-lock.json and Delete string spellRogueStealthMaxedOut

* remove unused string, restore package-lock.json changes

* restore client package-lock.json

* Change spellRogueStealthMaxedOut and spellAlreadyCast to a clearer wording

* Restore package-lock.json and Delete string spellRogueStealthMaxedOut

* remove unused string, restore package-lock.json changes

* restore client package-lock.json

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-09-04 12:21:50 +02:00
Sabe Jones 70d057e66c 4.155.1 2020-09-03 17:22:54 -05:00
Sabe Jones b680b6026b fix(teams): don't adjust source task value for rewards Fixes #12523 2020-09-03 10:00:32 -05:00
Matteo Pagliazzi 0c3b16ca74 fix(task modal): make sure task is loaded when template is shown 2020-09-03 16:33:44 +02:00
Melior 7be039a35f Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.7% (706 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (252 of 252 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (501 of 501 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2135 of 2135 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.2% (703 of 708 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (93 of 93 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Italian)

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (Dutch)

Currently translated at 99.8% (2127 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (French)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/

Translated using Weblate (Greek)

Currently translated at 73.2% (41 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/el/

Translated using Weblate (Greek)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/el/

Translated using Weblate (Greek)

Currently translated at 100.0% (6 of 6 strings)

Translation: Habitica/Inventory
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/el/

Translated using Weblate (Greek)

Currently translated at 79.8% (1702 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/el/

Translated using Weblate (Greek)

Currently translated at 100.0% (70 of 70 strings)

Translation: Habitica/Contrib
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/el/

Translated using Weblate (Greek)

Currently translated at 100.0% (4 of 4 strings)

Translation: Habitica/Noscript
Translate-URL: https://translate.habitica.com/projects/habitica/noscript/el/

Translated using Weblate (Greek)

Currently translated at 100.0% (27 of 27 strings)

Translation: Habitica/Loginincentives
Translate-URL: https://translate.habitica.com/projects/habitica/loginincentives/el/

Translated using Weblate (Czech)

Currently translated at 88.9% (1895 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (French)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (Russian)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ru/

Translated using Weblate (Japanese)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ja/

Translated using Weblate (Italian)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/it/

Translated using Weblate (Russian)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ru/

Translated using Weblate (Russian)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/vi/

Translated using Weblate (English (Pirate))

Currently translated at 87.5% (7 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/en@pirate/

Translated using Weblate (French)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (French)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/fr/

Translated using Weblate (English (Pirate))

Currently translated at 85.8% (79 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en@pirate/

Translated using Weblate (French)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/vi/

Translated using Weblate (French)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/fr/

Translated using Weblate (French)

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/fr/

Translated using Weblate (French)

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (French)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/fr/

Translated using Weblate (French)

Currently translated at 100.0% (134 of 134 strings)

Translation: Habitica/Challenge
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/fr/

Translated using Weblate (French)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/

Translated using Weblate (French)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/

Translated using Weblate (Vietnamese)

Currently translated at 82.5% (1760 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/vi/

Translated using Weblate (Latin)

Currently translated at 39.6% (25 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/la/

Translated using Weblate (Russian)

Currently translated at 98.2% (56 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/ru/

Translated using Weblate (Russian)

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ru/

Translated using Weblate (Russian)

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ru/

Translated using Weblate (Russian)

Currently translated at 99.6% (548 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/

Translated using Weblate (Russian)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/

Translated using Weblate (Russian)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/

Translated using Weblate (Czech)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/cs/

Translated using Weblate (English (Pirate))

Currently translated at 88.0% (191 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/en@pirate/

Translated using Weblate (Czech)

Currently translated at 88.3% (1883 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Japanese)

Currently translated at 91.0% (51 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Portuguese)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/

Translated using Weblate (Czech)

Currently translated at 86.7% (1849 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hant/

Translated using Weblate (Portuguese)

Currently translated at 87.2% (480 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hant/

Translated using Weblate (Italian)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/it/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hant/

Translated using Weblate (Italian)

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/it/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/en_GB/

Translated using Weblate (Czech)

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/cs/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (185 of 185 strings)

Translation: Habitica/Limited
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/

Translated using Weblate (Italian)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/

Translated using Weblate (Turkish)

Currently translated at 80.0% (1706 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/tr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Italian)

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/en_GB/

Translated using Weblate (Italian)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/it/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/en_GB/

Translated using Weblate (Italian)

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/it/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hant/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/

Translated using Weblate (Italian)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en_GB/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 99.5% (216 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ru/

Translated using Weblate (German)

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/de/

Translated using Weblate (Russian)

Currently translated at 95.2% (239 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/zh_Hans/

Translated using Weblate (German)

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 98.4% (492 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ru/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 96.1% (2048 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2131 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (German)

Currently translated at 99.8% (2128 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 92.8% (52 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 94.6% (53 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/

Translated using Weblate (German)

Currently translated at 98.2% (55 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/de/

Translated using Weblate (Turkish)

Currently translated at 99.1% (228 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/tr/

Translated using Weblate (Turkish)

Currently translated at 99.1% (228 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/tr/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 98.7% (543 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (550 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/

Translated using Weblate (German)

Currently translated at 99.8% (549 of 550 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/

Translated using Weblate (Russian)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/

Translated using Weblate (German)

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/

Translated using Weblate (Turkish)

Currently translated at 99.5% (229 of 230 strings)

Translation: Habitica/Character
Translate-URL: https://translate.habitica.com/projects/habitica/character/tr/
2020-09-01 19:42:34 +02:00
Sabe Jones 01ae56f944 Merge branch 'release' into develop 2020-09-01 11:10:26 -05:00
Sabe Jones 7b020e133f 4.155.0 2020-09-01 11:09:37 -05:00
Sabe Jones ca413ff41a chore(sprites): compile 2020-09-01 11:08:50 -05:00
Sabe Jones 81eef79da4 feat(content): Mystery Items and Challenges 2020-09-01 11:08:41 -05:00
negue f1469b52f6 hotfix datepicker size 2020-08-31 23:13:31 +02:00
Matteo Pagliazzi ef118f23c2 fix(loading): do not shift loading screen 2020-08-31 16:54:31 +02:00
dependabot-preview[bot] 964861bd6c build(deps-dev): bump axios from 0.19.2 to 0.20.0 (#12492)
Bumps [axios](https://github.com/axios/axios) from 0.19.2 to 0.20.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.19.2...v0.20.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 14:10:32 +02:00
dependabot-preview[bot] 32e9dbe1ed build(deps): bump @vue/cli-plugin-unit-mocha in /website/client (#12513)
Bumps [@vue/cli-plugin-unit-mocha](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-unit-mocha) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.4/packages/@vue/cli-plugin-unit-mocha)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:25:28 +02:00
dependabot-preview[bot] 466fb4e42e build(deps): bump axios from 0.19.2 to 0.20.0 in /website/client (#12516)
Bumps [axios](https://github.com/axios/axios) from 0.19.2 to 0.20.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/master/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.19.2...v0.20.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:24:47 +02:00
dependabot-preview[bot] 8f923f7753 build(deps): bump mongoose from 5.9.29 to 5.10.2 (#12503)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.29 to 5.10.2.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.29...5.10.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:24:01 +02:00
Matteo Pagliazzi 3bb8db45fd build(deps): bump @vue/cli-plugin-eslint in /website/client (#12510)
Bumps [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.4/packages/@vue/cli-plugin-eslint)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:22:56 +02:00
dependabot-preview[bot] 181317dbff build(deps): bump @vue/cli-plugin-eslint in /website/client
Bumps [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.4/packages/@vue/cli-plugin-eslint)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-31 11:22:44 +00:00
dependabot-preview[bot] 73a7ef8b2c build(deps): bump vue and vue-template-compiler in /website/client (#12511)
Bumps [vue](https://github.com/vuejs/vue) and [vue-template-compiler](https://github.com/vuejs/vue). These dependencies needed to be updated together.

Updates `vue` from 2.6.11 to 2.6.12
- [Release notes](https://github.com/vuejs/vue/releases)
- [Commits](https://github.com/vuejs/vue/compare/v2.6.11...v2.6.12)

Updates `vue-template-compiler` from 2.6.11 to 2.6.12
- [Release notes](https://github.com/vuejs/vue/releases)
- [Commits](https://github.com/vuejs/vue/compare/v2.6.11...v2.6.12)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:21:15 +02:00
dependabot-preview[bot] 206e3468f4 build(deps): bump vuedraggable from 2.24.0 to 2.24.1 in /website/client (#12520)
Bumps [vuedraggable](https://github.com/SortableJS/Vue.Draggable) from 2.24.0 to 2.24.1.
- [Release notes](https://github.com/SortableJS/Vue.Draggable/releases)
- [Commits](https://github.com/SortableJS/Vue.Draggable/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:17:49 +02:00
dependabot-preview[bot] 77fde9d73f build(deps): bump amplitude-js from 7.1.0 to 7.1.1 in /website/client (#12517)
Bumps [amplitude-js](https://github.com/amplitude/amplitude-javascript) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/amplitude/amplitude-javascript/releases)
- [Changelog](https://github.com/amplitude/Amplitude-JavaScript/blob/master/CHANGELOG.md)
- [Commits](https://github.com/amplitude/amplitude-javascript/compare/v7.1.0...v7.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:17:25 +02:00
dependabot-preview[bot] c1d4bcbac3 build(deps): bump @vue/cli-service in /website/client (#12514)
Bumps [@vue/cli-service](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-service) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.4/packages/@vue/cli-service)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:17:05 +02:00
dependabot-preview[bot] e98d0d88d9 build(deps): bump @storybook/addon-notes in /website/client (#12512)
Bumps [@storybook/addon-notes](https://github.com/storybookjs/storybook/tree/HEAD/addons/notes) from 5.3.19 to 5.3.21.
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/v5.3.21/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v5.3.21/addons/notes)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:16:39 +02:00
dependabot-preview[bot] fc3a1dd93d build(deps): bump @vue/cli-plugin-router in /website/client (#12509)
Bumps [@vue/cli-plugin-router](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-router) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.4/packages/@vue/cli-plugin-router)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:16:07 +02:00
dependabot-preview[bot] 897155e4c8 build(deps): bump @vue/cli-plugin-babel in /website/client (#12506)
Bumps [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel) from 4.5.3 to 4.5.4.
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v4.5.4/packages/@vue/cli-plugin-babel)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:15:55 +02:00
dependabot-preview[bot] 689f5ad634 build(deps): bump superagent from 6.0.0 to 6.1.0 (#12502)
Bumps [superagent](https://github.com/visionmedia/superagent) from 6.0.0 to 6.1.0.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v6.0.0...v6.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-31 13:15:45 +02:00
negue aa1ea74daa datepicker: add clear button (#12480)
* datepicker: add clear button

* use close icon instead of "x" as text
2020-08-29 17:22:31 +02:00
Bart Enkelaar 1b301e9c68 issue(11266) - Restyle level-up modal with sparkles (#12486)
* issue(11266) - Restyle level-up modal with sparkles

* issue(11266) - Add reward display to level up modal

At levels 15, 30, 40 and 60 the earned quests are now shown in the level-up modal.

* issue(11266) - Simplify css and don't use custom footer

* issue(11266) - Don't show pink bars and use colour variables
2020-08-29 16:33:06 +02:00
Matteo Pagliazzi c00b2247d4 fix #12498: do not score task when using a skill 2020-08-29 16:23:32 +02:00
Alys 88de5552a0 change blocked message 2020-08-29 18:03:59 +10:00
Sabe Jones 917c68d51f 4.154.1 2020-08-27 14:44:49 -05:00
Sabe Jones 44e438303a chore(news): Last Chance 2020-08-27 14:44:43 -05:00
Sabe Jones 7eeddcb033 Merge branch 'release' into develop 2020-08-25 16:05:40 -05:00
Sabe Jones 2fb8e16e8f 4.154.0 2020-08-25 16:05:13 -05:00
Sabe Jones 80ffcddb35 chore(sprites): compile 2020-08-25 16:04:35 -05:00
Sabe Jones f4c453675b feat(content): Wind-Up Potions quest 2020-08-25 16:04:28 -05:00
Alys 5165d491b0 fix some lint warnings (#12488)
* prevent some lint warnings by turning off some rules we don't seem to care about

require-prop-types has 167 violations

require-default-prop has 93 violations

* fix some lint warnings by adding eslint-disable-line comments

* prevent lint warnings by moving vue hooks to a different order

* apply some automatic lint fixes

* fix lint error by making line shorter

* prevent lint warnings from whitespace and @input, @click positioning

* revert 723fa38271

Reenables vue/require-prop-types and vue/require-default-prop
2020-08-25 18:06:39 +02:00
Sara Olson 6559353613 Update faq.json
some more android and ios faq changes
2020-08-25 18:01:37 +02:00
Matteo Pagliazzi 9caacc8f6c fix(links): restore styles changed in bootstrap@4.5.1 2020-08-25 16:17:12 +02:00
dependabot-preview[bot] b21b5a4f4b build(deps): bump jwks-rsa from 1.8.1 to 1.9.0 (#12493)
Bumps [jwks-rsa](https://github.com/auth0/node-jwks-rsa) from 1.8.1 to 1.9.0.
- [Release notes](https://github.com/auth0/node-jwks-rsa/releases)
- [Changelog](https://github.com/auth0/node-jwks-rsa/blob/master/CHANGELOG.md)
- [Commits](https://github.com/auth0/node-jwks-rsa/compare/v1.8.1...v1.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-24 18:23:12 +02:00
dependabot-preview[bot] 21f3e704d4 build(deps): bump @babel/core from 7.11.1 to 7.11.4 (#12489)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.11.1 to 7.11.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.4/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-24 14:26:14 +02:00
Matteo Pagliazzi d0bc0dbe49 Add API Call to bulk score tasks (#11389)
* Add new API call to complete multiple task scorings in one call

* Improve API response

* Improve saving process

* Improve handling for multiple tasks scored at once

* Handle challenge task errors better

* Improve check for alias

* Improve check for task scorings

* Fix merge errors

* make nodemon ignore content_cache

* Fix completing group tasks

* fix test

* fix tests (again)

* typo

* WIP(a11y): task modal updates

* fix(tasks): borders in modal

* fix(tasks): circley locks

* fix(task-modal): placeholders

* WIP(task-modal): disabled states, hide empty options, +/- restyle

* fix(task-modal): box shadows instead of borders, habit control pointer

* fix(task-modal): button states?

* fix(modal): tighten up layout, new spacing utils

* fix(tasks): more stylin

* fix(tasks): habit hovers

* fix(css): checklist labels, a11y colors

* fix(css): one more missed hover issue

* fix(css): lock Challenges, label fixes

* fix(css): scope input/textarea changes

* fix(style): task tweakies

* fix(style): more button fixage

* WIP(component): start select list story

* working example of a templated selectList

* fix(style): more button corrections

* fix(lint): EOL

* fix(buttons): factor btn-secondary to better override Bootstrap

* fix(styles): standardize more buttons

* wip: difficulty select - style fixes

* selectDifficulty works! 🎉 - fix styles

* change the dropdown-item sizes only for the selectList ones

* selectTranslatedArray

* changed many label margins

* more correct dropdown style

* fix(modals): button corrections

* input-group styling + datetime picker without today button

* Style/margins for "repeat every" - extract selectTag.vue

* working tag-selection / update - cleanup

* fix stories

* fix svg color on create modal (purple)

* fix task modal bottom padding

* correct dropdown shadow

* update dropdown-toggle caret size / color

* fixed checklist style

* sync checked state

* selectTag padding

* fix spacing between positive/negative streak inputs

* toggle-checkbox + fix some spacings

* disable repeat-on when its a groupTask

* fix new checklist-item

* fix toggle-checkbox style - fix difficulty style

* fix checklist ui

* add tags label , when there arent any tags selected

* WORKING select-tag component 🎉

* fix taglist story

* show max 5 items in tag dropdown + "X more" label

* fix datetime clear button

* replace m-b-xs to mb-1 (bootstrap) - fix input-group-text style

* fix styles of advanced settings

* fix delete task styles

* always show grippy on hover of the item

* extract modal-text-input mixin + fix the borders/dropshadow

* fix(spacing): revert most to Bootstrap

* feat(checklists): make local copy of master checklist non-editable
also aggressively update checklists because they weren't syncing??

* fix(checklists): handle add/remove options better

* feat(teams): manager notes field

* fix select/dropdown styles

* input border + icon colors

* delete task underline color

* fix checklist "delete icon" vertical position

* selectTag fixes - normal open/close toggle working again - remove icon color

* fixing icons:

Trash can - Delete
Little X - Remove
Big X - Close
Block - Block

* fix taglist margins / icon sizes

* wip margin overview (in storybook)

* fix routerlink

* remove unused method

* new selectTag style + add markdown inside tagList + scrollable tag selection

* fix selectTag / selectList active border

* fix difficulty select (svg default color)

* fix input padding-left + fix reset habit streak fullwidth / padding + "repeat every" gray text (no border)

* feat(teams): improved approval request > approve > reward flow

* fix(tests): address failures

* fix(lint): oops only

* fix(tasks): short-circuit group related logic

* fix(tasks): more short circuiting

* fix(tasks): more lines, less lint

* fix(tasks): how do i keep missing these

* feat(teams): provide assigning user summary

* fix(teams): don't attempt to record assiging user if not supplied

* fix advanced-settings styling / margin

* fix merge + hide advanced streak settings when none enabled

* fix styles

* set Roboto font for advanced settings

* Add Challenge flag to the tag list

* add tag with enter, when no other tag is found

* fix styles + tag cancel button

* refactor footer / margin

* split repeat fields into option mt-3 groups

* button all the things

* fix(tasks): style updates
* no hover state for non-editable tasks on team board
* keep assign/claim footer on task after requesting approval
* disable more fields on user copy of team task, and remove hover states 
for them

* fix(tasks): functional revisions
* "Claim Rewards" instead of "x" in task approved notif
* Remove default transition supplied by Bootstrap, apply individually to 
some elements
* Delete individual tasks and related notifications when master task 
deleted from team board
* Manager notes now save when supplied at task initial creation
* Can no longer dismiss rewards from approved task by hitting Dismiss 
All

* fix(tasks): clean tasksOrder
also adjust related test expectation

* fix(tests): adjust integration expectations

* fix(test): ratzen fratzen only

* fix lint

* fix tests

* fix(teams): checklist, notes

* handleSharedCompletion: handle error, make sure it is run after the user task has been saved

* fix typo

* correctly handle errors in handleSharedCompletion when approving a task

* fix(teams): improve disabled states

* handleSharedCompletion: do not increase completions by 1 manually to adjust for last approval not saved yet

* revert changes to config.json.example

* fix(teams): more style fixage

* add unit tests for findMultipleByIdOrAlias

* exclude api v4 route from apidocs

* BREAKING(teams): return 202 instead of 401 for approval request

* fix(teams): better taskboard sync
also re-re-fix checklist borders

* scoreTasks: validate body

* fix tests, move string to api errors

* fix(tests): update expectations for breaking change

* start updating api docs, process tasks sequentially to avoid conflicts with user._tmp

* do not crash entire bulk operation in case of errors

* save task only if modified

* fix lint

* undo changes to error handling: either all tasks scoring are successfull or none

* remove stale code

* do not return user._tmp when bulk scoring, it would be the last version only

* make sure user._tmp.leveledUp is not lost when bulk scoring

* rewards tests

* mixed tests

* fix tests, allow scoring the same task multiple times

* finish integration tests

* fix api docs for the bulk score route

* refactor(task-modal): lockable label component

* wip loading spinner

* refactor(teams): move task scoring to mixin

* fix(teams): style corrections

* fix(btn): fix padding to have height of 32px

* implement loading spinner

* remove console.log warnings

* fix(tasks): spacing and wording corrections

* fix(teams): don't bork manager notes

* fix(teams): assignment fix and more approval flow revisions

* WIP(teams): use tag dropdown control for assignment

* finish merge - never throw an error when a group task requires approval (wip - needs tests)

* fix taskModal merge

* fix merge

* fix(task modal): add newline

* fix(column.vue): add newline at end of file

* mvp yesterdaily modal

* fix tests

* fix api docs for bulk scoring group tasks

* separate task scoring and _tmp handling

* handle _tmp when bulk scoring

* rya: close modal before calling cron API, prevents issues with modals

* rya: fix conflicts with other modals

* add sounds, support for group plans, analytics

* use asyncResource for group plans

* fix lint

* streak bonus: add comment about missing in rya

* move yesterdailyModal

* fix issues with level up modals and rya

* add comments for future use, fix level up modals not showing up at levels with a quest drop

* handle errors in rya modal

* bundle quest and crit notifications

Co-authored-by: Phillip Thelen <phillip@habitica.com>
Co-authored-by: Phillip Thelen <viirus@pherth.net>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
Co-authored-by: negue <eugen.bolz@gmail.com>
2020-08-21 11:46:56 +02:00
Matteo Pagliazzi 46b5efcaf6 Allow group plans for private guilds only (#12479)
* hide upgrade button for public guilds

* prevent group plans for public guilds

* fix unit tests

* fix integration and unit tests that assumed group plans could be public guilds

* more unit tests fixes

* more resilient unit test

* more resilient unit test
2020-08-21 11:46:09 +02:00
Melior 633f3df372 Translated using Weblate (Turkish)
Currently translated at 96.3% (209 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/tr/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (217 of 217 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (57 of 57 strings)

Translation: Habitica/Spells
Translate-URL: https://translate.habitica.com/projects/habitica/spells/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.9% (2130 of 2131 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 98.2% (55 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (92 of 92 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
2020-08-20 22:45:40 +02:00
Sabe Jones fa79fb6608 4.153.1 2020-08-20 14:47:26 -05:00
Sabe Jones f9d9df5ddb chore(news): blogs 2020-08-20 14:47:18 -05:00
Sabe Jones 8dbbfcd3a1 Scheduling summary line for team Dailies and To Do's (#12439)
* WIP(dailies): summary sentence draft

* fix(dailies): hide summarized fields, handle future Daily start date

* fix(dailies): don't apply summary sentence to Challenges
...for the sake of non-English users

* fix(dailies): tweak date x Challenge logic

* refactor(dailies): use native JS forEach
2020-08-20 14:12:05 -05:00
Matteo Pagliazzi 9a07ba7417 Better XSS Fix (#12483)
* Revert "fix(test): adjust expectations"

This reverts commit 205436d5b1.

* Revert "fix(escaping): global inoffensive apostrophe"

This reverts commit 2b8f94b244.

* change <%- to <%=

* fix interpolation only where necessary

* remove unused variable
2020-08-20 13:41:46 -05:00
Phillip Thelen 8248c4ca4e Update faq.json (#12484) 2020-08-19 19:59:48 +02:00
Sabe Jones 0e9ac6d4f2 Merge branch 'release' into develop 2020-08-18 15:29:03 -05:00
Sabe Jones 56df62cf49 4.153.0 2020-08-18 15:27:12 -05:00
Sabe Jones eb16966953 fix(news): image 2020-08-18 15:26:54 -05:00
Sabe Jones 6255c5dcc7 feat(content): golden achievements 2020-08-18 15:13:06 -05:00
Matteo Pagliazzi 60ffc1fdaf fix(mongoose): revert to 5.9.29 2020-08-17 13:08:50 +02:00
Alexander Colen 0cfe0473b9 Remove Tavern from API v3 list of guilds when 'guild' or 'publicGuilds' type parameter get added. (Fixes #12407) (#12438)
* Excluding tavern from showing up in GET /groups API when 'guilds' or 'publicGuilds' type parameter is included.

* Fixed test errors.

* Resolved pull request #12438 issues.

Moved Tavern exclusion to Group model, removed Group controller back to the original and resolved test failures.
2020-08-17 12:38:07 +02:00
Matteo Pagliazzi 10f89c8d79 chore(vue deps): upgrade 2020-08-17 09:41:42 +02:00
dependabot-preview[bot] 0692eb10cc build(deps): bump lodash from 4.17.19 to 4.17.20 (#12461)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.20.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:30:30 +02:00
dependabot-preview[bot] 4ac160ab21 build(deps): bump lodash from 4.17.19 to 4.17.20 in /website/client (#12468)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.20.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:28:54 +02:00
dependabot-preview[bot] dc5163e8a0 build(deps): bump vue-router from 3.4.2 to 3.4.3 in /website/client (#12478)
Bumps [vue-router](https://github.com/vuejs/vue-router) from 3.4.2 to 3.4.3.
- [Release notes](https://github.com/vuejs/vue-router/releases)
- [Changelog](https://github.com/vuejs/vue-router/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-router/compare/v3.4.2...v3.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:28:22 +02:00
dependabot-preview[bot] d850b50009 build(deps): bump winston-loggly-bulk from 3.1.0 to 3.1.1 (#12465)
Bumps [winston-loggly-bulk](https://github.com/loggly/winston-loggly-bulk) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/loggly/winston-loggly-bulk/releases)
- [Commits](https://github.com/loggly/winston-loggly-bulk/compare/v3.1.0...v3.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:27:09 +02:00
dependabot-preview[bot] 65e00ef784 build(deps-dev): bump sinon from 9.0.2 to 9.0.3 (#12467)
Bumps [sinon](https://github.com/sinonjs/sinon) from 9.0.2 to 9.0.3.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v9.0.2...v9.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:26:40 +02:00
dependabot-preview[bot] fd11adbb82 build(deps): bump apidoc from 0.24.0 to 0.25.0 (#12466)
Bumps [apidoc](https://github.com/apidoc/apidoc) from 0.24.0 to 0.25.0.
- [Release notes](https://github.com/apidoc/apidoc/releases)
- [Changelog](https://github.com/apidoc/apidoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/apidoc/apidoc/compare/0.24.0...0.25.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:26:31 +02:00
dependabot-preview[bot] 4d64e299ef build(deps): bump mongoose from 5.9.27 to 5.10.0 (#12463)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.27 to 5.10.0.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.27...5.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-17 09:26:02 +02:00
Sabe Jones 29c21f09e1 4.152.3 2020-08-15 12:16:52 -05:00
Sabe Jones 205436d5b1 fix(test): adjust expectations 2020-08-15 11:56:47 -05:00
Sabe Jones 2b8f94b244 fix(escaping): global inoffensive apostrophe 2020-08-15 10:27:37 -05:00
Sabe Jones 30cedad9b2 4.152.2 2020-08-14 11:18:44 -05:00
Sabe Jones 3a67a36031 fix(escaping): Armoire and boss messages 2020-08-14 11:04:21 -05:00
Sabe Jones 9d645c1c2e fix(merge): missing string 2020-08-13 17:38:05 -05:00
Sabe Jones 6ee4c9870a fix(merge): missing string 2020-08-13 17:27:51 -05:00
Sabe Jones fbfe35b4eb 4.152.1 2020-08-13 17:12:09 -05:00
Sabe Jones 3b9509fa1a Merge remote-tracking branch 'habitica-private/xss-fix' into release 2020-08-13 17:11:48 -05:00
Sabe Jones 0f81c5cbdb Merge branch 'develop' into release 2020-08-13 16:21:21 -05:00
Sabe Jones d3fdfe33fb chore(news): Bailey 2020-08-13 16:20:52 -05:00
Sabe Jones d9cf7d3f79 fix(gdpr): handle blocked user; pace out requests 2020-08-13 15:35:11 +00:00
Melior ffe144e762 Merge branch 'origin/develop' into Weblate. 2020-08-11 22:47:12 +02:00
Sabe Jones cec3e67b16 Merge branch 'release' into develop 2020-08-11 15:44:48 -05:00
Sabe Jones 2a94ff41b1 4.152.0 2020-08-11 15:43:51 -05:00
Sabe Jones ce32477af7 chore(sprites): compile 2020-08-11 15:43:38 -05:00
Sabe Jones 1b6b99b521 feat(content): Armoire and backgrounds 8/2020 2020-08-11 15:43:29 -05:00
Matteo Pagliazzi b7964a411c fix(i18n): html-escape all interpolated strings where html is not necessary 2020-08-11 21:33:24 +02:00
Melior bce138f9c2 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Japanese)

Currently translated at 90.4% (1923 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/

Translated using Weblate (Czech)

Currently translated at 86.7% (1843 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Filipino)

Currently translated at 80.0% (1701 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fil/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Czech)

Currently translated at 86.3% (1834 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Korean)

Currently translated at 80.9% (51 of 63 strings)

Translation: Habitica/Defaulttasks
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/ko/

Translated using Weblate (Korean)

Currently translated at 95.2% (343 of 360 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/ko/

Translated using Weblate (Korean)

Currently translated at 88.8% (192 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ko/

Translated using Weblate (Czech)

Currently translated at 85.8% (1824 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 85.7% (1823 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 98.6% (213 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/cs/

Translated using Weblate (Czech)

Currently translated at 85.4% (1816 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Italian)

Currently translated at 100.0% (173 of 173 strings)

Translation: Habitica/Npc
Translate-URL: https://translate.habitica.com/projects/habitica/npc/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (493 of 493 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/it/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Czech)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/cs/

Translated using Weblate (Czech)

Currently translated at 91.0% (51 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/cs/

Translated using Weblate (Polish)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pl/

Translated using Weblate (Japanese)

Currently translated at 100.0% (67 of 67 strings)

Translation: Habitica/Messages
Translate-URL: https://translate.habitica.com/projects/habitica/messages/ja/

Translated using Weblate (Polish)

Currently translated at 99.4% (497 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pl/

Translated using Weblate (Japanese)

Currently translated at 99.8% (499 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/

Translated using Weblate (Polish)

Currently translated at 81.5% (1732 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/

Translated using Weblate (Japanese)

Currently translated at 90.4% (1921 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/

Translated using Weblate (Polish)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/pl/

Translated using Weblate (Polish)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pl/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (140 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/vi/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (Czech)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/cs/

Translated using Weblate (Czech)

Currently translated at 91.0% (51 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/cs/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Japanese)

Currently translated at 90.3% (1919 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Japanese)

Currently translated at 90.1% (1915 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/

Translated using Weblate (Czech)

Currently translated at 85.4% (1815 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 87.5% (49 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/cs/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/

Translated using Weblate (Vietnamese)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/vi/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Dutch)

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (31 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (31 of 31 strings)

Translation: Habitica/Maintenance
Translate-URL: https://translate.habitica.com/projects/habitica/maintenance/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (56 of 56 strings)

Translation: Habitica/Faq
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/
2020-08-11 05:10:44 +02:00
Matteo Pagliazzi d82213bfee 4.151.5 2020-08-10 19:09:05 +02:00
Matteo Pagliazzi 535aa860f1 fix(task): make sure daysOfMonth update is only applied to dailies 2020-08-10 19:08:36 +02:00
Scott 5d169d477a Added bannedWordsAllowed attribute to Group attributes (Partial fix for #12405) (#12440)
* Added bannedWordsAllowed attribute to Group attributes

Added an optional Boolean attribute which will determine if banned words are allowed

* Added bannedWordsAllowed attribute to non-settable fields
2020-08-10 18:38:56 +02:00
Matteo Pagliazzi d7ee1ec4f4 remove modals stack (#12423) 2020-08-10 18:38:24 +02:00
Sabe Jones 8c3a9c6dbc fix(teams): smol tweaks (#12443) 2020-08-10 11:27:19 -05:00
Matteo Pagliazzi 747c4ffbad Revert "fix(package-lock.json): rebuild"
This reverts commit e30e2f23ac.
2020-08-10 16:51:21 +02:00
Matteo Pagliazzi e30e2f23ac fix(package-lock.json): rebuild 2020-08-10 16:25:08 +02:00
Matteo Pagliazzi d016c1fa0a Revert "build(deps): bump mongoose from 5.9.27 to 5.9.28 (#12449)" (#12458)
This reverts commit 8796dbd8b8.
2020-08-10 16:20:29 +02:00
dependabot-preview[bot] 5b2b51e4f6 build(deps): bump superagent from 5.3.1 to 6.0.0 (#12450)
Bumps [superagent](https://github.com/visionmedia/superagent) from 5.3.1 to 6.0.0.
- [Release notes](https://github.com/visionmedia/superagent/releases)
- [Changelog](https://github.com/visionmedia/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/visionmedia/superagent/compare/v5.3.1...v6.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:31:26 +02:00
dependabot-preview[bot] 7393ef5162 build(deps): bump vue-router from 3.3.4 to 3.4.2 in /website/client (#12457)
Bumps [vue-router](https://github.com/vuejs/vue-router) from 3.3.4 to 3.4.2.
- [Release notes](https://github.com/vuejs/vue-router/releases)
- [Changelog](https://github.com/vuejs/vue-router/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-router/compare/v3.3.4...v3.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:29:58 +02:00
dependabot-preview[bot] 8a548a6a4d build(deps): bump bootstrap from 4.5.0 to 4.5.2 in /website/client (#12456)
Bumps [bootstrap](https://github.com/twbs/bootstrap) from 4.5.0 to 4.5.2.
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v4.5.0...v4.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:29:36 +02:00
dependabot-preview[bot] 5ed007190a build(deps): bump got from 11.5.1 to 11.5.2 (#12454)
Bumps [got](https://github.com/sindresorhus/got) from 11.5.1 to 11.5.2.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.5.1...v11.5.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:28:41 +02:00
dependabot-preview[bot] 24afffc2ae build(deps): bump @babel/core from 7.11.0 to 7.11.1 (#12452)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.11.0 to 7.11.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.1/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:28:31 +02:00
dependabot-preview[bot] 2ff3c7326c build(deps): bump csv-stringify from 5.5.0 to 5.5.1 (#12451)
Bumps [csv-stringify](https://github.com/adaltas/node-csv-stringify) from 5.5.0 to 5.5.1.
- [Release notes](https://github.com/adaltas/node-csv-stringify/releases)
- [Changelog](https://github.com/adaltas/node-csv-stringify/blob/master/CHANGELOG.md)
- [Commits](https://github.com/adaltas/node-csv-stringify/compare/v5.5.0...v5.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:28:07 +02:00
dependabot-preview[bot] 8796dbd8b8 build(deps): bump mongoose from 5.9.27 to 5.9.28 (#12449)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.27 to 5.9.28.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.27...5.9.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-10 15:25:31 +02:00
negue d2fc7c0c3d UI: redesign DatePicker (#12418)
* extract datepicker & settings as component + redesign

* fix updating values + fix button styling + popover position

* remove eslint-config-standard / html
2020-08-09 22:25:56 +02:00
Carlton McFarlane 13a5b276e9 fix(quest shop): add an index to v-for loop (#12446) 2020-08-09 19:58:40 +02:00
Rogesson 0a47af4ac3 update group members after accepting the quest (without page reload) (#12358)
* update group members after accepting the quest (without page reload)

* show quest information after starting

* removing quest.progress.up assignment

Co-authored-by: rogesson <rogesson.barboza@locaweb.com.br>
2020-08-09 19:44:46 +02:00
Jalansh c0bf2cffea Casting Chilling Frost and Stealth skill again will not be processed and return an error instead. Fixes #12361. (#12404)
* Added logic for a repeating Chilling Frost skill. Added test case for redundant chilling frost skill cast. Added comments for the logic of repeating Stealth skill because of an error.

* Added logic for a repeating Stealth skill. Avoiding MP reduction still pending because of console error. Test cases pending.

* Completed the logic for a repeated Stealth skill. Added repeated frost skill cast check in common. Removed exclusive test. Test cases are pending.

* Added test case for Stealth skill recast. Fixed lint errors. Fixed a flaw in if statement which led to test case failure.

* Fixed lint errors in test case.

* Added a common JSON entry for skil recasts in three files. Other files remaining. Added Chilling Frost recast check in common code. Modified test cases.

* Added spellDisabled condition in client code.

* Reverted JSON messages for three languages. Added spellAlreadyCast attribute to JSON file in locales/en. Made changes for showing appropriate message in client code.

* Added an import for throwing BadRequest in common code. Modified test case accordingly.

* Update website/common/script/content/spells.js

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>

* Added target and req attributes in cast() method arguments.

* Changed common code test case because of increased function parameters. Moved chilling frost test casse to common tests instead of server tests.

* Changed the test case format in common tests.

* Added a missing done statement.

* Fixed a minor error which led to failing test case. Removed the exclusive test which led to lint error.

* Fixed lint errors.

* Added a class named 'disabled' for the frontend change.

* fix(skills): style cleanup

* fix(skills): unfix

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2020-08-09 18:25:59 +02:00
Sabe Jones 954040dff8 4.151.4 2020-08-07 15:22:50 -05:00
Sabe Jones e7af07cebb Merge branch 'develop' into release 2020-08-07 15:22:43 -05:00
Sabe Jones d7d7f82723 fix(lint): allow console logging during Gulp tasks 2020-08-04 11:44:20 -05:00
Sabe Jones 7daaf04d0d fix(event): client Gala reversions 2020-08-03 13:50:30 -05:00
Melior dc8c40c613 Translated using Weblate (Dutch)
Currently translated at 99.9% (2124 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Merge branch 'origin/develop' into Weblate.

Translated using Weblate (Dutch)

Currently translated at 99.9% (2123 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Dutch)

Currently translated at 98.0% (2084 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nl/

Translated using Weblate (Dutch)

Currently translated at 97.7% (2077 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nl/

Translated using Weblate (Dutch)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nl/

Translated using Weblate (Dutch)

Currently translated at 93.0% (201 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/nl/

Translated using Weblate (Spanish)

Currently translated at 88.9% (1891 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/es/

Translated using Weblate (Czech)

Currently translated at 85.4% (1815 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 83.6% (210 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (146 of 146 strings)

Translation: Habitica/Pets
Translate-URL: https://translate.habitica.com/projects/habitica/pets/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/cs/

Translated using Weblate (Japanese)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/

Translated using Weblate (Japanese)

Currently translated at 89.9% (1911 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/pt_BR/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (360 of 360 strings)

Translation: Habitica/Content
Translate-URL: https://translate.habitica.com/projects/habitica/content/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hant/

Translated using Weblate (Czech)

Currently translated at 84.8% (1803 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/cs/

Translated using Weblate (Japanese)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ja/

Translated using Weblate (Japanese)

Currently translated at 89.5% (1903 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Japanese)

Currently translated at 97.1% (682 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
2020-08-03 20:41:36 +02:00
Sabe Jones 9a0e029491 Merge branch 'release' into develop 2020-08-03 13:27:57 -05:00
Sabe Jones d6cfbd5529 4.151.3 2020-08-03 13:27:13 -05:00
Sabe Jones 74244fd3ba chore(event): Splash cleanup and Bailey 2020-08-03 13:26:53 -05:00
Matteo Pagliazzi 65e15e0c1d Fix multiple purchases with Amazon Pay (#12422)
* fix(amazon): logout when modal is closed, prevents issue with multiple order reference ids

* amazon logout when the button is loaded the first time
2020-08-03 15:34:18 +02:00
dependabot-preview[bot] d21b9a5af4 build(deps): bump @babel/preset-env from 7.10.4 to 7.11.0 (#12433)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.10.4 to 7.11.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.0/packages/babel-preset-env)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
2020-08-03 12:42:42 +02:00
dependabot-preview[bot] 7cedecf27e build(deps): bump uuid from 8.2.0 to 8.3.0 in /website/client (#12434)
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.2.0 to 8.3.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.2.0...v8.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:41:05 +02:00
dependabot-preview[bot] 9aaeb2c4ac build(deps): bump @babel/core from 7.10.5 to 7.11.0 (#12428)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.10.5 to 7.11.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.0/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:40:13 +02:00
dependabot-preview[bot] df461f7642 build(deps): bump webpack from 4.44.0 to 4.44.1 in /website/client (#12435)
Bumps [webpack](https://github.com/webpack/webpack) from 4.44.0 to 4.44.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v4.44.0...v4.44.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:40:02 +02:00
dependabot-preview[bot] 0f72064923 build(deps-dev): bump monk from 7.3.0 to 7.3.1 (#12425)
Bumps [monk](https://github.com/Automattic/monk) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/Automattic/monk/releases)
- [Changelog](https://github.com/Automattic/monk/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/monk/compare/v7.3.0...v7.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:39:39 +02:00
dependabot-preview[bot] 139645ff76 build(deps): bump mongoose from 5.9.25 to 5.9.27 (#12426)
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.9.25 to 5.9.27.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/History.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.9.25...5.9.27)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:39:30 +02:00
dependabot-preview[bot] aedcb483a0 build(deps): bump rate-limiter-flexible from 2.1.9 to 2.1.10 (#12429)
Bumps [rate-limiter-flexible](https://github.com/animir/node-rate-limiter-flexible) from 2.1.9 to 2.1.10.
- [Release notes](https://github.com/animir/node-rate-limiter-flexible/releases)
- [Commits](https://github.com/animir/node-rate-limiter-flexible/commits/v2.1.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:38:41 +02:00
dependabot-preview[bot] cfb335ab78 build(deps): bump uuid from 8.2.0 to 8.3.0 (#12430)
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.2.0 to 8.3.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.2.0...v8.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:38:20 +02:00
dependabot-preview[bot] 70aea8c14a build(deps): bump bootstrap-vue from 2.15.0 to 2.16.0 in /website/client (#12436)
Bumps [bootstrap-vue](https://github.com/bootstrap-vue/bootstrap-vue) from 2.15.0 to 2.16.0.
- [Release notes](https://github.com/bootstrap-vue/bootstrap-vue/releases)
- [Changelog](https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/bootstrap-vue/bootstrap-vue/compare/v2.15.0...v2.16.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-03 12:37:25 +02:00
Matteo Pagliazzi f53022c00e fix(monthly tests): update test to use future date 2020-08-02 16:29:26 +02:00
Melior b82a79361b Merge branch 'origin/develop' into Weblate. 2020-07-31 21:53:24 +02:00
Sabe Jones ebb3a12e92 fix(migrations): better dummy require 2020-07-31 14:52:23 -05:00
Sabe Jones 272a6ec19d fix(migrations): better dummy require 2020-07-31 14:52:08 -05:00
Melior dbf2ee6d6d Merge branch 'origin/develop' into Weblate. 2020-07-31 21:50:50 +02:00
Melior af0b2ab16e Translated using Weblate (Hindi)
Currently translated at 0.6% (2 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/hi/

Translated using Weblate (Czech)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/cs/

Translated using Weblate (Czech)

Currently translated at 83.8% (1781 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (212 of 212 strings)

Translation: Habitica/Settings
Translate-URL: https://translate.habitica.com/projects/habitica/settings/cs/

Translated using Weblate (Polish)

Currently translated at 81.3% (1728 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/

Translated using Weblate (Polish)

Currently translated at 83.4% (586 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pl/

Translated using Weblate (Japanese)

Currently translated at 99.8% (499 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/
2020-07-31 21:50:41 +02:00
Sabe Jones 43fb747c8f Merge branch 'release' into develop 2020-07-31 14:45:36 -05:00
Sabe Jones 9291414f7b 4.151.2 2020-07-31 14:45:01 -05:00
Sabe Jones e4c95275ac chore(event): Naming Day news and migration 2020-07-31 14:38:41 -05:00
Matteo Pagliazzi bd3e783274 Paypal IPN Upgrade (#12415)
* upgrade paypal ipn verification module

* paypal ipn: allow sandbox when testing

* improved error handling
2020-07-31 12:32:24 +02:00
Matteo Pagliazzi 9089b64af3 Merge pull request #12420 from HabitRPG/bigsee-12271
fix(task list): update todo due date on every save
2020-07-31 11:48:10 +02:00
Carlton 59f4e7f598 fix (task list) replace deprecated cache-busting of computed properties with methods 2020-07-31 11:41:00 +02:00
Laurel Thomson 1f8e2d5677 Updating daysOfMonths array when the startDate of a monthly is updated in the API - Fixes #12041 (#12399)
* Updating daily daysOfMonth array when startDate is updated and adding integration tests to test this functionality

* Adding more test cases and adding semicolons to the end of lines

* Only updating the monthly repetition if the daily was already set to repeat on a day of the month

* fix(lint): whitespace

Co-authored-by: Laurel Thomson <laurel.beth.thomson@gmai.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2020-07-31 11:16:55 +02:00
Ieahleen c4049608a8 removing wrong info on updating challenge leader from apidoc (#12413)
* removing wrong info on updating challenge leader

as discussed in the Aspiring Comrades, doing the change because the route `/api/v3/challenges/:challengeId` can't be used to change challenge leader, so I am deleting it from the docs

* adding summary to section title

as requested by @paglias

* missing comma

* fix(lint): line length

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2020-07-31 11:10:47 +02:00
Sabe Jones 8003632041 fix(modals): remove unnecessary scrollbar (#12416)
Fixes #9863
2020-07-30 15:01:18 -05:00
Sabe Jones f4c840faec chore(ABtest): end drop experiment in favor of boosting 2020-07-30 14:53:50 -05:00
Melior e9bb171e04 Merge branch 'origin/develop' into Weblate. 2020-07-30 21:49:39 +02:00
Melior 093ef68f5c Translated using Weblate (Japanese)
Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ja/

Translated using Weblate (Czech)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (298 of 298 strings)

Translation: Habitica/Generic
Translate-URL: https://translate.habitica.com/projects/habitica/generic/cs/

Translated using Weblate (Spanish)

Currently translated at 97.7% (531 of 543 strings)

Translation: Habitica/Backgrounds
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/es/

Translated using Weblate (Spanish)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/

Translated using Weblate (Czech)

Currently translated at 100.0% (328 of 328 strings)

Translation: Habitica/Front
Translate-URL: https://translate.habitica.com/projects/habitica/front/cs/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/zh_Hans/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/en_GB/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/en_GB/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/en_GB/

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hant/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/

Translated using Weblate (English (United Kingdom))

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en_GB/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Italian)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/it/

Translated using Weblate (Russian)

Currently translated at 99.5% (215 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ru/

Translated using Weblate (Russian)

Currently translated at 98.6% (213 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ru/

Translated using Weblate (Italian)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (French)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (Czech)

Currently translated at 92.1% (129 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/cs/

Translated using Weblate (Czech)

Currently translated at 89.2% (125 of 140 strings)

Translation: Habitica/Quests
Translate-URL: https://translate.habitica.com/projects/habitica/quests/cs/

Translated using Weblate (Czech)

Currently translated at 100.0% (124 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/cs/

Translated using Weblate (Italian)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/it/

Translated using Weblate (Italian)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/it/

Translated using Weblate (Czech)

Currently translated at 83.8% (1781 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/cs/

Translated using Weblate (Czech)

Currently translated at 97.5% (121 of 124 strings)

Translation: Habitica/Communityguidelines
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/cs/

Translated using Weblate (Italian)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/fr/

Translated using Weblate (German)

Currently translated at 100.0% (216 of 216 strings)

Translation: Habitica/Tasks
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/fr/

Translated using Weblate (German)

Currently translated at 100.0% (8 of 8 strings)

Translation: Habitica/Overview
Translate-URL: https://translate.habitica.com/projects/habitica/overview/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/fr/

Translated using Weblate (German)

Currently translated at 100.0% (500 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (2125 of 2125 strings)

Translation: Habitica/Gear
Translate-URL: https://translate.habitica.com/projects/habitica/gear/fr/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (702 of 702 strings)

Translation: Habitica/Questscontent
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/zh_Hans/

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/

Translated using Weblate (French)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/

Translated using Weblate (German)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/

Translated using Weblate (Czech)

Currently translated at 100.0% (86 of 86 strings)

Translation: Habitica/Achievements
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/cs/

Translated using Weblate (German)

Currently translated at 100.0% (251 of 251 strings)

Translation: Habitica/Subscriber
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/de/

Translated using Weblate (German)

Currently translated at 98.6% (493 of 500 strings)

Translation: Habitica/Groups
Translate-URL: https://translate.habitica.com/projects/habitica/groups/de/
2020-07-30 18:12:59 +02:00
1680 changed files with 44733 additions and 64103 deletions
+1
View File
@@ -38,6 +38,7 @@ yarn.lock
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml
/.vscode
# webstorm fake webpack for path intellisense
+5 -3
View File
@@ -1,3 +1,5 @@
/* eslint-disable no-console */
import gulp from 'gulp';
import path from 'path';
import babel from 'gulp-babel';
@@ -46,17 +48,17 @@ gulp.task('build:prepare-mongo', async () => {
return;
}
console.log('MongoDB data folder is missing, setting up.');
console.log('MongoDB data folder is missing, setting up.'); // eslint-disable-line no-console
// use run-rs without --keep, kill it as soon as the replica set starts
const runRsProcess = spawn('run-rs', ['-v', '4.2.8', '-l', 'ubuntu1804', '--dbpath', 'mongodb-data', '--number', '1', '--quiet']);
for await (const chunk of runRsProcess.stdout) {
const stringChunk = chunk.toString();
console.log(stringChunk);
console.log(stringChunk); // eslint-disable-line no-console
// kills the process after the replica set is setup
if (stringChunk.includes('Started replica set')) {
console.log('MongoDB setup correctly.');
console.log('MongoDB setup correctly.'); // eslint-disable-line no-console
runRsProcess.kill();
}
}
@@ -0,0 +1,87 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20200731_naming_day';
import { v4 as uuid } from 'uuid';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
let set;
let push;
const inc = {
'items.food.Cake_Base': 1,
'items.food.Cake_CottonCandyBlue': 1,
'items.food.Cake_CottonCandyPink': 1,
'items.food.Cake_Desert': 1,
'items.food.Cake_Golden': 1,
'items.food.Cake_Red': 1,
'items.food.Cake_Shade': 1,
'items.food.Cake_Skeleton': 1,
'items.food.Cake_White': 1,
'items.food.Cake_Zombie': 1,
'achievements.habiticaDays': 1,
};
if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.back_special_namingDay2020 !== 'undefined') {
set = { migration: MIGRATION_NAME };
} else if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.body_special_namingDay2018 !== 'undefined') {
set = { migration: MIGRATION_NAME, 'items.gear.owned.back_special_namingDay2020': false };
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.back_special_namingDay2020', _id: uuid() }};
} else if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.head_special_namingDay2017 !== 'undefined') {
set = { migration: MIGRATION_NAME, 'items.gear.owned.body_special_namingDay2018': false };
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.body_special_namingDay2018', _id: uuid() }};
} else if (user && user.items && user.items.pets && typeof user.items.pets['Gryphon-RoyalPurple'] !== 'undefined') {
set = { migration: MIGRATION_NAME, 'items.gear.owned.head_special_namingDay2017': false };
push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.head_special_namingDay2017', _id: uuid() }};
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Gryphon-RoyalPurple'] !== 'undefined') {
set = { migration: MIGRATION_NAME, 'items.pets.Gryphon-RoyalPurple': 5 };
} else {
set = { migration: MIGRATION_NAME, 'items.mounts.Gryphon-RoyalPurple': true };
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (push) {
return await User.update({ _id: user._id }, { $set: set, $inc: inc, $push: push }).exec();
} else {
return await User.update({ _id: user._id }, { $set: set, $inc: inc }).exec();
}
}
export default async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2020-07-01') },
};
const fields = {
_id: 1,
items: 1,
};
while (true) { // eslint-disable-line no-constant-condition
const users = await User // eslint-disable-line no-await-in-loop
.find(query)
.limit(250)
.sort({_id: 1})
.select(fields)
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1]._id,
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
@@ -1,5 +1,5 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20200218_pet_color_achievements';
const MIGRATION_NAME = '20200818_pet_color_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
@@ -14,31 +14,31 @@ async function updateUser (user) {
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['Wolf-CottonCandyPink'] > 0
&& pets['TigerCub-CottonCandyPink'] > 0
&& pets['PandaCub-CottonCandyPink'] > 0
&& pets['LionCub-CottonCandyPink'] > 0
&& pets['Fox-CottonCandyPink'] > 0
&& pets['FlyingPig-CottonCandyPink'] > 0
&& pets['Dragon-CottonCandyPink'] > 0
&& pets['Cactus-CottonCandyPink'] > 0
&& pets['BearCub-CottonCandyPink'] > 0) {
set['achievements.tickledPink'] = true;
if (pets['Wolf-Golden'] > 0
&& pets['TigerCub-Golden'] > 0
&& pets['PandaCub-Golden'] > 0
&& pets['LionCub-Golden'] > 0
&& pets['Fox-Golden'] > 0
&& pets['FlyingPig-Golden'] > 0
&& pets['Dragon-Golden'] > 0
&& pets['Cactus-Golden'] > 0
&& pets['BearCub-Golden'] > 0) {
set['achievements.goodAsGold'] = true;
}
}
if (user && user.items && user.items.mounts) {
const mounts = user.items.mounts;
if (mounts['Wolf-CottonCandyPink']
&& mounts['TigerCub-CottonCandyPink']
&& mounts['PandaCub-CottonCandyPink']
&& mounts['LionCub-CottonCandyPink']
&& mounts['Fox-CottonCandyPink']
&& mounts['FlyingPig-CottonCandyPink']
&& mounts['Dragon-CottonCandyPink']
&& mounts['Cactus-CottonCandyPink']
&& mounts['BearCub-CottonCandyPink'] ) {
set['achievements.rosyOutlook'] = true;
if (mounts['Wolf-Golden']
&& mounts['TigerCub-Golden']
&& mounts['PandaCub-Golden']
&& mounts['LionCub-Golden']
&& mounts['Fox-Golden']
&& mounts['FlyingPig-Golden']
&& mounts['Dragon-Golden']
&& mounts['Cactus-Golden']
&& mounts['BearCub-Golden'] ) {
set['achievements.allThatGlitters'] = true;
}
}
@@ -50,7 +50,7 @@ async function updateUser (user) {
module.exports = async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2020-02-01') },
'auth.timestamps.loggedin': { $gt: new Date('2020-08-01') },
};
const fields = {
+1 -1
View File
@@ -18,7 +18,7 @@ function setUpServer () {
setUpServer();
// Replace this with your migration
const processUsers = require('./archive/2020/20200721_summer_splash_orcas').default;
const processUsers = require().default;
processUsers()
.then(() => {
@@ -0,0 +1,73 @@
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = 'tag-challenge-field-string2bool';
const progressCount = 1000;
let count = 0;
export default async function processUsers () {
const query = {
migration: { $ne: MIGRATION_NAME },
tags: {
$elemMatch: {
challenge: {
$exists: true,
$type: 'string',
},
},
},
};
while (true) { // eslint-disable-line no-constant-condition
// eslint-disable-next-line no-await-in-loop
const users = await User.find(query)
.sort({ _id: 1 })
.limit(250)
.select({ _id: 1, tags: 1 })
.lean()
.exec();
if (users.length === 0) {
console.warn('All appropriate users found and modified.');
console.warn(`\n${count} users processed\n`);
break;
} else {
query._id = {
$gt: users[users.length - 1],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
}
async function updateUser (user) {
count += 1;
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
let requiresUpdate = false;
if (user && user.tags) {
user.tags.forEach(tag => {
if (tag && typeof tag.challenge === 'string') {
requiresUpdate = true;
if (tag.challenge === 'true') {
tag.challenge = true;
} else if (tag.challenge === 'false') {
tag.challenge = false;
} else {
tag.challenge = null;
}
}
});
}
if (requiresUpdate) {
const set = {
migration: MIGRATION_NAME,
tags: user.tags,
};
return User.update({ _id: user._id }, { $set: set }).exec();
}
return null;
}
+525 -249
View File
File diff suppressed because it is too large Load Diff
+22 -22
View File
@@ -1,18 +1,18 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.151.1",
"version": "4.161.0",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.10.3",
"@babel/preset-env": "^7.10.3",
"@babel/register": "^7.10.3",
"@google-cloud/trace-agent": "^5.1.0",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@babel/register": "^7.11.5",
"@google-cloud/trace-agent": "^5.1.1",
"@slack/client": "^4.12.0",
"accepts": "^1.3.5",
"amazon-payments": "^0.2.8",
"amplitude": "^3.5.0",
"apidoc": "^0.24.0",
"apidoc": "^0.25.0",
"apn": "^2.2.0",
"apple-auth": "^1.0.6",
"bcrypt": "^5.0.0",
@@ -20,7 +20,7 @@
"compression": "^1.7.4",
"cookie-session": "^1.4.0",
"coupon-code": "^0.4.5",
"csv-stringify": "^5.5.0",
"csv-stringify": "^5.5.1",
"cwait": "^1.1.1",
"domain-middleware": "~0.1.0",
"eslint": "^6.8.0",
@@ -30,25 +30,25 @@
"express-basic-auth": "^1.1.5",
"express-validator": "^5.2.0",
"glob": "^7.1.6",
"got": "^11.5.0",
"got": "^11.7.0",
"gulp": "^4.0.0",
"gulp-babel": "^8.0.0",
"gulp-imagemin": "^7.1.0",
"gulp-nodemon": "^2.5.0",
"gulp.spritesmith": "^6.9.0",
"habitica-markdown": "^2.0.2",
"habitica-markdown": "^3.0.0",
"helmet": "^3.23.3",
"image-size": "^0.8.3",
"image-size": "^0.9.1",
"in-app-purchase": "^1.11.3",
"js2xmlparser": "^4.0.1",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^1.8.1",
"lodash": "^4.17.19",
"jwks-rsa": "^1.9.0",
"lodash": "^4.17.20",
"merge-stream": "^2.0.0",
"method-override": "^3.0.0",
"moment": "^2.27.0",
"moment": "^2.28.0",
"moment-recur": "^1.0.7",
"mongoose": "^5.9.25",
"mongoose": "^5.10.3",
"morgan": "^1.10.0",
"nconf": "^0.10.0",
"node-gcm": "^1.0.3",
@@ -57,24 +57,24 @@
"passport-facebook": "^3.0.0",
"passport-google-oauth2": "^0.2.0",
"passport-google-oauth20": "1.0.0",
"paypal-ipn": "3.0.0",
"paypal-rest-sdk": "^1.8.1",
"pp-ipn": "^1.1.0",
"ps-tree": "^1.0.0",
"rate-limiter-flexible": "^2.1.7",
"rate-limiter-flexible": "^2.1.10",
"redis": "^3.0.2",
"regenerator-runtime": "^0.13.7",
"remove-markdown": "^0.3.0",
"rimraf": "^3.0.2",
"short-uuid": "^3.0.0",
"stripe": "^7.15.0",
"superagent": "^5.3.1",
"superagent": "^6.1.0",
"universal-analytics": "^0.4.23",
"useragent": "^2.1.9",
"uuid": "^8.2.0",
"validator": "^13.1.1",
"uuid": "^8.3.0",
"validator": "^13.1.17",
"vinyl-buffer": "^1.0.1",
"winston": "^3.3.3",
"winston-loggly-bulk": "^3.1.0",
"winston-loggly-bulk": "^3.1.1",
"xml2js": "^0.4.23"
},
"private": true,
@@ -118,10 +118,10 @@
"expect.js": "^0.3.1",
"istanbul": "^1.1.0-alpha.1",
"mocha": "^5.1.1",
"monk": "^7.3.0",
"monk": "^7.3.2",
"require-again": "^2.0.0",
"run-rs": "^0.6.2",
"sinon": "^9.0.2",
"sinon": "^9.0.3",
"sinon-chai": "^3.5.0",
"sinon-stub-promise": "^4.0.0"
},
+4 -1
View File
@@ -31,19 +31,22 @@ async function deleteAmplitudeData (userId, email) {
console.log(`${userId} (${email}) Amplitude response: ${response.status} ${response.statusText}`);
}
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
async function deleteHabiticaData (user, email) {
const truncatedEmail = email.slice(0, email.indexOf('@'));
const set = {
'auth.blocked': false,
'auth.local.hashed_password': '$2a$10$QDnNh1j1yMPnTXDEOV38xOePEWFd4X8DSYwAM8XTmqmacG5X0DKjW',
'auth.local.passwordHashMethod': 'bcrypt',
};
if (!user.auth.local.email) set['auth.local.email'] = `${truncatedEmail}@example.com`;
if (!user.auth.local.email) set['auth.local.email'] = `${truncatedEmail}-gdpr@example.com`;
await User.update(
{ _id: user._id },
{ $set: set },
);
await new Promise(resolve => setTimeout(resolve, 1000));
const response = await axios.delete(
`${BASE_URL}/api/v3/user`,
{
+19 -15
View File
@@ -171,28 +171,32 @@ describe('highlightMentions', () => {
it('github issue 12118, method crashes when square brackets are used', async () => {
const text = '[test]';
let err;
const result = await highlightMentions(text);
try {
await highlightMentions(text);
} catch (e) {
err = e;
}
expect(err).to.be.undefined;
expect(result[0]).to.equal(text);
});
it('github issue 12138, method crashes when regex chars are used in code block', async () => {
const text = '`[test]`';
let err;
const result = await highlightMentions(text);
try {
await highlightMentions(text);
} catch (e) {
err = e;
}
expect(result[0]).to.equal(text);
});
expect(err).to.be.undefined;
it('github issue 12586, method crashes when empty link is used', async () => {
const text = '[]()';
const result = await highlightMentions(text);
expect(result[0]).to.equal(text);
});
it('github issue 12586, method crashes when link without title is used', async () => {
const text = '[](www.google.com)';
const result = await highlightMentions(text);
expect(result[0]).to.equal(text);
});
});
@@ -2,13 +2,14 @@ import { model as User } from '../../../../../../website/server/models/user';
import amzLib from '../../../../../../website/server/libs/payments/amazon';
import payments from '../../../../../../website/server/libs/payments/payments';
import common from '../../../../../../website/common';
import apiError from '../../../../../../website/server/libs/apiError';
const { i18n } = common;
describe('Amazon Payments - Checkout', () => {
const subKey = 'basic_3mo';
let user; let orderReferenceId; let
headers;
headers; const gemsBlockKey = '21gems'; const gemsBlock = common.content.gems[gemsBlockKey];
let setOrderReferenceDetailsSpy;
let confirmOrderReferenceSpy;
let authorizeSpy;
@@ -16,7 +17,7 @@ describe('Amazon Payments - Checkout', () => {
let paymentBuyGemsStub;
let paymentCreateSubscritionStub;
let amount = 5;
let amount = gemsBlock.price / 100;
function expectOrderReferenceSpy () {
expect(setOrderReferenceDetailsSpy).to.be.calledOnce;
@@ -107,13 +108,20 @@ describe('Amazon Payments - Checkout', () => {
paymentMethod,
headers,
};
if (gift) expectedArgs.gift = gift;
if (gift) {
expectedArgs.gift = gift;
expectedArgs.gemsBlock = undefined;
} else {
expectedArgs.gemsBlock = gemsBlock;
}
expect(paymentBuyGemsStub).to.be.calledWith(expectedArgs);
}
it('should purchase gems', async () => {
sinon.stub(user, 'canGetGems').resolves(true);
await amzLib.checkout({ user, orderReferenceId, headers });
await amzLib.checkout({
user, orderReferenceId, headers, gemsBlock: gemsBlockKey,
});
expectBuyGemsStub(amzLib.constants.PAYMENT_METHOD);
expectAmazonStubs();
@@ -144,7 +152,9 @@ describe('Amazon Payments - Checkout', () => {
it('should error if user cannot get gems gems', async () => {
sinon.stub(user, 'canGetGems').resolves(false);
await expect(amzLib.checkout({ user, orderReferenceId, headers }))
await expect(amzLib.checkout({
user, orderReferenceId, headers, gemsBlock: gemsBlockKey,
}))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
message: i18n.t('groupPolicyCannotGetGems'),
@@ -153,6 +163,17 @@ describe('Amazon Payments - Checkout', () => {
user.canGetGems.restore();
});
it('should error if gems block is not valid', async () => {
await expect(amzLib.checkout({
user, orderReferenceId, headers, gemsBlock: 'invalid',
}))
.to.eventually.be.rejected.and.to.eql({
httpCode: 400,
message: apiError('invalidGemsBlock'),
name: 'BadRequest',
});
});
it('should gift gems', async () => {
const receivingUser = new User();
await receivingUser.save();
@@ -195,6 +216,7 @@ describe('Amazon Payments - Checkout', () => {
paymentMethod: amzLib.constants.PAYMENT_METHOD_GIFT,
headers,
gift,
gemsBlock: undefined,
});
expectAmazonStubs();
});
@@ -31,11 +31,14 @@ describe('#upgradeGroupPlan', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
await group.save();
user.guilds.push(group._id);
await user.save();
spy = sinon.stub(amzLib, 'authorizeOnBillingAgreement');
spy.resolves([]);
+16 -13
View File
@@ -5,7 +5,6 @@ import applePayments from '../../../../../website/server/libs/payments/apple';
import iap from '../../../../../website/server/libs/inAppPurchases';
import { model as User } from '../../../../../website/server/models/user';
import common from '../../../../../website/common';
import { mockFindById, restoreFindById } from '../../../../helpers/mongoose.helper';
const { i18n } = common;
@@ -84,7 +83,7 @@ describe('Apple Payments', () => {
user.canGetGems.restore();
});
it('errors if amount does not exist', async () => {
it('errors if gemsBlock does not exist', async () => {
sinon.stub(user, 'canGetGems').resolves(true);
iapGetPurchaseDataStub.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
@@ -106,23 +105,23 @@ describe('Apple Payments', () => {
const gemsCanPurchase = [
{
productId: 'com.habitrpg.ios.Habitica.4gems',
amount: 1,
gemsBlock: '4gems',
},
{
productId: 'com.habitrpg.ios.Habitica.20gems',
amount: 5.25,
gemsBlock: '21gems',
},
{
productId: 'com.habitrpg.ios.Habitica.21gems',
amount: 5.25,
gemsBlock: '21gems',
},
{
productId: 'com.habitrpg.ios.Habitica.42gems',
amount: 10.5,
gemsBlock: '42gems',
},
{
productId: 'com.habitrpg.ios.Habitica.84gems',
amount: 21,
gemsBlock: '84gems',
},
];
@@ -149,8 +148,9 @@ describe('Apple Payments', () => {
expect(paymentBuyGemsStub).to.be.calledWith({
user,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
amount: gemTest.amount,
gemsBlock: common.content.gems[gemTest.gemsBlock],
headers,
gift: undefined,
});
expect(user.canGetGems).to.be.calledOnce;
user.canGetGems.restore();
@@ -161,8 +161,6 @@ describe('Apple Payments', () => {
const receivingUser = new User();
await receivingUser.save();
mockFindById(receivingUser);
iapGetPurchaseDataStub.restore();
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
.returns([{
@@ -184,12 +182,17 @@ describe('Apple Payments', () => {
expect(paymentBuyGemsStub).to.be.calledOnce;
expect(paymentBuyGemsStub).to.be.calledWith({
user: receivingUser,
user,
paymentMethod: applePayments.constants.PAYMENT_METHOD_APPLE,
amount: gemsCanPurchase[0].amount,
headers,
gift: {
type: 'gems',
gems: { amount: 4 },
member: sinon.match({ _id: receivingUser._id }),
uuid: receivingUser._id,
},
gemsBlock: common.content.gems['4gems'],
});
restoreFindById();
});
});
+14
View File
@@ -0,0 +1,14 @@
import common from '../../../../../website/common';
import { getGemsBlock } from '../../../../../website/server/libs/payments/gems';
describe('payments/gems', () => {
describe('#getGemsBlock', () => {
it('throws an error if the gem block key is invalid', () => {
expect(() => getGemsBlock('invalid')).to.throw;
});
it('returns the gem block for the given key', () => {
expect(getGemsBlock('21gems')).to.equal(common.content.gems['21gems']);
});
});
});
+11 -8
View File
@@ -5,7 +5,6 @@ import googlePayments from '../../../../../website/server/libs/payments/google';
import iap from '../../../../../website/server/libs/inAppPurchases';
import { model as User } from '../../../../../website/server/models/user';
import common from '../../../../../website/common';
import { mockFindById, restoreFindById } from '../../../../helpers/mongoose.helper';
const { i18n } = common;
@@ -14,7 +13,7 @@ describe('Google Payments', () => {
describe('verifyGemPurchase', () => {
let sku; let user; let token; let receipt; let signature; let
headers;
headers; const gemsBlock = common.content.gems['21gems'];
let iapSetupStub; let iapValidateStub; let iapIsValidatedStub; let
paymentBuyGemsStub;
@@ -103,8 +102,9 @@ describe('Google Payments', () => {
expect(paymentBuyGemsStub).to.be.calledWith({
user,
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
amount: 5.25,
gemsBlock,
headers,
gift: undefined,
});
expect(user.canGetGems).to.be.calledOnce;
user.canGetGems.restore();
@@ -114,8 +114,6 @@ describe('Google Payments', () => {
const receivingUser = new User();
await receivingUser.save();
mockFindById(receivingUser);
const gift = { uuid: receivingUser._id };
await googlePayments.verifyGemPurchase({
user, gift, receipt, signature, headers,
@@ -132,12 +130,17 @@ describe('Google Payments', () => {
expect(paymentBuyGemsStub).to.be.calledOnce;
expect(paymentBuyGemsStub).to.be.calledWith({
user: receivingUser,
user,
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
amount: 5.25,
gemsBlock,
headers,
gift: {
type: 'gems',
gems: { amount: 21 },
member: sinon.match({ _id: receivingUser._id }),
uuid: receivingUser._id,
},
});
restoreFindById();
});
});
@@ -21,11 +21,14 @@ describe('Canceling a subscription for group', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
await group.save();
user.guilds.push(group._id);
await user.save();
data = {
user,
sub: {
@@ -141,6 +144,8 @@ describe('Canceling a subscription for group', () => {
it('prevents non group leader from managing subscription', async () => {
const groupMember = new User();
groupMember.guilds.push(group._id);
await groupMember.save();
data.user = groupMember;
data.groupId = group._id;
@@ -162,7 +167,9 @@ describe('Canceling a subscription for group', () => {
let updatedGroup = await Group.findById(group._id).exec();
const newLeader = new User();
newLeader.profile.name = 'newLeader';
updatedGroup.leader = newLeader._id;
await newLeader.save();
await updatedGroup.save();
await api.cancelSubscription(data);
@@ -185,8 +192,6 @@ describe('Canceling a subscription for group', () => {
'user-agent': '',
},
};
user.guilds.push(group._id);
await user.save();
expect(group.purchased.plan.planId).to.not.exist;
data.groupId = group._id;
await api.createSubscription(data);
@@ -211,10 +216,15 @@ describe('Canceling a subscription for group', () => {
await api.createSubscription(data);
await api.cancelSubscription(data);
expect(sender.sendTxn).to.be.have.callCount(4);
expect(sender.sendTxn.thirdCall.args[0]._id).to.equal(recipient._id);
expect(sender.sendTxn.thirdCall.args[1]).to.equal('group-member-cancel');
expect(sender.sendTxn.thirdCall.args[2]).to.eql([
expect(sender.sendTxn).to.be.have.callCount(6);
const recipientCall = sender.sendTxn.getCalls().find(call => {
const isRecipient = call.args[0]._id === recipient._id;
const isGroupMemberCancel = call.args[1] === 'group-member-cancel';
return isRecipient && isGroupMemberCancel;
});
expect(recipientCall.args[0]._id).to.equal(recipient._id);
expect(recipientCall.args[1]).to.equal('group-member-cancel');
expect(recipientCall.args[2]).to.eql([
{ name: 'LEADER', content: user.profile.name },
{ name: 'GROUP_NAME', content: group.name },
]);
@@ -246,8 +256,6 @@ describe('Canceling a subscription for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -259,11 +267,13 @@ describe('Canceling a subscription for group', () => {
const group2 = generateGroup({
name: 'test group2',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
data.groupId = group2._id;
await group2.save();
user.guilds.push(group2._id);
await user.save();
recipient.guilds.push(group2._id);
await recipient.save();
@@ -285,8 +295,6 @@ describe('Canceling a subscription for group', () => {
});
it('does cancel a leader subscription with two cancelled group plans', async () => {
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -298,7 +306,7 @@ describe('Canceling a subscription for group', () => {
const group2 = generateGroup({
name: 'test group2',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
user.guilds.push(group2._id);
@@ -12,6 +12,7 @@ import { model as Group } from '../../../../../../website/server/models/group';
import {
generateGroup,
} from '../../../../../helpers/api-unit.helper';
import i18n from '../../../../../../website/common/script/i18n';
describe('Purchasing a group plan for group', () => {
const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE = 'Google_subscription';
@@ -33,11 +34,14 @@ describe('Purchasing a group plan for group', () => {
group = generateGroup({
name: groupName,
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
await group.save();
user.guilds.push(group._id);
await user.save();
data = {
user,
sub: {
@@ -112,6 +116,30 @@ describe('Purchasing a group plan for group', () => {
expect(updatedGroup.purchased.plan.dateCreated).to.exist;
});
it('does not create a group plan for a public guild', async () => {
const publicGroup = generateGroup({
name: groupName,
type: 'guild',
privacy: 'public',
leader: user._id,
});
await publicGroup.save();
expect(publicGroup.purchased.plan.planId).to.not.exist;
data.groupId = publicGroup._id;
await expect(api.createSubscription(data))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
name: 'NotAuthorized',
message: i18n.t('onlyPrivateGuildsCanUpgrade'),
});
const updatedGroup = await Group.findById(publicGroup._id).exec();
expect(updatedGroup.purchased.plan.planId).to.not.exist;
});
it('sends an email', async () => {
expect(group.purchased.plan.planId).to.not.exist;
data.groupId = group._id;
@@ -148,8 +176,6 @@ describe('Purchasing a group plan for group', () => {
});
it('grants all members of a group a subscription', async () => {
user.guilds.push(group._id);
await user.save();
expect(group.purchased.plan.planId).to.not.exist;
data.groupId = group._id;
@@ -179,17 +205,28 @@ describe('Purchasing a group plan for group', () => {
await api.createSubscription(data);
expect(sender.sendTxn).to.be.calledTwice;
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
expect(sender.sendTxn.firstCall.args[2]).to.eql([
expect(sender.sendTxn).to.be.calledThrice;
const recipientCall = sender.sendTxn.getCalls().find(call => {
const isRecipient = call.args[0]._id === recipient._id;
const isJoin = call.args[1] === 'group-member-join';
return isRecipient && isJoin;
});
expect(recipientCall.args[0]._id).to.equal(recipient._id);
expect(recipientCall.args[1]).to.equal('group-member-join');
expect(recipientCall.args[2]).to.eql([
{ name: 'LEADER', content: user.profile.name },
{ name: 'GROUP_NAME', content: group.name },
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE },
]);
// confirm that the other email sent is appropriate:
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins');
const leaderCall = sender.sendTxn.getCalls().find(call => {
const isLeader = call.args[0]._id === group.leader;
const isSubscriptionBegin = call.args[1] === 'group-subscription-begins';
return isLeader && isSubscriptionBegin;
});
expect(leaderCall.args[0]._id).to.equal(group.leader);
expect(leaderCall.args[1]).to.equal('group-subscription-begins');
});
it('sends one email to subscribed member of group, stating subscription is cancelled (Stripe)', async () => {
@@ -205,17 +242,28 @@ describe('Purchasing a group plan for group', () => {
await api.createSubscription(data);
expect(sender.sendTxn).to.be.calledTwice;
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
expect(sender.sendTxn.firstCall.args[2]).to.eql([
expect(sender.sendTxn).to.be.calledThrice;
const recipientCall = sender.sendTxn.getCalls().find(call => {
const isRecipient = call.args[0]._id === recipient._id;
const isJoin = call.args[1] === 'group-member-join';
return isRecipient && isJoin;
});
expect(recipientCall.args[0]._id).to.equal(recipient._id);
expect(recipientCall.args[1]).to.equal('group-member-join');
expect(recipientCall.args[2]).to.eql([
{ name: 'LEADER', content: user.profile.name },
{ name: 'GROUP_NAME', content: group.name },
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL },
]);
// confirm that the other email sent is not a cancel-subscription email:
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins');
const leaderCall = sender.sendTxn.getCalls().find(call => {
const isLeader = call.args[0]._id === group.leader;
const isSubscriptionBegin = call.args[1] === 'group-subscription-begins';
return isLeader && isSubscriptionBegin;
});
expect(leaderCall.args[0]._id).to.equal(group.leader);
expect(leaderCall.args[1]).to.equal('group-subscription-begins');
});
it('sends one email to subscribed member of group, stating subscription is cancelled (Amazon)', async () => {
@@ -238,17 +286,28 @@ describe('Purchasing a group plan for group', () => {
await api.createSubscription(data);
expect(sender.sendTxn).to.be.calledTwice;
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
expect(sender.sendTxn.firstCall.args[2]).to.eql([
expect(sender.sendTxn).to.be.calledThrice;
const recipientCall = sender.sendTxn.getCalls().find(call => {
const isRecipient = call.args[0]._id === recipient._id;
const isJoin = call.args[1] === 'group-member-join';
return isRecipient && isJoin;
});
expect(recipientCall.args[0]._id).to.equal(recipient._id);
expect(recipientCall.args[1]).to.equal('group-member-join');
expect(recipientCall.args[2]).to.eql([
{ name: 'LEADER', content: user.profile.name },
{ name: 'GROUP_NAME', content: group.name },
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL },
]);
// confirm that the other email sent is not a cancel-subscription email:
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins');
const leaderCall = sender.sendTxn.getCalls().find(call => {
const isLeader = call.args[0]._id === group.leader;
const isSubscriptionBegin = call.args[1] === 'group-subscription-begins';
return isLeader && isSubscriptionBegin;
});
expect(leaderCall.args[0]._id).to.equal(group.leader);
expect(leaderCall.args[1]).to.equal('group-subscription-begins');
amzLib.getBillingAgreementDetails.restore();
});
@@ -275,17 +334,28 @@ describe('Purchasing a group plan for group', () => {
await api.createSubscription(data);
expect(sender.sendTxn).to.be.calledTwice;
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id);
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join');
expect(sender.sendTxn.firstCall.args[2]).to.eql([
expect(sender.sendTxn).to.be.calledThrice;
const recipientCall = sender.sendTxn.getCalls().find(call => {
const isRecipient = call.args[0]._id === recipient._id;
const isJoin = call.args[1] === 'group-member-join';
return isRecipient && isJoin;
});
expect(recipientCall.args[0]._id).to.equal(recipient._id);
expect(recipientCall.args[1]).to.equal('group-member-join');
expect(recipientCall.args[2]).to.eql([
{ name: 'LEADER', content: user.profile.name },
{ name: 'GROUP_NAME', content: group.name },
{ name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL },
]);
// confirm that the other email sent is not a cancel-subscription email:
expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader);
expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins');
const leaderCall = sender.sendTxn.getCalls().find(call => {
const isLeader = call.args[0]._id === group.leader;
const isSubscriptionBegin = call.args[1] === 'group-subscription-begins';
return isLeader && isSubscriptionBegin;
});
expect(leaderCall.args[0]._id).to.equal(group.leader);
expect(leaderCall.args[1]).to.equal('group-subscription-begins');
paypalPayments.paypalBillingAgreementGet.restore();
paypalPayments.paypalBillingAgreementCancel.restore();
@@ -302,8 +372,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -356,8 +424,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -419,8 +485,6 @@ describe('Purchasing a group plan for group', () => {
data.gift = undefined;
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -455,8 +519,6 @@ describe('Purchasing a group plan for group', () => {
data.gift = undefined;
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -483,8 +545,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -511,8 +571,6 @@ describe('Purchasing a group plan for group', () => {
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -541,8 +599,6 @@ describe('Purchasing a group plan for group', () => {
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -566,8 +622,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await recipient.cancelSubscription();
@@ -589,8 +643,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await recipient.cancelSubscription();
@@ -611,8 +663,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -632,8 +682,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -653,8 +701,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -688,8 +734,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -713,8 +757,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -726,13 +768,15 @@ describe('Purchasing a group plan for group', () => {
const group2 = generateGroup({
name: 'test group2',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
data.groupId = group2._id;
await group2.save();
recipient.guilds.push(group2._id);
await recipient.save();
user.guilds.push(group2._id);
await user.save();
await api.createSubscription(data);
@@ -757,8 +801,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -770,17 +812,22 @@ describe('Purchasing a group plan for group', () => {
const group2 = generateGroup({
name: 'test group2',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
data.groupId = group2._id;
await group2.save();
recipient.guilds.push(group2._id);
await recipient.save();
user.guilds.push(group2._id);
await user.save();
await api.createSubscription(data);
const updatedGroup = await Group.findById(group._id).exec();
updatedGroup.memberCount = 2;
await updatedGroup.save();
await updatedGroup.leave(recipient);
updatedUser = await User.findById(recipient._id).exec();
@@ -806,8 +853,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -835,8 +880,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -864,8 +907,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
@@ -894,8 +935,6 @@ describe('Purchasing a group plan for group', () => {
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
+48 -16
View File
@@ -1,6 +1,7 @@
import moment from 'moment';
import * as sender from '../../../../../website/server/libs/email';
import common from '../../../../../website/common';
import api from '../../../../../website/server/libs/payments/payments';
import * as analytics from '../../../../../website/server/libs/analyticsService';
import * as notifications from '../../../../../website/server/libs/pushNotifications';
@@ -9,6 +10,7 @@ import { translate as t } from '../../../../helpers/api-integration/v3';
import {
generateGroup,
} from '../../../../helpers/api-unit.helper';
import * as worldState from '../../../../../website/server/libs/worldState';
describe('payments/index', () => {
let user; let group; let data; let
@@ -555,6 +557,7 @@ describe('payments/index', () => {
beforeEach(() => {
data = {
user,
gemsBlock: common.content.gems['21gems'],
paymentMethod: 'payment',
headers: {
'x-client': 'habitica-web',
@@ -564,22 +567,6 @@ describe('payments/index', () => {
});
context('Self Purchase', () => {
it('amount property defaults to 5', async () => {
expect(user.balance).to.eql(0);
await api.buyGems(data);
expect(user.balance).to.eql(5);
});
it('can set amount that is purchased', async () => {
data.amount = 13;
await api.buyGems(data);
expect(user.balance).to.eql(13);
});
it('sends a donation email', async () => {
await api.buyGems(data);
@@ -588,6 +575,51 @@ describe('payments/index', () => {
});
});
context('No Active Promotion', () => {
beforeEach(() => {
sinon.stub(worldState, 'getCurrentEvent').returns(null);
});
afterEach(() => {
worldState.getCurrentEvent.restore();
});
it('does not apply a discount', async () => {
const balanceBefore = user.balance;
await api.buyGems(data);
const balanceAfter = user.balance;
const balanceDiff = balanceAfter - balanceBefore;
expect(balanceDiff * 4).to.eql(21);
});
});
context('Active Promotion', () => {
beforeEach(() => {
sinon.stub(worldState, 'getCurrentEvent').returns({
...common.content.events.fall2020,
event: 'fall2020',
});
});
afterEach(() => {
worldState.getCurrentEvent.restore();
});
it('applies a discount', async () => {
const balanceBefore = user.balance;
await api.buyGems(data);
const balanceAfter = user.balance;
const balanceDiff = balanceAfter - balanceBefore;
expect(balanceDiff * 4).to.eql(30);
});
});
context('Gift', () => {
let recipient;
@@ -2,11 +2,13 @@
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
import payments from '../../../../../../website/server/libs/payments/payments';
import { model as User } from '../../../../../../website/server/models/user';
import common from '../../../../../../website/common';
describe('checkout success', () => {
describe('paypal - checkout success', () => {
const subKey = 'basic_3mo';
let user; let gift; let customerId; let
paymentId;
const gemsBlockKey = '21gems'; const gemsBlock = common.content.gems[gemsBlockKey];
let paypalPaymentExecuteStub; let paymentBuyGemsStub; let
paymentsCreateSubscritionStub;
@@ -28,7 +30,7 @@ describe('checkout success', () => {
it('purchases gems', async () => {
await paypalPayments.checkoutSuccess({
user, gift, paymentId, customerId,
user, gift, paymentId, customerId, gemsBlock: gemsBlockKey,
});
expect(paypalPaymentExecuteStub).to.be.calledOnce;
@@ -38,6 +40,7 @@ describe('checkout success', () => {
user,
customerId,
paymentMethod: 'Paypal',
gemsBlock,
});
});
@@ -4,12 +4,14 @@ import nconf from 'nconf';
import paypalPayments from '../../../../../../website/server/libs/payments/paypal';
import { model as User } from '../../../../../../website/server/models/user';
import common from '../../../../../../website/common';
import apiError from '../../../../../../website/server/libs/apiError';
const BASE_URL = nconf.get('BASE_URL');
const { i18n } = common;
describe('checkout', () => {
describe('paypal - checkout', () => {
const subKey = 'basic_3mo';
const gemsBlockKey = '21gems';
let paypalPaymentCreateStub;
let approvalHerf;
@@ -53,10 +55,10 @@ describe('checkout', () => {
});
it('creates a link for gem purchases', async () => {
const link = await paypalPayments.checkout({ user: new User() });
const link = await paypalPayments.checkout({ user: new User(), gemsBlock: gemsBlockKey });
expect(paypalPaymentCreateStub).to.be.calledOnce;
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('Habitica Gems', 5.00));
expect(paypalPaymentCreateStub).to.be.calledWith(getPaypalCreateOptions('Habitica Gems', 4.99));
expect(link).to.eql(approvalHerf);
});
@@ -83,11 +85,23 @@ describe('checkout', () => {
const user = new User();
sinon.stub(user, 'canGetGems').resolves(false);
await expect(paypalPayments.checkout({ user })).to.eventually.be.rejected.and.to.eql({
httpCode: 401,
message: i18n.t('groupPolicyCannotGetGems'),
name: 'NotAuthorized',
});
await expect(paypalPayments.checkout({ user, gemsBlock: gemsBlockKey }))
.to.eventually.be.rejected.and.to.eql({
httpCode: 401,
message: i18n.t('groupPolicyCannotGetGems'),
name: 'NotAuthorized',
});
});
it('should error if the gems block is not valid', async () => {
const user = new User();
await expect(paypalPayments.checkout({ user, gemsBlock: 'invalid' }))
.to.eventually.be.rejected.and.to.eql({
httpCode: 400,
message: apiError('invalidGemsBlock'),
name: 'BadRequest',
});
});
it('creates a link for gifting gems', async () => {
@@ -6,7 +6,7 @@ import {
} from '../../../../../helpers/api-unit.helper';
import { model as User } from '../../../../../../website/server/models/user';
describe('ipn', () => {
describe('paypal - ipn', () => {
const subKey = 'basic_3mo';
let user; let group; let txn_type; let userPaymentId; let
groupPaymentId;
@@ -10,7 +10,7 @@ import { createNonLeaderGroupMember } from '../paymentHelpers';
const { i18n } = common;
describe('subscribeCancel', () => {
describe('paypal - subscribeCancel', () => {
const subKey = 'basic_3mo';
let user; let group; let groupId; let customerId; let groupCustomerId; let
nextBillingDate;
@@ -7,7 +7,7 @@ import {
import { model as User } from '../../../../../../website/server/models/user';
import common from '../../../../../../website/common';
describe('subscribeSuccess', () => {
describe('paypal - subscribeSuccess', () => {
const subKey = 'basic_3mo';
let user; let group; let block; let groupId; let token; let headers; let
customerId;
@@ -8,7 +8,7 @@ import common from '../../../../../../website/common';
const { i18n } = common;
describe('subscribe', () => {
describe('paypal - subscribe', () => {
const subKey = 'basic_3mo';
let coupon; let sub; let
approvalHerf;
@@ -4,7 +4,7 @@ import api from '../../../../../../website/server/libs/payments/payments';
const groupPlanId = api.constants.GROUP_PLAN_CUSTOMER_ID;
describe('#calculateSubscriptionTerminationDate', () => {
describe('stripe - #calculateSubscriptionTerminationDate', () => {
let plan;
let nextBill;
@@ -10,7 +10,7 @@ import common from '../../../../../../website/common';
const { i18n } = common;
describe('cancel subscription', () => {
describe('stripe - cancel subscription', () => {
const subKey = 'basic_3mo';
const stripe = stripeModule('test');
let user; let groupId; let
@@ -12,7 +12,7 @@ import common from '../../../../../../website/common';
const { i18n } = common;
describe('checkout with subscription', () => {
describe('stripe - checkout with subscription', () => {
const subKey = 'basic_3mo';
const stripe = stripeModule('test');
let user; let group; let data; let gift; let sub;
@@ -4,16 +4,17 @@ import { model as User } from '../../../../../../website/server/models/user';
import stripePayments from '../../../../../../website/server/libs/payments/stripe';
import payments from '../../../../../../website/server/libs/payments/payments';
import common from '../../../../../../website/common';
import apiError from '../../../../../../website/server/libs/apiError';
const { i18n } = common;
describe('checkout', () => {
describe('stripe - checkout', () => {
const subKey = 'basic_3mo';
const stripe = stripeModule('test');
let stripeChargeStub; let paymentBuyGemsStub; let
paymentCreateSubscritionStub;
let user; let gift; let groupId; let email; let headers; let coupon; let customerIdResponse; let
token;
token; const gemsBlockKey = '21gems'; const gemsBlock = common.content.gems[gemsBlockKey];
beforeEach(() => {
user = new User();
@@ -89,6 +90,7 @@ describe('checkout', () => {
await expect(stripePayments.checkout({
token,
user,
gemsBlock: gemsBlockKey,
gift,
groupId,
email,
@@ -101,6 +103,25 @@ describe('checkout', () => {
});
});
it('should error if the gems block is invalid', async () => {
gift = undefined;
await expect(stripePayments.checkout({
token,
user,
gemsBlock: 'invalid',
gift,
groupId,
email,
headers,
coupon,
}, stripe)).to.eventually.be.rejected.and.to.eql({
httpCode: 400,
message: apiError('invalidGemsBlock'),
name: 'BadRequest',
});
});
it('should purchase gems', async () => {
gift = undefined;
sinon.stub(user, 'canGetGems').resolves(true);
@@ -108,6 +129,7 @@ describe('checkout', () => {
await stripePayments.checkout({
token,
user,
gemsBlock: gemsBlockKey,
gift,
groupId,
email,
@@ -117,7 +139,7 @@ describe('checkout', () => {
expect(stripeChargeStub).to.be.calledOnce;
expect(stripeChargeStub).to.be.calledWith({
amount: 500,
amount: 499,
currency: 'usd',
card: token,
});
@@ -128,6 +150,7 @@ describe('checkout', () => {
customerId: customerIdResponse,
paymentMethod: 'Stripe',
gift,
gemsBlock,
});
expect(user.canGetGems).to.be.calledOnce;
user.canGetGems.restore();
@@ -167,6 +190,7 @@ describe('checkout', () => {
customerId: customerIdResponse,
paymentMethod: 'Gift',
gift,
gemsBlock: undefined,
});
});
@@ -205,6 +229,7 @@ describe('checkout', () => {
customerId: customerIdResponse,
paymentMethod: 'Gift',
gift,
gemsBlock: undefined,
});
});
});
@@ -9,7 +9,7 @@ import common from '../../../../../../website/common';
const { i18n } = common;
describe('edit subscription', () => {
describe('stripe - edit subscription', () => {
const subKey = 'basic_3mo';
const stripe = stripeModule('test');
let user; let groupId; let group; let
@@ -33,11 +33,14 @@ describe('Stripe - Upgrade Group Plan', () => {
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'public',
privacy: 'private',
leader: user._id,
});
await group.save();
user.guilds.push(group._id);
await user.save();
spy = sinon.stub(stripe.subscriptions, 'update');
spy.resolves([]);
data.groupId = group._id;
+130 -3
View File
@@ -3,7 +3,6 @@ import { model as Challenge } from '../../../../website/server/models/challenge'
import { model as Group } from '../../../../website/server/models/group';
import { model as User } from '../../../../website/server/models/user';
import * as Tasks from '../../../../website/server/models/task';
import { InternalServerError } from '../../../../website/server/libs/errors';
import { generateHistory } from '../../../helpers/api-unit.helper';
describe('Task Model', () => {
@@ -99,7 +98,8 @@ describe('Task Model', () => {
throw new Error('No exception when Id is None');
} catch (err) {
expect(err).to.exist;
expect(err).to.eql(new InternalServerError('Task identifier is a required argument'));
expect(err).to.be.an.instanceOf(Error);
expect(err.message).to.eql('Task identifier is a required argument');
}
});
@@ -109,7 +109,8 @@ describe('Task Model', () => {
throw new Error('No exception when user_id is undefined');
} catch (err) {
expect(err).to.exist;
expect(err).to.eql(new InternalServerError('User identifier is a required argument'));
expect(err).to.be.an.instanceOf(Error);
expect(err.message).to.eql('User identifier is a required argument');
}
});
@@ -153,6 +154,132 @@ describe('Task Model', () => {
});
});
describe('findMultipleByIdOrAlias', () => {
let taskWithAlias;
let secondTask;
let user;
beforeEach(async () => {
user = new User();
await user.save();
taskWithAlias = new Tasks.todo({ // eslint-disable-line new-cap
text: 'some text',
alias: 'short-name',
userId: user.id,
});
await taskWithAlias.save();
secondTask = new Tasks.habit({ // eslint-disable-line new-cap
text: 'second task',
alias: 'second-short-name',
userId: user.id,
});
await secondTask.save();
sandbox.spy(Tasks.Task, 'find');
});
it('throws an error if task identifiers is not passed in', async () => {
try {
await Tasks.Task.findMultipleByIdOrAlias(null, user._id);
throw new Error('No exception when Id is None');
} catch (err) {
expect(err).to.exist;
expect(err).to.be.an.instanceOf(Error);
expect(err.message).to.eql('Task identifiers is a required array argument');
}
});
it('throws an error if task identifiers is not an array', async () => {
try {
await Tasks.Task.findMultipleByIdOrAlias('string', user._id);
throw new Error('No exception when Id is None');
} catch (err) {
expect(err).to.exist;
expect(err).to.be.an.instanceOf(Error);
expect(err.message).to.eql('Task identifiers is a required array argument');
}
});
it('throws an error if user identifier is not passed in', async () => {
try {
await Tasks.Task.findMultipleByIdOrAlias([taskWithAlias._id]);
throw new Error('No exception when user_id is undefined');
} catch (err) {
expect(err).to.exist;
expect(err).to.be.an.instanceOf(Error);
expect(err.message).to.eql('User identifier is a required argument');
}
});
it('returns task by id', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias([taskWithAlias._id], user._id);
expect(foundTasks[0].text).to.eql(taskWithAlias.text);
});
it('returns task by alias', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(
[taskWithAlias.alias], user._id,
);
expect(foundTasks[0].text).to.eql(taskWithAlias.text);
});
it('returns multiple tasks', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(
[taskWithAlias.alias, secondTask._id], user._id,
);
expect(foundTasks.length).to.eql(2);
expect(foundTasks[0]._id).to.eql(taskWithAlias._id);
expect(foundTasks[1]._id).to.eql(secondTask._id);
});
it('returns a task only once if searched by both id and alias', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(
[taskWithAlias.alias, taskWithAlias._id], user._id,
);
expect(foundTasks.length).to.eql(1);
expect(foundTasks[0].text).to.eql(taskWithAlias.text);
});
it('scopes alias lookup to user', async () => {
await Tasks.Task.findMultipleByIdOrAlias([taskWithAlias.alias], user._id);
expect(Tasks.Task.find).to.be.calledOnce;
expect(Tasks.Task.find).to.be.calledWithMatch({
$or: [
{ _id: { $in: [] } },
{ alias: { $in: [taskWithAlias.alias] } },
],
userId: user._id,
});
});
it('returns empty array if tasks cannot be found', async () => {
const foundTasks = await Tasks.Task.findMultipleByIdOrAlias(['not-found'], user._id);
expect(foundTasks).to.eql([]);
});
it('accepts additional query parameters', async () => {
await Tasks.Task.findMultipleByIdOrAlias([taskWithAlias.alias], user._id, { foo: 'bar' });
expect(Tasks.Task.find).to.be.calledOnce;
expect(Tasks.Task.find).to.be.calledWithMatch({
$or: [
{ _id: { $in: [] } },
{ alias: { $in: [taskWithAlias.alias] } },
],
userId: user._id,
foo: 'bar',
});
});
});
describe('sanitizeUserChallengeTask ', () => {
});
@@ -6,8 +6,8 @@ import {
describe('GET challenges/user', () => {
context('no official challenges', () => {
let user; let member; let nonMember; let challenge; let challenge2; let
publicGuild;
let user; let member; let nonMember; let challenge; let challenge2;
let publicGuild; let userData; let groupData;
before(async () => {
const { group, groupLeader, members } = await createAndPopulateGroup({
@@ -19,225 +19,197 @@ describe('GET challenges/user', () => {
members: 1,
});
user = groupLeader;
publicGuild = group;
groupData = {
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
};
user = groupLeader;
userData = {
_id: publicGuild.leader._id,
id: publicGuild.leader._id,
profile: { name: user.profile.name },
auth: {
local: {
username: user.auth.local.username,
},
},
flags: {
verifiedUsername: true,
},
};
member = members[0]; // eslint-disable-line prefer-destructuring
nonMember = await generateUser();
challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
});
it('should return challenges user has joined', async () => {
await nonMember.post(`/challenges/${challenge._id}/join`);
});
context('all challenges', () => {
it('should return challenges user has joined', async () => {
const challenges = await nonMember.get('/challenges/user');
const challenges = await nonMember.get('/challenges/user');
const foundChallenge = _.find(challenges, { _id: challenge._id });
expect(foundChallenge).to.exist;
expect(foundChallenge.leader).to.eql(userData);
expect(foundChallenge.group).to.eql(groupData);
});
const foundChallenge = _.find(challenges, { _id: challenge._id });
expect(foundChallenge).to.exist;
expect(foundChallenge.leader).to.eql({
_id: publicGuild.leader._id,
id: publicGuild.leader._id,
profile: { name: user.profile.name },
auth: {
local: {
username: user.auth.local.username,
it('should not return challenges a non-member has not joined', async () => {
const challenges = await nonMember.get('/challenges/user');
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.not.exist;
});
it('should return challenges user has created', async () => {
const challenges = await user.get('/challenges/user');
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.exist;
expect(foundChallenge1.leader).to.eql(userData);
expect(foundChallenge1.group).to.eql(groupData);
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.exist;
expect(foundChallenge2.leader).to.eql(userData);
expect(foundChallenge2.group).to.eql(groupData);
});
it('should return challenges in user\'s group', async () => {
const challenges = await member.get('/challenges/user');
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.exist;
expect(foundChallenge1.leader).to.eql(userData);
expect(foundChallenge1.group).to.eql(groupData);
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.exist;
expect(foundChallenge2.leader).to.eql(userData);
expect(foundChallenge2.group).to.eql(groupData);
});
it('should return newest challenges first', async () => {
let challenges = await user.get('/challenges/user');
let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
expect(foundChallengeIndex).to.eql(0);
const newChallenge = await generateChallenge(user, publicGuild);
await user.post(`/challenges/${newChallenge._id}/join`);
challenges = await user.get('/challenges/user');
foundChallengeIndex = _.findIndex(challenges, { _id: newChallenge._id });
expect(foundChallengeIndex).to.eql(0);
});
it('should not return challenges user doesn\'t have access to', async () => {
const { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'TestPrivateGuild',
summary: 'summary for TestPrivateGuild',
type: 'guild',
privacy: 'private',
},
},
flags: {
verifiedUsername: true,
},
});
expect(foundChallenge.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
});
});
it('should return challenges user has created', async () => {
const challenges = await user.get('/challenges/user');
const privateChallenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.exist;
expect(foundChallenge1.leader).to.eql({
_id: publicGuild.leader._id,
id: publicGuild.leader._id,
profile: { name: user.profile.name },
auth: {
local: {
username: user.auth.local.username,
const challenges = await nonMember.get('/challenges/user');
const foundChallenge = _.find(challenges, { _id: privateChallenge._id });
expect(foundChallenge).to.not.exist;
});
it('should not return challenges user doesn\'t have access to, even with query parameters', async () => {
const { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'TestPrivateGuild',
summary: 'summary for TestPrivateGuild',
type: 'guild',
privacy: 'private',
},
},
flags: {
verifiedUsername: true,
},
});
expect(foundChallenge1.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.exist;
expect(foundChallenge2.leader).to.eql({
_id: publicGuild.leader._id,
id: publicGuild.leader._id,
profile: { name: user.profile.name },
auth: {
local: {
username: user.auth.local.username,
},
},
flags: {
verifiedUsername: true,
},
});
expect(foundChallenge2.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
const privateChallenge = await generateChallenge(groupLeader, group, {
categories: [{
name: 'academics',
slug: 'academics',
}],
});
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
const challenges = await nonMember.get('/challenges/user?categories=academics&owned=not_owned');
const foundChallenge = _.find(challenges, { _id: privateChallenge._id });
expect(foundChallenge).to.not.exist;
});
});
it('should return challenges in user\'s group', async () => {
const challenges = await member.get('/challenges/user');
context('my challenges', () => {
it('should return challenges user has joined', async () => {
const challenges = await nonMember.get(`/challenges/user?member=${true}`);
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.exist;
expect(foundChallenge1.leader).to.eql({
_id: publicGuild.leader._id,
id: publicGuild.leader._id,
profile: { name: user.profile.name },
auth: {
local: {
username: user.auth.local.username,
},
},
flags: {
verifiedUsername: true,
},
});
expect(foundChallenge1.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.exist;
expect(foundChallenge2.leader).to.eql({
_id: publicGuild.leader._id,
id: publicGuild.leader._id,
profile: { name: user.profile.name },
auth: {
local: {
username: user.auth.local.username,
},
},
flags: {
verifiedUsername: true,
},
});
expect(foundChallenge2.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
});
it('should not return challenges in user groups if we send member true param', async () => {
const challenges = await member.get(`/challenges/user?member=${true}`);
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.not.exist;
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.not.exist;
});
it('should return newest challenges first', async () => {
let challenges = await user.get('/challenges/user');
let foundChallengeIndex = _.findIndex(challenges, { _id: challenge2._id });
expect(foundChallengeIndex).to.eql(0);
const newChallenge = await generateChallenge(user, publicGuild);
await user.post(`/challenges/${newChallenge._id}/join`);
challenges = await user.get('/challenges/user');
foundChallengeIndex = _.findIndex(challenges, { _id: newChallenge._id });
expect(foundChallengeIndex).to.eql(0);
});
it('should not return challenges user doesn\'t have access to', async () => {
const { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'TestPrivateGuild',
summary: 'summary for TestPrivateGuild',
type: 'guild',
privacy: 'private',
},
const foundChallenge = _.find(challenges, { _id: challenge._id });
expect(foundChallenge).to.exist;
expect(foundChallenge.leader).to.eql(userData);
expect(foundChallenge.group).to.eql(groupData);
});
const privateChallenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
it('should return challenges user has created', async () => {
const challenges = await user.get(`/challenges/user?member=${true}`);
const challenges = await nonMember.get('/challenges/user');
const foundChallenge = _.find(challenges, { _id: privateChallenge._id });
expect(foundChallenge).to.not.exist;
});
it('should not return challenges user doesn\'t have access to, even with query parameters', async () => {
const { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'TestPrivateGuild',
summary: 'summary for TestPrivateGuild',
type: 'guild',
privacy: 'private',
},
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.exist;
expect(foundChallenge1.leader).to.eql(userData);
expect(foundChallenge1.group).to.eql(groupData);
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.exist;
expect(foundChallenge2.leader).to.eql(userData);
expect(foundChallenge2.group).to.eql(groupData);
});
const privateChallenge = await generateChallenge(groupLeader, group, {
categories: [{
name: 'academics',
slug: 'academics',
}],
it('should return challenges user has created if filter by owned', async () => {
const challenges = await user.get(`/challenges/user?member=${true}&owned=owned`);
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.exist;
expect(foundChallenge1.leader).to.eql(userData);
expect(foundChallenge1.group).to.eql(groupData);
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.exist;
expect(foundChallenge2.leader).to.eql(userData);
expect(foundChallenge2.group).to.eql(groupData);
});
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
const challenges = await nonMember.get('/challenges/user?categories=academics&owned=not_owned');
it('should not return challenges user has created if filter by not owned', async () => {
const challenges = await user.get(`/challenges/user?owned=not_owned&member=${true}`);
const foundChallenge = _.find(challenges, { _id: privateChallenge._id });
expect(foundChallenge).to.not.exist;
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.not.exist;
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.not.exist;
});
it('should not return challenges in user groups', async () => {
const challenges = await member.get(`/challenges/user?member=${true}`);
const foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.not.exist;
const foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.not.exist;
});
});
});
@@ -159,7 +159,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
expect(testTask.challenge.broken).to.eql('CHALLENGE_CLOSED');
expect(testTask.challenge.winner).to.eql(winningUser.profile.name);
expect(challengeTag.challenge).to.eql('false');
expect(challengeTag.challenge).to.eql(false);
});
});
});
@@ -14,7 +14,6 @@ import {
TAVERN_ID,
} from '../../../../../website/server/models/group';
import { CHAT_FLAG_FROM_SHADOW_MUTE, MAX_MESSAGE_LENGTH } from '../../../../../website/common/script/constants';
import guildsAllowingBannedWords from '../../../../../website/server/libs/guildsAllowingBannedWords';
import * as email from '../../../../../website/server/libs/email';
const BASE_URL = nconf.get('BASE_URL');
@@ -329,7 +328,8 @@ describe('POST /chat', () => {
members: 1,
});
guildsAllowingBannedWords[group._id] = true;
// Update the bannedWordsAllowed property for the group
group.update({ bannedWordsAllowed: true });
const message = await members[0].post(`/groups/${group._id}/chat`, { message: testBannedWordMessage });
@@ -503,8 +503,8 @@ describe('POST /chat', () => {
const memberUsername = 'memberUsername';
await member.update({ 'auth.local.username': memberUsername });
const messageWithMentions = `hi @${memberUsername} 123456789
123456789 123456789 123456789 123456789 123456789 123456789 89 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678 END.`;
const messageWithMentions = `hi @${memberUsername} 123456789
123456789 123456789 123456789 123456789 123456789 123456789 89 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 12345678 END.`;
expect(messageWithMentions.length).to.equal(MAX_MESSAGE_LENGTH);
const newMessage = await user.post(`/groups/${groupWithChat._id}/chat`, { message: messageWithMentions });
const groupMessages = await user.get(`/groups/${groupWithChat._id}/chat`);
@@ -12,7 +12,7 @@ import apiError from '../../../../../website/server/libs/apiError';
describe('GET /groups', () => {
let user;
let userInGuild;
const NUMBER_OF_PUBLIC_GUILDS = 3; // 2 + the tavern
const NUMBER_OF_PUBLIC_GUILDS = 2;
const NUMBER_OF_PUBLIC_GUILDS_USER_IS_LEADER = 2;
const NUMBER_OF_PUBLIC_GUILDS_USER_IS_MEMBER = 1;
const NUMBER_OF_USERS_PRIVATE_GUILDS = 1;
@@ -236,11 +236,22 @@ describe('GET /groups', () => {
await expect(user.get('/groups?type=publicGuilds&paginate=true&page=1'))
.to.eventually.have.a.lengthOf(GUILD_PER_PAGE);
const page2 = await expect(user.get('/groups?type=publicGuilds&paginate=true&page=2'))
.to.eventually.have.a.lengthOf(1 + 4); // 1 created now, 4 by other tests
expect(page2[4].name).to.equal('guild with less members');
// 1 created now, 4 by other tests, -1 for no more tavern.
.to.eventually.have.a.lengthOf(1 + 4 - 1);
expect(page2[3].name).to.equal('guild with less members');
}).timeout(10000);
});
it('makes sure that the tavern doesn\'t show up when guilds is passed as a query', async () => {
const guilds = await user.get('/groups?type=guilds');
expect(guilds.find(g => g.id === TAVERN_ID)).to.be.undefined;
});
it('makes sure that the tavern doesn\'t show up when publicGuilds is passed as a query', async () => {
const guilds = await user.get('/groups?type=publicGuilds');
expect(guilds.find(g => g.id === TAVERN_ID)).to.be.undefined;
});
it('returns all the user\'s guilds when guilds passed in as query', async () => {
await expect(user.get('/groups?type=guilds'))
.to.eventually.have.a
@@ -254,7 +265,7 @@ describe('GET /groups', () => {
it('returns a list of groups user has access to', async () => {
await expect(user.get('/groups?type=privateGuilds,publicGuilds,party,tavern'))
.to.eventually.have.lengthOf(NUMBER_OF_GROUPS_USER_CAN_VIEW);
.to.eventually.have.lengthOf(NUMBER_OF_GROUPS_USER_CAN_VIEW - 1); // -1 for no Tavern.
});
it('returns a list of groups user has access to', async () => {
@@ -274,6 +274,7 @@ describe('POST /groups/:groupId/leave', () => {
each(typesOfGroups, (groupDetails, groupType) => {
context(`Leaving a group plan when the group is a ${groupType}`, () => {
if (groupDetails.privacy === 'public') return; // public guilds cannot be group plans
let groupWithPlan;
let leader;
let member;
@@ -341,6 +342,7 @@ describe('POST /groups/:groupId/leave', () => {
each(typesOfGroups, (groupDetails, groupType) => {
context(`Leaving a group with extraMonths left plan when the group is a ${groupType}`, () => {
if (groupDetails.privacy === 'public') return; // public guilds cannot be group plans
const extraMonths = 12;
let groupWithPlan;
let member;
@@ -79,4 +79,56 @@ describe('PUT /group', () => {
expect(updatedGroup.leader.profile.name).to.eql(nonLeader.profile.name);
expect(updatedGroup.name).to.equal(groupUpdatedName);
});
it('allows for an admin to update the bannedWordsAllow property for an existing guild', async () => {
const { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'public guild',
type: 'guild',
privacy: 'public',
},
});
const updateGroupDetails = {
id: group._id,
name: 'public guild',
type: 'guild',
privacy: 'public',
bannedWordsAllowed: true,
};
// Make guild leader into admin
await groupLeader.post('/debug/make-admin');
await groupLeader.sync();
// Update the bannedWordsAllowed property for the group
const response = await groupLeader.put(`/groups/${group._id}`, updateGroupDetails);
expect(groupLeader.contributor.admin).to.eql(true);
expect(response.bannedWordsAllowed).to.eql(true);
});
it('does not allow for a non-admin to update the bannedWordsAllow property for an existing guild', async () => {
const { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'public guild',
type: 'guild',
privacy: 'public',
},
});
const updateGroupDetails = {
id: group._id,
name: 'public guild',
type: 'guild',
privacy: 'public',
bannedWordsAllowed: true,
};
// Update the bannedWordsAllowed property for the group
const response = await groupLeader.put(`/groups/${group._id}`, updateGroupDetails);
expect(groupLeader.contributor.admin).to.eql(undefined);
expect(response.bannedWordsAllowed).to.eql(undefined);
});
});
@@ -14,7 +14,10 @@ describe('payments - stripe - #checkout', () => {
});
it('verifies credentials', async () => {
await expect(user.post(endpoint, { id: 123 })).to.eventually.be.rejected.and.include({
await expect(user.post(
`${endpoint}?gemsBlock=4gems`,
{ id: 123 },
)).to.eventually.be.rejected.and.include({
code: 401,
error: 'Error',
// message: 'Invalid API Key provided: aaaabbbb********************1111',
@@ -32,7 +35,7 @@ describe('payments - stripe - #checkout', () => {
stripePayments.checkout.restore();
});
it('cancels a user subscription', async () => {
it('creates a user subscription', async () => {
user = await generateUser({
'profile.name': 'sender',
'purchased.plan.customerId': 'customer-id',
@@ -48,7 +51,7 @@ describe('payments - stripe - #checkout', () => {
expect(stripeCheckoutSubscriptionStub.args[0][0].groupId).to.eql(undefined);
});
it('cancels a group subscription', async () => {
it('creates a group subscription', async () => {
user = await generateUser({
'profile.name': 'sender',
'purchased.plan.customerId': 'customer-id',
@@ -1,4 +1,5 @@
import { v4 as generateUUID } from 'uuid';
import apiError from '../../../../../website/server/libs/apiError';
import {
generateUser,
sleep,
@@ -44,7 +45,7 @@ describe('POST /tasks/:id/score/:direction', () => {
await expect(user.post(`/tasks/${generateUUID()}/score/tt`)).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
message: apiError('directionUpDown'),
});
});
@@ -261,6 +262,7 @@ describe('POST /tasks/:id/score/:direction', () => {
const task = await user.get(`/tasks/${daily._id}`);
expect(task.completed).to.equal(true);
expect(task.value).to.be.greaterThan(daily.value);
});
it('uncompletes daily when direction is down', async () => {
@@ -499,6 +499,45 @@ describe('PUT /tasks/:id', () => {
});
});
context('monthly dailys', () => {
let monthly;
beforeEach(async () => {
const date1 = moment.utc('2020-07-01').toDate();
monthly = await user.post('/tasks/user', {
text: 'test monthly',
type: 'daily',
frequency: 'monthly',
startDate: date1,
daysOfMonth: [date1.getDate()],
});
});
it('updates days of month when start date updated', async () => {
const date2 = moment.utc('2020-07-01').toDate();
const savedMonthly = await user.put(`/tasks/${monthly._id}`, {
startDate: date2,
});
expect(savedMonthly.daysOfMonth).to.deep.equal([moment(date2).date()]);
});
it('updates next due when start date updated', async () => {
const date2 = moment.utc('2022-07-01').toDate();
const savedMonthly = await user.put(`/tasks/${monthly._id}`, {
startDate: date2,
});
expect(savedMonthly.nextDue.length).to.eql(6);
expect(moment(savedMonthly.nextDue[0]).toDate()).to.eql(moment.utc('2022-08-01').toDate());
expect(moment(savedMonthly.nextDue[1]).toDate()).to.eql(moment.utc('2022-09-01').toDate());
expect(moment(savedMonthly.nextDue[2]).toDate()).to.eql(moment.utc('2022-10-01').toDate());
expect(moment(savedMonthly.nextDue[3]).toDate()).to.eql(moment.utc('2022-11-01').toDate());
expect(moment(savedMonthly.nextDue[4]).toDate()).to.eql(moment.utc('2022-12-01').toDate());
expect(moment(savedMonthly.nextDue[5]).toDate()).to.eql(moment.utc('2023-01-01').toDate());
});
});
context('rewards', () => {
let reward;
@@ -46,7 +46,7 @@ describe('POST /tasks/:id/score/:direction', () => {
const response = await member.post(`/tasks/${syncedTask._id}/score/${direction}`);
expect(response.data.approvalRequested).to.equal(true);
expect(response.data.requiresApproval).to.equal(true);
expect(response.message).to.equal(t('taskApprovalHasBeenRequested'));
const updatedTask = await member.get(`/tasks/${syncedTask._id}`);
@@ -107,12 +107,9 @@ describe('POST /tasks/:id/score/:direction', () => {
await member.post(`/tasks/${syncedTask._id}/score/up`);
await expect(member.post(`/tasks/${syncedTask._id}/score/up`))
.to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('taskRequiresApproval'),
});
const response = await member.post(`/tasks/${syncedTask._id}/score/up`);
expect(response.data.requiresApproval).to.equal(true);
expect(response.message).to.equal(t('taskRequiresApproval'));
});
it('allows a user to score an approved task', async () => {
@@ -73,7 +73,7 @@ describe('PUT /tasks/:id', () => {
// score up to trigger approval
const response = await member2.post(`/tasks/${syncedTask._id}/score/up`);
expect(response.data.approvalRequested).to.equal(true);
expect(response.data.requiresApproval).to.equal(true);
expect(response.message).to.equal(t('taskApprovalHasBeenRequested'));
});
@@ -161,6 +161,23 @@ describe('POST /user/class/cast/:spellId', () => {
});
});
it('Issue #12361: returns an error if stealth has already been cast', async () => {
await user.update({
'stats.class': 'rogue',
'stats.lvl': 15,
'stats.mp': 400,
'stats.buffs.stealth': 1,
});
await user.sync();
await expect(user.post('/user/class/cast/stealth'))
.to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('spellAlreadyCast'),
});
expect(user.stats.mp).to.equal(400);
});
it('returns an error if targeted party member doesn\'t exist', async () => {
const { groupLeader } = await createAndPopulateGroup({
groupDetails: { type: 'party', privacy: 'private' },
@@ -4,6 +4,8 @@ import {
requester,
resetHabiticaDB,
} from '../../../../helpers/api-integration/v3';
import * as worldState from '../../../../../website/server/libs/worldState';
import common from '../../../../../website/common';
describe('GET /world-state', () => {
before(async () => {
@@ -39,4 +41,41 @@ describe('GET /world-state', () => {
expect(res).to.have.nested.property('npcImageSuffix');
expect(res.npcImageSuffix).to.be.a('string');
});
context('no current event', () => {
beforeEach(async () => {
sinon.stub(worldState, 'getCurrentEvent').returns(null);
});
afterEach(() => {
worldState.getCurrentEvent.restore();
});
it('returns null for the current event when there is none active', async () => {
const res = await requester().get('/world-state');
expect(res.currentEvent).to.be.null;
});
});
context('no current event', () => {
const evt = {
...common.content.events.fall2020,
event: 'fall2020',
};
beforeEach(async () => {
sinon.stub(worldState, 'getCurrentEvent').returns(evt);
});
afterEach(() => {
worldState.getCurrentEvent.restore();
});
it('returns the current event when there is an active one', async () => {
const res = await requester().get('/world-state');
expect(res.currentEvent).to.eql(evt);
});
});
});
@@ -0,0 +1,583 @@
import { v4 as generateUUID } from 'uuid';
import {
generateUser,
sleep,
translate as t,
server,
} from '../../../helpers/api-integration/v4';
describe('POST /tasks/bulk-score', () => {
let user;
beforeEach(async () => {
user = await generateUser({
'stats.gp': 100,
});
});
context('all', () => {
it('can use id to identify the task', async () => {
const todo = await user.post('/tasks/user', {
text: 'test todo',
type: 'todo',
alias: 'alias',
});
const res = await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }]);
expect(res).to.be.ok;
expect(res.tasks.length).to.equal(1);
expect(res.tasks[0].id).to.equal(todo._id);
expect(res.tasks[0].delta).to.be.greaterThan(0);
});
it('can use a alias in place of the id', async () => {
const todo = await user.post('/tasks/user', {
text: 'test todo',
type: 'todo',
alias: 'alias',
});
const res = await user.post('/tasks/bulk-score', [{ id: todo.alias, direction: 'up' }]);
expect(res).to.be.ok;
expect(res.tasks.length).to.equal(1);
expect(res.tasks[0].id).to.equal(todo._id);
expect(res.tasks[0].delta).to.be.greaterThan(0);
});
it('sends task scored webhooks', async () => {
const uuid = generateUUID();
await server.start();
await user.post('/user/webhook', {
url: `http://localhost:${server.port}/webhooks/${uuid}`,
type: 'taskActivity',
enabled: true,
options: {
created: false,
scored: true,
},
});
const task = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
await user.post('/tasks/bulk-score', [{ id: task.id, direction: 'up' }]);
await sleep();
await server.close();
const body = server.getWebhookData(uuid);
expect(body.user).to.have.all.keys('_id', '_tmp', 'stats');
expect(body.user.stats).to.have.all.keys('hp', 'mp', 'exp', 'gp', 'lvl', 'class', 'points', 'str', 'con', 'int', 'per', 'buffs', 'training', 'maxHealth', 'maxMP', 'toNextLevel');
expect(body.task.id).to.eql(task.id);
expect(body.direction).to.eql('up');
expect(body.delta).to.be.greaterThan(0);
});
context('sending user activity webhooks', () => {
before(async () => {
await server.start();
});
after(async () => {
await server.close();
});
it('sends user activity webhook when the user levels up', async () => {
const uuid = generateUUID();
await user.post('/user/webhook', {
url: `http://localhost:${server.port}/webhooks/${uuid}`,
type: 'userActivity',
enabled: true,
options: {
leveledUp: true,
},
});
const initialLvl = user.stats.lvl;
await user.update({
'stats.exp': 3000,
});
const task = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
await user.post('/tasks/bulk-score', [{ id: task.id, direction: 'up' }]);
await user.sync();
await sleep();
const body = server.getWebhookData(uuid);
expect(body.type).to.eql('leveledUp');
expect(body.initialLvl).to.eql(initialLvl);
expect(body.finalLvl).to.eql(user.stats.lvl);
});
});
it('fails the entire op if one task scoring fails', async () => {
const todo = await user.post('/tasks/user', {
text: 'test todo',
type: 'todo',
});
const habit = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
await expect(user.post('/tasks/bulk-score', [
{ id: todo.id, direction: 'down' },
{ id: habit.id, direction: 'down' },
])).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('sessionOutdated'),
});
const updatedHabit = await user.get(`/tasks/${habit._id}`);
expect(updatedHabit.history.length).to.equal(0);
expect(updatedHabit.value).to.equal(0);
const updatedTodo = await user.get(`/tasks/${todo._id}`);
expect(updatedTodo.value).to.equal(0);
});
it('sends _tmp for each task', async () => {
const habit1 = await user.post('/tasks/user', {
text: 'test habit 1',
type: 'habit',
});
const habit2 = await user.post('/tasks/user', {
text: 'test habit 2',
type: 'habit',
});
await user.update({
'party.quest.key': 'gryphon',
});
const res = await user.post('/tasks/bulk-score', [
{ id: habit1._id, direction: 'up' },
{ id: habit2._id, direction: 'up' },
]);
await user.sync();
expect(res.tasks[0]._tmp.quest.progressDelta).to.be.greaterThan(0);
expect(res.tasks[1]._tmp.quest.progressDelta).to.be.greaterThan(0);
expect(user.party.quest.progress.up).to
.eql(res.tasks[0]._tmp.quest.progressDelta + res.tasks[1]._tmp.quest.progressDelta);
});
});
context('todos', () => {
let todo;
beforeEach(async () => {
todo = await user.post('/tasks/user', {
text: 'test todo',
type: 'todo',
});
});
it('completes todo when direction is up', async () => {
await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }]);
const task = await user.get(`/tasks/${todo._id}`);
expect(task.completed).to.equal(true);
expect(task.dateCompleted).to.be.a('string'); // date gets converted to a string as json doesn't have a Date type
});
it('moves completed todos out of user.tasksOrder.todos', async () => {
const getUser = await user.get('/user');
expect(getUser.tasksOrder.todos.indexOf(todo._id)).to.not.equal(-1);
await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }]);
const updatedTask = await user.get(`/tasks/${todo._id}`);
expect(updatedTask.completed).to.equal(true);
const updatedUser = await user.get('/user');
expect(updatedUser.tasksOrder.todos.indexOf(todo._id)).to.equal(-1);
});
it('moves un-completed todos back into user.tasksOrder.todos', async () => {
const getUser = await user.get('/user');
expect(getUser.tasksOrder.todos.indexOf(todo._id)).to.not.equal(-1);
await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }]);
await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'down' }]);
const updatedTask = await user.get(`/tasks/${todo._id}`);
expect(updatedTask.completed).to.equal(false);
const updatedUser = await user.get('/user');
const l = updatedUser.tasksOrder.todos.length;
expect(updatedUser.tasksOrder.todos.indexOf(todo._id)).not.to.equal(-1);
// Check that it was pushed at the bottom
expect(updatedUser.tasksOrder.todos.indexOf(todo._id)).to.equal(l - 1);
});
it('uncompletes todo when direction is down', async () => {
await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }, { id: todo.id, direction: 'down' }]);
const updatedTask = await user.get(`/tasks/${todo._id}`);
expect(updatedTask.completed).to.equal(false);
expect(updatedTask.dateCompleted).to.be.a('undefined');
});
it('doesn\'t let a todo be uncompleted twice', async () => {
await expect(user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'down' }])).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('sessionOutdated'),
});
});
context('user stats when direction is up', () => {
let updatedUser; let res;
beforeEach(async () => {
res = await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }]);
updatedUser = await user.get('/user');
});
it('increases user\'s mp', () => {
expect(updatedUser.stats.mp).to.be.greaterThan(user.stats.mp);
expect(res.mp).to.equal(updatedUser.stats.mp);
});
it('increases user\'s exp', () => {
expect(updatedUser.stats.exp).to.be.greaterThan(user.stats.exp);
expect(res.exp).to.equal(updatedUser.stats.exp);
});
it('increases user\'s gold', () => {
expect(updatedUser.stats.gp).to.be.greaterThan(user.stats.gp);
expect(res.gp).to.equal(updatedUser.stats.gp);
});
});
context('user stats when direction is down', () => {
let updatedUser; let initialUser; let res;
beforeEach(async () => {
await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'up' }]);
initialUser = await user.get('/user');
res = await user.post('/tasks/bulk-score', [{ id: todo.id, direction: 'down' }]);
updatedUser = await user.get('/user');
});
it('decreases user\'s mp', () => {
expect(updatedUser.stats.mp).to.be.lessThan(initialUser.stats.mp);
});
it('decreases user\'s exp', () => {
expect(updatedUser.stats.exp).to.be.lessThan(initialUser.stats.exp);
expect(res.exp).to.equal(updatedUser.stats.exp);
});
it('decreases user\'s gold', () => {
expect(updatedUser.stats.gp).to.be.lessThan(initialUser.stats.gp);
expect(res.gp).to.equal(updatedUser.stats.gp);
});
});
});
context('dailys', () => {
let daily;
beforeEach(async () => {
daily = await user.post('/tasks/user', {
text: 'test daily',
type: 'daily',
});
});
it('completes daily when direction is up', async () => {
await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'up' }]);
const task = await user.get(`/tasks/${daily._id}`);
expect(task.completed).to.equal(true);
});
it('uncompletes daily when direction is down', async () => {
await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'up' }, { id: daily.id, direction: 'down' }]);
const task = await user.get(`/tasks/${daily._id}`);
expect(task.completed).to.equal(false);
});
it('computes isDue', async () => {
await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'up' }]);
const task = await user.get(`/tasks/${daily._id}`);
expect(task.isDue).to.equal(true);
});
it('computes nextDue', async () => {
await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'up' }]);
const task = await user.get(`/tasks/${daily._id}`);
expect(task.nextDue.length).to.eql(6);
});
context('user stats when direction is up', () => {
let updatedUser; let res;
beforeEach(async () => {
res = await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'up' }]);
updatedUser = await user.get('/user');
});
it('increases user\'s mp', () => {
expect(updatedUser.stats.mp).to.be.greaterThan(user.stats.mp);
expect(res.mp).to.equal(updatedUser.stats.mp);
});
it('increases user\'s exp', () => {
expect(updatedUser.stats.exp).to.be.greaterThan(user.stats.exp);
expect(res.exp).to.equal(updatedUser.stats.exp);
});
it('increases user\'s gold', () => {
expect(updatedUser.stats.gp).to.be.greaterThan(user.stats.gp);
expect(res.gp).to.equal(updatedUser.stats.gp);
});
});
context('user stats when direction is down', () => {
let updatedUser; let initialUser; let res;
beforeEach(async () => {
await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'up' }]);
initialUser = await user.get('/user');
res = await user.post('/tasks/bulk-score', [{ id: daily.id, direction: 'down' }]);
updatedUser = await user.get('/user');
});
it('decreases user\'s mp', () => {
expect(updatedUser.stats.mp).to.be.lessThan(initialUser.stats.mp);
expect(res.mp).to.equal(updatedUser.stats.mp);
});
it('decreases user\'s exp', () => {
expect(updatedUser.stats.exp).to.be.lessThan(initialUser.stats.exp);
expect(res.exp).to.equal(updatedUser.stats.exp);
});
it('decreases user\'s gold', () => {
expect(updatedUser.stats.gp).to.be.lessThan(initialUser.stats.gp);
expect(res.gp).to.equal(updatedUser.stats.gp);
});
});
});
context('habits', () => {
let habit; let minusHabit; let plusHabit; let
neitherHabit; // eslint-disable-line no-unused-vars
beforeEach(async () => {
habit = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
minusHabit = await user.post('/tasks/user', {
text: 'test min habit',
type: 'habit',
up: false,
});
plusHabit = await user.post('/tasks/user', {
text: 'test plus habit',
type: 'habit',
down: false,
});
neitherHabit = await user.post('/tasks/user', {
text: 'test neither habit',
type: 'habit',
up: false,
down: false,
});
});
it('increases user\'s mp when direction is up', async () => {
const res = await user.post('/tasks/bulk-score', [{ id: habit.id, direction: 'up' }, {
id: plusHabit.id,
direction: 'up',
}]);
const updatedUser = await user.get('/user');
expect(updatedUser.stats.mp).to.be.greaterThan(user.stats.mp);
expect(res.mp).to.equal(updatedUser.stats.mp);
});
it('decreases user\'s mp when direction is down', async () => {
const res = await user.post('/tasks/bulk-score', [{
id: habit.id,
direction: 'down',
}, {
id: minusHabit.id,
direction: 'down',
}]);
const updatedUser = await user.get('/user');
expect(updatedUser.stats.mp).to.be.lessThan(user.stats.mp);
expect(res.mp).to.equal(updatedUser.stats.mp);
});
it('increases user\'s exp when direction is up', async () => {
const res = await user.post('/tasks/bulk-score', [{
id: habit.id,
direction: 'up',
}, {
id: plusHabit.id,
direction: 'up',
}]);
const updatedUser = await user.get('/user');
expect(updatedUser.stats.exp).to.be.greaterThan(user.stats.exp);
expect(res.exp).to.equal(updatedUser.stats.exp);
});
it('increases user\'s gold when direction is up', async () => {
const res = await user.post('/tasks/bulk-score', [{
id: habit.id,
direction: 'up',
}, {
id: plusHabit.id,
direction: 'up',
}]);
const updatedUser = await user.get('/user');
expect(updatedUser.stats.gp).to.be.greaterThan(user.stats.gp);
expect(res.gp).to.equal(updatedUser.stats.gp);
});
it('records only one history entry per day', async () => {
const initialHistoryLength = habit.history.length;
await user.post('/tasks/bulk-score', [{
id: habit.id,
direction: 'up',
}, {
id: habit.id,
direction: 'up',
}, {
id: habit.id,
direction: 'down',
}, {
id: habit.id,
direction: 'up',
}]);
const updatedTask = await user.get(`/tasks/${habit._id}`);
expect(updatedTask.history.length).to.eql(initialHistoryLength + 1);
const lastHistoryEntry = updatedTask.history[updatedTask.history.length - 1];
expect(lastHistoryEntry.scoredUp).to.equal(3);
expect(lastHistoryEntry.scoredDown).to.equal(1);
});
});
context('mixed', () => {
let habit; let daily; let todo;
beforeEach(async () => {
habit = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
daily = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
todo = await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
});
it('scores habits, dailies, todos', async () => {
const res = await user.post('/tasks/bulk-score', [
{ id: habit.id, direction: 'down' },
{ id: daily.id, direction: 'up' },
{ id: todo.id, direction: 'up' },
]);
expect(res.tasks[0].id).to.eql(habit.id);
expect(res.tasks[0].delta).to.be.below(0);
expect(res.tasks[0]._tmp).to.exist;
expect(res.tasks[1].id).to.eql(daily.id);
expect(res.tasks[1].delta).to.be.greaterThan(0);
expect(res.tasks[1]._tmp).to.exist;
expect(res.tasks[2].id).to.eql(todo.id);
expect(res.tasks[2].delta).to.be.greaterThan(0);
expect(res.tasks[2]._tmp).to.exist;
const updatedHabit = await user.get(`/tasks/${habit._id}`);
const updatedDaily = await user.get(`/tasks/${daily._id}`);
const updatedTodo = await user.get(`/tasks/${todo._id}`);
expect(habit.value).to.be.greaterThan(updatedHabit.value);
expect(updatedHabit.counterDown).to.equal(1);
expect(updatedDaily.value).to.be.greaterThan(daily.value);
expect(updatedTodo.value).to.be.greaterThan(todo.value);
});
});
context('reward', () => {
it('correctly handles rewards', async () => {
const reward = await user.post('/tasks/user', {
text: 'test reward',
type: 'reward',
value: 5,
});
const res = await user.post('/tasks/bulk-score', [{ id: reward.id, direction: 'up' }]);
const updatedUser = await user.get('/user');
// purchases reward
expect(user.stats.gp).to.equal(updatedUser.stats.gp + 5);
expect(res.gp).to.equal(updatedUser.stats.gp);
// does not change user\'s mp
expect(user.stats.mp).to.equal(updatedUser.stats.mp);
expect(res.mp).to.equal(updatedUser.stats.mp);
// does not change user\'s exp
expect(user.stats.exp).to.equal(updatedUser.stats.exp);
expect(res.exp).to.equal(updatedUser.stats.exp);
});
it('fails if the user does not have enough gold', async () => {
const reward = await user.post('/tasks/user', {
text: 'test reward',
type: 'reward',
value: 500,
});
await expect(user.post('/tasks/bulk-score', [{ id: reward.id, direction: 'up' }])).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('messageNotEnoughGold'),
});
const updatedUser = await user.get('/user');
// does not purchase reward
expect(user.stats.gp).to.equal(updatedUser.stats.gp);
});
});
});
+20 -1
View File
@@ -4,6 +4,7 @@ import {
import spells from '../../../website/common/script/content/spells';
import {
NotAuthorized,
BadRequest,
} from '../../../website/common/script/libs/errors';
import i18n from '../../../website/common/script/i18n';
@@ -25,7 +26,7 @@ describe('shared.ops.spells', () => {
const spell = spells.healer.heal;
try {
spell.cast(user);
spell.cast(user, null, { language: 'en' });
} catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageHealthAlreadyMax'));
@@ -35,4 +36,22 @@ describe('shared.ops.spells', () => {
done();
}
});
it('Issue #12361: returns an error if chilling frost has already been cast', done => {
user.stats.class = 'wizard';
user.stats.lvl = 15;
user.stats.mp = 400;
user.stats.buffs.streaks = true;
const spell = spells.wizard.frost;
try {
spell.cast(user, null, { language: 'en' });
} catch (err) {
expect(err).to.be.an.instanceof(BadRequest);
expect(err.message).to.equal(i18n.t('spellAlreadyCast'));
expect(user.stats.mp).to.eql(400);
done();
}
});
});
+1 -2
View File
@@ -2,7 +2,6 @@
import { configure } from '@storybook/vue';
import './margin.css';
import '../../src/assets/scss/index.scss';
import '../../src/assets/scss/spacing.scss';
import '../../src/assets/css/sprites.css';
import '../../src/assets/css/sprites/spritesmith-main-0.css';
@@ -37,7 +36,7 @@ import BootstrapVue from 'bootstrap-vue';
import StoreModule from '@/libs/store';
// couldn't inject the languages easily,
// so just a "$t()" string to show that this will be translated
// so just a "$t()" string to show that this will be translated
Vue.prototype.$t = function translateString (...args) {
return `$t(${JSON.stringify(args)})`;
};
+2014 -879
View File
File diff suppressed because it is too large Load Diff
+21 -21
View File
@@ -16,50 +16,50 @@
"@storybook/addon-actions": "^5.3.19",
"@storybook/addon-knobs": "^5.3.19",
"@storybook/addon-links": "^5.3.19",
"@storybook/addon-notes": "^5.3.19",
"@storybook/addon-notes": "^5.3.21",
"@storybook/vue": "^5.3.19",
"@vue/cli-plugin-babel": "^4.4.6",
"@vue/cli-plugin-eslint": "^4.4.6",
"@vue/cli-plugin-router": "^4.4.6",
"@vue/cli-plugin-unit-mocha": "^4.4.6",
"@vue/cli-service": "^4.4.6",
"@vue/cli-plugin-babel": "^4.5.6",
"@vue/cli-plugin-eslint": "^4.5.6",
"@vue/cli-plugin-router": "^4.5.6",
"@vue/cli-plugin-unit-mocha": "^4.5.6",
"@vue/cli-service": "^4.5.6",
"@vue/test-utils": "1.0.0-beta.29",
"amplitude-js": "^7.1.0",
"amplitude-js": "^7.1.1",
"axios": "^0.19.2",
"axios-progress-bar": "^1.2.0",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.5.0",
"bootstrap-vue": "^2.15.0",
"bootstrap": "^4.5.2",
"bootstrap-vue": "^2.17.3",
"chai": "^4.1.2",
"core-js": "^3.6.5",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.3.0",
"eslint-plugin-vue": "^6.2.2",
"habitica-markdown": "^2.0.2",
"habitica-markdown": "^3.0.0",
"hellojs": "^1.18.4",
"inspectpack": "^4.5.2",
"intro.js": "^2.9.3",
"jquery": "^3.5.1",
"lodash": "^4.17.19",
"moment": "^2.27.0",
"lodash": "^4.17.20",
"moment": "^2.28.0",
"nconf": "^0.10.0",
"sass": "^1.26.10",
"sass": "^1.26.11",
"sass-loader": "^8.0.2",
"smartbanner.js": "^1.16.0",
"svg-inline-loader": "^0.8.2",
"svg-url-loader": "^6.0.0",
"svgo": "^1.3.2",
"svgo-loader": "^2.2.1",
"uuid": "^8.2.0",
"validator": "^13.1.1",
"vue": "^2.6.11",
"uuid": "^8.3.0",
"validator": "^13.1.17",
"vue": "^2.6.12",
"vue-cli-plugin-storybook": "^0.6.1",
"vue-mugen-scroll": "^0.2.6",
"vue-router": "^3.3.4",
"vue-template-compiler": "^2.6.11",
"vuedraggable": "^2.24.0",
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
"webpack": "^4.44.0"
"vue-router": "^3.4.3",
"vue-template-compiler": "^2.6.12",
"vuedraggable": "^2.24.1",
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#153d339e4dbebb73733658aeda1d5b7fcc55b0a0",
"webpack": "^4.44.2"
}
}
+6 -214
View File
@@ -26,7 +26,6 @@
id="app"
:class="{
'casting-spell': castingSpell,
'resting': showRestingBanner
}"
>
<!-- <banned-account-modal /> -->
@@ -38,31 +37,8 @@
<router-view v-if="!isUserLoggedIn || isStaticPage" />
<template v-else>
<template v-if="isUserLoaded">
<div
v-show="showRestingBanner"
ref="restingBanner"
class="resting-banner"
>
<span class="content">
<span class="label d-inline d-sm-none">{{ $t('innCheckOutBannerShort') }}</span>
<span class="label d-none d-sm-inline">{{ $t('innCheckOutBanner') }}</span>
<span class="separator">|</span>
<span
class="resume"
@click="resumeDamage()"
>{{ $t('resumeDamage') }}</span>
</span>
<div
class="closepadding"
@click="hideBanner()"
>
<span
class="svg-icon inline icon-10"
aria-hidden="true"
v-html="icons.close"
></span>
</div>
</div>
<damage-paused-banner />
<gems-promo-banner />
<notifications-display />
<app-menu />
<div
@@ -99,27 +75,17 @@
<style lang='scss' scoped>
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/variables.scss';
#app {
display: flex;
flex-direction: column;
overflow-x: hidden;
&.resting {
--banner-resting-height: #{$restingToolbarHeight};
}
&.giftingBanner {
--banner-gifting-height: 2.5rem;
}
}
#loading-screen-inapp {
#melior {
margin: 0 auto;
width: 70.9px;
margin-bottom: 1em;
}
.row {
@@ -144,15 +110,6 @@
cursor: crosshair;
}
.closepadding {
margin: 11px 24px;
display: inline-block;
position: relative;
right: 0;
top: 0;
cursor: pointer;
}
.container-fluid {
flex: 1 0 auto;
}
@@ -173,56 +130,11 @@
margin-top: .5em;
margin-bottom: .5em;
}
.resting-banner {
width: 100%;
height: $restingToolbarHeight;
background-color: $blue-10;
top: 0;
z-index: 1300;
display: flex;
.content {
line-height: 1.71;
text-align: center;
color: $white;
padding: 8px 38px 8px 8px;
margin: auto;
}
@media only screen and (max-width: 768px) {
.content {
font-size: 12px;
line-height: 1.4;
}
}
.separator {
color: $blue-100;
margin: 0px 15px;
}
.resume {
font-weight: bold;
cursor: pointer;
white-space:nowrap;
}
}
</style>
<style lang='scss'>
@import '~@/assets/scss/colors.scss';
.closepadding span svg path {
stroke: #FFF;
opacity: 0.48;
}
/* @TODO: The modal-open class is not being removed. Let's try this for now */
.modal {
overflow-y: scroll !important;
}
.modal-backdrop {
opacity: .9 !important;
background-color: $purple-100 !important;
@@ -240,6 +152,8 @@ import { loadProgressBar } from 'axios-progress-bar';
import AppMenu from './components/header/menu';
import AppHeader from './components/header/index';
import DamagePausedBanner from './components/header/banners/damagePaused';
import GemsPromoBanner from './components/header/banners/gemsPromo';
import AppFooter from './components/appFooter';
import notificationsDisplay from './components/notifications';
import snackbars from './components/snackbars/notifications';
@@ -261,8 +175,6 @@ import {
removeLocalSetting,
} from '@/libs/userlocalManager';
import svgClose from '@/assets/svg/close.svg';
const COMMUNITY_MANAGER_EMAIL = process.env.EMAILS_COMMUNITY_MANAGER_EMAIL; // eslint-disable-line
export default {
@@ -271,6 +183,8 @@ export default {
AppMenu,
AppHeader,
AppFooter,
DamagePausedBanner,
GemsPromoBanner,
notificationsDisplay,
snackbars,
BuyModal,
@@ -283,9 +197,6 @@ export default {
mixins: [notifications, spellsMixin],
data () {
return {
icons: Object.freeze({
close: svgClose,
}),
selectedItemToBuy: null,
selectedSpellToBuy: null,
@@ -305,9 +216,6 @@ export default {
castingSpell () {
return this.$store.state.spellOptions.castingSpell;
},
showRestingBanner () {
return !this.bannerHidden && this.user && this.user.preferences.sleep;
},
noMargin () {
return ['privateMessages'].includes(this.$route.name);
},
@@ -518,13 +426,9 @@ export default {
} else {
this.hideLoadingScreen();
}
this.initializeModalStack();
},
beforeDestroy () {
this.$root.$off('playSound');
this.$root.$off('bv::modal::hidden');
this.$root.$off('bv::show::modal');
this.$root.$off('buyModal::showItem');
this.$root.$off('selectMembersModal::showItem');
},
@@ -554,112 +458,6 @@ export default {
this.$store.dispatch('auth:logout', { redirectToLogin: true });
return true;
},
initializeModalStack () {
// Manage modals
this.$root.$on('bv::show::modal', (modalId, data = {}) => {
if (data.fromRoot) return;
const { modalStack } = this.$store.state;
this.trackGemPurchase(modalId, data);
// Add new modal to the stack
const prev = modalStack[modalStack.length - 1];
const prevId = prev ? prev.modalId : undefined;
modalStack.push({ modalId, prev: prevId });
});
this.$root.$on('bv::modal::hidden', bvEvent => {
let modalId = bvEvent.target && bvEvent.target.id;
// sometimes the target isn't passed to the hidden event, fallback is the vueTarget
if (!modalId) {
modalId = bvEvent.vueTarget && bvEvent.vueTarget.id;
}
if (!modalId) {
return;
}
const { modalStack } = this.$store.state;
const modalOnTop = modalStack[modalStack.length - 1];
// Check for invalid modal. Event systems can send multiples
if (!this.validStack(modalStack)) return;
// If we are moving forward
if (modalOnTop && modalOnTop.prev === modalId) return;
// Remove modal from stack
this.$store.state.modalStack.pop();
// Get previous modal
const modalBefore = modalOnTop ? modalOnTop.prev : undefined;
if (modalBefore) this.$root.$emit('bv::show::modal', modalBefore, { fromRoot: true });
});
// Dismiss modal aggressively. Pass a modal ID to remove a modal instance from the stack
// (both the stack entry itself and its "prev" reference) so we don't reopen it
this.$root.$on('habitica::dismiss-modal', oldModal => {
if (!oldModal) return;
this.$root.$emit('bv::hide::modal', oldModal);
let removeIndex = this.$store.state.modalStack
.map(modal => modal.modalId)
.indexOf(oldModal);
if (removeIndex >= 0) {
this.$store.state.modalStack.splice(removeIndex, 1);
}
removeIndex = this.$store.state.modalStack
.map(modal => modal.prev)
.indexOf(oldModal);
if (removeIndex >= 0) {
delete this.$store.state.modalStack[removeIndex].prev;
}
});
},
validStack (modalStack) {
const modalsThatCanShowTwice = ['profile'];
const modalCount = {};
const prevAndCurrent = 2;
for (const current of modalStack) {
if (!modalCount[current.modalId]) modalCount[current.modalId] = 0;
modalCount[current.modalId] += 1;
if (
modalCount[current.modalId] > prevAndCurrent
&& modalsThatCanShowTwice.indexOf(current.modalId) === -1
) {
this.$store.state.modalStack = [];
return false;
}
if (!current.prev) continue; // eslint-disable-line
if (!modalCount[current.prev]) modalCount[current.prev] = 0;
modalCount[current.prev] += 1;
if (
modalCount[current.prev] > prevAndCurrent
&& modalsThatCanShowTwice.indexOf(current.prev) === -1
) {
this.$store.state.modalStack = [];
return false;
}
}
return true;
},
trackGemPurchase (modalId, data) {
// Track opening of gems modal unless it's been already tracked
// For example the gems button in the menu already tracks the event by itself
if (modalId === 'buy-gems' && data.alreadyTracked !== true) {
Analytics.track({
hitType: 'event',
eventCategory: 'button',
eventAction: 'click',
eventLabel: 'Gems > Wallet',
});
}
},
itemSelected (item) {
this.selectedItemToBuy = item;
},
@@ -705,12 +503,6 @@ export default {
hideLoadingScreen () {
this.loading = false;
},
hideBanner () {
this.bannerHidden = true;
},
resumeDamage () {
this.$store.dispatch('user:sleep');
},
},
};
</script>
+15 -4
View File
@@ -4,16 +4,27 @@
height: 219px;
}
.Pet_HatchingPotion_Dessert {
background: url("~@/assets/images/animated/Pet_HatchingPotion_Dessert.gif") no-repeat;
.quest_windup {
background: url("~@/assets/images/animated/quest_windup.gif") no-repeat;
width: 219px;
height: 219px;
}
.Pet_HatchingPotion_Dessert, .Pet_HatchingPotion_Veggie, .Pet_HatchingPotion_Windup {
width: 68px;
height: 68px;
}
.Pet_HatchingPotion_Dessert {
background: url("~@/assets/images/animated/Pet_HatchingPotion_Dessert.gif") no-repeat;
}
.Pet_HatchingPotion_Veggie {
background: url("~@/assets/images/animated/Pet_HatchingPotion_Veggie.gif") no-repeat;
width: 68px;
height: 68px;
}
.Pet_HatchingPotion_Windup {
background: url("~@/assets/images/animated/Pet_HatchingPotion_Windup.gif") no-repeat;
}
.Gems {
@@ -1,84 +1,54 @@
.promo_aquatic_amigos_bundle {
.promo_armoire_backgrounds_202009 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -622px;
background-position: 0px -452px;
width: 423px;
height: 147px;
}
.promo_armoire_backgrounds_202007 {
.promo_fall_customizations {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -812px 0px;
width: 423px;
height: 147px;
background-position: 0px -244px;
width: 336px;
height: 207px;
}
.promo_mystery_202007 {
.promo_fall_festival_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -812px -453px;
background-position: -532px 0px;
width: 360px;
height: 189px;
}
.promo_fall_festival_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -532px -190px;
width: 360px;
height: 174px;
}
.promo_mystery_202009 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -600px;
width: 282px;
height: 147px;
}
.promo_mystery_202008 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -812px -296px;
width: 294px;
height: 156px;
}
.promo_orcas {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -812px -601px;
width: 219px;
height: 147px;
}
.promo_sand_sculpture_potions {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -812px -148px;
width: 423px;
height: 147px;
}
.promo_seafoam {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -473px;
width: 425px;
height: 148px;
}
.promo_splashy_skins {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -409px -286px;
width: 375px;
height: 186px;
}
.customize-option.promo_splashy_skins {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -434px -301px;
width: 60px;
height: 60px;
}
.promo_summer_splash_2019 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -286px;
width: 408px;
height: 186px;
}
.promo_summer_splash_2020 {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -367px 0px;
width: 444px;
height: 198px;
}
.promo_take_this {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -1107px -296px;
background-position: -532px -365px;
width: 96px;
height: 69px;
}
.scene_cathb {
.promo_vampire_potions {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -770px;
width: 141px;
height: 167px;
background-position: -424px -452px;
width: 423px;
height: 147px;
}
.scene_tools {
.scene_positivity {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px 0px;
width: 366px;
height: 285px;
width: 531px;
height: 243px;
}
.scene_squall {
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -337px -244px;
width: 141px;
height: 169px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,606 @@
.weapon_special_3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1629px -1371px;
width: 90px;
height: 90px;
}
.weapon_special_aetherCrystals {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1629px -1280px;
width: 114px;
height: 90px;
}
.weapon_special_bardInstrument {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1306px -1315px;
width: 90px;
height: 90px;
}
.weapon_special_fencingFoil {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1397px -1315px;
width: 90px;
height: 90px;
}
.weapon_special_lunarScythe {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1488px -1315px;
width: 90px;
height: 90px;
}
.weapon_special_mammothRiderSpear {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -190px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_nomadsScimitar {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -281px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_pageBanner {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -372px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_roguishRainbowMessage {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -463px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_skeletonKey {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -554px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_tachi {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -645px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_taskwoodsLantern {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -736px -1466px;
width: 90px;
height: 90px;
}
.weapon_special_tridentOfCrashingTides {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -827px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_0 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -918px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1009px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1100px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1191px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_4 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1282px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_5 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1373px -1466px;
width: 90px;
height: 90px;
}
.weapon_warrior_6 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1464px -1466px;
width: 90px;
height: 90px;
}
.weapon_wizard_0 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1555px -1466px;
width: 90px;
height: 90px;
}
.weapon_wizard_1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1646px -1466px;
width: 90px;
height: 90px;
}
.weapon_wizard_2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1608px;
width: 90px;
height: 90px;
}
.weapon_wizard_3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -91px -1608px;
width: 90px;
height: 90px;
}
.weapon_wizard_4 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -182px -1608px;
width: 90px;
height: 90px;
}
.weapon_wizard_5 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -273px -1608px;
width: 90px;
height: 90px;
}
.weapon_wizard_6 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -364px -1608px;
width: 90px;
height: 90px;
}
.Pet_Currency_Gem {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1603px -1608px;
width: 68px;
height: 68px;
}
.Pet_Currency_Gem1x {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -596px;
width: 15px;
height: 13px;
}
.Pet_Currency_Gem2x {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1748px -828px;
width: 30px;
height: 26px;
}
.PixelPaw-Gold {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1748px -724px;
width: 51px;
height: 51px;
}
.PixelPaw {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1748px -776px;
width: 51px;
height: 51px;
}
.PixelPaw002 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -856px;
width: 51px;
height: 51px;
}
.avatar_floral_healer {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -906px -1315px;
width: 99px;
height: 99px;
}
.avatar_floral_rogue {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1006px -1315px;
width: 99px;
height: 99px;
}
.avatar_floral_warrior {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1106px -1315px;
width: 99px;
height: 99px;
}
.avatar_floral_wizard {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1206px -1315px;
width: 99px;
height: 99px;
}
.avatar_snowball_healer {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1629px -856px;
width: 120px;
height: 105px;
}
.avatar_snowball_rogue {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1629px -962px;
width: 120px;
height: 105px;
}
.avatar_snowball_warrior {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1629px -1068px;
width: 120px;
height: 105px;
}
.avatar_snowball_wizard {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1629px -1174px;
width: 120px;
height: 105px;
}
.empty_bottles {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -138px -1699px;
width: 64px;
height: 54px;
}
.ghost {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -455px -1608px;
width: 90px;
height: 90px;
}
.inventory_present {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1320px -1164px;
width: 68px;
height: 68px;
}
.inventory_present_01 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1720px -1371px;
width: 68px;
height: 68px;
}
.inventory_present_02 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -324px;
width: 68px;
height: 68px;
}
.inventory_present_03 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -435px;
width: 68px;
height: 68px;
}
.inventory_present_04 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -504px;
width: 68px;
height: 68px;
}
.inventory_present_05 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -573px;
width: 68px;
height: 68px;
}
.inventory_present_06 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -655px;
width: 68px;
height: 68px;
}
.inventory_present_07 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -724px;
width: 68px;
height: 68px;
}
.inventory_present_08 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -793px;
width: 68px;
height: 68px;
}
.inventory_present_09 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1100px -875px;
width: 68px;
height: 68px;
}
.inventory_present_10 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1100px -944px;
width: 68px;
height: 68px;
}
.inventory_present_11 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1100px -1013px;
width: 68px;
height: 68px;
}
.inventory_present_12 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1320px -1095px;
width: 68px;
height: 68px;
}
.inventory_special_birthday {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1320px -1233px;
width: 68px;
height: 68px;
}
.inventory_special_congrats {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -637px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_fortify {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -706px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_getwell {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -775px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_goodluck {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -844px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_greeting {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -913px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_nye {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -982px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_opaquePotion {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1051px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_seafoam {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1120px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_shinySeed {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1189px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_snowball {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1258px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_spookySparkles {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1327px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_thankyou {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1396px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_trinket {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1465px -1608px;
width: 68px;
height: 68px;
}
.inventory_special_valentine {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1534px -1608px;
width: 68px;
height: 68px;
}
.knockout {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px -1245px;
width: 120px;
height: 47px;
}
.pet_key {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1672px -1608px;
width: 68px;
height: 68px;
}
.rebirth_orb {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1699px;
width: 68px;
height: 68px;
}
.seafoam_star {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -546px -1608px;
width: 90px;
height: 90px;
}
.shop_armoire {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -69px -1699px;
width: 68px;
height: 68px;
}
.zzz {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -962px;
width: 40px;
height: 40px;
}
.zzz_light {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -908px;
width: 40px;
height: 40px;
}
.notif_inventory_present_01 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1003px;
width: 28px;
height: 28px;
}
.notif_inventory_present_02 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1032px;
width: 28px;
height: 28px;
}
.notif_inventory_present_03 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1068px;
width: 28px;
height: 28px;
}
.notif_inventory_present_04 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1097px;
width: 28px;
height: 28px;
}
.notif_inventory_present_05 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1126px;
width: 28px;
height: 28px;
}
.notif_inventory_present_06 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1174px;
width: 28px;
height: 28px;
}
.notif_inventory_present_07 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1203px;
width: 28px;
height: 28px;
}
.notif_inventory_present_08 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1750px -1232px;
width: 28px;
height: 28px;
}
.notif_inventory_present_09 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1744px -1280px;
width: 28px;
height: 28px;
}
.notif_inventory_present_10 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1773px -1280px;
width: 28px;
height: 28px;
}
.notif_inventory_present_11 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1744px -1309px;
width: 28px;
height: 28px;
}
.notif_inventory_present_12 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1773px -1309px;
width: 28px;
height: 28px;
}
.notif_inventory_special_birthday {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -449px;
width: 20px;
height: 24px;
}
.notif_inventory_special_congrats {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -524px;
width: 20px;
height: 22px;
}
.notif_inventory_special_getwell {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -547px;
width: 20px;
height: 22px;
}
.notif_inventory_special_goodluck {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -422px;
width: 20px;
height: 26px;
}
.notif_inventory_special_greeting {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -573px;
width: 20px;
height: 22px;
}
.notif_inventory_special_nye {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1779px -828px;
width: 24px;
height: 26px;
}
.notif_inventory_special_thankyou {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -474px;
width: 20px;
height: 24px;
}
.notif_inventory_special_valentine {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1780px -499px;
width: 20px;
height: 24px;
}
.npc_bailey {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1737px -1466px;
width: 60px;
height: 72px;
}
.npc_justin {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -203px;
width: 84px;
height: 120px;
}
.npc_matt {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -459px -1535px;
background-position: -710px -1315px;
width: 195px;
height: 138px;
}
@@ -12,7 +612,7 @@
}
.banner_flair_dysheartener {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1844px -856px;
background-position: -1720px -1440px;
width: 69px;
height: 18px;
}
@@ -24,7 +624,7 @@
}
.quest_alligator {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px -1079px;
background-position: -1407px -642px;
width: 201px;
height: 213px;
}
@@ -42,13 +642,13 @@
}
.quest_atom1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1325px -1315px;
background-position: 0px -1315px;
width: 250px;
height: 150px;
}
.quest_atom2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -251px -1535px;
background-position: -502px -1315px;
width: 207px;
height: 138px;
}
@@ -72,13 +672,13 @@
}
.quest_basilist {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -191px -1686px;
background-position: 0px -1466px;
width: 189px;
height: 141px;
}
.quest_beetle {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px -1293px;
background-position: -1407px -856px;
width: 204px;
height: 201px;
}
@@ -108,7 +708,7 @@
}
.quest_cow {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1844px 0px;
background-position: -1629px 0px;
width: 174px;
height: 213px;
}
@@ -120,13 +720,13 @@
}
.quest_dilatoryDistress1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px -868px;
background-position: -1407px -431px;
width: 210px;
height: 210px;
}
.quest_dilatoryDistress2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1844px -422px;
background-position: -1629px -422px;
width: 150px;
height: 150px;
}
@@ -156,13 +756,13 @@
}
.quest_egg {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1844px -214px;
background-position: -1629px -214px;
width: 165px;
height: 207px;
}
.quest_evilsanta {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1844px -724px;
background-position: -1629px -724px;
width: 118px;
height: 131px;
}
@@ -192,7 +792,7 @@
}
.quest_frog {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -880px -1315px;
background-position: -1407px 0px;
width: 221px;
height: 213px;
}
@@ -210,7 +810,7 @@
}
.quest_goldenknight2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1535px;
background-position: -251px -1315px;
width: 250px;
height: 150px;
}
@@ -240,7 +840,7 @@
}
.quest_hedgehog {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px -1100px;
background-position: -1407px -1058px;
width: 219px;
height: 186px;
}
@@ -288,7 +888,7 @@
}
.quest_mayhemMistiflying1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1844px -573px;
background-position: -1629px -573px;
width: 150px;
height: 150px;
}
@@ -312,91 +912,7 @@
}
.quest_moon1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px 0px;
width: 216px;
height: 216px;
}
.quest_moon2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px 0px;
width: 219px;
height: 219px;
}
.quest_moon3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px -220px;
width: 219px;
height: 219px;
}
.quest_moonstone1 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px -440px;
width: 219px;
height: 219px;
}
.quest_moonstone2 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px -660px;
width: 219px;
height: 219px;
}
.quest_moonstone3 {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1407px -880px;
width: 219px;
height: 219px;
}
.quest_nudibranch {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px -217px;
width: 216px;
height: 216px;
}
.quest_octopus {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1102px -1315px;
width: 222px;
height: 177px;
}
.quest_owl {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1315px;
width: 219px;
height: 219px;
}
.quest_peacock {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px -434px;
width: 216px;
height: 216px;
}
.quest_penguin {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: 0px -1686px;
width: 190px;
height: 183px;
}
.quest_pterodactyl {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -220px -1315px;
width: 219px;
height: 219px;
}
.quest_rat {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -440px -1315px;
width: 219px;
height: 219px;
}
.quest_robot {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -660px -1315px;
width: 219px;
height: 219px;
}
.quest_rock {
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
background-position: -1627px -651px;
background-position: -1407px -214px;
width: 216px;
height: 216px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Some files were not shown because too many files have changed in this diff Show More