Merge branch 'develop' into refactor-content
15
.jshintrc
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"globals": {
|
||||
"confirm": false
|
||||
},
|
||||
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
|
||||
"esnext": true,
|
||||
|
||||
"asi": true,
|
||||
"boss": true,
|
||||
"newcap": false
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
.2014_Fall_HealerPROMO2 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -640px -843px;
|
||||
background-position: -564px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
.2014_Fall_Warrior_PROMO {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -367px -843px;
|
||||
background-position: -473px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -42,7 +42,7 @@
|
||||
}
|
||||
.promo_dilatoryDistress {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -94px -843px;
|
||||
background-position: -837px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -54,7 +54,7 @@
|
||||
}
|
||||
.promo_enchanted_armoire_201507 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -882px -641px;
|
||||
background-position: -882px -550px;
|
||||
width: 217px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
.promo_enchanted_armoire_201509 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -276px -843px;
|
||||
background-position: -291px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -76,6 +76,18 @@
|
||||
width: 175px;
|
||||
height: 175px;
|
||||
}
|
||||
.promo_haunted_hair {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -1023px -402px;
|
||||
width: 100px;
|
||||
height: 137px;
|
||||
}
|
||||
.customize-option. {
|
||||
background-image: url();
|
||||
background-position: ;
|
||||
width: ;
|
||||
height: ;
|
||||
}
|
||||
.promo_item_notif {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -882px 0px;
|
||||
@@ -84,7 +96,7 @@
|
||||
}
|
||||
.promo_mystery_201405 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -822px -843px;
|
||||
background-position: -200px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -96,7 +108,7 @@
|
||||
}
|
||||
.promo_mystery_201407 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: 0px -934px;
|
||||
background-position: -195px -949px;
|
||||
width: 42px;
|
||||
height: 62px;
|
||||
}
|
||||
@@ -108,7 +120,7 @@
|
||||
}
|
||||
.promo_mystery_201409 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -549px -843px;
|
||||
background-position: -746px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -120,13 +132,13 @@
|
||||
}
|
||||
.promo_mystery_201411 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -731px -843px;
|
||||
background-position: -928px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.promo_mystery_201412 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -1065px -843px;
|
||||
background-position: -152px -949px;
|
||||
width: 42px;
|
||||
height: 66px;
|
||||
}
|
||||
@@ -138,25 +150,25 @@
|
||||
}
|
||||
.promo_mystery_201502 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -185px -843px;
|
||||
background-position: -382px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.promo_mystery_201503 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -913px -843px;
|
||||
background-position: 0px -949px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.promo_mystery_201504 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -1004px -843px;
|
||||
background-position: -91px -949px;
|
||||
width: 60px;
|
||||
height: 69px;
|
||||
}
|
||||
.promo_mystery_201505 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -458px -843px;
|
||||
background-position: -655px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
@@ -174,19 +186,25 @@
|
||||
}
|
||||
.promo_mystery_201508 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: 0px -843px;
|
||||
background-position: -106px -843px;
|
||||
width: 93px;
|
||||
height: 90px;
|
||||
}
|
||||
.promo_mystery_201509 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -1019px -843px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.promo_mystery_3014 {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -882px -550px;
|
||||
background-position: -882px -641px;
|
||||
width: 217px;
|
||||
height: 90px;
|
||||
}
|
||||
.promo_orca {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -1023px -402px;
|
||||
background-position: 0px -843px;
|
||||
width: 105px;
|
||||
height: 105px;
|
||||
}
|
||||
@@ -198,7 +216,7 @@
|
||||
}
|
||||
.promo_pastel_skin {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: -331px -668px;
|
||||
background-position: 0px -668px;
|
||||
width: 330px;
|
||||
height: 83px;
|
||||
}
|
||||
@@ -222,7 +240,7 @@
|
||||
}
|
||||
.promo_shimmer_hair {
|
||||
background-image: url(spritesmith-largeSprites-0.png);
|
||||
background-position: 0px -668px;
|
||||
background-position: -331px -668px;
|
||||
width: 330px;
|
||||
height: 83px;
|
||||
}
|
||||
|
||||
BIN
common/dist/sprites/spritesmith-largeSprites-0.png
vendored
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 146 KiB |
3346
common/dist/sprites/spritesmith-main-4.css
vendored
BIN
common/dist/sprites/spritesmith-main-4.png
vendored
|
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 132 KiB |
484
common/dist/sprites/spritesmith-main-5.css
vendored
BIN
common/dist/sprites/spritesmith-main-5.png
vendored
|
Before Width: | Height: | Size: 328 KiB After Width: | Height: | Size: 321 KiB |
494
common/dist/sprites/spritesmith-main-6.css
vendored
BIN
common/dist/sprites/spritesmith-main-6.png
vendored
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 153 KiB |
464
common/dist/sprites/spritesmith-main-7.css
vendored
BIN
common/dist/sprites/spritesmith-main-7.png
vendored
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 148 KiB |
624
common/dist/sprites/spritesmith-main-8.css
vendored
BIN
common/dist/sprites/spritesmith-main-8.png
vendored
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 150 KiB |
846
common/dist/sprites/spritesmith-main-9.css
vendored
BIN
common/dist/sprites/spritesmith-main-9.png
vendored
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
@@ -336,6 +336,8 @@
|
||||
"armorMystery201506Notes": "Snorkel through a coral reef in this brightly-colored swim suit! Confers no benefit. June 2015 Subscriber Item.",
|
||||
"armorMystery201508Text": "Cheetah Costume",
|
||||
"armorMystery201508Notes": "Run fast as a flash in the fluffy Cheetah Costume! Confers no benefit. August 2015 Subscriber Item.",
|
||||
"armorMystery201509Text": "Werewolf Costume",
|
||||
"armorMystery201509Notes": "This IS a costume, right? Confers no benefit. September 2015 Subscriber Item.",
|
||||
"armorMystery301404Text": "Steampunk Suit",
|
||||
"armorMystery301404Notes": "Dapper and dashing, wot! Confers no benefit. February 3015 Subscriber Item.",
|
||||
|
||||
@@ -509,6 +511,8 @@
|
||||
"headMystery201505Notes": "The green plume on this iron helm waves proudly. Confers no benefit. May 2015 Subscriber Item.",
|
||||
"headMystery201508Text": "Cheetah Hat",
|
||||
"headMystery201508Notes": "This cozy cheetah hat is very fuzzy! Confers no benefit. August 2015 Subscriber Item.",
|
||||
"headMystery201509Text": "Werewolf Mask",
|
||||
"headMystery201509Notes": "This IS a mask, right? Confers no benefit. September 2015 Subscriber Item.",
|
||||
"headMystery301404Text": "Fancy Top Hat",
|
||||
"headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
|
||||
"headMystery301405Text": "Basic Top Hat",
|
||||
|
||||
@@ -1834,6 +1834,11 @@ api.wrap = (user, main=true) ->
|
||||
user.stats.mp += _.max([10,.1 * user._statsComputed.maxMP]) * dailyChecked / (dailyDueUnchecked + dailyChecked)
|
||||
user.stats.mp = user._statsComputed.maxMP if user.stats.mp > user._statsComputed.maxMP
|
||||
|
||||
# After all is said and done, progress up user's effect on quest, return those values & reset the user's
|
||||
progress = user.party.quest.progress; _progress = _.cloneDeep progress
|
||||
_.merge progress, {down:0,up:0}
|
||||
progress.collect = _.transform progress.collect, ((m,v,k)->m[k]=0)
|
||||
|
||||
# Analytics
|
||||
user.flags.cronCount?=0
|
||||
user.flags.cronCount++
|
||||
@@ -1845,14 +1850,12 @@ api.wrap = (user, main=true) ->
|
||||
uuid: user._id,
|
||||
user: user,
|
||||
resting: user.preferences.sleep,
|
||||
cronCount: user.flags.cronCount
|
||||
cronCount: user.flags.cronCount,
|
||||
progressUp: _progress.up,
|
||||
progressDown: _progress.down
|
||||
}
|
||||
options.analytics?.track('Cron', analyticsData)
|
||||
|
||||
# After all is said and done, progress up user's effect on quest, return those values & reset the user's
|
||||
progress = user.party.quest.progress; _progress = _.cloneDeep progress
|
||||
_.merge progress, {down:0,up:0}
|
||||
progress.collect = _.transform progress.collect, ((m,v,k)->m[k]=0)
|
||||
_progress
|
||||
|
||||
# Registered users with some history
|
||||
|
||||
@@ -593,8 +593,13 @@ let head = {
|
||||
text: t('headMystery201508Text'),
|
||||
notes: t('headMystery201508Notes'),
|
||||
mystery: '201508',
|
||||
value: 0,
|
||||
int: 0
|
||||
value: 0
|
||||
},
|
||||
201509: {
|
||||
text: t('headMystery201509Text'),
|
||||
notes: t('headMystery201509Notes'),
|
||||
mystery:'201509',
|
||||
value: 0
|
||||
},
|
||||
301404: {
|
||||
text: t('headMystery301404Text'),
|
||||
|
||||
@@ -84,8 +84,13 @@ export var armor = {
|
||||
text: t('armorMystery201508Text'),
|
||||
notes: t('armorMystery201508Notes'),
|
||||
mystery: '201508',
|
||||
value: 0,
|
||||
int: 0
|
||||
value: 0
|
||||
},
|
||||
201509: {
|
||||
text: t('armorMystery201509Text'),
|
||||
notes: t('armorMystery201509Notes'),
|
||||
mystery: '201509',
|
||||
value: 0
|
||||
},
|
||||
301404: {
|
||||
text: t('armorMystery301404Text'),
|
||||
|
||||
@@ -97,6 +97,11 @@ let mysterySets = {
|
||||
end: '2015-09-02',
|
||||
text: 'Cheetah Costume Set'
|
||||
},
|
||||
201509: {
|
||||
start:'2015-09-24',
|
||||
end:'2015-10-02',
|
||||
text:'Werewolf Set'
|
||||
},
|
||||
301404: {
|
||||
start: '3014-03-24',
|
||||
end: '3014-04-02',
|
||||
|
||||
@@ -2,7 +2,7 @@ var _id = '';
|
||||
var update = {
|
||||
$addToSet: {
|
||||
'purchased.plan.mysteryItems':{
|
||||
$each:['head_mystery_201508','armor_mystery_201508']
|
||||
$each:['head_mystery_201509','armor_mystery_201509']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"grunt-karma": "~0.6.2",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-clean": "^0.3.1",
|
||||
"gulp-eslint": "^1.0.0",
|
||||
"gulp-grunt": "^0.5.2",
|
||||
"gulp-imagemin": "^2.3.0",
|
||||
"gulp-nodemon": "^2.0.4",
|
||||
|
||||
45
tasks/gulp-eslint.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import gulp from 'gulp';
|
||||
import eslint from 'gulp-eslint';
|
||||
import _ from 'lodash';
|
||||
|
||||
// TODO remove once we upgrade to lodash 3
|
||||
const defaultsDeep = _.partialRight(_.merge, _.defaults);
|
||||
|
||||
const shared = {
|
||||
rules: {
|
||||
indent: [2, 2],
|
||||
quotes: [2, 'single'],
|
||||
'linebreak-style': [2, 'unix'],
|
||||
semi: [2, 'always']
|
||||
},
|
||||
extends: 'eslint:recommended',
|
||||
env: {
|
||||
es6: true
|
||||
}
|
||||
};
|
||||
|
||||
gulp.task('lint:client', () => {
|
||||
// Ignore .coffee files
|
||||
return gulp.src(['./website/public/js/**/*.js'])
|
||||
.pipe(eslint(defaultsDeep({
|
||||
env: {
|
||||
node: true
|
||||
}
|
||||
}, shared)))
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError());
|
||||
});
|
||||
|
||||
gulp.task('lint:server', () => {
|
||||
// Ignore .coffee files
|
||||
return gulp.src(['./website/src/**/*.js'])
|
||||
.pipe(eslint(defaultsDeep({
|
||||
env: {
|
||||
browser: true
|
||||
}
|
||||
}, shared)))
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError());
|
||||
});
|
||||
|
||||
gulp.task('lint', ['lint:server', 'lint:client']);
|
||||
@@ -7,7 +7,7 @@ var User = require('mongoose').model('User');
|
||||
var shared = require('../../../../common');
|
||||
var payments = require('./index');
|
||||
var cc = require('coupon-code');
|
||||
var isProd = nconf.get("NODE_ENV") === 'production';
|
||||
var isProd = nconf.get('NODE_ENV') === 'production';
|
||||
|
||||
var amzPayment = amazonPayments.connect({
|
||||
environment: amazonPayments.Environment[isProd ? 'Production' : 'Sandbox'],
|
||||
@@ -122,7 +122,7 @@ exports.checkout = function(req, res, next){
|
||||
|
||||
executePayment: function(cb){
|
||||
async.waterfall([
|
||||
function(cb2){ User.findById(gift ? gift.uuid : undefined, cb2) },
|
||||
function(cb2){ User.findById(gift ? gift.uuid : undefined, cb2); },
|
||||
function(member, cb2){
|
||||
var data = {user:user, paymentMethod:'Amazon Payments'};
|
||||
var method = 'buyGems';
|
||||
@@ -151,7 +151,7 @@ exports.subscribe = function(req, res, next){
|
||||
return res.json(400, {err: 'Billing Agreement Id not supplied.'});
|
||||
}
|
||||
|
||||
var billingAgreementId = req.body.billingAgreementId
|
||||
var billingAgreementId = req.body.billingAgreementId;
|
||||
var sub = req.body.subscription ? shared.content.subscriptionBlocks[req.body.subscription] : false;
|
||||
var coupon = req.body.coupon;
|
||||
var user = res.locals.user;
|
||||
@@ -167,7 +167,7 @@ exports.subscribe = function(req, res, next){
|
||||
mongoose.model('Coupon').findOne({_id:cc.validate(coupon), event:sub.key}, function(err, coupon){
|
||||
if(err) return cb(err);
|
||||
if(!coupon) return cb(new Error('Coupon code not found.'));
|
||||
cb()
|
||||
cb();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -236,7 +236,7 @@ exports.subscribe = function(req, res, next){
|
||||
exports.subscribeCancel = function(req, res, next){
|
||||
var user = res.locals.user;
|
||||
if (!user.purchased.plan.customerId)
|
||||
return res.json(401, {err: "User does not have a plan subscription"});
|
||||
return res.json(401, {err: 'User does not have a plan subscription'});
|
||||
|
||||
var billingAgreementId = user.purchased.plan.customerId;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ var nconf = require('nconf');
|
||||
var inAppPurchase = require('in-app-purchase');
|
||||
inAppPurchase.config({
|
||||
// this is the path to the directory containing iap-sanbox/iap-live files
|
||||
googlePublicKeyPath: nconf.get("IAP_GOOGLE_KEYDIR")
|
||||
googlePublicKeyPath: nconf.get('IAP_GOOGLE_KEYDIR')
|
||||
});
|
||||
|
||||
// Validation ERROR Codes
|
||||
@@ -101,7 +101,7 @@ exports.iosVerify = function(req, res, next) {
|
||||
if (iap.isValidated(appleRes)) {
|
||||
var purchaseDataList = iap.getPurchaseData(appleRes);
|
||||
if (purchaseDataList.length > 0) {
|
||||
if (purchaseDataList[0].productId === "com.habitrpg.ios.Habitica.20gems") {
|
||||
if (purchaseDataList[0].productId === 'com.habitrpg.ios.Habitica.20gems') {
|
||||
//Correct receipt
|
||||
payments.buyGems({user:user, paymentMethod:'IAP AppleStore'});
|
||||
var resObj = {
|
||||
@@ -117,7 +117,7 @@ exports.iosVerify = function(req, res, next) {
|
||||
ok: false,
|
||||
data: {
|
||||
code: INVALID_PAYLOAD,
|
||||
message: "Incorrect receipt content"
|
||||
message: 'Incorrect receipt content'
|
||||
}
|
||||
};
|
||||
return res.json(resObj);
|
||||
@@ -127,7 +127,7 @@ exports.iosVerify = function(req, res, next) {
|
||||
ok: false,
|
||||
data: {
|
||||
code: INVALID_PAYLOAD,
|
||||
message: "Invalid receipt"
|
||||
message: 'Invalid receipt'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var nconf = require('nconf');
|
||||
var stripe = require("stripe")(nconf.get('STRIPE_API_KEY'));
|
||||
var stripe = require('stripe')(nconf.get('STRIPE_API_KEY'));
|
||||
var async = require('async');
|
||||
var payments = require('./index');
|
||||
var User = require('mongoose').model('User');
|
||||
@@ -38,10 +38,10 @@ exports.checkout = function(req, res, next) {
|
||||
], cb);
|
||||
} else {
|
||||
stripe.charges.create({
|
||||
amount: !gift ? "500" //"500" = $5
|
||||
: gift.type=='subscription' ? ""+shared.content.subscriptionBlocks[gift.subscription.key].price*100
|
||||
: ""+gift.gems.amount/4*100,
|
||||
currency: "usd",
|
||||
amount: !gift ? '500' //"500" = $5
|
||||
: gift.type=='subscription' ? ''+shared.content.subscriptionBlocks[gift.subscription.key].price*100
|
||||
: ''+gift.gems.amount/4*100,
|
||||
currency: 'usd',
|
||||
card: token
|
||||
}, cb);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ exports.checkout = function(req, res, next) {
|
||||
function(response, cb) {
|
||||
if (sub) return payments.createSubscription({user:user, customerId:response.id, paymentMethod:'Stripe', sub:sub}, cb);
|
||||
async.waterfall([
|
||||
function(cb2){ User.findById(gift ? gift.uuid : undefined, cb2) },
|
||||
function(cb2){ User.findById(gift ? gift.uuid : undefined, cb2); },
|
||||
function(member, cb2){
|
||||
var data = {user:user, customerId:response.id, paymentMethod:'Stripe', gift:gift};
|
||||
var method = 'buyGems';
|
||||
@@ -72,7 +72,7 @@ exports.checkout = function(req, res, next) {
|
||||
exports.subscribeCancel = function(req, res, next) {
|
||||
var user = res.locals.user;
|
||||
if (!user.purchased.plan.customerId)
|
||||
return res.json(401, {err: "User does not have a plan subscription"});
|
||||
return res.json(401, {err: 'User does not have a plan subscription'});
|
||||
|
||||
async.auto({
|
||||
get_cus: function(cb){
|
||||
|
||||
@@ -22,7 +22,7 @@ module.exports = function(server,mongoose) {
|
||||
apdexBad = score < .75 || score == 1,
|
||||
memory = os.freemem() / os.totalmem(),
|
||||
memoryHigh = memory < 0.1;
|
||||
if (/*apdexBad || */memoryHigh) throw "[Memory Leak] Apdex="+score+" Memory="+parseFloat(memory).toFixed(3)+" Time="+moment().format();
|
||||
if (/*apdexBad || */memoryHigh) throw '[Memory Leak] Apdex='+score+' Memory='+parseFloat(memory).toFixed(3)+' Time='+moment().format();
|
||||
});
|
||||
}, mins*60*1000);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var nconf = require('nconf');
|
||||
var IS_PROD = nconf.get('NODE_ENV') === 'production';
|
||||
var ignoreRedirect = nconf.get('IGNORE_REDIRECT');
|
||||
var BASE_URL = nconf.get("BASE_URL");
|
||||
var BASE_URL = nconf.get('BASE_URL');
|
||||
|
||||
function isHTTP(req) {
|
||||
return (
|
||||
|
||||
@@ -10,7 +10,7 @@ var i18n = require('../i18n');
|
||||
// -------- App --------
|
||||
router.get('/', i18n.getUserLanguage, locals, function(req, res) {
|
||||
if (!req.headers['x-api-user'] && !req.headers['x-api-key'] && !(req.session && req.session.userId))
|
||||
return res.redirect('/static/front')
|
||||
return res.redirect('/static/front');
|
||||
|
||||
return res.render('index', {
|
||||
title: 'Habitica | Your Life The Role Playing Game',
|
||||
@@ -29,7 +29,7 @@ _.each(pages, function(name){
|
||||
marked: require('marked')
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
// --------- Redirects --------
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ router.get('/paypal/subscribe/success', i18n.getUserLanguage, payments.paypalSub
|
||||
router.get('/paypal/subscribe/cancel', auth.authWithUrl, i18n.getUserLanguage, payments.paypalSubscribeCancel);
|
||||
router.post('/paypal/ipn', i18n.getUserLanguage, payments.paypalIPN); // misc ipn handling
|
||||
|
||||
router.post("/stripe/checkout", auth.auth, i18n.getUserLanguage, payments.stripeCheckout);
|
||||
router.post("/stripe/subscribe/edit", auth.auth, i18n.getUserLanguage, payments.stripeSubscribeEdit)
|
||||
//router.get("/stripe/subscribe", auth.authWithUrl, i18n.getUserLanguage, payments.stripeSubscribe); // checkout route is used (above) with ?plan= instead
|
||||
router.get("/stripe/subscribe/cancel", auth.authWithUrl, i18n.getUserLanguage, payments.stripeSubscribeCancel);
|
||||
router.post('/stripe/checkout', auth.auth, i18n.getUserLanguage, payments.stripeCheckout);
|
||||
router.post('/stripe/subscribe/edit', auth.auth, i18n.getUserLanguage, payments.stripeSubscribeEdit);
|
||||
//router.get('/stripe/subscribe', auth.authWithUrl, i18n.getUserLanguage, payments.stripeSubscribe); // checkout route is used (above) with ?plan= instead
|
||||
router.get('/stripe/subscribe/cancel', auth.authWithUrl, i18n.getUserLanguage, payments.stripeSubscribeCancel);
|
||||
|
||||
router.post('/amazon/verifyAccessToken', auth.auth, i18n.getUserLanguage, payments.amazonVerifyAccessToken);
|
||||
router.post('/amazon/createOrderReferenceId', auth.auth, i18n.getUserLanguage, payments.amazonCreateOrderReferenceId);
|
||||
@@ -23,9 +23,9 @@ router.post('/amazon/checkout', auth.auth, i18n.getUserLanguage, payments.amazon
|
||||
router.post('/amazon/subscribe', auth.auth, i18n.getUserLanguage, payments.amazonSubscribe);
|
||||
router.get('/amazon/subscribe/cancel', auth.authWithUrl, i18n.getUserLanguage, payments.amazonSubscribeCancel);
|
||||
|
||||
router.post("/iap/android/verify", auth.authWithUrl, /*i18n.getUserLanguage, */payments.iapAndroidVerify);
|
||||
router.post("/iap/ios/verify", auth.auth, /*i18n.getUserLanguage, */ payments.iapIosVerify);
|
||||
router.post('/iap/android/verify', auth.authWithUrl, /*i18n.getUserLanguage, */payments.iapAndroidVerify);
|
||||
router.post('/iap/ios/verify', auth.auth, /*i18n.getUserLanguage, */ payments.iapIosVerify);
|
||||
|
||||
router.get("/api/v2/coupons/valid-discount/:code", /*auth.authWithUrl, i18n.getUserLanguage, */ payments.validCoupon);
|
||||
router.get('/api/v2/coupons/valid-discount/:code', /*auth.authWithUrl, i18n.getUserLanguage, */ payments.validCoupon);
|
||||
|
||||
module.exports = router;
|
||||
@@ -84,7 +84,7 @@ mixin customizeProfile(mobile)
|
||||
button(type='button', ng-if='user.purchased.hair.color.#{color}', class='customize-option hair hair_bangs_1_#{color}', ng-click='unlock("hair.color.#{color}")', ng-class='{selectableInventory: user.preferences.hair.color == "#{color}"}')
|
||||
+buyPref('hair.color', ['rainbow','yellow','green','purple','blue','TRUred'], 'rainbowColors')
|
||||
+buyPref('hair.color', ['pblue2','pgreen2','porange2','ppink2','ppurple2','pyellow2'], 'shimmerColors', 'disabled')
|
||||
+buyPref('hair.color', ['candycorn','ghostwhite','halloween','midnight','pumpkin','zombie'], 'hauntedColors', 'disabled')
|
||||
+buyPref('hair.color', ['candycorn','ghostwhite','halloween','midnight','pumpkin','zombie'], 'hauntedColors')
|
||||
+buyPref('hair.color', ['aurora','festive','hollygreen','peppermint','snowy','winterstar'], 'winteryColors', 'disabled')
|
||||
|
||||
li.customize-menu
|
||||
@@ -152,7 +152,7 @@ mixin customizeProfile(mobile)
|
||||
// Seasonal event skins. Note that Spooky Skins are a legacy set and should always be disabled for purchase
|
||||
+buyPref('skin', ['pastelPink','pastelOrange','pastelYellow','pastelGreen','pastelBlue','pastelPurple','pastelRainbowChevron','pastelRainbowDiagonal'], 'pastelSkins', 'disabled')
|
||||
+buyPref('skin', ['monster','pumpkin','skeleton','zombie','ghost','shadow'], 'spookySkins', 'disabled')
|
||||
+buyPref('skin', ['candycorn','ogre','pumpkin2','reptile','shadow2','skeleton2','transparent','zombie2'], 'supernaturalSkins', 'disabled')
|
||||
+buyPref('skin', ['candycorn','ogre','pumpkin2','reptile','shadow2','skeleton2','transparent','zombie2'], 'supernaturalSkins')
|
||||
+buyPref('skin', ['clownfish','deepocean','merblue','mergold','mergreen','merruby','shark','tropicalwater'], 'splashySkins', 'disabled')
|
||||
|
||||
|
||||
|
||||
@@ -1,41 +1,65 @@
|
||||
h2 9/21/2015 - FALL FESTIVAL! LIMITED-EDITION OUTFITS, SEASONAL SHOP, CANDY FOOD DROPS, AND NPC DRESS-UP
|
||||
h2 9/24/2015 - HAUNTED HAIR COLORS, SUPERNATURAL SKIN SET, AND WEREWOLF SUBSCRIBER ITEM! PLUS, THE FALL PLOT-LINE CONTINUES...
|
||||
hr
|
||||
tr
|
||||
td
|
||||
h3 Fall Festival Begins
|
||||
p We've moved to the Flourishing Fields for the Fall Festival! The air is crisp, the leaves are red, and everyone is sweet and spooky. Come celebrate the Fall Festival with us... if you dare!
|
||||
h3 Haunted Hair Colors and Supernatural Skin Set
|
||||
.promo_haunted_hair.pull-right
|
||||
p The Seasonal Edition Haunted Hair Colors are now available for purchase in <a href='/#/options/profile/avatar'>the avatar customizations page</a>! Now you can dye your avatar's hair Pumpkin, Midnight, Candy Corn, Ghost White, Zombie, or Halloween. Get them before October 31st!
|
||||
br
|
||||
p The Supernatural Skin Set is also available until October 31st! Now your avatar can become an Ogre, Skeleton, Pumpkin, Candy Corn, Reptile, or Dread Shade.
|
||||
br
|
||||
p Seasonal Edition items recur unchanged every year, but they are only available to purchase during a short period of time. Get them now, or you'll have to wait until next year!
|
||||
p.small.muted by Lemoness, mariahm, and crystal phoenix
|
||||
tr
|
||||
td
|
||||
.promo_classes_fall_2015.pull-right
|
||||
h3 Limited Edition Class Outfits
|
||||
p Habiticans everywhere are dressing up. From now until October 31st, limited edition outfits are available in the Rewards column. Depending on your class, you can be a Scarecrow Warrior, Bat-tle Rogue, Potioner, or Stitch Witch! You'd better get productive to earn enough Gold before your time runs out...
|
||||
p.small.muted by Lemoness and UncommonCriminal
|
||||
tr
|
||||
td
|
||||
.promo_classes_fall_2014.pull-right
|
||||
h3 Seasonal Shop Opens
|
||||
p The <a href='/#/options/inventory/seasonalshop'>Seasonal Shop</a> has opened! It's stocking autumnal Seasonal Edition goodies at the moment, including last year's fall outfits. Everything there will be available to purchase during the Fall Festival event each year, but it's only open until October 31st, so be sure to stock up now, or you'll have to wait a year to buy these items again!
|
||||
h3 September Subscriber Items Revealed
|
||||
.promo_mystery_201509.pull-right
|
||||
p The September Subscriber Item has been revealed: the Werewolf Armor Set! All September subscribers will receive the Werewolf Mask and the Werewolf Costume. You still have six days to <a href='/#/options/settings/subscription'>subscribe</a> and receive the item set! Thank you so much for your support - we really do rely on you to keep Habitica free to use and running smoothly.
|
||||
p.small.muted by Lemoness
|
||||
tr
|
||||
td
|
||||
.Pet_Food_Candy_Base.pull-right
|
||||
h3 Candy Food Drops!
|
||||
p For the duration of the Fall Festival, you may randomly find candy drops when you complete your tasks. These candies function just like normal food drops - can you guess which flavors your pets will like best?
|
||||
p.small.muted by Lemoness and SabreCat
|
||||
tr
|
||||
td
|
||||
.seasonalshop_open.pull-right
|
||||
h3 NPC Dress Up
|
||||
p The NPCs have decided to blend in with the locals of the Flourishing Fields by dressing up for the Fall Festival! Browse through the site to admire their new costumes.
|
||||
p.small.muted by Lemoness
|
||||
h3 Fall Plot-Line Continues
|
||||
p In general, we've all been enjoying the Flourishing Fields. Habiticans are posing in fun costumes, taking pictures of the orange-and-black wildlife, and casting Spooky Sparkles on each other.
|
||||
br
|
||||
p Unfortunately, there does seem to be a serious problem with production for the first time in the history of the Fields. Deadlines are being missed. Shipments are not arriving. As you walk down the street, you overhear worried whispers among the citizens, speculating on the cause.
|
||||
br
|
||||
p Some blame the unseasonal heat wave that has begun in the past few days. Others point to the difficulty of the tasks, and their ever-increasing quantity. And a few people -- just a few -- murmur that some of the hardest-working citizens have been disappearing, one by one, leaving their obligations abandoned. But surely that is nothing more than rumor?
|
||||
|
||||
if menuItem !== 'oldNews'
|
||||
hr
|
||||
a(href='/static/old-news', target='_blank') Read older news
|
||||
|
||||
mixin oldNews
|
||||
h2 9/21/2015 - FALL FESTIVAL! LIMITED-EDITION OUTFITS, SEASONAL SHOP, CANDY FOOD DROPS, AND NPC DRESS-UP
|
||||
tr
|
||||
td
|
||||
h3 Fall Festival Begins
|
||||
p We've moved to the Flourishing Fields for the Fall Festival! The air is crisp, the leaves are red, and everyone is sweet and spooky. Come celebrate the Fall Festival with us... if you dare!
|
||||
tr
|
||||
td
|
||||
.promo_classes_fall_2015.pull-right
|
||||
h3 Limited Edition Class Outfits
|
||||
p Habiticans everywhere are dressing up. From now until October 31st, limited edition outfits are available in the Rewards column. Depending on your class, you can be a Scarecrow Warrior, Bat-tle Rogue, Potioner, or Stitch Witch! You'd better get productive to earn enough Gold before your time runs out...
|
||||
p.small.muted by Lemoness and UncommonCriminal
|
||||
tr
|
||||
td
|
||||
.promo_classes_fall_2014.pull-right
|
||||
h3 Seasonal Shop Opens
|
||||
p The <a href='/#/options/inventory/seasonalshop'>Seasonal Shop</a> has opened! It's stocking autumnal Seasonal Edition goodies at the moment, including last year's fall outfits. Everything there will be available to purchase during the Fall Festival event each year, but it's only open until October 31st, so be sure to stock up now, or you'll have to wait a year to buy these items again!
|
||||
p.small.muted by Lemoness
|
||||
tr
|
||||
td
|
||||
.Pet_Food_Candy_Base.pull-right
|
||||
h3 Candy Food Drops!
|
||||
p For the duration of the Fall Festival, you may randomly find candy drops when you complete your tasks. These candies function just like normal food drops - can you guess which flavors your pets will like best?
|
||||
p.small.muted by Lemoness and SabreCat
|
||||
tr
|
||||
td
|
||||
.seasonalshop_open.pull-right
|
||||
h3 NPC Dress Up
|
||||
p The NPCs have decided to blend in with the locals of the Flourishing Fields by dressing up for the Fall Festival! Browse through the site to admire their new costumes.
|
||||
p.small.muted by Lemoness
|
||||
h2 9/16/2015 - MAMMOTHS AND MANTIS SHRIMPS IN TIME TRAVELER SHOP! PLUS, FALL FESTIVAL PLOT-LINE CONTINUES
|
||||
hr
|
||||
tr
|
||||
td
|
||||
.Pet-MantisShrimp-Base.pull-right
|
||||
|
||||