Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6959d8b8d4 | |||
| efb4efd768 | |||
| 40ba81a5d9 | |||
| 1cd1d45410 | |||
| 25caf1f850 | |||
| 3f1e8ceae4 | |||
| 1224d6d0c9 | |||
| 2565772093 | |||
| 11ebc6c397 | |||
| 0f9f8a7723 | |||
| 45efbc1e4b | |||
| faec0bc979 | |||
| e597906f35 | |||
| 42de623fc6 | |||
| fb74f59ae5 | |||
| 6395070eb6 | |||
| d0033322f7 | |||
| 76b5332d78 | |||
| e8f9c4953e | |||
| cf3a092f06 | |||
| ae9bca3ac7 | |||
| 194f2d512a | |||
| f70f7b2a1c | |||
| 9a6f98b0b5 | |||
| bfd960b7b6 | |||
| 91d75bae29 | |||
| 8983e7fea2 | |||
| bff88434fd | |||
| a1d31e37a3 | |||
| c09a014d8d | |||
| ca8b232e01 | |||
| af7ce402e5 | |||
| e82d415d5f | |||
| 3839fd276b | |||
| 987801fa83 | |||
| f9c288acdf | |||
| 49b8ec22f4 | |||
| d3a4c3eaea | |||
| 2dea0c0b9c | |||
| 6a6963103b | |||
| 62986426ba | |||
| 95c8302c9a | |||
| cf75888ffe | |||
| f939208cdb | |||
| ffe5340cf2 | |||
| 750ce0d6cc | |||
| 9af9c553d4 | |||
| 6705ce0dec | |||
| 0fb421897e | |||
| d20d254c6f | |||
| 7d78a7b320 | |||
| 2362976f14 | |||
| 99b63456c8 | |||
| e0b8cfbaa7 | |||
| 4ca4fd9ae7 | |||
| bb84b6f6c2 | |||
| 451df7d50d | |||
| 3a359cc057 | |||
| 66b2b47f87 | |||
| b4efe11e6a | |||
| 46822ecbae | |||
| 85c979a22d | |||
| ed02913e9d | |||
| 84ecb7c701 | |||
| dbd283514c | |||
| 12f802709b | |||
| a504f69b8a | |||
| ca8e6c74f6 | |||
| b9dbc0f829 | |||
| 789248a8a4 | |||
| eaad244181 | |||
| a859dbd646 | |||
| 106290a11e | |||
| 3fa0bac36f | |||
| b40dee9e68 | |||
| 6a9ffae758 | |||
| f1ce7f23c3 | |||
| f093634cb2 | |||
| 5f0672f3a6 | |||
| eca1d8501c | |||
| 3fc0fec95e | |||
| f4f1eac92d | |||
| 0e679f0fea | |||
| d55d3fc56d | |||
| 9a6347afb6 | |||
| 20fa676fae | |||
| 25603634db | |||
| ef5d6d7889 | |||
| f15a32255b | |||
| a7fc1aa7a7 | |||
| 2ca3c225c4 | |||
| 9ceb45b058 | |||
| 4881d870c7 | |||
| 5b7b87e524 | |||
| 6ab6fdf1f0 | |||
| 5653030c64 |
@@ -1,3 +1,2 @@
|
||||
node_modules
|
||||
.git
|
||||
website
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
FROM node:12
|
||||
WORKDIR /code
|
||||
COPY package*.json /code/
|
||||
RUN npm install
|
||||
RUN npm install -g gulp-cli mocha
|
||||
FROM node:12
|
||||
|
||||
# Install global packages
|
||||
RUN npm install -g gulp-cli mocha
|
||||
|
||||
# Copy Habitica code into container and install dependencies
|
||||
WORKDIR /usr/src/habitica
|
||||
COPY . /usr/src/habitica
|
||||
|
||||
RUN npm install
|
||||
RUN npm run postinstall
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20191127_harvest_feast';
|
||||
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 inc;
|
||||
let push;
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (typeof user.items.gear.owned.head_special_turkeyHelmGilded !== 'undefined') {
|
||||
inc = {
|
||||
'items.food.Pie_Base': 1,
|
||||
'items.food.Pie_CottonCandyBlue': 1,
|
||||
'items.food.Pie_CottonCandyPink': 1,
|
||||
'items.food.Pie_Desert': 1,
|
||||
'items.food.Pie_Golden': 1,
|
||||
'items.food.Pie_Red': 1,
|
||||
'items.food.Pie_Shade': 1,
|
||||
'items.food.Pie_Skeleton': 1,
|
||||
'items.food.Pie_Zombie': 1,
|
||||
'items.food.Pie_White': 1,
|
||||
}
|
||||
} else if (typeof user.items.gear.owned.armor_special_turkeyArmorBase !== 'undefined') {
|
||||
set['items.gear.owned.head_special_turkeyHelmGilded'] = false;
|
||||
set['items.gear.owned.armor_special_turkeyArmorGilded'] = false;
|
||||
set['items.gear.owned.back_special_turkeyTailGilded'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_turkeyHelmGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.armor_special_turkeyArmorGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.back_special_turkeyTailGilded',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (user.items && user.items.mounts && user.items.mounts['Turkey-Gilded']) {
|
||||
set['items.gear.owned.head_special_turkeyHelmBase'] = false;
|
||||
set['items.gear.owned.armor_special_turkeyArmorBase'] = false;
|
||||
set['items.gear.owned.back_special_turkeyTailBase'] = false;
|
||||
push = [
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.head_special_turkeyHelmBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.armor_special_turkeyArmorBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
{
|
||||
type: 'marketGear',
|
||||
path: 'gear.flat.back_special_turkeyTailBase',
|
||||
_id: uuid(),
|
||||
},
|
||||
];
|
||||
} else if (user.items && user.items.pets && user.items.pets['Turkey-Gilded']) {
|
||||
set['items.mounts.Turkey-Gilded'] = true;
|
||||
} else if (user.items && user.items.mounts && user.items.mounts['Turkey-Base']) {
|
||||
set['items.pets.Turkey-Gilded'] = 5;
|
||||
} else if (user.items && user.items.pets && user.items.pets['Turkey-Base']) {
|
||||
set['items.mounts.Turkey-Base'] = true;
|
||||
} else {
|
||||
set['items.pets.Turkey-Base'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (inc) {
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
} else if (push) {
|
||||
return await User.update({_id: user._id}, {$set: set, $push: {pinnedItems: {$each: push}}}).exec();
|
||||
} else {
|
||||
return await User.update({_id: user._id}, {$set: set}).exec();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-11-01')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20191210_pet_color_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Wolf-White'] > 0
|
||||
&& pets['TigerCub-White'] > 0
|
||||
&& pets['PandaCub-White'] > 0
|
||||
&& pets['LionCub-White'] > 0
|
||||
&& pets['Fox-White'] > 0
|
||||
&& pets['FlyingPig-White'] > 0
|
||||
&& pets['Dragon-White'] > 0
|
||||
&& pets['Cactus-White'] > 0
|
||||
&& pets['BearCub-White'] > 0) {
|
||||
set['achievements.primedForPainting'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (user && user.items && user.items.mounts) {
|
||||
const mounts = user.items.mounts;
|
||||
if (mounts['Wolf-White']
|
||||
&& mounts['TigerCub-White']
|
||||
&& mounts['PandaCub-White']
|
||||
&& mounts['LionCub-White']
|
||||
&& mounts['Fox-White']
|
||||
&& mounts['FlyingPig-White']
|
||||
&& mounts['Dragon-White']
|
||||
&& mounts['Cactus-White']
|
||||
&& mounts['BearCub-White'] ) {
|
||||
set['achievements.pearlyPro'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2019-12-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,110 +0,0 @@
|
||||
import monk from 'monk';
|
||||
import nconf from 'nconf';
|
||||
|
||||
const migrationName = 'mystery-items-201808.js'; // Update per month
|
||||
const authorName = 'Sabe'; // in case script author needs to know when their ...
|
||||
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Award this month's mystery items to subscribers
|
||||
*/
|
||||
const MYSTERY_ITEMS = ['armor_mystery_201810', 'head_mystery_201810'];
|
||||
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
|
||||
|
||||
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
|
||||
let UserNotification = require('../../website/server/models/userNotification').model;
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
let query = {
|
||||
migration: {$ne: migrationName},
|
||||
'purchased.plan.customerId': { $ne: null },
|
||||
$or: [
|
||||
{ 'purchased.plan.dateTerminated': { $gte: new Date() } },
|
||||
{ 'purchased.plan.dateTerminated': { $exists: false } },
|
||||
{ 'purchased.plan.dateTerminated': { $eq: null } },
|
||||
],
|
||||
};
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
$gt: lastId,
|
||||
};
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
fields: [
|
||||
], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return;
|
||||
}
|
||||
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const addToSet = {
|
||||
'purchased.plan.mysteryItems': {
|
||||
$each: MYSTERY_ITEMS,
|
||||
},
|
||||
};
|
||||
const push = {
|
||||
notifications: (new UserNotification({
|
||||
type: 'NEW_MYSTERY_ITEMS',
|
||||
data: {
|
||||
MYSTERY_ITEMS,
|
||||
},
|
||||
})).toJSON(),
|
||||
};
|
||||
|
||||
dbUsers.update({_id: user._id}, {$addToSet: addToSet, $push: push});
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
module.exports = processUsers;
|
||||
@@ -16,7 +16,7 @@ async function updateUser (user) {
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
sendTxn(
|
||||
await sendTxn(
|
||||
user,
|
||||
EMAIL_SLUG,
|
||||
[{ name: 'BASE_URL', content: BASE_URL }], // Add variables from template
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
import { model as UserNotification } from '../../website/server/models/userNotification';
|
||||
|
||||
const MIGRATION_NAME = 'mystery_items_201910';
|
||||
const MYSTERY_ITEMS = ['armor_mystery_201910', 'head_mystery_201910'];
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count += 1;
|
||||
|
||||
const addToSet = {
|
||||
'purchased.plan.mysteryItems': {
|
||||
$each: MYSTERY_ITEMS,
|
||||
},
|
||||
};
|
||||
const push = {
|
||||
notifications: (new UserNotification({
|
||||
type: 'NEW_MYSTERY_ITEMS',
|
||||
data: {
|
||||
MYSTERY_ITEMS,
|
||||
},
|
||||
})).toJSON(),
|
||||
};
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return User.update({ _id: user._id }, { $set: set, $push: push, $addToSet: addToSet }).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
const query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'purchased.plan.customerId': { $ne: null },
|
||||
$or: [
|
||||
{ 'purchased.plan.dateTerminated': { $gte: new Date() } },
|
||||
{ 'purchased.plan.dateTerminated': { $exists: false } },
|
||||
{ 'purchased.plan.dateTerminated': { $eq: null } },
|
||||
],
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 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,21 +1,21 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.121.1",
|
||||
"version": "4.126.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.7.2",
|
||||
"@babel/preset-env": "^7.7.1",
|
||||
"@babel/register": "^7.7.0",
|
||||
"@google-cloud/trace-agent": "^4.2.2",
|
||||
"@babel/core": "^7.7.4",
|
||||
"@babel/preset-env": "^7.7.4",
|
||||
"@babel/register": "^7.7.4",
|
||||
"@google-cloud/trace-agent": "^4.2.3",
|
||||
"@slack/client": "^3.8.1",
|
||||
"accepts": "^1.3.5",
|
||||
"amazon-payments": "^0.2.7",
|
||||
"amplitude": "^3.5.0",
|
||||
"apidoc": "^0.17.5",
|
||||
"apn": "^2.2.0",
|
||||
"aws-sdk": "^2.568.0",
|
||||
"bcrypt": "^3.0.6",
|
||||
"aws-sdk": "^2.578.0",
|
||||
"bcrypt": "^3.0.7",
|
||||
"body-parser": "^1.18.3",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-session": "^1.3.3",
|
||||
@@ -23,7 +23,7 @@
|
||||
"csv-stringify": "^5.1.0",
|
||||
"cwait": "^1.1.1",
|
||||
"domain-middleware": "~0.1.0",
|
||||
"eslint": "^6.6.0",
|
||||
"eslint": "^6.7.1",
|
||||
"eslint-config-habitrpg": "^6.2.0",
|
||||
"eslint-plugin-mocha": "^5.0.0",
|
||||
"express": "^4.16.3",
|
||||
@@ -33,7 +33,7 @@
|
||||
"got": "^9.0.0",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-babel": "^8.0.0",
|
||||
"gulp-imagemin": "^6.1.1",
|
||||
"gulp-imagemin": "^6.2.0",
|
||||
"gulp-nodemon": "^2.4.1",
|
||||
"gulp.spritesmith": "^6.9.0",
|
||||
"habitica-markdown": "^1.3.0",
|
||||
@@ -46,7 +46,7 @@
|
||||
"method-override": "^3.0.0",
|
||||
"moment": "^2.24.0",
|
||||
"moment-recur": "^1.0.7",
|
||||
"mongoose": "^5.7.9",
|
||||
"mongoose": "^5.7.12",
|
||||
"morgan": "^1.7.0",
|
||||
"nconf": "^0.10.0",
|
||||
"node-gcm": "^1.0.2",
|
||||
@@ -61,8 +61,8 @@
|
||||
"regenerator-runtime": "^0.13.3",
|
||||
"rimraf": "^3.0.0",
|
||||
"short-uuid": "^3.0.0",
|
||||
"stripe": "^7.13.0",
|
||||
"superagent": "^5.0.2",
|
||||
"stripe": "^7.13.1",
|
||||
"superagent": "^5.1.1",
|
||||
"universal-analytics": "^0.4.17",
|
||||
"useragent": "^2.1.9",
|
||||
"uuid": "^3.3.3",
|
||||
|
||||
@@ -24,7 +24,13 @@ async function deleteAmplitudeData (userId, email) {
|
||||
console.log(err.response.data);
|
||||
});
|
||||
|
||||
if (response) console.log(`${response.status} ${response.statusText}`);
|
||||
if (response) {
|
||||
if (response.status === 200) {
|
||||
console.log(`${userId} (${email}) Amplitude deletion request OK.`);
|
||||
} else {
|
||||
console.log(`${userId} (${email}) Amplitude response: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteHabiticaData (user, email) {
|
||||
@@ -54,39 +60,46 @@ async function deleteHabiticaData (user, email) {
|
||||
});
|
||||
|
||||
if (response) {
|
||||
console.log(`${response.status} ${response.statusText}`);
|
||||
if (response.status === 200) console.log(`${user._id} (${email}) removed. Last login: ${user.auth.timestamps.loggedin}`);
|
||||
if (response.status === 200) {
|
||||
console.log(`${user._id} (${email}) removed from Habitica. Last login: ${user.auth.timestamps.loggedin}`);
|
||||
} else {
|
||||
console.log(`${user._id} (${email}) Habitica response: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function processEmailAddress (email) {
|
||||
const emailRegex = new RegExp(`^${email}$`, 'i');
|
||||
const users = await User.find({
|
||||
$or: [
|
||||
{ 'auth.local.email': emailRegex },
|
||||
{ 'auth.facebook.emails.value': emailRegex },
|
||||
{ 'auth.google.emails.value': emailRegex },
|
||||
],
|
||||
},
|
||||
{
|
||||
_id: 1,
|
||||
apiToken: 1,
|
||||
auth: 1,
|
||||
}).exec();
|
||||
const localUsers = await User.find(
|
||||
{ 'auth.local.email': emailRegex },
|
||||
{ _id: 1, apiToken: 1, auth: 1 },
|
||||
).exec();
|
||||
|
||||
const socialUsers = await User.find(
|
||||
{
|
||||
$or: [
|
||||
{ 'auth.facebook.emails.value': email },
|
||||
{ 'auth.google.emails.value': email },
|
||||
],
|
||||
},
|
||||
{ _id: 1, apiToken: 1, auth: 1 },
|
||||
).collation(
|
||||
{ locale: 'en', strength: 1 },
|
||||
).exec();
|
||||
|
||||
const users = localUsers.concat(socialUsers);
|
||||
|
||||
if (users.length < 1) {
|
||||
console.log(`No users found with email address ${email}`);
|
||||
} else {
|
||||
Promise.all(users.map(user => (async () => {
|
||||
await deleteAmplitudeData(user._id, email); // eslint-disable-line no-await-in-loop
|
||||
await deleteHabiticaData(user, email); // eslint-disable-line no-await-in-loop
|
||||
})()));
|
||||
return console.log(`No users found with email address ${email}`);
|
||||
}
|
||||
|
||||
return Promise.all(users.map(user => (async () => {
|
||||
await deleteAmplitudeData(user._id, email); // eslint-disable-line no-await-in-loop
|
||||
await deleteHabiticaData(user, email); // eslint-disable-line no-await-in-loop
|
||||
})()));
|
||||
}
|
||||
|
||||
function deleteUserData (emails) {
|
||||
export default function deleteUserData (emails) {
|
||||
const emailPromises = emails.map(processEmailAddress);
|
||||
return Promise.all(emailPromises);
|
||||
}
|
||||
|
||||
module.exports = deleteUserData;
|
||||
|
||||
@@ -88,6 +88,28 @@ describe('cron', () => {
|
||||
user.purchased.plan.dateUpdated = moment().subtract(1, 'months').toDate();
|
||||
});
|
||||
|
||||
it('awards current mystery items to subscriber', () => {
|
||||
user.purchased.plan.dateUpdated = new Date('2018-12-11');
|
||||
clock = sinon.useFakeTimers(new Date('2019-01-29'));
|
||||
cron({
|
||||
user, tasksByType, daysMissed, analytics,
|
||||
});
|
||||
expect(user.purchased.plan.mysteryItems.length).to.eql(2);
|
||||
const filteredNotifications = user.notifications.filter(n => n.type === 'NEW_MYSTERY_ITEMS');
|
||||
expect(filteredNotifications.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('awards multiple mystery item sets if user skipped months between logins', () => {
|
||||
user.purchased.plan.dateUpdated = new Date('2018-11-11');
|
||||
clock = sinon.useFakeTimers(new Date('2019-01-29'));
|
||||
cron({
|
||||
user, tasksByType, daysMissed, analytics,
|
||||
});
|
||||
expect(user.purchased.plan.mysteryItems.length).to.eql(4);
|
||||
const filteredNotifications = user.notifications.filter(n => n.type === 'NEW_MYSTERY_ITEMS');
|
||||
expect(filteredNotifications.length).to.equal(1);
|
||||
});
|
||||
|
||||
it('resets plan.gemsBought on a new month', () => {
|
||||
user.purchased.plan.gemsBought = 10;
|
||||
cron({
|
||||
|
||||
@@ -439,31 +439,6 @@ describe('payments/index', () => {
|
||||
fakeClock.restore();
|
||||
});
|
||||
|
||||
it('does not awards mystery items when not within the timeframe for a mystery item', async () => {
|
||||
const noMysteryItemTimeframe = 1462183920000; // May 2nd 2016
|
||||
const fakeClock = sinon.useFakeTimers(noMysteryItemTimeframe);
|
||||
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
||||
|
||||
await api.createSubscription(data);
|
||||
|
||||
expect(user.purchased.plan.mysteryItems).to.have.a.lengthOf(0);
|
||||
|
||||
fakeClock.restore();
|
||||
});
|
||||
|
||||
it('does not add a notification for mystery items if none was awarded', async () => {
|
||||
const noMysteryItemTimeframe = 1462183920000; // May 2nd 2016
|
||||
const fakeClock = sinon.useFakeTimers(noMysteryItemTimeframe);
|
||||
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
|
||||
|
||||
await api.createSubscription(data);
|
||||
|
||||
expect(user.purchased.plan.mysteryItems).to.have.a.lengthOf(0);
|
||||
expect(user.notifications.find(n => n.type === 'NEW_MYSTERY_ITEMS')).to.be.undefined;
|
||||
|
||||
fakeClock.restore();
|
||||
});
|
||||
|
||||
it('does not award mystery item when user already owns the item', async () => {
|
||||
const mayMysteryItemTimeframe = 1464725113000; // May 31st 2016
|
||||
const fakeClock = sinon.useFakeTimers(mayMysteryItemTimeframe);
|
||||
|
||||
@@ -63,6 +63,26 @@ describe('PUT /user/webhook/:id', () => {
|
||||
expect(webhook.options).to.eql(options);
|
||||
});
|
||||
|
||||
it('updates a webhook with empty label', async () => {
|
||||
const url = 'http://a-new-url.com';
|
||||
const type = 'groupChatReceived';
|
||||
const label = '';
|
||||
const options = { groupId: generateUUID() };
|
||||
|
||||
await user.put(`/user/webhook/${webhookToUpdate.id}`, {
|
||||
url, type, options, label,
|
||||
});
|
||||
|
||||
await user.sync();
|
||||
|
||||
const webhook = user.webhooks.find(hook => webhookToUpdate.id === hook.id);
|
||||
|
||||
expect(webhook.url).to.equal(url);
|
||||
expect(webhook.label).to.equal(label);
|
||||
expect(webhook.type).to.equal(type);
|
||||
expect(webhook.options).to.eql(options);
|
||||
});
|
||||
|
||||
it('returns the updated webhook', async () => {
|
||||
const url = 'http://a-new-url.com';
|
||||
const type = 'groupChatReceived';
|
||||
|
||||
@@ -1798,9 +1798,9 @@
|
||||
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM="
|
||||
},
|
||||
"amplitude-js": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/amplitude-js/-/amplitude-js-5.6.0.tgz",
|
||||
"integrity": "sha512-XGaM0sTvMOrVYqfHhkKEikjQ/SzhEGbupxYopcrzEpEuNLenSOIBMyB0JycBcFI1hTWR4rGJ2TDRqIeRMmUZvg==",
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/amplitude-js/-/amplitude-js-5.7.0.tgz",
|
||||
"integrity": "sha512-nKE5oJhfuGTxUlJje4XJ7hpRmCTkM1G4sKRvk9vFxo/SsgHZ2qofd9a5Bvk/OKO2N4P9RMyLRa0byJ9j6NIAeg==",
|
||||
"requires": {
|
||||
"@amplitude/ua-parser-js": "0.7.20",
|
||||
"blueimp-md5": "^2.10.0",
|
||||
@@ -1825,17 +1825,17 @@
|
||||
"integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw=="
|
||||
},
|
||||
"ansi-escapes": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz",
|
||||
"integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
|
||||
"integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
|
||||
"requires": {
|
||||
"type-fest": "^0.5.2"
|
||||
"type-fest": "^0.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
|
||||
"integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw=="
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2386,13 +2386,13 @@
|
||||
"integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
|
||||
},
|
||||
"bootstrap-vue": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.4.tgz",
|
||||
"integrity": "sha512-/5WXa3ir5uajcs7ze7jz7QXpYuJGWHjvJ8biMq0+e0IIIxw2jSdh4LsiFKD7C7qtgKre28hhXOfx79RmZX4wcQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.1.0.tgz",
|
||||
"integrity": "sha512-dftb5fc42x7QLv814nN+3Cx8MMuCB+xrGQjOmSXH81ET0+yo7KYb4lUN3/pOnf+8Tkv8oaawZ1OOth5/AZfktg==",
|
||||
"requires": {
|
||||
"@nuxt/opencollective": "^0.3.0",
|
||||
"bootstrap": ">=4.3.1 <5.0.0",
|
||||
"popper.js": "^1.15.0",
|
||||
"popper.js": "^1.16.0",
|
||||
"portal-vue": "^2.1.6",
|
||||
"vue-functional-data-merge": "^3.1.0"
|
||||
}
|
||||
@@ -3120,9 +3120,9 @@
|
||||
"integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg=="
|
||||
},
|
||||
"consola": {
|
||||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/consola/-/consola-2.10.1.tgz",
|
||||
"integrity": "sha512-4sxpH6SGFYLADfUip4vuY65f/gEogrzJoniVhNUYkJHtng0l8ZjnDCqxxrSVRHOHwKxsy8Vm5ONZh1wOR3/l/w=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/consola/-/consola-2.11.0.tgz",
|
||||
"integrity": "sha512-2bcAqHastlPSCvZ+ur8bgHInGAWvUnysWz3h3xRX+/XZoCY7avolJJnVXOPGoVoyCcg1b231XixonoArmgxaoA=="
|
||||
},
|
||||
"console-browserify": {
|
||||
"version": "1.1.0",
|
||||
@@ -3283,9 +3283,9 @@
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.0.tgz",
|
||||
"integrity": "sha512-lQxb4HScV71YugF/X28LtePZj9AB7WqOpcB+YztYxusvhrgZiQXPmCYfPC5LHsw/+ScEtDbXU3xbqH3CjBRmYA=="
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.4.2.tgz",
|
||||
"integrity": "sha512-bUTfqFWtNKWp73oNIfRkqwYZJeNT3lstzZcAkhhiuvDraRSgOH1/+F9ZklbpR4zpdKuo4cpXN8tKP7s61yjX+g=="
|
||||
},
|
||||
"core-js-compat": {
|
||||
"version": "3.3.4",
|
||||
@@ -4257,9 +4257,9 @@
|
||||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz",
|
||||
"integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==",
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.1.tgz",
|
||||
"integrity": "sha512-UWzBS79pNcsDSxgxbdjkmzn/B6BhsXMfUaOHnNwyE8nD+Q6pyT96ow2MccVayUTV4yMid4qLhMiQaywctRkBLA==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"ajv": "^6.10.0",
|
||||
@@ -4276,7 +4276,7 @@
|
||||
"file-entry-cache": "^5.0.1",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"glob-parent": "^5.0.0",
|
||||
"globals": "^11.7.0",
|
||||
"globals": "^12.1.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.0.0",
|
||||
"imurmurhash": "^0.1.4",
|
||||
@@ -4289,7 +4289,7 @@
|
||||
"minimatch": "^3.0.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.8.2",
|
||||
"optionator": "^0.8.3",
|
||||
"progress": "^2.0.0",
|
||||
"regexpp": "^2.0.1",
|
||||
"semver": "^6.1.2",
|
||||
@@ -4317,15 +4317,36 @@
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "12.3.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
|
||||
"integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
|
||||
"requires": {
|
||||
"type-fest": "^0.8.1"
|
||||
}
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
|
||||
"integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
|
||||
"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
|
||||
"requires": {
|
||||
"parent-module": "^1.0.0",
|
||||
"resolve-from": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"optionator": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
|
||||
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
|
||||
"requires": {
|
||||
"deep-is": "~0.1.3",
|
||||
"fast-levenshtein": "~2.0.6",
|
||||
"levn": "~0.3.0",
|
||||
"prelude-ls": "~1.1.2",
|
||||
"type-check": "~0.3.2",
|
||||
"word-wrap": "~1.2.3"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||
@@ -4340,6 +4361,11 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
|
||||
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw=="
|
||||
},
|
||||
"type-fest": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4525,11 +4551,11 @@
|
||||
}
|
||||
},
|
||||
"eslint-plugin-vue": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.0.0.tgz",
|
||||
"integrity": "sha512-+LxTJCd6nDt+AKQ1X+ySD48xJHft8OkeQmAhiq6UoAMxRFTiEKIDusiGgEUJLwKyiwGUGWbbqEbbWvupH5TSjg==",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.0.1.tgz",
|
||||
"integrity": "sha512-5tgFPcxGDKjfVB/6Yi56bKiWxygUibfZmzSh26Np3kuwAk/lfaGbVld+Yt+MPgD84ppvcachtiL4/winsXLjXA==",
|
||||
"requires": {
|
||||
"vue-eslint-parser": "^6.0.4"
|
||||
"vue-eslint-parser": "^6.0.5"
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
@@ -4568,11 +4594,6 @@
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
|
||||
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ=="
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
|
||||
"integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -6343,6 +6364,11 @@
|
||||
"through": "^2.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
@@ -6384,13 +6410,23 @@
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz",
|
||||
"integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
|
||||
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^5.2.0"
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
|
||||
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9779,9 +9815,9 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.23.3.tgz",
|
||||
"integrity": "sha512-1DKRZxJMOh4Bme16AbWTyYeJAjTlrvw2+fWshHHaepeJfGq2soFZTnt0YhWit+bohtDu4LdyPoEj6VFD4APHog==",
|
||||
"version": "1.23.7",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.23.7.tgz",
|
||||
"integrity": "sha512-cYgc0fanwIpi0rXisGxl+/wadVQ/HX3RhpdRcjLdj2o2ye/sxUTpAxIhbmJy3PLQgRFbf6Pn8Jsrta2vdXcoOQ==",
|
||||
"requires": {
|
||||
"chokidar": ">=2.0.0 <4.0.0"
|
||||
}
|
||||
@@ -10090,9 +10126,9 @@
|
||||
}
|
||||
},
|
||||
"smartbanner.js": {
|
||||
"version": "1.14.6",
|
||||
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.14.6.tgz",
|
||||
"integrity": "sha512-yAc7ueVIiQ3kyHrQxOZncZiEFv6ubXxWj5E01xj45njFk8XZ8zG3VpAFPl70Yvmv/H0L/qjxOmQqF3H3T0j/SQ=="
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.15.0.tgz",
|
||||
"integrity": "sha512-a82o2llcEB8KLjMaqeeeZxevRiPSiKbXsUoep1wMunkwggDUStkgXI56c6Qt54Elh9qo3ZrRHJTh5HvVm68o+g=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
@@ -10653,12 +10689,32 @@
|
||||
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q="
|
||||
},
|
||||
"svg-url-loader": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-3.0.2.tgz",
|
||||
"integrity": "sha512-MUJFVU2uuOTZW6Eq6NuXZxhaIyWiuKtZMcT90nCkcvIZPGGc0CYyZWYP/rtXUkja5qagNMpxDwdZ/tuC6ywfWg==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/svg-url-loader/-/svg-url-loader-3.0.3.tgz",
|
||||
"integrity": "sha512-MKGiRNDs8fnHcZcPkhGcw9+130IXyFM9H8m6T7u3ScUuZYEeVzX0vNMru30D4MCF6vMYas5iw/Ru9lwFKBjaGw==",
|
||||
"requires": {
|
||||
"file-loader": "~4.2.0",
|
||||
"file-loader": "~4.3.0",
|
||||
"loader-utils": "~1.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"file-loader": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz",
|
||||
"integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==",
|
||||
"requires": {
|
||||
"loader-utils": "^1.2.3",
|
||||
"schema-utils": "^2.5.0"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.5.0.tgz",
|
||||
"integrity": "sha512-32ISrwW2scPXHUSusP8qMg5dLUawKkyV+/qIEV9JdXKx+rsM6mi8vZY8khg2M69Qom16rtroWXD3Ybtiws38gQ==",
|
||||
"requires": {
|
||||
"ajv": "^6.10.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"svgo": {
|
||||
@@ -11820,6 +11876,11 @@
|
||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
|
||||
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY="
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
"@vue/cli-plugin-unit-mocha": "^4.0.5",
|
||||
"@vue/cli-service": "^4.0.5",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"amplitude-js": "^5.6.0",
|
||||
"amplitude-js": "^5.7.0",
|
||||
"axios": "^0.19.0",
|
||||
"axios-progress-bar": "^1.2.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"bootstrap": "^4.3.1",
|
||||
"bootstrap-vue": "^2.0.4",
|
||||
"bootstrap-vue": "^2.1.0",
|
||||
"chai": "^4.1.2",
|
||||
"core-js": "^3.4.0",
|
||||
"eslint": "^6.6.0",
|
||||
"core-js": "^3.4.2",
|
||||
"eslint": "^6.7.1",
|
||||
"eslint-config-habitrpg": "^6.2.0",
|
||||
"eslint-plugin-mocha": "^5.3.0",
|
||||
"eslint-plugin-vue": "^6.0.0",
|
||||
"eslint-plugin-vue": "^6.0.1",
|
||||
"habitica-markdown": "^1.3.0",
|
||||
"hellojs": "^1.18.1",
|
||||
"inspectpack": "^4.2.2",
|
||||
@@ -37,11 +37,11 @@
|
||||
"lodash": "^4.17.15",
|
||||
"moment": "^2.24.0",
|
||||
"nconf": "^0.10.0",
|
||||
"sass": "^1.23.3",
|
||||
"sass": "^1.23.7",
|
||||
"sass-loader": "^8.0.0",
|
||||
"smartbanner.js": "^1.14.5",
|
||||
"smartbanner.js": "^1.15.0",
|
||||
"svg-inline-loader": "^0.8.0",
|
||||
"svg-url-loader": "^3.0.2",
|
||||
"svg-url-loader": "^3.0.3",
|
||||
"svgo": "^1.3.2",
|
||||
"svgo-loader": "^2.2.1",
|
||||
"uuid": "^3.3.3",
|
||||
|
||||
@@ -1,28 +1,40 @@
|
||||
.promo_armoire_backgrounds_201911 {
|
||||
.promo_achievement_white {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -752px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
background-position: -928px -465px;
|
||||
width: 204px;
|
||||
height: 102px;
|
||||
}
|
||||
.promo_costume_achievement {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -928px -296px;
|
||||
width: 144px;
|
||||
height: 156px;
|
||||
}
|
||||
.promo_delightful_dinos {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -424px -752px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_ember_thunderstorm_potions {
|
||||
.promo_armoire_backgrounds_201912 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -928px 0px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_mystery_201910 {
|
||||
.promo_costume_achievement {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -1175px -296px;
|
||||
width: 144px;
|
||||
height: 156px;
|
||||
}
|
||||
.promo_delightful_dinos {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -752px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_ember_thunderstorm_potions {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -424px -752px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_harvest_feast {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -928px -296px;
|
||||
width: 246px;
|
||||
height: 168px;
|
||||
}
|
||||
.promo_mystery_201912 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -928px -148px;
|
||||
width: 282px;
|
||||
|
||||
@@ -1,330 +1,492 @@
|
||||
.weapon_warrior_3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1893px -1361px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_warrior_4 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1893px -1270px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_warrior_5 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -1452px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_warrior_6 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1893px -1452px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_0 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -1543px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1893px -1543px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1893px -997px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -1088px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_4 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1893px -1088px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_5 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -1179px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.weapon_wizard_6 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -1270px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.Pet_Currency_Gem {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1269px;
|
||||
background-position: -1921px -444px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_Currency_Gem1x {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1992px -592px;
|
||||
background-position: -1957px -676px;
|
||||
width: 15px;
|
||||
height: 13px;
|
||||
}
|
||||
.Pet_Currency_Gem2x {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1766px -1474px;
|
||||
background-position: -1960px -766px;
|
||||
width: 30px;
|
||||
height: 26px;
|
||||
}
|
||||
.PixelPaw-Gold {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1929px -711px;
|
||||
background-position: -1688px -1436px;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
}
|
||||
.PixelPaw {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -1474px;
|
||||
background-position: -1740px -1436px;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
}
|
||||
.PixelPaw002 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1614px;
|
||||
background-position: -220px -203px;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
}
|
||||
.avatar_floral_healer {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1887px -576px;
|
||||
width: 99px;
|
||||
height: 99px;
|
||||
}
|
||||
.avatar_floral_rogue {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -697px;
|
||||
width: 99px;
|
||||
height: 99px;
|
||||
}
|
||||
.avatar_floral_warrior {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -897px;
|
||||
width: 99px;
|
||||
height: 99px;
|
||||
}
|
||||
.avatar_floral_wizard {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -797px;
|
||||
width: 99px;
|
||||
height: 99px;
|
||||
}
|
||||
.empty_bottles {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1921px -513px;
|
||||
width: 64px;
|
||||
height: 54px;
|
||||
}
|
||||
.ghost {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1802px -997px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.inventory_present {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1935px -854px;
|
||||
background-position: -1696px -608px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_01 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1902px -797px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_02 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1902px -897px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_03 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -470px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_04 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -539px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_05 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1696px -539px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_06 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -884px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_07 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1696px -884px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_08 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -953px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_09 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1696px -1367px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_10 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1902px -697px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_11 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1200px;
|
||||
background-position: -1696px -470px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_present_12 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1269px;
|
||||
background-position: -1627px -608px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_birthday {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -993px;
|
||||
background-position: -1627px -746px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_congrats {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1338px;
|
||||
background-position: -1696px -746px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_fortify {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1407px;
|
||||
background-position: -1627px -815px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_getwell {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1476px;
|
||||
background-position: -1696px -953px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_goodluck {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1929px -642px;
|
||||
background-position: -1627px -1367px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_greeting {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1935px -763px;
|
||||
background-position: -1696px -1298px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_nye {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1062px;
|
||||
background-position: -1627px -1298px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_opaquePotion {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1131px;
|
||||
background-position: -1696px -1229px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_seafoam {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1338px;
|
||||
background-position: -1627px -1229px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_shinySeed {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1545px;
|
||||
background-position: -1696px -1160px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_snowball {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1614px;
|
||||
background-position: -1627px -1160px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_spookySparkles {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -993px;
|
||||
background-position: -1696px -1091px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_thankyou {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1062px;
|
||||
background-position: -1627px -1091px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_trinket {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1131px;
|
||||
background-position: -1696px -1022px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_special_valentine {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1200px;
|
||||
background-position: -1627px -1022px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.knockout {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -945px;
|
||||
background-position: -1627px -422px;
|
||||
width: 120px;
|
||||
height: 47px;
|
||||
}
|
||||
.pet_key {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1545px;
|
||||
background-position: -1696px -815px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.rebirth_orb {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1476px;
|
||||
background-position: -1696px -677px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.seafoam_star {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -854px;
|
||||
background-position: -1893px -1179px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.shop_armoire {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1913px -1407px;
|
||||
background-position: -1627px -677px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.snowman {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -763px;
|
||||
background-position: -1802px -1361px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
.zzz {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1963px -551px;
|
||||
background-position: -220px -255px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.zzz_light {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1963px -510px;
|
||||
background-position: -1748px -422px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.notif_inventory_present_01 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1981px -711px;
|
||||
background-position: -1953px -229px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_02 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1965px -945px;
|
||||
background-position: -1953px -200px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_03 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1965px -1614px;
|
||||
background-position: -1953px -171px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_04 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -1683px;
|
||||
background-position: -1953px -142px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_05 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1873px -1683px;
|
||||
background-position: -1931px -766px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_06 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1902px -1683px;
|
||||
background-position: -1902px -766px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_07 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1737px -1474px;
|
||||
background-position: -1953px -409px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_08 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1960px -1683px;
|
||||
background-position: -1953px -380px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_09 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1679px -1474px;
|
||||
background-position: -1953px -351px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_10 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1963px -592px;
|
||||
background-position: -1953px -322px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_11 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1708px -1474px;
|
||||
background-position: -1953px -258px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_present_12 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1931px -1683px;
|
||||
background-position: -1953px -293px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.notif_inventory_special_birthday {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -1131px;
|
||||
background-position: -1971px -797px;
|
||||
width: 20px;
|
||||
height: 24px;
|
||||
}
|
||||
.notif_inventory_special_congrats {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -1156px;
|
||||
background-position: -1927px -866px;
|
||||
width: 20px;
|
||||
height: 22px;
|
||||
}
|
||||
.notif_inventory_special_getwell {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1981px -740px;
|
||||
background-position: -1948px -866px;
|
||||
width: 20px;
|
||||
height: 22px;
|
||||
}
|
||||
.notif_inventory_special_goodluck {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -1020px;
|
||||
background-position: -1971px -697px;
|
||||
width: 20px;
|
||||
height: 26px;
|
||||
}
|
||||
.notif_inventory_special_greeting {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -1200px;
|
||||
background-position: -1969px -866px;
|
||||
width: 20px;
|
||||
height: 22px;
|
||||
}
|
||||
.notif_inventory_special_nye {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -993px;
|
||||
background-position: -1902px -866px;
|
||||
width: 24px;
|
||||
height: 26px;
|
||||
}
|
||||
.notif_inventory_special_thankyou {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -1087px;
|
||||
background-position: -1971px -724px;
|
||||
width: 20px;
|
||||
height: 24px;
|
||||
}
|
||||
.notif_inventory_special_valentine {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1982px -1062px;
|
||||
background-position: -1971px -822px;
|
||||
width: 20px;
|
||||
height: 24px;
|
||||
}
|
||||
.npc_bailey {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -203px;
|
||||
background-position: -1627px -1436px;
|
||||
width: 60px;
|
||||
height: 72px;
|
||||
}
|
||||
.npc_justin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -642px;
|
||||
background-position: -1802px -576px;
|
||||
width: 84px;
|
||||
height: 120px;
|
||||
}
|
||||
.npc_matt {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1155px -1315px;
|
||||
background-position: -208px -1529px;
|
||||
width: 195px;
|
||||
height: 138px;
|
||||
}
|
||||
@@ -336,22 +498,28 @@
|
||||
}
|
||||
.banner_flair_dysheartener {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1935px -832px;
|
||||
background-position: -1887px -676px;
|
||||
width: 69px;
|
||||
height: 18px;
|
||||
}
|
||||
.phobia_dysheartener {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -1278px;
|
||||
background-position: -307px -220px;
|
||||
width: 201px;
|
||||
height: 195px;
|
||||
}
|
||||
.quest_alligator {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -862px;
|
||||
background-position: -967px -660px;
|
||||
width: 201px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_amber {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_armadillo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -527px 0px;
|
||||
@@ -360,73 +528,73 @@
|
||||
}
|
||||
.quest_atom1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -445px -1315px;
|
||||
background-position: -1335px -1315px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_atom2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -947px -1315px;
|
||||
background-position: 0px -1529px;
|
||||
width: 207px;
|
||||
height: 138px;
|
||||
}
|
||||
.quest_atom3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -967px -660px;
|
||||
background-position: -433px -1315px;
|
||||
width: 216px;
|
||||
height: 180px;
|
||||
}
|
||||
.quest_axolotl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -655px;
|
||||
background-position: -660px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_badger {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -875px;
|
||||
background-position: 0px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_basilist {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -191px -1529px;
|
||||
background-position: -1802px 0px;
|
||||
width: 189px;
|
||||
height: 141px;
|
||||
}
|
||||
.quest_beetle {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -1076px;
|
||||
background-position: -747px -440px;
|
||||
width: 204px;
|
||||
height: 201px;
|
||||
}
|
||||
.quest_bronze {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px -660px;
|
||||
background-position: -880px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_bunny {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px -880px;
|
||||
background-position: -222px -1315px;
|
||||
width: 210px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_butterfly {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1407px 0px;
|
||||
background-position: -1187px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_cheetah {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1407px -660px;
|
||||
background-position: 0px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_cow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -307px -220px;
|
||||
background-position: -1627px 0px;
|
||||
width: 174px;
|
||||
height: 213px;
|
||||
}
|
||||
@@ -438,31 +606,31 @@
|
||||
}
|
||||
.quest_dilatoryDistress1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -651px;
|
||||
background-position: -1187px -880px;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.quest_dilatoryDistress2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -208px;
|
||||
background-position: -1802px -293px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_dilatoryDistress3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -1095px;
|
||||
background-position: -1407px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatory_derby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1407px -440px;
|
||||
background-position: -880px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -1095px;
|
||||
background-position: -1407px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -474,31 +642,31 @@
|
||||
}
|
||||
.quest_egg {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px 0px;
|
||||
background-position: -1627px -214px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -510px;
|
||||
background-position: -1802px -444px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -1095px;
|
||||
background-position: -1407px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_falcon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -1095px;
|
||||
background-position: -1100px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1095px;
|
||||
background-position: -440px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -510,19 +678,19 @@
|
||||
}
|
||||
.quest_ghost_stag {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px -440px;
|
||||
background-position: -440px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px -220px;
|
||||
background-position: -220px -1095px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -696px -1315px;
|
||||
background-position: -1084px -1315px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
@@ -534,49 +702,49 @@
|
||||
}
|
||||
.quest_gryphon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -747px -440px;
|
||||
background-position: -867px -1315px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_guineapig {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1407px -880px;
|
||||
background-position: -1187px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_harpy {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -875px;
|
||||
background-position: -1187px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_hedgehog {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1407px -1100px;
|
||||
background-position: -527px -220px;
|
||||
width: 219px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_hippo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -875px;
|
||||
background-position: -660px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_horse {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -875px;
|
||||
background-position: -307px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kangaroo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -875px;
|
||||
background-position: -220px -875px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kraken {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -527px -220px;
|
||||
background-position: -650px -1315px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
@@ -600,31 +768,31 @@
|
||||
}
|
||||
.quest_mayhemMistiflying1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1844px -359px;
|
||||
background-position: -1802px -142px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_mayhemMistiflying2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -655px;
|
||||
background-position: -440px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -655px;
|
||||
background-position: -220px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_monkey {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -655px;
|
||||
background-position: 0px -655px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -217px;
|
||||
background-position: -1407px -880px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
@@ -660,37 +828,7 @@
|
||||
}
|
||||
.quest_nudibranch {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px -434px;
|
||||
background-position: -1407px -1097px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_octopus {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -222px -1315px;
|
||||
width: 222px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_owl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -307px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_peacock {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1627px 0px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_penguin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1529px;
|
||||
width: 190px;
|
||||
height: 183px;
|
||||
}
|
||||
.quest_pterodactyl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1187px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 481 KiB After Width: | Height: | Size: 477 KiB |
|
Before Width: | Height: | Size: 669 KiB After Width: | Height: | Size: 685 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 369 KiB After Width: | Height: | Size: 363 KiB |
|
Before Width: | Height: | Size: 318 KiB After Width: | Height: | Size: 322 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 126 KiB |
@@ -1,41 +1,83 @@
|
||||
.tier1 {
|
||||
color: #c42870;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color: #c42870;
|
||||
}
|
||||
}
|
||||
|
||||
.tier2 {
|
||||
color: #b01515;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color: #b01515;
|
||||
}
|
||||
}
|
||||
|
||||
.tier3 {
|
||||
color: #d70e14;
|
||||
|
||||
:hover, :active, :focus {
|
||||
color: #d70e14;
|
||||
}
|
||||
}
|
||||
|
||||
.tier4 {
|
||||
color: #c24d00;
|
||||
|
||||
&:hover, &:active, :focus {
|
||||
color: #c24d00;
|
||||
}
|
||||
}
|
||||
|
||||
.tier5 {
|
||||
color: #9e650f;
|
||||
|
||||
:hover, :active, :focus {
|
||||
color: #9e650f;
|
||||
}
|
||||
}
|
||||
|
||||
.tier6 {
|
||||
color: #2b8363;
|
||||
|
||||
:hover, :active, &:focus {
|
||||
color: #2b8363;
|
||||
}
|
||||
}
|
||||
|
||||
.tier7 {
|
||||
color: #167e87;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color: #167e87;
|
||||
}
|
||||
}
|
||||
|
||||
.tier8 {
|
||||
color: #277eab;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color: #277eab;
|
||||
}
|
||||
}
|
||||
|
||||
.tier9 {
|
||||
color: #6133b4;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color: #6133b4;
|
||||
}
|
||||
}
|
||||
|
||||
.tierNPC, .npc {
|
||||
color: #77f4c7;
|
||||
fill: #77f4c7;
|
||||
stroke: #005737;
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
color: #77f4c7;
|
||||
fill: #77f4c7;
|
||||
stroke: #005737;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
v-model="user.preferences.suppressModals.streak"
|
||||
type="checkbox"
|
||||
@change="suppressModals"
|
||||
id="user-preferences-suppressModals-streak"
|
||||
>
|
||||
<label>{{ $t('dontShowAgain') }}</label>
|
||||
<label for="user-preferences-suppressModals-streak">{{ $t('dontShowAgain') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -151,7 +151,13 @@ export default {
|
||||
'blackTopFrame', 'blueTopFrame', 'greenTopFrame', 'pinkTopFrame', 'redTopFrame', 'whiteTopFrame', 'yellowTopFrame',
|
||||
'blackHalfMoon', 'blueHalfMoon', 'greenHalfMoon', 'pinkHalfMoon', 'redHalfMoon', 'whiteHalfMoon', 'yellowHalfMoon',
|
||||
];
|
||||
const options = keys.map(key => {
|
||||
const noneOption = this.createGearItem(0, 'eyewear', 'base');
|
||||
noneOption.none = true;
|
||||
const options = [
|
||||
noneOption,
|
||||
];
|
||||
|
||||
for (const key of keys) {
|
||||
const newKey = `eyewear_special_${key}`;
|
||||
const option = {};
|
||||
option.key = key;
|
||||
@@ -164,8 +170,9 @@ export default {
|
||||
|
||||
return this.equip(newKey, type);
|
||||
};
|
||||
return option;
|
||||
});
|
||||
options.push(option);
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
freeShirts () {
|
||||
@@ -179,20 +186,18 @@ export default {
|
||||
},
|
||||
headbands () {
|
||||
const keys = ['blackHeadband', 'blueHeadband', 'greenHeadband', 'pinkHeadband', 'redHeadband', 'whiteHeadband', 'yellowHeadband'];
|
||||
const options = keys.map(key => {
|
||||
const newKey = `headAccessory_special_${key}`;
|
||||
const option = {};
|
||||
option.key = key;
|
||||
option.active = this.user.preferences.costume
|
||||
? this.user.items.gear.costume.headAccessory === newKey
|
||||
: this.user.items.gear.equipped.headAccessory === newKey;
|
||||
option.class = `headAccessory_special_${option.key} headband`;
|
||||
option.click = () => {
|
||||
const type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
return this.equip(newKey, type);
|
||||
};
|
||||
return option;
|
||||
});
|
||||
const noneOption = this.createGearItem(0, 'headAccessory', 'base', 'headband');
|
||||
noneOption.none = true;
|
||||
const options = [
|
||||
noneOption,
|
||||
];
|
||||
|
||||
for (const key of keys) {
|
||||
const option = this.createGearItem(key, 'headAccessory', 'special', 'headband');
|
||||
|
||||
options.push(option);
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
chairs () {
|
||||
@@ -234,7 +239,14 @@ export default {
|
||||
// user purchases object, this is not recomputed. Hack for now
|
||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||
const keys = this.animalItemKeys[category];
|
||||
const options = keys.map(key => {
|
||||
|
||||
const noneOption = this.createGearItem(0, category, 'base', category);
|
||||
noneOption.none = true;
|
||||
const options = [
|
||||
noneOption,
|
||||
];
|
||||
|
||||
for (const key of keys) {
|
||||
const newKey = `${category}_special_${key}`;
|
||||
const userPurchased = this.user.items.gear.owned[newKey];
|
||||
|
||||
@@ -265,8 +277,10 @@ export default {
|
||||
const type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
return this.equip(newKey, type);
|
||||
};
|
||||
return option;
|
||||
});
|
||||
|
||||
options.push(option);
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
animalItemsUnlockString (category) {
|
||||
@@ -285,6 +299,44 @@ export default {
|
||||
});
|
||||
return own;
|
||||
},
|
||||
createGearItem (key, gearType, subGearType, additionalClass) {
|
||||
const newKey = `${gearType}_${subGearType ? `${subGearType}_` : ''}${key}`;
|
||||
const option = {};
|
||||
option.key = key;
|
||||
const visibleGearType = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
const currentlyEquippedValue = this.user.items.gear[visibleGearType][gearType];
|
||||
|
||||
option.active = currentlyEquippedValue === newKey;
|
||||
|
||||
if (key === 0) {
|
||||
// if key is the "none" option check if a property
|
||||
// doesn't have a value and mark it as active
|
||||
option.active = option.active || !currentlyEquippedValue;
|
||||
}
|
||||
|
||||
option.class = `${newKey} ${additionalClass}`;
|
||||
option.click = () => {
|
||||
const type = this.user.preferences.costume ? 'costume' : 'equipped';
|
||||
const currentlyEquipped = this.user.items.gear[type][gearType];
|
||||
|
||||
// no need to call api/equip-op if its already selected
|
||||
if (currentlyEquipped === newKey || (key === 0 && !currentlyEquipped)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let keyToEquip = newKey;
|
||||
|
||||
if (option.none) {
|
||||
// you need to "equip" the current selected AGAIN in order to un-equip it
|
||||
// the "none-key" isn't allowed to be sent
|
||||
keyToEquip = currentlyEquipped;
|
||||
}
|
||||
|
||||
this.equip(keyToEquip, type);
|
||||
};
|
||||
|
||||
return option;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<challenge-modal @updatedChallenge="updatedChallenge" />
|
||||
<leave-challenge-modal :challenge-id="challenge._id" />
|
||||
<leave-challenge-modal :challenge-id="challenge._id" @update-challenge="updateChallenge" />
|
||||
<close-challenge-modal
|
||||
:members="members"
|
||||
:challenge-id="challenge._id"
|
||||
@@ -123,7 +123,7 @@
|
||||
class="col-12 col-sm-6"
|
||||
:type="column"
|
||||
:task-list-override="tasksByType[column]"
|
||||
:show-options="showOptions"
|
||||
:challenge="challenge"
|
||||
@editTask="editTask"
|
||||
@taskDestroyed="taskDestroyed"
|
||||
/>
|
||||
@@ -386,9 +386,6 @@ export default {
|
||||
canJoin () {
|
||||
return !this.isMember;
|
||||
},
|
||||
showOptions () {
|
||||
return this.isLeader;
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
if (!this.searchId) this.searchId = this.challengeId;
|
||||
@@ -417,7 +414,12 @@ export default {
|
||||
return cleansedTask;
|
||||
},
|
||||
async loadChallenge () {
|
||||
this.challenge = await this.$store.dispatch('challenges:getChallenge', { challengeId: this.searchId });
|
||||
try {
|
||||
this.challenge = await this.$store.dispatch('challenges:getChallenge', { challengeId: this.searchId });
|
||||
} catch (e) {
|
||||
this.$router.push('/challenges/findChallenges');
|
||||
return;
|
||||
}
|
||||
this.members = await this
|
||||
.loadMembers({ challengeId: this.searchId, includeAllPublicFields: true });
|
||||
const tasks = await this.$store.dispatch('tasks:getChallengeTasks', { challengeId: this.searchId });
|
||||
@@ -491,12 +493,20 @@ export default {
|
||||
},
|
||||
async joinChallenge () {
|
||||
this.user.challenges.push(this.searchId);
|
||||
await this.$store.dispatch('challenges:joinChallenge', { challengeId: this.searchId });
|
||||
this.challenge = await this.$store.dispatch('challenges:joinChallenge', { challengeId: this.searchId });
|
||||
this.members = await this
|
||||
.loadMembers({ challengeId: this.searchId, includeAllPublicFields: true });
|
||||
|
||||
await this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true });
|
||||
},
|
||||
async leaveChallenge () {
|
||||
this.$root.$emit('bv::show::modal', 'leave-challenge-modal');
|
||||
},
|
||||
async updateChallenge () {
|
||||
this.challenge = await this.$store.dispatch('challenges:getChallenge', { challengeId: this.searchId });
|
||||
this.members = await this
|
||||
.loadMembers({ challengeId: this.searchId, includeAllPublicFields: true });
|
||||
},
|
||||
closeChallenge () {
|
||||
this.$root.$emit('bv::show::modal', 'close-challenge-modal');
|
||||
},
|
||||
|
||||
@@ -54,6 +54,7 @@ export default {
|
||||
this.close();
|
||||
},
|
||||
close () {
|
||||
this.$emit('update-challenge');
|
||||
this.$root.$emit('bv::hide::modal', 'leave-challenge-modal');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
class="col-12 col-md-3"
|
||||
:type="column"
|
||||
:task-list-override="tasksByType[column]"
|
||||
:show-options="showOptions"
|
||||
:group="group"
|
||||
:search-text="searchText"
|
||||
@editTask="editTask"
|
||||
@@ -199,9 +198,6 @@ export default {
|
||||
return (this.group.leader && this.group.leader._id === this.user._id)
|
||||
|| (this.group.managers && Boolean(this.group.managers[this.user._id]));
|
||||
},
|
||||
showOptions () {
|
||||
return this.canCreateTasks;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// call again the method if the route changes (when this route is already active)
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="px-3 py-3">
|
||||
<quest-sidebar-section
|
||||
v-if="isParty"
|
||||
:group="group"
|
||||
@@ -255,11 +255,10 @@
|
||||
.sidebar {
|
||||
background-color: $gray-600;
|
||||
padding-bottom: 2em;
|
||||
|
||||
}
|
||||
|
||||
.buttons-wrapper {
|
||||
padding-top: 2.8em;
|
||||
padding: 2.8em 24px 0em 24px;
|
||||
}
|
||||
|
||||
.card {
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
-info-button(@click="showWorldBossInfo()") {{$t('whatIsWorldBoss') }}
|
||||
-->
|
||||
</div>
|
||||
<div class="sleep below-header-sections">
|
||||
<div class="sleep px-4 py-3">
|
||||
<strong v-once>{{ $t('sleepDescription') }}</strong>
|
||||
<ul>
|
||||
<li v-once>
|
||||
@@ -263,7 +263,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-3">
|
||||
<div class="px-4">
|
||||
<sidebar-section :title="$t('staffAndModerators')">
|
||||
<div class="row">
|
||||
<div
|
||||
@@ -511,10 +511,6 @@
|
||||
.sidebar {
|
||||
background-color: $gray-600;
|
||||
padding: 0em;
|
||||
|
||||
.below-header-sections {
|
||||
padding: 1em 1.75em 1em 1.75em;
|
||||
}
|
||||
}
|
||||
|
||||
.pause-button {
|
||||
|
||||
@@ -169,7 +169,7 @@ export default {
|
||||
openStatus: undefined,
|
||||
actionableNotifications: [
|
||||
'GUILD_INVITATION', 'PARTY_INVITATION', 'CHALLENGE_INVITATION',
|
||||
'QUEST_INVITATION', 'GROUP_TASK_NEEDS_WORK', 'GROUP_TASK_APPROVAL',
|
||||
'QUEST_INVITATION', 'GROUP_TASK_NEEDS_WORK',
|
||||
],
|
||||
// A list of notifications handled by this component,
|
||||
// listed in the order they should appear in the notifications panel.
|
||||
|
||||
@@ -70,7 +70,8 @@
|
||||
}
|
||||
|
||||
.text {
|
||||
height: 60px;
|
||||
height: auto;
|
||||
min-height: 60px;
|
||||
font-size: 14px;
|
||||
line-height: 1.43;
|
||||
text-align: center;
|
||||
|
||||
@@ -235,6 +235,16 @@ const NOTIFICATIONS = {
|
||||
label: $t => `${$t('achievement')}: ${$t('achievementUndeadUndertaker')}`,
|
||||
modalId: 'generic-achievement',
|
||||
},
|
||||
ACHIEVEMENT_PRIMED_FOR_PAINTING: {
|
||||
achievement: true,
|
||||
label: $t => `${$t('achievement')}: ${$t('achievementPrimedForPainting')}`,
|
||||
modalId: 'generic-achievement',
|
||||
},
|
||||
ACHIEVEMENT_PEARLY_PRO: {
|
||||
achievement: true,
|
||||
label: $t => `${$t('achievement')}: ${$t('achievementPearlyPro')}`,
|
||||
modalId: 'generic-achievement',
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
@@ -291,7 +301,8 @@ export default {
|
||||
'CRON', 'SCORED_TASK', 'LOGIN_INCENTIVE', 'ACHIEVEMENT_ALL_YOUR_BASE', 'ACHIEVEMENT_BACK_TO_BASICS',
|
||||
'GENERIC_ACHIEVEMENT', 'ACHIEVEMENT_PARTY_UP', 'ACHIEVEMENT_PARTY_ON', 'ACHIEVEMENT_BEAST_MASTER',
|
||||
'ACHIEVEMENT_MOUNT_MASTER', 'ACHIEVEMENT_TRIAD_BINGO', 'ACHIEVEMENT_DUST_DEVIL', 'ACHIEVEMENT_ARID_AUTHORITY',
|
||||
'ACHIEVEMENT_MONSTER_MAGUS', 'ACHIEVEMENT_UNDEAD_UNDERTAKER', 'GENERIC_ACHIEVEMENT',
|
||||
'ACHIEVEMENT_MONSTER_MAGUS', 'ACHIEVEMENT_UNDEAD_UNDERTAKER', 'ACHIEVEMENT_PRIMED_FOR_PAINTING',
|
||||
'ACHIEVEMENT_PEARLY_PRO', 'GENERIC_ACHIEVEMENT',
|
||||
].forEach(type => {
|
||||
handledNotifications[type] = true;
|
||||
});
|
||||
@@ -697,6 +708,8 @@ export default {
|
||||
case 'ACHIEVEMENT_TRIAD_BINGO':
|
||||
case 'ACHIEVEMENT_MONSTER_MAGUS':
|
||||
case 'ACHIEVEMENT_UNDEAD_UNDERTAKER':
|
||||
case 'ACHIEVEMENT_PRIMED_FOR_PAINTING':
|
||||
case 'ACHIEVEMENT_PEARLY_PRO':
|
||||
case 'GENERIC_ACHIEVEMENT':
|
||||
this.showNotificationWithModal(notification);
|
||||
break;
|
||||
|
||||
@@ -32,14 +32,8 @@
|
||||
<br>
|
||||
{{ $t('beeminderDesc') }}
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://chrome.google.com/webstore/detail/habitrpg-chat-client/hidkdfgonpoaiannijofifhjidbnilbb"
|
||||
>{{ $t('chromeChatExtension') }}</a>
|
||||
<br>
|
||||
{{ $t('chromeChatExtensionDesc') }}
|
||||
</li>
|
||||
<li v-html="$t('chatExtension')"></li>
|
||||
<span>{{ $t('chatExtensionDesc') }}</span>
|
||||
<li>
|
||||
<a
|
||||
target="_blank"
|
||||
@@ -48,10 +42,8 @@
|
||||
<br>
|
||||
{{ $t('dataToolDesc') }}
|
||||
</li>
|
||||
<li v-html="$t('otherExtensions')">
|
||||
<br>
|
||||
{{ $t('otherDesc') }}
|
||||
</li>
|
||||
<li v-html="$t('otherExtensions')"></li>
|
||||
<span>{{ $t('otherDesc') }}</span>
|
||||
</ul>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
:key="task.id"
|
||||
:task="task"
|
||||
:is-user="isUser"
|
||||
:show-options="showOptions"
|
||||
:group="group"
|
||||
:challenge="challenge"
|
||||
@editTask="editTask"
|
||||
@moveTo="moveTo"
|
||||
@taskDestroyed="taskDestroyed"
|
||||
@@ -372,10 +372,7 @@ export default {
|
||||
selectedTags: {},
|
||||
taskListOverride: {},
|
||||
group: {},
|
||||
showOptions: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
challenge: {},
|
||||
}, // @TODO: maybe we should store the group on state?
|
||||
data () {
|
||||
const icons = Object.freeze({
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
</div>
|
||||
<div slot="dropdown-content">
|
||||
<div
|
||||
v-if="showEdit"
|
||||
ref="editTaskItem"
|
||||
class="dropdown-item edit-task-item"
|
||||
>
|
||||
@@ -137,7 +138,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="canDelete(task)"
|
||||
v-if="showDelete"
|
||||
class="dropdown-item"
|
||||
@click="destroy"
|
||||
>
|
||||
@@ -371,7 +372,7 @@
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 1px 8px 0 rgba($black, 0.12), 0 4px 4px 0 rgba($black, 0.16);
|
||||
z-index: 10;
|
||||
z-index: 11;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,6 +790,7 @@ import moment from 'moment';
|
||||
import axios from 'axios';
|
||||
import Vue from 'vue';
|
||||
import uuid from 'uuid';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { mapState, mapGetters, mapActions } from '@/libs/store';
|
||||
import scoreTask from '@/../../common/script/ops/scoreTask';
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
@@ -825,7 +827,7 @@ export default {
|
||||
markdown: markdownDirective,
|
||||
},
|
||||
mixins: [notifications],
|
||||
props: ['task', 'isUser', 'group', 'dueDate', 'showOptions'], // @TODO: maybe we should store the group on state?
|
||||
props: ['task', 'isUser', 'group', 'challenge', 'dueDate'], // @TODO: maybe we should store the group on state?
|
||||
data () {
|
||||
return {
|
||||
random: uuid.v4(), // used to avoid conflicts between checkboxes ids
|
||||
@@ -859,6 +861,7 @@ export default {
|
||||
getTagsFor: 'tasks:getTagsFor',
|
||||
getTaskClasses: 'tasks:getTaskClasses',
|
||||
canDelete: 'tasks:canDelete',
|
||||
canEdit: 'tasks:canEdit',
|
||||
}),
|
||||
hasChecklist () {
|
||||
return this.task.checklist && this.task.checklist.length > 0;
|
||||
@@ -937,6 +940,27 @@ export default {
|
||||
|
||||
return this.task.challenge.shortName ? this.task.challenge.shortName.toString() : '';
|
||||
},
|
||||
isChallangeTask () {
|
||||
return !isEmpty(this.task.challenge);
|
||||
},
|
||||
isGroupTask () {
|
||||
return this.task.group.taskId || this.task.group.id;
|
||||
},
|
||||
taskCategory () {
|
||||
let taskCategory = 'default';
|
||||
if (this.isGroupTask) taskCategory = 'group';
|
||||
else if (this.isChallangeTask) taskCategory = 'challenge';
|
||||
return taskCategory;
|
||||
},
|
||||
showDelete () {
|
||||
return this.canDelete(this.task, this.taskCategory, this.isUser, this.group, this.challenge);
|
||||
},
|
||||
showEdit () {
|
||||
return this.canEdit(this.task, this.taskCategory, this.isUser, this.group, this.challenge);
|
||||
},
|
||||
showOptions () {
|
||||
return this.showEdit || this.showDelete || this.isUser;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
@@ -950,7 +974,7 @@ export default {
|
||||
this.scoreChecklistItem({ taskId: this.task._id, itemId: item.id });
|
||||
},
|
||||
edit (e, task) {
|
||||
if (this.isRunningYesterdailies) return;
|
||||
if (this.isRunningYesterdailies || !this.showEdit) return;
|
||||
|
||||
// Prevent clicking on a link from opening the edit modal
|
||||
const target = e.target || e.srcElement;
|
||||
|
||||
@@ -1437,6 +1437,10 @@ export default {
|
||||
this.task.group.sharedCompletion = this.sharedCompletion;
|
||||
}
|
||||
|
||||
if (this.task.type === 'reward' && this.task.value === '') {
|
||||
this.task.value = 0;
|
||||
}
|
||||
|
||||
if (this.purpose === 'create') {
|
||||
if (this.challengeId) {
|
||||
const response = await this.$store.dispatch('tasks:createChallengeTasks', {
|
||||
|
||||
@@ -246,6 +246,8 @@
|
||||
@import '~@/assets/scss/create-task.scss';
|
||||
|
||||
.user-tasks-page {
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,75 @@ function getTaskColor (task) {
|
||||
return 'best';
|
||||
}
|
||||
|
||||
export function canDelete () {
|
||||
return task => {
|
||||
const isUserChallenge = Boolean(task.userId);
|
||||
const activeChallenge = isUserChallenge
|
||||
&& task.challenge && task.challenge.id && !task.challenge.broken;
|
||||
return !activeChallenge;
|
||||
export function canDelete (store) {
|
||||
return (task, taskCategory, onUserDashboard, group, challenge) => {
|
||||
const user = store.state.user.data;
|
||||
const userId = user.id || user._id;
|
||||
|
||||
const isUserAdmin = user.contributor && !!user.contributor.admin;
|
||||
const isUserGroupLeader = group && (group.leader
|
||||
&& group.leader._id === userId);
|
||||
const isUserGroupManager = group && (group.managers
|
||||
&& Boolean(group.managers[userId]));
|
||||
const isUserChallenge = userId === (challenge && challenge.leader.id);
|
||||
|
||||
let isUserCanDeleteTask = onUserDashboard;
|
||||
|
||||
switch (taskCategory) {
|
||||
case 'challenge':
|
||||
if (!onUserDashboard) {
|
||||
isUserCanDeleteTask = isUserChallenge || isUserAdmin;
|
||||
} else {
|
||||
isUserCanDeleteTask = isUserAdmin;
|
||||
}
|
||||
break;
|
||||
case 'group':
|
||||
if (!onUserDashboard) {
|
||||
isUserCanDeleteTask = isUserGroupLeader || isUserGroupManager || isUserAdmin;
|
||||
} else {
|
||||
isUserCanDeleteTask = isUserAdmin;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Boolean(isUserCanDeleteTask);
|
||||
};
|
||||
}
|
||||
|
||||
export function canEdit (store) {
|
||||
return (task, taskCategory, onUserDashboard, group, challenge) => {
|
||||
let isUserCanEditTask = onUserDashboard;
|
||||
const user = store.state.user.data;
|
||||
const userId = user.id || user._id;
|
||||
|
||||
const isUserAdmin = user.contributor && !!user.contributor.admin;
|
||||
const isUserGroupLeader = group && (group.leader
|
||||
&& group.leader._id === userId);
|
||||
const isUserGroupManager = group && (group.managers
|
||||
&& Boolean(group.managers[userId]));
|
||||
const isUserChallenge = userId === (challenge && challenge.leader.id);
|
||||
|
||||
|
||||
switch (taskCategory) {
|
||||
case 'challenge':
|
||||
if (!onUserDashboard) {
|
||||
isUserCanEditTask = isUserChallenge || isUserAdmin;
|
||||
} else {
|
||||
isUserCanEditTask = true;
|
||||
}
|
||||
break;
|
||||
case 'group':
|
||||
if (!onUserDashboard) {
|
||||
isUserCanEditTask = isUserGroupLeader || isUserGroupManager || isUserAdmin;
|
||||
} else {
|
||||
isUserCanEditTask = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Boolean(isUserCanEditTask);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,73 @@
|
||||
import generateStore from '@/store';
|
||||
|
||||
|
||||
describe('canDelete getter', () => {
|
||||
it('cannot delete active challenge task', () => {
|
||||
const store = generateStore();
|
||||
let store;
|
||||
let group;
|
||||
let challenge;
|
||||
let task;
|
||||
|
||||
beforeEach(() => {
|
||||
store = generateStore();
|
||||
|
||||
const task = { userId: 1, challenge: { id: 2 } };
|
||||
expect(store.getters['tasks:canDelete'](task)).to.equal(false);
|
||||
store.state.user.data = {
|
||||
id: 10,
|
||||
contributor: {
|
||||
admin: false,
|
||||
},
|
||||
};
|
||||
|
||||
group = {
|
||||
leader: {
|
||||
_id: 123,
|
||||
},
|
||||
managers: {
|
||||
123984: {},
|
||||
},
|
||||
};
|
||||
|
||||
challenge = {
|
||||
leader: {
|
||||
id: 123,
|
||||
},
|
||||
};
|
||||
|
||||
task = { userId: 1, challenge: { id: 2 } };
|
||||
});
|
||||
it('cannot Delete challenge or group task in own dashboard', () => {
|
||||
expect(store.getters['tasks:canDelete'](task, 'challenge', true, null, challenge)).to.equal(false);
|
||||
expect(store.getters['tasks:canDelete'](task, 'group', true, group, null)).to.equal(false);
|
||||
});
|
||||
|
||||
it('can delete broken challenge task', () => {
|
||||
const store = generateStore();
|
||||
it('can Delete any challenge task as admin', () => {
|
||||
store.state.user.data.contributor.admin = true;
|
||||
|
||||
expect(store.getters['tasks:canDelete'](task, 'challenge', true, null, challenge)).to.equal(true);
|
||||
});
|
||||
|
||||
const task = { userId: 1, challenge: { id: 2, broken: true } };
|
||||
expect(store.getters['tasks:canDelete'](task)).to.equal(true);
|
||||
it('can Delete own challenge task if leader', () => {
|
||||
store.state.user.data.id = 123;
|
||||
|
||||
expect(store.getters['tasks:canDelete'](task, 'challenge', false, null, challenge)).to.equal(true);
|
||||
});
|
||||
|
||||
it('cannot Delete challenge task if non leader on challenge page', () => {
|
||||
expect(store.getters['tasks:canDelete'](task, 'challenge', false, null, challenge)).to.equal(false);
|
||||
});
|
||||
|
||||
it('can Delete group task as leader on group page', () => {
|
||||
store.state.user.data.id = 123;
|
||||
|
||||
expect(store.getters['tasks:canDelete'](task, 'group', false, group)).to.equal(true);
|
||||
});
|
||||
|
||||
it('can Delete group task if manager on group page', () => {
|
||||
store.state.user.data.id = 123984;
|
||||
|
||||
expect(store.getters['tasks:canDelete'](task, 'group', false, group)).to.equal(true);
|
||||
});
|
||||
|
||||
it('cannot Delete group task if not a leader on group page', () => {
|
||||
expect(store.getters['tasks:canDelete'](task, 'group', false, group)).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import generateStore from '@/store';
|
||||
|
||||
|
||||
describe('canEdit getter', () => {
|
||||
let store;
|
||||
let group;
|
||||
let challenge;
|
||||
let task;
|
||||
|
||||
beforeEach(() => {
|
||||
store = generateStore();
|
||||
|
||||
store.state.user.data = {
|
||||
id: 10,
|
||||
contributor: {
|
||||
admin: false,
|
||||
},
|
||||
};
|
||||
|
||||
group = {
|
||||
leader: {
|
||||
_id: 123,
|
||||
},
|
||||
managers: {
|
||||
123984: {},
|
||||
},
|
||||
};
|
||||
|
||||
challenge = {
|
||||
leader: {
|
||||
id: 123,
|
||||
},
|
||||
};
|
||||
|
||||
task = { userId: 1, challenge: { id: 2 } };
|
||||
});
|
||||
it('can Edit task in own dashboard', () => {
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', true, null, challenge)).to.equal(true);
|
||||
expect(store.getters['tasks:canEdit'](task, 'group', true, group, null)).to.equal(true);
|
||||
});
|
||||
|
||||
it('can Edit any challenge task if admin', () => {
|
||||
store.state.user.data.contributor.admin = true;
|
||||
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', true, null, challenge)).to.equal(true);
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', false, null, challenge)).to.equal(true);
|
||||
});
|
||||
|
||||
it('can Edit own challenge task if leader', () => {
|
||||
store.state.user.data.id = 123;
|
||||
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', true, null, challenge)).to.equal(true);
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', false, null, challenge)).to.equal(true);
|
||||
});
|
||||
|
||||
it('cannot Edit challenge task if not leader on challenge page', () => {
|
||||
expect(store.getters['tasks:canEdit'](task, 'challenge', false, null, challenge)).to.equal(false);
|
||||
});
|
||||
|
||||
it('can Edit group task as leader on group page', () => {
|
||||
store.state.user.data.id = 123;
|
||||
|
||||
expect(store.getters['tasks:canEdit'](task, 'group', false, group)).to.equal(true);
|
||||
});
|
||||
|
||||
it('can Edit group task if manager on group page', () => {
|
||||
store.state.user.data.id = 123984;
|
||||
|
||||
expect(store.getters['tasks:canEdit'](task, 'group', false, group)).to.equal(true);
|
||||
});
|
||||
|
||||
it('cannot Edit group task if not leader on group page', () => {
|
||||
expect(store.getters['tasks:canEdit'](task, 'group', false, group)).to.equal(false);
|
||||
});
|
||||
});
|
||||
@@ -3,8 +3,8 @@
|
||||
"challengeDetails": "Challenges are community events in which players compete and earn prizes by completing a group of related tasks.",
|
||||
"brokenChaLink": "Broken Challenge Link",
|
||||
"brokenTask": "Broken Challenge Link: this task was part of a challenge, but has been removed from it. What would you like to do?",
|
||||
"keepIt": "Keep It",
|
||||
"removeIt": "Remove It",
|
||||
"keepIt": "এটি রাখুন",
|
||||
"removeIt": "এটি মুছে ফেলুন",
|
||||
"brokenChallenge": "Broken Challenge Link: this task was part of a challenge, but the challenge (or group) has been deleted. What to do with the orphan tasks?",
|
||||
"keepThem": "Keep Tasks",
|
||||
"removeThem": "Remove Tasks",
|
||||
@@ -136,4 +136,4 @@
|
||||
"selectMember": "Select Member",
|
||||
"confirmKeepChallengeTasks": "Do you want to keep challenge tasks?",
|
||||
"selectParticipant": "Select a Participant"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"frequentlyAskedQuestions": "Frequently Asked Questions",
|
||||
"frequentlyAskedQuestions": "বারবার জিজ্ঞাসিত প্রশ্ন",
|
||||
"faqQuestion0": "I'm confused. Where do I get an overview?",
|
||||
"iosFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn experience and gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as Pets, Skills, and Quests! You can customize your character under Menu > Customize Avatar.\n\n Some basic ways to interact: click the (+) in the upper-right-hand corner to add a new task. Tap on an existing task to edit it, and swipe left on a task to delete it. You can sort tasks using Tags in the upper-left-hand corner, and expand and contract checklists by clicking on the checklist bubble.",
|
||||
"androidFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn experience and gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as Pets, Skills, and Quests! You can customize your character under Menu > [Inventory >] Avatar.\n\n Some basic ways to interact: click the (+) in the lower-right-hand corner to add a new task. Tap on an existing task to edit it, and swipe left on a task to delete it. You can sort tasks using Tags in the upper-right-hand corner, and expand and contract checklists by clicking on the checklist count box.",
|
||||
@@ -8,11 +8,11 @@
|
||||
"iosFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
|
||||
"androidFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your character will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
|
||||
"webFaqAnswer1": "* Good Habits (the ones with a :heavy_plus_sign:) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a :heavy_minus_sign:) are tasks that you should avoid, like biting nails. Habits with a :heavy_plus_sign: and a :heavy_minus_sign: have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award Experience and Gold. Bad Habits subtract Health.\n* Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by clicking the pencil item to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n* To-Dos are your To-Do list. Completing a To-Do earns you Gold and Experience. You never lose Health from To-Dos. You can add a due date to a To-Do by clicking the pencil icon to edit.",
|
||||
"faqQuestion2": "What are some sample tasks?",
|
||||
"faqQuestion2": "করণীয় কাজের কিছু নমুনা কী হতে পারে?",
|
||||
"iosFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n<br><br>\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
|
||||
"androidFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n<br><br>\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
|
||||
"webFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
|
||||
"faqQuestion3": "Why do my tasks change color?",
|
||||
"faqQuestion3": "আমার করণীয় কাজগুলো রঙ পরিবর্তন করছে কেন?",
|
||||
"iosFaqAnswer3": "Your tasks change color based on how well you are currently accomplishing them! Each new task starts out as a neutral yellow. Perform Dailies or positive Habits more frequently and they move toward blue. Miss a Daily or give in to a bad Habit and the task moves toward red. The redder a task, the more rewards it will give you, but if it's a Daily or bad Habit, the more it will hurt you! This helps motivate you to complete the tasks that are giving you trouble.",
|
||||
"androidFaqAnswer3": "Your tasks change color based on how well you are currently accomplishing them! Each new task starts out as a neutral yellow. Perform Dailies or positive Habits more frequently and they move toward blue. Miss a Daily or give in to a bad Habit and the task moves toward red. The redder a task, the more rewards it will give you, but if it's a Daily or bad Habit, the more it will hurt you! This helps motivate you to complete the tasks that are giving you trouble.",
|
||||
"webFaqAnswer3": "Your tasks change color based on how well you are currently accomplishing them! Each new task starts out as a neutral yellow. Perform Dailies or positive Habits more frequently and they move toward blue. Miss a Daily or give in to a bad Habit and the task moves toward red. The redder a task, the more rewards it will give you, but if it’s a Daily or bad Habit, the more it will hurt you! This helps motivate you to complete the tasks that are giving you trouble.",
|
||||
@@ -55,4 +55,4 @@
|
||||
"iosFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
|
||||
"androidFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
|
||||
"webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the [Habitica Help guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! We're happy to help."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
{
|
||||
"languageName": "English",
|
||||
"languageName": "ইংরেজি",
|
||||
"stringNotFound": "String '<%= string %>' not found.",
|
||||
"titleIndex": "Habitica | Your Life The Role Playing Game",
|
||||
"habitica": "Habitica",
|
||||
"habiticaLink": "<a href='http://habitica.wikia.com/wiki/Habitica' target='_blank'>Habitica</a>",
|
||||
"onward": "Onward!",
|
||||
"done": "Done",
|
||||
"gotIt": "Got it!",
|
||||
"gotIt": "বুঝতে পেরেছি!",
|
||||
"titleTasks": "Tasks",
|
||||
"titleAvatar": "Avatar",
|
||||
"titleBackgrounds": "Backgrounds",
|
||||
"titleStats": "Stats",
|
||||
"titleAchievs": "Achievements",
|
||||
"titleAchievs": "অর্জন",
|
||||
"titleProfile": "Profile",
|
||||
"titleInbox": "Inbox",
|
||||
"titleTavern": "Tavern",
|
||||
"titleTavern": "সরাইখানা",
|
||||
"titleParty": "Party",
|
||||
"titleHeroes": "Hall of Heroes",
|
||||
"titlePatrons": "Hall of Patrons",
|
||||
"titleGuilds": "Guilds",
|
||||
"titleChallenges": "Challenges",
|
||||
"titleDrops": "Market",
|
||||
"titleDrops": "বাজার",
|
||||
"titleQuests": "Quests",
|
||||
"titlePets": "Pets",
|
||||
"titlePets": "পোষা প্রাণী",
|
||||
"titleMounts": "Mounts",
|
||||
"titleEquipment": "Equipment",
|
||||
"titleTimeTravelers": "Time Travelers",
|
||||
"titleSeasonalShop": "Seasonal Shop",
|
||||
"titleSettings": "Settings",
|
||||
"saveEdits": "Save Edits",
|
||||
"showMore": "Show More",
|
||||
"showLess": "Show Less",
|
||||
"showMore": "আরো দেখান",
|
||||
"showLess": "কম দেখান",
|
||||
"expandToolbar": "Expand Toolbar",
|
||||
"collapseToolbar": "Collapse Toolbar",
|
||||
"markdownHelpLink": "Markdown formatting help",
|
||||
"showFormattingHelp": "Show formatting help",
|
||||
"hideFormattingHelp": "Hide formatting help",
|
||||
"youType": "You type:",
|
||||
"youSee": "You see:",
|
||||
"italics": "*Italics*",
|
||||
"bold": "**Bold**",
|
||||
"youType": "আপনি লিখুন:",
|
||||
"youSee": "আপনি দেখুন:",
|
||||
"italics": "*ইটালিক*",
|
||||
"bold": "**গাঢ়**",
|
||||
"strikethrough": "~~Strikethrough~~",
|
||||
"emojiExample": ":smile:",
|
||||
"markdownLinkEx": "[Habitica is great!](https://habitica.com)",
|
||||
@@ -290,5 +290,9 @@
|
||||
"selected": "Selected",
|
||||
"howManyToBuy": "How many would you like to buy?",
|
||||
"habiticaHasUpdated": "There is a new Habitica update. Refresh to get the latest version!",
|
||||
"contactForm": "Contact the Moderation Team"
|
||||
}
|
||||
"contactForm": "Contact the Moderation Team",
|
||||
"loadEarlierMessages": "আগের বার্তাগুলো লোড করুন",
|
||||
"demo": "ডেমো",
|
||||
"options": "Options",
|
||||
"finish": "সমাপ্ত"
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"dateEndAugust": "August 31",
|
||||
"dateEndSeptember": "September 21",
|
||||
"dateEndOctober": "October 31",
|
||||
"dateEndNovember": "December 3",
|
||||
"dateEndNovember": "৩০ নভেম্বর",
|
||||
"dateEndJanuary": "January 31",
|
||||
"dateEndFebruary": "February 28",
|
||||
"winterPromoGiftHeader": "GIFT A SUBSCRIPTION AND GET ONE FREE!",
|
||||
@@ -151,5 +151,8 @@
|
||||
"winterPromoGiftDetails2": "Please note that if you or your gift recipient already have a recurring subscription, the gifted subscription will only start after that subscription is cancelled or has expired. Thanks so much for your support! <3",
|
||||
"discountBundle": "bundle",
|
||||
"g1g1Announcement": "Gift a Subscription, Get a Subscription Free event going on now!",
|
||||
"g1g1Details": "Gift a sub to a friend from their profile and you’ll receive the same sub for free!"
|
||||
}
|
||||
"g1g1Details": "Gift a sub to a friend from their profile and you’ll receive the same sub for free!",
|
||||
"spring2019RobinHealerSet": "রবিন (চিকিৎসক)",
|
||||
"spring2019AmberMageSet": "অ্যাম্বার (জাদুকর)",
|
||||
"spring2019OrchidWarriorSet": "অর্কিড (যোদ্ধা)"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"clearCompleted": "Delete Completed",
|
||||
"clearCompleted": "বাদ দেওয়া সম্পূর্ণ",
|
||||
"clearCompletedDescription": "Completed To-Dos are deleted after 30 days for non-subscribers and 90 days for subscribers.",
|
||||
"clearCompletedConfirm": "Are you sure you want to delete your completed To-Dos?",
|
||||
"sureDeleteCompletedTodos": "Are you sure you want to delete your completed To-Dos?",
|
||||
@@ -210,4 +210,4 @@
|
||||
"searchTasks": "Search titles and descriptions...",
|
||||
"sessionOutdated": "Your session is outdated. Please refresh or sync.",
|
||||
"errorTemporaryItem": "This item is temporary and cannot be pinned."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,6 @@
|
||||
"changeClass": "Change Class, Refund Stat Points",
|
||||
"lvl10ChangeClass": "To change class you must be at least level 10.",
|
||||
"changeClassConfirmCost": "Are you sure you want to change your class for 3 Gems?",
|
||||
"invalidClass": "Invalid class. Please specify 'warrior', 'rogue', 'wizard', or 'healer'.",
|
||||
"levelPopover": "Each level earns you one Point to assign to a Stat of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options.",
|
||||
"unallocated": "Unallocated Stat Points",
|
||||
"haveUnallocated": "You have <%= points %> unallocated Stat Point(s)",
|
||||
@@ -225,4 +224,4 @@
|
||||
"offHand": "Off-Hand",
|
||||
"statPoints": "Stat Points",
|
||||
"pts": "pts"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
"allocatePerPop": "Přidat bod k vnímání",
|
||||
"allocateInt": "Body přiřazené k Inteligenci:",
|
||||
"allocateIntPop": "Přidat bod k inteligenci",
|
||||
"noMoreAllocate": "Nyní, když jsi dosáhl úrovně 100, už nebudeš dostávat žádné body atributů. Můžeš pokračovat v dosahování dalších úrovní, nebo můžeš začít nové dobrodružství na úrovni 1, když použiješ <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb Znovuzrození</a>, který nyní najdeš zdarma na Trhu.",
|
||||
"noMoreAllocate": "Nyní, když jsi dosáhl úrovně 100, už nebudeš dostávat žádné body atributů. Můžeš pokračovat v dosahování dalších úrovní, nebo můžeš začít nové dobrodružství na úrovni 1, když použiješ <a href='http://habitica.fandom.com/wiki/Orb_of_Rebirth' target='_blank'>Orb Znovuzrození</a>!",
|
||||
"stats": "Statistiky",
|
||||
"achievs": "Úspěchy",
|
||||
"strength": "Síla",
|
||||
|
||||
@@ -350,5 +350,6 @@
|
||||
"questEggDolphinAdjective": "radostný",
|
||||
"questEggDolphinMountText": "Delfín",
|
||||
"questEggDolphinText": "Delfín",
|
||||
"hatchingPotionShadow": "Stín"
|
||||
"hatchingPotionShadow": "Stín",
|
||||
"premiumPotionUnlimitedNotes": "Nepoužitelné na vejce z výprav."
|
||||
}
|
||||
|
||||
@@ -1762,5 +1762,52 @@
|
||||
"weaponSpecialSpring2019WarriorNotes": "Špatné návyky se schovávají před tímto zeleným ostřím. Zvýší sílu o <%= str %>. Limitovaná edice Jarní výzbroj 2019.",
|
||||
"weaponSpecialSpring2019RogueNotes": "Tyto zbraně obsahují sílu nebe a deště. Doporučujeme, že je nebudeš používat ve vodě. Zvýší sílu o <%= str %>. Limitovaná edice Jarní výstroj 2019.",
|
||||
"weaponSpecialKS2019Notes": "Zakulacená jako zobák a drápy gryfona, ti tato zbraň připomene Tvou sílu, když se úkol před tebou zdá skličujicí. Zvýší tvou sílu o <%= str %>.",
|
||||
"weaponSpecialKS2019Text": "Mytická gryfonní halapartna"
|
||||
"weaponSpecialKS2019Text": "Mytická gryfonní halapartna",
|
||||
"eyewearSpecialYellowHalfMoonNotes": "Brýle s žlutým rámečkem a čočkami ve tvaru půlměsíce. Nepřináší žádnou výhodu.",
|
||||
"eyewearSpecialWhiteHalfMoonNotes": "Brýle s bílým rámečkem a čočkami ve tvaru půlměsíce. Nepřináší žádnou výhodu.",
|
||||
"eyewearSpecialRedHalfMoonNotes": "Brýle s červeným rámečkem a čočkami ve tvaru půlměsíce. Nepřináší žádnou výhodu.",
|
||||
"eyewearSpecialPinkHalfMoonNotes": "Brýle s růžovým rámečkem a čočkami ve tvaru půlměsíce. Nepřináší žádnou výhodu.",
|
||||
"eyewearSpecialGreenHalfMoonNotes": "Brýle se zeleným rámečkem a čočkami ve tvaru půlměsíce. Nepřináší žádnou výhodu.",
|
||||
"shieldArmoireAlchemistsScaleText": "Alchymistova stupnice",
|
||||
"shieldArmoirePolishedPocketwatchText": "Leštěné kapesní hodinky",
|
||||
"shieldArmoireTrustyUmbrellaText": "Spolehlivý deštník",
|
||||
"shieldArmoireMightyPizzaText": "Mocná pizza",
|
||||
"shieldSpecialSummer2019MageText": "Kapky čisté vody",
|
||||
"shieldSpecialSpring2019HealerText": "Štít z vaječné skořápky",
|
||||
"shieldSpecialPiDayText": "Pí štít",
|
||||
"headArmoireAlchemistsHatText": "Alchymistický klobouk",
|
||||
"headMystery201907Text": "Zpětná čepice",
|
||||
"headSpecialFall2019HealerText": "Tmavá mitra",
|
||||
"headSpecialFall2019RogueText": "Antický operní klobouk",
|
||||
"headSpecialSummer2019HealerText": "Škeblí koruna",
|
||||
"headSpecialSummer2019WarriorText": "Želví helma",
|
||||
"headSpecialSummer2019RogueText": "Kladivounova helma",
|
||||
"headSpecialPiDayText": "Pí klobouk",
|
||||
"armorArmoireNephriteArmorText": "Nefritová zbroj",
|
||||
"armorArmoireChefsJacketText": "Šéfkuchařská bunda",
|
||||
"armorMystery201908Notes": "Tyto nohy byly určeny pro tanec! A přesně to udělají. Nepřináší žádnou výhodu. Srpen 2019 Subscriber Item.",
|
||||
"armorMystery201907Notes": "Zůstaňte v pohodě a vypadejte skvěle i v nejteplejším letním dni. Nepřináší žádnou výhodu. Odběratelská položka z července 2019.",
|
||||
"armorMystery201907Text": "Květinová košile",
|
||||
"armorSpecialFall2019HealerText": "Róba temnoty",
|
||||
"armorSpecialFall2019WarriorText": "Křídla noci",
|
||||
"armorSpecialSummer2019HealerText": "Ocas tropických přílivů",
|
||||
"armorSpecialSummer2019MageText": "Květinové šátečky",
|
||||
"armorSpecialSummer2019WarriorText": "Krunýřové brnění",
|
||||
"armorSpecialSummer2019RogueText": "Ocas žraloka kladivouna",
|
||||
"armorSpecialKS2019Text": "Mýtické zbroje Gryfa",
|
||||
"weaponArmoireResplendentRapierText": "Úžasný rapír",
|
||||
"weaponArmoireFloridFanText": "Květinový vějíř",
|
||||
"weaponArmoireMagnifyingGlassText": "Zvětšovací sklo",
|
||||
"weaponArmoireAstronomersTelescopeText": "Astronomův dalekohled",
|
||||
"weaponArmoireBambooCaneText": "Bambusová třtina",
|
||||
"weaponArmoireNephriteBowText": "Nefritový luk",
|
||||
"weaponArmoireSlingshotText": "Prak",
|
||||
"weaponArmoireJugglingBallsText": "Žonglovácí míče",
|
||||
"weaponArmoireVernalTaperText": "Jarní svíce",
|
||||
"weaponArmoireChefsSpoonText": "Šéfkuchařská lžíce",
|
||||
"weaponSpecialFall2019HealerText": "Hrůzná fylakterie",
|
||||
"weaponSpecialFall2019MageText": "Jednooká hůl",
|
||||
"weaponSpecialFall2019WarriorText": "Pařátový trojzubec",
|
||||
"weaponSpecialFall2019RogueText": "Notový pult",
|
||||
"weaponSpecialSummer2019HealerText": "Bublinová hůlka"
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
"dateEndAugust": "Srpen 31",
|
||||
"dateEndSeptember": "21. Září",
|
||||
"dateEndOctober": "Říjen 31",
|
||||
"dateEndNovember": "December 3",
|
||||
"dateEndNovember": "30. listopadu",
|
||||
"dateEndJanuary": "Leden 31",
|
||||
"dateEndFebruary": "Únor 28",
|
||||
"winterPromoGiftHeader": "DARUJ PŘEDPLATNÉ A ZÍSKEJ JEDNO ZDARMA!",
|
||||
@@ -167,5 +167,6 @@
|
||||
"spring2019CloudRogueSet": "Mrak (Tulák)",
|
||||
"spring2019RobinHealerSet": "Červenka (Léčitel)",
|
||||
"spring2019AmberMageSet": "Jantar (Mág)",
|
||||
"spring2019OrchidWarriorSet": "Orchidej (válečník)"
|
||||
"spring2019OrchidWarriorSet": "Orchidej (válečník)",
|
||||
"augustYYYY": "Srpen <%=rok %>"
|
||||
}
|
||||
|
||||