Compare commits

...

116 Commits

Author SHA1 Message Date
Sabe Jones 07e5bf1437 4.78.0 2018-12-31 23:48:21 +00:00
Sabe Jones d2ca738256 chore(i18n): update locales 2018-12-31 23:48:11 +00:00
Sabe Jones f7983f39eb feat(event): New Year's 2018-19 2018-12-31 17:44:13 -06:00
Sabe Jones 82d0e737a6 4.77.6 2018-12-27 15:47:36 +00:00
Sabe Jones f8213aaf1b chore(i18n): update locales 2018-12-27 15:47:25 +00:00
Matteo Pagliazzi 2335ad4167 fix(gems modal): remove duplicate id property, fix #10919 2018-12-27 15:04:14 +01:00
Sabe Jones 88f28188a1 4.77.5 2018-12-21 20:45:20 +00:00
Sabe Jones fce5be2e8f chore(i18n): update locales 2018-12-21 20:44:16 +00:00
Sabe Jones 1d68cbfaa2 chore(news): more Bailey 2018-12-21 14:42:11 -06:00
Sabe Jones a44222a350 4.77.4 2018-12-20 16:37:04 -06:00
Sabe Jones 4d2510e322 fix(sprites): add missing dragon icon 2018-12-20 16:36:57 -06:00
Sabe Jones 3b5ed33e03 4.77.3 2018-12-20 21:29:58 +00:00
Sabe Jones 0a6bf92b6b chore(i18n): update locales 2018-12-20 21:29:24 +00:00
Sabe Jones 05ae40bc2e fix(content): correct timeframe tag for string 2018-12-20 15:26:17 -06:00
Sabe Jones 57e96ea092 4.77.2 2018-12-20 12:14:38 -06:00
Sabe Jones ea49b5b8e0 fix(content): add set string for Dec Mystery 2018-12-20 12:14:28 -06:00
Sabe Jones 11a5de714a 4.77.1 2018-12-20 17:25:33 +00:00
Sabe Jones f74b4d3e73 Merge branch 'develop' into release 2018-12-20 17:24:59 +00:00
Sabe Jones ab6fdb99af 4.77.0 2018-12-20 17:23:29 +00:00
Sabe Jones e3efa557dd chore(i18n): update locales 2018-12-20 17:22:57 +00:00
Sabe Jones a6cea47789 feat(event): Winter Wonderland 2018 2018-12-20 11:11:50 -06:00
Sabe Jones 5a200a88bd chore(sprites): compile 2018-12-20 09:42:04 -06:00
Sabe Jones 545499ea0b WIP(event): partial content build 2018-12-20 09:40:54 -06:00
Sabe Jones 3e7f4229ec Merge branch 'release' into develop 2018-12-19 13:03:20 +00:00
Sabe Jones 56d5f77b6e 4.76.1 2018-12-19 13:02:58 +00:00
Sabe Jones efdf5a2e16 chore(i18n): update locales 2018-12-19 13:01:40 +00:00
Sabe Jones add3a2887f fix(css): restore close svg defaults 2018-12-19 06:58:56 -06:00
Sabe Jones 0ed7c7596a Merge branch 'release' into develop 2018-12-18 21:32:39 +00:00
Sabe Jones 55a452694f 4.76.0 2018-12-18 21:32:12 +00:00
Sabe Jones cd4d5f83ff chore(i18n): update locales 2018-12-18 21:31:56 +00:00
Sabe Jones 8220199e49 Gift 1 Get 1 Promo 2018-19! (#10915)
* feat(subscription): promo banner in modal

* feat(subscription): promo banner on main page

* fix(banners): remove extraneous margin adjustment

* fix(banners): various

* feat(promotion): gift 1, get 1

* fix(promo): various

* chore(promo): add Bailey

* fix(promo): use different email template for promo beneficiary

* fix(promo): turns out Winter is meaningful
2018-12-18 15:28:53 -06:00
Sabe Jones bd1f6918ba fix(sprites): wolf and penguin tweaks 2018-12-18 12:22:46 -06:00
Matteo Pagliazzi 5b21e62647 fix(i18n): format 2018-12-18 15:02:03 +01:00
Matteo Pagliazzi 5e76d6df21 fix(i18n): position of $ sign 2018-12-17 13:12:35 +01:00
Matteo Pagliazzi 7348145b7d fix(success-modal): misc fixes 2018-12-16 15:39:37 +01:00
Sabe Jones ba2832d21f 4.75.5 2018-12-14 21:22:05 +00:00
Sabe Jones 688f5084a1 chore(i18n): update locales 2018-12-14 21:19:56 +00:00
Sabe Jones d5955b8889 Merge branch 'develop' into release 2018-12-14 15:15:06 -06:00
Sabe Jones 01fd17ee3f fix(script): revert email query 2018-12-14 15:14:50 -06:00
Sabe Jones 979497dd35 fix(deletion): user delete bugs
Correct lookup in GDPR script, and address a TypeError when deleting a user with no tasks
2018-12-14 00:54:59 +00:00
Sabe Jones 1d3db244ba 4.75.4 2018-12-11 18:26:58 -06:00
Sabe Jones 80ca074352 fix(deploy): correct Dockerfile 2018-12-11 18:26:07 -06:00
Sabe Jones 6d4f9e0759 4.75.3 2018-12-11 20:48:40 +00:00
Sabe Jones d096695559 Usernames Misc: Bulk Email and New Party Modal (#10898)
* feat(migrations): genericize bulk email

* chore(migrations): archive one-offs

* feat(usernames): change create party modal to copy username

* fix(modal): styling

* fix(modal): add Chrome clipboard implementation
2018-12-11 20:48:34 +00:00
Sabe Jones a2c8b8b05c Usernames Misc: Bulk Email and New Party Modal (#10898)
* feat(migrations): genericize bulk email

* chore(migrations): archive one-offs

* feat(usernames): change create party modal to copy username

* fix(modal): styling

* fix(modal): add Chrome clipboard implementation
2018-12-11 14:47:50 -06:00
Sabe Jones 8750701c08 Merge branch 'release' into develop 2018-12-11 20:45:44 +00:00
Sabe Jones 900676bf0a 4.75.2 2018-12-11 20:45:15 +00:00
Sabe Jones e219daf44c chore(i18n): update locales 2018-12-11 20:44:53 +00:00
Sabe Jones 1b12a6b51f feat(content): Bird Buddies Bundle 2018-12-11 14:41:09 -06:00
Matteo Pagliazzi 8441b0a3d6 fix http auth env var 2018-12-09 20:12:50 +01:00
Matteo Pagliazzi 0667695390 Payments: Success Messages (#10903)
* fix v-once

* gems purchase success dialog

* amazon and stripe support for gems message, translations

* subscriptions success message

* subscriptions success message

* group plans success message and many fixes

* finish success messages for payments

* add success modal when gifting from balance
2018-12-09 20:08:01 +01:00
Matteo Pagliazzi 4d322c1bf6 Merge branch 'sukh0128-develop' into develop 2018-12-07 15:20:27 +01:00
Matteo Pagliazzi a855ddacc7 Merge branch 'develop' of https://github.com/sukh0128/habitica into sukh0128-develop 2018-12-07 15:20:12 +01:00
Matteo Pagliazzi 9d48ef7322 Merge pull request #10896 from AyoubElk/patch-1
Fixed typo in folder path
2018-12-07 15:13:08 +01:00
Sabe Jones 2991f7acfb 4.75.1 2018-12-06 16:23:28 +00:00
Sabe Jones 9dbfb565bb chore(i18n): update locales 2018-12-06 16:22:06 +00:00
Sabe Jones f42e22b58f Make env vars more palatable for containerization (#10895)
* refactor(env-vars): remove object/colon syntax

* fix(tests): correct config expectations
2018-12-06 10:13:49 -06:00
Ayoub El Khattabi 95f3315796 Fixed typo in folder path
The tast test:api:unit:watch should watch the path 'test/api/unit/**/*' instead of the non existent 'test/api/v3/unit/**/*'
2018-12-06 11:26:22 +00:00
Sabe Jones 18ab57eb91 Merge branch 'release' into develop 2018-12-05 20:44:02 +00:00
Sabe Jones 0dcbd8ccb8 4.75.0 2018-12-05 20:43:39 +00:00
Sabe Jones ed82b46f7b chore(i18n): update locales 2018-12-05 20:43:23 +00:00
Sabe Jones dcc3044685 chore(sprites): compile 2018-12-05 14:39:09 -06:00
Sabe Jones 5cd62d7052 feat(content): Armoire and BGs 2018-12 2018-12-05 14:38:53 -06:00
Erdenesukh Tsendjav 5e232d8c9f Merge branch 'develop' of github.com:sukh0128/habitica into develop 2018-12-04 17:29:16 -06:00
Erdenesukh Tsendjav 13793f8b3c revert 2018-12-04 17:28:27 -06:00
Erdenesukh Tsendjav 55f875f95a Delete package-lock.json 2018-12-04 17:04:55 -06:00
Erdenesukh Tsendjav 14576be374 merged 2018-12-04 16:03:11 -06:00
Erdenesukh Tsendjav 4cb2c26475 The istanbul command string in the gulp-tests.js file for each of the tests had to be changed to just the keyword istanbul instead of pointing to the istanbul file location on WINDOWS machines 2018-12-04 15:55:09 -06:00
Matteo Pagliazzi b66a0b76ef Merge pull request #10886 from jeongjinhwi/develop
Accoount Deletion Feedback:update email #10880
2018-12-04 09:38:33 +01:00
Sabe Jones dd313b17b5 fix(migration): correct push op 2018-12-03 21:06:23 -06:00
Sabe Jones bb01475e02 Merge branch 'release' into develop 2018-12-03 22:54:08 +00:00
Sabe Jones 757959529b 4.74.7 2018-12-03 22:53:23 +00:00
Sabe Jones 71ad1957b1 chore(i18n): update locales 2018-12-03 22:52:42 +00:00
Sabe Jones 3ba5ea1d2d chore(news): Bailey 2018-12-03 16:50:02 -06:00
Sabe Jones 902da35f2b fix(migration): syntax 2018-12-03 22:06:58 +00:00
Sabe Jones aaa16a9527 refactor(migrations): move Take This to new template
also fix linting error in server lib
2018-12-03 22:04:52 +00:00
Sabe Jones b98e95ee45 chore(items): deactivate premium potions 2018-12-03 15:49:09 -06:00
Matteo Pagliazzi 757160d6b7 update karma to fix tests 2018-12-03 13:33:58 +01:00
Matteo Pagliazzi 4cf68eb018 update package-lock 2018-12-03 13:22:23 +01:00
Matteo Pagliazzi e91d5e5664 Merge pull request #10863 from HabitRPG/payments/paypal-amazon-checkout
Paypal and Amazon: Improve checkout experience
2018-12-03 12:55:53 +01:00
Matteo Pagliazzi b9e12aca3e success modal and fix redirects 2018-12-02 17:33:21 +01:00
Jeong Jin Hwi 53ca9475ee Accoount Deletion Feedback:update email #10880 2018-12-03 01:04:42 +09:00
Matteo Pagliazzi e212842b50 fix redirects and basic success message 2018-12-02 15:44:52 +01:00
Matteo Pagliazzi d2f7cba43d Merge branch 'develop' into payments/paypal-amazon-checkout 2018-12-02 14:47:56 +01:00
Matteo Pagliazzi 84558f79d6 Merge pull request #10885 from HabitRPG/greenkeeper/initial
Update dependencies to enable Greenkeeper 🌴
2018-12-02 14:46:11 +01:00
Matteo Pagliazzi 178e59f287 update npm files 2018-12-02 14:44:19 +01:00
greenkeeper[bot] 7acccc0763 chore(package): update dependencies 2018-12-02 13:36:14 +00:00
Matteo Pagliazzi 8ac21d2fd4 update package-lock.json 2018-12-01 18:53:12 +01:00
Matteo Pagliazzi 7873800f87 fix(kafka queue): remove leftover code 2018-12-01 12:16:34 +01:00
Sabe Jones 727041f020 fix(chat): escape regexes so parentheses etc. don't bust it 2018-11-30 16:19:22 -06:00
Sabe Jones de0c62a37f Merge branch 'release' into develop 2018-11-30 20:28:23 +00:00
Sabe Jones 68f420991e 4.74.6 2018-11-30 20:27:53 +00:00
Sabe Jones f211ebeb0a chore(i18n): update locales 2018-11-30 20:25:45 +00:00
Sabe Jones b91ef9f539 chore(news): Last Chance Bailey
also give a few more days for items
2018-11-30 14:21:12 -06:00
Matteo Pagliazzi ac0601630e Merge branch 'develop' into payments/paypal-amazon-checkout 2018-11-30 16:11:55 +01:00
Matteo Pagliazzi 3239491144 fix(lint): remove unused params 2018-11-30 16:04:56 +01:00
Sabe Jones c3b0a73507 4.74.5 2018-11-29 14:52:02 +00:00
Sabe Jones b218eb2c00 Merge remote-tracking branch 'origin/greenkeeper/update-to-node-10' into release
also remove Kafka
2018-11-29 14:51:40 +00:00
Sabe Jones 37d9f76fea 4.74.4 2018-11-29 07:48:06 -06:00
Matteo Pagliazzi 7f2e12ba23 remove memwatch-next, try/catch 2018-11-29 14:35:22 +01:00
Matteo Pagliazzi 2cbd78b139 Merge branch 'develop' into payments/paypal-amazon-checkout 2018-11-29 10:55:13 +01:00
Matteo Pagliazzi cc751960ac save state and close tab afetr success 2018-11-21 11:42:32 +01:00
Matteo Pagliazzi 433c73c9d3 paypal: restore url after purchase 2018-11-21 11:25:36 +01:00
Matteo Pagliazzi 680c2162a7 paypal: new redirects 2018-11-21 11:19:55 +01:00
Matteo Pagliazzi 1815d2b6d3 docker: use 10 2018-10-31 17:11:59 +01:00
Matteo Pagliazzi 14cba76ba8 Merge branch 'develop' into greenkeeper/update-to-node-10 2018-10-31 17:09:08 +01:00
Erdenesukh Tsendjav 3d757c7814 trying something 2018-10-24 16:31:46 -05:00
Matteo Pagliazzi fd700f92ae remove node 8 2018-06-18 10:17:38 +02:00
Matteo Pagliazzi f41665f5a9 update deps 2018-06-18 10:04:03 +02:00
Matteo Pagliazzi 8b385c0b7b update deps 2018-06-18 10:01:09 +02:00
Matteo Pagliazzi 282f8db933 Merge branch 'develop' into greenkeeper/update-to-node-10 2018-06-18 09:57:39 +02:00
Matteo Pagliazzi 662b08c242 update engines 2018-06-18 09:57:35 +02:00
Matteo Pagliazzi b7e601be16 Merge branch 'develop' into greenkeeper/update-to-node-10 2018-04-27 19:49:11 +02:00
greenkeeper[bot] 395676fcb1 Update engines to node 10 in package.json 2018-04-27 11:41:03 +00:00
greenkeeper[bot] cc4df1c995 Update to node 10 in .nvmrc 2018-04-27 11:41:01 +00:00
greenkeeper[bot] 48eada2c37 Update to node 10 in .travis.yml 2018-04-27 11:40:58 +00:00
636 changed files with 29260 additions and 25700 deletions
+1 -1
View File
@@ -1 +1 @@
8
10
+1 -1
View File
@@ -1,6 +1,6 @@
language: node_js
node_js:
- '8'
- '10'
services:
- mongodb
cache:
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:8
FROM node:10
ENV ADMIN_EMAIL admin@habitica.com
ENV AMAZON_PAYMENTS_CLIENT_ID amzn1.application-oa2-client.68ed9e6904ef438fbc1bf86bf494056e
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:8
FROM node:10
# Install global packages
RUN npm install -g gulp-cli mocha
+79 -114
View File
@@ -1,116 +1,81 @@
{
"PORT":3000,
"ENABLE_CONSOLE_LOGS_IN_PROD":"false",
"IP":"0.0.0.0",
"WEB_CONCURRENCY":1,
"BASE_URL":"http://localhost:3000",
"FACEBOOK_KEY":"123456789012345",
"FACEBOOK_SECRET":"aaaabbbbccccddddeeeeffff00001111",
"GOOGLE_CLIENT_ID":"123456789012345",
"GOOGLE_CLIENT_SECRET":"aaaabbbbccccddddeeeeffff00001111",
"PLAY_API": {
"CLIENT_ID": "aaaabbbbccccddddeeeeffff00001111",
"CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"ACCESS_TOKEN":"aaaabbbbccccddddeeeeffff00001111",
"REFRESH_TOKEN":"aaaabbbbccccddddeeeeffff00001111"
},
"NODE_DB_URI":"mongodb://localhost/habitrpg",
"TEST_DB_URI":"mongodb://localhost/habitrpg_test",
"NODE_ENV":"development",
"ENABLE_CONSOLE_LOGS_IN_TEST": "false",
"CRON_SAFE_MODE":"false",
"CRON_SEMI_SAFE_MODE":"false",
"MAINTENANCE_MODE": "false",
"SESSION_SECRET":"YOUR SECRET HERE",
"SESSION_SECRET_KEY": "1234567891234567891234567891234567891234567891234567891234567891",
"SESSION_SECRET_IV": "12345678912345678912345678912345",
"ADMIN_EMAIL": "you@example.com",
"SMTP_USER":"user@example.com",
"SMTP_PASS":"password",
"SMTP_SERVICE":"Gmail",
"SMTP_HOST":"example.com",
"SMTP_PORT": 587,
"SMTP_TLS": true,
"STRIPE_API_KEY":"aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY":"22223333444455556666777788889999",
"NEW_RELIC_LICENSE_KEY":"NEW_RELIC_LICENSE_KEY",
"NEW_RELIC_NO_CONFIG_FILE":"true",
"NEW_RELIC_APPLICATION_ID":"NEW_RELIC_APPLICATION_ID",
"NEW_RELIC_API_KEY":"NEW_RELIC_API_KEY",
"GA_ID": "GA_ID",
"AMPLITUDE_KEY": "AMPLITUDE_KEY",
"AMPLITUDE_SECRET": "AMPLITUDE_SECRET",
"AMAZON_PAYMENTS": {
"SELLER_ID": "SELLER_ID",
"CLIENT_ID": "CLIENT_ID",
"MWS_KEY": "",
"MWS_SECRET": "",
"MODE": "sandbox"
},
"FLAG_REPORT_EMAIL": "email@mod.com,email2@mod.com",
"EMAIL_SERVER": {
"url": "http://example.com",
"authUser": "user",
"authPassword": "password"
},
"S3":{
"bucket":"bucket",
"accessKeyId":"accessKeyId",
"secretAccessKey":"secretAccessKey"
},
"SLACK_URL": "https://hooks.slack.com/services/some-url",
"TRANSIFEX_SLACK_CHANNEL": "transifex",
"PAYPAL":{
"billing_plans": {
"basic_earned":"basic_earned",
"basic_3mo":"basic_3mo",
"basic_6mo":"basic_6mo",
"google_6mo":"google_6mo",
"basic_12mo":"basic_12mo"
},
"mode":"sandbox",
"client_id":"client_id",
"client_secret":"client_secret",
"experience_profile_id": ""
},
"IAP_GOOGLE_KEYDIR": "/path/to/google/public/key/dir/",
"LOGGLY_TOKEN": "token",
"LOGGLY_CLIENT_TOKEN": "token",
"LOGGLY_ACCOUNT": "account",
"PUSH_CONFIGS": {
"GCM_SERVER_API_KEY": "",
"APN_ENABLED": "false",
"APN_KEY_ID": "xxxxxxxxxx",
"APN_KEY": "xxxxxxxxxx",
"APN_TEAM_ID": "aaabbbcccd",
"FCM_SERVER_API_KEY": ""
},
"SITE_HTTP_AUTH": {
"ENABLED": "false",
"USERNAME": "admin",
"PASSWORD": "password"
},
"SLACK": {
"FLAGGING_URL": "https://hooks.slack.com/services/id/id/id",
"FLAGGING_FOOTER_LINK": "https://habitrpg.github.io/flag-o-rama/",
"SUBSCRIPTIONS_URL": "https://hooks.slack.com/services/id/id/id"
},
"ITUNES_SHARED_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"EMAILS" : {
"COMMUNITY_MANAGER_EMAIL" : "admin@habitica.com",
"TECH_ASSISTANCE_EMAIL" : "admin@habitica.com",
"PRESS_ENQUIRY_EMAIL" : "admin@habitica.com"
},
"LOGGLY" : {
"TOKEN" : "example-token",
"SUBDOMAIN" : "exmaple-subdomain"
},
"KAFKA": {
"GROUP_ID": "",
"CLOUDKARAFKA_BROKERS": "",
"CLOUDKARAFKA_USERNAME": "",
"CLOUDKARAFKA_PASSWORD": "",
"CLOUDKARAFKA_TOPIC_PREFIX": ""
},
"MIGRATION_CONNECT_STRING": "mongodb://localhost:27017/habitrpg?auto_reconnect=true"
"ADMIN_EMAIL": "you@example.com",
"AMAZON_PAYMENTS_CLIENT_ID": "CLIENT_ID",
"AMAZON_PAYMENTS_MODE": "sandbox",
"AMAZON_PAYMENTS_MWS_KEY": "MWS_KEY",
"AMAZON_PAYMENTS_MWS_SECRET": "MWS_SECRET",
"AMAZON_PAYMENTS_SELLER_ID": "SELLER_ID",
"AMPLITUDE_KEY": "AMPLITUDE_KEY",
"AMPLITUDE_SECRET": "AMPLITUDE_SECRET",
"BASE_URL": "http://localhost:3000",
"CRON_SAFE_MODE": "false",
"CRON_SEMI_SAFE_MODE": "false",
"DISABLE_REQUEST_LOGGING": "true",
"EMAILS_COMMUNITY_MANAGER_EMAIL": "admin@habitica.com",
"EMAILS_PRESS_ENQUIRY_EMAIL": "admin@habitica.com",
"EMAILS_TECH_ASSISTANCE_EMAIL": "admin@habitica.com",
"EMAIL_SERVER_AUTH_PASSWORD": "password",
"EMAIL_SERVER_AUTH_USER": "user",
"EMAIL_SERVER_URL": "http://example.com",
"ENABLE_CONSOLE_LOGS_IN_PROD": "false",
"ENABLE_CONSOLE_LOGS_IN_TEST": "false",
"FACEBOOK_KEY": "123456789012345",
"FACEBOOK_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"FLAG_REPORT_EMAIL": "email@example.com, email2@example.com",
"GA_ID": "GA_ID",
"GOOGLE_CLIENT_ID": "123456789012345",
"GOOGLE_CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"IAP_GOOGLE_KEYDIR": "/path/to/google/public/key/dir/",
"IGNORE_REDIRECT": "true",
"ITUNES_SHARED_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"LOGGLY_CLIENT_TOKEN": "token",
"LOGGLY_SUBDOMAIN": "example-subdomain",
"LOGGLY_TOKEN": "example-token",
"MAINTENANCE_MODE": "false",
"NODE_DB_URI": "mongodb://localhost/habitrpg",
"NODE_ENV": "development",
"PATH": "bin:node_modules/.bin:/usr/local/bin:/usr/bin:/bin",
"PAYPAL_BILLING_PLANS_basic_12mo": "basic_12mo",
"PAYPAL_BILLING_PLANS_basic_3mo": "basic_3mo",
"PAYPAL_BILLING_PLANS_basic_6mo": "basic_6mo",
"PAYPAL_BILLING_PLANS_basic_earned": "basic_earned",
"PAYPAL_BILLING_PLANS_google_6mo": "google_6mo",
"PAYPAL_CLIENT_ID": "client_id",
"PAYPAL_CLIENT_SECRET": "client_secret",
"PAYPAL_EXPERIENCE_PROFILE_ID": "xp_profile_id",
"PAYPAL_MODE": "sandbox",
"PLAY_API_ACCESS_TOKEN": "aaaabbbbccccddddeeeeffff00001111",
"PLAY_API_CLIENT_ID": "aaaabbbbccccddddeeeeffff00001111",
"PLAY_API_CLIENT_SECRET": "aaaabbbbccccddddeeeeffff00001111",
"PLAY_API_REFRESH_TOKEN": "aaaabbbbccccddddeeeeffff00001111",
"PORT": 3000,
"PUSH_CONFIGS_APN_ENABLED": "false",
"PUSH_CONFIGS_APN_KEY": "xxxxxxxxxx",
"PUSH_CONFIGS_APN_KEY_ID": "xxxxxxxxxx",
"PUSH_CONFIGS_APN_TEAM_ID": "aaabbbcccd",
"PUSH_CONFIGS_FCM_SERVER_API_KEY": "aaabbbcccd",
"S3_ACCESS_KEY_ID": "accessKeyId",
"S3_BUCKET": "bucket",
"S3_SECRET_ACCESS_KEY": "secretAccessKey",
"SESSION_SECRET": "YOUR SECRET HERE",
"SESSION_SECRET_IV": "12345678912345678912345678912345",
"SESSION_SECRET_KEY": "1234567891234567891234567891234567891234567891234567891234567891",
"SITE_HTTP_AUTH_ENABLED": "false",
"SITE_HTTP_AUTH_PASSWORD": "password",
"SITE_HTTP_AUTH_USERNAME": "admin",
"SLACK_FLAGGING_FOOTER_LINK": "https://habitrpg.github.io/flag-o-rama/",
"SLACK_FLAGGING_URL": "https://hooks.slack.com/services/id/id/id",
"SLACK_SUBSCRIPTIONS_URL": "https://hooks.slack.com/services/id/id/id",
"SLACK_URL": "https://hooks.slack.com/services/some-url",
"SMTP_HOST": "example.com",
"SMTP_PASS": "password",
"SMTP_PORT": 587,
"SMTP_SERVICE": "Gmail",
"SMTP_TLS": "true",
"SMTP_USER": "user@example.com",
"STRIPE_API_KEY": "aaaabbbbccccddddeeeeffff00001111",
"STRIPE_PUB_KEY": "22223333444455556666777788889999",
"TEST_DB_URI": "mongodb://localhost/habitrpg_test",
"TRANSIFEX_SLACK_CHANNEL": "transifex",
"WEB_CONCURRENCY": 1
}
+5 -5
View File
@@ -167,7 +167,7 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
gulp.task('test:api:unit', (done) => {
let runner = exec(
testBin('node_modules/.bin/istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
testBin('istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
(err) => {
if (err) {
process.exit(1);
@@ -180,12 +180,12 @@ gulp.task('test:api:unit', (done) => {
});
gulp.task('test:api:unit:watch', () => {
return gulp.watch(['website/server/libs/*', 'test/api/v3/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done()));
return gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done()));
});
gulp.task('test:api-v3:integration', (done) => {
let runner = exec(
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
{maxBuffer: 500 * 1024},
(err) => {
if (err) {
@@ -217,7 +217,7 @@ gulp.task('test:api-v3:integration:separate-server', (done) => {
gulp.task('test:api-v4:integration', (done) => {
let runner = exec(
testBin('node_modules/.bin/istanbul cover --dir coverage/api-v4-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
{maxBuffer: 500 * 1024},
(err) => {
if (err) {
@@ -254,4 +254,4 @@ gulp.task('test:api-v3', gulp.series(
'test:api:unit',
'test:api-v3:integration',
done => done()
));
));
+110
View File
@@ -0,0 +1,110 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20181231_nye';
import { model as User } from '../../../website/server/models/user';
import mongoose from 'mongoose';
import { v4 as uuid } from 'uuid';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
const set = {'flags.newStuff': true};
let push;
set.migration = MIGRATION_NAME;
if (typeof user.items.gear.owned.head_special_nye2017 !== 'undefined') {
set['items.gear.owned.head_special_nye2018'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2018',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2016 !== 'undefined') {
set['items.gear.owned.head_special_nye2017'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2017',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2015 !== 'undefined') {
set['items.gear.owned.head_special_nye2016'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2016',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye2014 !== 'undefined') {
set['items.gear.owned.head_special_nye2015'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2015',
_id: uuid(),
},
];
} else if (typeof user.items.gear.owned.head_special_nye !== 'undefined') {
set['items.gear.owned.head_special_nye2014'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye2014',
_id: uuid(),
},
];
} else {
set['items.gear.owned.head_special_nye'] = false;
push = [
{
type: 'marketGear',
path: 'gear.flat.head_special_nye',
_id: uuid(),
},
];
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
}
module.exports = async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
};
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],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
+1 -1
View File
@@ -17,7 +17,7 @@ function setUpServer () {
setUpServer();
// Replace this with your migration
const processUsers = require('./users/20181122_turkey_day.js');
const processUsers = require('./archive/2018/20181231_nye.js');
processUsers()
.then(function success () {
process.exit(0);
+61
View File
@@ -0,0 +1,61 @@
/* eslint-disable no-console */
import { sendTxn } from '../../../website/server/libs/email';
import { model as User } from '../../website/server/models/user';
import moment from 'moment';
import nconf from 'nconf';
const BASE_URL = nconf.get('BASE_URL');
const EMAIL_SLUG = 'mandrill-email-slug'; // Set email template to send
const MIGRATION_NAME = 'bulk-email';
const progressCount = 1000;
let count = 0;
async function updateUser (user) {
count++;
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
sendTxn(
user,
EMAIL_SLUG,
[{name: 'BASE_URL', content: BASE_URL}] // Add variables from template
);
return await User.update({_id: user._id}, {$set: {migration: MIGRATION_NAME}}).exec();
}
module.exports = async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
'auth.timestamps.loggedin': {$gt: moment().subtract(2, 'weeks').toDate()}, // customize or remove to target different populations
};
const fields = {
_id: 1,
auth: 1,
preferences: 1,
profile: 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],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
+2 -2
View File
@@ -1,6 +1,6 @@
/* eslint-disable no-console */
const MIGRATION_NAME = 'mystery_items_201811';
const MYSTERY_ITEMS = ['head_mystery_201811', 'weapon_mystery_201811'];
const MIGRATION_NAME = 'mystery_items_201812';
const MYSTERY_ITEMS = ['headAccessory_mystery_201812', 'back_mystery_201812'];
import { model as User } from '../../website/server/models/user';
import { model as UserNotification } from '../../website/server/models/userNotification';
+81
View File
@@ -0,0 +1,81 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20181203_take_this';
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++;
const set = {};
let push;
set.migration = MIGRATION_NAME;
if (typeof user.items.gear.owned.back_special_takeThis !== 'undefined') {
push = false;
} else if (typeof user.items.gear.owned.body_special_takeThis !== 'undefined') {
set['items.gear.owned.back_special_takeThis'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.back_special_takeThis', _id: uuid()}};
} else if (typeof user.items.gear.owned.head_special_takeThis !== 'undefined') {
set['items.gear.owned.body_special_takeThis'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.body_special_takeThis', _id: uuid()}};
} else if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') {
set['items.gear.owned.head_special_takeThis'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_takeThis', _id: uuid()}};
} else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
set['items.gear.owned.armor_special_takeThis'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_takeThis', _id: uuid()}};
} else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set['items.gear.owned.weapon_special_takeThis'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.weapon_special_takeThis', _id: uuid()}};
} else {
set['items.gear.owned.shield_special_takeThis'] = false;
push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.shield_special_takeThis', _id: uuid()}};
}
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (push) {
return await User.update({_id: user._id}, {$set: set, $push: push}).exec();
} else {
return await User.update({_id: user._id}, {$set: set}).exec();
}
}
module.exports = async function processUsers () {
let query = {
migration: {$ne: MIGRATION_NAME},
challenges: '00708425-d477-41a5-bf27-6270466e7976',
};
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],
};
}
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
}
};
+377 -290
View File
File diff suppressed because it is too large Load Diff
+13 -16
View File
@@ -1,7 +1,7 @@
{
"name": "habitica",
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
"version": "4.74.3",
"version": "4.78.0",
"main": "./website/server/index.js",
"dependencies": {
"@slack/client": "^3.8.1",
@@ -33,7 +33,7 @@
"compression": "^1.7.2",
"cookie-session": "^1.2.0",
"coupon-code": "^0.4.5",
"cross-env": "^5.1.5",
"cross-env": "^5.2.0",
"css-loader": "^0.28.11",
"csv-stringify": "^4.3.1",
"cwait": "^1.1.1",
@@ -80,7 +80,7 @@
"ps-tree": "^1.0.0",
"pug": "^2.0.3",
"rimraf": "^2.4.3",
"sass-loader": "^7.0.0",
"sass-loader": "^7.0.3",
"shelljs": "^0.8.2",
"short-uuid": "^3.0.0",
"smartbanner.js": "^1.9.1",
@@ -90,7 +90,7 @@
"svg-url-loader": "^2.3.2",
"svgo": "^1.0.5",
"svgo-loader": "^2.1.0",
"universal-analytics": "^0.4.16",
"universal-analytics": "^0.4.17",
"update": "^0.7.4",
"upgrade": "^1.1.0",
"url-loader": "^1.0.0",
@@ -107,15 +107,15 @@
"vuedraggable": "^2.15.0",
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
"webpack": "^3.12.0",
"webpack-merge": "^4.0.0",
"winston": "^2.4.2",
"webpack-merge": "^4.1.3",
"winston": "^2.4.3",
"winston-loggly-bulk": "^2.0.2",
"xml2js": "^0.4.4"
},
"private": true,
"engines": {
"node": "^8.9.4",
"npm": "^5.6.0"
"node": "^10",
"npm": "^6"
},
"scripts": {
"lint": "eslint --ext .js,.vue .",
@@ -144,13 +144,13 @@
"apidoc": "gulp apidoc"
},
"devDependencies": {
"@vue/test-utils": "^1.0.0-beta.16",
"@vue/test-utils": "^1.0.0-beta.19",
"babel-plugin-istanbul": "^4.1.6",
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chalk": "^2.4.1",
"chromedriver": "^2.38.3",
"chromedriver": "^2.40.0",
"connect-history-api-fallback": "^1.1.0",
"coveralls": "^3.0.1",
"cross-spawn": "^6.0.5",
@@ -164,7 +164,7 @@
"expect.js": "^0.3.1",
"http-proxy-middleware": "^0.19.0",
"istanbul": "^1.1.0-alpha.1",
"karma": "^3.0.0",
"karma": "^3.1.3",
"karma-babel-preprocessor": "^7.0.0",
"karma-chai-plugins": "^0.9.0",
"karma-chrome-launcher": "^2.2.0",
@@ -180,7 +180,7 @@
"mocha": "^5.1.1",
"monk": "^6.0.6",
"nightwatch": "^0.9.21",
"puppeteer": "^1.4.0",
"puppeteer": "^1.5.0",
"require-again": "^2.0.0",
"selenium-server": "^3.12.0",
"sinon": "^6.3.5",
@@ -190,8 +190,5 @@
"webpack-dev-middleware": "^2.0.5",
"webpack-hot-middleware": "^2.22.2"
},
"optionalDependencies": {
"memwatch-next": "^0.3.0",
"node-rdkafka": "^2.3.0"
}
"optionalDependencies": {}
}
+4 -3
View File
@@ -27,12 +27,13 @@ async function _deleteAmplitudeData (userId, email) {
if (response) console.log(`${response.status} ${response.statusText}`);
}
async function _deleteHabiticaData (user) {
async function _deleteHabiticaData (user, email) {
await User.update(
{_id: user._id},
{$set: {
'auth.local.passwordHashMethod': 'bcrypt',
'auth.local.email': email,
'auth.local.hashed_password': '$2a$10$QDnNh1j1yMPnTXDEOV38xOePEWFd4X8DSYwAM8XTmqmacG5X0DKjW',
'auth.local.passwordHashMethod': 'bcrypt',
}}
);
const response = await axios.delete(
@@ -75,7 +76,7 @@ async function _processEmailAddress (email) {
} else {
for (const user of users) {
await _deleteAmplitudeData(user._id, email); // eslint-disable-line no-await-in-loop
await _deleteHabiticaData(user); // eslint-disable-line no-await-in-loop
await _deleteHabiticaData(user, email); // eslint-disable-line no-await-in-loop
}
}
}
+10 -14
View File
@@ -12,28 +12,27 @@ const nconf = require('nconf');
const _ = require('lodash');
const paypal = require('paypal-rest-sdk');
const blocks = require('../website/common').content.subscriptionBlocks;
const live = nconf.get('PAYPAL:mode') === 'live';
const live = nconf.get('PAYPAL_MODE') === 'live';
nconf.argv().env().file('user', path.join(path.resolve(__dirname, '../config.json')));
let OP = 'create'; // list create update remove
let OP = 'create'; // list get update create create-webprofile
paypal.configure({
mode: nconf.get('PAYPAL:mode'), // sandbox or live
client_id: nconf.get('PAYPAL:client_id'),
client_secret: nconf.get('PAYPAL:client_secret'),
mode: nconf.get('PAYPAL_MODE'), // sandbox or live
client_id: nconf.get('PAYPAL_CLIENT_ID'),
client_secret: nconf.get('PAYPAL_CLIENT_SECRET'),
});
// https://developer.paypal.com/docs/api/#billing-plans-and-agreements
let billingPlanTitle = 'Habitica Subscription';
let billingPlanAttributes = {
name: billingPlanTitle,
description: billingPlanTitle,
type: 'INFINITE',
merchant_preferences: {
auto_bill_amount: 'yes',
cancel_url: live ? 'https://habitica.com' : 'http://localhost:3000',
return_url: `${live ? 'https://habitica.com' : 'http://localhost:3000' }/paypal/subscribe/success`,
return_url: `${live ? 'https://habitica.com' : 'http://localhost:3000'}/paypal/subscribe/success`,
},
payment_definitions: [{
type: 'REGULAR',
@@ -45,7 +44,7 @@ let billingPlanAttributes = {
_.each(blocks, (block) => {
block.definition = _.cloneDeep(billingPlanAttributes);
_.merge(block.definition.payment_definitions[0], {
name: `${billingPlanTitle } ($${block.price} every ${block.months} months, recurring)`,
name: `${billingPlanTitle} ($${block.price} every ${block.months} months, recurring)`,
frequency_interval: `${block.months}`,
amount: {
currency: 'USD',
@@ -63,7 +62,7 @@ switch (OP) {
});
break;
case 'get':
paypal.billingPlan.get(nconf.get('PAYPAL:billing_plans:12'), (err, plan) => {
paypal.billingPlan.get(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), (err, plan) => {
console.log({err, plan});
});
break;
@@ -75,7 +74,7 @@ switch (OP) {
cancel_url: 'https://habitica.com',
},
};
paypal.billingPlan.update(nconf.get('PAYPAL:billing_plans:12'), updatePayload, (err, res) => {
paypal.billingPlan.update(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), updatePayload, (err, res) => {
console.log({err, plan: res});
});
break;
@@ -101,9 +100,6 @@ switch (OP) {
});
});
break;
case 'remove': break;
case 'create-webprofile':
let webexpinfo = {
name: 'HabiticaProfile',
@@ -116,4 +112,4 @@ switch (OP) {
console.log(error, result);
});
break;
}
}
+72 -1
View File
@@ -209,7 +209,7 @@ describe('payments/index', () => {
await api.createSubscription(data);
let msg = '\`Hello recipient, sender has sent you 3 months of subscription!\`';
expect(user.sendMessage).to.be.calledOnce;
expect(user.sendMessage).to.be.calledTwice;
expect(user.sendMessage).to.be.calledWith(recipient, { receiverMsg: msg, senderMsg: msg, save: false });
});
@@ -247,6 +247,77 @@ describe('payments/index', () => {
},
});
});
context('Winter 2018-19 Gift-1-Get-1 Promotion', async () => {
it('creates a gift subscription for purchaser and recipient if none exist', async () => {
await api.createSubscription(data);
expect(user.items.pets['Jackalope-RoyalPurple']).to.eql(5);
expect(user.purchased.plan.customerId).to.eql('Gift');
expect(user.purchased.plan.dateTerminated).to.exist;
expect(user.purchased.plan.dateUpdated).to.exist;
expect(user.purchased.plan.dateCreated).to.exist;
expect(recipient.items.pets['Jackalope-RoyalPurple']).to.eql(5);
expect(recipient.purchased.plan.customerId).to.eql('Gift');
expect(recipient.purchased.plan.dateTerminated).to.exist;
expect(recipient.purchased.plan.dateUpdated).to.exist;
expect(recipient.purchased.plan.dateCreated).to.exist;
});
it('adds extraMonths to existing subscription for purchaser and creates a gift subscription for recipient without sub', async () => {
user.purchased.plan = plan;
expect(user.purchased.plan.extraMonths).to.eql(0);
await api.createSubscription(data);
expect(user.purchased.plan.extraMonths).to.eql(3);
expect(recipient.items.pets['Jackalope-RoyalPurple']).to.eql(5);
expect(recipient.purchased.plan.customerId).to.eql('Gift');
expect(recipient.purchased.plan.dateTerminated).to.exist;
expect(recipient.purchased.plan.dateUpdated).to.exist;
expect(recipient.purchased.plan.dateCreated).to.exist;
});
it('adds extraMonths to existing subscription for recipient and creates a gift subscription for purchaser without sub', async () => {
recipient.purchased.plan = plan;
expect(recipient.purchased.plan.extraMonths).to.eql(0);
await api.createSubscription(data);
expect(recipient.purchased.plan.extraMonths).to.eql(3);
expect(user.items.pets['Jackalope-RoyalPurple']).to.eql(5);
expect(user.purchased.plan.customerId).to.eql('Gift');
expect(user.purchased.plan.dateTerminated).to.exist;
expect(user.purchased.plan.dateUpdated).to.exist;
expect(user.purchased.plan.dateCreated).to.exist;
});
it('adds extraMonths to existing subscriptions for purchaser and recipient', async () => {
user.purchased.plan = plan;
recipient.purchased.plan = plan;
expect(user.purchased.plan.extraMonths).to.eql(0);
expect(recipient.purchased.plan.extraMonths).to.eql(0);
await api.createSubscription(data);
expect(user.purchased.plan.extraMonths).to.eql(3);
expect(recipient.purchased.plan.extraMonths).to.eql(3);
});
it('sends a private message about the promotion', async () => {
await api.createSubscription(data);
let msg = '\`Hello sender, you received 3 months of subscription as part of our holiday gift-giving promotion!\`';
expect(user.sendMessage).to.be.calledTwice;
expect(user.sendMessage).to.be.calledWith(user, { senderMsg: msg });
});
});
});
context('Purchasing a subscription for self', () => {
@@ -15,6 +15,7 @@ describe('checkout', () => {
function getPaypalCreateOptions (description, amount) {
return {
experience_profile_id: 'xp_profile_id',
intent: 'sale',
payer: { payment_method: 'Paypal' },
redirect_urls: {
+1 -1
View File
@@ -110,7 +110,7 @@ describe('slack', () => {
});
it('noops if no flagging url is provided', () => {
sandbox.stub(nconf, 'get').withArgs('SLACK:FLAGGING_URL').returns('');
sandbox.stub(nconf, 'get').withArgs('SLACK_FLAGGING_URL').returns('');
sandbox.stub(logger, 'error');
let reRequiredSlack = requireAgain('../../../../website/server/libs/slack');
@@ -106,7 +106,7 @@ describe('POST /groups/:id/chat/:id/clearflags', () => {
.to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('messageCannotFlagSystemMessages', {communityManagerEmail: config.EMAILS.COMMUNITY_MANAGER_EMAIL}),
message: t('messageCannotFlagSystemMessages', {communityManagerEmail: config.EMAILS_COMMUNITY_MANAGER_EMAIL}),
});
// let messages = await members[0].get(`/groups/${group._id}/chat`);
// expect(messages[0].id).to.eql(skillMsg.id);
@@ -333,7 +333,7 @@ describe('Post /groups/:groupId/invite', () => {
.to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('inviteLimitReached', {techAssistanceEmail: nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL')}),
message: t('inviteLimitReached', {techAssistanceEmail: nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL')}),
});
});
@@ -45,7 +45,7 @@ describe('POST /user/auth/local/login', () => {
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('accountSuspended', { communityManagerEmail: nconf.get('EMAILS:COMMUNITY_MANAGER_EMAIL'), userId: user._id }),
message: t('accountSuspended', { communityManagerEmail: nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL'), userId: user._id }),
});
});
@@ -71,7 +71,7 @@ describe('PUT /user/auth/update-email', () => {
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('cannotFulfillReq', { techAssistanceEmail: nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL') }),
message: t('cannotFulfillReq', { techAssistanceEmail: nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL') }),
});
});
+8 -8
View File
@@ -15,11 +15,11 @@ setupNconf(configFile);
// @TODO: Do we need? const CLIENT_VARS = ['language', 'isStaticPage', 'availableLanguages', 'translations',
// 'FACEBOOK_KEY', 'GOOGLE_CLIENT_ID', 'NODE_ENV', 'BASE_URL', 'GA_ID',
// 'AMAZON_PAYMENTS', 'STRIPE_PUB_KEY', 'AMPLITUDE_KEY',
// 'worldDmg', 'mods', 'IS_MOBILE', 'PUSHER:KEY', 'PUSHER:ENABLED'];
// 'worldDmg', 'mods', 'IS_MOBILE'];
const AMAZON_SELLER_ID = nconf.get('AMAZON_PAYMENTS:SELLER_ID') || nconf.get('AMAZON_PAYMENTS_SELLER_ID');
const AMAZON_CLIENT_ID = nconf.get('AMAZON_PAYMENTS:CLIENT_ID') || nconf.get('AMAZON_PAYMENTS_CLIENT_ID');
const AMAZON_MODE = nconf.get('AMAZON_PAYMENTS:MODE') || nconf.get('AMAZON_PAYMENTS_MODE');
const AMAZON_SELLER_ID = nconf.get('AMAZON_PAYMENTS_SELLER_ID');
const AMAZON_CLIENT_ID = nconf.get('AMAZON_PAYMENTS_CLIENT_ID');
const AMAZON_MODE = nconf.get('AMAZON_PAYMENTS_MODE');
let env = {
NODE_ENV: '"production"',
@@ -30,13 +30,13 @@ let env = {
MODE: `"${AMAZON_MODE}"`,
},
EMAILS: {
COMMUNITY_MANAGER_EMAIL: `"${nconf.get('EMAILS:COMMUNITY_MANAGER_EMAIL')}"`,
TECH_ASSISTANCE_EMAIL: `"${nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL')}"`,
PRESS_ENQUIRY_EMAIL: `"${nconf.get('EMAILS:PRESS_ENQUIRY_EMAIL')}"`,
COMMUNITY_MANAGER_EMAIL: `"${nconf.get('EMAILS_COMMUNITY_MANAGER_EMAIL')}"`,
TECH_ASSISTANCE_EMAIL: `"${nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL')}"`,
PRESS_ENQUIRY_EMAIL: `"${nconf.get('EMAILS_PRESS_ENQUIRY_EMAIL')}"`,
},
};
'NODE_ENV BASE_URL GA_ID STRIPE_PUB_KEY FACEBOOK_KEY GOOGLE_CLIENT_ID AMPLITUDE_KEY PUSHER:KEY PUSHER:ENABLED LOGGLY_CLIENT_TOKEN'
'NODE_ENV BASE_URL GA_ID STRIPE_PUB_KEY FACEBOOK_KEY GOOGLE_CLIENT_ID AMPLITUDE_KEY LOGGLY_CLIENT_TOKEN'
.split(' ')
.forEach(key => {
env[key] = `"${nconf.get(key)}"`;
+103 -63
View File
@@ -11,22 +11,29 @@ div
#app(:class='{"casting-spell": castingSpell}')
banned-account-modal
amazon-payments-modal(v-if='!isStaticPage')
payments-success-modal
snackbars
router-view(v-if="!isUserLoggedIn || isStaticPage")
template(v-else)
template(v-if="isUserLoaded")
div.resting-banner(v-show="showRestingBanner", ref="restingBanner")
.resting-banner(v-show="showRestingBanner", ref="restingBanner")
span.content
span.label.d-inline.d-sm-none {{ $t('innCheckOutBannerShort') }}
span.label.d-none.d-sm-inline {{ $t('innCheckOutBanner') }}
span.separator |
span.resume(@click="resumeDamage()") {{ $t('resumeDamage') }}
div.closepadding(@click="hideBanner()")
.closepadding(@click="hideBanner()")
span.svg-icon.inline.icon-10(aria-hidden="true", v-html="icons.close")
.g1g1-banner.d-flex.justify-content-center.align-items-center(v-if="!giftingHidden")
.svg-icon.svg-gifts.left-gift(v-html="icons.gifts")
router-link(:to="{name: 'subscription'}") {{ $t('g1g1Announcement') }}
.svg-icon.svg-gifts.right-gift(v-html="icons.gifts")
.closepadding(@click="hideGiftingBanner()")
span.svg-icon.inline.icon-10(aria-hidden="true", v-html="icons.close")
notifications-display
app-menu(:class='{"restingInn": showRestingBanner}' :style="{ marginTop: bannerHeight + 'px' }")
app-menu
.container-fluid
app-header(:class='{"restingInn": showRestingBanner}')
app-header
buyModal(
:item="selectedItemToBuy || {}",
:withPin="true",
@@ -49,6 +56,13 @@ div
<style lang='scss' scoped>
@import '~client/assets/scss/colors.scss';
#app {
height: calc(100% - 56px); /* 56px is the menu */
display: flex;
flex-direction: column;
min-height: 100vh;
}
#loading-screen-inapp {
#melior {
margin: 0 auto;
@@ -78,6 +92,46 @@ div
cursor: crosshair;
}
.container-fluid {
overflow-x: hidden;
flex: 1 0 auto;
}
.g1g1-banner {
width: 100%;
min-height: 2.5rem;
background-color: #34b5c1;
a {
color: $white;
text-decoration: none;
font-weight: bold;
}
.closepadding {
margin: 11px 24px;
display: inline-block;
position: relative;
right: 0;
top: 0;
cursor: pointer;
}
.left-gift {
margin: auto 1rem auto auto;
}
.right-gift {
margin: auto auto auto 1rem;
filter: FlipH;
transform: scaleX(-1);
}
.svg-gifts {
width: 4.6rem;
}
}
.notification {
border-radius: 1000px;
background-color: $green-10;
@@ -88,42 +142,10 @@ div
margin-bottom: .5em;
}
.container-fluid {
overflow-x: hidden;
flex: 1 0 auto;
}
#app {
height: calc(100% - 56px); /* 56px is the menu */
display: flex;
flex-direction: column;
min-height: 100vh;
}
</style>
<style lang='scss'>
@import '~client/assets/scss/colors.scss';
/* @TODO: The modal-open class is not being removed. Let's try this for now */
.modal {
overflow-y: scroll !important;
}
.modal-backdrop.show {
opacity: .9 !important;
background-color: $purple-100 !important;
}
/* Push progress bar above modals */
#nprogress .bar {
z-index: 1600 !important; /* Must stay above nav bar */
}
.resting-banner {
width: 100%;
min-height: 40px;
background-color: $blue-10;
position: fixed;
top: 0;
z-index: 1300;
display: flex;
@@ -139,14 +161,10 @@ div
.closepadding {
margin: 11px 24px;
display: inline-block;
position: absolute;
position: relative;
right: 0;
top: 0;
cursor: pointer;
span svg path {
stroke: $blue-500;
}
}
@media only screen and (max-width: 768px) {
@@ -169,6 +187,30 @@ div
}
</style>
<style lang='scss'>
@import '~client/assets/scss/colors.scss';
.closepadding span svg path {
stroke: #FFF;
opacity: 0.48;
}
/* @TODO: The modal-open class is not being removed. Let's try this for now */
.modal {
overflow-y: scroll !important;
}
.modal-backdrop.show {
opacity: .9 !important;
background-color: $purple-100 !important;
}
/* Push progress bar above modals */
#nprogress .bar {
z-index: 1600 !important; /* Must stay above nav bar */
}
</style>
<script>
import axios from 'axios';
import { loadProgressBar } from 'axios-progress-bar';
@@ -185,8 +227,12 @@ import SelectMembersModal from 'client/components/selectMembersModal.vue';
import notifications from 'client/mixins/notifications';
import { setup as setupPayments } from 'client/libs/payments';
import amazonPaymentsModal from 'client/components/payments/amazonModal';
import spellsMixin from 'client/mixins/spells';
import paymentsSuccessModal from 'client/components/payments/successModal';
import spellsMixin from 'client/mixins/spells';
import { CONSTANTS, getLocalSetting, removeLocalSetting, setLocalSetting } from 'client/libs/userlocalManager';
import gifts from 'assets/svg/gifts.svg';
import svgClose from 'assets/svg/close.svg';
import bannedAccountModal from 'client/components/bannedAccountModal';
@@ -205,11 +251,13 @@ export default {
SelectMembersModal,
amazonPaymentsModal,
bannedAccountModal,
paymentsSuccessModal,
},
data () {
return {
icons: Object.freeze({
close: svgClose,
gifts,
}),
selectedItemToBuy: null,
selectedSpellToBuy: null,
@@ -221,6 +269,7 @@ export default {
currentTipNumber: 0,
bannerHidden: false,
bannerHeight: 0,
giftingHidden: getLocalSetting(CONSTANTS.keyConstants.GIFTING_BANNER_DISPLAY) === 'dismissed',
};
},
computed: {
@@ -418,14 +467,6 @@ export default {
this.hideLoadingScreen();
window.addEventListener('resize', this.setBannerOffset);
// Adjust the positioning of the header banners
this.$watch('showRestingBanner', () => {
this.$nextTick(() => {
this.setBannerOffset();
});
}, {immediate: true});
// Adjust the timezone offset
if (this.user.preferences.timezoneOffset !== this.browserTimezoneOffset) {
this.$store.dispatch('user:set', {
@@ -433,6 +474,14 @@ export default {
});
}
let appState = getLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
if (appState) {
appState = JSON.parse(appState);
if (appState.paymentCompleted) {
removeLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE);
this.$root.$emit('habitica:payment-success', appState);
}
}
this.$nextTick(() => {
// Load external scripts after the app has been rendered
setupPayments();
@@ -452,7 +501,6 @@ export default {
this.$root.$off('bv::show::modal');
this.$root.$off('buyModal::showItem');
this.$root.$off('selectMembersModal::showItem');
window.removeEventListener('resize', this.setBannerOffset);
},
mounted () {
// Remove the index.html loading screen and now show the inapp loading
@@ -611,22 +659,14 @@ export default {
},
hideBanner () {
this.bannerHidden = true;
this.setBannerOffset();
},
hideGiftingBanner () {
setLocalSetting(CONSTANTS.keyConstants.GIFTING_BANNER_DISPLAY, 'dismissed');
this.giftingHidden = true;
},
resumeDamage () {
this.$store.dispatch('user:sleep');
},
setBannerOffset () {
let contentPlacement = 0;
if (this.showRestingBanner && this.$refs.restingBanner !== undefined) {
contentPlacement = this.$refs.restingBanner.clientHeight;
}
this.bannerHeight = contentPlacement;
let smartBanner = document.getElementsByClassName('smartbanner')[0];
if (smartBanner !== undefined) {
smartBanner.style.top = `${contentPlacement}px`;
}
},
},
};
</script>
@@ -1,6 +1,6 @@
.achievement-costumeContest6x {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -1136px -148px;
background-position: -994px -233px;
width: 144px;
height: 156px;
}
@@ -10,65 +10,83 @@
width: 480px;
height: 360px;
}
.promo_animal_tails {
.promo_armoire_backgrounds_201812 {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -994px 0px;
width: 141px;
height: 441px;
}
.promo_armoire_backgrounds_201811 {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -481px -420px;
background-position: -481px -387px;
width: 423px;
height: 147px;
}
.promo_frost_potions {
.promo_bird_buddies_bundle {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -421px -723px;
width: 417px;
background-position: 0px -723px;
width: 420px;
height: 147px;
}
.promo_g1g1 {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -241px -871px;
width: 237px;
height: 150px;
}
.promo_ios {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -361px;
width: 375px;
height: 361px;
}
.promo_mystery_201811 {
.promo_mystery_201812 {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -839px -723px;
width: 282px;
height: 147px;
background-position: -481px -209px;
width: 393px;
height: 177px;
}
.promo_oddballs_bundle {
.promo_npc_alex {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -481px -568px;
background-position: -994px -529px;
width: 162px;
height: 138px;
}
.promo_nye_card {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -994px -668px;
width: 117px;
height: 123px;
}
.promo_seasonal_shop {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -994px -390px;
width: 162px;
height: 138px;
}
.promo_snow_potions {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -481px -535px;
width: 423px;
height: 147px;
}
.promo_piyo {
.promo_studying {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -1136px 0px;
width: 279px;
height: 147px;
background-position: -994px 0px;
width: 220px;
height: 232px;
}
.promo_take_this {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -1281px -148px;
background-position: -1112px -668px;
width: 96px;
height: 69px;
}
.promo_turkey_day_2018 {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -723px;
width: 420px;
height: 147px;
}
.promo_veteran_pets {
.promo_todos {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: 0px -871px;
width: 363px;
height: 141px;
width: 240px;
height: 195px;
}
.promo_winter_wonderland_2019 {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -421px -723px;
width: 402px;
height: 147px;
}
.scene_nametag {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
@@ -76,15 +94,3 @@
width: 512px;
height: 208px;
}
.scene_sleep {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -481px -209px;
width: 390px;
height: 210px;
}
.scene_veteran_pets {
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
background-position: -1136px -305px;
width: 242px;
height: 62px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,78 +1,144 @@
.quest_TEMPLATE_FOR_MISSING_IMAGE {
.quest_alligator {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -251px -1519px;
width: 221px;
height: 39px;
}
.quest_cow {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -175px;
width: 174px;
background-position: -1540px -1079px;
width: 201px;
height: 213px;
}
.quest_dilatory {
.quest_armadillo {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px 0px;
background-position: -1320px -440px;
width: 219px;
height: 219px;
}
.quest_dilatoryDistress1 {
.quest_atom1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px -1085px;
width: 210px;
height: 210px;
}
.quest_dilatoryDistress2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -959px;
width: 150px;
background-position: -1094px -1332px;
width: 250px;
height: 150px;
}
.quest_dilatoryDistress3 {
.quest_atom2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -642px -1519px;
width: 207px;
height: 138px;
}
.quest_atom3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -211px -1519px;
width: 216px;
height: 180px;
}
.quest_axolotl {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -232px;
width: 219px;
height: 219px;
}
.quest_badger {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px -232px;
width: 219px;
height: 219px;
}
.quest_dilatory_derby {
.quest_basilist {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1320px -660px;
width: 219px;
height: 219px;
background-position: -191px -1706px;
width: 189px;
height: 141px;
}
.quest_dustbunnies {
.quest_beetle {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px 0px;
width: 219px;
height: 219px;
background-position: -1322px -1112px;
width: 204px;
height: 201px;
}
.quest_egg {
.quest_bunny {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -751px;
width: 165px;
height: 207px;
background-position: 0px -1519px;
width: 210px;
height: 186px;
}
.quest_evilsanta {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1562px -1332px;
width: 118px;
height: 131px;
}
.quest_evilsanta2 {
.quest_butterfly {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -452px;
width: 219px;
height: 219px;
}
.quest_falcon {
.quest_cheetah {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px -452px;
width: 219px;
height: 219px;
}
.quest_cow {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px 0px;
width: 174px;
height: 213px;
}
.quest_dilatory {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px -220px;
width: 219px;
height: 219px;
}
.quest_dilatoryDistress1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px -868px;
width: 210px;
height: 210px;
}
.quest_dilatoryDistress2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -573px;
width: 150px;
height: 150px;
}
.quest_dilatoryDistress3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -672px;
width: 219px;
height: 219px;
}
.quest_dilatory_derby {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px 0px;
width: 219px;
height: 219px;
}
.quest_dustbunnies {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px -672px;
width: 219px;
height: 219px;
}
.quest_egg {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -214px;
width: 165px;
height: 207px;
}
.quest_evilsanta {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -724px;
width: 118px;
height: 131px;
}
.quest_evilsanta2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px 0px;
width: 219px;
height: 219px;
}
.quest_falcon {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px -220px;
width: 219px;
height: 219px;
}
.quest_ferret {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px -452px;
background-position: -1100px -440px;
width: 219px;
height: 219px;
}
@@ -84,19 +150,19 @@
}
.quest_ghost_stag {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px -220px;
background-position: 0px -892px;
width: 219px;
height: 219px;
}
.quest_goldenknight1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px -440px;
background-position: -220px -892px;
width: 219px;
height: 219px;
}
.quest_goldenknight2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1311px -1332px;
background-position: -1345px -1332px;
width: 250px;
height: 150px;
}
@@ -108,19 +174,19 @@
}
.quest_gryphon {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1322px -1112px;
background-position: -660px -1332px;
width: 216px;
height: 177px;
}
.quest_guineapig {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px -672px;
background-position: -1100px -892px;
width: 219px;
height: 219px;
}
.quest_harpy {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px -672px;
background-position: -1320px 0px;
width: 219px;
height: 219px;
}
@@ -132,109 +198,109 @@
}
.quest_hippo {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px -220px;
background-position: -220px 0px;
width: 219px;
height: 219px;
}
.quest_horse {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px -440px;
background-position: -1320px -660px;
width: 219px;
height: 219px;
}
.quest_kangaroo {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px -660px;
background-position: -1320px -880px;
width: 219px;
height: 219px;
}
.quest_kraken {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -877px -1332px;
background-position: -443px -1332px;
width: 216px;
height: 177px;
}
.quest_lostMasterclasser1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -892px;
background-position: -220px -1112px;
width: 219px;
height: 219px;
}
.quest_lostMasterclasser2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px -892px;
background-position: -440px -1112px;
width: 219px;
height: 219px;
}
.quest_lostMasterclasser3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px -892px;
background-position: -660px -1112px;
width: 219px;
height: 219px;
}
.quest_mayhemMistiflying1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -1261px;
background-position: -1757px -422px;
width: 150px;
height: 150px;
}
.quest_mayhemMistiflying2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px -892px;
background-position: -1100px -660px;
width: 219px;
height: 219px;
}
.quest_mayhemMistiflying3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1320px 0px;
background-position: -880px -672px;
width: 219px;
height: 219px;
}
.quest_monkey {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1320px -220px;
background-position: -880px -440px;
width: 219px;
height: 219px;
}
.quest_moon1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px -217px;
background-position: -1540px -434px;
width: 216px;
height: 216px;
}
.quest_moon2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px 0px;
background-position: -660px -452px;
width: 219px;
height: 219px;
}
.quest_moon3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1320px -880px;
background-position: -660px -892px;
width: 219px;
height: 219px;
}
.quest_moonstone1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: 0px -1112px;
background-position: -880px -892px;
width: 219px;
height: 219px;
}
.quest_moonstone2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -1112px;
background-position: 0px -1112px;
width: 219px;
height: 219px;
}
.quest_moonstone3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px -1112px;
background-position: -1320px -220px;
width: 219px;
height: 219px;
}
.quest_nudibranch {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px -868px;
background-position: -1540px 0px;
width: 216px;
height: 216px;
}
@@ -246,73 +312,73 @@
}
.quest_owl {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px -1112px;
background-position: -440px -892px;
width: 219px;
height: 219px;
}
.quest_peacock {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px 0px;
background-position: -1540px -217px;
width: 216px;
height: 216px;
}
.quest_penguin {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -567px;
background-position: 0px -1706px;
width: 190px;
height: 183px;
}
.quest_pterodactyl {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1320px -440px;
background-position: -660px -672px;
width: 219px;
height: 219px;
}
.quest_rat {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px -892px;
background-position: 0px -672px;
width: 219px;
height: 219px;
}
.quest_rock {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px -434px;
background-position: -1540px -651px;
width: 216px;
height: 216px;
}
.quest_rooster {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px 0px;
background-position: -428px -1519px;
width: 213px;
height: 174px;
}
.quest_sabretooth {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: 0px -892px;
background-position: 0px -452px;
width: 219px;
height: 219px;
}
.quest_seaserpent {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1100px 0px;
background-position: -660px -220px;
width: 219px;
height: 219px;
}
.quest_sheep {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -440px -672px;
background-position: -660px 0px;
width: 219px;
height: 219px;
}
.quest_slime {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: 0px -672px;
background-position: 0px -232px;
width: 219px;
height: 219px;
}
.quest_sloth {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -880px 0px;
background-position: -440px 0px;
width: 219px;
height: 219px;
}
@@ -324,79 +390,7 @@
}
.quest_snake {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px -1332px;
background-position: -877px -1332px;
width: 216px;
height: 177px;
}
.quest_spider {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: 0px -1519px;
width: 250px;
height: 150px;
}
.quest_squirrel {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: 0px -452px;
width: 219px;
height: 219px;
}
.quest_stoikalmCalamity1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -1412px;
width: 150px;
height: 150px;
}
.quest_stoikalmCalamity2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -660px -220px;
width: 219px;
height: 219px;
}
.quest_stoikalmCalamity3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -232px;
width: 219px;
height: 219px;
}
.quest_taskwoodsTerror1 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -1110px;
width: 150px;
height: 150px;
}
.quest_taskwoodsTerror2 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1540px -651px;
width: 216px;
height: 216px;
}
.quest_taskwoodsTerror3 {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: 0px -232px;
width: 219px;
height: 219px;
}
.quest_treeling {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1094px -1332px;
width: 216px;
height: 177px;
}
.quest_trex {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -1757px -389px;
width: 204px;
height: 177px;
}
.quest_trex_undead {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -443px -1332px;
width: 216px;
height: 177px;
}
.quest_triceratops {
background-image: url('~assets/images/sprites/spritesmith-main-11.png');
background-position: -220px -672px;
width: 219px;
height: 219px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 KiB

After

Width:  |  Height:  |  Size: 537 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 KiB

After

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 KiB

After

Width:  |  Height:  |  Size: 394 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

After

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 120 KiB

+5 -5
View File
@@ -2,8 +2,8 @@
// possible values are: normal, fall, habitoween, thanksgiving, winter, nye, birthday, valentines, spring, summer
// more to be added on future seasons
$npc_market_flavor: 'normal';
$npc_quests_flavor: 'normal';
$npc_seasonal_flavor: 'normal';
$npc_timetravelers_flavor: 'normal';
$npc_tavern_flavor: 'normal';
$npc_market_flavor: 'nye';
$npc_quests_flavor: 'nye';
$npc_seasonal_flavor: 'nye';
$npc_timetravelers_flavor: 'winter';
$npc_tavern_flavor: 'nye';
+44
View File
@@ -0,0 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" width="73" height="27" viewBox="0 0 73 27">
<g fill="none" fill-rule="evenodd">
<path fill="#8EEDF6" d="M4.333 9.757l2.166-.554-1.742-1.401-.554-2.166-1.401 1.742-2.166.554 1.742 1.4.554 2.167zM70.333 5.757l2.166-.554-1.742-1.401-.554-2.166-1.401 1.742-2.166.554 1.742 1.4.554 2.167zM37.147 5.518l2.573.428-1.202-2.315.428-2.574-2.315 1.202-2.574-.427 1.202 2.315-.427 2.573zM68.735 22.132l2.367 1.812.03-2.981 1.812-2.368-2.981-.03-2.368-1.812-.03 2.982-1.812 2.367zM33.676 23.656l1.839.305-.859-1.653.305-1.839-1.653.859-1.839-.305.859 1.653-.305 1.839zM10.695 25.362l.805 1.68.862-1.651 1.68-.804-1.651-.862-.804-1.681-.862 1.652-1.681.804z"/>
<path fill="#F8F9F9" d="M21.862 9.542l5.914-1.585 2.219 8.28-5.914 1.584z"/>
<path fill="#DDF3F3" d="M15.949 11.126l5.913-1.584 2.219 8.28-5.914 1.584z"/>
<path fill="#FFA624" d="M20.68 9.859l1.182-.317 2.219 8.28-1.183.316z"/>
<path fill="#FFBE5D" d="M21.862 9.542l1.183-.317 2.219 8.28-1.183.316z"/>
<path fill="#EE9109" d="M22.581 16.955l1.183-.317.317 1.183-1.183.317zM20.68 9.859l1.182-.317.317 1.183-1.182.317z"/>
<path fill="#C1E9E9" d="M15.949 11.126l4.73-1.267.318 1.183-4.732 1.267zM17.85 18.223l4.731-1.268.317 1.183-4.731 1.268z"/>
<path fill="#DDF3F3" d="M23.045 9.225l4.731-1.268.317 1.183-4.73 1.268zM24.947 16.322l4.73-1.268.318 1.183-4.731 1.267z"/>
<path fill="#FFA624" d="M23.764 16.638l1.183-.316.317 1.182-1.183.317zM21.862 9.542l1.183-.317.317 1.183-1.183.317z"/>
<g>
<path stroke="#FFA624" stroke-width="1.5" d="M21.737 3.348c-.295-1.038-1.009-2.02-2.008-2.204-1-.184-1.69.542-1.495 1.297.195.755.88.984 3.075 1.916.623.264.723.03.428-1.009z"/>
<path stroke="#FFBE5D" stroke-width="1.5" d="M24.307 3.71c.57-.918 1.527-1.664 2.538-1.565 1.012.098 1.475.986 1.08 1.658-.396.671-1.117.703-3.484.994-.672.083-.703-.17-.134-1.088z"/>
<path fill="#EE9109" d="M23.129 2.769c-1.968-.277-1.106 2.141-.317 2.252.79.111 2.285-1.976.317-2.252z"/>
<path fill="#F8F9F9" d="M22.862 4.665l7.276 1.022-.511 3.638-7.276-1.022z"/>
<path fill="#DDF3F3" d="M15.587 3.642l7.275 1.023-.51 3.638-7.276-1.023z"/>
<path fill="#FFBE5D" d="M20.437 4.324l4.85.682-.51 3.638-4.85-.682z"/>
<path fill="#FFA624" d="M20.437 4.324l2.425.341-.51 3.638-2.426-.341z"/>
<path fill="#FFA624" d="M22.862 4.665l2.426.34-.17 1.213-2.426-.34z"/>
<path fill="#EE9109" d="M20.437 4.324l2.425.341-.17 1.213-2.425-.341z"/>
<path fill="#C1E9E9" d="M15.246 6.068l4.85.681-.17 1.213-4.85-.682z"/>
<path fill="#DDF3F3" d="M24.947 7.431l4.85.682-.17 1.212-4.85-.681z"/>
</g>
<g>
<path stroke="#FFA624" stroke-width="1.5" d="M49.696 7.04c-.549-1.24-1.609-2.337-2.885-2.391-1.276-.054-2.007.969-1.632 1.874.374.905 1.266 1.071 4.16 1.847.822.22.905-.09.357-1.33z"/>
<path stroke="#FFBE5D" stroke-width="1.5" d="M52.956 7.04c.548-1.24 1.609-2.337 2.885-2.391 1.276-.054 2.007.969 1.632 1.874-.374.905-1.266 1.071-4.16 1.847-.822.22-.905-.09-.357-1.33z"/>
<path fill="#EE9109" d="M51.326 6.075c-2.497 0-1.002 2.858 0 2.858s2.497-2.858 0-2.858z"/>
<path fill="#F8F9F9" d="M51.326 8.481h9.23v4.616h-9.23z"/>
<path fill="#DDF3F3" d="M42.095 8.481h9.23v4.616h-9.23z"/>
<path fill="#FFBE5D" d="M48.249 8.481h6.154v4.616h-6.154z"/>
<path fill="#FFA624" d="M48.249 8.481h3.077v4.616h-3.077zM51.326 8.481h3.077v1.539h-3.077z"/>
<path fill="#EE9109" d="M48.249 8.481h3.077v1.539h-3.077z"/>
<path fill="#F8F9F9" d="M51.326 13.097h7.692v10.769h-7.692z"/>
<path fill="#DDF3F3" d="M43.634 13.097h7.692v10.769h-7.692z"/>
<path fill="#FFA624" d="M49.787 13.097h1.538v10.769h-1.538z"/>
<path fill="#FFBE5D" d="M51.326 13.097h1.538v10.769h-1.538z"/>
<path fill="#EE9109" d="M49.787 22.327h1.539v1.539h-1.539zM49.787 13.097h1.539v1.538h-1.539z"/>
<path fill="#C1E9E9" d="M43.634 13.097h6.153v1.538h-6.153zM42.095 11.558h6.154v1.539h-6.154zM43.634 22.327h6.153v1.539h-6.153z"/>
<path fill="#DDF3F3" d="M52.864 13.097h6.154v1.538h-6.154zM54.403 11.558h6.154v1.539h-6.154zM52.864 22.327h6.154v1.539h-6.154z"/>
<path fill="#FFA624" d="M51.326 22.327h1.538v1.539h-1.538zM51.326 13.097h1.538v1.538h-1.538z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

@@ -164,30 +164,30 @@ export default {
classGear (heroClass) {
if (heroClass === 'rogue') {
return {
armor: 'armor_rogue_5',
head: 'head_rogue_5',
shield: 'shield_rogue_6',
weapon: 'weapon_rogue_6',
armor: 'armor_special_winter2019Rogue',
head: 'head_special_winter2019Rogue',
shield: 'shield_special_winter2019Rogue',
weapon: 'weapon_special_winter2019Rogue',
};
} else if (heroClass === 'wizard') {
return {
armor: 'armor_wizard_5',
head: 'head_wizard_5',
weapon: 'weapon_wizard_6',
armor: 'armor_special_winter2019Mage',
head: 'head_special_winter2019Mage',
weapon: 'weapon_special_winter2019Mage',
};
} else if (heroClass === 'healer') {
return {
armor: 'armor_healer_5',
head: 'head_healer_5',
shield: 'shield_healer_5',
weapon: 'weapon_healer_6',
armor: 'armor_special_winter2019Healer',
head: 'head_special_winter2019Healer',
shield: 'shield_special_winter2019Healer',
weapon: 'weapon_special_winter2019Healer',
};
} else {
return {
armor: 'armor_warrior_5',
head: 'head_warrior_5',
shield: 'shield_warrior_5',
weapon: 'weapon_warrior_6',
armor: 'armor_special_winter2019Warrior',
head: 'head_special_winter2019Warrior',
shield: 'shield_special_winter2019Warrior',
weapon: 'weapon_special_winter2019Warrior',
};
}
},
@@ -6,7 +6,7 @@
.quest(:class='`quest_${user.party.quest.completed}`')
p(v-if='questData.completion && typeof questData.completion === "function"', v-html='questData.completion()')
.quest-rewards.text-center
h3 {{ $t('youReceived') }}
h3(v-once) {{ $t('paymentYouReceived') }}
questDialogDrops(:item="questData")
.modal-footer
button.btn.btn-primary(@click='setQuestCompleted()') {{ $t('ok') }}
+3 -1
View File
@@ -298,7 +298,9 @@ export default {
this.$emit('show-member-modal', memberId);
},
atHighlight (text) {
const userRegex = new RegExp(`@(${this.user.auth.local.username}|${this.user.profile.name})(?:\\b)`, 'gi');
const escapedDisplayName = escapeRegExp(this.user.profile.name);
const escapedUsername = escapeRegExp(this.user.auth.local.username);
const userRegex = new RegExp(`@(${escapedDisplayName}|${escapedUsername})(?:\\b)`, 'gi');
const atRegex = new RegExp(/(?!\b)@[\w-]+/g);
if (userRegex.test(text)) {
@@ -141,7 +141,7 @@ export default {
this.changePage(this.PAGES.PAY);
},
pay (paymentMethod) {
const subscriptionKey = 'group_monthly'; // @TODO: Get from content API?
const subscriptionKey = 'group_monthly';
let paymentData = {
subscription: subscriptionKey,
coupon: null,
@@ -149,6 +149,7 @@ export default {
if (this.upgradingGroup && this.upgradingGroup._id) {
paymentData.groupId = this.upgradingGroup._id;
paymentData.group = this.upgradingGroup;
} else {
paymentData.groupToCreate = this.newGroup;
}
@@ -1,100 +1,61 @@
<template lang="pug">
b-modal#create-party-modal(title="Empty", size='lg', hide-footer=true)
b-modal#create-party-modal(size='lg', hide-footer=true)
.header-wrap(slot="modal-header")
.quest_screen
.row.heading
.col-12.text-center
h2(v-once) {{$t('playInPartyTitle')}}
p(v-once) {{$t('playInPartyDescription')}}
.col-12.text-center.pr-5.pl-5
h2(v-once) {{ $t('playInPartyTitle') }}
p.mb-4(v-once) {{ $t('playInPartyDescription') }}
button.btn.btn-primary(v-once, @click='createParty()') {{ $t('createParty') }}
.row.grey-row
.col-6.text-center
.start-party
h3(v-once) {{$t('startYourOwnPartyTitle')}}
p(v-once) {{$t('startYourOwnPartyDescription')}}
button.btn.btn-primary(v-once, @click='createParty()') {{$t('createParty')}}
.col-6
div.text-center
.join-party
h3(v-once) {{$t('wantToJoinPartyTitle')}}
p(v-once) {{$t('wantToJoinPartyDescription')}}
button.btn.btn-primary(v-once, @click='shareUserId()') {{$t('shartUserId')}}
.share-userid-options(v-if="shareUserIdShown")
.option-item(@click='copyUserId()')
.svg-icon(v-html="icons.copy")
input(type="text", v-model="user._id", id="userIdInput")
| Copy User ID
//.option-item(v-once)
.svg-icon(v-html="icons.greyBadge")
| {{$t('lookingForGroup')}}
//.option-item(v-once)
.svg-icon(v-html="icons.qrCode")
| {{$t('qrCode')}}
//.option-item(v-once)
.svg-icon.facebook(v-html="icons.facebook")
| Facebook
//.option-item(v-once)
.svg-icon(v-html="icons.twitter")
| Twitter
.col-12.text-center
.join-party
h2(v-once) {{ $t('wantToJoinPartyTitle') }}
p(v-html='$t("wantToJoinPartyDescription")')
.form-group(@click='copyUsername')
.d-flex.align-items-center
label.mr-3(v-once) {{ $t('username') }}
.flex-grow-1
.input-group-prepend.input-group-text @
.text {{ user.auth.local.username }}
.svg-icon.copy-icon(v-html='icons.copy')
.small(v-once) {{ $t('copy') }}
</template>
<style>
#create-party-modal .modal-body {
padding: 0rem 0.75rem;
}
#create-party-modal .modal-dialog {
width: 684px;
width: 35.75rem;
}
#create-party-modal .modal-header {
padding: 0;
border-bottom: 0px;
}
</style>
<style lang="scss">
<style lang="scss" scoped>
@import '~client/assets/scss/colors.scss';
.heading {
margin-top: 1em;
margin-bottom: 1em;
.copy-icon {
width: 1rem;
}
.header-wrap {
padding: 0;
color: #4e4a57;
width: 100%;
.quest_screen {
background-image: url('~client/assets/images/quest_screen.png');
background-size: cover;
width: 100%;
height: 246px;
margin-bottom: .5em;
border-radius: 2px 2px 0 0;
}
h2 {
color: #4f2a93;
}
.form-control[readonly] {
background-color: $white;
color: $gray-50;
}
.start-party {
background-image: url('~client/assets/images/basilist@3x.png');
background-size: cover;
width: 122px;
height: 69px;
margin: 0 auto;
margin-bottom: 1em;
}
.join-party {
background-image: url('~client/assets/images/party@3x.png');
background-size: cover;
width: 203px;
height: 66px;
margin: 0 auto;
margin-bottom: 1em;
}
.modal-body {
padding-bottom: 0;
padding-top: 0;
.form-group {
background-color: $gray-600;
border-radius: 2px;
border: solid 1px $gray-500;
width: 90%;
margin: auto;
cursor: pointer;
}
.grey-row {
@@ -104,97 +65,130 @@ b-modal#create-party-modal(title="Empty", size='lg', hide-footer=true)
border-radius: 0px 0px 2px 2px;
}
.share-userid-options {
background-color: $white;
border-radius: 2px;
width: 220px;
position: absolute;
top: 9em;
left: 4.8em;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
h2 {
color: $gray-100;
}
#userIdInput {
position: absolute;
left: 1000rem;
.header-wrap {
padding: 0;
color: #4e4a57;
width: 100%;
.quest_screen {
background-image: url('~client/assets/images/group@3x.png');
background-size: cover;
width: 100%;
height: 246px;
margin-bottom: 1.5rem;
border-radius: 2px 2px 0 0;
image-rendering: optimizequality;
}
.option-item {
padding: 1em;
.svg-icon {
margin-right: .5em;
width: 20px;
display: inline-block;
vertical-align: bottom;
}
.facebook svg {
width: 15px;
height: 15px;
}
}
.option-item:hover {
background-color: $header-color;
h2 {
color: $purple-200;
cursor: pointer;
}
}
.heading {
margin-top: 1rem;
margin-bottom: 1rem;
}
input.form-control {
border: 0px;
padding-left: 0.25rem;
}
.input-group-prepend {
margin-right: 0px;
}
.input-group-text {
background-color: $white;
border: 0px;
border-radius: 0px;
color: $gray-300;
padding: 0rem 0.1rem 0rem 0.75rem;
}
.join-party {
background-image: url('~client/assets/images/party.png');
background-size: cover;
width: 203px;
height: 66px;
margin: 0 auto;
margin-bottom: 1em;
}
label {
color: $gray-100;
font-weight: bold;
margin-bottom: 0rem;
margin-left: 1rem;
cursor: pointer;
}
.modal-dialog .text {
min-height: 1rem;
margin: 0.75rem auto 0.75rem 0.25rem;
}
.small {
color: $gray-200;
margin: auto 0.5rem auto 0.25rem;
}
</style>
<script>
import { mapState } from 'client/libs/store';
import * as Analytics from 'client/libs/analytics';
import { mapState } from 'client/libs/store';
import * as Analytics from 'client/libs/analytics';
import notifications from 'client/mixins/notifications';
import copyIcon from 'assets/svg/copy.svg';
import greyBadgeIcon from 'assets/svg/grey-badge.svg';
import qrCodeIcon from 'assets/svg/qrCode.svg';
import facebookIcon from 'assets/svg/facebook.svg';
import twitterIcon from 'assets/svg/twitter.svg';
import copyIcon from 'assets/svg/copy.svg';
export default {
data () {
return {
icons: Object.freeze({
copy: copyIcon,
greyBadge: greyBadgeIcon,
qrCode: qrCodeIcon,
facebook: facebookIcon,
twitter: twitterIcon,
}),
shareUserIdShown: false,
};
},
computed: {
...mapState({user: 'user.data'}),
},
methods: {
shareUserId () {
this.shareUserIdShown = !this.shareUserIdShown;
},
async createParty () {
let group = {
type: 'party',
export default {
data () {
return {
icons: Object.freeze({
copy: copyIcon,
}),
};
group.name = this.$t('possessiveParty', {name: this.user.profile.name});
let party = await this.$store.dispatch('guilds:create', {group});
this.$store.state.party.data = party;
this.user.party._id = party._id;
Analytics.updateUser({
partyID: party._id,
partySize: 1,
});
this.$root.$emit('bv::hide::modal', 'create-party-modal');
this.$router.push('/party');
},
copyUserId () {
const copyText = document.getElementById('userIdInput');
copyText.select();
document.execCommand('copy');
alert('User ID has been copied');
computed: {
...mapState({user: 'user.data'}),
},
},
};
methods: {
async createParty () {
let group = {
type: 'party',
};
group.name = this.$t('possessiveParty', {name: this.user.profile.name});
let party = await this.$store.dispatch('guilds:create', {group});
this.$store.state.party.data = party;
this.user.party._id = party._id;
Analytics.updateUser({
partyID: party._id,
partySize: 1,
});
this.$root.$emit('bv::hide::modal', 'create-party-modal');
this.$router.push('/party');
},
copyUsername () {
if (navigator.clipboard) {
navigator.clipboard.writeText(this.user.auth.local.username);
} else {
let copyText = document.createElement('textarea');
copyText.value = this.user.auth.local.username;
document.body.appendChild(copyText);
copyText.select();
document.execCommand('copy');
document.body.removeChild(copyText);
}
this.text(this.$t('usernameCopied'));
},
},
mixins: [notifications],
};
</script>
@@ -395,14 +395,15 @@ export default {
this.changePage(this.PAGES.PAY);
},
pay (paymentMethod) {
let subscriptionKey = 'group_monthly'; // @TODO: Get from content API?
let paymentData = {
const subscriptionKey = 'group_monthly'; // @TODO: Get from content API?
const paymentData = {
subscription: subscriptionKey,
coupon: null,
};
if (this.upgradingGroup && this.upgradingGroup._id) {
paymentData.groupId = this.upgradingGroup._id;
paymentData.group = this.upgradingGroup;
} else {
paymentData.groupToCreate = this.newGroup;
}
-6
View File
@@ -1,6 +0,0 @@
<template lang="pug">
.row
.col
h1.page-header Page
p {{ $route.path }}
</template>
@@ -33,8 +33,11 @@
import * as Analytics from 'client/libs/analytics';
import axios from 'axios';
import { mapState } from 'client/libs/store';
import { CONSTANTS, setLocalSetting } from 'client/libs/userlocalManager';
import pick from 'lodash/pick';
const AMAZON_PAYMENTS = process.env.AMAZON_PAYMENTS; // eslint-disable-line
const habiticaUrl = `${location.protocol}//${location.host}`;
export default {
data () {
@@ -54,6 +57,8 @@ export default {
OffAmazonPayments: {},
isAmazonSetup: false,
amazonButtonEnabled: false,
groupToCreate: null, // creating new group
group: null, // upgrading existing group
};
},
computed: {
@@ -186,6 +191,45 @@ export default {
new this.OffAmazonPayments.Widgets.Wallet(walletParams).bind('AmazonPayWallet');
},
storePaymentStatusAndReload (url) {
let paymentType;
if (this.amazonPayments.type === 'single' && !this.amazonPayments.gift) paymentType = 'gems';
if (this.amazonPayments.type === 'subscription') paymentType = 'subscription';
if (this.amazonPayments.groupId || this.amazonPayments.groupToCreate) paymentType = 'groupPlan';
if (this.amazonPayments.type === 'single' && this.amazonPayments.gift && this.amazonPayments.giftReceiver) {
paymentType = this.amazonPayments.gift.type === 'gems' ? 'gift-gems' : 'gift-subscription';
}
const appState = {
paymentMethod: 'amazon',
paymentCompleted: true,
paymentType,
};
if (paymentType === 'subscription') {
appState.subscriptionKey = this.amazonPayments.subscription;
} else if (paymentType === 'groupPlan') {
appState.subscriptionKey = this.amazonPayments.subscription;
if (this.amazonPayments.groupToCreate) {
appState.newGroup = true;
appState.group = pick(this.amazonPayments.groupToCreate, ['_id', 'memberCount', 'name']);
} else {
appState.newGroup = false;
appState.group = pick(this.amazonPayments.group, ['_id', 'memberCount', 'name']);
}
} else if (paymentType.indexOf('gift-') === 0) {
appState.gift = this.amazonPayments.gift;
appState.giftReceiver = this.amazonPayments.giftReceiver;
}
setLocalSetting(CONSTANTS.savedAppStateValues.SAVED_APP_STATE, JSON.stringify(appState));
if (url) {
window.location.assign(url);
} else {
window.location.reload(true);
}
},
async amazonCheckOut () {
this.amazonButtonEnabled = false;
@@ -201,12 +245,11 @@ export default {
});
this.$set(this, 'amazonButtonEnabled', true);
this.reset();
// @TODO: What are we syncing?
window.location.reload(true);
this.storePaymentStatusAndReload();
} catch (e) {
console.error(e); // eslint-disable-line no-console
this.$set(this, 'amazonButtonEnabled', true);
this.amazonPaymentsreset();
this.reset();
}
} else if (this.amazonPayments.type === 'subscription') {
let url = '/amazon/subscribe';
@@ -231,8 +274,6 @@ export default {
if (newGroup && newGroup._id) {
// Handle new user signup
if (!this.$store.state.isUserLoggedIn) {
const habiticaUrl = `${location.protocol}//${location.host}`;
Analytics.track({
hitType: 'event',
eventCategory: 'group-plans-static',
@@ -240,23 +281,21 @@ export default {
eventLabel: 'paid-with-amazon',
});
location.href = `${habiticaUrl}/group-plans/${newGroup._id}/task-information?showGroupOverview=true`;
this.storePaymentStatusAndReload(`${habiticaUrl}/group-plans/${newGroup._id}/task-information?showGroupOverview=true`);
return;
}
// @TODO: Just append? or $emit?
this.$router.push(`/group-plans/${newGroup._id}/task-information`);
this.user.guilds.push(newGroup._id);
this.storePaymentStatusAndReload(`${habiticaUrl}/group-plans/${newGroup._id}/task-information`);
return;
}
if (this.amazonPayments.groupId) {
this.$router.push(`/group-plans/${this.amazonPayments.groupId}/task-information`);
this.storePaymentStatusAndReload(`${habiticaUrl}/group-plans/${this.amazonPayments.groupId}/task-information`);
return;
}
window.location.reload(true);
this.reset();
this.storePaymentStatusAndReload();
} catch (e) {
this.$set(this, 'amazonButtonEnabled', true);
// @TODO: do we need this? this.amazonPaymentsreset();
@@ -276,13 +315,19 @@ export default {
this.amazonPayments.modal = null;
this.amazonPayments.type = null;
this.amazonPayments.loggedIn = false;
// Gift
this.amazonPayments.gift = null;
this.amazonPayments.giftReceiver = null;
this.amazonPayments.billingAgreementId = null;
this.amazonPayments.orderReferenceId = null;
this.amazonPayments.paymentSelected = false;
this.amazonPayments.recurringConsent = false;
this.amazonPayments.subscription = null;
this.amazonPayments.coupon = null;
this.amazonPayments.groupToCreate = null;
this.amazonPayments.group = null;
},
},
};
@@ -2,180 +2,172 @@
mixin featureBullet (text)
.row
.col-md-2.offset-1
.bubble.mx-auto
.svg-icon.check(v-html='icons.check')
.d-flex.bubble.justify-content-center.align-items-center
.svg-icon.check.mx-auto(v-html='icons.check')
.col-md-8.align-self-center
p=text
div(v-if='user')
b-modal(:hide-footer='true', :hide-header='true', :id='"buy-gems"', size='lg')
.container-fluid.purple-gradient
.gemfall
b-modal#buy-gems(:hide-footer='true', size='lg')
.header-wrap(slot='modal-header')
.image-gemfall
.row
h2.text-invert.mx-auto {{ $t('support') }}
h2.header-invert.mx-auto {{ $t('support') }}
.row
.logo.svg-icon.mx-auto(v-html="icons.logo")
.container-fluid
.row
.col-6.offset-3.nav
.nav-item(@click='selectedPage = "subscribe"', :class="{active: selectedPage === 'subscribe'}") {{ $t('subscribe') }}
.nav-item(@click='selectedPage = "gems"', :class="{active: selectedPage === 'gems'}") {{ $t('buyGems') }}
div(v-show='selectedPage === "gems"')
div(v-if='hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('subscriptionAlreadySubscribedLeadIn') }}
.row.text-center
.col-6.offset-3
p {{ $t("gemsPurchaseNote") }}
.d-flex.nav.justify-content-center
.nav-item.text-center(@click='selectedPage = "subscribe"', :class="{active: selectedPage === 'subscribe'}") {{ $t('subscribe') }}
.nav-item.text-center(@click='selectedPage = "gems"', :class="{active: selectedPage === 'gems'}") {{ $t('buyGems') }}
div(v-show='selectedPage === "gems"')
div(v-if='hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('gemBenefitLeadin') }}
h2.mx-auto.text-leadin {{ $t('subscriptionAlreadySubscribedLeadIn') }}
.row.text-center
.col-6.offset-3
p {{ $t("gemsPurchaseNote") }}
.row.text-center
h2.mx-auto.text-leadin {{ $t('gemBenefitLeadin') }}
.row
.col
+featureBullet("{{ $t('gemBenefit1') }}")
+featureBullet("{{ $t('gemBenefit2') }}")
.col
+featureBullet("{{ $t('gemBenefit3') }}")
+featureBullet("{{ $t('gemBenefit4') }}")
.card-deck.gem-deck
.card.text-center.col-3(:class="{active: gemAmount === 20 }")
.card-img-top
.mx-auto(v-html='icons.twentyOneGems', style='"height: 55px; width: 47.5px; margin-top: 1.85em;"')
.card-body
.gem-count 20
.gem-text {{ $t('gems') }}
.divider
button.btn.btn-primary(@click='gemAmount === 20 ? gemAmount = 0 : gemAmount = 20') {{gemAmount === 20 ? $t('selected') : '$5.00'}}
.row.text-center
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
.card-deck
.card.text-center.payment-method(@click='showStripe({})')
.card-body
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
.card.text-center.payment-method
a.card-body.paypal(@click="openPaypal(paypalCheckoutLink, 'gems')")
img(src='~assets/images/paypal.png')
.card.text-center.payment-method(@click="amazonPaymentsInit({type: 'single'})")
.card-body.amazon
img(src='~assets/images/amazon-payments.png')
.row.text-center
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"')
.row.text-center.text-outtro
.col-6.offset-3 {{ $t('buyGemsSupportsDevs') }}
div(v-show='selectedPage === "subscribe"')
.g1g1-promo.d-flex.justify-content-center.align-items-center
.svg-icon.svg-gifts.left-gift(v-html="icons.gifts")
.text-center
strong.gift-text {{ $t('g1g1Announcement') }}
.gift-text {{ $t('g1g1Details') }}
.svg-icon.svg-gifts.right-gift(v-html="icons.gifts")
div(v-if='hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('subscriptionAlreadySubscribedLeadIn') }}
.row.text-center
.col-10.offset-1
p(v-html='$t("subscriptionAlreadySubscribed1")')
div(v-if='!hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('subscriptionBenefitLeadin') }}
.row
.col
+featureBullet("{{ $t('gemBenefit1') }}")
+featureBullet("{{ $t('gemBenefit2') }}")
+featureBullet("{{ $t('subscriptionBenefit1') }}")
+featureBullet("{{ $t('subscriptionBenefit2') }}")
+featureBullet("{{ $t('subscriptionBenefit3') }}")
.col
+featureBullet("{{ $t('gemBenefit3') }}")
+featureBullet("{{ $t('gemBenefit4') }}")
.card-deck.gem-deck
//.card.text-center(:class="{active: gemAmount === 4}")
.card-img-top
.mx-auto(v-html='icons.fourGems', style='"height: 53px; width: 49.5px; margin-top: 2em;"')
.card-body
.gem-count 4
.gem-text {{ $t('gems') }}
.divider
button.btn.btn-primary(@click='gemAmount = 4') {{gemAmount === 4 ? $t('selected') : '$1.00'}}
.card.text-center.col-3(:class="{active: gemAmount === 20 }")
.card-img-top
.mx-auto(v-html='icons.twentyOneGems', style='"height: 55px; width: 47.5px; margin-top: 1.85em;"')
.card-body
.gem-count 20
.gem-text {{ $t('gems') }}
.divider
button.btn.btn-primary(@click='gemAmount === 20 ? gemAmount = 0 : gemAmount = 20') {{gemAmount === 20 ? $t('selected') : '$5.00'}}
//.card.text-center(:class="{active: gemAmount === 42}")
.card-img-top
.mx-auto(v-html='icons.fortyTwoGems', style='"height: 49.5px; width: 51px; margin-top: 1.9em;"')
.card-body
.gem-count 42
.gem-text {{ $t('gems') }}
.divider
button.btn.btn-primary(@click='gemAmount = 42') {{gemAmount === 42 ? $t('selected') : '$10.00'}}
//.card.text-center(:class="{active: gemAmount === 84}")
.card-img-top
.mx-auto(v-html='icons.eightyFourGems', style='"height: 65px; width: 67px; margin-top: 1em;"')
.card-body
.gem-count 84
.gem-text {{ $t('gems') }}
.divider
button.btn.btn-primary(@click='gemAmount = 84') {{gemAmount === 84 ? $t('selected') : '$20.00'}}
.row.text-center
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
+featureBullet("{{ $t('subscriptionBenefit4') }}")
+featureBullet("{{ $t('subscriptionBenefit5') }}")
+featureBullet("{{ $t('subscriptionBenefit6') }}")
.card-deck
.card.text-center.payment-method(@click='showStripe({})')
.card.text-center(:class='{active: subscriptionPlan === "basic_earned"}')
.card-body
.subscription-price
span.superscript $
span 5
span.superscript.muted .00
.small(v-once) {{ $t('everyMonth') }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})')
.spacer
button.btn.btn-primary(@click='subscriptionPlan = "basic_earned"') {{ subscriptionPlan === "basic_earned" ? $t('selected') : $t('select') }}
.card.text-center(:class='{active: subscriptionPlan === "basic_3mo"}')
.card-body
.subscription-price
span.superscript $
span 15
span.superscript.muted .00
.small(v-once) {{ $t('everyXMonths', {interval: 3}) }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})')
p.benefits(v-markdown='$t("receiveMysticHourglass")')
button.btn.btn-primary(@click='subscriptionPlan = "basic_3mo"') {{ subscriptionPlan === "basic_3mo" ? $t('selected') : $t('select') }}
.card.text-center(:class='{active: subscriptionPlan === "basic_6mo"}')
.card-body
.subscription-price
span.superscript $
span 30
span.superscript.muted .00
.small(v-once) {{ $t('everyXMonths', {interval: 6}) }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})')
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})')
button.btn.btn-primary(@click='subscriptionPlan = "basic_6mo"') {{ subscriptionPlan === "basic_6mo" ? $t('selected') : $t('select') }}
.card.text-center(:class='{active: subscriptionPlan === "basic_12mo"}')
.card-body
.subscription-price
span.superscript $
span 48
span.superscript.muted .00
.small(v-once) {{ $t('everyYear') }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})')
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})')
button.btn.btn-primary(@click='subscriptionPlan = "basic_12mo"') {{ subscriptionPlan === "basic_12mo" ? $t('selected') : $t('select') }}
.row.text-center(v-if='subscriptionPlan')
h2.mx-auto.text-payment(v-once) {{ $t('choosePaymentMethod') }}
.row.text-center
a.mx-auto(v-once) {{ $t('haveCouponCode') }}
.card-deck(v-if='subscriptionPlan')
.card.text-center.payment-method
.card-body(@click='showStripe({subscription: subscriptionPlan})')
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
.card.text-center.payment-method
a.card-body.paypal(:href='paypalCheckoutLink', target='_blank')
a.card-body.paypal(@click="openPaypal(paypalSubscriptionLink, 'subscription')")
img(src='~assets/images/paypal.png')
.card.text-center.payment-method(@click="amazonPaymentsInit({type: 'single'})")
.card-body.amazon
.card.text-center.payment-method
.card-body.amazon(@click="amazonPaymentsInit({type: 'subscription', subscription: subscriptionPlan})")
img(src='~assets/images/amazon-payments.png')
.row.text-center
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"')
.row.text-center.text-outtro
.col-6.offset-3 {{ $t('buyGemsSupportsDevs') }}
div(v-show='selectedPage === "subscribe"')
div(v-if='hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('subscriptionAlreadySubscribedLeadIn') }}
.row.text-center
.col
p(v-html='$t("subscriptionAlreadySubscribed1")')
div(v-if='!hasSubscription')
.row.text-center
h2.mx-auto.text-leadin {{ $t('subscriptionBenefitLeadin') }}
.row
.col
+featureBullet("{{ $t('subscriptionBenefit1') }}")
+featureBullet("{{ $t('subscriptionBenefit2') }}")
+featureBullet("{{ $t('subscriptionBenefit3') }}")
.col
+featureBullet("{{ $t('subscriptionBenefit4') }}")
+featureBullet("{{ $t('subscriptionBenefit5') }}")
+featureBullet("{{ $t('subscriptionBenefit6') }}")
.card-deck
.card.text-center(:class='{active: subscriptionPlan === "basic_earned"}')
.card-body
.subscription-price
span.superscript $
span 5
span.superscript.muted .00
.small {{ $t('everyMonth') }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})')
.spacer
button.btn.btn-primary(@click='subscriptionPlan = "basic_earned"') {{ subscriptionPlan === "basic_earned" ? $t('selected') : $t('select') }}
.card.text-center(:class='{active: subscriptionPlan === "basic_3mo"}')
.card-body
.subscription-price
span.superscript $
span 15
span.superscript.muted .00
.small {{ $t('everyXMonths', {interval: 3}) }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})')
p.benefits(v-markdown='$t("receiveMysticHourglass")')
button.btn.btn-primary(@click='subscriptionPlan = "basic_3mo"') {{ subscriptionPlan === "basic_3mo" ? $t('selected') : $t('select') }}
.card.text-center(:class='{active: subscriptionPlan === "basic_6mo"}')
.card-body
.subscription-price
span.superscript $
span 30
span.superscript.muted .00
.small {{ $t('everyXMonths', {interval: 6}) }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})')
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})')
button.btn.btn-primary(@click='subscriptionPlan = "basic_6mo"') {{ subscriptionPlan === "basic_6mo" ? $t('selected') : $t('select') }}
.card.text-center(:class='{active: subscriptionPlan === "basic_12mo"}')
.card-body
.subscription-price
span.superscript $
span 48
span.superscript.muted .00
.small {{ $t('everyYear') }}
.divider
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})')
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})')
button.btn.btn-primary(@click='subscriptionPlan = "basic_12mo"') {{ subscriptionPlan === "basic_12mo" ? $t('selected') : $t('select') }}
.row.text-center(v-if='subscriptionPlan')
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
.row.text-center
a.mx-auto {{ $t('haveCouponCode') }}
.card-deck(v-if='subscriptionPlan')
.card.text-center.payment-method
.card-body(@click='showStripe({subscription: subscriptionPlan})')
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
.card.text-center.payment-method
a.card-body.paypal(:href='paypalSubscriptionLink', target='_blank')
img(src='~assets/images/paypal.png')
.card.text-center.payment-method
.card-body.amazon(@click="amazonPaymentsInit({type: 'subscription', subscription: subscriptionPlan})")
img(src='~assets/images/amazon-payments.png')
.row.text-center
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"')
.row.text-center.text-outtro
.col-6.offset-3 {{ $t('subscribeSupportsDevs') }}
.col-6.offset-3 {{ $t('subscribeSupportsDevs') }}
</template>
<style lang="scss">
#buy-gems__BV_body_ {
#buy-gems .modal-body {
padding: 0;
}
#buy-gems .modal-content {
border-radius: 8px;
width: 824px;
}
#buy-gems .modal-header {
padding: 0;
border-bottom: 0px;
}
</style>
<style lang="scss" scoped>
@import '~client/assets/scss/colors.scss';
a.mx-auto {
color: #2995cd;
}
@@ -228,6 +220,11 @@
margin: 1em auto;
}
.g1g1-promo {
background-color: #34b5c1;
height: 3.75rem;
}
.gem-count {
font-family: Roboto;
font-size: 40px;
@@ -242,11 +239,40 @@
margin-bottom: 1em;
}
.gemfall {
.gift-text {
color: $white;
font-size: 14px;
}
.image-gemfall {
background: url(~assets/images/gemfall.png) center repeat-y;
height: 14em;
}
.svg-gifts {
width: 4.6rem;
}
.left-gift {
margin: auto 1rem auto 4.8rem;
}
.right-gift {
margin: auto 4.8rem auto 1rem;
filter: FlipH;
transform: scaleX(-1);
}
.header-wrap {
background-image: linear-gradient(74deg, #4f2a93, #6133b4);
height: 14em;
width: 100%;
color: #4e4a57;
padding: 0;
border-top-left-radius: 7px;
border-top-right-radius: 7px;
}
.logo {
width: 256px;
height: 56px;
@@ -258,19 +284,21 @@
.nav {
font-weight: bold;
height: 40px;
background-color: $gray-600;
}
.nav-item {
box-sizing: border-box;
display: inline-block;
font-size: 16px;
margin: 0 auto;
padding: 1.5em;
margin: 0rem;
padding: 1rem;
width: 7.5rem;
}
.nav-item:hover, .nav-item.active {
color: #4f2a93;
border-bottom: 2px solid #4f2a93;
border-bottom: 4px solid $purple-300;
cursor: pointer;
}
@@ -286,11 +314,6 @@
padding-top: 1.3em;
}
.purple-gradient {
background-image: linear-gradient(74deg, #4f2a93, #6133b4);
height: 14em;
}
.spacer {
height: 4em;
}
@@ -309,10 +332,11 @@
.svg-icon.check {
color: #bda8ff;
width: 1rem;
}
.text-invert {
margin: 1.6em;
.header-invert {
margin: 3rem auto 1.5rem;
color: #FFFFFF;
font-family: Roboto;
font-weight: normal;
@@ -320,9 +344,9 @@
}
.text-leadin {
margin: 1.6em;
font-weight: normal;
color: #4f2a93;
margin: 1rem;
font-weight: bold;
color: $purple-200;
}
.text-outtro {
@@ -346,6 +370,7 @@
import checkIcon from 'assets/svg/check.svg';
import creditCard from 'assets/svg/credit-card.svg';
import gifts from 'assets/svg/gifts.svg';
import heart from 'assets/svg/health.svg';
import logo from 'assets/svg/habitica-logo.svg';
@@ -381,6 +406,7 @@
check: checkIcon,
creditCard,
fourGems,
gifts,
heart,
twentyOneGems,
fortyTwoGems,
@@ -31,11 +31,17 @@ b-modal#send-gems(:title="title", :hide-footer="true", size='lg', @hide='onHide(
)
h3.panel-heading {{ $t('subscription') }}
.panel-body
.form-group
.radio(v-for='block in subscriptionBlocks', v-if="block.target !== 'group' && block.canSubscribe === true")
label
input(type="radio", name="subRadio", :value="block.key", v-model='gift.subscription.key')
| {{ $t('sendGiftSubscription', {price: block.price, months: block.months}) }}
.row
.col-md-4
.form-group
.radio(v-for='block in subscriptionBlocks', v-if="block.target !== 'group' && block.canSubscribe === true")
label
input(type="radio", name="subRadio", :value="block.key", v-model='gift.subscription.key')
| {{ $t('sendGiftSubscription', {price: block.price, months: block.months}) }}
.col-md-8
h4 {{ $t('winterPromoGiftHeader') }}
p {{ $t('winterPromoGiftDetails1') }}
p {{ $t('winterPromoGiftDetails2') }}
textarea.form-control(rows='3', v-model='gift.message', :placeholder="$t('sendGiftMessagePlaceholder')")
//include ../formatting-help
@@ -47,9 +53,9 @@ b-modal#send-gems(:title="title", :hide-footer="true", size='lg', @hide='onHide(
:disabled="sendingInProgress"
) {{ $t("send") }}
template(v-else)
button.btn.btn-primary(@click='showStripe({gift, uuid: userReceivingGems._id})') {{ $t('card') }}
button.btn.btn-warning(@click='openPaypalGift({gift: gift, giftedTo: userReceivingGems._id})') PayPal
button.btn.btn-success(@click="amazonPaymentsInit({type: 'single', gift, giftedTo: userReceivingGems._id})") Amazon Payments
button.btn.btn-primary(@click='showStripe({gift, uuid: userReceivingGems._id, receiverName})') {{ $t('card') }}
button.btn.btn-warning(@click='openPaypalGift({gift: gift, giftedTo: userReceivingGems._id, receiverName})') PayPal
button.btn.btn-success(@click="amazonPaymentsInit({type: 'single', gift, giftedTo: userReceivingGems._id, receiverName})") Amazon Payments
button.btn.btn-secondary(@click='close()') {{$t('cancel')}}
</template>
@@ -131,6 +137,13 @@ export default {
if (!this.userReceivingGems) return '';
return this.$t('sendGiftHeading', {name: this.userReceivingGems.profile.name});
},
receiverName () {
if (this.userReceivingGems.auth && this.userReceivingGems.auth.local && this.userReceivingGems.auth.local.username) {
return this.userReceivingGems.auth.local.username;
} else {
return this.userReceivingGems.profile.name;
}
},
},
methods: {
// @TODO move to payments mixin or action (problem is that we need notifications)
@@ -141,11 +154,23 @@ export default {
toUserId: this.userReceivingGems._id,
gemAmount: this.gift.gems.amount,
});
this.text(this.$t('sentGems'));
this.close();
setTimeout(() => { // wait for the send gem modal to be closed
this.$root.$emit('habitica:payment-success', {
paymentMethod: 'balance',
paymentCompleted: true,
paymentType: 'gift-gems-balance',
gift: {
gems: {
amount: this.gift.gems.amount,
},
},
giftReceiver: this.receiverName,
});
}, 500);
},
onHide () {
// TODO this breaks amazon purchases because when the amazon modal
// @TODO this breaks amazon purchases because when the amazon modal
// is opened this one is closed and the amount reset
// this.gift.gems.amount = 0;
this.gift.message = '';
@@ -0,0 +1,179 @@
<template lang="pug">
b-modal#payments-success-modal(
:title="$t('accountSuspendedTitle')",
size='sm',
:hideFooter="isFromBalance",
:modalClass="isFromBalance ? ['modal-hidden-footer'] : []"
)
div(slot="modal-header")
.check-container.d-flex.align-items-center.justify-content-center
.svg-icon.check(v-html="icons.check", v-once)
h2 {{ $t(isFromBalance ? 'success' : 'paymentSuccessful') }}
div(slot="modal-footer")
.small-text(v-once) {{ $t('giftSubscriptionText4') }}
.row
.col-12.modal-body-col
template(v-if="paymentData.paymentType === 'gems'")
strong(v-once) {{ $t('paymentYouReceived') }}
.details-block.gems
.svg-icon(v-html="icons.gem", v-once)
span 20
template(v-if="paymentData.paymentType === 'gift-gems' || paymentData.paymentType === 'gift-gems-balance'")
span(v-html="$t('paymentYouSentGems', {name: paymentData.giftReceiver})")
.details-block.gems
.svg-icon(v-html="icons.gem", v-once)
span {{ paymentData.gift.gems.amount }}
template(v-if="paymentData.paymentType === 'gift-subscription'")
span(v-html="$t('paymentYouSentSubscription', {name: paymentData.giftReceiver, months: paymentData.subscription.months})")
template(v-if="paymentData.paymentType === 'subscription'")
strong(v-once) {{ $t('nowSubscribed') }}
.details-block
span(v-html="$t('paymentSubBilling', {amount: paymentData.subscription.price, months: paymentData.subscription.months})")
template(v-if="paymentData.paymentType === 'groupPlan'")
span(v-html="$t(paymentData.newGroup ? 'groupPlanCreated' : 'groupPlanUpgraded', {groupName: paymentData.group.name})")
.details-block
span(v-html="$t('paymentSubBilling', {amount: groupPlanCost, months: paymentData.subscription.months})")
button.btn.btn-primary(@click='close()', v-once) {{$t('onwards')}}
</template>
<style lang="scss">
@import '~client/assets/scss/colors.scss';
#payments-success-modal .modal-content {
background: transparent;
}
#payments-success-modal.modal-hidden-footer .modal-body {
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
}
#payments-success-modal .modal-header {
justify-content: center;
padding-top: 24px;
padding-bottom: 0px;
background: $green-10;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
border-bottom: none;
h2 {
color: white;
}
.check-container {
width: 64px;
height: 64px;
border-radius: 50%;
background: #1CA372;
margin: 0 auto;
margin-bottom: 16px;
}
.check {
width: 35.1px;
height: 28px;
color: white;
}
}
#payments-success-modal .modal-body {
padding-top: 16px;
padding-bottom: 24px;
background: white;
.modal-body-col {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.btn.btn-primary {
margin-top: 24px;
}
}
.details-block {
background: $gray-700;
border-radius: 4px;
padding: 8px 24px;
margin-top: 16px;
display: flex;
flex-direction: row;
text-align: center;
&.gems {
padding: 12px 16px 12px 20px;
color: $green-10;
font-size: 24px;
font-weight: bold;
line-height: 1.33;
.svg-icon {
margin-right: 8px;
width: 32px;
height: 32px;
}
}
}
}
#payments-success-modal .modal-footer {
background: $gray-700;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
justify-content: center;
border-top: none;
.small-text {
font-style: normal;
}
}
</style>
<script>
import checkIcon from 'assets/svg/check.svg';
import gemIcon from 'assets/svg/gem.svg';
import subscriptionBlocks from '../../../common/script/content/subscriptionBlocks';
export default {
data () {
return {
icons: Object.freeze({
check: checkIcon,
gem: gemIcon,
}),
paymentData: {},
};
},
mounted () {
this.$root.$on('habitica:payment-success', (data) => {
if (['subscription', 'groupPlan', 'gift-subscription'].indexOf(data.paymentType) !== -1) {
data.subscription = subscriptionBlocks[data.subscriptionKey || data.gift.subscription.key];
}
this.paymentData = data;
this.$root.$emit('bv::show::modal', 'payments-success-modal');
});
},
destroyed () {
this.paymentData = {};
this.$root.$off('habitica:payments-success');
},
computed: {
groupPlanCost () {
const sub = this.paymentData.subscription;
const memberCount = this.paymentData.group.memberCount || 1;
return sub.price + 3 * (memberCount - 1);
},
isFromBalance () {
return this.paymentData.paymentType === 'gift-gems-balance';
},
},
methods: {
close () {
this.paymentData = {};
this.$root.$emit('bv::hide::modal', 'payments-success-modal');
},
},
};
</script>

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