Compare commits

..

233 Commits

Author SHA1 Message Date
SabreCat bf222351e5 4.277.4 2023-08-01 18:38:31 -05:00
SabreCat 6867aab74b fix(faq): better mobile routing, new q 2023-08-01 18:38:21 -05:00
SabreCat 38ac4c53d1 4.277.3 2023-08-01 13:44:54 -05:00
SabreCat 9b8bb99039 fix(profile): revert accidental changes 2023-08-01 13:44:49 -05:00
SabreCat f8bcc81fe6 4.277.2 2023-08-01 13:02:00 -05:00
SabreCat cc18acd69a Merge branch 'sabrecat/chat-warning' into release 2023-08-01 13:01:15 -05:00
SabreCat c5a2e5a2e0 fix(chat): fill in the blank 2023-07-31 19:25:07 -05:00
SabreCat 8f92993045 4.277.1 2023-07-31 12:10:32 -05:00
SabreCat 712205d253 Merge branch 'develop' into sabrecat/chat-warning 2023-07-31 12:07:48 -05:00
Sabe Jones ede036e94b Universal routing for migrations (#14772)
* refactor(notifs): universal routing for migrations

* fix(lint): remove whitespace

* chore(content): update migration for new scheme

* fix(migration): account for cake

* chore(images): update sprite CSS

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-07-31 12:07:46 -05:00
SabreCat 67c16c137b Merge branch 'release' into develop 2023-07-31 12:07:26 -05:00
CuriousMagpie 652dfa6ecc feat(content): upgrade profile page 2023-07-26 16:33:05 -04:00
SabreCat 5c4aa664b5 4.277.0 2023-07-25 14:17:04 -05:00
SabreCat 184a9df775 Merge branch 'develop' into release 2023-07-25 14:16:54 -05:00
Phillip Thelen 754d46f1f3 Optimise looking for party request (#14773)
* Reset looking for party state if a user joins a party

* filter out users that already received an invite in query

* fix(lfp): add back in-party filter
Temporary until migration to clear seeking flag from users in party

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-07-25 14:16:03 -05:00
Sabe Jones 683649ff1a Don't collapse different spell targets in party chat (#14775)
* fix(spells): don't collapse different targets

* fix(lint): indentation

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-07-25 14:15:12 -05:00
Natalie L 08ac059a7f feat(content): add August 2023 subscriber items (#14784)
* feat(content): add June subscriber items

* feat(content): add August subscriber items
2023-07-25 14:14:28 -05:00
Weblate 7c9b0f207c Merge branch 'origin/develop' into Weblate. 2023-07-25 21:11:35 +02:00
Weblate f193b8de2c Translated using Weblate (English (en@lolcat))
Currently translated at 5.5% (44 of 798 strings)

Translated using Weblate (English (en@lolcat))

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (112 of 112 strings)

Translated using Weblate (Russian)

Currently translated at 98.8% (2837 of 2871 strings)

Translated using Weblate (Ukrainian)

Currently translated at 90.5% (692 of 764 strings)

Translated using Weblate (Dutch)

Currently translated at 91.3% (729 of 798 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Japanese)

Currently translated at 99.6% (2862 of 2871 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (798 of 798 strings)

Translated using Weblate (English (en@lolcat))

Currently translated at 3.6% (29 of 798 strings)

Translated using Weblate (Indonesian)

Currently translated at 76.6% (2197 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 85.2% (651 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 99.4% (187 of 188 strings)

Translated using Weblate (Japanese)

Currently translated at 99.2% (792 of 798 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 76.2% (2187 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 29.0% (833 of 2871 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (2830 of 2871 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (2830 of 2871 strings)

Translated using Weblate (Ukrainian)

Currently translated at 84.4% (645 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 84.2% (644 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 75.9% (2177 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (188 of 188 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (798 of 798 strings)

Translated using Weblate (French)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (French)

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Ukrainian)

Currently translated at 83.6% (639 of 764 strings)

Translated using Weblate (French)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (French)

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 75.5% (2167 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 83.6% (639 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 75.2% (2157 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 82.9% (634 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 29.0% (833 of 2871 strings)

Translated using Weblate (Indonesian)

Currently translated at 74.8% (2147 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 81.4% (622 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Ukrainian)

Currently translated at 78.1% (597 of 764 strings)

Translated using Weblate (Croatian)

Currently translated at 77.0% (94 of 122 strings)

Translated using Weblate (Indonesian)

Currently translated at 74.5% (2137 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 77.7% (594 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 74.1% (2127 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 77.4% (592 of 764 strings)

Translated using Weblate (Vietnamese)

Currently translated at 97.3% (148 of 152 strings)

Translated using Weblate (Dutch)

Currently translated at 86.6% (2484 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 73.8% (2117 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.8% (587 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Ukrainian)

Currently translated at 29.0% (833 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.7% (586 of 764 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 73.4% (2107 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.7% (586 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 72.7% (2087 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 72.2% (2071 of 2867 strings)

Translated using Weblate (Spanish)

Currently translated at 51.8% (55 of 106 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 46.2% (49 of 106 strings)

Translated using Weblate (Spanish (Latin America))

Currently translated at 74.5% (91 of 122 strings)

Translated using Weblate (Indonesian)

Currently translated at 71.9% (2064 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.7% (586 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 71.6% (2054 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 97.1% (103 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.7% (586 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.6% (822 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.6% (822 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (222 of 222 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.5% (819 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.5% (819 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.5% (819 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.5% (819 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 71.2% (2043 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 81.1% (86 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 81.1% (86 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 81.1% (86 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.7% (586 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 76.7% (586 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.0% (573 of 764 strings)

Translated using Weblate (Dutch)

Currently translated at 86.6% (2483 of 2867 strings)

Translated using Weblate (Dutch)

Currently translated at 99.1% (121 of 122 strings)

Translated using Weblate (Indonesian)

Currently translated at 70.9% (2033 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 70.5% (2024 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 70.1% (2011 of 2867 strings)

Translated using Weblate (Russian)

Currently translated at 99.7% (789 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 69.2% (1984 of 2867 strings)

Translated using Weblate (Korean)

Currently translated at 73.8% (584 of 791 strings)

Translated using Weblate (Croatian)

Currently translated at 75.4% (92 of 122 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (222 of 222 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.8% (1974 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.6% (1968 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.6% (1968 of 2867 strings)

Translated using Weblate (Latvian)

Currently translated at 23.5% (25 of 106 strings)

Translated using Weblate (Latvian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.3% (1959 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.3% (1959 of 2867 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.3% (1959 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.3% (1959 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 68.0% (1950 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 67.1% (1926 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 67.1% (1924 of 2867 strings)

Translated using Weblate (Dutch)

Currently translated at 68.8% (73 of 106 strings)

Translated using Weblate (Latvian)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Japanese)

Currently translated at 97.6% (409 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.9% (1919 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Latvian)

Currently translated at 70.3% (107 of 152 strings)

Translated using Weblate (Japanese)

Currently translated at 99.7% (2860 of 2867 strings)

Translated using Weblate (Japanese)

Currently translated at 99.5% (221 of 222 strings)

Translated using Weblate (Japanese)

Currently translated at 99.7% (2860 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Turkish)

Currently translated at 62.9% (498 of 791 strings)

Translated using Weblate (Belarusian)

Currently translated at 23.0% (35 of 152 strings)

Translated using Weblate (Polish)

Currently translated at 98.6% (150 of 152 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Turkish)

Currently translated at 96.8% (91 of 94 strings)

Translated using Weblate (Ukrainian)

Currently translated at 28.4% (816 of 2867 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Belarusian)

Currently translated at 17.1% (26 of 152 strings)

Translated using Weblate (Belarusian)

Currently translated at 11.1% (17 of 152 strings)

Translated using Weblate (Dutch)

Currently translated at 86.5% (2480 of 2867 strings)

Translated using Weblate (Dutch)

Currently translated at 65.0% (69 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Korean)

Currently translated at 73.1% (579 of 791 strings)

Translated using Weblate (Croatian)

Currently translated at 91.7% (167 of 182 strings)

Translated using Weblate (Croatian)

Currently translated at 53.6% (119 of 222 strings)

Translated using Weblate (Croatian)

Currently translated at 80.7% (617 of 764 strings)

Translated using Weblate (Croatian)

Currently translated at 67.0% (63 of 94 strings)

Translated using Weblate (Croatian)

Currently translated at 88.9% (194 of 218 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Croatian)

Currently translated at 81.9% (308 of 376 strings)

Translated using Weblate (Croatian)

Currently translated at 63.1% (77 of 122 strings)

Translated using Weblate (Croatian)

Currently translated at 71.8% (158 of 220 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 79.2% (84 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.0% (573 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 97.7% (217 of 222 strings)

Translated using Weblate (Dutch)

Currently translated at 95.4% (212 of 222 strings)

Translated using Weblate (Turkish)

Currently translated at 75.8% (318 of 419 strings)

Translated using Weblate (Ukrainian)

Currently translated at 73.5% (78 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 51.8% (55 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 91.7% (726 of 791 strings)

Translated using Weblate (Turkish)

Currently translated at 59.2% (469 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Portuguese)

Currently translated at 61.9% (1775 of 2867 strings)

Translated using Weblate (Polish)

Currently translated at 96.0% (146 of 152 strings)

Translated using Weblate (Polish)

Currently translated at 61.1% (1754 of 2867 strings)

Translated using Weblate (Polish)

Currently translated at 75.9% (580 of 764 strings)

Translated using Weblate (Polish)

Currently translated at 96.4% (763 of 791 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Ukrainian)

Currently translated at 64.1% (68 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 64.1% (68 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 75.0% (573 of 764 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.8% (414 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Polish)

Currently translated at 96.3% (762 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Croatian)

Currently translated at 79.5% (105 of 132 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Croatian)

Currently translated at 72.0% (302 of 419 strings)

Translated using Weblate (Croatian)

Currently translated at 61.4% (75 of 122 strings)

Translated using Weblate (Polish)

Currently translated at 95.5% (756 of 791 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Croatian)

Currently translated at 27.3% (29 of 106 strings)

Translated using Weblate (Croatian)

Currently translated at 78.7% (104 of 132 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Croatian)

Currently translated at 61.4% (75 of 122 strings)

Translated using Weblate (Croatian)

Currently translated at 71.3% (157 of 220 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Japanese)

Currently translated at 98.9% (756 of 764 strings)

Translated using Weblate (Turkish)

Currently translated at 72.9% (89 of 122 strings)

Translated using Weblate (Polish)

Currently translated at 95.3% (754 of 791 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2867 of 2867 strings)

Translated using Weblate (Turkish)

Currently translated at 46.2% (49 of 106 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (15 of 15 strings)

Translated using Weblate (Turkish)

Currently translated at 73.5% (562 of 764 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (47 of 47 strings)

Translated using Weblate (Polish)

Currently translated at 95.1% (753 of 791 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (222 of 222 strings)

Translated using Weblate (Turkish)

Currently translated at 71.3% (87 of 122 strings)

Translated using Weblate (Arabic)

Currently translated at 23.5% (25 of 106 strings)

Translated using Weblate (Arabic)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (222 of 222 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (112 of 112 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Turkish)

Currently translated at 48.0% (132 of 275 strings)

Translated using Weblate (Turkish)

Currently translated at 75.6% (317 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Turkish)

Currently translated at 41.5% (44 of 106 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (54 of 54 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (98 of 98 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Turkish)

Currently translated at 93.6% (44 of 47 strings)

Translated using Weblate (Turkish)

Currently translated at 93.4% (142 of 152 strings)

Translated using Weblate (Korean)

Currently translated at 72.9% (577 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Translated using Weblate (Polish)

Currently translated at 94.5% (748 of 791 strings)

Translated using Weblate (Polish)

Currently translated at 94.5% (748 of 791 strings)

Translated using Weblate (Polish)

Currently translated at 94.5% (748 of 791 strings)

Translated using Weblate (Polish)

Currently translated at 94.0% (744 of 791 strings)

Translated using Weblate (Russian)

Currently translated at 97.9% (2808 of 2867 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2867 of 2867 strings)

Translated using Weblate (Russian)

Currently translated at 99.6% (761 of 764 strings)

Translated using Weblate (Polish)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Russian)

Currently translated at 99.6% (788 of 791 strings)

Translated using Weblate (Polish)

Currently translated at 94.0% (744 of 791 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (222 of 222 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Russian)

Currently translated at 98.1% (218 of 222 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Russian)

Currently translated at 98.8% (414 of 419 strings)

Translated using Weblate (Russian)

Currently translated at 99.4% (760 of 764 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (222 of 222 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.5% (1909 of 2867 strings)

Co-authored-by: Adrián Chaves Fernández <adrian@chaves.io>
Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Anony Moly <supersoda1233@gmail.com>
Co-authored-by: Bengisu Diri <bengisudiri@hotmail.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: Bogdan Derdziak <bagtirr@gmail.com>
Co-authored-by: BryanLim <youmakemysonlooklikeelonmusk@gmail.com>
Co-authored-by: Chucklestone <utkuulassimsek@gmail.com>
Co-authored-by: Deni Zubin <deni.zubin@gmail.com>
Co-authored-by: Elsyana Z <frostaxter@gmail.com>
Co-authored-by: Evan Kletniek <rutakl2010@gmail.com>
Co-authored-by: Falzart <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: Full Name <supersoda1233@gmail.com>
Co-authored-by: Hinano_Miyako <sinemgokcebircan@gmail.com>
Co-authored-by: John Collins <munmedia9865@gmail.com>
Co-authored-by: João Pedro <lolpeople.mega@gmail.com>
Co-authored-by: Julian H <julian.henin29@gmail.com>
Co-authored-by: Justcallme rye <Blizzardscf32@gmail.com>
Co-authored-by: Kiryla <ansgar@tut.by>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Marek Tomek <markowalzky2@gmail.com>
Co-authored-by: Maria G <magu18ab@hotmail.com>
Co-authored-by: Melina Rake <melinarake@gmail.com>
Co-authored-by: Nazar Paruna <nazarparuna@gmail.com>
Co-authored-by: Nodaysoff <convoron@yandex.ru>
Co-authored-by: Oleksandr Shtonda <oleksandrshtonda@gmail.com>
Co-authored-by: Omar Bertolla <scaram@icloud.com>
Co-authored-by: Rayane Benamre <thegamercore3@gmail.com>
Co-authored-by: Simon Hagman <dragonzimpan@gmail.com>
Co-authored-by: Svetlana <shkulepo@rambler.ru>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Tetiana <merekka13@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yuliia Pastukh <yuliya.bratash666@gmail.com>
Co-authored-by: billypat <kreideraine@gmail.com>
Co-authored-by: inesa <inessami200@gmail.com>
Co-authored-by: minhtan <minhtan11221122@gmail.com>
Co-authored-by: sam de wit <samedewit@gmail.com>
Co-authored-by: Ілля <bo4onok5@gmail.com>
Co-authored-by: Катерина <kate0712ann@gmail.com>
Co-authored-by: 왕효준 <gywns0417@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ar/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/be/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/it/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/lv/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/sv/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/vi/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/en@lolcat/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/id/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/challenge/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/character/id/
Translate-URL: https://translate.habitica.com/projects/habitica/character/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/character/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/content/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/content/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/content/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/en@lolcat/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/death/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/death/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/defaulttasks/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ar/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/es_419/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/lv/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/front/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/front/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/id/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/lv/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pl/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/id/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/tr/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/uk/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Challenge
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Death
Translation: Habitica/Defaulttasks
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2023-07-25 21:11:22 +02:00
Natalie L 812e2132d9 fix(config.json.example) (#14787)
* fix(string): questVice1Notes html changed to a mobile-device friendly format

* fix(strings): updated limited.json with "dateEnd" & "monthYYYY" months & put in chronological order

* fix(string): remove extra word from headSpecialSummer2022WarriorNotes

* fix(string): corrected armorSpecialSummer2022MageNotes

* fix: remove duplicated string and adjust upgrade button style

* fix(style): set border radii to 8px on upgrading-group id

* fix(payments): remove duplicate entry from another modal

* chore(fix): restore string inadvertently removed during a refactor

* chore(fix): comma dangle

* chore(typo): who knew, that Y was actually important...

* chore(typo): fix text in questBewilderNotes

* chore(string): clarify polar pets requirements

* couple small changes to the footer as pointed out by users

* chore(fix): correct name of Fabulous Party Hat

* fix(typo): correct February backgrounds release date to 2023, not 2022

* fix(trusted_domains): removed https:// from the beginning of localhost

* fix(config): correct habitica url format too

---------

Co-authored-by: SabreCat <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2023-07-25 14:10:47 -05:00
SabreCat 8558dcc3a8 4.276.2 2023-07-18 10:34:02 -05:00
SabreCat f8a8b61726 Merge branch 'phillip/chat-skill-merge' into release 2023-07-18 10:33:55 -05:00
SabreCat 067a1de49e fix(lint): newlines, console 2023-07-18 10:20:58 -05:00
SabreCat 65ef3bfeca fix(migration): casing 2023-07-18 10:04:56 -05:00
SabreCat af04657856 feat(event): Summer Splash Orcas 2023-07-18 09:12:28 -05:00
SabreCat 6089b02746 4.276.1 2023-07-13 14:45:37 -05:00
SabreCat f3f69b1871 fix(lfp): white background for seeker card 2023-07-13 14:45:31 -05:00
SabreCat 259f7ef588 fix(chat): add default to switch block 2023-07-11 18:25:59 -05:00
SabreCat 106a0c9ed8 fix(chat): collapse repetitive spells for real now 2023-07-11 17:01:17 -05:00
SabreCat 578083dde6 chore(faq): sync up 2023-07-11 14:15:27 -05:00
Phillip Thelen 74ba5c0b27 bring merging to MVP 2023-07-11 15:10:50 +02:00
SabreCat bb54a6532d fix(chat): correct bad length check 2023-07-10 15:37:46 -05:00
SabreCat 3c36c59bb3 Merge branch 'develop' into phillip/chat-skill-merge 2023-07-10 15:12:12 -05:00
SabreCat 2308961de6 fix(lint): address fatal errors 2023-07-10 15:11:22 -05:00
Phillip Thelen 2d71a902f1 Merge skill casting messages together 2023-07-10 16:27:31 +02:00
SabreCat 1deb903186 Merge branch 'release' into sabrecat/chat-warning 2023-07-06 15:23:46 -05:00
SabreCat 8c00b91cc6 feat(faq): update sunset faq 2023-07-06 15:23:42 -05:00
SabreCat 70d59be39b 4.276.0 2023-07-04 13:23:29 -05:00
Natalie L c562c93158 feat(content): add July 2023 backgrounds and Enchanted Armoire (#14733)
* feat(content): add June subscriber items

* feat(content): add July backgrounds and Enchanted Armoire Items

* Update backgrounds.json

---------

Co-authored-by: SabreCat <sabe@habitica.com>
Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2023-07-04 13:23:06 -05:00
SabreCat 7a430889a8 Merge branch 'develop' into sabrecat/chat-warning 2023-06-29 14:53:15 -05:00
SabreCat 519da49886 4.275.0 2023-06-29 14:51:37 -05:00
Weblate 79d50cb3e0 Merge branch 'origin/develop' into Weblate. 2023-06-29 21:36:09 +02:00
Weblate c588c2b2ff Translated using Weblate (Korean)
Currently translated at 97.8% (46 of 47 strings)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Deleted translation using Weblate (Acehnese)

Added translation using Weblate (Acehnese)

Translated using Weblate (Scots)

Currently translated at 90.9% (111 of 122 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2863 of 2863 strings)

Translated using Weblate (Portuguese)

Currently translated at 62.0% (1777 of 2863 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (218 of 218 strings)

Added translation using Weblate (Acehnese)

Translated using Weblate (Russian)

Currently translated at 97.4% (2790 of 2863 strings)

Translated using Weblate (Russian)

Currently translated at 96.7% (2769 of 2863 strings)

Translated using Weblate (Croatian)

Currently translated at 26.4% (28 of 106 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Croatian)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Swedish)

Currently translated at 98.6% (150 of 152 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 98.3% (2817 of 2863 strings)

Translated using Weblate (Swedish)

Currently translated at 98.6% (150 of 152 strings)

Translated using Weblate (Russian)

Currently translated at 96.4% (2761 of 2863 strings)

Translated using Weblate (Swedish)

Currently translated at 76.6% (321 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Malay)

Currently translated at 48.2% (54 of 112 strings)

Translated using Weblate (Korean)

Currently translated at 72.9% (577 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Galician)

Currently translated at 65.5% (501 of 764 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Malay)

Currently translated at 54.3% (430 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2863 of 2863 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Russian)

Currently translated at 99.1% (784 of 791 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Korean)

Currently translated at 72.3% (572 of 791 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Japanese)

Currently translated at 97.4% (268 of 275 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (137 of 137 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (275 of 275 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.8% (2859 of 2863 strings)

Translated using Weblate (German)

Currently translated at 63.2% (67 of 106 strings)

Translated using Weblate (German)

Currently translated at 81.1% (99 of 122 strings)

Translated using Weblate (Galician)

Currently translated at 98.5% (135 of 137 strings)

Translated using Weblate (German)

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Galician)

Currently translated at 98.5% (271 of 275 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (German)

Currently translated at 99.4% (787 of 791 strings)

Translated using Weblate (German)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Korean)

Currently translated at 99.7% (375 of 376 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.5% (2851 of 2863 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1892 of 2863 strings)

Translated using Weblate (Russian)

Currently translated at 95.0% (116 of 122 strings)

Translated using Weblate (Russian)

Currently translated at 98.1% (217 of 221 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.3% (2844 of 2863 strings)

Translated using Weblate (Russian)

Currently translated at 90.9% (111 of 122 strings)

Translated using Weblate (Russian)

Currently translated at 98.8% (782 of 791 strings)

Translated using Weblate (Malay)

Currently translated at 53.2% (421 of 791 strings)

Translated using Weblate (Ukrainian)

Currently translated at 99.2% (131 of 132 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.5% (413 of 419 strings)

Translated using Weblate (Hebrew)

Currently translated at 63.7% (267 of 419 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.3% (2843 of 2863 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1891 of 2863 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Ukrainian)

Currently translated at 55.6% (59 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 49.0% (52 of 106 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Dutch)

Currently translated at 89.7% (710 of 791 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Malay)

Currently translated at 52.3% (414 of 791 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.0% (1891 of 2863 strings)

Translated using Weblate (Hebrew)

Currently translated at 56.5% (237 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.7% (1891 of 2831 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Galician)

Currently translated at 65.5% (501 of 764 strings)

Translated using Weblate (Russian)

Currently translated at 98.1% (217 of 221 strings)

Translated using Weblate (Hebrew)

Currently translated at 60.1% (133 of 221 strings)

Translated using Weblate (Hebrew)

Currently translated at 50.3% (211 of 419 strings)

Translated using Weblate (Russian)

Currently translated at 99.5% (217 of 218 strings)

Translated using Weblate (Russian)

Currently translated at 98.3% (179 of 182 strings)

Translated using Weblate (Russian)

Currently translated at 98.3% (179 of 182 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Galician)

Currently translated at 65.5% (501 of 764 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (Malay)

Currently translated at 52.0% (412 of 791 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 66.4% (1881 of 2831 strings)

Translated using Weblate (Hebrew)

Currently translated at 41.0% (325 of 791 strings)

Translated using Weblate (Ukrainian)

Currently translated at 98.6% (150 of 152 strings)

Translated using Weblate (Hebrew)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Malay)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Dutch)

Currently translated at 97.3% (148 of 152 strings)

Translated using Weblate (Malay)

Currently translated at 82.0% (87 of 106 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 65.2% (1848 of 2831 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (135 of 135 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (112 of 112 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (Indonesian)

Currently translated at 92.6% (388 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 64.9% (1838 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 91.1% (382 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 64.2% (1818 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 98.6% (754 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (French)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Portuguese)

Currently translated at 38.6% (41 of 106 strings)

Translated using Weblate (Malay)

Currently translated at 74.5% (79 of 106 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 99.0% (219 of 221 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 91.1% (382 of 419 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (2835 of 2835 strings)

Translated using Weblate (Indonesian)

Currently translated at 63.5% (1798 of 2831 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (764 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 97.3% (744 of 764 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 89.4% (375 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 62.8% (1778 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 93.4% (714 of 764 strings)

Co-authored-by: Adrián Chaves Fernández <adrian@chaves.io>
Co-authored-by: Ana Beatriz <anabeatriz.augusto06@yahoo.com>
Co-authored-by: Andreway <watermelontvandreway2@gmail.com>
Co-authored-by: Antje Schubert <antje.schubert96@web.de>
Co-authored-by: Arthur Ouzlaner <panther1984@gmail.com>
Co-authored-by: Benoit Hetru <me+hbtc@gahanka.net>
Co-authored-by: BryanLim <youmakemysonlooklikeelonmusk@gmail.com>
Co-authored-by: Deni Zubin <deni.zubin@gmail.com>
Co-authored-by: Falzart <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: Hanafi <naflizo@gmail.com>
Co-authored-by: Jan Willem Middag <jwmiddag@gmail.com>
Co-authored-by: Jinnel <1210678078@qq.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Natalie Luhrs <eilatan@gmail.com>
Co-authored-by: Phillip Thelen <phillip@habitica.com>
Co-authored-by: Rostislav <rostislav.zem@gmail.com>
Co-authored-by: Sara Olson <sara@habitica.com>
Co-authored-by: Simon Hagman <dragonzimpan@gmail.com>
Co-authored-by: Svetlana <shkulepo@rambler.ru>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Thiago Braga <thibraga06@gmail.com>
Co-authored-by: Timur Niyazov <timmy568@gmail.com>
Co-authored-by: Vladyslav Yavnyk <yavnyjvladislav@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: lilia petervari <lilipetervari@gmail.com>
Co-authored-by: Ілля <bo4onok5@gmail.com>
Co-authored-by: Естай <akseleu@yahoo.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/de/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/he/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/sv/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/de/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/he/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/character/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/de/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/sco/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/contrib/ko/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/de/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/nl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/front/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/id/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/es/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/he/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/id/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/sv/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/id/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/uk/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/id/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/he/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/pt_BR/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/hr/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/id/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/pt_BR/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Contrib
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2023-06-29 21:35:54 +02:00
Natalie L 77a490283c feat(content): add July 2023 subscriber items (#14732)
* feat(content): add June subscriber items

* feat(content): add July subscriber items
2023-06-29 14:35:05 -05:00
dependabot[bot] e49d26eacd build(deps): bump stripe from 12.8.0 to 12.9.0 (#14699)
Bumps [stripe](https://github.com/stripe/stripe-node) from 12.8.0 to 12.9.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v12.8.0...v12.9.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-21 13:50:08 -04:00
dependabot[bot] 7b0fd57eb9 build(deps): bump @babel/core from 7.22.1 to 7.22.5 (#14700)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.22.1 to 7.22.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.22.5/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-21 13:49:41 -04:00
dependabot[bot] 7171334e31 build(deps): bump @babel/register from 7.21.0 to 7.22.5 (#14702)
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.21.0 to 7.22.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.22.5/packages/babel-register)

---
updated-dependencies:
- dependency-name: "@babel/register"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-21 13:49:16 -04:00
dependabot[bot] a3235214b2 build(deps): bump core-js from 3.30.2 to 3.31.0 in /website/client (#14704)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.30.2 to 3.31.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.31.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-21 13:48:45 -04:00
dependabot[bot] fca234c45a build(deps-dev): bump sinon from 15.1.0 to 15.1.2 (#14713)
Bumps [sinon](https://github.com/sinonjs/sinon) from 15.1.0 to 15.1.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.1.0...v15.1.2)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-21 13:47:21 -04:00
dependabot[bot] 7519023f06 build(deps): bump sass from 1.62.1 to 1.63.4 in /website/client (#14719)
Bumps [sass](https://github.com/sass/dart-sass) from 1.62.1 to 1.63.4.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.62.1...1.63.4)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-21 13:46:01 -04:00
SabreCat df84d7c7b1 Merge branch 'release' into develop 2023-06-19 16:36:39 -05:00
SabreCat e837ebec49 4.274.0 2023-06-19 16:36:13 -05:00
Natalie L c7ed693e18 feat(gala): Add 2023 Summer Splash Gala Items (#14712)
* feat(content): add June subscriber items

* feat(gala): add images

* feat(gala): add code

* feat(gala): text strings

* feat(gala): testing and final updates

* feat(gala): fixed a couple of typos

* fix(event): proofread strings and dates
Also replace empty descriptions for Rogue and Healer

* fix(event): NO EGG

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-06-19 16:36:05 -05:00
Ash e72a25ad02 Fixes #14438: a11y: add semantic roles to habit and todo controls (#14467)
* a11y: add aria roles to habit control

* a11y: add role to todo checkboxes

* a11y: add aria-labels to score buttons
Helps with screen readers

* add i18n to aria-labels
2023-06-19 17:00:16 -04:00
SabreCat 2c12d5ee29 4.273.3 2023-06-13 14:57:37 -05:00
Weblate c3f0abadd7 Merge branch 'origin/develop' into Weblate. 2023-06-13 21:54:27 +02:00
Phillip Thelen adf0a2efca Fix perkMonthCount not being editable/saving (#14711)
Co-authored-by: SabreCat <sabe@habitica.com>
2023-06-13 14:51:58 -05:00
SabreCat e4523c09dc Merge branch 'release' into develop 2023-06-13 14:40:41 -05:00
SabreCat 91d98b86e1 fix(lint): whitespace 2023-06-13 14:40:26 -05:00
Weblate 779fb8bce5 Translated using Weblate (Indonesian)
Currently translated at 62.0% (1758 of 2831 strings)

Translated using Weblate (Malay)

Currently translated at 70.7% (75 of 106 strings)

Translated using Weblate (Japanese)

Currently translated at 98.9% (756 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 61.9% (1753 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 87.8% (368 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 61.8% (1752 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 92.1% (704 of 764 strings)

Translated using Weblate (Malay)

Currently translated at 61.3% (65 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 85.9% (360 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 61.4% (1740 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 89.5% (684 of 764 strings)

Translated using Weblate (Malay)

Currently translated at 59.4% (63 of 106 strings)

Translated using Weblate (Norwegian Bokmål)

Currently translated at 92.6% (202 of 218 strings)

Translated using Weblate (Indonesian)

Currently translated at 84.7% (355 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 60.6% (1718 of 2831 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.9% (641 of 764 strings)

Translated using Weblate (Irish)

Currently translated at 75.0% (114 of 152 strings)

Translated using Weblate (Irish)

Currently translated at 75.0% (114 of 152 strings)

Translated using Weblate (Russian)

Currently translated at 95.4% (211 of 221 strings)

Translated using Weblate (Russian)

Currently translated at 99.4% (760 of 764 strings)

Translated using Weblate (English (Pirate))

Currently translated at 82.2% (125 of 152 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (Russian)

Currently translated at 96.3% (213 of 221 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Russian)

Currently translated at 95.5% (259 of 271 strings)

Translated using Weblate (Indonesian)

Currently translated at 60.6% (1718 of 2831 strings)

Translated using Weblate (Russian)

Currently translated at 89.6% (95 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Malay)

Currently translated at 52.8% (56 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (791 of 791 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Malay)

Currently translated at 98.6% (150 of 152 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (413 of 419 strings)

Translated using Weblate (Serbian)

Currently translated at 23.5% (25 of 106 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (784 of 784 strings)

Translated using Weblate (Malay)

Currently translated at 52.8% (56 of 106 strings)

Translated using Weblate (Malay)

Currently translated at 85.1% (115 of 135 strings)

Translated using Weblate (Indonesian)

Currently translated at 81.6% (342 of 419 strings)

Co-authored-by: Abiel Meza <mezaabiel@gmail.com>
Co-authored-by: Anastasia Wysocka <legitemail.uwu420@gmail.com>
Co-authored-by: Edward McGibney <edwardmcgibney95@gmail.com>
Co-authored-by: Falzart <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: Hanafi <naflizo@gmail.com>
Co-authored-by: Lauren C <laurenc7834@gmail.com>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Miroslav <entferner@yandex.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: i3beograd <milica.the@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/en@pirate/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/es/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ga/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/id/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/sr/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/id/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/es/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/nb_NO/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/id/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/id/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ru/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/ms/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Faq
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Limited
Translation: Habitica/Npc
Translation: Habitica/Questscontent
Translation: Habitica/Settings
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2023-06-13 09:29:03 +02:00
SabreCat f0fc83ed85 Merge branch 'release' into develop 2023-06-12 15:02:18 -05:00
SabreCat 30d2108c78 4.273.2 2023-06-12 15:02:06 -05:00
Natalie L ab68e8a5fe feat(content): add June pet quest bundle (#14694)
* feat(content): add June subscriber items

* feat(content): add June pet quest bundle

* fix(bundle): correct timing and visual issues

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-06-12 15:01:34 -05:00
dependabot[bot] 31e9100ba2 build(deps): bump @babel/preset-env from 7.21.5 to 7.22.5 (#14695)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.21.5 to 7.22.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.22.5/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-08 15:45:46 -04:00
dependabot[bot] 0070f366bb build(deps): bump xml2js from 0.5.0 to 0.6.0 (#14673)
Bumps [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) from 0.5.0 to 0.6.0.
- [Commits](https://github.com/Leonidas-from-XIV/node-xml2js/compare/0.5.0...0.6.0)

---
updated-dependencies:
- dependency-name: xml2js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-08 15:38:28 -04:00
dependabot[bot] 2be6865a5c build(deps): bump winston from 3.8.2 to 3.9.0 (#14676)
Bumps [winston](https://github.com/winstonjs/winston) from 3.8.2 to 3.9.0.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/master/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/v3.8.2...v3.9.0)

---
updated-dependencies:
- dependency-name: winston
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-08 15:37:58 -04:00
dependabot[bot] db85768e9d build(deps): bump stripe from 12.6.0 to 12.8.0 (#14690)
Bumps [stripe](https://github.com/stripe/stripe-node) from 12.6.0 to 12.8.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v12.6.0...v12.8.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-08 15:34:03 -04:00
dependabot[bot] 3d40413882 build(deps): bump fast-xml-parser and is-svg (#14693)
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and [is-svg](https://github.com/sindresorhus/is-svg). These dependencies needed to be updated together.

Updates `fast-xml-parser` from 3.19.0 to 4.2.4
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/commits)

Updates `is-svg` from 4.3.1 to 4.4.0
- [Release notes](https://github.com/sindresorhus/is-svg/releases)
- [Commits](https://github.com/sindresorhus/is-svg/compare/v4.3.1...v4.4.0)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-type: indirect
- dependency-name: is-svg
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-08 15:32:28 -04:00
dependabot[bot] cc88e75950 build(deps): bump @babel/core from 7.21.8 to 7.22.1 (#14670)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.21.8 to 7.22.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.22.1/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-08 15:31:54 -04:00
SabreCat ff860b04fc Merge remote-tracking branch 'private/natalie/antisocial' into sabrecat/chat-warning 2023-06-07 15:02:11 -05:00
SabreCat 45dedbbdaa fix(banners): correct dismiss/show behavior 2023-06-07 15:00:51 -05:00
CuriousMagpie b6359ad032 WIP(faq): pixelate Daniel's border 2023-06-07 13:33:58 -04:00
SabreCat a5ae3e5877 4.273.1 2023-06-06 16:33:33 -05:00
SabreCat 60ed9d2944 Merge branch 'develop' into release 2023-06-06 16:33:27 -05:00
Natalie L 91fc4235aa fix(string): remove "due" string (#14683) 2023-06-06 16:33:01 -05:00
SabreCat 42e8dd1361 fix(vue): correct bad popovers breaking Chrome 2023-06-06 16:30:37 -05:00
CuriousMagpie 658a02bfc3 WIP(faq): add Daniel to sidebar 2023-06-06 15:26:31 -04:00
SabreCat 0185a1fbd6 Merge branch 'develop' into sabrecat/chat-warning 2023-06-06 09:22:23 -05:00
SabreCat 0a4bbbf173 4.273.0 2023-06-06 09:21:35 -05:00
SabreCat df22f5f7bf Merge branch 'develop' into release 2023-06-06 09:21:25 -05:00
Natalie L bb28bb5969 feat(content): add June backgrounds and Enchanted Armoire items (#14684)
* feat(content): add June subscriber items

* feat(content): add July backgrounds and Enchanted Armoire items

* feat(fix): correct sizing for aquarium background

* fix(strings): JSON formatting

* fix(sprites): add missing broad variant

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-06-06 09:17:22 -05:00
SabreCat 3b6c39dc9b fix(banner): restore close X on pause 2023-06-06 08:57:10 -05:00
Weblate e4e8e0ff60 Translated using Weblate (Malay)
Currently translated at 51.8% (55 of 106 strings)

Translated using Weblate (Japanese)

Currently translated at 96.8% (214 of 221 strings)

Translated using Weblate (Malay)

Currently translated at 50.9% (54 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 81.1% (340 of 419 strings)

Translated using Weblate (Portuguese)

Currently translated at 60.1% (163 of 271 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (135 of 135 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (56 of 56 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (271 of 271 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (61 of 61 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (Belarusian)

Currently translated at 71.3% (157 of 220 strings)

Translated using Weblate (Japanese)

Currently translated at 95.9% (212 of 221 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (112 of 112 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Japanese)

Currently translated at 97.4% (264 of 271 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (271 of 271 strings)

Translated using Weblate (Japanese)

Currently translated at 96.4% (404 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 80.6% (338 of 419 strings)

Translated using Weblate (Japanese)

Currently translated at 99.8% (2828 of 2831 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (784 of 784 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (Japanese)

Currently translated at 94.1% (208 of 221 strings)

Translated using Weblate (Indonesian)

Currently translated at 91.8% (249 of 271 strings)

Translated using Weblate (Indonesian)

Currently translated at 79.4% (333 of 419 strings)

Translated using Weblate (Indonesian)

Currently translated at 60.6% (1718 of 2831 strings)

Translated using Weblate (Japanese)

Currently translated at 78.3% (83 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Japanese)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (French)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Galician)

Currently translated at 60.2% (1706 of 2831 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (271 of 271 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Indonesian)

Currently translated at 78.5% (213 of 271 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 54.7% (58 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (152 of 152 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (419 of 419 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Galician)

Currently translated at 100.0% (220 of 220 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (221 of 221 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (94 of 94 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (13 of 13 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (112 of 112 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (132 of 132 strings)

Translated using Weblate (Indonesian)

Currently translated at 63.4% (172 of 271 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (8 of 8 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (218 of 218 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (182 of 182 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (106 of 106 strings)

Translated using Weblate (Indonesian)

Currently translated at 83.3% (637 of 764 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (122 of 122 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (376 of 376 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (186 of 186 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (784 of 784 strings)

Translated using Weblate (Indonesian)

Currently translated at 100.0% (152 of 152 strings)

Co-authored-by: Adrián Chaves Fernández <adrian@chaves.io>
Co-authored-by: Falzart <muh_fauzi_ramadhan@yahoo.co.id>
Co-authored-by: Hanafi <naflizo@gmail.com>
Co-authored-by: Hanna Aniskevich <northernwind@tut.by>
Co-authored-by: LiziKnight <liziknight0316@outlook.com>
Co-authored-by: Sara Olson <sara@habitica.com>
Co-authored-by: TOMA Mitsuru <toma0001@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yatharth <megacutiemauandtuchchu@gmail.com>
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/fr/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/id/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/achievements/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/id/
Translate-URL: https://translate.habitica.com/projects/habitica/backgrounds/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/character/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/character/id/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/id/
Translate-URL: https://translate.habitica.com/projects/habitica/communityguidelines/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/content/id/
Translate-URL: https://translate.habitica.com/projects/habitica/content/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/id/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/ms/
Translate-URL: https://translate.habitica.com/projects/habitica/faq/zh_Hans/
Translate-URL: https://translate.habitica.com/projects/habitica/front/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/front/id/
Translate-URL: https://translate.habitica.com/projects/habitica/front/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/id/
Translate-URL: https://translate.habitica.com/projects/habitica/gear/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/generic/id/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/id/
Translate-URL: https://translate.habitica.com/projects/habitica/groups/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/inventory/id/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/id/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/limited/pt/
Translate-URL: https://translate.habitica.com/projects/habitica/messages/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/id/
Translate-URL: https://translate.habitica.com/projects/habitica/npc/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/overview/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/id/
Translate-URL: https://translate.habitica.com/projects/habitica/pets/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/quests/id/
Translate-URL: https://translate.habitica.com/projects/habitica/questscontent/id/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/rebirth/id/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/be/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/settings/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/spells/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/gl/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/id/
Translate-URL: https://translate.habitica.com/projects/habitica/subscriber/ja/
Translate-URL: https://translate.habitica.com/projects/habitica/tasks/gl/
Translation: Habitica/Achievements
Translation: Habitica/Backgrounds
Translation: Habitica/Character
Translation: Habitica/Communityguidelines
Translation: Habitica/Content
Translation: Habitica/Faq
Translation: Habitica/Front
Translation: Habitica/Gear
Translation: Habitica/Generic
Translation: Habitica/Groups
Translation: Habitica/Inventory
Translation: Habitica/Limited
Translation: Habitica/Messages
Translation: Habitica/Npc
Translation: Habitica/Overview
Translation: Habitica/Pets
Translation: Habitica/Quests
Translation: Habitica/Questscontent
Translation: Habitica/Rebirth
Translation: Habitica/Settings
Translation: Habitica/Spells
Translation: Habitica/Subscriber
Translation: Habitica/Tasks
2023-06-06 05:00:15 +02:00
SabreCat 84e5c00be1 WIP(announcement): correct layout and close X 2023-06-05 16:16:19 -05:00
SabreCat 187029f44f Merge remote-tracking branch 'private/natalie/antisocial' into sabrecat/chat-warning 2023-06-05 15:54:41 -05:00
CuriousMagpie efbc7d1460 WIP(faq): sidebar formatting 2023-06-05 16:53:48 -04:00
SabreCat 36f84d083e Merge remote-tracking branch 'private/natalie/antisocial' into sabrecat/chat-warning 2023-06-05 15:32:46 -05:00
CuriousMagpie 2154ba5451 WIP(fix): change URL 2023-06-05 12:33:40 -04:00
SabreCat cf0e45c68c Merge branch 'natalie/antisocial' into sabrecat/chat-warning 2023-06-02 16:14:20 -05:00
CuriousMagpie 93d9038765 WIP(faq): initial formatting of main text, started on sidebar 2023-06-02 17:00:13 -04:00
SabreCat 302eabb30f WIP(faq): hack background to white 2023-06-02 14:58:16 -05:00
SabreCat 09695f637e Merge branch 'release' into natalie/antisocial 2023-06-02 14:12:52 -05:00
SabreCat e9a15fcb83 fix(strings): JSON formatting 2023-06-02 13:55:04 -05:00
CuriousMagpie 97c8138340 feat(content): minor updates 2023-06-02 11:31:43 -04:00
SabreCat a65b0d1f4d fix(banner): make dismissable 2023-06-01 16:33:11 -05:00
SabreCat c0cf647873 fix(banner): only show when relevant 2023-05-31 16:55:21 -05:00
CuriousMagpie d20e976176 feat(style): css work 2023-05-31 14:27:52 -04:00
SabreCat 739016ba01 WIP(chat): add warning banner 2023-05-30 16:25:29 -05:00
SabreCat a5602eec8d 4.272.0 2023-05-30 15:28:16 -05:00
Natalie L 867eed176e feat(content): add June subscriber items (#14669)
Co-authored-by: SabreCat <sabe@habitica.com>
2023-05-30 15:26:16 -05:00
SabreCat ba883ae104 chore(subproj): update habitica-images 2023-05-30 14:55:00 -05:00
SabreCat deba7b6220 feat(faq): update for mobile workflows 2023-05-30 14:50:13 -05:00
CuriousMagpie 55d6ee3f7e feat(content): add staff and tiers 2023-05-30 12:01:21 -04:00
SabreCat 69c538858b 4.271.2 2023-05-25 14:42:53 -05:00
SabreCat 17072dcc45 Merge branch 'due-dates-in-todos' into release 2023-05-25 14:42:46 -05:00
SabreCat 2448f401f2 Merge branch 'increment-component' into release 2023-05-25 14:42:42 -05:00
CuriousMagpie 9ef13dad68 feat(content): starting add styling, string updates 2023-05-25 12:25:08 -04:00
CuriousMagpie 14fa69719b feat(content): static page created and strings in place 2023-05-24 16:18:31 -04:00
SabreCat 5745e3df5f 4.271.1 2023-05-24 13:30:21 -05:00
Phillip Thelen d4a5823916 Fix one-off issue for monthly subs (#14643)
* Fix initial plan.consecutive.offset for 1 month subs

* fix initial values for group plan subs

* Make perkMonthCount editable in admin panel

* Add aditional info to admin panel

* Implement automatic fix for affected users

* fix(lint): exclusive test, code style

* fixes

* fix issue with initialization

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-05-24 13:29:42 -05:00
CuriousMagpie 929b0196a4 add strings 2023-05-24 13:24:44 -04:00
CuriousMagpie 1b91f620e1 initial commit 2023-05-23 16:01:40 -04:00
CuriousMagpie 86b15cb580 fix(style): css fix, today if-statement added 2023-05-23 15:19:26 -04:00
SabreCat 8e5b66a73e Merge branch 'release' into develop 2023-05-23 09:16:50 -05:00
SabreCat f755d4c133 4.271.0 2023-05-23 09:07:47 -05:00
SabreCat 102c71c4ca Merge remote-tracking branch 'CuriousMagpie/2023-05-pet-quest-bundle' into release 2023-05-22 15:14:18 -05:00
SabreCat a7bde80349 Squashed commit of the following:
commit 27287ac3aa
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon May 22 15:59:20 2023 -0400

    fix(typo): typos fixed

commit a4df8097cf
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon May 22 15:57:17 2023 -0400

    feat(content): add migration script

commit 23ff7845c1
Merge: d02644e21b 8ba7117fa5
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Mon May 22 15:42:32 2023 -0400

    Merge branch 'develop' into achievement-dinosaur-dynasty

commit 8ba7117fa5
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Mon May 22 12:35:07 2023 -0400

    build(deps): bump stripe from 12.5.0 to 12.6.0 (#14662)

    Bumps [stripe](https://github.com/stripe/stripe-node) from 12.5.0 to 12.6.0.
    - [Release notes](https://github.com/stripe/stripe-node/releases)
    - [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
    - [Commits](https://github.com/stripe/stripe-node/compare/v12.5.0...v12.6.0)

    ---
    updated-dependencies:
    - dependency-name: stripe
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit fe5d4a0551
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Mon May 22 12:34:28 2023 -0400

    build(deps-dev): bump sinon from 15.0.4 to 15.1.0 (#14661)

    Bumps [sinon](https://github.com/sinonjs/sinon) from 15.0.4 to 15.1.0.
    - [Release notes](https://github.com/sinonjs/sinon/releases)
    - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
    - [Commits](https://github.com/sinonjs/sinon/compare/v15.0.4...v15.1.0)

    ---
    updated-dependencies:
    - dependency-name: sinon
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit d02644e21b
Author: CuriousMagpie <eilatan@gmail.com>
Date:   Wed May 17 11:36:28 2023 -0400

    feat(content): add dinosaur dynasty achievement
2023-05-22 15:13:49 -05:00
SabreCat bedce203ee 4.270.3 2023-05-22 13:28:31 -05:00
dependabot[bot] 8ba7117fa5 build(deps): bump stripe from 12.5.0 to 12.6.0 (#14662)
Bumps [stripe](https://github.com/stripe/stripe-node) from 12.5.0 to 12.6.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v12.5.0...v12.6.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-22 12:35:07 -04:00
dependabot[bot] fe5d4a0551 build(deps-dev): bump sinon from 15.0.4 to 15.1.0 (#14661)
Bumps [sinon](https://github.com/sinonjs/sinon) from 15.0.4 to 15.1.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.0.4...v15.1.0)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-22 12:34:28 -04:00
SabreCat deebc09a79 fix(analytics): typo 2023-05-22 09:54:10 -05:00
SabreCat b63f2fa1fa fix(analytics): add missing headers to 3 events 2023-05-19 14:54:30 -05:00
CuriousMagpie 60b180681e Merge remote-tracking branch 'origin/due-dates-in-todos' into due-dates-in-todos 2023-05-17 13:30:45 -04:00
CuriousMagpie 7c1c18a329 fix(styling): update colors to be a11y-friendly and to show items due today in gray 2023-05-17 13:29:26 -04:00
CuriousMagpie 0b0cbb45f4 feat(content): add May pet quest bundle 2023-05-17 10:49:37 -04:00
SabreCat 0e03f079a7 Merge branch 'due-dates-in-todos' of https://github.com/CuriousMagpie/habitica into due-dates-in-todos 2023-05-16 14:27:56 -05:00
SabreCat a71e44b331 fix(test): remove test for old function 2023-05-16 14:27:15 -05:00
Sabe Jones 48917fd8be Merge branch 'develop' into due-dates-in-todos 2023-05-16 14:18:22 -05:00
SabreCat 2a054a25ee fix(test): include user pref needed for date 2023-05-16 14:15:34 -05:00
SabreCat d176c31382 4.270.2 2023-05-16 12:22:21 -05:00
Phillip Thelen 8150fef993 Database Access optimisations (#14544)
* Optimize database access during spell casting

* load less data when casting spells

* Begin migrating update calls to updateOne and updateMany

* Only update user objects that don’t have notification yet

* fix test

* fix spy

* Don’t unnecessarily update user when requesting invalid guild

* fix sort order for middlewares to not load user twice every request

* fix tests

* fix integration test

* fix skill usage not always deducting mp

* addtest case for blessing spell

* fix healAll

* fix lint

* Fix error for when some spells are used outside of party

* Add check to not run bulk spells in web client

* fix(tags): change const to let

---------

Co-authored-by: SabreCat <sabe@habitica.com>
2023-05-16 12:21:45 -05:00
SabreCat f0637dcf49 4.270.1 2023-05-15 16:15:22 -05:00
SabreCat 0518b90eab Merge branch 'develop' into release 2023-05-15 16:11:30 -05:00
SabreCat f968bdd3a9 fix(analytics): re-enable group chat tracking 2023-05-15 16:02:24 -05:00
negue e3a1ea6180 save task column filter (#14587)
* save task column filter

* remove old setting

* fix tests
2023-05-15 16:01:32 -05:00
Natalie L 17f6054ef0 feat(content): add May magic hatching potions (#14641) 2023-05-15 15:59:49 -05:00
dependabot[bot] 9b8f213c63 build(deps): bump jquery from 3.6.4 to 3.7.0 in /website/client (#14653)
Bumps [jquery](https://github.com/jquery/jquery) from 3.6.4 to 3.7.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.6.4...3.7.0)

---
updated-dependencies:
- dependency-name: jquery
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-15 13:46:41 -04:00
CuriousMagpie daccade2e2 disabled sell button when user tries to sell more items than they own 2023-05-15 12:03:58 -04:00
dependabot[bot] 48bb3e2886 build(deps): bump core-js from 3.30.1 to 3.30.2 in /website/client (#14635)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.30.1 to 3.30.2.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.30.2/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:47:35 -05:00
dependabot[bot] 308d557770 build(deps): bump superagent from 8.0.6 to 8.0.9 (#14473)
Bumps [superagent](https://github.com/ladjs/superagent) from 8.0.6 to 8.0.9.
- [Release notes](https://github.com/ladjs/superagent/releases)
- [Changelog](https://github.com/ladjs/superagent/blob/master/HISTORY.md)
- [Commits](https://github.com/ladjs/superagent/compare/v8.0.6...v8.0.9)

---
updated-dependencies:
- dependency-name: superagent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:35:21 -05:00
dependabot[bot] 0f4816c674 build(deps): bump intro.js from 6.0.0 to 7.0.1 in /website/client (#14558)
Bumps [intro.js](https://github.com/usablica/intro.js) from 6.0.0 to 7.0.1.
- [Release notes](https://github.com/usablica/intro.js/releases)
- [Changelog](https://github.com/usablica/intro.js/blob/master/tsconfig.release.json)
- [Commits](https://github.com/usablica/intro.js/compare/v6.0.0...v7.0.1)

---
updated-dependencies:
- dependency-name: intro.js
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:35:06 -05:00
dependabot[bot] f1b98a530d build(deps): bump jsonwebtoken from 8.5.1 to 9.0.0 (#14418)
Bumps [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) from 8.5.1 to 9.0.0.
- [Release notes](https://github.com/auth0/node-jsonwebtoken/releases)
- [Changelog](https://github.com/auth0/node-jsonwebtoken/blob/master/CHANGELOG.md)
- [Commits](https://github.com/auth0/node-jsonwebtoken/compare/v8.5.1...v9.0.0)

---
updated-dependencies:
- dependency-name: jsonwebtoken
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:29:16 -05:00
dependabot[bot] 1498eba8d4 build(deps): bump @babel/preset-env from 7.20.2 to 7.21.5 (#14616)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.20.2 to 7.21.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.21.5/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:28:41 -05:00
dependabot[bot] fc16ffbf2d build(deps): bump dompurify from 2.4.3 to 3.0.3 in /website/client (#14639)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.4.3 to 3.0.3.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/2.4.3...3.0.3)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:22:06 -05:00
dependabot[bot] 021180fa59 build(deps): bump uuid from 8.3.2 to 9.0.0 in /website/client (#14227)
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.3.2 to 9.0.0.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.3.2...v9.0.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:13:53 -05:00
dependabot[bot] 102e6a64ad chore(deps): bump sass from 1.34.0 to 1.62.1 in /website/client (#14614)
Bumps [sass](https://github.com/sass/dart-sass) from 1.34.0 to 1.62.1.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.34.0...1.62.1)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:07:36 -05:00
SabreCat 79a5c2ec5f Merge branch 'develop' into due-dates-in-todos 2023-05-12 16:06:18 -05:00
dependabot[bot] 8cd6e1654f build(deps): bump @babel/core from 7.21.4 to 7.21.8 (#14630)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.21.4 to 7.21.8.
- [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.21.8/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:05:20 -05:00
dependabot[bot] 63ea21c46d build(deps): bump stripe from 11.10.0 to 12.5.0 (#14646)
Bumps [stripe](https://github.com/stripe/stripe-node) from 11.10.0 to 12.5.0.
- [Release notes](https://github.com/stripe/stripe-node/releases)
- [Changelog](https://github.com/stripe/stripe-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/stripe/stripe-node/compare/v11.10.0...v12.5.0)

---
updated-dependencies:
- dependency-name: stripe
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-12 16:03:29 -05:00
CuriousMagpie 0a23dd5311 attempt to fix sellModal 2023-05-11 16:25:11 -04:00
SabreCat 6e3a367832 Merge branch 'release' into develop 2023-05-11 14:13:58 -05:00
SabreCat f3348aca4c 4.270.0 2023-05-09 10:29:19 -05:00
SabreCat 90e1bc9d5e Merge branch 'sabrecat/link-tweak' into release 2023-05-09 10:29:14 -05:00
Natalie L 453bf3a961 feat(content): add May Backgrounds and Enchanted Armoire items (#14628) 2023-05-09 10:26:00 -05:00
SabreCat b026daec90 fix(rya): wait for DOM finished before update 2023-05-05 16:27:19 -05:00
SabreCat 49f45d27e3 4.269.1 2023-05-04 16:08:53 -05:00
CuriousMagpie 479cfb76ef fix(to do dates): locate a string for "Due" 2023-05-04 16:40:11 -04:00
CuriousMagpie 0e0cd99ded fix(to do dates): Add the word "Due" to the HTML 2023-05-04 16:35:27 -04:00
CuriousMagpie 7e210c56b0 fix(to do dates): change formatDueDate () to show exact due dates 2023-05-04 16:29:54 -04:00
SabreCat d92a03048b fix(analytics): tweak CTA event 2023-05-04 14:20:49 -05:00
SabreCat 8183699cb7 feat(analytics): differentiate party CTA scenarios 2023-05-03 16:04:22 -05:00
SabreCat 9f9e6c4950 feat(links): skip modal for user's own tasks 2023-05-03 16:00:58 -05:00
SabreCat c77dd5f200 fix(analytics): move lfp events out of mounted 2023-05-02 16:52:50 -05:00
CuriousMagpie 06ac6ae80c fix(html): fix behavior of buyModal when gems are being purchased; typo correction 2023-05-02 13:23:31 -04:00
SabreCat 13e87b1ea0 fix(tests): linting 2023-05-02 10:11:57 -05:00
CuriousMagpie 4a32a29bea Merge branch 'develop' into increment-component 2023-05-02 11:03:46 -04:00
SabreCat 71e165433a Merge branch 'release' into develop 2023-05-02 09:53:39 -05:00
SabreCat c2515a4042 4.269.0 2023-05-02 09:51:55 -05:00
SabreCat e31bfdc22b fix(stats): allow negative EXP 2023-05-02 09:51:49 -05:00
SabreCat e9e4265545 Squashed commit of the following:
commit 00affb306655a543f5d29b3af6361e686b577a97
Author: SabreCat <sabe@habitica.com>
Date:   Tue May 2 09:47:25 2023 -0500

    fix(tests): account for invite limit changes

commit 47661117f9fd661b8bc8f63b7cc7c8d5f8fa0fd7
Author: SabreCat <sabe@habitica.com>
Date:   Mon May 1 17:39:29 2023 -0500

    fix(lfp): final polish

commit 6a1e5af1db0dd90be3ced7e223f53c9183a206f5
Merge: 728ed2ddad 9e0777bb42
Author: SabreCat <sabe@habitica.com>
Date:   Mon May 1 16:54:12 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit 728ed2ddad7f0962d28f1ab0a271e3555b19296c
Author: SabreCat <sabe@habitica.com>
Date:   Thu Apr 27 16:51:06 2023 -0500

    fix(lfp): loading layout and page visit event

commit 8a56ab329bff922e05963e3ef78fbc26ff273924
Author: SabreCat <sabe@habitica.com>
Date:   Wed Apr 26 16:54:46 2023 -0500

    fix(faq): copy and style updates

commit 6fd00d7f30150a1802e5a37edbb914ef120caf9a
Author: SabreCat <sabe@habitica.com>
Date:   Fri Apr 21 17:12:52 2023 -0500

    feat(lfp): fixes, analytics, FAQ

commit 4b5d7304ad7cfc5f72320b23456ed2898e53caac
Author: SabreCat <sabe@habitica.com>
Date:   Mon Apr 17 15:13:03 2023 -0500

    fix(lfp): smol tweaks

commit 9a5476a2558eb17a603f4aae1b5b2d35773be8b4
Author: SabreCat <sabe@habitica.com>
Date:   Thu Apr 13 16:03:33 2023 -0500

    feat(lfp): refresh button

commit aa58f5018469f38a9a9d31c3bffa26bb88a8c672
Merge: bbb03d006e c8adf20804
Author: SabreCat <sabe@habitica.com>
Date:   Tue Apr 11 17:44:56 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit bbb03d006e8b122bb7206bdc778a31de422167bb
Author: SabreCat <sabe@habitica.com>
Date:   Tue Apr 4 18:30:50 2023 -0500

    fix(lint): whitespace and const

commit 23683ad29a4cce0b0da061ad6c030982034c0a9c
Author: SabreCat <sabe@habitica.com>
Date:   Tue Apr 4 17:02:57 2023 -0500

    chore(LFP): add analytics
    also re-fix loading state

commit 4477d84f5266c87f5583368029b72153f00f0568
Author: SabreCat <sabe@habitica.com>
Date:   Mon Apr 3 16:24:26 2023 -0500

    fix(LFP): address issues with loading

commit bdc5154f24bb5e50963376c3c0c9cc73c0b05ccc
Merge: 81923eef6f 229ed46425
Author: SabreCat <sabe@habitica.com>
Date:   Mon Apr 3 15:58:12 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit 81923eef6f0c627d079475a28f9d93d8e4628934
Author: SabreCat <sabe@habitica.com>
Date:   Thu Mar 30 16:44:49 2023 -0500

    feat(LFP): release candidate

commit fe1f8939fc6b09d36cfaf0b6e5838df04e41009d
Author: SabreCat <sabe@habitica.com>
Date:   Wed Mar 29 17:35:54 2023 -0500

    WIP(LFP): fixes

commit afc361f5a9f806cbd814ad910d1274e3a6609efd
Merge: d6b5cbdebc 7ede3acd01
Author: SabreCat <sabe@habitica.com>
Date:   Wed Mar 29 16:24:39 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit d6b5cbdebc2829e9325ea57fb5deeccc128c1635
Author: SabreCat <sabe@habitica.com>
Date:   Tue Mar 28 16:13:18 2023 -0500

    WIP(LFP): change copy, add close X, fix API response

commit 4274a4625862351ef0ecf33c8a3249ca5ebec7cb
Author: SabreCat <sabe@habitica.com>
Date:   Mon Mar 27 17:07:36 2023 -0500

    fix(LFP): layout, unset when stopping

commit 95abfcfa5f13c9cce6385206947a47f85b76d11d
Merge: 4a360eedd8 53c536b525
Author: SabreCat <sabe@habitica.com>
Date:   Mon Mar 27 16:32:46 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit 4a360eedd8b9cf41d3a0fe7a4cfaa72c5bd7bd26
Author: SabreCat <sabe@habitica.com>
Date:   Thu Mar 23 16:54:49 2023 -0500

    feat(LFP): completed style and infinite scroll

commit bbc439d9d03c9631a450236eb33af66f0428fa50
Author: SabreCat <sabe@habitica.com>
Date:   Tue Mar 21 10:40:26 2023 -0500

    WIP(LFP): nicer layout, buffs fix

commit 1658688597456663477ab19da61ae1b9bc85cf2a
Merge: 664507434f 027e61a93e
Author: SabreCat <sabe@habitica.com>
Date:   Tue Mar 21 09:29:02 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit 664507434f2f76e6bf3b61cdc9e3daddb81204af
Author: SabreCat <sabe@habitica.com>
Date:   Fri Mar 17 17:13:08 2023 -0500

    WIP(LFP): API and client adjustments

commit 2f0b6f2517f9e2d634cb23ee303cfb4542e998ce
Merge: 0db1704325 a16098ccda
Author: SabreCat <sabe@habitica.com>
Date:   Fri Mar 17 16:45:13 2023 -0500

    Merge branch 'release' into sabrecat/party-seeking

commit 0db1704325c3555f0b5d9c8d1dfc44177e90c093
Author: SabreCat <sabe@habitica.com>
Date:   Mon Mar 13 14:48:10 2023 -0500

    fix(modal): scrollbar for squashed viewports

commit 733c35192e0a4e31e1bebfdd7488cfc1f7587f36
Author: SabreCat <sabe@habitica.com>
Date:   Thu Mar 9 12:51:02 2023 -0600

    WIP(party): seekers functional rough

commit d4b854410b557db26eec6e6a26b6d174c02cee3a
Merge: 7fe919825a 0b6b967753
Author: SabreCat <sabe@habitica.com>
Date:   Thu Mar 9 10:07:28 2023 -0600

    Merge branch 'release' into sabrecat/party-seeking

commit 7fe919825abfb6d518cb93b91f5997d3831bd0b5
Author: SabreCat <sabe@habitica.com>
Date:   Thu Mar 2 14:40:09 2023 -0600

    feat(party): several adjustments to seeking feature

commit c93900efcf925f7aaa4c4cb56b4451f19adfb1b3
Author: SabreCat <sabe@habitica.com>
Date:   Wed Mar 1 20:37:11 2023 -0600

    feat(party): initial Seeking API

commit 8bb784daeceb14c23992a6f3af1054a900fc26c1
Merge: e19a661a21 f327795761
Author: SabreCat <sabe@habitica.com>
Date:   Wed Mar 1 18:58:20 2023 -0600

    Merge branch 'release' into sabrecat/party-seeking

commit e19a661a2163a50307a286379bffb44201ed392e
Author: SabreCat <sabe@habitica.com>
Date:   Fri Feb 24 15:51:42 2023 -0600

    WIP(parties): add seeking flag and modal toggle
2023-05-02 09:51:33 -05:00
SabreCat 9e0777bb42 fix(group-plans): tokenize and update ad text 2023-05-01 16:30:21 -05:00
dependabot[bot] b159182188 build(deps): bump json5 from 1.0.1 to 1.0.2 (#14441)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:39:05 -04:00
dependabot[bot] ca1b8370a0 build(deps): bump stopword from 2.0.7 to 2.0.8 in /website/client (#14560)
Bumps [stopword](https://github.com/fergiemcdowall/stopword) from 2.0.7 to 2.0.8.
- [Release notes](https://github.com/fergiemcdowall/stopword/releases)
- [Commits](https://github.com/fergiemcdowall/stopword/compare/v.2.0.7...v2.0.8)

---
updated-dependencies:
- dependency-name: stopword
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:35:11 -04:00
dependabot[bot] a397da2b93 build(deps): bump jquery from 3.6.3 to 3.6.4 in /website/client (#14540)
Bumps [jquery](https://github.com/jquery/jquery) from 3.6.3 to 3.6.4.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.6.3...3.6.4)

---
updated-dependencies:
- dependency-name: jquery
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:32:06 -04:00
dependabot[bot] b5acc0e0d6 build(deps-dev): bump @babel/plugin-proposal-optional-chaining (#14522)
Bumps [@babel/plugin-proposal-optional-chaining](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-optional-chaining) from 7.20.7 to 7.21.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.21.0/packages/babel-plugin-proposal-optional-chaining)

---
updated-dependencies:
- dependency-name: "@babel/plugin-proposal-optional-chaining"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:30:42 -04:00
dependabot[bot] 2635c5fcee build(deps): bump @babel/register from 7.18.9 to 7.21.0 (#14517)
Bumps [@babel/register](https://github.com/babel/babel/tree/HEAD/packages/babel-register) from 7.18.9 to 7.21.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.21.0/packages/babel-register)

---
updated-dependencies:
- dependency-name: "@babel/register"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:29:55 -04:00
dependabot[bot] ee2936834a build(deps): bump body-parser from 1.20.1 to 1.20.2 (#14518)
Bumps [body-parser](https://github.com/expressjs/body-parser) from 1.20.1 to 1.20.2.
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.20.1...1.20.2)

---
updated-dependencies:
- dependency-name: body-parser
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:28:07 -04:00
dependabot[bot] c94a5304c7 build(deps): bump xml2js from 0.4.23 to 0.5.0 (#14574)
Bumps [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) from 0.4.23 to 0.5.0.
- [Release notes](https://github.com/Leonidas-from-XIV/node-xml2js/releases)
- [Commits](https://github.com/Leonidas-from-XIV/node-xml2js/commits)

---
updated-dependencies:
- dependency-name: xml2js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:07:53 -04:00
dependabot[bot] c6b004a474 build(deps): bump apple-auth from 1.0.7 to 1.0.9 (#14578)
Bumps [apple-auth](https://github.com/ananay/apple-auth) from 1.0.7 to 1.0.9.
- [Release notes](https://github.com/ananay/apple-auth/releases)
- [Commits](https://github.com/ananay/apple-auth/compare/1.0.7...1.0.9)

---
updated-dependencies:
- dependency-name: apple-auth
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 16:07:01 -04:00
dependabot[bot] de918ec43b build(deps): bump core-js from 3.27.2 to 3.30.1 in /website/client (#14601)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.27.2 to 3.30.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.30.1/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 15:41:26 -04:00
dependabot[bot] 069e994b25 build(deps): bump @babel/core from 7.20.12 to 7.21.4 (#14566)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.20.12 to 7.21.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.21.4/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 15:39:50 -04:00
dependabot[bot] 663692f2d5 chore(deps-dev): bump sinon from 15.0.1 to 15.0.4 (#14605)
Bumps [sinon](https://github.com/sinonjs/sinon) from 15.0.1 to 15.0.4.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.0.1...v15.0.4)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 15:38:03 -04:00
dependabot[bot] 0ba4761083 chore(deps-dev): bump axios from 1.2.2 to 1.3.6 (#14606)
Bumps [axios](https://github.com/axios/axios) from 1.2.2 to 1.3.6.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/1.2.2...v1.3.6)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 15:37:30 -04:00
dependabot[bot] afad3815a2 chore(deps): bump smartbanner.js in /website/client (#14610)
Bumps [smartbanner.js](https://github.com/ain/smartbanner.js) from 1.19.1 to 1.19.2.
- [Release notes](https://github.com/ain/smartbanner.js/releases)
- [Commits](https://github.com/ain/smartbanner.js/compare/v1.19.1...v1.19.2)

---
updated-dependencies:
- dependency-name: smartbanner.js
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-28 15:25:55 -04:00
CuriousMagpie 0c85835dc2 update to sellModal, buyModal, and questDialogContent.vue 2023-04-07 10:41:43 -04:00
CuriousMagpie 54df8397a7 fixes to svg and other spacing 2023-04-06 17:00:37 -04:00
CuriousMagpie 0644032a4f style: more spacing updates 2023-04-05 13:50:14 -04:00
CuriousMagpie 44265ac616 style: more spacing updates 2023-04-03 14:56:43 -04:00
CuriousMagpie ac3b953633 style: vertical spacing tweaks 2023-03-30 09:07:37 -04:00
CuriousMagpie 5de2921d22 Merge branch 'develop' into increment-component 2023-03-30 08:33:24 -04:00
CuriousMagpie c1a0f8a8d1 style: buyModal, sellModal, buyQuestModal, questRewards 2023-03-28 15:07:49 -04:00
CuriousMagpie 7e9506391f more buyModal styling 2023-03-27 16:13:06 -04:00
CuriousMagpie 3c7ca56089 buyModal styling 2023-03-27 15:58:56 -04:00
CuriousMagpie 0d155535c3 Merge branch 'develop' into increment-component 2023-03-27 14:16:55 -04:00
CuriousMagpie 09a0d2b3b8 change spacing on buyModal 2023-03-23 16:01:33 -04:00
CuriousMagpie 83dcf8d56a tightening up spacing on buyModal, fixing footer 2023-03-22 13:15:11 -04:00
CuriousMagpie bfc13bc21b Merge branch 'develop' into increment-component 2023-03-22 12:14:04 -04:00
CuriousMagpie 5afb46f237 fix close icon on buy & sell and keyboard input into number increment component is now a number, not a string 2023-03-21 16:08:26 -04:00
CuriousMagpie 9cc4fc19d3 more tiny updates 2023-03-21 11:26:31 -04:00
CuriousMagpie cc81629f09 updates to buyModal styling 2023-03-18 17:18:41 -04:00
CuriousMagpie e83db7a28a Merge branch 'develop' into increment-component 2023-03-17 11:47:17 -04:00
CuriousMagpie 80e193e4ce Merge branch 'develop' into increment-component 2023-03-15 12:38:07 -04:00
CuriousMagpie 76fa6ec1b8 updates to snumberIncrement, buyModal, and sellModal 2023-03-09 15:54:26 -05:00
CuriousMagpie 1ac4466c24 trying to make more components for the buy/sell modals 2023-03-02 14:33:27 -05:00
CuriousMagpie 03f0061c85 Merge branch 'develop' into increment-component 2023-03-01 15:46:04 -05:00
CuriousMagpie c349de6908 finish up sellModal and questModal (also Time Travelers) 2023-02-15 12:54:26 -05:00
CuriousMagpie fd7f3a646e add functionality and styling to sellModal and questModal 2023-02-14 17:22:05 -05:00
CuriousMagpie 7244c1bebc Merge branch 'develop' into increment-component 2023-02-14 15:30:18 -05:00
CuriousMagpie 20df5eeb8f buy modal complete! 2023-02-08 15:16:17 -05:00
CuriousMagpie 23f7dd94b6 more stylin' of the buy modal 2023-02-07 15:24:53 -05:00
CuriousMagpie 7125da4533 Merge branch 'develop' into increment-component 2023-02-07 14:05:48 -05:00
CuriousMagpie 684cb59a7c buyModal styling/functions 2023-02-06 16:23:20 -05:00
CuriousMagpie 9274fe9a10 Merge branch 'develop' into increment-component 2023-02-06 14:30:34 -05:00
CuriousMagpie a21f083761 gem modal styling/functions 2023-01-25 16:44:14 -05:00
CuriousMagpie c7e2834fc6 Merge branch 'develop' into increment-component 2023-01-25 14:35:39 -05:00
CuriousMagpie a08c26b076 calculations working, style updates to subscriber gem modal 2022-12-22 16:50:55 -05:00
CuriousMagpie f4aa88e1ff more style updates to buy modal 2022-12-21 16:58:22 -05:00
CuriousMagpie 53eab7aa29 Working on styling 2022-12-20 16:53:51 -05:00
CuriousMagpie 8374d61f52 why does NaN ask the user to buy gems? 2022-12-19 17:26:49 -05:00
CuriousMagpie 4c943b7575 number-increment works on buy modal and there was much rejoicing... 2022-12-16 16:51:19 -05:00
CuriousMagpie 24032b57f6 why clicky click no click? 2022-12-15 16:48:59 -05:00
CuriousMagpie 8628c774e5 more css changes to buy modal 2022-12-13 10:53:38 -05:00
CuriousMagpie 523f044914 css changes to buy modal 2022-12-09 17:04:35 -05:00
CuriousMagpie 892c9ad040 trying to make clicky clicky work 2022-12-09 11:47:57 -05:00
CuriousMagpie 570f39c620 Merge branch 'develop' into increment-component 2022-12-08 10:22:08 -05:00
CuriousMagpie a73316ef9f Merge branch 'develop' into increment-component 2022-12-06 11:47:53 -05:00
CuriousMagpie 6d6195ae6a props attempt 2022-12-01 14:43:08 -05:00
CuriousMagpie 4ba66c7018 unbreaking what was broken yesterday 2022-11-30 17:16:51 -05:00
CuriousMagpie 54b9424c6e Merge branch 'develop' into increment-component 2022-11-30 12:04:09 -05:00
CuriousMagpie af574634b0 tried to make if/else logic simpler, ended up breaking everything. 2022-11-29 17:13:48 -05:00
CuriousMagpie d1e1c09b4a add conditionals, add component to buy & sell modals 2022-11-22 15:28:48 -05:00
CuriousMagpie 4f5a720c30 how to make component show up? 2022-11-18 15:27:18 -05:00
CuriousMagpie 4ddfdb84ac get most of the right parts in the same place 2022-11-17 14:57:58 -05:00
395 changed files with 11496 additions and 4391 deletions
+1 -1
View File
@@ -87,5 +87,5 @@
"REDIS_HOST": "aaabbbcccdddeeefff",
"REDIS_PORT": "1234",
"REDIS_PASSWORD": "12345678",
"TRUSTED_DOMAINS": "https://localhost,https://habitica.com"
"TRUSTED_DOMAINS": "localhost,habitica.com"
}
@@ -0,0 +1,158 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20230522_pet_group_achievements';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {
migration: MIGRATION_NAME,
};
if (user && user.items && user.items.pets) {
const pets = user.items.pets;
if (pets['Parrot-Base']
&& pets['Parrot-CottonCandyBlue']
&& pets['Parrot-CottonCandyPink']
&& pets['Parrot-Desert']
&& pets['Parrot-Golden']
&& pets['Parrot-Red']
&& pets['Parrot-Shade']
&& pets['Parrot-Skeleton']
&& pets['Parrot-White']
&& pets['Parrot-Zombie']
&& pets['Rooster-Base']
&& pets['Rooster-CottonCandyBlue']
&& pets['Rooster-CottonCandyPink']
&& pets['Rooster-Desert']
&& pets['Rooster-Golden']
&& pets['Rooster-Red']
&& pets['Rooster-Shade']
&& pets['Rooster-Skeleton']
&& pets['Rooster-White']
&& pets['Rooster-Zombie']
&& pets['Triceratops-Base']
&& pets['Triceratops-CottonCandyBlue']
&& pets['Triceratops-CottonCandyPink']
&& pets['Triceratops-Desert']
&& pets['Triceratops-Golden']
&& pets['Triceratops-Red']
&& pets['Triceratops-Shade']
&& pets['Triceratops-Skeleton']
&& pets['Triceratops-White']
&& pets['Triceratops-Zombie']
&& pets['TRex-Base']
&& pets['TRex-CottonCandyBlue']
&& pets['TRex-CottonCandyPink']
&& pets['TRex-Desert']
&& pets['TRex-Golden']
&& pets['TRex-Red']
&& pets['TRex-Shade']
&& pets['TRex-Skeleton']
&& pets['TRex-White']
&& pets['TRex-Zombie']
&& pets['Pterodactyl-Base']
&& pets['Pterodactyl-CottonCandyBlue']
&& pets['Pterodactyl-CottonCandyPink']
&& pets['Pterodactyl-Desert']
&& pets['Pterodactyl-Golden']
&& pets['Pterodactyl-Red']
&& pets['Pterodactyl-Shade']
&& pets['Pterodactyl-Skeleton']
&& pets['Pterodactyl-White']
&& pets['Pterodactyl-Zombie']
&& pets['Owl-Base']
&& pets['Owl-CottonCandyBlue']
&& pets['Owl-CottonCandyPink']
&& pets['Owl-Desert']
&& pets['Owl-Golden']
&& pets['Owl-Red']
&& pets['Owl-Shade']
&& pets['Owl-Skeleton']
&& pets['Owl-White']
&& pets['Owl-Zombie']
&& pets['Velociraptor-Base']
&& pets['Velociraptor-CottonCandyBlue']
&& pets['Velociraptor-CottonCandyPink']
&& pets['Velociraptor-Desert']
&& pets['Velociraptor-Golden']
&& pets['Velociraptor-Red']
&& pets['Velociraptor-Shade']
&& pets['Velociraptor-Skeleton']
&& pets['Velociraptor-White']
&& pets['Velociraptor-Zombie']
&& pets['Penguin-Base']
&& pets['Penguin-CottonCandyBlue']
&& pets['Penguin-CottonCandyPink']
&& pets['Penguin-Desert']
&& pets['Penguin-Golden']
&& pets['Penguin-Red']
&& pets['Penguin-Shade']
&& pets['Penguin-Skeleton']
&& pets['Penguin-White']
&& pets['Penguin-Zombie']
&& pets['Falcon-Base']
&& pets['Falcon-CottonCandyBlue']
&& pets['Falcon-CottonCandyPink']
&& pets['Falcon-Desert']
&& pets['Falcon-Golden']
&& pets['Falcon-Red']
&& pets['Falcon-Shade']
&& pets['Falcon-Skeleton']
&& pets['Falcon-White']
&& pets['Falcon-Zombie']
&& pets['Peacock-Base']
&& pets['Peacock-CottonCandyBlue']
&& pets['Peacock-CottonCandyPink']
&& pets['Peacock-Desert']
&& pets['Peacock-Golden']
&& pets['Peacock-Red']
&& pets['Peacock-Shade']
&& pets['Peacock-Skeleton']
&& pets['Peacock-White']
&& pets['Peacock-Zombie']) {
set['achievements.dinosaurDynasty'] = true;
}
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({ _id: user._id }, { $set: set }).exec();
}
export default async function processUsers () {
let query = {
// migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2023-04-15') },
};
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
}
};
@@ -0,0 +1,79 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20230718_summer_splash_orcas';
import { model as User } from '../../../website/server/models/user';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = { migration: MIGRATION_NAME };
const push = {};
if (user && user.items && user.items.pets && typeof user.items.pets['Orca-Base'] !== 'undefined') {
return;
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Orca-Base'] !== 'undefined') {
set['items.pets.Orca-Base'] = 5;
push.notifications = {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_orca_pet',
title: 'Orcas for Summer Splash!',
text: 'To celebrate Summer Splash, we\'ve given you an Orca Pet!',
destination: 'stable',
},
seen: false,
};
} else {
set['items.mounts.Orca-Base'] = true;
push.notifications = {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_orca_mount',
title: 'Orcas for Summer Splash!',
text: 'To celebrate Summer Splash, we\'ve given you an Orca Mount!',
destination: 'stable',
},
seen: false,
};
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await user.updateOne({ $set: set, $push: push }).exec();
}
export default async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: new Date('2023-06-18')},
};
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)
.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
}
};
@@ -0,0 +1,155 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20230731_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 };
push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_cake',
title: 'Happy Naming Day!',
text: 'To celebrate the day we became Habitica, weve awarded you some cake!',
destination: '/inventory/items',
},
seen: false,
},
};
} 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': true };
push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_back',
title: 'Happy Naming Day!',
text: 'To celebrate the day we became Habitica, weve awarded you a Royal Purple Gryphon Tail and cake!',
destination: '/inventory/equipment',
},
seen: false,
},
};
} 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': true };
push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_body',
title: 'Happy Naming Day!',
text: 'To celebrate the day we became Habitica, weve awarded you a Royal Purple Gryphon Cloak and cake!',
destination: '/inventory/equipment',
},
seen: false,
},
};
} 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': true };
push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_head',
title: 'Happy Naming Day!',
text: 'To celebrate the day we became Habitica, weve awarded you a Royal Purple Gryphon Helm and cake!',
destination: '/inventory/equipment',
},
seen: false,
},
};
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Gryphon-RoyalPurple'] !== 'undefined') {
set = { migration: MIGRATION_NAME, 'items.pets.Gryphon-RoyalPurple': 5 };
push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_pet',
title: 'Happy Naming Day!',
text: 'To celebrate the day we became Habitica, weve awarded you a Royal Purple Gryphon Pet and cake!',
destination: '/inventory/stable',
},
seen: false,
},
};
} else {
set = { migration: MIGRATION_NAME, 'items.mounts.Gryphon-RoyalPurple': true };
push = {
notifications: {
type: 'ITEM_RECEIVED',
data: {
icon: 'notif_namingDay_mount',
title: 'Happy Naming Day!',
text: 'To celebrate the day we became Habitica, weve awarded you a Royal Purple Gryphon Mount and cake!',
destination: '/inventory/stable',
},
seen: false,
},
};
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (push) {
return await user.updateOne({ $set: set, $inc: inc, $push: push }).exec();
} else {
return await user.updateOne({ $set: set, $inc: inc }).exec();
}
}
export default async function processUsers () {
let query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2023-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)
.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
}
};
+1794 -1263
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -1,12 +1,12 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.268.1",
"version": "4.277.4",
"main": "./website/server/index.js",
"dependencies": {
"@babel/core": "^7.20.12",
"@babel/preset-env": "^7.20.2",
"@babel/register": "^7.18.9",
"@babel/core": "^7.22.5",
"@babel/preset-env": "^7.22.5",
"@babel/register": "^7.22.5",
"@google-cloud/trace-agent": "^7.1.2",
"@parse/node-apn": "^5.1.3",
"@slack/webhook": "^6.1.0",
@@ -14,9 +14,9 @@
"amazon-payments": "^0.2.9",
"amplitude": "^6.0.0",
"apidoc": "^0.54.0",
"apple-auth": "^1.0.7",
"apple-auth": "^1.0.9",
"bcrypt": "^5.1.0",
"body-parser": "^1.20.1",
"body-parser": "^1.20.2",
"bootstrap": "^4.6.0",
"compression": "^1.7.4",
"cookie-session": "^2.0.0",
@@ -42,7 +42,7 @@
"image-size": "^1.0.2",
"in-app-purchase": "^1.11.3",
"js2xmlparser": "^5.0.0",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"jwks-rsa": "^2.1.5",
"lodash": "^4.17.21",
"merge-stream": "^2.0.0",
@@ -67,16 +67,16 @@
"remove-markdown": "^0.5.0",
"rimraf": "^3.0.2",
"short-uuid": "^4.2.2",
"stripe": "^11.10.0",
"superagent": "^8.0.6",
"stripe": "^12.9.0",
"superagent": "^8.0.9",
"universal-analytics": "^0.5.3",
"useragent": "^2.1.9",
"uuid": "^9.0.0",
"validator": "^13.9.0",
"vinyl-buffer": "^1.0.1",
"winston": "^3.8.2",
"winston": "^3.9.0",
"winston-loggly-bulk": "^3.2.1",
"xml2js": "^0.4.23"
"xml2js": "^0.6.0"
},
"private": true,
"engines": {
@@ -110,7 +110,7 @@
"apidoc": "gulp apidoc"
},
"devDependencies": {
"axios": "^1.2.2",
"axios": "^1.3.6",
"chai": "^4.3.7",
"chai-as-promised": "^7.1.1",
"chai-moment": "^0.1.0",
@@ -122,7 +122,7 @@
"monk": "^7.3.4",
"require-again": "^2.0.0",
"run-rs": "^0.7.7",
"sinon": "^15.0.1",
"sinon": "^15.1.2",
"sinon-chai": "^3.7.0",
"sinon-stub-promise": "^4.0.0"
},
+11 -1
View File
@@ -748,9 +748,19 @@ describe('payments/index', () => {
});
it('does not add to plans.consecutive.offset if 1 month subscription', async () => {
data.sub.key = 'basic_earned';
await api.createSubscription(data);
expect(user.purchased.plan.extraMonths).to.eql(0);
expect(user.purchased.plan.consecutive.offset).to.eql(0);
});
it('resets plans.consecutive.offset if 1 month subscription', async () => {
user.purchased.plan.consecutive.offset = 1;
await user.save();
data.sub.key = 'basic_earned';
await api.createSubscription(data);
expect(user.purchased.plan.consecutive.offset).to.eql(0);
});
it('adds 5 to plan.consecutive.gemCapExtra for 3 month block', async () => {
+1 -1
View File
@@ -242,7 +242,7 @@ describe('cron middleware', () => {
sandbox.spy(cronLib, 'recoverCron');
sandbox.stub(User, 'update')
sandbox.stub(User, 'updateOne')
.withArgs({
_id: user._id,
$or: [
+18 -18
View File
@@ -1732,7 +1732,7 @@ describe('Group Model', () => {
});
it('updates participting members (not including user)', async () => {
sandbox.spy(User, 'update');
sandbox.spy(User, 'updateMany');
await party.startQuest(nonParticipatingMember);
@@ -1740,7 +1740,7 @@ describe('Group Model', () => {
questLeader._id, participatingMember._id, sleepingParticipatingMember._id,
];
expect(User.update).to.be.calledWith(
expect(User.updateMany).to.be.calledWith(
{ _id: { $in: members } },
{
$set: {
@@ -1753,11 +1753,11 @@ describe('Group Model', () => {
});
it('updates non-user quest leader and decrements quest scroll', async () => {
sandbox.spy(User, 'update');
sandbox.spy(User, 'updateOne');
await party.startQuest(participatingMember);
expect(User.update).to.be.calledWith(
expect(User.updateOne).to.be.calledWith(
{ _id: questLeader._id },
{
$inc: {
@@ -1819,29 +1819,29 @@ describe('Group Model', () => {
};
it('doesn\'t retry successful operations', async () => {
sandbox.stub(User, 'update').returns(successfulMock);
sandbox.stub(User, 'updateOne').returns(successfulMock);
await party.finishQuest(quest);
expect(User.update).to.be.calledThrice;
expect(User.updateOne).to.be.calledThrice;
});
it('stops retrying when a successful update has occurred', async () => {
const updateStub = sandbox.stub(User, 'update');
const updateStub = sandbox.stub(User, 'updateOne');
updateStub.onCall(0).returns(failedMock);
updateStub.returns(successfulMock);
await party.finishQuest(quest);
expect(User.update.callCount).to.equal(4);
expect(User.updateOne.callCount).to.equal(4);
});
it('retries failed updates at most five times per user', async () => {
sandbox.stub(User, 'update').returns(failedMock);
sandbox.stub(User, 'updateOne').returns(failedMock);
await expect(party.finishQuest(quest)).to.eventually.be.rejected;
expect(User.update.callCount).to.eql(15); // for 3 users
expect(User.updateOne.callCount).to.eql(15); // for 3 users
});
});
@@ -2088,17 +2088,17 @@ describe('Group Model', () => {
context('Party quests', () => {
it('updates participating members with rewards', async () => {
sandbox.spy(User, 'update');
sandbox.spy(User, 'updateOne');
await party.finishQuest(quest);
expect(User.update).to.be.calledThrice;
expect(User.update).to.be.calledWithMatch({
expect(User.updateOne).to.be.calledThrice;
expect(User.updateOne).to.be.calledWithMatch({
_id: questLeader._id,
});
expect(User.update).to.be.calledWithMatch({
expect(User.updateOne).to.be.calledWithMatch({
_id: participatingMember._id,
});
expect(User.update).to.be.calledWithMatch({
expect(User.updateOne).to.be.calledWithMatch({
_id: sleepingParticipatingMember._id,
});
});
@@ -2173,11 +2173,11 @@ describe('Group Model', () => {
});
it('updates all users with rewards', async () => {
sandbox.spy(User, 'update');
sandbox.spy(User, 'updateMany');
await party.finishQuest(tavernQuest);
expect(User.update).to.be.calledOnce;
expect(User.update).to.be.calledWithMatch({});
expect(User.updateMany).to.be.calledOnce;
expect(User.updateMany).to.be.calledWithMatch({});
});
it('sets quest completed to the world quest key', async () => {
@@ -2,7 +2,6 @@ import { v4 as generateUUID } from 'uuid';
import {
generateUser,
createAndPopulateGroup,
checkExistence,
translate as t,
} from '../../../../helpers/api-integration/v3';
@@ -258,47 +257,6 @@ describe('POST /group/:groupId/join', () => {
await expect(user.get('/user')).to.eventually.have.nested.property('items.quests.basilist', 2);
});
it('deletes previous party where the user was the only member', async () => {
const userToInvite = await generateUser();
const oldParty = await userToInvite.post('/groups', { // add user to a party
name: 'Another Test Party',
type: 'party',
});
await expect(checkExistence('groups', oldParty._id)).to.eventually.equal(true);
await user.post(`/groups/${party._id}/invite`, {
uuids: [userToInvite._id],
});
await userToInvite.post(`/groups/${party._id}/join`);
await expect(user.get('/user')).to.eventually.have.nested.property('party._id', party._id);
await expect(checkExistence('groups', oldParty._id)).to.eventually.equal(false);
});
it('does not allow user to leave a party if a quest was active and they were the only member', async () => {
const userToInvite = await generateUser();
const oldParty = await userToInvite.post('/groups', { // add user to a party
name: 'Another Test Party',
type: 'party',
});
await userToInvite.update({
[`items.quests.${PET_QUEST}`]: 1,
});
await userToInvite.post(`/groups/${oldParty._id}/quests/invite/${PET_QUEST}`);
await expect(checkExistence('groups', oldParty._id)).to.eventually.equal(true);
await user.post(`/groups/${party._id}/invite`, {
uuids: [userToInvite._id],
});
await expect(userToInvite.post(`/groups/${party._id}/join`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('messageCannotLeaveWhileQuesting'),
});
});
it('invites joining member to active quest', async () => {
await user.update({
[`items.quests.${PET_QUEST}`]: 1,
@@ -1,6 +1,7 @@
import { v4 as generateUUID } from 'uuid';
import nconf from 'nconf';
import {
createAndPopulateGroup,
generateUser,
generateGroup,
translate as t,
@@ -581,20 +582,7 @@ describe('Post /groups/:groupId/invite', () => {
});
});
it('allow inviting a user to a party if they are partying solo', async () => {
const userToInvite = await generateUser();
await userToInvite.post('/groups', { // add user to a party
name: 'Another Test Party',
type: 'party',
});
await inviter.post(`/groups/${party._id}/invite`, {
uuids: [userToInvite._id],
});
expect((await userToInvite.get('/user')).invitations.parties[0].id).to.equal(party._id);
});
it('allow inviting a user to 2 different parties', async () => {
it('allows inviting a user to 2 different parties', async () => {
// Create another inviter
const inviter2 = await generateUser();
@@ -635,29 +623,48 @@ describe('Post /groups/:groupId/invite', () => {
});
expect((await userToInvite.get('/user')).invitations.parties[0].id).to.equal(party._id);
});
});
describe('party size limits', () => {
let party;
let partyLeader;
beforeEach(async () => {
group = await createAndPopulateGroup({
groupDetails: {
name: 'Test Party',
type: 'party',
privacy: 'private',
},
// Generate party with 20 members
members: PARTY_LIMIT_MEMBERS - 10,
});
party = group.group;
partyLeader = group.groupLeader;
});
it('allows 30 members in a party', async () => {
const invitesToGenerate = [];
// Generate 29 users to invite (29 + leader = 30 members)
for (let i = 0; i < PARTY_LIMIT_MEMBERS - 1; i += 1) {
// Generate 10 new invites
for (let i = 1; i < 10; i += 1) {
invitesToGenerate.push(generateUser());
}
const generatedInvites = await Promise.all(invitesToGenerate);
// Invite users
expect(await inviter.post(`/groups/${party._id}/invite`, {
expect(await partyLeader.post(`/groups/${party._id}/invite`, {
uuids: generatedInvites.map(invite => invite._id),
})).to.be.an('array');
}).timeout(10000);
it('does not allow 30+ members in a party', async () => {
it('does not allow >30 members in a party', async () => {
const invitesToGenerate = [];
// Generate 30 users to invite (30 + leader = 31 members)
for (let i = 0; i < PARTY_LIMIT_MEMBERS; i += 1) {
// Generate 11 invites
for (let i = 1; i < 11; i += 1) {
invitesToGenerate.push(generateUser());
}
const generatedInvites = await Promise.all(invitesToGenerate);
// Invite users
await expect(inviter.post(`/groups/${party._id}/invite`, {
await expect(partyLeader.post(`/groups/${party._id}/invite`, {
uuids: generatedInvites.map(invite => invite._id),
}))
.to.eventually.be.rejected.and.eql({
@@ -202,18 +202,86 @@ describe('POST /user/class/cast/:spellId', () => {
await group.groupLeader.post('/user/class/cast/mpheal');
promises = [];
promises.push(group.groupLeader.sync());
promises.push(group.members[0].sync());
promises.push(group.members[1].sync());
promises.push(group.members[2].sync());
promises.push(group.members[3].sync());
await Promise.all(promises);
expect(group.groupLeader.stats.mp).to.be.equal(170); // spell caster
expect(group.members[0].stats.mp).to.be.greaterThan(0); // warrior
expect(group.members[1].stats.mp).to.equal(0); // wizard
expect(group.members[2].stats.mp).to.be.greaterThan(0); // rogue
expect(group.members[3].stats.mp).to.be.greaterThan(0); // healer
});
const spellList = [
{
className: 'warrior',
spells: [['smash', 'task'], ['defensiveStance'], ['valorousPresence'], ['intimidate']],
},
{
className: 'wizard',
spells: [['fireball', 'task'], ['mpheal'], ['earth'], ['frost']],
},
{
className: 'healer',
spells: [['heal'], ['brightness'], ['protectAura'], ['healAll']],
},
{
className: 'rogue',
spells: [['pickPocket', 'task'], ['backStab', 'task'], ['toolsOfTrade'], ['stealth']],
},
];
spellList.forEach(async habitClass => {
describe(`For a ${habitClass.className}`, async () => {
habitClass.spells.forEach(async spell => {
describe(`Using ${spell[0]}`, async () => {
it('Deducts MP from spell caster', async () => {
const { groupLeader } = await createAndPopulateGroup({
groupDetails: { type: 'party', privacy: 'private' },
members: 3,
});
await groupLeader.update({
'stats.mp': 200, 'stats.class': habitClass.className, 'stats.lvl': 20, 'stats.hp': 40,
});
// need this for task spells and for stealth
const task = await groupLeader.post('/tasks/user', {
text: 'test habit',
type: 'daily',
});
if (spell.length === 2 && spell[1] === 'task') {
await groupLeader.post(`/user/class/cast/${spell[0]}?targetId=${task._id}`);
} else {
await groupLeader.post(`/user/class/cast/${spell[0]}`);
}
await groupLeader.sync();
expect(groupLeader.stats.mp).to.be.lessThan(200);
});
it('works without a party', async () => {
await user.update({
'stats.mp': 200, 'stats.class': habitClass.className, 'stats.lvl': 20, 'stats.hp': 40,
});
// need this for task spells and for stealth
const task = await user.post('/tasks/user', {
text: 'test habit',
type: 'daily',
});
if (spell.length === 2 && spell[1] === 'task') {
await user.post(`/user/class/cast/${spell[0]}?targetId=${task._id}`);
} else {
await user.post(`/user/class/cast/${spell[0]}`);
}
await user.sync();
expect(user.stats.mp).to.be.lessThan(200);
});
});
});
});
});
it('cast bulk', async () => {
let { group, groupLeader } = await createAndPopulateGroup({ // eslint-disable-line prefer-const
groupDetails: { type: 'party', privacy: 'private' },
+2
View File
@@ -14,6 +14,8 @@ module.exports = {
// TODO find a way to let eslint understand webpack aliases
'import/no-unresolved': 'off',
'import/extensions': 'off',
'vue/component-tags-order': 'off',
'vue/no-mutating-props': 'off',
'vue/no-v-html': 'off',
'vue/html-self-closing': ['error', {
html: {
+53 -52
View File
@@ -1842,9 +1842,9 @@
}
},
"@babel/plugin-proposal-optional-chaining": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz",
"integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz",
"integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==",
"requires": {
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
@@ -1870,9 +1870,9 @@
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
},
"@babel/types": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
"integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
"version": "7.21.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz",
"integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==",
"requires": {
"@babel/helper-string-parser": "^7.19.4",
"@babel/helper-validator-identifier": "^7.19.1",
@@ -13321,14 +13321,12 @@
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"optional": true
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"optional": true
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
@@ -13339,7 +13337,6 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
@@ -13381,7 +13378,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
@@ -13390,7 +13386,6 @@
"version": "npm:vue-loader@16.8.3",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
@@ -13401,7 +13396,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -16907,9 +16901,9 @@
}
},
"core-js": {
"version": "3.27.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz",
"integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w=="
"version": "3.31.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz",
"integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ=="
},
"core-js-compat": {
"version": "3.11.0",
@@ -17958,9 +17952,9 @@
}
},
"dompurify": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz",
"integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ=="
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.3.tgz",
"integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ=="
},
"domutils": {
"version": "1.7.0",
@@ -21077,6 +21071,11 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
},
"immutable": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
"integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg=="
},
"import-cwd": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
@@ -21437,9 +21436,9 @@
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
},
"intro.js": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/intro.js/-/intro.js-6.0.0.tgz",
"integrity": "sha512-ZUiR6BoLSvPSlLG0boewnWVgji1fE1gBvP/pyw5pgCKXEDQz1mMeUxarggClPNs71UTq364LwSk9zxz17A9gaQ=="
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/intro.js/-/intro.js-7.0.1.tgz",
"integrity": "sha512-1oqz6aOz9cGQ3CrtVYhCSo6AkjnXUn302kcIWLaZ3TI4kKssRXDwDSz4VRoGcfC1jN+WfaSJXRBrITz+QVEBzg=="
},
"invariant": {
"version": "2.2.4",
@@ -22019,9 +22018,9 @@
}
},
"jquery": {
"version": "3.6.3",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz",
"integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz",
"integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ=="
},
"js-message": {
"version": "1.0.5",
@@ -27367,17 +27366,19 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sass": {
"version": "1.34.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.34.0.tgz",
"integrity": "sha512-rHEN0BscqjUYuomUEaqq3BMgsXqQfkcMVR7UhscsAVub0/spUrZGBMxQXFS2kfiDsPLZw5yuU9iJEFNC2x38Qw==",
"version": "1.63.4",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.63.4.tgz",
"integrity": "sha512-Sx/+weUmK+oiIlI+9sdD0wZHsqpbgQg8wSwSnGBjwb5GwqFhYNwwnI+UWZtLjKvKyFlKkatRK235qQ3mokyPoQ==",
"requires": {
"chokidar": ">=3.0.0 <4.0.0"
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
},
"dependencies": {
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -27397,18 +27398,18 @@
}
},
"chokidar": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"requires": {
"anymatch": "~3.1.1",
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"fsevents": "~2.3.1",
"glob-parent": "~5.1.0",
"fsevents": "~2.3.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.5.0"
"readdirp": "~3.6.0"
}
},
"fill-range": {
@@ -27447,9 +27448,9 @@
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
"readdirp": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"requires": {
"picomatch": "^2.2.1"
}
@@ -27801,9 +27802,9 @@
}
},
"smartbanner.js": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.19.1.tgz",
"integrity": "sha512-x3alFTlk6pLuqrm9PrYQv1E+86CrEIgPf/KJ+nP5342BmOWstbdR8OwD3TPmM56zHQm4MEr/eoqbEcfTKdvdKw=="
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.19.2.tgz",
"integrity": "sha512-hwcGNp5Hza5PJHTmqP6H8q0XBYhloIQyJgdzv0ldz3HQSeEuKB2riVraQXdKuquE6ZU/0M0yubno53xJ/ZiQQg=="
},
"snapdragon": {
"version": "0.8.2",
@@ -28175,9 +28176,9 @@
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"stopword": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/stopword/-/stopword-2.0.7.tgz",
"integrity": "sha512-s+uLKAxrproCLrq0Wcd3JAIjlJLx6l80b2Rzt0u8+ra5SzGkHnNG8PS3DfGmYk2TrKePDVLL4SdKYwKpgSLc+w=="
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/stopword/-/stopword-2.0.8.tgz",
"integrity": "sha512-btlEC2vEuhCuvshz99hSGsY8GzaP5qzDPQm56j6rR/R38p8xdsOXgU5a6tIgvU/4hcCta1Vlo/2FVXA9m0f8XA=="
},
"store2": {
"version": "2.10.0",
@@ -30271,9 +30272,9 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
},
"uuid-browser": {
"version": "3.1.0",
+9 -9
View File
@@ -32,8 +32,8 @@
"bootstrap": "^4.6.0",
"bootstrap-vue": "^2.23.1",
"chai": "^4.3.7",
"core-js": "^3.27.2",
"dompurify": "^2.4.3",
"core-js": "^3.31.0",
"dompurify": "^3.0.3",
"eslint": "^6.8.0",
"eslint-config-habitrpg": "^6.2.0",
"eslint-plugin-mocha": "^5.3.0",
@@ -41,20 +41,20 @@
"habitica-markdown": "^3.0.0",
"hellojs": "^1.20.0",
"inspectpack": "^4.7.1",
"intro.js": "^6.0.0",
"jquery": "^3.6.3",
"intro.js": "^7.0.1",
"jquery": "^3.7.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"nconf": "^0.12.0",
"sass": "^1.34.0",
"sass": "^1.63.4",
"sass-loader": "^8.0.2",
"smartbanner.js": "^1.19.1",
"stopword": "^2.0.7",
"smartbanner.js": "^1.19.2",
"stopword": "^2.0.8",
"svg-inline-loader": "^0.8.2",
"svg-url-loader": "^7.1.1",
"svgo": "^1.3.2",
"svgo-loader": "^2.2.1",
"uuid": "^8.3.2",
"uuid": "^9.0.0",
"validator": "^13.9.0",
"vue": "^2.7.10",
"vue-cli-plugin-storybook": "2.1.0",
@@ -66,6 +66,6 @@
"webpack": "^4.46.0"
},
"devDependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.20.7"
"@babel/plugin-proposal-optional-chaining": "^7.21.0"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

+3
View File
@@ -41,6 +41,7 @@
<router-view v-if="!isUserLoggedIn || isStaticPage" />
<template v-else>
<template v-if="isUserLoaded">
<chat-banner />
<damage-paused-banner />
<gems-promo-banner />
<gift-promo-banner />
@@ -159,6 +160,7 @@ import { loadProgressBar } from 'axios-progress-bar';
import birthdayModal from '@/components/news/birthdayModal';
import AppMenu from './components/header/menu';
import AppHeader from './components/header/index';
import ChatBanner from './components/header/banners/chatBanner';
import DamagePausedBanner from './components/header/banners/damagePaused';
import GemsPromoBanner from './components/header/banners/gemsPromo';
import GiftPromoBanner from './components/header/banners/giftPromo';
@@ -198,6 +200,7 @@ export default {
AppHeader,
AppFooter,
birthdayModal,
ChatBanner,
DamagePausedBanner,
GemsPromoBanner,
GiftPromoBanner,
File diff suppressed because it is too large Load Diff
+13 -8
View File
@@ -24,9 +24,9 @@
}
}
.icon-16 {
width: 16px;
height: 16px;
.icon-10 {
width: 10px;
height: 10px;
}
.icon-12 {
@@ -34,21 +34,26 @@
height: 12px;
}
.icon-16 {
width: 16px;
height: 16px;
}
.icon-24 {
width: 24px;
height: 24px;
}
.icon-32 {
width: 32px;
height: 32px;
}
.icon-48 {
width: 48px;
height: 48px;
}
.icon-10 {
width: 10px;
height: 10px;
}
.inline {
display: inline-block;
}
+1
View File
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path id="b" d="m10,6h6V0h-2v2.72C12.49.99,10.3,0,8,0,3.59,0,0,3.59,0,8s3.59,8,8,8c2.69,0,5.2-1.35,6.68-3.6l-1.67-1.1c-1.11,1.69-2.99,2.71-5.01,2.7-3.31,0-6-2.69-6-6s2.69-6,6-6c1.72,0,3.33.74,4.46,2h-2.46v2Z" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 341 B

@@ -17,10 +17,18 @@
Payment schedule ("basic-earned" is monthly):
<strong>{{ hero.purchased.plan.planId }}</strong>
</div>
<div v-if="hero.purchased.plan.planId == 'group_plan_auto'">
Group plan ID:
<strong>{{ hero.purchased.plan.owner }}</strong>
</div>
<div v-if="hero.purchased.plan.dateCreated">
Creation date:
<strong>{{ dateFormat(hero.purchased.plan.dateCreated) }}</strong>
</div>
<div v-if="hero.purchased.plan.dateCurrentTypeCreated">
Start date for current subscription type:
<strong>{{ dateFormat(hero.purchased.plan.dateCurrentTypeCreated) }}</strong>
</div>
<div>
Termination date:
<strong
@@ -46,9 +54,16 @@
Perk offset months:
<strong>{{ hero.purchased.plan.consecutive.offset }}</strong>
</div>
<div>
<div class="form-inline">
Perk month count:
<strong>{{ hero.purchased.plan.perkMonthCount }}</strong>
<input
v-model="hero.purchased.plan.perkMonthCount"
class="form-control"
type="number"
min="0"
max="2"
step="1"
>
</div>
<div>
Next Mystic Hourglass:
+40 -15
View File
@@ -183,10 +183,8 @@
<div
v-for="bg in backgroundShopSets[0].items"
:key="bg.key"
:id="bg.key"
class="col-2"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="unlock('background.' + bg.key)"
>
<div
@@ -195,6 +193,13 @@
>
<div class="small-rectangle"></div>
</div>
<b-popover
:target="bg.key"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
:content="bg.notes"
/>
</div>
</div>
<div
@@ -211,16 +216,21 @@
<div
v-for="bg in backgroundShopSets[2].items"
:key="bg.key"
:id="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="unlock('background.' + bg.key)"
>
<div
class="background"
:class="`background_${bg.key}`"
></div>
<b-popover
:target="bg.key"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
:content="bg.notes"
/>
</div>
</div>
</div>
@@ -236,10 +246,8 @@
<div
v-for="bg in backgroundShopSets[1].items"
:key="bg.key"
:id="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="!user.purchased.background[bg.key]
? backgroundSelected(bg) : unlock('background.' + bg.key)"
>
@@ -270,6 +278,13 @@
:pinned="isBackgroundPinned(bg)"
/>
</span>
<b-popover
:target="bg.key"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
:content="bg.notes"
/>
</div>
</div>
</div>
@@ -302,10 +317,8 @@
<div
v-for="bg in set.items"
:key="bg.key"
:id="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="!user.purchased.background[bg.key]
? backgroundSelected(bg) : unlock('background.' + bg.key)"
>
@@ -336,6 +349,13 @@
:pinned="isBackgroundPinned(bg)"
/>
</span>
<b-popover
:target="bg.key"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
:content="bg.notes"
/>
</div>
<div
v-if="!ownsSet('background', set.items) && set.identifier !== 'incentiveBackgrounds'"
@@ -358,16 +378,21 @@
<div
v-for="(bg) in ownedBackgrounds"
:key="bg.key"
:id="bg.key"
class="col-4 text-center customize-option background-button"
:popover-title="bg.text"
:popover="bg.notes"
popover-trigger="mouseenter"
@click="unlock('background.' + bg.key)"
>
<div
class="background"
:class="[`background_${bg.key}`, backgroundLockedStatus(bg.key)]"
></div>
<b-popover
:target="bg.key"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
:content="bg.notes"
/>
</div>
</div>
</div>
@@ -11,9 +11,12 @@
<div class="quest_screen"></div>
<div class="row heading">
<div class="col-12 text-center pr-5 pl-5">
<h2 v-once>
<h1
v-once
class="mb-2"
>
{{ $t('playInPartyTitle') }}
</h2>
</h1>
<p
v-once
class="mb-4"
@@ -22,67 +25,91 @@
</p>
<button
v-once
class="btn btn-primary"
class="btn btn-primary px-4 mb-2"
@click="createParty()"
>
{{ $t('createParty') }}
</button>
</div>
</div>
<close-x
@close="close()"
/>
</div>
<div class="row grey-row">
<div class="col-12 text-center">
<div class="col-12 text-center px-0">
<div class="join-party"></div>
<h2 v-once>
{{ $t('wantToJoinPartyTitle') }}
</h2>
<p v-html="$t('wantToJoinPartyDescription')"></p>
<div
class="form-group"
@click="copyUsername"
<h1
v-once
class="mb-2"
>
<div class="d-flex align-items-center">
<label
v-once
class="mr-3"
>{{ $t('username') }}</label>
<div class="flex-grow-1">
<div class="input-group-prepend input-group-text">
@
<div class="text">
{{ user.auth.local.username }}
</div>
<div
class="svg-icon copy-icon"
v-html="icons.copy"
></div>
<div
v-once
class="small"
>
{{ $t('copy') }}
</div>
</div>
{{ $t('wantToJoinPartyTitle') }}
</h1>
<p
v-once
class="mb-4"
v-html="$t('partyFinderDescription')"
>
</p>
<div
v-if="seeking"
>
<div
class="green-bar mb-3"
>
{{ $t('currentlyLookingForParty') }}
</div>
<div class="d-flex justify-content-center">
<div
class="red-link"
@click="seekParty()"
>
{{ $t('leave') }}
</div>
</div>
</div>
<button
v-else
class="btn btn-primary px-4 mt-2 mb-1"
@click="seekParty()"
>
{{ $t('lookForParty') }}
</button>
</div>
</div>
</b-modal>
</template>
<style>
#create-party-modal .modal-body {
padding: 0rem 0.75rem;
}
<style lang="scss">
#create-party-modal {
display: flex !important;
overflow-y: hidden;
#create-party-modal .modal-dialog {
width: 35.75rem;
}
@media (max-height: 770px) {
overflow-y: auto;
}
#create-party-modal .modal-header {
padding: 0;
border-bottom: 0px;
.modal-body {
padding: 0rem 0.75rem;
}
.modal-content {
border-radius: 8px;
}
.modal-dialog {
width: 566px;
margin: auto;
@media (max-height: 826px) {
margin-top: 56px;
}
}
.modal-header {
padding: 0;
border-bottom: 0px;
}
}
</style>
@@ -107,15 +134,27 @@
cursor: pointer;
}
.green-bar {
height: 32px;
font-size: 14px;
font-weight: bold;
line-height: 1.71;
text-align: center;
color: $green-1;
background-color: $green-100;
border-radius: 2px;
padding: 4px 0px 4px 0px;
}
.grey-row {
background-color: $gray-700;
color: #4e4a57;
padding: 2em;
border-radius: 0px 0px 2px 2px;
border-radius: 0px 0px 8px 8px;
}
h2 {
color: $gray-100;
h1 {
color: $purple-300;
}
.header-wrap {
@@ -132,10 +171,6 @@
border-radius: 2px 2px 0 0;
image-rendering: optimizequality;
}
h2 {
color: $purple-200;
}
}
.heading {
@@ -182,6 +217,21 @@
margin: 0.75rem auto 0.75rem 0.25rem;
}
p {
line-height: 1.71;
}
.red-link {
cursor: pointer;
font-size: 14px;
line-height: 1.71;
text-align: center;
color: $maroon-50;
&:hover {
text-decoration: underline;
}
}
.small {
color: $gray-200;
margin: auto 0.5rem auto 0.25rem;
@@ -192,21 +242,29 @@
import { mapState } from '@/libs/store';
import * as Analytics from '@/libs/analytics';
import notifications from '@/mixins/notifications';
import closeX from '../ui/closeX';
import copyIcon from '@/assets/svg/copy.svg';
export default {
components: {
closeX,
},
mixins: [notifications],
data () {
return {
icons: Object.freeze({
copy: copyIcon,
}),
seeking: false,
};
},
computed: {
...mapState({ user: 'user.data' }),
},
mounted () {
this.seeking = Boolean(this.user.party.seeking);
},
methods: {
async createParty () {
const group = {
@@ -223,7 +281,10 @@ export default {
});
this.$root.$emit('bv::hide::modal', 'create-party-modal');
this.$router.push('/party');
await this.$router.push('/party');
},
close () {
this.$root.$emit('bv::hide::modal', 'create-party-modal');
},
copyUsername () {
if (navigator.clipboard) {
@@ -238,6 +299,12 @@ export default {
}
this.text(this.$t('usernameCopied'));
},
seekParty () {
this.$store.dispatch('user:set', {
'party.seeking': !this.user.party.seeking ? new Date() : null,
});
this.seeking = !this.seeking;
},
},
};
</script>
@@ -542,7 +542,8 @@ export default {
await this.$store.dispatch('guilds:leave', data);
if (this.isParty) {
this.$router.push({ name: 'tasks' });
await this.$router.push({ name: 'tasks' });
window.location.reload(true);
}
},
upgradeGroup () {
@@ -4,12 +4,12 @@
<group-plan-creation-modal />
<div>
<div class="header">
<h1 class="text-center">
Need more for your Group?
<h1 v-once class="text-center">
{{ $t('groupPlanTitle') }}
</h1>
<div class="row">
<div class="col-8 offset-2 text-center">
<h2 class="sub-text">
<h2 v-once class="sub-text">
{{ $t('groupBenefitsDescription') }}
</h2>
</div>
@@ -24,8 +24,8 @@
src="~@/assets/images/group-plans/group-14@3x.png"
>
<hr>
<h2>{{ $t('teamBasedTasks') }}</h2>
<p>Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!</p><!-- eslint-disable-line max-len -->
<h2 v-once> {{ $t('teamBasedTasks') }} </h2>
<p v-once> {{ $t('teamBasedTasksListDesc') }} </p>
</div>
</div>
<div class="col-4">
@@ -35,8 +35,8 @@
src="~@/assets/images/group-plans/group-12@3x.png"
>
<hr>
<h2>Group Management Controls</h2>
<p>Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.</p><!-- eslint-disable-line max-len -->
<h2 v-once> {{ $t('groupManagementControls') }} </h2>
<p v-once> {{ $t('groupManagementControlsDesc') }} </p>
</div>
</div>
<div class="col-4">
@@ -46,8 +46,8 @@
src="~@/assets/images/group-plans/group-13@3x.png"
>
<hr>
<h2>In-Game Benefits</h2>
<p>Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.</p><!-- eslint-disable-line max-len -->
<h2 v-once> {{ $t('inGameBenefits') }} </h2>
<p v-once> {{ $t('inGameBenefitsDesc') }} </p>
</div>
</div>
</div>
@@ -0,0 +1,344 @@
<template>
<div>
<div class="d-flex justify-content-center">
<div
v-if="seekers.length > 0"
class="fit-content mx-auto mt-4"
>
<div class="d-flex align-items-center">
<h1 v-once class="my-auto mr-auto"> {{ $t('findPartyMembers') }}</h1>
<div
class="btn btn-secondary btn-sync ml-auto my-auto pl-2 pr-3 d-flex"
@click="refreshList()"
>
<div class="svg-icon icon-16 color my-auto mr-2" v-html="icons.sync"></div>
<div class="ml-auto"> {{ $t('refreshList') }} </div>
</div>
</div>
<div class="d-flex flex-wrap seeker-list">
<div
v-for="(seeker, index) in seekers"
:key="seeker._id"
class="seeker"
>
<div class="d-flex">
<avatar
:member="seeker"
:hideClassBadge="true"
@click.native="showMemberModal(seeker._id)"
class="mr-3 mb-2"
/>
<div class="card-data">
<user-link
:user-id="seeker._id"
:name="seeker.profile.name"
:backer="seeker.backer"
:contributor="seeker.contributor"
/>
<div class="small-with-border pb-2 mb-2">
@{{ seeker.auth.local.username }} {{ $t('level') }} {{ seeker.stats.lvl }}
</div>
<div
class="d-flex"
>
<strong v-once> {{ $t('classLabel') }} </strong>
<span
class="svg-icon d-inline-block icon-16 my-auto mx-2"
v-html="icons[seeker.stats.class]"
>
</span>
<strong
:class="`${seeker.stats.class}-color`"
>
{{ $t(seeker.stats.class) }}
</strong>
</div>
<div>
<strong v-once class="mr-2"> {{ $t('checkinsLabel') }} </strong>
{{ seeker.loginIncentives }}
</div>
<div>
<strong v-once class="mr-2"> {{ $t('languageLabel') }} </strong>
{{ displayLanguage(seeker.preferences.language) }}
</div>
</div>
</div>
<strong
v-if="!seeker.invited"
@click="inviteUser(seeker._id, index)"
class="btn btn-primary w-100"
>
{{ $t('inviteToParty') }}
</strong>
<div
v-else
@click="rescindInvite(seeker._id, index)"
class="btn btn-success w-100"
v-html="$t('invitedToYourParty')"
>
</div>
</div>
<mugen-scroll
v-show="loading"
:handler="infiniteScrollTrigger"
:should-handle="!loading && canLoadMore"
:threshold="1"
/>
</div>
</div>
<div
v-if="seekers.length === 0 && !loading"
class="d-flex flex-column empty-state text-center my-5"
>
<div class="gray-circle mb-3 mx-auto d-flex">
<div
class="svg-icon icon-32 color m-auto"
v-html="icons.users"
>
</div>
</div>
<strong class="mb-1"> {{ $t('findMorePartyMembers') }} </strong>
<div v-html="$t('noOneLooking')"></div>
</div>
</div>
<h2
v-show="loading"
class="loading"
:class="seekers.length === 0 ? 'mt-3' : 'mt-0'"
>
{{ $t('loading') }}
</h2>
</div>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
h1 {
color: $purple-300;
}
strong {
line-height: 1.71;
}
.avatar {
background-color: $gray-600;
}
.btn-success {
box-shadow: none;
color: $green-1;
font-weight: normal;
&:not(:disabled):not(.disabled):active {
color: $green-1;
}
}
.btn-sync {
min-width: 128px;
max-height: 32px;
.svg-icon {
color: $gray-200;
}
}
.card-data {
width: 267px;
}
.empty-state {
color: $gray-100;
line-height: 1.71;
}
.fit-content {
width: fit-content;
}
.gray-circle {
width: 64px;
height: 64px;
color: $gray-600;
background-color: $gray-200;
border-radius: 100px;
.icon-32 {
height: auto;
}
}
.loading {
text-align: center;
color: $purple-300;
}
.seeker-list {
max-width: 920px;
@media (max-width: 962px) {
max-width: 464px;
};
.seeker {
width: 448px;
margin-bottom: 24px;
padding: 8px;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(26, 24, 29, 0.12), 0 1px 2px 0 rgba(26, 24, 29, 0.24);
background-color: $white;
&:first-of-type {
margin-top: 24px;
}
@media (min-width: 963px) {
&:nth-child(2) {
margin-top: 24px;
}
&:nth-child(even) {
margin-left: 24px;
}
}
}
}
.small-with-border {
border-bottom: 1px solid $gray-500;
color: $gray-100;
font-size: 12px;
font-weight: normal;
line-height: 1.33;
}
.healer-color {
color: $yellow-10;
}
.rogue-color {
color: $purple-200;
}
.warrior-color {
color: $red-50;
}
.wizard-color {
color: $blue-10;
}
</style>
<script>
import debounce from 'lodash/debounce';
import MugenScroll from 'vue-mugen-scroll';
import Avatar from '../avatar';
import userLink from '../userLink';
import { mapState } from '@/libs/store';
import syncIcon from '@/assets/svg/sync-2.svg';
import usersIcon from '@/assets/svg/users.svg';
import warriorIcon from '@/assets/svg/warrior.svg';
import rogueIcon from '@/assets/svg/rogue.svg';
import healerIcon from '@/assets/svg/healer.svg';
import wizardIcon from '@/assets/svg/wizard.svg';
export default {
components: {
Avatar,
MugenScroll,
userLink,
},
data () {
return {
canLoadMore: true,
loading: true,
page: 0,
party: {},
seekers: [],
icons: Object.freeze({
warrior: warriorIcon,
rogue: rogueIcon,
healer: healerIcon,
sync: syncIcon,
users: usersIcon,
wizard: wizardIcon,
}),
};
},
computed: {
...mapState({
availableLanguages: 'i18n.availableLanguages',
user: 'user.data',
}),
},
async mounted () {
try {
this.party = await this.$store.dispatch('guilds:getGroup', { groupId: this.user.party._id });
} catch {
this.$router.push('/');
}
if (!this.party._id || this.party.leader._id !== this.user._id) {
this.$router.push('/');
} else {
this.$store.dispatch('common:setTitle', {
section: this.$t('lookingForPartyTitle'),
});
this.seekers = await this.$store.dispatch('party:lookingForParty');
this.canLoadMore = this.seekers.length === 30;
this.loading = false;
}
},
methods: {
displayLanguage (languageCode) {
const language = this.availableLanguages.find(lang => lang.code === languageCode);
if (language) {
return language.name;
}
return languageCode;
},
infiniteScrollTrigger () {
if (this.canLoadMore) {
this.loading = true;
}
this.loadMore();
},
async inviteUser (userId, index) {
await this.$store.dispatch('guilds:invite', {
invitationDetails: {
inviter: this.user.profile.name,
uuids: [userId],
},
groupId: this.party._id,
});
this.seekers[index].invited = true;
},
loadMore: debounce(async function loadMoreDebounce () {
this.page += 1;
const addlSeekers = await this.$store.dispatch('party:lookingForParty', { page: this.page });
this.seekers = this.seekers.concat(addlSeekers);
this.canLoadMore = this.seekers.length % 30 === 0;
this.loading = false;
}, 1000),
async refreshList () {
this.loading = true;
this.page = 0;
this.seekers = await this.$store.dispatch('party:lookingForParty');
this.canLoadMore = this.seekers.length === 30;
this.loading = false;
},
async rescindInvite (userId, index) {
await this.$store.dispatch('members:removeMember', {
memberId: userId,
groupId: this.party._id,
});
this.seekers[index].invited = false;
},
showMemberModal (userId) {
this.$router.push({ name: 'userProfile', params: { userId } });
},
},
};
</script>
@@ -2,7 +2,7 @@
<div class="sidebar px-4">
<div>
<div class="buttons-wrapper">
<div class="button-container button-with-menu-row">
<div class="button-container d-flex">
<button
v-if="!isMember"
class="btn btn-success btn-success"
@@ -203,10 +203,6 @@ export default {
}
}
.button-with-menu-row {
display: flex;
}
.menuIcon {
width: 4px;
height: 1rem;
+19 -6
View File
@@ -258,13 +258,22 @@
:key="hero._id"
>
<td>
<user-link
<div
v-if="hasPermission(hero, 'userSupport')"
:user="hero"
:popover="$t('gamemaster')"
popover-trigger="mouseenter"
popover-placement="right"
/>
class="width-content"
>
<user-link
:id="hero._id"
:user="hero"
/>
<b-popover
:target="hero._id"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('gamemaster')"
/>
</div>
<user-link
v-else
:user="hero"
@@ -302,6 +311,10 @@
h4.expand-toggle::after {
margin-left: 5px;
}
.width-content {
width: fit-content;
}
</style>
<script>
@@ -6,13 +6,10 @@
:style="{height}"
>
<slot name="content"></slot>
<div
<close-x
v-if="canClose"
class="close-icon svg-icon icon-12"
@click="close()"
v-html="icons.close"
></div>
@close="close()"
/>
</div>
</template>
@@ -30,32 +27,24 @@ body.modal-open .habitica-top-banner {
padding-left: 1.5rem;
padding-right: 1.625rem;
z-index: 1300;
}
.close-icon.svg-icon {
position: relative;
top: 0;
right: 0;
opacity: 0.48;
& ::v-deep svg path {
stroke: $white !important;
}
&:hover {
opacity: 0.75;
.modal-close {
position: unset;
}
}
</style>
<script>
import closeIcon from '@/assets/svg/close.svg';
import closeX from '@/components/ui/closeX';
import {
clearBannerSetting, hideBanner, isBannerHidden, updateBannerHeight,
} from '@/libs/banner.func';
import { EVENTS } from '@/libs/events';
export default {
components: {
closeX,
},
props: {
bannerId: {
type: String,
@@ -82,9 +71,6 @@ export default {
},
data () {
return {
icons: Object.freeze({
close: closeIcon,
}),
hidden: false,
};
},
@@ -119,8 +105,6 @@ export default {
close () {
hideBanner(this.bannerId);
this.hidden = true;
this.$root.$emit(EVENTS.BANNER_HIDDEN, this.bannerId);
},
},
};
@@ -0,0 +1,67 @@
<template>
<base-banner
banner-id="chat-warning"
banner-class="chat-banner"
class="chat-banner"
height="3rem"
v-if="showChatWarning"
:class="{faq: faqPage}"
>
<div
slot="content"
class="w-100 text-center"
v-html="$t('chatSunsetWarning')"
>
</div>
</base-banner>
</template>
<style lang="scss">
@import '~@/assets/scss/colors.scss';
.chat-banner {
width: 100%;
min-height: 48px;
padding: 8px;
color: $orange-1;
background-color: $orange-100;
line-height: 1.71;
a {
color: $orange-1;
text-decoration: underline;
&:hover {
color: $orange-1;
}
}
&.faq {
position: fixed;
top: 3.5rem;
}
}
</style>
<script>
import BaseBanner from './base';
export default {
components: {
BaseBanner,
},
computed: {
faqPage () {
return (this.$route.fullPath.indexOf('/faq')) !== -1;
},
showChatWarning () {
if (this.$route.fullPath.indexOf('/groups') !== -1) return true;
if (this.$route.fullPath.indexOf('/tavern-and-guilds') !== -1) return false;
if (this.$route.fullPath.indexOf('/tavern') !== -1) return true;
return this.faqPage;
},
},
};
</script>
+21 -6
View File
@@ -51,20 +51,20 @@
</div>
<div
v-else
class="no-party d-none d-md-flex justify-content-center text-center mr-4"
class="no-party d-none d-md-flex justify-content-center text-center mr-4"
>
<div class="align-self-center">
<h3>{{ $t('battleWithFriends') }}</h3>
<h3>{{ user.party._id ? $t('questWithOthers') : $t('battleWithFriends') }}</h3>
<span
class="small-text"
v-html="$t('inviteFriendsParty')"
v-html="user.party._id ? $t('inviteFriendsParty') : $t('startPartyDetail')"
></span>
<br>
<button
class="btn btn-primary"
@click="createOrInviteParty()"
>
{{ user.party._id ? $t('inviteFriends') : $t('startAParty') }}
{{ user.party._id ? $t('findPartyMembers') : $t('getStarted') }}
</button>
</div>
</div>
@@ -122,6 +122,7 @@
<script>
import orderBy from 'lodash/orderBy';
import * as Analytics from '@/libs/analytics';
import { mapGetters, mapActions } from '@/libs/store';
import MemberDetails from '../memberDetails';
import createPartyModal from '../groups/createPartyModal';
@@ -232,10 +233,24 @@ export default {
this.expandedMember = memberId;
}
},
createOrInviteParty () {
async createOrInviteParty () {
if (this.user.party._id) {
this.$root.$emit('inviteModal::inviteToGroup', this.user.party);
await Analytics.track({
eventName: 'Header Party CTA',
eventAction: 'Header Party CTA',
eventCategory: 'behavior',
hitType: 'event',
state: 'Find Party Members',
});
this.$router.push('/looking-for-party');
} else {
await Analytics.track({
eventName: 'Header Party CTA',
eventAction: 'Header Party CTA',
eventCategory: 'behavior',
hitType: 'event',
state: 'Get Started',
});
this.$root.$emit('bv::show::modal', 'create-party-modal');
}
},
+49 -6
View File
@@ -148,7 +148,7 @@
</div>
</li>
<b-nav-item
v-if="user.party._id"
v-if="user.party._id && user._id !== partyLeaderId"
class="topbar-item"
:class="{'active': $route.path.startsWith('/party')}"
tag="li"
@@ -156,6 +156,36 @@
>
{{ $t('party') }}
</b-nav-item>
<li
v-if="user.party._id && user._id === partyLeaderId"
class="topbar-item droppable"
:class="{'active': $route.path.startsWith('/party')}"
>
<div
class="chevron rotate"
@click="dropdownMobile($event)"
>
<div
v-once
class="chevron-icon-down"
v-html="icons.chevronDown"
></div>
</div>
<router-link
class="nav-link"
:to="{name: 'party'}"
>
{{ $t('party') }}
</router-link>
<div class="topbar-dropdown">
<router-link
class="topbar-dropdown-item dropdown-item"
:to="{name: 'lookingForParty'}"
>
{{ $t('lookingForPartyTitle') }}
</router-link>
</div>
</li>
<b-nav-item
v-if="!user.party._id"
class="topbar-item"
@@ -768,6 +798,7 @@ export default {
return {
isUserDropdownOpen: false,
menuIsOpen: false,
partyLeaderId: null,
icons: Object.freeze({
gem: gemIcon,
gold: goldIcon,
@@ -796,15 +827,21 @@ export default {
};
},
},
mounted () {
this.getUserGroupPlans();
Array.from(document.getElementById('menu_collapse').getElementsByTagName('a')).forEach(link => {
link.addEventListener('click', this.closeMenu);
});
async mounted () {
await this.getUserGroupPlans();
await this.getUserParty();
if (document.getElementById('menu_collapse')) {
Array.from(document.getElementById('menu_collapse').getElementsByTagName('a')).forEach(link => {
link.addEventListener('click', this.closeMenu);
});
}
Array.from(document.getElementsByClassName('topbar-item')).forEach(link => {
link.addEventListener('mouseenter', this.dropdownDesktop);
link.addEventListener('mouseleave', this.dropdownDesktop);
});
this.$root.$on('update-party', () => {
this.getUserParty();
});
},
methods: {
modForm () {
@@ -816,6 +853,12 @@ export default {
async getUserGroupPlans () {
await this.$store.dispatch('guilds:getGroupPlans');
},
async getUserParty () {
if (this.user.party._id) {
await this.$store.dispatch('party:getParty');
this.partyLeaderId = this.$store.state.party.data.leader._id;
}
},
openPartyModal () {
this.$root.$emit('bv::show::modal', 'create-party-modal');
},
@@ -44,13 +44,13 @@ export default {
if (!this.notification || !this.notification.data) {
return;
}
if (this.notification.data.destination === 'backgrounds') {
if (this.notification.data.destination.indexOf('backgrounds') !== -1) {
this.$store.state.avatarEditorOptions.editingUser = true;
this.$store.state.avatarEditorOptions.startingPage = 'backgrounds';
this.$store.state.avatarEditorOptions.subpage = '2023';
this.$root.$emit('bv::show::modal', 'avatar-modal');
} else {
this.$router.push({ name: this.notification.data.destination || 'items' });
this.$router.push(this.notification.data.destination || '/inventory/items');
}
},
},
@@ -34,11 +34,13 @@
<script>
import BaseNotification from './base';
import { mapState } from '@/libs/store';
import sync from '@/mixins/sync';
export default {
components: {
BaseNotification,
},
mixins: [sync],
props: {
notification: {
type: Object,
@@ -73,6 +75,7 @@ export default {
}
await this.$store.dispatch('guilds:join', { groupId: group.id, type: 'party' });
this.sync();
this.$router.push('/party');
},
reject () {
@@ -126,7 +126,7 @@
<!-- the word "total" -->
<div class="buy-gem-total">
{{ $t('sendGiftTotal') }}
{{ $t('sendTotal') }}
</div>
<!-- the actual dollar amount -->
+46 -38
View File
@@ -128,7 +128,10 @@
<hr>
</div>
<div>
<div class="checkbox">
<div
class="checkbox"
id="preferenceAdvancedCollapsed"
>
<label>
<input
v-model="user.preferences.advancedCollapsed"
@@ -136,33 +139,22 @@
class="mr-2"
@change="set('advancedCollapsed')"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('startAdvCollapsedPop')"
>{{ $t('startAdvCollapsed') }}</span>
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="user.preferences.dailyDueDefaultView"
type="checkbox"
class="mr-2"
@change="set('dailyDueDefaultView')"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('dailyDueDefaultViewPop')"
>{{ $t('dailyDueDefaultView') }}</span>
<span class="hint">
{{ $t('startAdvCollapsed') }}
</span>
<b-popover
target="preferenceAdvancedCollapsed"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('startAdvCollapsedPop')"
/>
</label>
</div>
<div
v-if="party.memberCount === 1"
class="checkbox"
id="preferenceDisplayInviteAtOneMember"
>
<label>
<input
@@ -171,12 +163,9 @@
class="mr-2"
@change="set('displayInviteToPartyWhenPartyIs1')"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('displayInviteToPartyWhenPartyIs1')"
>{{ $t('displayInviteToPartyWhenPartyIs1') }}</span>
<span class="hint">
{{ $t('displayInviteToPartyWhenPartyIs1') }}
</span>
</label>
</div>
<div class="checkbox">
@@ -217,32 +206,47 @@
</div>
<hr>
<button
id="buttonShowBailey"
class="btn btn-primary mr-2 mb-2"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('showBaileyPop')"
@click="showBailey()"
>
{{ $t('showBailey') }}
<b-popover
target="buttonShowBailey"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('showBaileyPop')"
/>
</button>
<button
id="buttonFCV"
class="btn btn-primary mr-2 mb-2"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('fixValPop')"
@click="openRestoreModal()"
>
{{ $t('fixVal') }}
<b-popover
target="buttonFCV"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('fixValPop')"
/>
</button>
<button
v-if="user.preferences.disableClasses == true"
id="buttonEnableClasses"
class="btn btn-primary mb-2"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('enableClassPop')"
@click="changeClassForUser(false)"
>
{{ $t('enableClass') }}
<b-popover
target="buttonEnableClasses"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('enableClassPop')"
/>
</button>
<hr>
<day-start-adjustment />
@@ -532,6 +536,10 @@
input {
color: $gray-50;
}
.checkbox {
width: fit-content;
}
.usersettings h5 {
margin-top: 1em;
}
@@ -0,0 +1,93 @@
<template>
<div class="item-cost">
<span
class="cost"
:class="getPriceClass()"
>
<span
class="svg-icon inline icon-24"
aria-hidden="true"
v-html="icons[getPriceClass()]"
>
</span>
<span
:class="getPriceClass()"
>{{ item.value }}</span>
</span>
</div>
</template>
<style lang="scss">
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/mixins.scss';
.item-cost {
padding-bottom: 16px;
}
.cost {
height: 40px;
font-size: 1.25rem;
font-weight: bold;
line-height: 1.4;
vertical-align: middle;
&.gems {
color: $gems-color;
border-radius: 20px;
padding: 8px 20px 8px 20px;
margin-top: 16px;
margin-bottom: 16px;
background-color: rgba(36, 204, 143, 0.15);
}
&.gold {
color: $gold-color;
border-radius: 20px;
padding: 8px 20px 8px 20px;
margin-top: 16px;
margin-bottom: 16px;
background-color: rgba(255, 190, 93, 0.15);
}
&.hourglasses {
color: $hourglass-color;
border-radius: 20px;
padding: 8px 20px 8px 20px;
margin-top: 16px;
margin-bottom: 16px;
background-color: rgba(41, 149, 205, 0.15);
}
}
</style>
<script>
import svgClose from '@/assets/svg/close.svg';
import svgGold from '@/assets/svg/gold.svg';
import svgGem from '@/assets/svg/gem.svg';
export default {
data () {
return {
icons: Object.freeze({
close: svgClose,
gold: svgGold,
gems: svgGem,
}),
selectedAmountToBuy: 1,
selectedAmount: 1,
};
},
methods: {
getPriceClass () {
if (this.priceType && this.icons[this.priceType]) {
return this.priceType;
} if (this.item.currency && this.icons[this.item.currency]) {
return this.item.currency;
}
return 'gold';
},
},
};
</script>
@@ -0,0 +1,137 @@
<template>
<div class="d-flex flex-row align-items-center justify-content-center number-increment">
<!-- buy modal -->
<div
class="gray-circle"
@click="quantity <= 0
? quantity = 0
: quantity--"
>
<div
class="icon-negative"
v-html="icons.svgNegative"
></div>
</div>
<div class="input-group">
<div class="align-items-center">
</div>
<input
v-model="quantity"
class="form-control alignment"
step="1"
type="number"
>
</div>
<div
class="gray-circle"
@click="quantity++"
>
<div
class="icon-positive"
v-html="icons.svgPositive"
></div>
</div>
</div>
</template>
<style scoped lang="scss">
@import '~@/assets/scss/colors.scss';
.number-increment {
padding-bottom: 0px;
}
.alignment {
text-align: center;
}
.input-group {
width: 94px;
height: 32px;
width: 48px;
margin: 0px 16px 0px 16px;
padding: 0;
border-radius: 2px;
border: solid 1px $gray-400;
background-color: $white;
}
.gray-circle {
border-radius: 100%;
border: solid 2px $gray-300;
width: 32px;
height: 32px;
cursor: pointer;
&:hover {
border-color: $purple-300;
}
}
.gray-circle:hover{
.icon-positive, .icon-negative {
& ::v-deep svg path {
fill: $purple-300;
}
}
}
.icon-positive, .icon-negative {
width: 10px;
height: 10px;
margin: 4px auto;
& ::v-deep svg path {
fill: $gray-300;
}
}
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
</style>
<script>
// icons
import svgGem from '@/assets/svg/gem.svg';
import svgGold from '@/assets/svg/gold.svg';
import svgPositive from '@/assets/svg/positive.svg';
import svgNegative from '@/assets/svg/negative.svg';
export default {
data () {
return {
icons: Object.freeze({
svgGem,
svgGold,
svgPositive,
svgNegative,
}),
item: { },
quantity: 1,
};
},
computed: {
},
watch: {
quantity () {
this.$emit('updateQuantity', this.quantity);
},
},
methods: {
setDefaults () {
this.input = 1;
},
},
};
</script>
@@ -22,10 +22,11 @@
@import '~@/assets/scss/colors.scss';
span {
font-weight: normal;
font-size: 12px;
font-size: 0.75rem;
line-height: 1.33;
color: $gray-200;
color: $gray-100;
margin-bottom: 16px;
margin-top: -4px;
display: inline-block;
}
+363 -102
View File
@@ -17,7 +17,7 @@
</span>
<div>
<span
class="svg-icon icon-12 close-icon"
class="svg-icon close-icon icon-16 color"
aria-hidden="true"
tabindex="0"
@click="hideDialog()"
@@ -45,6 +45,13 @@
:sprites-margin="'0px auto 0px -24px'"
/>
</div>
<item
v-else-if="item.key === 'gem'"
class="flat bordered-item"
:item="item"
:item-content-class="item.class"
:show-popover="false"
/>
<item
v-else-if="item.key != 'gem'"
class="flat bordered-item"
@@ -53,10 +60,20 @@
:show-popover="false"
/>
</slot>
<div
v-if="!showAvatar && user.items[item.purchaseType]"
class="owned"
:class="totalOwned"
>
<!-- eslint-disable-next-line max-len -->
<span class="owned-text">{{ $t('owned') }}: <span class="user-amount">{{ totalOwned }}</span></span>
</div>
<h4 class="title">
{{ itemText }}
</h4>
<div v-html="itemNotes"></div>
<div class="item-notes">
{{ itemNotes }}
</div>
<slot
name="additionalInfo"
:item="item"
@@ -69,60 +86,61 @@
/>
</slot>
<div
v-if="item.value > 0"
v-if="item.value > 0 && !(item.key === 'gem' && gemsLeft < 1)"
class="purchase-amount"
>
<div
v-if="showAmountToBuy(item)"
class="how-many-to-buy"
>
<strong>{{ $t('howManyToBuy') }}</strong>
</div>
<div v-if="showAmountToBuy(item)">
<div class="box">
<input
v-model.number="selectedAmountToBuy"
class="form-control"
type="number"
min="0"
step="1"
>
</div>
<span :class="{'notEnough': notEnoughCurrency}">
<!-- this is where the pretty item cost element lives -->
<div class="item-cost">
<span
class="cost"
:class="getPriceClass()"
>
<span
class="svg-icon inline icon-32"
class="svg-icon inline icon-24"
aria-hidden="true"
v-html="icons[getPriceClass()]"
></span>
>
</span>
<span
class="cost"
:class="getPriceClass()"
>{{ item.value }}</span>
</span>
</div>
<div
v-else
class="d-flex align-items-middle"
v-if="showAmountToBuy(item)"
class="how-many-to-buy"
>
<span
class="svg-icon inline icon-32 ml-auto my-auto"
aria-hidden="true"
v-html="icons[getPriceClass()]"
></span>
<span
class="cost mr-auto my-auto"
:class="getPriceClass()"
>{{ item.value }}</span>
{{ $t('howManyToBuy') }}
</div>
<div
v-if="showAmountToBuy(item)"
>
<number-increment
class="number-increment"
@updateQuantity="selectedAmountToBuy = $event"
/>
<div
:class="{'notEnough': notEnoughCurrency}"
class="total"
>
<span class="total-text">{{ $t('sendTotal') }}</span>
<span
class="svg-icon total icon-24"
aria-hidden="true"
v-html="icons[getPriceClass()]"
></span>
<span
class="total-text"
:class="getPriceClass()"
>{{ item.value * selectedAmountToBuy }}</span>
</div>
</div>
</div>
<div
v-if="item.key === 'gem'"
class="gems-left"
v-if="item.key === 'gem' && gemsLeft < 1"
class="no-more-gems"
>
<strong v-if="gemsLeft > 0">{{ gemsLeft }} {{ $t('gemsRemaining') }}</strong>
<strong v-if="gemsLeft === 0">{{ $t('maxBuyGems') }}</strong>
</div>
<div v-if="attemptingToPurchaseMoreGemsThanAreLeft">
{{ $t('notEnoughGemsToBuy') }}
</div>
<div
@@ -147,7 +165,7 @@
{{ $t('viewSubscriptions') }}
</button>
<button
v-else
v-else-if="!(item.key === 'gem' && gemsLeft < 1)"
class="btn btn-primary"
:disabled="item.key === 'gem' && gemsLeft === 0 ||
attemptingToPurchaseMoreGemsThanAreLeft || numberInvalid || item.locked ||
@@ -165,6 +183,7 @@
<countdown-banner
v-if="item.event && item.owned == null"
:end-date="endDate"
class="limitedTime available"
/>
<div
v-if="item.key === 'rebirth_orb' && item.value > 0 && user.stats.lvl >= 100"
@@ -179,12 +198,31 @@
</div>
</div>
<div
slot="modal-footer"
class="d-flex"
v-if="item.key === 'gem'"
class="d-flex justify-content-center align-items-center"
>
<span class="balance mr-auto">{{ $t('yourBalance') }}</span>
<div
v-if="gemsLeft > 0"
class="gems-left d-flex justify-content-center align-items-center"
>
<strong>{{ $t('monthlyGems') }} &nbsp;</strong>
{{ gemsLeft }} / {{ totalGems }} {{ $t('gemsRemaining') }}
</div>
<div
v-if="gemsLeft === 0"
class="out-of-gems-banner d-flex justify-content-center align-items-center"
>
<strong>{{ $t('monthlyGems') }} &nbsp;</strong>
{{ gemsLeft }} / {{ totalGems }} {{ $t('gemsRemaining') }}
</div>
</div>
<div
slot="modal-footer"
class="clearfix"
>
<span class="user-balance float-left">{{ $t('yourBalance') }}</span>
<balanceInfo
class="ml-auto"
class="currency-totals"
:currency-needed="getPriceClass()"
:amount-needed="item.value"
/>
@@ -200,11 +238,47 @@
@include centeredModal();
.modal-body {
padding-left: 0px;
padding-right: 0px;
padding-bottom: 0px;
}
.modal-footer {
height: 48px;
background-color: $gray-700;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
display: block;
margin: 24px 0 0 0;
padding: 16px 24px;
align-content: center;
.user-balance {
width: 150px;
height: 16px;
font-size: 0.75rem;
font-weight: bold;
line-height: 1.33;
color: $gray-100;
margin-bottom: 16px;
margin-top: -4px;
margin-left: -4px;
}
.currency-totals {
margin-right: -8px;
float: right;
}
}
.modal-dialog {
width: 330px;
width: 448px;
box-sizing: border-box;
}
.badge-dialog {
left: -8px;
top: -8px;
}
.avatar {
@@ -212,8 +286,71 @@
margin: 0 auto;
}
.owned {
height: 32px;
width: 141px;
margin-top: -36px;
margin-left: 153px;
padding-top: 6px;
background-color: $gray-600;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
display: block;
text-align: center;
position: relative;
z-index: 1;
.owned-text {
font-size: 0.75rem;
font-weight: bold;
line-height: 1.71;
}
.user-amount {
font-weight: normal !important;
}
}
.item {
width: 141px;
height: 147px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
cursor: default;
}
.item-content {
transform: scale(1.45, 1.45);
top: -25.67px;
left: 1px;
&.shop_gem {
transform: scale(1.45, 1.45);
top: -2px;
left: 0px;
}
}
.title {
height: 28px;
color: $gray-10;
font-size: 1.25rem;
margin-top: 25px;
}
.item-notes {
margin-top: 8px;
padding-left: 48.5px;
padding-right: 48.5px;
line-height: 1.71;
font-size: 0.875rem;
}
.content {
text-align: center;
width: 448px;
}
.item-wrapper {
@@ -221,15 +358,22 @@
}
.inner-content {
margin: 33px auto auto;
width: 282px;
margin: 32px auto auto;
}
.btn-primary {
margin-top: 16px;
}
.purchase-amount {
margin-top: 24px;
margin-top: 0px;
.how-many-to-buy {
margin-bottom: 16px;
font-weight: bold !important;
}
.number-increment {
margin-top: 16px;
}
.box {
@@ -255,31 +399,105 @@
}
}
}
.no-more-gems {
color: $yellow-5;
font-size: 0.875em;
line-height: 1.33;
margin: 16px 48px 0 48px;
}
span.svg-icon.inline.icon-32 {
height: 32px;
width: 32px;
// for cost icon of a single item
span.svg-icon.inline.icon-24 {
display: inline-block;
height: 24px;
width: 24px;
margin-right: 4px;
padding-top: 4px;
}
// for the total user cost
span.svg-icon.total.icon-24 {
display: inline-block;
height: 24px;
width: 24px;
margin-left: 6px;
margin-right: 8px;
padding-top: 6px;
}
vertical-align: middle;
span.svg-icon.icon-16 {
height: 16px;
width: 16px;
}
.close-icon {
color: $gray-200;
stroke-width: 0px;
&:hover {
color: $gray-100;
}
}
.attributes-group {
margin: 32px;
border-radius: 4px;
line-height: 1.71;
font-size: 0.875;
}
.attributesGrid {
margin-top: 28px;
border-radius: 2px;
background-color: $gray-500;
}
.item-cost {
display: inline-flex;
margin: 16px 0;
align-items: center;
height: 40px;
}
.cost {
width: 28px;
height: 32px;
font-size: 24px;
display: inline-block;
font-family: sans-serif;
font-size: 1.25rem;
font-weight: bold;
line-height: 1.33;
vertical-align: middle;
padding: 6px 20px;
line-height: 1.4;
border-radius: 20px;
&.gems {
color: $gems-color;
color: $green-10;
background-color: rgba(36, 204, 143, 0.15);
align-items: center;
}
&.gold {
color: $gold-color;
color: $yellow-5;
background-color: rgba(255, 190, 93, 0.15);
align-items: center;
}
&.hourglasses {
color: $hourglass-color;
background-color: rgba(41, 149, 205, 0.15);
align-items: center;
}
}
.total {
font-weight: bold;
font-size: 0.875rem;
padding-top: 2px;
margin-top: 4px;
&.gems {
color: $green-10;
}
&.gold {
color: $yellow-5;
}
&.hourglasses {
@@ -287,62 +505,84 @@
}
}
.total-text {
color: $gray-50;
font-weight: bold;
font-size: 0.875rem;
line-height: 1.71;
&.gems {
color: $green-10;
}
&.gold {
color: $yellow-5;
}
&.hourglasses {
color: $hourglass-color;
}
}
button.btn.btn-primary {
margin-top: 24px;
margin-bottom: 24px;
min-width: 6rem;
margin-top: 16px;
padding: 4px 16px;
height: 32px;
&:focus {
border: 2px solid black;
}
}
.balance {
width: 74px;
height: 16px;
font-size: 12px;
font-weight: bold;
line-height: 1.33;
color: $gray-200;
}
.notEnough {
pointer-events: none;
opacity: 0.55;
}
.modal-footer {
height: 48px;
background-color: $gray-700;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
display: block;
}
.free-rebirth {
background-color: $yellow-5;
color: $white;
height: 2rem;
line-height: 16px;
margin: auto -1rem -1rem;
}
.notEnough {
pointer-events: none;
opacity: 0.55;
}
// .pt-015 {
// padding-top: 0.15rem;
// }
.attributesGrid {
margin-top: 8px;
border-radius: 2px;
background-color: $gray-500;
margin: 10px 0 24px;
}
.gems-left {
margin-top: .5em;
height: 32px;
background-color: $green-100;
font-size: 0.75rem;
margin-top: 24px;
color: $green-1;
width: 100%;
margin-bottom: -24px;
}
.free-rebirth {
background-color: $yellow-5;
.out-of-gems-banner {
height: 32px;
font-size: 0.75rem;
margin-top: 24px;
background-color: $yellow-100;
color: $yellow-1;
width: 100%;
margin-bottom: -24px;
}
.limitedTime {
height: 32px;
width: 446px;
font-size: 0.75rem;
margin: 24px 0 0 0;
background-color: $purple-300;
color: $white;
height: 2rem;
line-height: 16px;
margin: auto -1rem -1rem;
}
.pt-015 {
padding-top: 0.15rem;
margin-bottom: -24px;
}
}
</style>
<style lang="scss" scoped>
@@ -370,6 +610,8 @@ import svgGem from '@/assets/svg/gem.svg';
import svgHourglasses from '@/assets/svg/hourglass.svg';
import svgClock from '@/assets/svg/clock.svg';
import svgWhiteClock from '@/assets/svg/clock-white.svg';
import svgPositive from '@/assets/svg/positive.svg';
import svgNegative from '@/assets/svg/negative.svg';
import BalanceInfo from './balanceInfo.vue';
import PinBadge from '@/components/ui/pinBadge';
@@ -377,6 +619,7 @@ import CountdownBanner from './countdownBanner';
import currencyMixin from './_currencyMixin';
import notifications from '@/mixins/notifications';
import buyMixin from '@/mixins/buy';
import numberIncrement from '@/components/shared/numberIncrement';
import { mapState } from '@/libs/store';
@@ -407,14 +650,17 @@ export default {
Avatar,
PinBadge,
CountdownBanner,
numberIncrement,
},
mixins: [buyMixin, currencyMixin, notifications, numberInvalid, spellsMixin],
props: {
// eslint-disable-next-line vue/require-default-prop
item: {
type: Object,
},
priceType: {
type: String,
default: '',
},
withPin: {
type: Boolean,
@@ -433,10 +679,14 @@ export default {
hourglasses: svgHourglasses,
clock: svgClock,
whiteClock: svgWhiteClock,
positive: svgPositive,
negative: svgNegative,
}),
selectedAmountToBuy: 1,
selectedAmount: 1,
isPinned: false,
quantity: 1,
};
},
computed: {
@@ -474,6 +724,11 @@ export default {
return planGemLimits.convCap
+ this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
},
totalGems () {
if (!this.user.purchased.plan) return 0;
return planGemLimits.convCap
+ this.user.purchased.plan.consecutive.gemCapExtra;
},
attemptingToPurchaseMoreGemsThanAreLeft () {
if (this.item && this.item.key && this.item.key === 'gem' && this.selectedAmountToBuy > this.gemsLeft) return true;
return false;
@@ -490,6 +745,9 @@ export default {
endDate () {
return moment(this.item.event.end);
},
totalOwned () {
return this.user.items[this.item.purchaseType][this.item.key] || 0;
},
},
watch: {
item: function itemChanged () {
@@ -500,7 +758,9 @@ export default {
methods: {
onChange ($event) {
this.$emit('change', $event);
this.selectedAmountToBuy = 1;
},
buyItem () {
// @TODO: I think we should buying to the items.
// Turn the items into classes, and use polymorphism
@@ -597,6 +857,7 @@ export default {
}
},
hideDialog () {
this.selectedAmountToBuy = 1;
this.$root.$emit('bv::hide::modal', 'buy-modal');
},
getPriceClass () {
@@ -16,9 +16,6 @@
.limitedTime {
height: 32px;
width: calc(100% + 30px);
margin: 0 -15px; // the modal content has its own padding
font-size: 12px;
line-height: 1.33;
text-align: center;
@@ -4,9 +4,9 @@
:hide-header="true"
@change="onChange($event)"
>
<div class="close">
<div>
<span
class="svg-icon inline icon-10"
class="svg-icon close-icon icon-16 color"
aria-hidden="true"
@click="hideDialog()"
v-html="icons.close"
@@ -14,60 +14,73 @@
</div>
<div
v-if="item"
class="content"
class="content bordered-item"
>
<div class="inner-content">
<item
class="flat"
class="flat bordered-item"
:item="item"
:item-content-class="itemContextToSell.itemClass"
:show-popover="false"
>
<countBadge
slot="itemBadge"
:show="true"
:count="itemContextToSell.itemCount"
/>
</item>
/>
<span class="owned">
{{ $t('owned') }}: <span class="user-amount">{{ itemContextToSell.itemCount }}</span>
</span>
<h4 class="title">
{{ itemContextToSell.itemName }}
</h4>
<div v-if="item.key === 'Saddle'">
<div class="text">
<div class="item-notes">
{{ item.sellWarningNote() }}
</div>
<br>
</div>
<div v-else>
<div>
<div class="text">
<div class="item-notes">
{{ item.notes() }}
</div>
<div>
<b class="how-many-to-sell">{{ $t('howManyToSell') }}</b>
<div class="item-cost">
<span class="cost gold">
<span
class="svg-icon inline icon-24"
aria-hidden="true"
v-html="icons.gold"
></span>
<span>{{ item.value }}</span>
</span>
</div>
<div>
<b-input
v-model="selectedAmountToSell"
class="itemsToSell"
type="number"
:max="itemContextToSell.itemCount"
min="1"
step="1"
@keyup.native="preventNegative($event)"
/>
<span
class="svg-icon inline icon-32"
class="how-many-to-sell"
>
{{ $t('howManyToSell') }}
</span>
</div>
<div>
<number-increment
@updateQuantity="selectedAmountToSell = $event"
/>
</div>
<div class="total-row">
<span class="total-text">
{{ $t('sendTotal') }}
</span>
<span
class="svg-icon total icon-24"
aria-hidden="true"
v-html="icons.gold"
></span>
<span class="value">{{ item.value }}</span>
<span class="total-text gold">
{{ item.value * selectedAmountToSell }}
</span>
</div>
<button
class="btn btn-primary"
:disabled="selectedAmountToSell > itemContextToSell.itemCount"
@click="sellItems()"
>
{{ $t('sell') }}
{{ $t('sellItems') }}
</button>
</div>
</div>
@@ -77,8 +90,10 @@
slot="modal-footer"
class="clearfix"
>
<span class="balance float-left">{{ $t('yourBalance') }}</span>
<balanceInfo class="float-right" />
<span class="user-balance float-left">{{ $t('yourBalance') }}</span>
<balanceInfo
class="float-right currency-totals"
/>
</div>
</b-modal>
</template>
@@ -95,51 +110,13 @@
}
.modal-dialog {
width: 330px;
width: 448px;
}
.content {
text-align: center;
}
.inner-content {
margin: 33px auto auto;
width: 282px;
}
span.svg-icon.inline.icon-32 {
height: 32px;
width: 32px;
margin-left: 24px;
margin-right: 8px;
vertical-align: middle;
}
.value {
width: 28px;
height: 32px;
font-size: 24px;
font-weight: bold;
line-height: 1.33;
color: #df911e;
vertical-align: middle;
}
button.btn.btn-primary {
margin-top: 24px;
margin-bottom: 24px;
}
.balance {
width: 74px;
height: 16px;
font-size: 12px;
font-weight: bold;
line-height: 1.33;
color: $gray-200;
.modal-body {
padding-left: 0px;
padding-right: 0px;
padding-bottom: 0px;
}
.modal-footer {
@@ -148,29 +125,215 @@
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
display: block;
margin: 24px 0 0;
padding: 16px 24px;
align-content: center;
.user-balance {
width: 150px;
height: 16px;
font-size: 0.75rem;
font-weight: bold;
line-height: 1.33;
color: $gray-100;
margin-bottom: 16px;
margin-top: -4px;
margin-left: -4px;
}
.currency-totals {
margin-right: -8px;
float: right;
}
}
.how-many-to-sell {
margin-bottom: 16px;
.content {
text-align: center;
}
.inner-content {
margin: 33px auto auto;
width: 282px;
}
.owned {
font-size: 0.75rem;
font-weight: bold;
line-height: 1.33;
background-color: $gray-600;
padding: 8px 8px;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
display: block;
width: 141px;
margin-left: 71px;
margin-top: -48px;
position: relative;
z-index: 1;
.user-amount {
font-weight: normal !important;
}
}
.item-wrapper {
margin-top: -10px;
}
.item {
width: 141px;
height: 147px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
cursor: default;
margin-top: 8px;
}
.item-content {
transform: scale(1.45, 1.45);
top: -25px;
left: 1px;
}
.title {
color: $gray-10;
font-size: 1.25rem;
margin-top: 26px;
margin-bottom: 0px;
}
.item-notes {
margin-top: 12px;
line-height: 1.71;
font-size: 0.875rem;
}
// for cost icon of a single item
span.svg-icon.inline.icon-24 {
display: inline-block;
height: 24px;
width: 24px;
margin-right: 4px;
padding-top: 4px;
}
// for the total user cost
span.svg-icon.total.icon-24 {
display: inline-block;
height: 24px;
width: 24px;
margin-left: 6px;
margin-right: 8px;
padding-top: 6px;
}
span.svg-icon.icon-16 {
height: 16px;
width: 16px;
}
.close-icon {
color: $gray-200;
stroke-width: 0px;
cursor: pointer;
&:hover {
color: $gray-100;
}
}
.item-cost {
display: inline-flex;
margin: 16px 0;
align-items: center;
height: 40px;
}
.cost {
display: inline-block;
font-family: sans-serif;
font-size: 1.25rem;
font-weight: bold;
padding: 6px 20px;
line-height: 1.4;
border-radius: 20px;
&.gold {
color: $yellow-5;
background-color: rgba(255, 190, 93, 0.15);
align-items: center;
}
}
}
.how-many-to-sell {
font-weight: bold !important;
}
.number-increment {
margin-top: 16px;
}
.total-row {
font-weight: bold;
font-size: 0.875rem;
margin-top: 16px;
&.gold {
color: $yellow-5;
}
}
.total-text {
color: $gray-50;
font-weight: bold;
font-size: 0.875rem;
line-height: 1.71;
&.gold {
color: $yellow-5;
}
}
button.btn.btn-primary {
margin-top: 16px;
padding: 4px 16px;
height: 32px;
&:focus {
border: 2px solid black;
}
.balance {
width: 74px;
height: 16px;
font-size: 12px;
font-weight: bold;
line-height: 1.33;
color: $gray-200;
}
}
</style>
<script>
import svgClose from '@/assets/svg/close.svg';
import svgGold from '@/assets/svg/gold.svg';
import svgGem from '@/assets/svg/gem.svg';
import svgPositive from '@/assets/svg/positive.svg';
import svgNegative from '@/assets/svg/negative.svg';
import BalanceInfo from '../balanceInfo.vue';
import Item from '@/components/inventory/item';
import CountBadge from '@/components/ui/countBadge';
import numberIncrement from '@/components/shared/numberIncrement';
export default {
components: {
BalanceInfo,
Item,
CountBadge,
numberIncrement,
},
data () {
return {
@@ -181,6 +344,8 @@ export default {
close: svgClose,
gold: svgGold,
gem: svgGem,
svgPositive,
svgNegative,
}),
};
},
@@ -211,6 +376,10 @@ export default {
this.selectedAmountToSell = 0;
}
},
maxOwned () {
const maxOwned = this.itemContextToSell.itemCount;
return maxOwned;
},
sellItems () {
if (!Number.isInteger(Number(this.selectedAmountToSell))) {
this.selectedAmountToSell = 0;
@@ -33,6 +33,22 @@
v-if="!item.locked"
class="purchase-amount"
>
<div class="item-cost">
<span
class="cost"
:class="priceType"
>
<span
class="svg-icon inline icon-24"
aria-hidden="true"
v-html="icons[priceType]"
>
</span>
<span
:class="priceType"
>{{ item.value }}</span>
</span>
</div>
<div class="how-many-to-buy">
<strong>{{ $t('howManyToBuy') }}</strong>
</div>
@@ -42,24 +58,25 @@
>
{{ item.addlNotes }}
</div>
<div class="box">
<input
v-model.number="selectedAmountToBuy"
class="form-control"
type="number"
min="0"
step="1"
>
<div>
<number-increment
@updateQuantity="selectedAmountToBuy = $event"
/>
</div>
<div class="total-row">
<span class="total-text">
{{ $t('sendTotal') }}
</span>
<span
class="svg-icon inline icon-20"
aria-hidden="true"
v-html="currencyIcon"
></span>
<span
class="total"
:class="priceType"
>{{ item.value * selectedAmountToBuy }}</span>
</div>
<span
class="svg-icon inline icon-32"
aria-hidden="true"
v-html="currencyIcon"
></span>
<span
class="value"
:class="priceType"
>{{ item.value }}</span>
</div>
<button
v-if="priceType === 'gems'
@@ -72,7 +89,7 @@
</button>
<button
v-else
class="btn btn-primary"
class="btn btn-primary mb-4"
:class="{'notEnough': !enoughCurrency(priceType, item.value * selectedAmountToBuy)}"
:disabled="numberInvalid"
@click="buyItem()"
@@ -112,6 +129,39 @@
margin-top: 1rem;
}
.modal-body {
padding-left: 0px;
padding-right: 0px;
padding-bottom: 0px;
}
.modal-footer {
height: 48px;
background-color: $gray-700;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
display: block;
padding: 16px 24px;
align-content: center;
.user-balance {
width: 150px;
height: 16px;
font-size: 0.75rem;
font-weight: bold;
line-height: 1.33;
color: $gray-100;
margin-bottom: 16px;
margin-top: -4px;
margin-left: -4px;
}
.currency-totals {
margin-right: -8px;
float: right;
}
}
.modal-dialog {
margin-top: 8%;
width: 448px !important;
@@ -129,8 +179,13 @@
margin: 33px auto auto;
}
.modal-body {
padding-bottom: 0px;
.item-notes {
height: 48px;
margin-top: 8px;
padding-left: 48.5px;
padding-right: 48.5px;
line-height: 1.71;
font-size: 0.875rem;
}
.questInfo {
@@ -152,16 +207,14 @@
height: 100%;
}
span.svg-icon.inline.icon-32 {
height: 32px;
width: 32px;
margin-right: 8px;
vertical-align: middle;
}
button.btn.btn-primary {
margin-top: 24px;
margin-bottom: 24px;
margin-top: 14px;
padding: 4px 16px;
height: 32px;
&:focus {
border: 2px solid black;
}
}
.balance {
@@ -173,19 +226,6 @@
color: $gray-200;
}
.modal-footer {
height: 48px;
background-color: $gray-700;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
display: block;
padding: 1rem 1.5rem;
&> * {
margin: 0;
}
}
.notEnough {
pointer-events: none;
opacity: 0.55;
@@ -198,30 +238,108 @@
margin-bottom: 16px;
}
.box {
display: inline-block;
width: 74px;
height: 40px;
border-radius: 2px;
background-color: #ffffff;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
margin-right: 24px;
input {
width: 100%;
border: none;
.item-cost {
padding-bottom: 16px;
}
input::-webkit-contacts-auto-fill-button {
visibility: hidden;
display: none !important;
pointer-events: none;
position: absolute;
right: 0;
}
.cost {
height: 40px;
font-size: 1.25rem;
font-weight: bold;
vertical-align: middle;
padding: 8px 20px 8px 20px;
&.gems {
color: $green-10;
background-color: rgba(36, 204, 143, 0.15);
line-height: 1.4;
margin: 0 0 0 -4px;
border-radius: 20px;
}
&.gold {
color: $yellow-5;
background-color: rgba(255, 190, 93, 0.15);
line-height: 1.4;
margin: 0 0 0 -4px;
border-radius: 20px;
}
&.hourglasses {
color: $hourglass-color;
background-color: rgba(41, 149, 205, 0.15);
line-height: 1.4;
margin: 0 0 0 -4px;
border-radius: 20px;
}
}
.total-row {
font-weight: bold;
font-size: 0.875rem;
margin-top: 16px;
}
.total {
font-weight: bold;
font-size: 0.875rem;
margin-top: 16px;
&.gems {
color: $green-10;
}
&.gold {
color: $yellow-5;
}
&.hourglasses {
color: $hourglass-color;
}
}
.total-text {
color: $gray-50;
font-weight: bold;
font-size: 0.875rem;
height: 24px;
line-height: 1.71;
padding-right: 4px;
&.gems {
color: $green-10;
}
&.gold {
color: $yellow-5;
}
&.hourglasses {
color: $hourglass-color;
}
}
span.svg-icon.inline.icon-20 {
height: 20px;
width: 20px;
margin-right: 4px;
vertical-align: middle;
}
span.svg-icon.inline.icon-24 {
height: 24px;
width: 24px;
margin-right: 8px;
vertical-align: middle;
}
span.svg-icon.inline.icon-32 {
height: 32px;
width: 32px;
margin-right: 8px;
vertical-align: middle;
}
@media only screen and (max-width: 1000px) {
.modal-dialog {
max-width: 80%;
@@ -234,9 +352,10 @@
}
}
}
}
</style>
<style lang="scss" scoped>
<!-- <style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.value {
@@ -260,7 +379,7 @@
color: $hourglass-color;
}
}
</style>
</style> -->
<script>
import moment from 'moment';
@@ -272,6 +391,8 @@ import svgExperience from '@/assets/svg/experience.svg';
import svgGem from '@/assets/svg/gem.svg';
import svgGold from '@/assets/svg/gold.svg';
import svgHourglasses from '@/assets/svg/hourglass.svg';
import svgPositive from '@/assets/svg/positive.svg';
import svgNegative from '@/assets/svg/negative.svg';
import BalanceInfo from '../balanceInfo.vue';
import currencyMixin from '../_currencyMixin';
@@ -280,6 +401,7 @@ import buyMixin from '@/mixins/buy';
import numberInvalid from '@/mixins/numberInvalid';
import PinBadge from '@/components/ui/pinBadge';
import CountdownBanner from '../countdownBanner';
import numberIncrement from '@/components/shared/numberIncrement';
import questDialogContent from './questDialogContent';
import QuestRewards from './questRewards';
@@ -293,6 +415,7 @@ export default {
PinBadge,
questDialogContent,
CountdownBanner,
numberIncrement,
},
mixins: [buyMixin, currencyMixin, notifications, numberInvalid],
props: {
@@ -301,6 +424,7 @@ export default {
},
priceType: {
type: String,
default: '',
},
withPin: {
type: Boolean,
@@ -312,9 +436,11 @@ export default {
clock: svgClock,
close: svgClose,
experience: svgExperience,
gem: svgGem,
gems: svgGem,
gold: svgGold,
hourglass: svgHourglasses,
hourglasses: svgHourglasses,
positive: svgPositive,
negative: svgNegative,
}),
isPinned: false,
@@ -339,8 +465,8 @@ export default {
},
currencyIcon () {
if (this.priceType === 'gold') return this.icons.gold;
if (this.priceType === 'hourglasses') return this.icons.hourglass;
return this.icons.gem;
if (this.priceType === 'hourglasses') return this.icons.hourglasses;
return this.icons.gems;
},
endDate () {
return moment(this.item.event.end);
@@ -33,17 +33,17 @@
h3 {
color: $gray-10;
margin-bottom: 0.25rem;
margin-bottom: 4pxrem;
}
.quest-image {
margin: 0 auto;
margin-bottom: 1em;
margin-top: 1.5em;
margin-bottom: 16px;
margin-top: 24px;
}
.text {
margin-bottom: 1rem;
margin: 16px 16px;
overflow-y: auto;
text-overflow: ellipsis;
}
@@ -54,10 +54,10 @@
line-height: 1.71;
color: $gray-50;
text-align: center;
margin-bottom: 0.5rem;
margin-bottom: 8px;
::v-deep .user-label {
font-size: 14px;
font-size: 0.875rem;
}
}
@@ -177,9 +177,6 @@ export default {
@import '~@/assets/scss/colors.scss';
.quest-rewards {
margin-left: -1rem;
margin-right: -1rem;
background-color: $gray-700;
}
@@ -106,6 +106,7 @@ export default {
preventMultipleWatchExecution: false,
eventPromoBannerHeight: null,
sleepingBannerHeight: null,
warningBannerHeight: null,
};
},
computed: {
@@ -135,6 +136,10 @@ export default {
notificationBannerHeight () {
let scrollPosToCheck = 56;
if (this.warningBannerHeight) {
scrollPosToCheck += this.warningBannerHeight;
}
if (this.sleepingBannerHeight) {
scrollPosToCheck += this.sleepingBannerHeight;
}
@@ -361,6 +366,7 @@ export default {
updateBannerHeightAndScrollY () {
this.updateEventBannerHeight();
this.warningBannerHeight = getBannerHeight('chat-warning');
this.sleepingBannerHeight = getBannerHeight('damage-paused');
this.updateScrollY();
},
@@ -0,0 +1,615 @@
<template>
<div class="top-container mx-auto">
<div class="main-text mr-4">
<!-- title goes here -->
<div class="title-details">
<h1 v-once>
{{ $t('sunsetFaqTitle') }}
</h1>
</div>
<div class="body-text">
<p v-html="$t('sunsetFaqPara1')"></p> <!-- there's html in here -->
<p>{{ $t('sunsetFaqPara2') }}</p>
<p>{{ $t('sunsetFaqPara3') }}</p>
<p>{{ $t('sunsetFaqPara4') }}</p>
<p>{{ $t('sunsetFaqPara5') }}</p>
</div>
<!-- Which services are ending -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader1') }}
</h3>
</div>
<div class="body-text">
<p v-html="$t('sunsetFaqPara6')"></p>
</div>
<!-- Why are tavern and guild ending? -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader2') }}
</h3>
</div>
<div class="body-text">
<ul>
<li>{{ $t('sunsetFaqList1') }}</li>
<li>{{ $t('sunsetFaqList2') }}</li>
<li>{{ $t('sunsetFaqList3') }}</li>
</ul>
</div>
<!-- Can I still talk to my party/group members? -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader3') }}
</h3>
</div>
<div class="body-text">
<p>{{ $t('sunsetFaqPara7') }}</p>
</div>
<!-- Pausing dailies -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader4') }}
</h3>
</div>
<div class="body-text">
<p>{{ $t('sunsetFaqPara8') }}</p>
</div>
<!-- Accessing group plans -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader5') }}
</h3>
</div>
<div class="body-text">
<p v-html="$t('sunsetFaqPara9')"></p> <!-- there's html in here -->
</div>
<!-- Can I access guild chats? Or banked Gems? -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader12') }}
</h3>
</div>
<div class="body-text">
<p v-html="$t('sunsetFaqPara21')"></p>
</div>
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader6') }}
</h3>
</div>
<div class="body-text">
<p>{{ $t('sunsetFaqPara10') }}</p>
</div>
<!-- How can players find groups? -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader7') }}
</h3>
</div>
<div class="body-text">
<p>{{ $t('sunsetFaqPara11') }}</p>
</div>
<!-- What about contributors? -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader8') }}
</h3>
</div>
<div class="body-text">
<p v-html="$t('sunsetFaqPara12')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara13')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara14')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara15')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara16')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara17')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara18')"></p> <!-- there's html in here -->
<p v-html="$t('sunsetFaqPara19')"></p> <!-- there's html in here -->
</div>
<!-- Challenges -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader9') }}
</h3>
</div>
<div class="body-text">
<ul>
<li>{{ $t('sunsetFaqList4') }}</li>
<li>{{ $t('sunsetFaqList5') }}</li>
<li>{{ $t('sunsetFaqList6') }}</li>
<li>{{ $t('sunsetFaqList7') }}</li>
</ul>
</div>
<!-- Questions about how to use Habitica -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader10') }}
</h3>
</div>
<div class="body-text">
<ul>
<li v-html="$t('sunsetFaqList8')"></li> <!-- there's html in here -->
<li v-html="$t('sunsetFaqList9')"></li> <!-- there's html in here -->
<li v-html="$t('sunsetFaqList10')"></li> <!-- there's html in here -->
</ul>
</div>
<!-- Community Guidelines and TOS -->
<div>
<h3 class="headings">
{{ $t('sunsetFaqHeader11') }}
</h3>
</div>
<div class="body-text">
<p v-html="$t('sunsetFaqPara20')"></p>
</div>
</div>
<!-- sidebar -->
<div class="sidebar py-4 d-flex flex-column">
<!-- staff -->
<div class="ml-4">
<h2>
{{ $t('staff') }}
</h2>
<div class="d-flex flex-wrap">
<div
v-for="user in staff"
:key="user.uuid"
class="staff col-6 p-0"
>
<div class="d-flex">
<router-link
class="title"
:to="{'name': 'userProfile', 'params': {'userId': user.uuid}}"
>
{{ user.name }}
</router-link>
<div
v-if="user.type === 'Staff'"
class="svg-icon staff-icon ml-1"
v-html="icons.tierStaff"
></div>
</div>
</div>
</div>
</div>
<!-- player tiers -->
<div class="ml-4">
<h2 class="mt-4 mb-1">
{{ $t('playerTiers') }}
</h2>
<ul class="tier-list">
<li
v-once
class="tier1 d-flex justify-content-center"
>
{{ $t('tier1') }}
<div
class="svg-icon ml-1"
v-html="icons.tier1"
></div>
</li>
<li
v-once
class="tier2 d-flex justify-content-center"
>
{{ $t('tier2') }}
<div
class="svg-icon ml-1"
v-html="icons.tier2"
></div>
</li>
<li
v-once
class="tier3 d-flex justify-content-center"
>
{{ $t('tier3') }}
<div
class="svg-icon ml-1"
v-html="icons.tier3"
></div>
</li>
<li
v-once
class="tier4 d-flex justify-content-center"
>
{{ $t('tier4') }}
<div
class="svg-icon ml-1"
v-html="icons.tier4"
></div>
</li>
<li
v-once
class="tier5 d-flex justify-content-center"
>
{{ $t('tier5') }}
<div
class="svg-icon ml-1"
v-html="icons.tier5"
></div>
</li>
<li
v-once
class="tier6 d-flex justify-content-center"
>
{{ $t('tier6') }}
<div
class="svg-icon ml-1"
v-html="icons.tier6"
></div>
</li>
<li
v-once
class="tier7 d-flex justify-content-center"
>
{{ $t('tier7') }}
<div
class="svg-icon ml-1"
v-html="icons.tier7"
></div>
</li>
<li
v-once
class="moderator d-flex justify-content-center"
>
{{ $t('tierModerator') }}
<div
class="svg-icon ml-1"
v-html="icons.tierMod"
></div>
</li>
<li
v-once
class="staff d-flex justify-content-center"
>
{{ $t('tierStaff') }}
<div
class="svg-icon ml-1"
v-html="icons.tierStaff"
></div>
</li>
<li
v-once
class="npc d-flex justify-content-center"
>
{{ $t('tierNPC') }}
</li>
</ul>
</div>
<!-- Daniel in sweet, sweet retirement with Jorts -->
<div>
<div class="gradient">
</div>
<div
class="grassy-meadow-backdrop"
:style="{'background-image': imageURLs.background}"
>
<div
class="daniel_front"
:style="{'background-image': imageURLs.npc}"
></div>
<div
class="pixel-border"
:style="{'background-image': imageURLs.pixel_border}"
></div>
</div>
</div>
<!-- email admin -->
<div class="d-flex flex-column justify-content-center">
<div class="question mx-auto">
{{ $t('anotherQuestion') }}
</div>
<div
class="contact mx-auto"
>
<p v-html="$t('contactAdmin')"></p> <!-- there's html in here -->
</div>
</div>
</div>
<!-- final div! -->
</div>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
h1 {
margin-top: 0px;
line-height: 1.33;
}
li {
padding-bottom: 16px;
&::marker {
size: 0.5em;
}
}
p {
margin-bottom: 21px;
}
ul {
padding-left: 20px;
}
.top-container {
width: 66.67%;
margin-top: 80px;
display: flex;
@media (max-width: 1024px) {
flex-wrap: wrap;
}
}
.main-text {
.body-text {
font-size: 1em;
color: $gray-10;
line-height: 1.71;
}
.headings {
font-size: 1.15em;
font-weight: 400;
line-height: 1.75;
color: $purple-200;
}
}
.sidebar {
height: fit-content;
width: 330px;
background-color: $gray-700;
border-radius: 16px;
h2 {
color: $gray-10;
font-family: Roboto;
font-size: 14px;
font-weight: bold;
line-height: 1.71;
}
.staff {
.staff-icon {
width: 10px;
margin-top: 5px;
}
.title {
height: 24px;
color: $purple-300;
font-weight: bold;
display: inline-block;
margin-bottom: 4px;
}
}
.tier-list {
list-style-type: none;
padding: 0;
width: 282px;
font-size: 1em !important;
li {
height: 40px;
border-radius: 4px;
border: solid 1px $gray-500;
text-align: center;
padding: 8px 0;
margin-bottom: 8px;
margin-right: 4px;
font-weight: bold;
line-height: 1.71;
}
.tier1 {
color: #c42870;
.svg-icon {
width: 11px;
margin-top: 5px;
}
}
.tier2 {
color: #b01515;
.svg-icon {
width: 11px;
margin-top: 5px;
}
}
.tier3 {
color: #d70e14;
.svg-icon {
width: 13px;
margin-top: 4px;
}
}
.tier4 {
color: #c24d00;
.svg-icon {
width: 13px;
margin-top: 4px;
}
}
.tier5 {
color: #9e650f;
.svg-icon {
width: 8px;
margin-top: 7px;
}
}
.tier6 {
color: #2b8363;
.svg-icon {
width: 8px;
margin-top: 7px;
}
}
.tier7 {
color: #167e87;
.svg-icon {
width: 12px;
margin-top: 4px;
}
}
.moderator {
color: #277eab;
.svg-icon {
width: 13px;
margin-top: 3px;
}
}
.staff {
color: #6133b4;
.svg-icon {
width: 10px;
margin-top: 7px;
}
}
.npc {
color: $black;
}
}
.gradient {
position: absolute;
width: 330px;
height: 100px;
margin: -1px 0 116px;
background-image: linear-gradient(to bottom, $gray-700 0%, rgba(249, 249, 249, 0) 100%);
}
.grassy-meadow-backdrop {
background-repeat: repeat-x;
width: 330px;
height: 246px;
}
.daniel_front {
height: 246px;
width: 330px;
background-repeat: no-repeat;
margin: 0 auto;
}
.pixel-border {
width: 330px;
height: 30px;
background-repeat: no-repeat;
position: absolute;
margin-top: -30px;
}
.question {
font-size: 1em;
font-weight: bold;
line-height: 1.71;
color: $gray-10;
margin-top: 24px;
}
.contact p {
font-size: 1em;
margin-bottom: 0px;
}
}
</style>
<script>
import find from 'lodash/find';
import { mapState } from '@/libs/store';
import tier1 from '@/assets/svg/tier-1.svg';
import tier2 from '@/assets/svg/tier-2.svg';
import tier3 from '@/assets/svg/tier-3.svg';
import tier4 from '@/assets/svg/tier-4.svg';
import tier5 from '@/assets/svg/tier-5.svg';
import tier6 from '@/assets/svg/tier-6.svg';
import tier7 from '@/assets/svg/tier-7.svg';
import tierMod from '@/assets/svg/tier-mod.svg';
import tierNPC from '@/assets/svg/tier-npc.svg';
import tierStaff from '@/assets/svg/tier-staff.svg';
import staffList from '../../libs/staffList';
export default {
data () {
return {
icons: Object.freeze({
tier1,
tier2,
tier3,
tier4,
tier5,
tier6,
tier7,
tierMod,
tierNPC,
tierStaff,
}),
group: {
chat: [],
},
sections: {
worldBoss: true,
},
staff: staffList,
};
},
computed: {
...mapState({
currentEventList: 'worldState.data.currentEventList',
}),
imageURLs () {
const currentEvent = find(this.currentEventList, event => Boolean(event.season));
if (!currentEvent) {
return {
background: 'url(/static/npc/normal/tavern_background.png)',
npc: 'url(/static/npc/normal/tavern_npc.png)',
pixel_border: 'url(/static/npc/normal/pixel_border.png)',
};
}
return {
background: `url(/static/npc/${currentEvent.season}/tavern_background.png)`,
npc: `url(/static/npc/${currentEvent.season}/tavern_npc.png)`,
pixel_border: 'url(/static/npc/normal/pixel_border.png)',
};
},
},
async mounted () {
this.$store.dispatch('common:setTitle', {
subSection: this.$t('faq/taverns-and-guilds'),
});
document.body.style.background = '#ffffff';
},
};
</script>
@@ -7,13 +7,19 @@
<br>
<p class="text-center">
<button
id="buttonClearBrowserData"
class="btn btn-lg btn-danger"
popover-trigger="mouseover"
:popover="$t('localStorageClearExplanation')"
@click="clearLocalStorage()"
>
{{ $t('localStorageClear') }}
</button>
<b-popover
target="buttonClearBrowserData"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('localStorageClearExplanation')"
/>
</p>
<br>
<p v-html="$t('localStorageTryNext', localStorageTryNext) "></p>
+45 -16
View File
@@ -17,6 +17,19 @@
class="faq-question"
>
<h2
v-once
v-if="index === 0"
>
{{ $t('general') }}
</h2>
<h2
v-once
v-if="entry.heading === 'party-with-friends'"
id="parties"
>
{{ $t('parties') }}
</h2>
<h3
v-once
v-b-toggle="entry.heading"
role="tab"
@@ -24,7 +37,7 @@
@click="handleClick($event)"
>
{{ entry.question }}
</h2>
</h3>
<b-collapse
:id="entry.heading"
:visible="isVisible(entry.heading)"
@@ -49,25 +62,41 @@
</template>
<style lang='scss' scoped>
.card-body {
margin-bottom: 1em;
h2 {
color: #34313a;
border-bottom: 1px solid #e1e0e3;
margin-top: 24px;
padding-bottom: 16px;
}
.faq-question h2 {
cursor: pointer;
.faq-question {
a {
text-decoration: none;
color: #4F2A93;
}
h3 {
font-size: 16px;
font-weight: normal;
line-height: 1.75;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
.card-body {
padding: 0;
font-size: 14px;
line-height: 1.71;
margin-bottom: 1em;
}
}
.faq-question .card-body {
padding: 0;
}
.static-wrapper .faq-question h2 {
margin: 0 0 16px 0;
}
.faq-question a {
text-decoration: none;
color: #4F2A93;
.container-fluid {
position: relative;
top: 2rem;
}
@media only screen and (max-width: 768px) {
@@ -1,11 +1,12 @@
<template>
<div>
<chat-banner />
<static-header
v-if="showContentWrap"
:class="{
'home-header': ['home', 'front'].indexOf($route.name) !== -1,
'white-header': this.$route.name === 'plans'
}"
v-if="showContentWrap"
:class="{
'home-header': ['home', 'front'].indexOf($route.name) !== -1,
'white-header': this.$route.name === 'plans'
}"
/>
<div class="static-wrapper">
<router-view />
@@ -198,10 +199,6 @@
color: $purple-200;
}
li, p {
font-size: 16px;
}
.media img {
margin: 1em;
}
@@ -247,11 +244,13 @@
<script>
import AppFooter from '@/components/appFooter';
import ChatBanner from '@/components/header/banners/chatBanner';
import StaticHeader from './header.vue';
export default {
components: {
AppFooter,
ChatBanner,
StaticHeader,
},
computed: {
+13 -6
View File
@@ -521,7 +521,12 @@ export default {
// Get Category Filter Labels
this.typeFilters = getFilterLabels(this.type, this.challenge);
// Set default filter for task column
this.activateFilter(this.type);
if (this.challenge) {
this.activateFilter(this.type);
} else {
this.activateFilter(this.type, this.user.preferences.tasks.activeFilter[this.type], true);
}
},
mounted () {
this.setColumnBackgroundVisibility();
@@ -661,7 +666,7 @@ export default {
taskSummary (task) {
this.$emit('taskSummary', task);
},
activateFilter (type, filter = '') {
activateFilter (type, filter = '', skipSave = false) {
// Needs a separate API call as this data may not reside in store
if (type === 'todo' && filter === 'complete2') {
if (this.group && this.group._id) {
@@ -677,14 +682,16 @@ export default {
// as default filter for daily
// and set the filter as 'due' only when the component first
// loads and not on subsequent reloads.
if (
type === 'daily' && filter === '' && !this.challenge
&& this.user.preferences.dailyDueDefaultView
) {
if (type === 'daily' && filter === '' && !this.challenge) {
filter = 'due'; // eslint-disable-line no-param-reassign
}
this.activeFilter = getActiveFilter(type, filter, this.challenge);
if (!skipSave && !this.challenge) {
const propertyToUpdate = `preferences.tasks.activeFilter.${type}`;
this.$store.dispatch('user:set', { [propertyToUpdate]: filter });
}
},
setColumnBackgroundVisibility () {
this.$nextTick(() => {
+17 -9
View File
@@ -6,6 +6,7 @@
'groupTask': task.group.id,
'task-not-editable': !teamManagerAccess,
'task-not-scoreable': showTaskLockIcon,
'link-exempt': !isChallengeTask && !isGroupTask,
}, `type_${task.type}`
]"
@click="castEnd($event, task)"
@@ -31,6 +32,9 @@
'task-not-scoreable': showTaskLockIcon,
}, controlClass.up.inner]"
tabindex="0"
role="button"
:aria-label="$t('scoreUp')"
:aria-disabled="showTaskLockIcon || (!task.up && !showTaskLockIcon)"
@click="score('up')"
@keypress.enter="score('up')"
>
@@ -62,6 +66,7 @@
controlClass.inner,
]"
tabindex="0"
role="checkbox"
@click="score(showCheckIcon ? 'down' : 'up' )"
@keypress.enter="score(showCheckIcon ? 'down' : 'up' )"
>
@@ -240,7 +245,7 @@
>
<div
v-b-tooltip.hover.bottom="$t('dueDate')"
class="svg-icon calendar"
class="svg-icon calendar my-auto"
v-html="icons.calendar"
></div>
<span>{{ formatDueDate() }}</span>
@@ -358,6 +363,9 @@
'task-not-scoreable': showTaskLockIcon,
}, controlClass.down.inner]"
tabindex="0"
role="button"
:aria-label="$t('scoreDown')"
:aria-disabled="showTaskLockIcon || (!task.down && !showTaskLockIcon)"
@click="score('down')"
@keypress.enter="score('down')"
>
@@ -700,7 +708,7 @@
.icons {
margin-top: 4px;
color: $gray-300;
color: $gray-100;
font-style: normal;
&-right {
@@ -759,7 +767,7 @@
}
.due-overdue {
color: $red-50;
color: $maroon-10;
}
.calendar.svg-icon {
@@ -898,7 +906,7 @@
}
</style>
<!-- eslint-enable max-len -->
<!-- eslint-disable-next-line vue/component-tags-order -->
<script>
import moment from 'moment';
import { v4 as uuid } from 'uuid';
@@ -1125,13 +1133,13 @@ export default {
return moment.duration(endOfDueDate.diff(endOfToday));
},
checkIfOverdue () {
return this.calculateTimeTillDue().asDays() <= 0;
return this.calculateTimeTillDue().asDays() < 0;
},
formatDueDate () {
const timeTillDue = this.calculateTimeTillDue();
const dueIn = timeTillDue.asDays() === 0 ? this.$t('today') : timeTillDue.humanize(true);
return this.task.date && this.$t('dueIn', { dueIn });
if (moment().isSame(this.task.date, 'day')) {
return this.$t('today');
}
return moment(this.task.date).format(this.user.preferences.dateFormat.toUpperCase());
},
edit (e, task) {
if (this.isRunningYesterdailies) return;
@@ -110,7 +110,9 @@ export default {
};
},
updated () {
this.handleExternalLinks();
window.setTimeout(() => {
this.handleExternalLinks();
}, 500);
},
computed: {
...mapState({ user: 'user.data' }),
@@ -0,0 +1,46 @@
<template>
<div
class="modal-close"
@click="$emit('close')"
>
<div
class="svg-icon svg-close color"
v-html="icons.close"
>
</div>
</div>
</template>
<style lang="scss" scoped>
.modal-close {
position: absolute;
right: 16px;
top: 16px;
cursor: pointer;
.svg-close {
width: 18px;
height: 18px;
vertical-align: middle;
opacity: 0.75;
&:hover {
opacity: 1;
}
}
}
</style>
<script>
import close from '@/assets/svg/close.svg';
export default {
data () {
return {
icons: Object.freeze({
close,
}),
};
},
};
</script>
+10 -5
View File
@@ -2,13 +2,13 @@
<router-link
v-if="displayName"
v-b-tooltip.hover.top="tierTitle"
class="leader user-link"
class="leader user-link d-flex"
:to="{'name': 'userProfile', 'params': {'userId': id}}"
:class="levelStyle()"
>
{{ displayName }}
<div
class="svg-icon"
class="svg-icon icon-12"
v-html="tierIcon()"
></div>
</router-link>
@@ -37,10 +37,15 @@
color: $gray-50;
}
&[class*="tier"] .svg-icon {
margin-top: 5px;
}
&.npc .svg-icon {
margin-top: 4px;
}
.svg-icon {
width: 10px;
display: inline-block;
margin-left: .5em;
margin-left: 6px;
&:empty {
display: none;
+132 -76
View File
@@ -146,17 +146,19 @@
:key="stat"
class="row"
>
<div class="col-4">
<span
class="hint"
:popover-title="$t(statInfo.title)"
popover-placement="right"
:popover="$t(statInfo.popover)"
popover-trigger="mouseenter"
>
<strong>{{ $t(statInfo.title) }}</strong>
</span>
<div
class="col-4"
:id="statInfo.title"
>
<strong> {{ $t(statInfo.title)}} </strong>
<strong>: {{ statsComputed[stat] }}</strong>
<b-popover
:target="statInfo.title"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t(statInfo.popover)"
/>
</div>
<div class="col-6">
<ul class="bonus-stats">
@@ -183,27 +185,38 @@
</ul>
</div>
</div>
<div v-if="user.stats.buffs.stealth">
<div
v-if="user.stats.buffs.stealth"
id="stealthBuff"
>
<strong
v-once
class="hint"
:popover-title="$t('stealth')"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('stealthNewDay')"
>{{ $t('stealth') }}</strong>
<strong>: {{ user.stats.buffs.stealth }}&nbsp;</strong>
<b-popover
target="stealthBuff"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('stealthNewDay')"
/>
</div>
<div v-if="user.stats.buffs.streaks">
<div
v-if="user.stats.buffs.streaks"
id="streaksFrozenBuff"
>
<div>
<strong
class="hint"
popover-title="$t('streaksFrozen')"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('streaksFrozenText')"
></strong>
{{ $t('streaksFrozen') }}
<strong>
{{ $t('streaksFrozen') }}
</strong>
<b-popover
target="streaksFrozenBuff"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('streaksFrozenText')"
/>
</div>
</div>
</div>
@@ -237,19 +250,27 @@
>
{{ $t('noMoreAllocate') }}
</p>
<p v-if="user.stats.points || userLevel100Plus">
<p
v-if="user.stats.points || userLevel100Plus"
id="pointAllocation"
>
<strong class="inline">{{ user.stats.points }}&nbsp;</strong>
<strong
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('levelPopover')"
>{{ $t('unallocated') }}</strong>
<strong> {{ $t('unallocated') }} </strong>
<b-popover
target="pointAllocation"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('levelPopover')"
/>
</p>
</div>
<div>
<fieldset class="auto-allocate">
<div class="checkbox">
<div
id="preferenceAutomaticAllocation"
class="checkbox"
>
<label>
<input
v-model="user.preferences.automaticAllocation"
@@ -259,19 +280,24 @@
'preferences.allocationMode': 'taskbased'
})"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('autoAllocationPop')"
>{{ $t('autoAllocation') }}</span>
<b-popover
target="preferenceAutomaticAllocation"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('autoAllocationPop')"
/>
{{ $t('autoAllocation') }}
</label>
</div>
<form
v-if="user.preferences.automaticAllocation"
style="margin-left:1em"
>
<div class="radio">
<div
id="optionFlatAllocation"
class="radio"
>
<label>
<input
v-model="user.preferences.allocationMode"
@@ -280,15 +306,22 @@
value="flat"
@change="set({'preferences.allocationMode': 'flat'})"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('evenAllocationPop')"
>{{ $t('evenAllocation') }}</span>
<span class="hint">
{{ $t('evenAllocation') }}
</span>
<b-popover
target="optionFlatAllocation"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('evenAllocationPop')"
/>
</label>
</div>
<div class="radio">
<div
id="optionClassAllocation"
class="radio"
>
<label>
<input
v-model="user.preferences.allocationMode"
@@ -297,47 +330,63 @@
value="classbased"
@change="set({'preferences.allocationMode': 'classbased'})"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('classAllocationPop')"
>{{ $t('classAllocation') }}</span>
<span class="hint">
{{ $t('classAllocation') }}
</span>
<b-popover
target="optionClassAllocation"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('classAllocationPop')"
/>
</label>
</div>
<div class="radio">
<div
id="optionTaskAllocation"
class="radio"
>
<label>
<input
v-model="user.preferences.allocationMode"
type="radio"
name="allocationMode"
value="taskbased"
value="classbased"
@change="set({'preferences.allocationMode': 'taskbased'})"
>
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('taskAllocationPop')"
>{{ $t('taskAllocation') }}</span>
<span class="hint">
{{ $t('taskAllocation') }}
</span>
<b-popover
target="optionTaskAllocation"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('taskAllocationPop')"
/>
</label>
</div>
</form>
<div
v-if="user.preferences.automaticAllocation
&& !(user.preferences.allocationMode === 'taskbased') && (user.stats.points > 0)"
id="buttonDistributePoints"
>
<button
class="btn btn-primary btn-xs"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t('distributePointsPop')"
@click="allocateNow({})"
>
<span class="glyphicon glyphicon-download"></span>
&nbsp;
{{ $t('distributePoints') }}
</button>
<b-popover
target="buttonDistributePoints"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t('distributePointsPop')"
/>
</div>
</fieldset>
</div>
@@ -346,28 +395,35 @@
:key="stat"
class="row"
>
<div class="col-8">
<span
class="hint"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t(statInfo.popover)"
></span>
<div
:id="`${stat}-info`"
class="col-8"
>
{{ $t(statInfo.title) + user.stats[stat] }}
<b-popover
:target="`${stat}-info`"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t(statInfo.popover)"
/>
</div>
<div
v-if="user.stats.points"
:id="`${stat}-allocate`"
class="col-4"
@click="allocate(stat)"
>
<button
class="btn btn-primary"
popover-trigger="mouseenter"
popover-placement="right"
:popover="$t(statInfo.allocatepop)"
>
<button class="btn btn-primary">
+
</button>
<b-popover
:target="`${stat}-allocate`"
triggers="hover focus"
placement="right"
:prevent-overflow="false"
:content="$t(statInfo.allocatePop)"
/>
</div>
</div>
</div>
@@ -16,6 +16,7 @@ export default {
}
if ((link.classList.value.indexOf('external-link') === -1)
&& (!link.offsetParent || link.offsetParent.classList.value.indexOf('link-exempt') === -1)
&& domainIndex !== 1
&& !some(TRUSTED_DOMAINS.split(','), domain => link.href.indexOf(domain) === domainIndex)) {
link.classList.add('external-link');
+3 -1
View File
@@ -1,7 +1,9 @@
export default {
computed: {
numberInvalid () {
return this.selectedAmountToBuy < 1 || !Number.isInteger(this.selectedAmountToBuy);
const inputNumber = Number(this.selectedAmountToBuy);
return inputNumber < 1
|| !Number.isInteger(inputNumber);
},
},
};
+1 -1
View File
@@ -114,7 +114,7 @@ export default {
this.castCancel();
// the selected member doesn't have the flags property which sets `cardReceived`
if (spell.pinType !== 'card') {
if (spell.pinType !== 'card' && spell.bulk !== true) {
try {
spell.cast(this.user, target, {});
} catch (e) {
+28 -1
View File
@@ -1,5 +1,6 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
import * as Analytics from '@/libs/analytics';
import getStore from '@/store';
import handleRedirect from './handleRedirect';
@@ -27,6 +28,7 @@ const NewsPage = () => import(/* webpackChunkName: "static" */'@/components/stat
const OverviewPage = () => import(/* webpackChunkName: "static" */'@/components/static/overview');
const PressKitPage = () => import(/* webpackChunkName: "static" */'@/components/static/pressKit');
const PrivacyPage = () => import(/* webpackChunkName: "static" */'@/components/static/privacy');
const ChatSunsetFaq = () => import(/* webpackChunkName: "static" */'@/components/static/chatSunsetFaq');
const TermsPage = () => import(/* webpackChunkName: "static" */'@/components/static/terms');
const RegisterLoginReset = () => import(/* webpackChunkName: "auth" */'@/components/auth/registerLoginReset');
@@ -72,13 +74,14 @@ const ItemsPage = () => import(/* webpackChunkName: "inventory" */'@/components/
const EquipmentPage = () => import(/* webpackChunkName: "inventory" */'@/components/inventory/equipment/index');
const StablePage = () => import(/* webpackChunkName: "inventory" */'@/components/inventory/stable/index');
// Guilds
// Guilds & Parties
const GuildIndex = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/index');
const TavernPage = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/tavern');
const MyGuilds = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/myGuilds');
const GuildsDiscoveryPage = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/discovery');
const GroupPage = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/group');
const GroupPlansAppPage = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/groupPlan');
const LookingForParty = () => import(/* webpackChunkName: "guilds" */ '@/components/groups/lookingForParty');
// Group Plans
const GroupPlanIndex = () => import(/* webpackChunkName: "group-plans" */ '@/components/group-plans/index');
@@ -157,6 +160,7 @@ const router = new VueRouter({
],
},
{ name: 'party', path: '/party', component: GroupPage },
{ name: 'lookingForParty', path: '/looking-for-party', component: LookingForParty },
{ name: 'groupPlan', path: '/group-plans', component: GroupPlansAppPage },
{
name: 'groupPlanDetail',
@@ -309,6 +313,9 @@ const router = new VueRouter({
{
name: 'faq', path: 'faq', component: FAQPage, meta: { requiresLogin: false },
},
{
name: 'chatSunsetFaq', path: 'tavern-and-guilds', component: ChatSunsetFaq, meta: { requiresLogin: false },
},
{
name: 'features', path: 'features', component: FeaturesPage, meta: { requiresLogin: false },
},
@@ -379,6 +386,7 @@ const router = new VueRouter({
// Only used to handle some redirects
// See router.beforeEach
{ path: '/static/faq/tavern-and-guilds', redirect: '/static/tavern-and-guilds' },
{ path: '/redirect/:redirect', name: 'redirect' },
{ path: '*', redirect: { name: 'notFound' } },
],
@@ -433,6 +441,19 @@ router.beforeEach(async (to, from, next) => {
}
}
if (to.name === 'party') {
router.app.$root.$emit('update-party');
}
if (to.name === 'lookingForParty') {
Analytics.track({
hitType: 'event',
eventName: 'View Find Members',
eventAction: 'View Find Members',
eventCategory: 'behavior',
}, { trackOnClient: true });
}
// Redirect old guild urls
if (to.hash.indexOf('#/options/groups/guilds/') !== -1) {
const splits = to.hash.split('/');
@@ -493,4 +514,10 @@ router.beforeEach(async (to, from, next) => {
return next();
});
router.afterEach((to, from) => {
if (from.name === 'chatSunsetFaq') {
document.body.style.background = '#f9f9f9';
}
});
export default router;
+12
View File
@@ -1,3 +1,4 @@
import axios from 'axios';
import { loadAsyncResource } from '@/libs/asyncResource';
export function getMembers (store, forceLoad = false) {
@@ -23,3 +24,14 @@ export function getParty (store, forceLoad = false) {
forceLoad,
});
}
export async function lookingForParty (store, payload) {
let response;
if (payload && payload.page) {
response = await axios.get(`api/v4/looking-for-party?page=${payload.page}`);
} else {
response = await axios.get('api/v4/looking-for-party');
}
return response.data.data;
}
@@ -21,6 +21,18 @@ describe('Task Column', () => {
getters: {
'tasks:getFilteredTaskList': () => [],
},
state: {
user: {
data: {
preferences: {
tasks: {
activeFilter: {},
},
},
},
},
},
},
mocks,
stubs,
@@ -76,7 +88,20 @@ describe('Task Column', () => {
'tasks:getFilteredTaskList': () => () => habits,
};
const store = new Store({ getters });
const store = new Store({
getters,
state: {
user: {
data: {
preferences: {
tasks: {
activeFilter: {},
},
},
},
},
},
});
wrapper = makeWrapper({ store });
});
@@ -1,88 +0,0 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import moment from 'moment';
import Task from '@/components/tasks/task.vue';
import Store from '@/libs/store';
const localVue = createLocalVue();
localVue.use(Store);
describe('Task', () => {
let wrapper;
function makeWrapper (additionalTaskData = {}, additionalUserData = {}) {
return shallowMount(Task, {
propsData: {
task: {
group: {},
...additionalTaskData,
},
},
store: {
state: {
user: {
data: {
preferences: {},
...additionalUserData,
},
},
},
getters: {
'tasks:getTaskClasses': () => ({}),
'tasks:canEdit': () => ({}),
'tasks:canDelete': () => ({}),
},
},
mocks: { $t: (key, params) => key + (params ? JSON.stringify(params) : '') },
directives: { 'b-tooltip': {} },
localVue,
});
}
it('returns a vue instance', () => {
wrapper = makeWrapper();
expect(wrapper.isVueInstance()).to.be.true;
});
describe('Due date calculation', () => {
let clock;
function setClockTo (time) {
const now = moment(time);
clock = sinon.useFakeTimers(now.toDate());
return now;
}
afterEach(() => {
clock.restore();
});
it('formats due date to today if due today', () => {
const now = setClockTo('2019-09-17T17:57:00+02:00');
wrapper = makeWrapper({ date: now });
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"today"}');
});
it('formats due date to tomorrow if due tomorrow', () => {
const now = setClockTo('2012-06-12T14:17:28Z');
wrapper = makeWrapper({ date: now.add(1, 'day') });
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"in a day"}');
});
it('formats due date to 5 days if due in 5 days', () => {
const now = setClockTo();
wrapper = makeWrapper({ date: now.add(5, 'days') });
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"in 5 days"}');
});
it('formats due date to tomorrow if today but before dayStart', () => {
const now = setClockTo('2019-06-12T04:23:37+02:00');
wrapper = makeWrapper({ date: now.add(8, 'hours') }, { preferences: { dayStart: 7 } });
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"in a day"}');
});
});
});
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+1 -1
View File
@@ -312,7 +312,7 @@
"teamBasedTasksList": "Team-Based Task List",
"teamBasedTasksListDesc": "Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!",
"groupManagementControls": "Group Management Controls",
"groupManagementControlsDesc": "Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
"groupManagementControlsDesc": "View task status to verify that a task that was completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
"inGameBenefits": "In-Game Benefits",
"inGameBenefitsDesc": "Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.",
"inspireYourParty": "Inspire your party, gamify life together.",
+1 -1
View File
@@ -312,7 +312,7 @@
"teamBasedTasksList": "Team-Based Task List",
"teamBasedTasksListDesc": "Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!",
"groupManagementControls": "Group Management Controls",
"groupManagementControlsDesc": "Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
"groupManagementControlsDesc": "View task status to verify that a task that was completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
"inGameBenefits": "In-Game Benefits",
"inGameBenefitsDesc": "Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.",
"inspireYourParty": "Inspire your party, gamify life together.",
+4 -1
View File
@@ -147,5 +147,8 @@
"achievementBoneToPickModalText": "لقد جمعت كل الحيوانات الأليفة الهيكلية المغامرة والكلاسيكية!",
"achievementPlantParent": "والد النبات",
"achievementPlantParentText": "فقست جميع الحيوانات الأليفة النباتية في الألوان القياسية: الصبار والتريلنج!",
"achievementPlantParentModalText": "لقد جمعت كل الحيوانات الأليفة النباتية!"
"achievementPlantParentModalText": "لقد جمعت كل الحيوانات الأليفة النباتية!",
"achievementDinosaurDynastyModalText": "لقد جمعت جميع الطيور والديناسورات الأليفة!",
"achievementDinosaurDynasty": "سلالة الديناصورات",
"achievementDinosaurDynastyText": "لقد فقست جميع الألوان القياسية للطيور والديناسورات الأليفة: الصقر، البومة، الببغاء، الطاووس، البطريق، الديك، الزاحف المجنح، التي ريكس،الترايسيراتوبس، و الفيلوسيرابتور!"
}
+3 -2
View File
@@ -6,7 +6,7 @@
"webFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn Experience and Gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as pets, skills, and quests! For more detail, check out a step-by-step overview of the game at [Help -> Overview for New Users](https://habitica.com/static/overview).",
"faqQuestion1": "كيف أضيف مهماتي؟",
"iosFaqAnswer1": "العادات الجيدة (تلك التي تحتوي على علامة \"+\") هي المهام التي يمكنك القيام بها عدة مرات في اليوم، مثل تناول الخضروات. العادات السيئة (تلك التي تحتوي على علامة \"-\") هي المهام التي يجب عليك تجنبها، مثل عض الأظافر. والعادات التي تحتوي على علامة \"+\" و \"-\" لديها خيار جيد وخيار سيئ، مثل استخدام الدرج بدلاً من المصعد.\n\nالعادات الجيدة تمنحك خبرة وذهب. والعادات السيئة تقلل من صحتك.\n\nالمهام اليومية هي المهام التي يجب عليك القيام بها كل يوم، مثل تنظيف أسنانك أو التحقق من بريدك الإلكتروني. يمكنك تعديل تواريخ المهام اليومية بالنقر لتحريرها. إذا تخطيت مهمة يومية محددة، فسيتلقى أفاتارك ضررًا خلال الليل. كن حذرًا من عدم إضافة العديد من المهام اليومية في وقت واحد!\n\nالمهام التي يجب القيام بها هي قائمة المهام الخاصة بك. إكمال المهام يمنحك الذهب والخبرة. لن تفقد أبدًا صحتك بسبب هذه المهام. يمكنك إضافة تاريخ استحقاق للمهام التي يجب القيام بها بالنقر لتحريرها.",
"androidFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your character will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
"androidFaqAnswer1": "العادات الجيدة (تلك التي لديها +) هي المهام التي تقوم بها عدة مرات في اليوم، كأكل الخضروات مثلا. العادات السيئة (تلك التي لديها -) هي المهام التي يجب عليك تجنبها، كعض الأظافر مثلا. العادات التي لها + و لها خيار جيد وخيار سيء، كصعود الدرج مقابل ركوب المصعد. العادات الجيدة تجزيك بالنقات والذهب. العادات السيئة تطرح نقاط الحياة.\n\nاليوميات هي المهام التي يجب عليك القيام بها كل يوم، كتفريش أسنانك أو تفقد بريدك الإلكتروني. بإمكانك تحديد أيام أجل يومية بالنقر عليها لتحديثها. إذا تخطيت يومية أجلها اليوم، فستأخد شخصيتك الضرر الليلة. كن حذرا حتى لا تضيف الكثير من اليوميات مرة واحدة!\n\nالمهام هي قائمة المهام الخاصة بك. إكمال المهام يكسبك الذهب والنقاط. لا تفقد نقاط الحيات أبدا من المهام. يمكنك إضافة تاريخ أجل إلى المهام من خلال الضغط على \"تحديث\".",
"webFaqAnswer1": "* Good Habits (the ones with a :heavy_plus_sign:) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a :heavy_minus_sign:) are tasks that you should avoid, like biting nails. Habits with a :heavy_plus_sign: and a :heavy_minus_sign: have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award Experience and Gold. Bad Habits subtract Health.\n* Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by clicking the pencil item to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n* To-Dos are your To-Do list. Completing a To-Do earns you Gold and Experience. You never lose Health from To-Dos. You can add a due date to a To-Do by clicking the pencil icon to edit.",
"faqQuestion2": "ما هي أمثلة المهمات؟",
"iosFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n<br><br>\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
@@ -54,5 +54,6 @@
"webFaqAnswer12": "World Bosses are special monsters that appear in the Tavern. All active users are automatically battling the Boss, and their tasks and Skills will damage the Boss as usual. You can also be in a normal Quest at the same time. Your tasks and Skills will count towards both the World Boss and the Boss/Collection Quest in your party. A World Boss will never hurt you or your account in any way. Instead, it has a Rage Bar that fills when users skip Dailies. If its Rage bar fills, it will attack one of the Non-Player Characters around the site and their image will change. You can read more about [past World Bosses](http://habitica.wikia.com/wiki/World_Bosses) on the wiki.",
"iosFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
"androidFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
"webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the [Habitica Help guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! We're happy to help."
"webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the [Habitica Help guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! We're happy to help.",
"general": "عام"
}
+1 -1
View File
@@ -312,7 +312,7 @@
"teamBasedTasksList": "Team-Based Task List",
"teamBasedTasksListDesc": "Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!",
"groupManagementControls": "Group Management Controls",
"groupManagementControlsDesc": "Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
"groupManagementControlsDesc": "View task status to verify that a task that was completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.",
"inGameBenefits": "In-Game Benefits",
"inGameBenefitsDesc": "Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.",
"inspireYourParty": "Inspire your party, gamify life together.",

Some files were not shown because too many files have changed in this diff Show More