mirror of
https://github.com/HabitRPG/habitica.git
synced 2026-05-12 11:39:44 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 08127cfa67 | |||
| ae9f10420f | |||
| 26bddb6383 | |||
| 9a157168a9 |
+1
-1
@@ -87,5 +87,5 @@
|
||||
"REDIS_HOST": "aaabbbcccdddeeefff",
|
||||
"REDIS_PORT": "1234",
|
||||
"REDIS_PASSWORD": "12345678",
|
||||
"TRUSTED_DOMAINS": "localhost,habitica.com"
|
||||
"TRUSTED_DOMAINS": "https://localhost,https://habitica.com"
|
||||
}
|
||||
|
||||
+1
-1
Submodule habitica-images updated: 109539e445...dac6a71d1f
@@ -1,158 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20230522_pet_group_achievements';
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {
|
||||
migration: MIGRATION_NAME,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.pets) {
|
||||
const pets = user.items.pets;
|
||||
if (pets['Parrot-Base']
|
||||
&& pets['Parrot-CottonCandyBlue']
|
||||
&& pets['Parrot-CottonCandyPink']
|
||||
&& pets['Parrot-Desert']
|
||||
&& pets['Parrot-Golden']
|
||||
&& pets['Parrot-Red']
|
||||
&& pets['Parrot-Shade']
|
||||
&& pets['Parrot-Skeleton']
|
||||
&& pets['Parrot-White']
|
||||
&& pets['Parrot-Zombie']
|
||||
&& pets['Rooster-Base']
|
||||
&& pets['Rooster-CottonCandyBlue']
|
||||
&& pets['Rooster-CottonCandyPink']
|
||||
&& pets['Rooster-Desert']
|
||||
&& pets['Rooster-Golden']
|
||||
&& pets['Rooster-Red']
|
||||
&& pets['Rooster-Shade']
|
||||
&& pets['Rooster-Skeleton']
|
||||
&& pets['Rooster-White']
|
||||
&& pets['Rooster-Zombie']
|
||||
&& pets['Triceratops-Base']
|
||||
&& pets['Triceratops-CottonCandyBlue']
|
||||
&& pets['Triceratops-CottonCandyPink']
|
||||
&& pets['Triceratops-Desert']
|
||||
&& pets['Triceratops-Golden']
|
||||
&& pets['Triceratops-Red']
|
||||
&& pets['Triceratops-Shade']
|
||||
&& pets['Triceratops-Skeleton']
|
||||
&& pets['Triceratops-White']
|
||||
&& pets['Triceratops-Zombie']
|
||||
&& pets['TRex-Base']
|
||||
&& pets['TRex-CottonCandyBlue']
|
||||
&& pets['TRex-CottonCandyPink']
|
||||
&& pets['TRex-Desert']
|
||||
&& pets['TRex-Golden']
|
||||
&& pets['TRex-Red']
|
||||
&& pets['TRex-Shade']
|
||||
&& pets['TRex-Skeleton']
|
||||
&& pets['TRex-White']
|
||||
&& pets['TRex-Zombie']
|
||||
&& pets['Pterodactyl-Base']
|
||||
&& pets['Pterodactyl-CottonCandyBlue']
|
||||
&& pets['Pterodactyl-CottonCandyPink']
|
||||
&& pets['Pterodactyl-Desert']
|
||||
&& pets['Pterodactyl-Golden']
|
||||
&& pets['Pterodactyl-Red']
|
||||
&& pets['Pterodactyl-Shade']
|
||||
&& pets['Pterodactyl-Skeleton']
|
||||
&& pets['Pterodactyl-White']
|
||||
&& pets['Pterodactyl-Zombie']
|
||||
&& pets['Owl-Base']
|
||||
&& pets['Owl-CottonCandyBlue']
|
||||
&& pets['Owl-CottonCandyPink']
|
||||
&& pets['Owl-Desert']
|
||||
&& pets['Owl-Golden']
|
||||
&& pets['Owl-Red']
|
||||
&& pets['Owl-Shade']
|
||||
&& pets['Owl-Skeleton']
|
||||
&& pets['Owl-White']
|
||||
&& pets['Owl-Zombie']
|
||||
&& pets['Velociraptor-Base']
|
||||
&& pets['Velociraptor-CottonCandyBlue']
|
||||
&& pets['Velociraptor-CottonCandyPink']
|
||||
&& pets['Velociraptor-Desert']
|
||||
&& pets['Velociraptor-Golden']
|
||||
&& pets['Velociraptor-Red']
|
||||
&& pets['Velociraptor-Shade']
|
||||
&& pets['Velociraptor-Skeleton']
|
||||
&& pets['Velociraptor-White']
|
||||
&& pets['Velociraptor-Zombie']
|
||||
&& pets['Penguin-Base']
|
||||
&& pets['Penguin-CottonCandyBlue']
|
||||
&& pets['Penguin-CottonCandyPink']
|
||||
&& pets['Penguin-Desert']
|
||||
&& pets['Penguin-Golden']
|
||||
&& pets['Penguin-Red']
|
||||
&& pets['Penguin-Shade']
|
||||
&& pets['Penguin-Skeleton']
|
||||
&& pets['Penguin-White']
|
||||
&& pets['Penguin-Zombie']
|
||||
&& pets['Falcon-Base']
|
||||
&& pets['Falcon-CottonCandyBlue']
|
||||
&& pets['Falcon-CottonCandyPink']
|
||||
&& pets['Falcon-Desert']
|
||||
&& pets['Falcon-Golden']
|
||||
&& pets['Falcon-Red']
|
||||
&& pets['Falcon-Shade']
|
||||
&& pets['Falcon-Skeleton']
|
||||
&& pets['Falcon-White']
|
||||
&& pets['Falcon-Zombie']
|
||||
&& pets['Peacock-Base']
|
||||
&& pets['Peacock-CottonCandyBlue']
|
||||
&& pets['Peacock-CottonCandyPink']
|
||||
&& pets['Peacock-Desert']
|
||||
&& pets['Peacock-Golden']
|
||||
&& pets['Peacock-Red']
|
||||
&& pets['Peacock-Shade']
|
||||
&& pets['Peacock-Skeleton']
|
||||
&& pets['Peacock-White']
|
||||
&& pets['Peacock-Zombie']) {
|
||||
set['achievements.dinosaurDynasty'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await User.update({ _id: user._id }, { $set: set }).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
// migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2023-04-15') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,79 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20230718_summer_splash_orcas';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = { migration: MIGRATION_NAME };
|
||||
const push = {};
|
||||
|
||||
if (user && user.items && user.items.pets && typeof user.items.pets['Orca-Base'] !== 'undefined') {
|
||||
return;
|
||||
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Orca-Base'] !== 'undefined') {
|
||||
set['items.pets.Orca-Base'] = 5;
|
||||
push.notifications = {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_orca_pet',
|
||||
title: 'Orcas for Summer Splash!',
|
||||
text: 'To celebrate Summer Splash, we\'ve given you an Orca Pet!',
|
||||
destination: 'stable',
|
||||
},
|
||||
seen: false,
|
||||
};
|
||||
} else {
|
||||
set['items.mounts.Orca-Base'] = true;
|
||||
push.notifications = {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_orca_mount',
|
||||
title: 'Orcas for Summer Splash!',
|
||||
text: 'To celebrate Summer Splash, we\'ve given you an Orca Mount!',
|
||||
destination: 'stable',
|
||||
},
|
||||
seen: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return await user.updateOne({ $set: set, $push: push }).exec();
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2023-06-18')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,155 +0,0 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20230731_naming_day';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set;
|
||||
let push;
|
||||
const inc = {
|
||||
'items.food.Cake_Base': 1,
|
||||
'items.food.Cake_CottonCandyBlue': 1,
|
||||
'items.food.Cake_CottonCandyPink': 1,
|
||||
'items.food.Cake_Desert': 1,
|
||||
'items.food.Cake_Golden': 1,
|
||||
'items.food.Cake_Red': 1,
|
||||
'items.food.Cake_Shade': 1,
|
||||
'items.food.Cake_Skeleton': 1,
|
||||
'items.food.Cake_White': 1,
|
||||
'items.food.Cake_Zombie': 1,
|
||||
'achievements.habiticaDays': 1,
|
||||
};
|
||||
|
||||
if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.back_special_namingDay2020 !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME };
|
||||
push = {
|
||||
notifications: {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_namingDay_cake',
|
||||
title: 'Happy Naming Day!',
|
||||
text: 'To celebrate the day we became Habitica, we’ve awarded you some cake!',
|
||||
destination: '/inventory/items',
|
||||
},
|
||||
seen: false,
|
||||
},
|
||||
};
|
||||
} else if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.body_special_namingDay2018 !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.gear.owned.back_special_namingDay2020': true };
|
||||
push = {
|
||||
notifications: {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_namingDay_back',
|
||||
title: 'Happy Naming Day!',
|
||||
text: 'To celebrate the day we became Habitica, we’ve awarded you a Royal Purple Gryphon Tail and cake!',
|
||||
destination: '/inventory/equipment',
|
||||
},
|
||||
seen: false,
|
||||
},
|
||||
};
|
||||
} else if (user && user.items && user.items.gear && user.items.gear.owned && typeof user.items.gear.owned.head_special_namingDay2017 !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.gear.owned.body_special_namingDay2018': true };
|
||||
push = {
|
||||
notifications: {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_namingDay_body',
|
||||
title: 'Happy Naming Day!',
|
||||
text: 'To celebrate the day we became Habitica, we’ve awarded you a Royal Purple Gryphon Cloak and cake!',
|
||||
destination: '/inventory/equipment',
|
||||
},
|
||||
seen: false,
|
||||
},
|
||||
};
|
||||
} else if (user && user.items && user.items.pets && typeof user.items.pets['Gryphon-RoyalPurple'] !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.gear.owned.head_special_namingDay2017': true };
|
||||
push = {
|
||||
notifications: {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_namingDay_head',
|
||||
title: 'Happy Naming Day!',
|
||||
text: 'To celebrate the day we became Habitica, we’ve awarded you a Royal Purple Gryphon Helm and cake!',
|
||||
destination: '/inventory/equipment',
|
||||
},
|
||||
seen: false,
|
||||
},
|
||||
};
|
||||
} else if (user && user.items && user.items.mounts && typeof user.items.mounts['Gryphon-RoyalPurple'] !== 'undefined') {
|
||||
set = { migration: MIGRATION_NAME, 'items.pets.Gryphon-RoyalPurple': 5 };
|
||||
push = {
|
||||
notifications: {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_namingDay_pet',
|
||||
title: 'Happy Naming Day!',
|
||||
text: 'To celebrate the day we became Habitica, we’ve awarded you a Royal Purple Gryphon Pet and cake!',
|
||||
destination: '/inventory/stable',
|
||||
},
|
||||
seen: false,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
set = { migration: MIGRATION_NAME, 'items.mounts.Gryphon-RoyalPurple': true };
|
||||
push = {
|
||||
notifications: {
|
||||
type: 'ITEM_RECEIVED',
|
||||
data: {
|
||||
icon: 'notif_namingDay_mount',
|
||||
title: 'Happy Naming Day!',
|
||||
text: 'To celebrate the day we became Habitica, we’ve awarded you a Royal Purple Gryphon Mount and cake!',
|
||||
destination: '/inventory/stable',
|
||||
},
|
||||
seen: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
if (push) {
|
||||
return await user.updateOne({ $set: set, $inc: inc, $push: push }).exec();
|
||||
} else {
|
||||
return await user.updateOne({ $set: set, $inc: inc }).exec();
|
||||
}
|
||||
}
|
||||
|
||||
export default async function processUsers () {
|
||||
let query = {
|
||||
migration: { $ne: MIGRATION_NAME },
|
||||
'auth.timestamps.loggedin': { $gt: new Date('2023-07-01') },
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
Generated
+1188
-1719
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.277.1",
|
||||
"version": "4.270.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.22.5",
|
||||
"@babel/preset-env": "^7.22.5",
|
||||
"@babel/register": "^7.22.5",
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/register": "^7.18.9",
|
||||
"@google-cloud/trace-agent": "^7.1.2",
|
||||
"@parse/node-apn": "^5.1.3",
|
||||
"@slack/webhook": "^6.1.0",
|
||||
@@ -14,9 +14,9 @@
|
||||
"amazon-payments": "^0.2.9",
|
||||
"amplitude": "^6.0.0",
|
||||
"apidoc": "^0.54.0",
|
||||
"apple-auth": "^1.0.9",
|
||||
"apple-auth": "^1.0.7",
|
||||
"bcrypt": "^5.1.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"body-parser": "^1.20.1",
|
||||
"bootstrap": "^4.6.0",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-session": "^2.0.0",
|
||||
@@ -42,7 +42,7 @@
|
||||
"image-size": "^1.0.2",
|
||||
"in-app-purchase": "^1.11.3",
|
||||
"js2xmlparser": "^5.0.0",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jwks-rsa": "^2.1.5",
|
||||
"lodash": "^4.17.21",
|
||||
"merge-stream": "^2.0.0",
|
||||
@@ -67,16 +67,16 @@
|
||||
"remove-markdown": "^0.5.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"short-uuid": "^4.2.2",
|
||||
"stripe": "^12.9.0",
|
||||
"superagent": "^8.0.9",
|
||||
"stripe": "^11.10.0",
|
||||
"superagent": "^8.0.6",
|
||||
"universal-analytics": "^0.5.3",
|
||||
"useragent": "^2.1.9",
|
||||
"uuid": "^9.0.0",
|
||||
"validator": "^13.9.0",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
"winston": "^3.9.0",
|
||||
"winston": "^3.8.2",
|
||||
"winston-loggly-bulk": "^3.2.1",
|
||||
"xml2js": "^0.6.0"
|
||||
"xml2js": "^0.4.23"
|
||||
},
|
||||
"private": true,
|
||||
"engines": {
|
||||
@@ -110,7 +110,7 @@
|
||||
"apidoc": "gulp apidoc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^1.3.6",
|
||||
"axios": "^1.2.2",
|
||||
"chai": "^4.3.7",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chai-moment": "^0.1.0",
|
||||
@@ -122,7 +122,7 @@
|
||||
"monk": "^7.3.4",
|
||||
"require-again": "^2.0.0",
|
||||
"run-rs": "^0.7.7",
|
||||
"sinon": "^15.1.2",
|
||||
"sinon": "^15.0.1",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"sinon-stub-promise": "^4.0.0"
|
||||
},
|
||||
|
||||
@@ -748,19 +748,9 @@ describe('payments/index', () => {
|
||||
});
|
||||
|
||||
it('does not add to plans.consecutive.offset if 1 month subscription', async () => {
|
||||
data.sub.key = 'basic_earned';
|
||||
await api.createSubscription(data);
|
||||
|
||||
expect(user.purchased.plan.consecutive.offset).to.eql(0);
|
||||
});
|
||||
|
||||
it('resets plans.consecutive.offset if 1 month subscription', async () => {
|
||||
user.purchased.plan.consecutive.offset = 1;
|
||||
await user.save();
|
||||
data.sub.key = 'basic_earned';
|
||||
await api.createSubscription(data);
|
||||
|
||||
expect(user.purchased.plan.consecutive.offset).to.eql(0);
|
||||
expect(user.purchased.plan.extraMonths).to.eql(0);
|
||||
});
|
||||
|
||||
it('adds 5 to plan.consecutive.gemCapExtra for 3 month block', async () => {
|
||||
|
||||
@@ -242,7 +242,7 @@ describe('cron middleware', () => {
|
||||
|
||||
sandbox.spy(cronLib, 'recoverCron');
|
||||
|
||||
sandbox.stub(User, 'updateOne')
|
||||
sandbox.stub(User, 'update')
|
||||
.withArgs({
|
||||
_id: user._id,
|
||||
$or: [
|
||||
|
||||
@@ -1732,7 +1732,7 @@ describe('Group Model', () => {
|
||||
});
|
||||
|
||||
it('updates participting members (not including user)', async () => {
|
||||
sandbox.spy(User, 'updateMany');
|
||||
sandbox.spy(User, 'update');
|
||||
|
||||
await party.startQuest(nonParticipatingMember);
|
||||
|
||||
@@ -1740,7 +1740,7 @@ describe('Group Model', () => {
|
||||
questLeader._id, participatingMember._id, sleepingParticipatingMember._id,
|
||||
];
|
||||
|
||||
expect(User.updateMany).to.be.calledWith(
|
||||
expect(User.update).to.be.calledWith(
|
||||
{ _id: { $in: members } },
|
||||
{
|
||||
$set: {
|
||||
@@ -1753,11 +1753,11 @@ describe('Group Model', () => {
|
||||
});
|
||||
|
||||
it('updates non-user quest leader and decrements quest scroll', async () => {
|
||||
sandbox.spy(User, 'updateOne');
|
||||
sandbox.spy(User, 'update');
|
||||
|
||||
await party.startQuest(participatingMember);
|
||||
|
||||
expect(User.updateOne).to.be.calledWith(
|
||||
expect(User.update).to.be.calledWith(
|
||||
{ _id: questLeader._id },
|
||||
{
|
||||
$inc: {
|
||||
@@ -1819,29 +1819,29 @@ describe('Group Model', () => {
|
||||
};
|
||||
|
||||
it('doesn\'t retry successful operations', async () => {
|
||||
sandbox.stub(User, 'updateOne').returns(successfulMock);
|
||||
sandbox.stub(User, 'update').returns(successfulMock);
|
||||
|
||||
await party.finishQuest(quest);
|
||||
|
||||
expect(User.updateOne).to.be.calledThrice;
|
||||
expect(User.update).to.be.calledThrice;
|
||||
});
|
||||
|
||||
it('stops retrying when a successful update has occurred', async () => {
|
||||
const updateStub = sandbox.stub(User, 'updateOne');
|
||||
const updateStub = sandbox.stub(User, 'update');
|
||||
updateStub.onCall(0).returns(failedMock);
|
||||
updateStub.returns(successfulMock);
|
||||
|
||||
await party.finishQuest(quest);
|
||||
|
||||
expect(User.updateOne.callCount).to.equal(4);
|
||||
expect(User.update.callCount).to.equal(4);
|
||||
});
|
||||
|
||||
it('retries failed updates at most five times per user', async () => {
|
||||
sandbox.stub(User, 'updateOne').returns(failedMock);
|
||||
sandbox.stub(User, 'update').returns(failedMock);
|
||||
|
||||
await expect(party.finishQuest(quest)).to.eventually.be.rejected;
|
||||
|
||||
expect(User.updateOne.callCount).to.eql(15); // for 3 users
|
||||
expect(User.update.callCount).to.eql(15); // for 3 users
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2088,17 +2088,17 @@ describe('Group Model', () => {
|
||||
|
||||
context('Party quests', () => {
|
||||
it('updates participating members with rewards', async () => {
|
||||
sandbox.spy(User, 'updateOne');
|
||||
sandbox.spy(User, 'update');
|
||||
await party.finishQuest(quest);
|
||||
|
||||
expect(User.updateOne).to.be.calledThrice;
|
||||
expect(User.updateOne).to.be.calledWithMatch({
|
||||
expect(User.update).to.be.calledThrice;
|
||||
expect(User.update).to.be.calledWithMatch({
|
||||
_id: questLeader._id,
|
||||
});
|
||||
expect(User.updateOne).to.be.calledWithMatch({
|
||||
expect(User.update).to.be.calledWithMatch({
|
||||
_id: participatingMember._id,
|
||||
});
|
||||
expect(User.updateOne).to.be.calledWithMatch({
|
||||
expect(User.update).to.be.calledWithMatch({
|
||||
_id: sleepingParticipatingMember._id,
|
||||
});
|
||||
});
|
||||
@@ -2173,11 +2173,11 @@ describe('Group Model', () => {
|
||||
});
|
||||
|
||||
it('updates all users with rewards', async () => {
|
||||
sandbox.spy(User, 'updateMany');
|
||||
sandbox.spy(User, 'update');
|
||||
await party.finishQuest(tavernQuest);
|
||||
|
||||
expect(User.updateMany).to.be.calledOnce;
|
||||
expect(User.updateMany).to.be.calledWithMatch({});
|
||||
expect(User.update).to.be.calledOnce;
|
||||
expect(User.update).to.be.calledWithMatch({});
|
||||
});
|
||||
|
||||
it('sets quest completed to the world quest key', async () => {
|
||||
|
||||
@@ -202,86 +202,18 @@ describe('POST /user/class/cast/:spellId', () => {
|
||||
await group.groupLeader.post('/user/class/cast/mpheal');
|
||||
|
||||
promises = [];
|
||||
promises.push(group.groupLeader.sync());
|
||||
promises.push(group.members[0].sync());
|
||||
promises.push(group.members[1].sync());
|
||||
promises.push(group.members[2].sync());
|
||||
promises.push(group.members[3].sync());
|
||||
await Promise.all(promises);
|
||||
|
||||
expect(group.groupLeader.stats.mp).to.be.equal(170); // spell caster
|
||||
expect(group.members[0].stats.mp).to.be.greaterThan(0); // warrior
|
||||
expect(group.members[1].stats.mp).to.equal(0); // wizard
|
||||
expect(group.members[2].stats.mp).to.be.greaterThan(0); // rogue
|
||||
expect(group.members[3].stats.mp).to.be.greaterThan(0); // healer
|
||||
});
|
||||
|
||||
const spellList = [
|
||||
{
|
||||
className: 'warrior',
|
||||
spells: [['smash', 'task'], ['defensiveStance'], ['valorousPresence'], ['intimidate']],
|
||||
},
|
||||
{
|
||||
className: 'wizard',
|
||||
spells: [['fireball', 'task'], ['mpheal'], ['earth'], ['frost']],
|
||||
},
|
||||
{
|
||||
className: 'healer',
|
||||
spells: [['heal'], ['brightness'], ['protectAura'], ['healAll']],
|
||||
},
|
||||
{
|
||||
className: 'rogue',
|
||||
spells: [['pickPocket', 'task'], ['backStab', 'task'], ['toolsOfTrade'], ['stealth']],
|
||||
},
|
||||
];
|
||||
|
||||
spellList.forEach(async habitClass => {
|
||||
describe(`For a ${habitClass.className}`, async () => {
|
||||
habitClass.spells.forEach(async spell => {
|
||||
describe(`Using ${spell[0]}`, async () => {
|
||||
it('Deducts MP from spell caster', async () => {
|
||||
const { groupLeader } = await createAndPopulateGroup({
|
||||
groupDetails: { type: 'party', privacy: 'private' },
|
||||
members: 3,
|
||||
});
|
||||
await groupLeader.update({
|
||||
'stats.mp': 200, 'stats.class': habitClass.className, 'stats.lvl': 20, 'stats.hp': 40,
|
||||
});
|
||||
// need this for task spells and for stealth
|
||||
const task = await groupLeader.post('/tasks/user', {
|
||||
text: 'test habit',
|
||||
type: 'daily',
|
||||
});
|
||||
if (spell.length === 2 && spell[1] === 'task') {
|
||||
await groupLeader.post(`/user/class/cast/${spell[0]}?targetId=${task._id}`);
|
||||
} else {
|
||||
await groupLeader.post(`/user/class/cast/${spell[0]}`);
|
||||
}
|
||||
await groupLeader.sync();
|
||||
expect(groupLeader.stats.mp).to.be.lessThan(200);
|
||||
});
|
||||
it('works without a party', async () => {
|
||||
await user.update({
|
||||
'stats.mp': 200, 'stats.class': habitClass.className, 'stats.lvl': 20, 'stats.hp': 40,
|
||||
});
|
||||
// need this for task spells and for stealth
|
||||
const task = await user.post('/tasks/user', {
|
||||
text: 'test habit',
|
||||
type: 'daily',
|
||||
});
|
||||
if (spell.length === 2 && spell[1] === 'task') {
|
||||
await user.post(`/user/class/cast/${spell[0]}?targetId=${task._id}`);
|
||||
} else {
|
||||
await user.post(`/user/class/cast/${spell[0]}`);
|
||||
}
|
||||
await user.sync();
|
||||
expect(user.stats.mp).to.be.lessThan(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('cast bulk', async () => {
|
||||
let { group, groupLeader } = await createAndPopulateGroup({ // eslint-disable-line prefer-const
|
||||
groupDetails: { type: 'party', privacy: 'private' },
|
||||
|
||||
Generated
+52
-53
@@ -1842,9 +1842,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-proposal-optional-chaining": {
|
||||
"version": "7.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz",
|
||||
"integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==",
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz",
|
||||
"integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
|
||||
@@ -1870,9 +1870,9 @@
|
||||
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.21.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz",
|
||||
"integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==",
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
|
||||
"integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.19.4",
|
||||
"@babel/helper-validator-identifier": "^7.19.1",
|
||||
@@ -13321,12 +13321,14 @@
|
||||
"emojis-list": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
|
||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
|
||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
||||
"optional": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
@@ -13337,6 +13339,7 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
|
||||
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
@@ -13378,6 +13381,7 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
@@ -13386,6 +13390,7 @@
|
||||
"version": "npm:vue-loader@16.8.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.3.tgz",
|
||||
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
@@ -13396,6 +13401,7 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -16901,9 +16907,9 @@
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.31.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.0.tgz",
|
||||
"integrity": "sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ=="
|
||||
"version": "3.27.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz",
|
||||
"integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w=="
|
||||
},
|
||||
"core-js-compat": {
|
||||
"version": "3.11.0",
|
||||
@@ -17952,9 +17958,9 @@
|
||||
}
|
||||
},
|
||||
"dompurify": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.3.tgz",
|
||||
"integrity": "sha512-axQ9zieHLnAnHh0sfAamKYiqXMJAVwu+LM/alQ7WDagoWessyWvMSFyW65CqF3owufNu8HBcE4cM2Vflu7YWcQ=="
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz",
|
||||
"integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ=="
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
@@ -21071,11 +21077,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg=="
|
||||
},
|
||||
"immutable": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||
"integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg=="
|
||||
},
|
||||
"import-cwd": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
|
||||
@@ -21436,9 +21437,9 @@
|
||||
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
|
||||
},
|
||||
"intro.js": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/intro.js/-/intro.js-7.0.1.tgz",
|
||||
"integrity": "sha512-1oqz6aOz9cGQ3CrtVYhCSo6AkjnXUn302kcIWLaZ3TI4kKssRXDwDSz4VRoGcfC1jN+WfaSJXRBrITz+QVEBzg=="
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/intro.js/-/intro.js-6.0.0.tgz",
|
||||
"integrity": "sha512-ZUiR6BoLSvPSlLG0boewnWVgji1fE1gBvP/pyw5pgCKXEDQz1mMeUxarggClPNs71UTq364LwSk9zxz17A9gaQ=="
|
||||
},
|
||||
"invariant": {
|
||||
"version": "2.2.4",
|
||||
@@ -22018,9 +22019,9 @@
|
||||
}
|
||||
},
|
||||
"jquery": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.0.tgz",
|
||||
"integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ=="
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz",
|
||||
"integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
|
||||
},
|
||||
"js-message": {
|
||||
"version": "1.0.5",
|
||||
@@ -27366,19 +27367,17 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.63.4",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.63.4.tgz",
|
||||
"integrity": "sha512-Sx/+weUmK+oiIlI+9sdD0wZHsqpbgQg8wSwSnGBjwb5GwqFhYNwwnI+UWZtLjKvKyFlKkatRK235qQ3mokyPoQ==",
|
||||
"version": "1.34.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.34.0.tgz",
|
||||
"integrity": "sha512-rHEN0BscqjUYuomUEaqq3BMgsXqQfkcMVR7UhscsAVub0/spUrZGBMxQXFS2kfiDsPLZw5yuU9iJEFNC2x38Qw==",
|
||||
"requires": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
"chokidar": ">=3.0.0 <4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||
"requires": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
@@ -27398,18 +27397,18 @@
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
|
||||
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
|
||||
"requires": {
|
||||
"anymatch": "~3.1.2",
|
||||
"anymatch": "~3.1.1",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"fsevents": "~2.3.1",
|
||||
"glob-parent": "~5.1.0",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
"readdirp": "~3.5.0"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
@@ -27448,9 +27447,9 @@
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
|
||||
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
|
||||
"requires": {
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
@@ -27802,9 +27801,9 @@
|
||||
}
|
||||
},
|
||||
"smartbanner.js": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.19.2.tgz",
|
||||
"integrity": "sha512-hwcGNp5Hza5PJHTmqP6H8q0XBYhloIQyJgdzv0ldz3HQSeEuKB2riVraQXdKuquE6ZU/0M0yubno53xJ/ZiQQg=="
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/smartbanner.js/-/smartbanner.js-1.19.1.tgz",
|
||||
"integrity": "sha512-x3alFTlk6pLuqrm9PrYQv1E+86CrEIgPf/KJ+nP5342BmOWstbdR8OwD3TPmM56zHQm4MEr/eoqbEcfTKdvdKw=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
@@ -28176,9 +28175,9 @@
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"stopword": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/stopword/-/stopword-2.0.8.tgz",
|
||||
"integrity": "sha512-btlEC2vEuhCuvshz99hSGsY8GzaP5qzDPQm56j6rR/R38p8xdsOXgU5a6tIgvU/4hcCta1Vlo/2FVXA9m0f8XA=="
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/stopword/-/stopword-2.0.7.tgz",
|
||||
"integrity": "sha512-s+uLKAxrproCLrq0Wcd3JAIjlJLx6l80b2Rzt0u8+ra5SzGkHnNG8PS3DfGmYk2TrKePDVLL4SdKYwKpgSLc+w=="
|
||||
},
|
||||
"store2": {
|
||||
"version": "2.10.0",
|
||||
@@ -30272,9 +30271,9 @@
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
},
|
||||
"uuid-browser": {
|
||||
"version": "3.1.0",
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
"bootstrap": "^4.6.0",
|
||||
"bootstrap-vue": "^2.23.1",
|
||||
"chai": "^4.3.7",
|
||||
"core-js": "^3.31.0",
|
||||
"dompurify": "^3.0.3",
|
||||
"core-js": "^3.27.2",
|
||||
"dompurify": "^2.4.3",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-habitrpg": "^6.2.0",
|
||||
"eslint-plugin-mocha": "^5.3.0",
|
||||
@@ -41,20 +41,20 @@
|
||||
"habitica-markdown": "^3.0.0",
|
||||
"hellojs": "^1.20.0",
|
||||
"inspectpack": "^4.7.1",
|
||||
"intro.js": "^7.0.1",
|
||||
"jquery": "^3.7.0",
|
||||
"intro.js": "^6.0.0",
|
||||
"jquery": "^3.6.3",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.4",
|
||||
"nconf": "^0.12.0",
|
||||
"sass": "^1.63.4",
|
||||
"sass": "^1.34.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"smartbanner.js": "^1.19.2",
|
||||
"stopword": "^2.0.8",
|
||||
"smartbanner.js": "^1.19.1",
|
||||
"stopword": "^2.0.7",
|
||||
"svg-inline-loader": "^0.8.2",
|
||||
"svg-url-loader": "^7.1.1",
|
||||
"svgo": "^1.3.2",
|
||||
"svgo-loader": "^2.2.1",
|
||||
"uuid": "^9.0.0",
|
||||
"uuid": "^8.3.2",
|
||||
"validator": "^13.9.0",
|
||||
"vue": "^2.7.10",
|
||||
"vue-cli-plugin-storybook": "2.1.0",
|
||||
@@ -66,6 +66,6 @@
|
||||
"webpack": "^4.46.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.21.0"
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.20.7"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,18 +17,10 @@
|
||||
Payment schedule ("basic-earned" is monthly):
|
||||
<strong>{{ hero.purchased.plan.planId }}</strong>
|
||||
</div>
|
||||
<div v-if="hero.purchased.plan.planId == 'group_plan_auto'">
|
||||
Group plan ID:
|
||||
<strong>{{ hero.purchased.plan.owner }}</strong>
|
||||
</div>
|
||||
<div v-if="hero.purchased.plan.dateCreated">
|
||||
Creation date:
|
||||
<strong>{{ dateFormat(hero.purchased.plan.dateCreated) }}</strong>
|
||||
</div>
|
||||
<div v-if="hero.purchased.plan.dateCurrentTypeCreated">
|
||||
Start date for current subscription type:
|
||||
<strong>{{ dateFormat(hero.purchased.plan.dateCurrentTypeCreated) }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
Termination date:
|
||||
<strong
|
||||
@@ -54,16 +46,9 @@
|
||||
Perk offset months:
|
||||
<strong>{{ hero.purchased.plan.consecutive.offset }}</strong>
|
||||
</div>
|
||||
<div class="form-inline">
|
||||
<div>
|
||||
Perk month count:
|
||||
<input
|
||||
v-model="hero.purchased.plan.perkMonthCount"
|
||||
class="form-control"
|
||||
type="number"
|
||||
min="0"
|
||||
max="2"
|
||||
step="1"
|
||||
>
|
||||
<strong>{{ hero.purchased.plan.perkMonthCount }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
Next Mystic Hourglass:
|
||||
|
||||
@@ -183,8 +183,10 @@
|
||||
<div
|
||||
v-for="bg in backgroundShopSets[0].items"
|
||||
:key="bg.key"
|
||||
:id="bg.key"
|
||||
class="col-2"
|
||||
:popover-title="bg.text"
|
||||
:popover="bg.notes"
|
||||
popover-trigger="mouseenter"
|
||||
@click="unlock('background.' + bg.key)"
|
||||
>
|
||||
<div
|
||||
@@ -193,13 +195,6 @@
|
||||
>
|
||||
<div class="small-rectangle"></div>
|
||||
</div>
|
||||
<b-popover
|
||||
:target="bg.key"
|
||||
triggers="hover focus"
|
||||
placement="bottom"
|
||||
:prevent-overflow="false"
|
||||
:content="bg.notes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -216,21 +211,16 @@
|
||||
<div
|
||||
v-for="bg in backgroundShopSets[2].items"
|
||||
:key="bg.key"
|
||||
:id="bg.key"
|
||||
class="col-4 text-center customize-option background-button"
|
||||
:popover-title="bg.text"
|
||||
:popover="bg.notes"
|
||||
popover-trigger="mouseenter"
|
||||
@click="unlock('background.' + bg.key)"
|
||||
>
|
||||
<div
|
||||
class="background"
|
||||
:class="`background_${bg.key}`"
|
||||
></div>
|
||||
<b-popover
|
||||
:target="bg.key"
|
||||
triggers="hover focus"
|
||||
placement="bottom"
|
||||
:prevent-overflow="false"
|
||||
:content="bg.notes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -246,8 +236,10 @@
|
||||
<div
|
||||
v-for="bg in backgroundShopSets[1].items"
|
||||
:key="bg.key"
|
||||
:id="bg.key"
|
||||
class="col-4 text-center customize-option background-button"
|
||||
:popover-title="bg.text"
|
||||
:popover="bg.notes"
|
||||
popover-trigger="mouseenter"
|
||||
@click="!user.purchased.background[bg.key]
|
||||
? backgroundSelected(bg) : unlock('background.' + bg.key)"
|
||||
>
|
||||
@@ -278,13 +270,6 @@
|
||||
:pinned="isBackgroundPinned(bg)"
|
||||
/>
|
||||
</span>
|
||||
<b-popover
|
||||
:target="bg.key"
|
||||
triggers="hover focus"
|
||||
placement="bottom"
|
||||
:prevent-overflow="false"
|
||||
:content="bg.notes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -317,8 +302,10 @@
|
||||
<div
|
||||
v-for="bg in set.items"
|
||||
:key="bg.key"
|
||||
:id="bg.key"
|
||||
class="col-4 text-center customize-option background-button"
|
||||
:popover-title="bg.text"
|
||||
:popover="bg.notes"
|
||||
popover-trigger="mouseenter"
|
||||
@click="!user.purchased.background[bg.key]
|
||||
? backgroundSelected(bg) : unlock('background.' + bg.key)"
|
||||
>
|
||||
@@ -349,13 +336,6 @@
|
||||
:pinned="isBackgroundPinned(bg)"
|
||||
/>
|
||||
</span>
|
||||
<b-popover
|
||||
:target="bg.key"
|
||||
triggers="hover focus"
|
||||
placement="bottom"
|
||||
:prevent-overflow="false"
|
||||
:content="bg.notes"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="!ownsSet('background', set.items) && set.identifier !== 'incentiveBackgrounds'"
|
||||
@@ -378,21 +358,16 @@
|
||||
<div
|
||||
v-for="(bg) in ownedBackgrounds"
|
||||
:key="bg.key"
|
||||
:id="bg.key"
|
||||
class="col-4 text-center customize-option background-button"
|
||||
:popover-title="bg.text"
|
||||
:popover="bg.notes"
|
||||
popover-trigger="mouseenter"
|
||||
@click="unlock('background.' + bg.key)"
|
||||
>
|
||||
<div
|
||||
class="background"
|
||||
:class="[`background_${bg.key}`, backgroundLockedStatus(bg.key)]"
|
||||
></div>
|
||||
<b-popover
|
||||
:target="bg.key"
|
||||
triggers="hover focus"
|
||||
placement="bottom"
|
||||
:prevent-overflow="false"
|
||||
:content="bg.notes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -188,7 +188,6 @@
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 3px 0 rgba(26, 24, 29, 0.12), 0 1px 2px 0 rgba(26, 24, 29, 0.24);
|
||||
background-color: $white;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 24px;
|
||||
|
||||
@@ -258,22 +258,13 @@
|
||||
:key="hero._id"
|
||||
>
|
||||
<td>
|
||||
<div
|
||||
<user-link
|
||||
v-if="hasPermission(hero, 'userSupport')"
|
||||
class="width-content"
|
||||
>
|
||||
<user-link
|
||||
:id="hero._id"
|
||||
:user="hero"
|
||||
/>
|
||||
<b-popover
|
||||
:target="hero._id"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('gamemaster')"
|
||||
/>
|
||||
</div>
|
||||
:user="hero"
|
||||
:popover="$t('gamemaster')"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
/>
|
||||
<user-link
|
||||
v-else
|
||||
:user="hero"
|
||||
@@ -311,10 +302,6 @@
|
||||
h4.expand-toggle::after {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.width-content {
|
||||
width: fit-content;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -44,13 +44,13 @@ export default {
|
||||
if (!this.notification || !this.notification.data) {
|
||||
return;
|
||||
}
|
||||
if (this.notification.data.destination.indexOf('backgrounds') !== -1) {
|
||||
if (this.notification.data.destination === 'backgrounds') {
|
||||
this.$store.state.avatarEditorOptions.editingUser = true;
|
||||
this.$store.state.avatarEditorOptions.startingPage = 'backgrounds';
|
||||
this.$store.state.avatarEditorOptions.subpage = '2023';
|
||||
this.$root.$emit('bv::show::modal', 'avatar-modal');
|
||||
} else {
|
||||
this.$router.push(this.notification.data.destination || '/inventory/items');
|
||||
this.$router.push({ name: this.notification.data.destination || 'items' });
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
<!-- the word "total" -->
|
||||
<div class="buy-gem-total">
|
||||
{{ $t('sendTotal') }}
|
||||
{{ $t('sendGiftTotal') }}
|
||||
</div>
|
||||
|
||||
<!-- the actual dollar amount -->
|
||||
|
||||
@@ -128,10 +128,7 @@
|
||||
<hr>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="checkbox"
|
||||
id="preferenceAdvancedCollapsed"
|
||||
>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input
|
||||
v-model="user.preferences.advancedCollapsed"
|
||||
@@ -139,22 +136,33 @@
|
||||
class="mr-2"
|
||||
@change="set('advancedCollapsed')"
|
||||
>
|
||||
<span class="hint">
|
||||
{{ $t('startAdvCollapsed') }}
|
||||
</span>
|
||||
<b-popover
|
||||
target="preferenceAdvancedCollapsed"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('startAdvCollapsedPop')"
|
||||
/>
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('startAdvCollapsedPop')"
|
||||
>{{ $t('startAdvCollapsed') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input
|
||||
v-model="user.preferences.dailyDueDefaultView"
|
||||
type="checkbox"
|
||||
class="mr-2"
|
||||
@change="set('dailyDueDefaultView')"
|
||||
>
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('dailyDueDefaultViewPop')"
|
||||
>{{ $t('dailyDueDefaultView') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
v-if="party.memberCount === 1"
|
||||
class="checkbox"
|
||||
id="preferenceDisplayInviteAtOneMember"
|
||||
>
|
||||
<label>
|
||||
<input
|
||||
@@ -163,9 +171,12 @@
|
||||
class="mr-2"
|
||||
@change="set('displayInviteToPartyWhenPartyIs1')"
|
||||
>
|
||||
<span class="hint">
|
||||
{{ $t('displayInviteToPartyWhenPartyIs1') }}
|
||||
</span>
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('displayInviteToPartyWhenPartyIs1')"
|
||||
>{{ $t('displayInviteToPartyWhenPartyIs1') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
@@ -206,47 +217,32 @@
|
||||
</div>
|
||||
<hr>
|
||||
<button
|
||||
id="buttonShowBailey"
|
||||
class="btn btn-primary mr-2 mb-2"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('showBaileyPop')"
|
||||
@click="showBailey()"
|
||||
>
|
||||
{{ $t('showBailey') }}
|
||||
<b-popover
|
||||
target="buttonShowBailey"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('showBaileyPop')"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
id="buttonFCV"
|
||||
class="btn btn-primary mr-2 mb-2"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('fixValPop')"
|
||||
@click="openRestoreModal()"
|
||||
>
|
||||
{{ $t('fixVal') }}
|
||||
<b-popover
|
||||
target="buttonFCV"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('fixValPop')"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
v-if="user.preferences.disableClasses == true"
|
||||
id="buttonEnableClasses"
|
||||
class="btn btn-primary mb-2"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('enableClassPop')"
|
||||
@click="changeClassForUser(false)"
|
||||
>
|
||||
{{ $t('enableClass') }}
|
||||
<b-popover
|
||||
target="buttonEnableClasses"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('enableClassPop')"
|
||||
/>
|
||||
</button>
|
||||
<hr>
|
||||
<day-start-adjustment />
|
||||
@@ -536,10 +532,6 @@
|
||||
input {
|
||||
color: $gray-50;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
width: fit-content;
|
||||
}
|
||||
.usersettings h5 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<div class="item-cost">
|
||||
<span
|
||||
class="cost"
|
||||
:class="getPriceClass()"
|
||||
>
|
||||
<span
|
||||
class="svg-icon inline icon-24"
|
||||
aria-hidden="true"
|
||||
v-html="icons[getPriceClass()]"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
:class="getPriceClass()"
|
||||
>{{ item.value }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
@import '~@/assets/scss/mixins.scss';
|
||||
|
||||
.item-cost {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.cost {
|
||||
height: 40px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
vertical-align: middle;
|
||||
|
||||
&.gems {
|
||||
color: $gems-color;
|
||||
border-radius: 20px;
|
||||
padding: 8px 20px 8px 20px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
background-color: rgba(36, 204, 143, 0.15);
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $gold-color;
|
||||
border-radius: 20px;
|
||||
padding: 8px 20px 8px 20px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
background-color: rgba(255, 190, 93, 0.15);
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
color: $hourglass-color;
|
||||
border-radius: 20px;
|
||||
padding: 8px 20px 8px 20px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
background-color: rgba(41, 149, 205, 0.15);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import svgClose from '@/assets/svg/close.svg';
|
||||
import svgGold from '@/assets/svg/gold.svg';
|
||||
import svgGem from '@/assets/svg/gem.svg';
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
close: svgClose,
|
||||
gold: svgGold,
|
||||
gems: svgGem,
|
||||
}),
|
||||
selectedAmountToBuy: 1,
|
||||
selectedAmount: 1,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getPriceClass () {
|
||||
if (this.priceType && this.icons[this.priceType]) {
|
||||
return this.priceType;
|
||||
} if (this.item.currency && this.icons[this.item.currency]) {
|
||||
return this.item.currency;
|
||||
}
|
||||
return 'gold';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,137 +0,0 @@
|
||||
<template>
|
||||
<div class="d-flex flex-row align-items-center justify-content-center number-increment">
|
||||
<!-- buy modal -->
|
||||
<div
|
||||
class="gray-circle"
|
||||
@click="quantity <= 0
|
||||
? quantity = 0
|
||||
: quantity--"
|
||||
>
|
||||
<div
|
||||
class="icon-negative"
|
||||
v-html="icons.svgNegative"
|
||||
></div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<div class="align-items-center">
|
||||
</div>
|
||||
<input
|
||||
v-model="quantity"
|
||||
class="form-control alignment"
|
||||
step="1"
|
||||
type="number"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="gray-circle"
|
||||
@click="quantity++"
|
||||
>
|
||||
<div
|
||||
class="icon-positive"
|
||||
v-html="icons.svgPositive"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
.number-increment {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.alignment {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
width: 94px;
|
||||
height: 32px;
|
||||
width: 48px;
|
||||
margin: 0px 16px 0px 16px;
|
||||
padding: 0;
|
||||
border-radius: 2px;
|
||||
border: solid 1px $gray-400;
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.gray-circle {
|
||||
border-radius: 100%;
|
||||
border: solid 2px $gray-300;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border-color: $purple-300;
|
||||
}
|
||||
}
|
||||
|
||||
.gray-circle:hover{
|
||||
.icon-positive, .icon-negative {
|
||||
& ::v-deep svg path {
|
||||
fill: $purple-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-positive, .icon-negative {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin: 4px auto;
|
||||
|
||||
& ::v-deep svg path {
|
||||
fill: $gray-300;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chrome, Safari, Edge, Opera */
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
input[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// icons
|
||||
import svgGem from '@/assets/svg/gem.svg';
|
||||
import svgGold from '@/assets/svg/gold.svg';
|
||||
import svgPositive from '@/assets/svg/positive.svg';
|
||||
import svgNegative from '@/assets/svg/negative.svg';
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
svgGem,
|
||||
svgGold,
|
||||
svgPositive,
|
||||
svgNegative,
|
||||
}),
|
||||
item: { },
|
||||
quantity: 1,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
watch: {
|
||||
quantity () {
|
||||
this.$emit('updateQuantity', this.quantity);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setDefaults () {
|
||||
this.input = 1;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
@@ -22,11 +22,10 @@
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
span {
|
||||
font-size: 0.75rem;
|
||||
font-weight: normal;
|
||||
font-size: 12px;
|
||||
line-height: 1.33;
|
||||
color: $gray-100;
|
||||
margin-bottom: 16px;
|
||||
margin-top: -4px;
|
||||
color: $gray-200;
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
class="svg-icon close-icon icon-16 color"
|
||||
class="svg-icon icon-12 close-icon"
|
||||
aria-hidden="true"
|
||||
tabindex="0"
|
||||
@click="hideDialog()"
|
||||
@@ -45,13 +45,6 @@
|
||||
:sprites-margin="'0px auto 0px -24px'"
|
||||
/>
|
||||
</div>
|
||||
<item
|
||||
v-else-if="item.key === 'gem'"
|
||||
class="flat bordered-item"
|
||||
:item="item"
|
||||
:item-content-class="item.class"
|
||||
:show-popover="false"
|
||||
/>
|
||||
<item
|
||||
v-else-if="item.key != 'gem'"
|
||||
class="flat bordered-item"
|
||||
@@ -60,20 +53,10 @@
|
||||
:show-popover="false"
|
||||
/>
|
||||
</slot>
|
||||
<div
|
||||
v-if="!showAvatar && user.items[item.purchaseType]"
|
||||
class="owned"
|
||||
:class="totalOwned"
|
||||
>
|
||||
<!-- eslint-disable-next-line max-len -->
|
||||
<span class="owned-text">{{ $t('owned') }}: <span class="user-amount">{{ totalOwned }}</span></span>
|
||||
</div>
|
||||
<h4 class="title">
|
||||
{{ itemText }}
|
||||
</h4>
|
||||
<div class="item-notes">
|
||||
{{ itemNotes }}
|
||||
</div>
|
||||
<div v-html="itemNotes"></div>
|
||||
<slot
|
||||
name="additionalInfo"
|
||||
:item="item"
|
||||
@@ -86,61 +69,60 @@
|
||||
/>
|
||||
</slot>
|
||||
<div
|
||||
v-if="item.value > 0 && !(item.key === 'gem' && gemsLeft < 1)"
|
||||
v-if="item.value > 0"
|
||||
class="purchase-amount"
|
||||
>
|
||||
<!-- this is where the pretty item cost element lives -->
|
||||
<div class="item-cost">
|
||||
<span
|
||||
class="cost"
|
||||
:class="getPriceClass()"
|
||||
>
|
||||
<span
|
||||
class="svg-icon inline icon-24"
|
||||
aria-hidden="true"
|
||||
v-html="icons[getPriceClass()]"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
:class="getPriceClass()"
|
||||
>{{ item.value }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="showAmountToBuy(item)"
|
||||
class="how-many-to-buy"
|
||||
>
|
||||
{{ $t('howManyToBuy') }}
|
||||
<strong>{{ $t('howManyToBuy') }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-if="showAmountToBuy(item)"
|
||||
>
|
||||
<number-increment
|
||||
class="number-increment"
|
||||
@updateQuantity="selectedAmountToBuy = $event"
|
||||
/>
|
||||
<div
|
||||
:class="{'notEnough': notEnoughCurrency}"
|
||||
class="total"
|
||||
>
|
||||
<span class="total-text">{{ $t('sendTotal') }}</span>
|
||||
<div v-if="showAmountToBuy(item)">
|
||||
<div class="box">
|
||||
<input
|
||||
v-model.number="selectedAmountToBuy"
|
||||
class="form-control"
|
||||
type="number"
|
||||
min="0"
|
||||
step="1"
|
||||
>
|
||||
</div>
|
||||
<span :class="{'notEnough': notEnoughCurrency}">
|
||||
<span
|
||||
class="svg-icon total icon-24"
|
||||
class="svg-icon inline icon-32"
|
||||
aria-hidden="true"
|
||||
v-html="icons[getPriceClass()]"
|
||||
></span>
|
||||
<span
|
||||
class="total-text"
|
||||
class="cost"
|
||||
:class="getPriceClass()"
|
||||
>{{ item.value * selectedAmountToBuy }}</span>
|
||||
</div>
|
||||
>{{ item.value }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="d-flex align-items-middle"
|
||||
>
|
||||
<span
|
||||
class="svg-icon inline icon-32 ml-auto my-auto"
|
||||
aria-hidden="true"
|
||||
v-html="icons[getPriceClass()]"
|
||||
></span>
|
||||
<span
|
||||
class="cost mr-auto my-auto"
|
||||
:class="getPriceClass()"
|
||||
>{{ item.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.key === 'gem' && gemsLeft < 1"
|
||||
class="no-more-gems"
|
||||
v-if="item.key === 'gem'"
|
||||
class="gems-left"
|
||||
>
|
||||
<strong v-if="gemsLeft > 0">{{ gemsLeft }} {{ $t('gemsRemaining') }}</strong>
|
||||
<strong v-if="gemsLeft === 0">{{ $t('maxBuyGems') }}</strong>
|
||||
</div>
|
||||
<div v-if="attemptingToPurchaseMoreGemsThanAreLeft">
|
||||
{{ $t('notEnoughGemsToBuy') }}
|
||||
</div>
|
||||
<div
|
||||
@@ -165,7 +147,7 @@
|
||||
{{ $t('viewSubscriptions') }}
|
||||
</button>
|
||||
<button
|
||||
v-else-if="!(item.key === 'gem' && gemsLeft < 1)"
|
||||
v-else
|
||||
class="btn btn-primary"
|
||||
:disabled="item.key === 'gem' && gemsLeft === 0 ||
|
||||
attemptingToPurchaseMoreGemsThanAreLeft || numberInvalid || item.locked ||
|
||||
@@ -183,7 +165,6 @@
|
||||
<countdown-banner
|
||||
v-if="item.event && item.owned == null"
|
||||
:end-date="endDate"
|
||||
class="limitedTime available"
|
||||
/>
|
||||
<div
|
||||
v-if="item.key === 'rebirth_orb' && item.value > 0 && user.stats.lvl >= 100"
|
||||
@@ -197,32 +178,13 @@
|
||||
<span v-html="$t('nextFreeRebirth', {days: nextFreeRebirth})"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="item.key === 'gem'"
|
||||
class="d-flex justify-content-center align-items-center"
|
||||
>
|
||||
<div
|
||||
v-if="gemsLeft > 0"
|
||||
class="gems-left d-flex justify-content-center align-items-center"
|
||||
>
|
||||
<strong>{{ $t('monthlyGems') }} </strong>
|
||||
{{ gemsLeft }} / {{ totalGems }} {{ $t('gemsRemaining') }}
|
||||
</div>
|
||||
<div
|
||||
v-if="gemsLeft === 0"
|
||||
class="out-of-gems-banner d-flex justify-content-center align-items-center"
|
||||
>
|
||||
<strong>{{ $t('monthlyGems') }} </strong>
|
||||
{{ gemsLeft }} / {{ totalGems }} {{ $t('gemsRemaining') }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
slot="modal-footer"
|
||||
class="clearfix"
|
||||
class="d-flex"
|
||||
>
|
||||
<span class="user-balance float-left">{{ $t('yourBalance') }}</span>
|
||||
<span class="balance mr-auto">{{ $t('yourBalance') }}</span>
|
||||
<balanceInfo
|
||||
class="currency-totals"
|
||||
class="ml-auto"
|
||||
:currency-needed="getPriceClass()"
|
||||
:amount-needed="item.value"
|
||||
/>
|
||||
@@ -238,47 +200,11 @@
|
||||
@include centeredModal();
|
||||
|
||||
.modal-body {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
height: 48px;
|
||||
background-color: $gray-700;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
display: block;
|
||||
margin: 24px 0 0 0;
|
||||
padding: 16px 24px;
|
||||
align-content: center;
|
||||
|
||||
.user-balance {
|
||||
width: 150px;
|
||||
height: 16px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-100;
|
||||
margin-bottom: 16px;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.currency-totals {
|
||||
margin-right: -8px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
width: 448px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.badge-dialog {
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
width: 330px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
@@ -286,71 +212,8 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.owned {
|
||||
height: 32px;
|
||||
width: 141px;
|
||||
margin-top: -36px;
|
||||
margin-left: 153px;
|
||||
padding-top: 6px;
|
||||
background-color: $gray-600;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
.owned-text {
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.71;
|
||||
}
|
||||
|
||||
.user-amount {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
transform: scale(1.45, 1.45);
|
||||
top: -25.67px;
|
||||
left: 1px;
|
||||
|
||||
&.shop_gem {
|
||||
transform: scale(1.45, 1.45);
|
||||
top: -2px;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 28px;
|
||||
color: $gray-10;
|
||||
font-size: 1.25rem;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.item-notes {
|
||||
margin-top: 8px;
|
||||
padding-left: 48.5px;
|
||||
padding-right: 48.5px;
|
||||
line-height: 1.71;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
width: 448px;
|
||||
}
|
||||
|
||||
.item-wrapper {
|
||||
@@ -358,22 +221,15 @@
|
||||
}
|
||||
|
||||
.inner-content {
|
||||
margin: 32px auto auto;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
margin-top: 16px;
|
||||
margin: 33px auto auto;
|
||||
width: 282px;
|
||||
}
|
||||
|
||||
.purchase-amount {
|
||||
margin-top: 0px;
|
||||
margin-top: 24px;
|
||||
|
||||
.how-many-to-buy {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.number-increment {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.box {
|
||||
@@ -399,105 +255,31 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.no-more-gems {
|
||||
color: $yellow-5;
|
||||
font-size: 0.875em;
|
||||
line-height: 1.33;
|
||||
margin: 16px 48px 0 48px;
|
||||
}
|
||||
|
||||
// for cost icon of a single item
|
||||
span.svg-icon.inline.icon-24 {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-right: 4px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
// for the total user cost
|
||||
span.svg-icon.total.icon-24 {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-left: 6px;
|
||||
span.svg-icon.inline.icon-32 {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
|
||||
margin-right: 8px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
span.svg-icon.icon-16 {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
color: $gray-200;
|
||||
stroke-width: 0px;
|
||||
|
||||
&:hover {
|
||||
color: $gray-100;
|
||||
}
|
||||
}
|
||||
|
||||
.attributes-group {
|
||||
margin: 32px;
|
||||
border-radius: 4px;
|
||||
line-height: 1.71;
|
||||
font-size: 0.875;
|
||||
}
|
||||
|
||||
.attributesGrid {
|
||||
margin-top: 28px;
|
||||
border-radius: 2px;
|
||||
background-color: $gray-500;
|
||||
}
|
||||
|
||||
.item-cost {
|
||||
display: inline-flex;
|
||||
margin: 16px 0;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.cost {
|
||||
display: inline-block;
|
||||
font-family: sans-serif;
|
||||
font-size: 1.25rem;
|
||||
width: 28px;
|
||||
height: 32px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding: 6px 20px;
|
||||
line-height: 1.4;
|
||||
border-radius: 20px;
|
||||
line-height: 1.33;
|
||||
|
||||
vertical-align: middle;
|
||||
|
||||
&.gems {
|
||||
color: $green-10;
|
||||
background-color: rgba(36, 204, 143, 0.15);
|
||||
align-items: center;
|
||||
color: $gems-color;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
background-color: rgba(255, 190, 93, 0.15);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
color: $hourglass-color;
|
||||
background-color: rgba(41, 149, 205, 0.15);
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.total {
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
padding-top: 2px;
|
||||
margin-top: 4px;
|
||||
|
||||
&.gems {
|
||||
color: $green-10;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
color: $gold-color;
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
@@ -505,84 +287,62 @@
|
||||
}
|
||||
}
|
||||
|
||||
.total-text {
|
||||
color: $gray-50;
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.71;
|
||||
|
||||
&.gems {
|
||||
color: $green-10;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
color: $hourglass-color;
|
||||
}
|
||||
}
|
||||
|
||||
button.btn.btn-primary {
|
||||
margin-top: 16px;
|
||||
padding: 4px 16px;
|
||||
height: 32px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
min-width: 6rem;
|
||||
|
||||
&:focus {
|
||||
border: 2px solid black;
|
||||
}
|
||||
}
|
||||
|
||||
.notEnough {
|
||||
pointer-events: none;
|
||||
opacity: 0.55;
|
||||
}
|
||||
.balance {
|
||||
width: 74px;
|
||||
height: 16px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
.free-rebirth {
|
||||
background-color: $yellow-5;
|
||||
color: $white;
|
||||
height: 2rem;
|
||||
line-height: 16px;
|
||||
margin: auto -1rem -1rem;
|
||||
}
|
||||
.modal-footer {
|
||||
height: 48px;
|
||||
background-color: $gray-700;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
// .pt-015 {
|
||||
// padding-top: 0.15rem;
|
||||
// }
|
||||
.notEnough {
|
||||
pointer-events: none;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.attributesGrid {
|
||||
margin-top: 8px;
|
||||
border-radius: 2px;
|
||||
background-color: $gray-500;
|
||||
|
||||
margin: 10px 0 24px;
|
||||
}
|
||||
|
||||
.gems-left {
|
||||
height: 32px;
|
||||
background-color: $green-100;
|
||||
font-size: 0.75rem;
|
||||
margin-top: 24px;
|
||||
color: $green-1;
|
||||
width: 100%;
|
||||
margin-bottom: -24px;
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
.out-of-gems-banner {
|
||||
height: 32px;
|
||||
font-size: 0.75rem;
|
||||
margin-top: 24px;
|
||||
background-color: $yellow-100;
|
||||
color: $yellow-1;
|
||||
width: 100%;
|
||||
margin-bottom: -24px;
|
||||
}
|
||||
|
||||
.limitedTime {
|
||||
height: 32px;
|
||||
width: 446px;
|
||||
font-size: 0.75rem;
|
||||
margin: 24px 0 0 0;
|
||||
background-color: $purple-300;
|
||||
.free-rebirth {
|
||||
background-color: $yellow-5;
|
||||
color: $white;
|
||||
margin-bottom: -24px;
|
||||
height: 2rem;
|
||||
line-height: 16px;
|
||||
margin: auto -1rem -1rem;
|
||||
}
|
||||
|
||||
.pt-015 {
|
||||
padding-top: 0.15rem;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -610,8 +370,6 @@ import svgGem from '@/assets/svg/gem.svg';
|
||||
import svgHourglasses from '@/assets/svg/hourglass.svg';
|
||||
import svgClock from '@/assets/svg/clock.svg';
|
||||
import svgWhiteClock from '@/assets/svg/clock-white.svg';
|
||||
import svgPositive from '@/assets/svg/positive.svg';
|
||||
import svgNegative from '@/assets/svg/negative.svg';
|
||||
|
||||
import BalanceInfo from './balanceInfo.vue';
|
||||
import PinBadge from '@/components/ui/pinBadge';
|
||||
@@ -619,7 +377,6 @@ import CountdownBanner from './countdownBanner';
|
||||
import currencyMixin from './_currencyMixin';
|
||||
import notifications from '@/mixins/notifications';
|
||||
import buyMixin from '@/mixins/buy';
|
||||
import numberIncrement from '@/components/shared/numberIncrement';
|
||||
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
@@ -650,17 +407,14 @@ export default {
|
||||
Avatar,
|
||||
PinBadge,
|
||||
CountdownBanner,
|
||||
numberIncrement,
|
||||
},
|
||||
mixins: [buyMixin, currencyMixin, notifications, numberInvalid, spellsMixin],
|
||||
props: {
|
||||
// eslint-disable-next-line vue/require-default-prop
|
||||
item: {
|
||||
type: Object,
|
||||
},
|
||||
priceType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
withPin: {
|
||||
type: Boolean,
|
||||
@@ -679,14 +433,10 @@ export default {
|
||||
hourglasses: svgHourglasses,
|
||||
clock: svgClock,
|
||||
whiteClock: svgWhiteClock,
|
||||
positive: svgPositive,
|
||||
negative: svgNegative,
|
||||
}),
|
||||
|
||||
selectedAmountToBuy: 1,
|
||||
selectedAmount: 1,
|
||||
isPinned: false,
|
||||
quantity: 1,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -724,11 +474,6 @@ export default {
|
||||
return planGemLimits.convCap
|
||||
+ this.user.purchased.plan.consecutive.gemCapExtra - this.user.purchased.plan.gemsBought;
|
||||
},
|
||||
totalGems () {
|
||||
if (!this.user.purchased.plan) return 0;
|
||||
return planGemLimits.convCap
|
||||
+ this.user.purchased.plan.consecutive.gemCapExtra;
|
||||
},
|
||||
attemptingToPurchaseMoreGemsThanAreLeft () {
|
||||
if (this.item && this.item.key && this.item.key === 'gem' && this.selectedAmountToBuy > this.gemsLeft) return true;
|
||||
return false;
|
||||
@@ -745,9 +490,6 @@ export default {
|
||||
endDate () {
|
||||
return moment(this.item.event.end);
|
||||
},
|
||||
totalOwned () {
|
||||
return this.user.items[this.item.purchaseType][this.item.key] || 0;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
item: function itemChanged () {
|
||||
@@ -758,9 +500,7 @@ export default {
|
||||
methods: {
|
||||
onChange ($event) {
|
||||
this.$emit('change', $event);
|
||||
this.selectedAmountToBuy = 1;
|
||||
},
|
||||
|
||||
buyItem () {
|
||||
// @TODO: I think we should buying to the items.
|
||||
// Turn the items into classes, and use polymorphism
|
||||
@@ -857,7 +597,6 @@ export default {
|
||||
}
|
||||
},
|
||||
hideDialog () {
|
||||
this.selectedAmountToBuy = 1;
|
||||
this.$root.$emit('bv::hide::modal', 'buy-modal');
|
||||
},
|
||||
getPriceClass () {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
.limitedTime {
|
||||
height: 32px;
|
||||
width: calc(100% + 30px);
|
||||
margin: 0 -15px; // the modal content has its own padding
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 1.33;
|
||||
text-align: center;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
:hide-header="true"
|
||||
@change="onChange($event)"
|
||||
>
|
||||
<div>
|
||||
<div class="close">
|
||||
<span
|
||||
class="svg-icon close-icon icon-16 color"
|
||||
class="svg-icon inline icon-10"
|
||||
aria-hidden="true"
|
||||
@click="hideDialog()"
|
||||
v-html="icons.close"
|
||||
@@ -14,73 +14,60 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="item"
|
||||
class="content bordered-item"
|
||||
class="content"
|
||||
>
|
||||
<div class="inner-content">
|
||||
<item
|
||||
class="flat bordered-item"
|
||||
class="flat"
|
||||
:item="item"
|
||||
:item-content-class="itemContextToSell.itemClass"
|
||||
:show-popover="false"
|
||||
/>
|
||||
<span class="owned">
|
||||
{{ $t('owned') }}: <span class="user-amount">{{ itemContextToSell.itemCount }}</span>
|
||||
</span>
|
||||
>
|
||||
<countBadge
|
||||
slot="itemBadge"
|
||||
:show="true"
|
||||
:count="itemContextToSell.itemCount"
|
||||
/>
|
||||
</item>
|
||||
<h4 class="title">
|
||||
{{ itemContextToSell.itemName }}
|
||||
</h4>
|
||||
<div v-if="item.key === 'Saddle'">
|
||||
<div class="item-notes">
|
||||
<div class="text">
|
||||
{{ item.sellWarningNote() }}
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<div class="item-notes">
|
||||
<div class="text">
|
||||
{{ item.notes() }}
|
||||
</div>
|
||||
<div class="item-cost">
|
||||
<span class="cost gold">
|
||||
<span
|
||||
class="svg-icon inline icon-24"
|
||||
aria-hidden="true"
|
||||
v-html="icons.gold"
|
||||
></span>
|
||||
<span>{{ item.value }}</span>
|
||||
</span>
|
||||
<div>
|
||||
<b class="how-many-to-sell">{{ $t('howManyToSell') }}</b>
|
||||
</div>
|
||||
<div>
|
||||
<span
|
||||
class="how-many-to-sell"
|
||||
>
|
||||
{{ $t('howManyToSell') }}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<number-increment
|
||||
@updateQuantity="selectedAmountToSell = $event"
|
||||
<b-input
|
||||
v-model="selectedAmountToSell"
|
||||
class="itemsToSell"
|
||||
type="number"
|
||||
:max="itemContextToSell.itemCount"
|
||||
min="1"
|
||||
step="1"
|
||||
@keyup.native="preventNegative($event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="total-row">
|
||||
<span class="total-text">
|
||||
{{ $t('sendTotal') }}
|
||||
</span>
|
||||
<span
|
||||
class="svg-icon total icon-24"
|
||||
class="svg-icon inline icon-32"
|
||||
aria-hidden="true"
|
||||
v-html="icons.gold"
|
||||
></span>
|
||||
<span class="total-text gold">
|
||||
{{ item.value * selectedAmountToSell }}
|
||||
</span>
|
||||
<span class="value">{{ item.value }}</span>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
:disabled="selectedAmountToSell > itemContextToSell.itemCount"
|
||||
@click="sellItems()"
|
||||
>
|
||||
{{ $t('sellItems') }}
|
||||
{{ $t('sell') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -90,10 +77,8 @@
|
||||
slot="modal-footer"
|
||||
class="clearfix"
|
||||
>
|
||||
<span class="user-balance float-left">{{ $t('yourBalance') }}</span>
|
||||
<balanceInfo
|
||||
class="float-right currency-totals"
|
||||
/>
|
||||
<span class="balance float-left">{{ $t('yourBalance') }}</span>
|
||||
<balanceInfo class="float-right" />
|
||||
</div>
|
||||
</b-modal>
|
||||
</template>
|
||||
@@ -110,13 +95,51 @@
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
width: 448px;
|
||||
width: 330px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
padding-bottom: 0px;
|
||||
.content {
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.inner-content {
|
||||
margin: 33px auto auto;
|
||||
width: 282px;
|
||||
}
|
||||
|
||||
span.svg-icon.inline.icon-32 {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
|
||||
margin-left: 24px;
|
||||
margin-right: 8px;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.value {
|
||||
width: 28px;
|
||||
height: 32px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: #df911e;
|
||||
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
button.btn.btn-primary {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.balance {
|
||||
width: 74px;
|
||||
height: 16px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
@@ -125,215 +148,29 @@
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
display: block;
|
||||
margin: 24px 0 0;
|
||||
padding: 16px 24px;
|
||||
align-content: center;
|
||||
|
||||
.user-balance {
|
||||
width: 150px;
|
||||
height: 16px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-100;
|
||||
margin-bottom: 16px;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.currency-totals {
|
||||
margin-right: -8px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.inner-content {
|
||||
margin: 33px auto auto;
|
||||
width: 282px;
|
||||
}
|
||||
|
||||
.owned {
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
background-color: $gray-600;
|
||||
padding: 8px 8px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
.how-many-to-sell {
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
width: 141px;
|
||||
margin-left: 71px;
|
||||
margin-top: -48px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
.user-amount {
|
||||
font-weight: normal !important;
|
||||
}
|
||||
}
|
||||
|
||||
.item-wrapper {
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
cursor: default;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
transform: scale(1.45, 1.45);
|
||||
top: -25px;
|
||||
left: 1px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: $gray-10;
|
||||
font-size: 1.25rem;
|
||||
margin-top: 26px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.item-notes {
|
||||
margin-top: 12px;
|
||||
line-height: 1.71;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
// for cost icon of a single item
|
||||
span.svg-icon.inline.icon-24 {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-right: 4px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
// for the total user cost
|
||||
span.svg-icon.total.icon-24 {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-left: 6px;
|
||||
margin-right: 8px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
span.svg-icon.icon-16 {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
color: $gray-200;
|
||||
stroke-width: 0px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $gray-100;
|
||||
}
|
||||
}
|
||||
|
||||
.item-cost {
|
||||
display: inline-flex;
|
||||
margin: 16px 0;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.cost {
|
||||
display: inline-block;
|
||||
font-family: sans-serif;
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
padding: 6px 20px;
|
||||
line-height: 1.4;
|
||||
border-radius: 20px;
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
background-color: rgba(255, 190, 93, 0.15);
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.how-many-to-sell {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
.number-increment {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.total-row {
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 16px;
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
}
|
||||
}
|
||||
|
||||
.total-text {
|
||||
color: $gray-50;
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.71;
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
}
|
||||
}
|
||||
|
||||
button.btn.btn-primary {
|
||||
margin-top: 16px;
|
||||
padding: 4px 16px;
|
||||
height: 32px;
|
||||
|
||||
&:focus {
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
.balance {
|
||||
width: 74px;
|
||||
height: 16px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import svgClose from '@/assets/svg/close.svg';
|
||||
import svgGold from '@/assets/svg/gold.svg';
|
||||
import svgGem from '@/assets/svg/gem.svg';
|
||||
import svgPositive from '@/assets/svg/positive.svg';
|
||||
import svgNegative from '@/assets/svg/negative.svg';
|
||||
|
||||
import BalanceInfo from '../balanceInfo.vue';
|
||||
import Item from '@/components/inventory/item';
|
||||
import numberIncrement from '@/components/shared/numberIncrement';
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BalanceInfo,
|
||||
Item,
|
||||
numberIncrement,
|
||||
CountBadge,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -344,8 +181,6 @@ export default {
|
||||
close: svgClose,
|
||||
gold: svgGold,
|
||||
gem: svgGem,
|
||||
svgPositive,
|
||||
svgNegative,
|
||||
}),
|
||||
};
|
||||
},
|
||||
@@ -376,10 +211,6 @@ export default {
|
||||
this.selectedAmountToSell = 0;
|
||||
}
|
||||
},
|
||||
maxOwned () {
|
||||
const maxOwned = this.itemContextToSell.itemCount;
|
||||
return maxOwned;
|
||||
},
|
||||
sellItems () {
|
||||
if (!Number.isInteger(Number(this.selectedAmountToSell))) {
|
||||
this.selectedAmountToSell = 0;
|
||||
|
||||
@@ -33,22 +33,6 @@
|
||||
v-if="!item.locked"
|
||||
class="purchase-amount"
|
||||
>
|
||||
<div class="item-cost">
|
||||
<span
|
||||
class="cost"
|
||||
:class="priceType"
|
||||
>
|
||||
<span
|
||||
class="svg-icon inline icon-24"
|
||||
aria-hidden="true"
|
||||
v-html="icons[priceType]"
|
||||
>
|
||||
</span>
|
||||
<span
|
||||
:class="priceType"
|
||||
>{{ item.value }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="how-many-to-buy">
|
||||
<strong>{{ $t('howManyToBuy') }}</strong>
|
||||
</div>
|
||||
@@ -58,25 +42,24 @@
|
||||
>
|
||||
{{ item.addlNotes }}
|
||||
</div>
|
||||
<div>
|
||||
<number-increment
|
||||
@updateQuantity="selectedAmountToBuy = $event"
|
||||
/>
|
||||
</div>
|
||||
<div class="total-row">
|
||||
<span class="total-text">
|
||||
{{ $t('sendTotal') }}
|
||||
</span>
|
||||
<span
|
||||
class="svg-icon inline icon-20"
|
||||
aria-hidden="true"
|
||||
v-html="currencyIcon"
|
||||
></span>
|
||||
<span
|
||||
class="total"
|
||||
:class="priceType"
|
||||
>{{ item.value * selectedAmountToBuy }}</span>
|
||||
<div class="box">
|
||||
<input
|
||||
v-model.number="selectedAmountToBuy"
|
||||
class="form-control"
|
||||
type="number"
|
||||
min="0"
|
||||
step="1"
|
||||
>
|
||||
</div>
|
||||
<span
|
||||
class="svg-icon inline icon-32"
|
||||
aria-hidden="true"
|
||||
v-html="currencyIcon"
|
||||
></span>
|
||||
<span
|
||||
class="value"
|
||||
:class="priceType"
|
||||
>{{ item.value }}</span>
|
||||
</div>
|
||||
<button
|
||||
v-if="priceType === 'gems'
|
||||
@@ -89,7 +72,7 @@
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-primary mb-4"
|
||||
class="btn btn-primary"
|
||||
:class="{'notEnough': !enoughCurrency(priceType, item.value * selectedAmountToBuy)}"
|
||||
:disabled="numberInvalid"
|
||||
@click="buyItem()"
|
||||
@@ -129,39 +112,6 @@
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
height: 48px;
|
||||
background-color: $gray-700;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
display: block;
|
||||
padding: 16px 24px;
|
||||
align-content: center;
|
||||
|
||||
.user-balance {
|
||||
width: 150px;
|
||||
height: 16px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-100;
|
||||
margin-bottom: 16px;
|
||||
margin-top: -4px;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.currency-totals {
|
||||
margin-right: -8px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
margin-top: 8%;
|
||||
width: 448px !important;
|
||||
@@ -179,13 +129,8 @@
|
||||
margin: 33px auto auto;
|
||||
}
|
||||
|
||||
.item-notes {
|
||||
height: 48px;
|
||||
margin-top: 8px;
|
||||
padding-left: 48.5px;
|
||||
padding-right: 48.5px;
|
||||
line-height: 1.71;
|
||||
font-size: 0.875rem;
|
||||
.modal-body {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.questInfo {
|
||||
@@ -207,14 +152,16 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
button.btn.btn-primary {
|
||||
margin-top: 14px;
|
||||
padding: 4px 16px;
|
||||
span.svg-icon.inline.icon-32 {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 2px solid black;
|
||||
}
|
||||
button.btn.btn-primary {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.balance {
|
||||
@@ -226,6 +173,19 @@
|
||||
color: $gray-200;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
height: 48px;
|
||||
background-color: $gray-700;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
display: block;
|
||||
padding: 1rem 1.5rem;
|
||||
|
||||
&> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notEnough {
|
||||
pointer-events: none;
|
||||
opacity: 0.55;
|
||||
@@ -238,108 +198,30 @@
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.item-cost {
|
||||
padding-bottom: 16px;
|
||||
.box {
|
||||
display: inline-block;
|
||||
width: 74px;
|
||||
height: 40px;
|
||||
border-radius: 2px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||
margin-right: 24px;
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.cost {
|
||||
height: 40px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
padding: 8px 20px 8px 20px;
|
||||
|
||||
&.gems {
|
||||
color: $green-10;
|
||||
background-color: rgba(36, 204, 143, 0.15);
|
||||
line-height: 1.4;
|
||||
margin: 0 0 0 -4px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
background-color: rgba(255, 190, 93, 0.15);
|
||||
line-height: 1.4;
|
||||
margin: 0 0 0 -4px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
color: $hourglass-color;
|
||||
background-color: rgba(41, 149, 205, 0.15);
|
||||
line-height: 1.4;
|
||||
margin: 0 0 0 -4px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.total-row {
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.total {
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 16px;
|
||||
|
||||
&.gems {
|
||||
color: $green-10;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
color: $hourglass-color;
|
||||
input::-webkit-contacts-auto-fill-button {
|
||||
visibility: hidden;
|
||||
display: none !important;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.total-text {
|
||||
color: $gray-50;
|
||||
font-weight: bold;
|
||||
font-size: 0.875rem;
|
||||
height: 24px;
|
||||
line-height: 1.71;
|
||||
padding-right: 4px;
|
||||
|
||||
&.gems {
|
||||
color: $green-10;
|
||||
}
|
||||
|
||||
&.gold {
|
||||
color: $yellow-5;
|
||||
}
|
||||
|
||||
&.hourglasses {
|
||||
color: $hourglass-color;
|
||||
}
|
||||
}
|
||||
|
||||
span.svg-icon.inline.icon-20 {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span.svg-icon.inline.icon-24 {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span.svg-icon.inline.icon-32 {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
.modal-dialog {
|
||||
max-width: 80%;
|
||||
@@ -352,10 +234,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- <style lang="scss" scoped>
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
.value {
|
||||
@@ -379,7 +260,7 @@
|
||||
color: $hourglass-color;
|
||||
}
|
||||
}
|
||||
</style> -->
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
@@ -391,8 +272,6 @@ import svgExperience from '@/assets/svg/experience.svg';
|
||||
import svgGem from '@/assets/svg/gem.svg';
|
||||
import svgGold from '@/assets/svg/gold.svg';
|
||||
import svgHourglasses from '@/assets/svg/hourglass.svg';
|
||||
import svgPositive from '@/assets/svg/positive.svg';
|
||||
import svgNegative from '@/assets/svg/negative.svg';
|
||||
|
||||
import BalanceInfo from '../balanceInfo.vue';
|
||||
import currencyMixin from '../_currencyMixin';
|
||||
@@ -401,7 +280,6 @@ import buyMixin from '@/mixins/buy';
|
||||
import numberInvalid from '@/mixins/numberInvalid';
|
||||
import PinBadge from '@/components/ui/pinBadge';
|
||||
import CountdownBanner from '../countdownBanner';
|
||||
import numberIncrement from '@/components/shared/numberIncrement';
|
||||
|
||||
import questDialogContent from './questDialogContent';
|
||||
import QuestRewards from './questRewards';
|
||||
@@ -415,7 +293,6 @@ export default {
|
||||
PinBadge,
|
||||
questDialogContent,
|
||||
CountdownBanner,
|
||||
numberIncrement,
|
||||
},
|
||||
mixins: [buyMixin, currencyMixin, notifications, numberInvalid],
|
||||
props: {
|
||||
@@ -424,7 +301,6 @@ export default {
|
||||
},
|
||||
priceType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
withPin: {
|
||||
type: Boolean,
|
||||
@@ -436,11 +312,9 @@ export default {
|
||||
clock: svgClock,
|
||||
close: svgClose,
|
||||
experience: svgExperience,
|
||||
gems: svgGem,
|
||||
gem: svgGem,
|
||||
gold: svgGold,
|
||||
hourglasses: svgHourglasses,
|
||||
positive: svgPositive,
|
||||
negative: svgNegative,
|
||||
hourglass: svgHourglasses,
|
||||
}),
|
||||
|
||||
isPinned: false,
|
||||
@@ -465,8 +339,8 @@ export default {
|
||||
},
|
||||
currencyIcon () {
|
||||
if (this.priceType === 'gold') return this.icons.gold;
|
||||
if (this.priceType === 'hourglasses') return this.icons.hourglasses;
|
||||
return this.icons.gems;
|
||||
if (this.priceType === 'hourglasses') return this.icons.hourglass;
|
||||
return this.icons.gem;
|
||||
},
|
||||
endDate () {
|
||||
return moment(this.item.event.end);
|
||||
|
||||
@@ -33,17 +33,17 @@
|
||||
|
||||
h3 {
|
||||
color: $gray-10;
|
||||
margin-bottom: 4pxrem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.quest-image {
|
||||
margin: 0 auto;
|
||||
margin-bottom: 16px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin: 16px 16px;
|
||||
margin-bottom: 1rem;
|
||||
overflow-y: auto;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@@ -54,10 +54,10 @@
|
||||
line-height: 1.71;
|
||||
color: $gray-50;
|
||||
text-align: center;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
::v-deep .user-label {
|
||||
font-size: 0.875rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,6 +177,9 @@ export default {
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
.quest-rewards {
|
||||
margin-left: -1rem;
|
||||
margin-right: -1rem;
|
||||
|
||||
background-color: $gray-700;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,13 @@
|
||||
<br>
|
||||
<p class="text-center">
|
||||
<button
|
||||
id="buttonClearBrowserData"
|
||||
class="btn btn-lg btn-danger"
|
||||
popover-trigger="mouseover"
|
||||
:popover="$t('localStorageClearExplanation')"
|
||||
@click="clearLocalStorage()"
|
||||
>
|
||||
{{ $t('localStorageClear') }}
|
||||
</button>
|
||||
<b-popover
|
||||
target="buttonClearBrowserData"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('localStorageClearExplanation')"
|
||||
/>
|
||||
</p>
|
||||
<br>
|
||||
<p v-html="$t('localStorageTryNext', localStorageTryNext) "></p>
|
||||
|
||||
@@ -521,12 +521,7 @@ export default {
|
||||
// Get Category Filter Labels
|
||||
this.typeFilters = getFilterLabels(this.type, this.challenge);
|
||||
// Set default filter for task column
|
||||
|
||||
if (this.challenge) {
|
||||
this.activateFilter(this.type);
|
||||
} else {
|
||||
this.activateFilter(this.type, this.user.preferences.tasks.activeFilter[this.type], true);
|
||||
}
|
||||
this.activateFilter(this.type);
|
||||
},
|
||||
mounted () {
|
||||
this.setColumnBackgroundVisibility();
|
||||
@@ -666,7 +661,7 @@ export default {
|
||||
taskSummary (task) {
|
||||
this.$emit('taskSummary', task);
|
||||
},
|
||||
activateFilter (type, filter = '', skipSave = false) {
|
||||
activateFilter (type, filter = '') {
|
||||
// Needs a separate API call as this data may not reside in store
|
||||
if (type === 'todo' && filter === 'complete2') {
|
||||
if (this.group && this.group._id) {
|
||||
@@ -682,16 +677,14 @@ export default {
|
||||
// as default filter for daily
|
||||
// and set the filter as 'due' only when the component first
|
||||
// loads and not on subsequent reloads.
|
||||
if (type === 'daily' && filter === '' && !this.challenge) {
|
||||
if (
|
||||
type === 'daily' && filter === '' && !this.challenge
|
||||
&& this.user.preferences.dailyDueDefaultView
|
||||
) {
|
||||
filter = 'due'; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
|
||||
this.activeFilter = getActiveFilter(type, filter, this.challenge);
|
||||
|
||||
if (!skipSave && !this.challenge) {
|
||||
const propertyToUpdate = `preferences.tasks.activeFilter.${type}`;
|
||||
this.$store.dispatch('user:set', { [propertyToUpdate]: filter });
|
||||
}
|
||||
},
|
||||
setColumnBackgroundVisibility () {
|
||||
this.$nextTick(() => {
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
'task-not-scoreable': showTaskLockIcon,
|
||||
}, controlClass.up.inner]"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
:aria-label="$t('scoreUp')"
|
||||
:aria-disabled="showTaskLockIcon || (!task.up && !showTaskLockIcon)"
|
||||
@click="score('up')"
|
||||
@keypress.enter="score('up')"
|
||||
>
|
||||
@@ -66,7 +63,6 @@
|
||||
controlClass.inner,
|
||||
]"
|
||||
tabindex="0"
|
||||
role="checkbox"
|
||||
@click="score(showCheckIcon ? 'down' : 'up' )"
|
||||
@keypress.enter="score(showCheckIcon ? 'down' : 'up' )"
|
||||
>
|
||||
@@ -245,7 +241,7 @@
|
||||
>
|
||||
<div
|
||||
v-b-tooltip.hover.bottom="$t('dueDate')"
|
||||
class="svg-icon calendar my-auto"
|
||||
class="svg-icon calendar"
|
||||
v-html="icons.calendar"
|
||||
></div>
|
||||
<span>{{ formatDueDate() }}</span>
|
||||
@@ -363,9 +359,6 @@
|
||||
'task-not-scoreable': showTaskLockIcon,
|
||||
}, controlClass.down.inner]"
|
||||
tabindex="0"
|
||||
role="button"
|
||||
:aria-label="$t('scoreDown')"
|
||||
:aria-disabled="showTaskLockIcon || (!task.down && !showTaskLockIcon)"
|
||||
@click="score('down')"
|
||||
@keypress.enter="score('down')"
|
||||
>
|
||||
@@ -708,7 +701,7 @@
|
||||
|
||||
.icons {
|
||||
margin-top: 4px;
|
||||
color: $gray-100;
|
||||
color: $gray-300;
|
||||
font-style: normal;
|
||||
|
||||
&-right {
|
||||
@@ -767,7 +760,7 @@
|
||||
}
|
||||
|
||||
.due-overdue {
|
||||
color: $maroon-10;
|
||||
color: $red-50;
|
||||
}
|
||||
|
||||
.calendar.svg-icon {
|
||||
@@ -906,7 +899,7 @@
|
||||
}
|
||||
</style>
|
||||
<!-- eslint-enable max-len -->
|
||||
<!-- eslint-disable-next-line vue/component-tags-order -->
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
@@ -1133,13 +1126,13 @@ export default {
|
||||
return moment.duration(endOfDueDate.diff(endOfToday));
|
||||
},
|
||||
checkIfOverdue () {
|
||||
return this.calculateTimeTillDue().asDays() < 0;
|
||||
return this.calculateTimeTillDue().asDays() <= 0;
|
||||
},
|
||||
formatDueDate () {
|
||||
if (moment().isSame(this.task.date, 'day')) {
|
||||
return this.$t('today');
|
||||
}
|
||||
return moment(this.task.date).format(this.user.preferences.dateFormat.toUpperCase());
|
||||
const timeTillDue = this.calculateTimeTillDue();
|
||||
const dueIn = timeTillDue.asDays() === 0 ? this.$t('today') : timeTillDue.humanize(true);
|
||||
|
||||
return this.task.date && this.$t('dueIn', { dueIn });
|
||||
},
|
||||
edit (e, task) {
|
||||
if (this.isRunningYesterdailies) return;
|
||||
|
||||
@@ -190,10 +190,14 @@
|
||||
class="col-12 col-md-6"
|
||||
>
|
||||
<div class="row col-12 stats-column">
|
||||
<div
|
||||
:id="`${stat}-information`"
|
||||
class="col-12 col-md-4 attribute-label"
|
||||
>
|
||||
<div class="col-12 col-md-4 attribute-label">
|
||||
<span
|
||||
class="hint"
|
||||
:popover-title="$t(statInfo.title)"
|
||||
popover-placement="right"
|
||||
:popover="$t(statInfo.popover)"
|
||||
popover-trigger="mouseenter"
|
||||
></span>
|
||||
<div
|
||||
class="stat-title"
|
||||
:class="stat"
|
||||
@@ -202,13 +206,6 @@
|
||||
</div>
|
||||
<strong class="number">{{ totalStatPoints(stat) | floorWholeNumber }}</strong>
|
||||
</div>
|
||||
<b-popover
|
||||
:target="`${stat}-information`"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t(statInfo.popover)"
|
||||
/>
|
||||
<div class="col-12 col-md-6">
|
||||
<ul class="bonus-stats">
|
||||
<li>
|
||||
@@ -358,7 +355,7 @@ export default {
|
||||
},
|
||||
|
||||
allocateStatsList: {
|
||||
str: { title: 'allocateStr', popover: 'strText', allocatepop: 'allocateStrPop' },
|
||||
str: { title: 'allocateStr', popover: 'strengthText', allocatepop: 'allocateStrPop' },
|
||||
int: { title: 'allocateInt', popover: 'intText', allocatepop: 'allocateIntPop' },
|
||||
con: { title: 'allocateCon', popover: 'conText', allocatepop: 'allocateConPop' },
|
||||
per: { title: 'allocatePer', popover: 'perText', allocatepop: 'allocatePerPop' },
|
||||
@@ -367,7 +364,7 @@ export default {
|
||||
stats: {
|
||||
str: {
|
||||
title: 'strength',
|
||||
popover: 'strText',
|
||||
popover: 'strengthText',
|
||||
},
|
||||
int: {
|
||||
title: 'intelligence',
|
||||
|
||||
@@ -146,19 +146,17 @@
|
||||
:key="stat"
|
||||
class="row"
|
||||
>
|
||||
<div
|
||||
class="col-4"
|
||||
:id="statInfo.title"
|
||||
>
|
||||
<strong> {{ $t(statInfo.title)}} </strong>
|
||||
<div class="col-4">
|
||||
<span
|
||||
class="hint"
|
||||
:popover-title="$t(statInfo.title)"
|
||||
popover-placement="right"
|
||||
:popover="$t(statInfo.popover)"
|
||||
popover-trigger="mouseenter"
|
||||
>
|
||||
<strong>{{ $t(statInfo.title) }}</strong>
|
||||
</span>
|
||||
<strong>: {{ statsComputed[stat] }}</strong>
|
||||
<b-popover
|
||||
:target="statInfo.title"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t(statInfo.popover)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ul class="bonus-stats">
|
||||
@@ -185,38 +183,27 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="user.stats.buffs.stealth"
|
||||
id="stealthBuff"
|
||||
>
|
||||
<div v-if="user.stats.buffs.stealth">
|
||||
<strong
|
||||
v-once
|
||||
class="hint"
|
||||
:popover-title="$t('stealth')"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('stealthNewDay')"
|
||||
>{{ $t('stealth') }}</strong>
|
||||
<strong>: {{ user.stats.buffs.stealth }} </strong>
|
||||
<b-popover
|
||||
target="stealthBuff"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('stealthNewDay')"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="user.stats.buffs.streaks"
|
||||
id="streaksFrozenBuff"
|
||||
>
|
||||
<div v-if="user.stats.buffs.streaks">
|
||||
<div>
|
||||
<strong>
|
||||
{{ $t('streaksFrozen') }}
|
||||
</strong>
|
||||
<b-popover
|
||||
target="streaksFrozenBuff"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('streaksFrozenText')"
|
||||
/>
|
||||
<strong
|
||||
class="hint"
|
||||
popover-title="$t('streaksFrozen')"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('streaksFrozenText')"
|
||||
></strong>
|
||||
{{ $t('streaksFrozen') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -250,27 +237,19 @@
|
||||
>
|
||||
{{ $t('noMoreAllocate') }}
|
||||
</p>
|
||||
<p
|
||||
v-if="user.stats.points || userLevel100Plus"
|
||||
id="pointAllocation"
|
||||
>
|
||||
<p v-if="user.stats.points || userLevel100Plus">
|
||||
<strong class="inline">{{ user.stats.points }} </strong>
|
||||
<strong> {{ $t('unallocated') }} </strong>
|
||||
<b-popover
|
||||
target="pointAllocation"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('levelPopover')"
|
||||
/>
|
||||
<strong
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('levelPopover')"
|
||||
>{{ $t('unallocated') }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<fieldset class="auto-allocate">
|
||||
<div
|
||||
id="preferenceAutomaticAllocation"
|
||||
class="checkbox"
|
||||
>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input
|
||||
v-model="user.preferences.automaticAllocation"
|
||||
@@ -280,24 +259,19 @@
|
||||
'preferences.allocationMode': 'taskbased'
|
||||
})"
|
||||
>
|
||||
<b-popover
|
||||
target="preferenceAutomaticAllocation"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('autoAllocationPop')"
|
||||
/>
|
||||
{{ $t('autoAllocation') }}
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('autoAllocationPop')"
|
||||
>{{ $t('autoAllocation') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<form
|
||||
v-if="user.preferences.automaticAllocation"
|
||||
style="margin-left:1em"
|
||||
>
|
||||
<div
|
||||
id="optionFlatAllocation"
|
||||
class="radio"
|
||||
>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input
|
||||
v-model="user.preferences.allocationMode"
|
||||
@@ -306,22 +280,15 @@
|
||||
value="flat"
|
||||
@change="set({'preferences.allocationMode': 'flat'})"
|
||||
>
|
||||
<span class="hint">
|
||||
{{ $t('evenAllocation') }}
|
||||
</span>
|
||||
<b-popover
|
||||
target="optionFlatAllocation"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('evenAllocationPop')"
|
||||
/>
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('evenAllocationPop')"
|
||||
>{{ $t('evenAllocation') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
id="optionClassAllocation"
|
||||
class="radio"
|
||||
>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input
|
||||
v-model="user.preferences.allocationMode"
|
||||
@@ -330,63 +297,47 @@
|
||||
value="classbased"
|
||||
@change="set({'preferences.allocationMode': 'classbased'})"
|
||||
>
|
||||
<span class="hint">
|
||||
{{ $t('classAllocation') }}
|
||||
</span>
|
||||
<b-popover
|
||||
target="optionClassAllocation"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('classAllocationPop')"
|
||||
/>
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('classAllocationPop')"
|
||||
>{{ $t('classAllocation') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
id="optionTaskAllocation"
|
||||
class="radio"
|
||||
>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input
|
||||
v-model="user.preferences.allocationMode"
|
||||
type="radio"
|
||||
name="allocationMode"
|
||||
value="classbased"
|
||||
value="taskbased"
|
||||
@change="set({'preferences.allocationMode': 'taskbased'})"
|
||||
>
|
||||
<span class="hint">
|
||||
{{ $t('taskAllocation') }}
|
||||
</span>
|
||||
<b-popover
|
||||
target="optionTaskAllocation"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('taskAllocationPop')"
|
||||
/>
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('taskAllocationPop')"
|
||||
>{{ $t('taskAllocation') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
<div
|
||||
v-if="user.preferences.automaticAllocation
|
||||
&& !(user.preferences.allocationMode === 'taskbased') && (user.stats.points > 0)"
|
||||
id="buttonDistributePoints"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary btn-xs"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t('distributePointsPop')"
|
||||
@click="allocateNow({})"
|
||||
>
|
||||
<span class="glyphicon glyphicon-download"></span>
|
||||
|
||||
{{ $t('distributePoints') }}
|
||||
</button>
|
||||
<b-popover
|
||||
target="buttonDistributePoints"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t('distributePointsPop')"
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@@ -395,35 +346,28 @@
|
||||
:key="stat"
|
||||
class="row"
|
||||
>
|
||||
<div
|
||||
:id="`${stat}-info`"
|
||||
class="col-8"
|
||||
>
|
||||
<div class="col-8">
|
||||
<span
|
||||
class="hint"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t(statInfo.popover)"
|
||||
></span>
|
||||
{{ $t(statInfo.title) + user.stats[stat] }}
|
||||
<b-popover
|
||||
:target="`${stat}-info`"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t(statInfo.popover)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="user.stats.points"
|
||||
:id="`${stat}-allocate`"
|
||||
class="col-4"
|
||||
@click="allocate(stat)"
|
||||
>
|
||||
<button class="btn btn-primary">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
popover-trigger="mouseenter"
|
||||
popover-placement="right"
|
||||
:popover="$t(statInfo.allocatepop)"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
<b-popover
|
||||
:target="`${stat}-allocate`"
|
||||
triggers="hover focus"
|
||||
placement="right"
|
||||
:prevent-overflow="false"
|
||||
:content="$t(statInfo.allocatePop)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
export default {
|
||||
computed: {
|
||||
numberInvalid () {
|
||||
const inputNumber = Number(this.selectedAmountToBuy);
|
||||
return inputNumber < 1
|
||||
|| !Number.isInteger(inputNumber);
|
||||
return this.selectedAmountToBuy < 1 || !Number.isInteger(this.selectedAmountToBuy);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -114,7 +114,7 @@ export default {
|
||||
this.castCancel();
|
||||
|
||||
// the selected member doesn't have the flags property which sets `cardReceived`
|
||||
if (spell.pinType !== 'card' && spell.bulk !== true) {
|
||||
if (spell.pinType !== 'card') {
|
||||
try {
|
||||
spell.cast(this.user, target, {});
|
||||
} catch (e) {
|
||||
|
||||
@@ -21,18 +21,6 @@ describe('Task Column', () => {
|
||||
getters: {
|
||||
'tasks:getFilteredTaskList': () => [],
|
||||
},
|
||||
|
||||
state: {
|
||||
user: {
|
||||
data: {
|
||||
preferences: {
|
||||
tasks: {
|
||||
activeFilter: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mocks,
|
||||
stubs,
|
||||
@@ -88,20 +76,7 @@ describe('Task Column', () => {
|
||||
'tasks:getFilteredTaskList': () => () => habits,
|
||||
};
|
||||
|
||||
const store = new Store({
|
||||
getters,
|
||||
state: {
|
||||
user: {
|
||||
data: {
|
||||
preferences: {
|
||||
tasks: {
|
||||
activeFilter: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
const store = new Store({ getters });
|
||||
|
||||
wrapper = makeWrapper({ store });
|
||||
});
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import moment from 'moment';
|
||||
|
||||
import Task from '@/components/tasks/task.vue';
|
||||
import Store from '@/libs/store';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Store);
|
||||
|
||||
describe('Task', () => {
|
||||
let wrapper;
|
||||
|
||||
function makeWrapper (additionalTaskData = {}, additionalUserData = {}) {
|
||||
return shallowMount(Task, {
|
||||
propsData: {
|
||||
task: {
|
||||
group: {},
|
||||
...additionalTaskData,
|
||||
},
|
||||
},
|
||||
store: {
|
||||
state: {
|
||||
user: {
|
||||
data: {
|
||||
preferences: {},
|
||||
...additionalUserData,
|
||||
},
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
'tasks:getTaskClasses': () => ({}),
|
||||
'tasks:canEdit': () => ({}),
|
||||
'tasks:canDelete': () => ({}),
|
||||
},
|
||||
},
|
||||
mocks: { $t: (key, params) => key + (params ? JSON.stringify(params) : '') },
|
||||
directives: { 'b-tooltip': {} },
|
||||
localVue,
|
||||
});
|
||||
}
|
||||
|
||||
it('returns a vue instance', () => {
|
||||
wrapper = makeWrapper();
|
||||
expect(wrapper.isVueInstance()).to.be.true;
|
||||
});
|
||||
|
||||
describe('Due date calculation', () => {
|
||||
let clock;
|
||||
|
||||
function setClockTo (time) {
|
||||
const now = moment(time);
|
||||
clock = sinon.useFakeTimers(now.toDate());
|
||||
return now;
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('formats due date to today if due today', () => {
|
||||
const now = setClockTo('2019-09-17T17:57:00+02:00');
|
||||
wrapper = makeWrapper({ date: now });
|
||||
|
||||
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"today"}');
|
||||
});
|
||||
|
||||
it('formats due date to tomorrow if due tomorrow', () => {
|
||||
const now = setClockTo('2012-06-12T14:17:28Z');
|
||||
wrapper = makeWrapper({ date: now.add(1, 'day') });
|
||||
|
||||
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"in a day"}');
|
||||
});
|
||||
|
||||
it('formats due date to 5 days if due in 5 days', () => {
|
||||
const now = setClockTo();
|
||||
wrapper = makeWrapper({ date: now.add(5, 'days') });
|
||||
|
||||
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"in 5 days"}');
|
||||
});
|
||||
|
||||
it('formats due date to tomorrow if today but before dayStart', () => {
|
||||
const now = setClockTo('2019-06-12T04:23:37+02:00');
|
||||
wrapper = makeWrapper({ date: now.add(8, 'hours') }, { preferences: { dayStart: 7 } });
|
||||
|
||||
expect(wrapper.vm.formatDueDate()).to.equal('dueIn{"dueIn":"in a day"}');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -147,8 +147,5 @@
|
||||
"achievementBoneToPickModalText": "لقد جمعت كل الحيوانات الأليفة الهيكلية المغامرة والكلاسيكية!",
|
||||
"achievementPlantParent": "والد النبات",
|
||||
"achievementPlantParentText": "فقست جميع الحيوانات الأليفة النباتية في الألوان القياسية: الصبار والتريلنج!",
|
||||
"achievementPlantParentModalText": "لقد جمعت كل الحيوانات الأليفة النباتية!",
|
||||
"achievementDinosaurDynastyModalText": "لقد جمعت جميع الطيور والديناسورات الأليفة!",
|
||||
"achievementDinosaurDynasty": "سلالة الديناصورات",
|
||||
"achievementDinosaurDynastyText": "لقد فقست جميع الألوان القياسية للطيور والديناسورات الأليفة: الصقر، البومة، الببغاء، الطاووس، البطريق، الديك، الزاحف المجنح، التي ريكس،الترايسيراتوبس، و الفيلوسيرابتور!"
|
||||
"achievementPlantParentModalText": "لقد جمعت كل الحيوانات الأليفة النباتية!"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"webFaqAnswer0": "First, you'll set up tasks that you want to do in your everyday life. Then, as you complete the tasks in real life and check them off, you'll earn Experience and Gold. Gold is used to buy equipment and some items, as well as custom rewards. Experience causes your character to level up and unlock content such as pets, skills, and quests! For more detail, check out a step-by-step overview of the game at [Help -> Overview for New Users](https://habitica.com/static/overview).",
|
||||
"faqQuestion1": "كيف أضيف مهماتي؟",
|
||||
"iosFaqAnswer1": "العادات الجيدة (تلك التي تحتوي على علامة \"+\") هي المهام التي يمكنك القيام بها عدة مرات في اليوم، مثل تناول الخضروات. العادات السيئة (تلك التي تحتوي على علامة \"-\") هي المهام التي يجب عليك تجنبها، مثل عض الأظافر. والعادات التي تحتوي على علامة \"+\" و \"-\" لديها خيار جيد وخيار سيئ، مثل استخدام الدرج بدلاً من المصعد.\n\nالعادات الجيدة تمنحك خبرة وذهب. والعادات السيئة تقلل من صحتك.\n\nالمهام اليومية هي المهام التي يجب عليك القيام بها كل يوم، مثل تنظيف أسنانك أو التحقق من بريدك الإلكتروني. يمكنك تعديل تواريخ المهام اليومية بالنقر لتحريرها. إذا تخطيت مهمة يومية محددة، فسيتلقى أفاتارك ضررًا خلال الليل. كن حذرًا من عدم إضافة العديد من المهام اليومية في وقت واحد!\n\nالمهام التي يجب القيام بها هي قائمة المهام الخاصة بك. إكمال المهام يمنحك الذهب والخبرة. لن تفقد أبدًا صحتك بسبب هذه المهام. يمكنك إضافة تاريخ استحقاق للمهام التي يجب القيام بها بالنقر لتحريرها.",
|
||||
"androidFaqAnswer1": "العادات الجيدة (تلك التي لديها +) هي المهام التي تقوم بها عدة مرات في اليوم، كأكل الخضروات مثلا. العادات السيئة (تلك التي لديها -) هي المهام التي يجب عليك تجنبها، كعض الأظافر مثلا. العادات التي لها + و لها خيار جيد وخيار سيء، كصعود الدرج مقابل ركوب المصعد. العادات الجيدة تجزيك بالنقات والذهب. العادات السيئة تطرح نقاط الحياة.\n\nاليوميات هي المهام التي يجب عليك القيام بها كل يوم، كتفريش أسنانك أو تفقد بريدك الإلكتروني. بإمكانك تحديد أيام أجل يومية بالنقر عليها لتحديثها. إذا تخطيت يومية أجلها اليوم، فستأخد شخصيتك الضرر الليلة. كن حذرا حتى لا تضيف الكثير من اليوميات مرة واحدة!\n\nالمهام هي قائمة المهام الخاصة بك. إكمال المهام يكسبك الذهب والنقاط. لا تفقد نقاط الحيات أبدا من المهام. يمكنك إضافة تاريخ أجل إلى المهام من خلال الضغط على \"تحديث\".",
|
||||
"androidFaqAnswer1": "Good Habits (the ones with a +) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a -) are tasks that you should avoid, like biting nails. Habits with a + and a - have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award experience and gold. Bad Habits subtract health.\n\n Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by tapping to edit it. If you skip a Daily that is due, your character will take damage overnight. Be careful not to add too many Dailies at once!\n\n To-Dos are your To-Do list. Completing a To-Do earns you gold and experience. You never lose health from To-Dos. You can add a due date to a To-Do by tapping to edit.",
|
||||
"webFaqAnswer1": "* Good Habits (the ones with a :heavy_plus_sign:) are tasks that you can do many times a day, such as eating vegetables. Bad Habits (the ones with a :heavy_minus_sign:) are tasks that you should avoid, like biting nails. Habits with a :heavy_plus_sign: and a :heavy_minus_sign: have a good choice and a bad choice, like taking the stairs vs. taking the elevator. Good Habits award Experience and Gold. Bad Habits subtract Health.\n* Dailies are tasks that you have to do every day, like brushing your teeth or checking your email. You can adjust the days that a Daily is due by clicking the pencil item to edit it. If you skip a Daily that is due, your avatar will take damage overnight. Be careful not to add too many Dailies at once!\n* To-Dos are your To-Do list. Completing a To-Do earns you Gold and Experience. You never lose Health from To-Dos. You can add a due date to a To-Do by clicking the pencil icon to edit.",
|
||||
"faqQuestion2": "ما هي أمثلة المهمات؟",
|
||||
"iosFaqAnswer2": "The wiki has four lists of sample tasks to use as inspiration:\n<br><br>\n * [Sample Habits](http://habitica.wikia.com/wiki/Sample_Habits)\n * [Sample Dailies](http://habitica.wikia.com/wiki/Sample_Dailies)\n * [Sample To-Dos](http://habitica.wikia.com/wiki/Sample_To-Dos)\n * [Sample Custom Rewards](http://habitica.wikia.com/wiki/Sample_Custom_Rewards)",
|
||||
@@ -54,6 +54,5 @@
|
||||
"webFaqAnswer12": "World Bosses are special monsters that appear in the Tavern. All active users are automatically battling the Boss, and their tasks and Skills will damage the Boss as usual. You can also be in a normal Quest at the same time. Your tasks and Skills will count towards both the World Boss and the Boss/Collection Quest in your party. A World Boss will never hurt you or your account in any way. Instead, it has a Rage Bar that fills when users skip Dailies. If its Rage bar fills, it will attack one of the Non-Player Characters around the site and their image will change. You can read more about [past World Bosses](http://habitica.wikia.com/wiki/World_Bosses) on the wiki.",
|
||||
"iosFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
|
||||
"androidFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
|
||||
"webFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](http://habitica.wikia.com/wiki/FAQ), come ask in the [Habitica Help guild](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! We're happy to help.",
|
||||
"general": "عام"
|
||||
"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,37 +1,8 @@
|
||||
{
|
||||
"achievement": "Дасягненьне",
|
||||
"onwards": "Наперад!",
|
||||
"levelup": "Дасягнуўшы сваіх мэтаў у рэальным жыцьці, вы павысілі свой узровень і цяпер цалкам вылечыліся!",
|
||||
"reachedLevel": "Вы Дасягнулі Ўзроўню <%= level %>",
|
||||
"achievementLostMasterclasser": "Завяршальнік Квестаў: Серый Masterclasser",
|
||||
"achievementLostMasterclasserText": "Выкананы ўсе шаснаццаць квестаў у Серыях Masterclasser і вырашана таямніца зьніклага Masterclasser!",
|
||||
"letsGetStarted": "Давайце пачнем!",
|
||||
"viewAchievements": "Паглядзець Дасягненьні",
|
||||
"onboardingProgress": "<%= percentage %>% прагрэс",
|
||||
"showAllAchievements": "Паказаць Усё <%= category %>",
|
||||
"onboardingComplete": "Вы выканалі вашыя уводныя заданьні!",
|
||||
"yourRewards": "Вашыя Ўзнагароды",
|
||||
"earnedAchievement": "Вы зарабілі дасягненьне!",
|
||||
"gettingStartedDesc": "Выканаўшы гэтыя ўступныя заданьні, вы заробіце <strong>5 Дасягненьняў</strong> і <strong class=\"gold-amount\">100 Золата</strong> калі скончыце!",
|
||||
"yourProgress": "Ваш Прагрэс",
|
||||
"onboardingCompleteDesc": "Вы зарабілі <strong>5 Дасягненьняў</strong> і <strong class=\"gold-amount\">100 Золата</strong> за выкананы сьпіс.",
|
||||
"onboardingCompleteDescSmall": "Калі вы хочаце яшчэ больш, праверце Дасягненьні і пачніце зьбіраць!",
|
||||
"foundNewItems": "Вы знайшлі новы прадмет!",
|
||||
"achievementJustAddWater": "Проста Дабаўце Вады",
|
||||
"hideAchievements": "Схаваць <%= category %>",
|
||||
"achievementMindOverMatterText": "Выкананы квест для гадаванцаў Камень, Склізь і Пража.",
|
||||
"foundNewItemsExplanation": "Выкананьне задачаў дае вам шанс знайсці прадметы, такія як Яйкі, Інкубацыйныя зельлі і корм для гадаванцаў.",
|
||||
"achievementLostMasterclasserModalText": "Вы выканалі ўсе шаснаццаць квестаў у Серыях Masterclasser і вырашылі таямніцу зьніклага Masterclasser!",
|
||||
"achievementMindOverMatter": "Розум Важней Матэрыі",
|
||||
"foundNewItemsCTA": "Адкрыйце свой інвентар і паспрабуйце скамбінаваць вашыя новыя інкубацыйныя зельлі зь яйкамі!",
|
||||
"achievementMindOverMatterModalText": "Вы выканалі квест для гадаванцаў Камень, Склізь і Пража!",
|
||||
"achievementBackToBasicsModalText": "Вы сабралі ўсіх Базавых Гадаванцаў!",
|
||||
"achievementDustDevil": "Пыльны Д'ябал",
|
||||
"achievementAllYourBaseModalText": "Вы прыручылі ўсіх Базавых Маўнтаў!",
|
||||
"achievementJustAddWaterText": "Выкананы квесты гадаванца Васьміног, Марскі Конік, Каракаціца, Кіт, Чарапаха, Марскі Смоўж, Марская Зьмяя і Дэльфін.",
|
||||
"achievementJustAddWaterModalText": "Вы выканалі квесты гадаванца Васьміног, Марскі Конік, Каракаціца, Кіт, Чарапаха, Марскі Смоўж, Марская Зьмяя і Дэльфін!",
|
||||
"achievementBackToBasics": "Вярнуцца да Асноваў",
|
||||
"achievementBackToBasicsText": "Сабраны ўсе Базавыя Гадаванцы.",
|
||||
"achievementAllYourBase": "Уся Вашая База",
|
||||
"achievementAllYourBaseText": "Прыручаны ўсе Базавыя Маўнты."
|
||||
"levelup": "By accomplishing your real life goals, you leveled up and are now fully healed!",
|
||||
"reachedLevel": "You Reached Level <%= level %>",
|
||||
"achievementLostMasterclasser": "Quest Completionist: Masterclasser Series",
|
||||
"achievementLostMasterclasserText": "Completed all sixteen quests in the Masterclasser Quest Series and solved the mystery of the Lost Masterclasser!"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"settings": "Налады",
|
||||
"language": "Мова",
|
||||
"settings": "Settings",
|
||||
"language": "Language",
|
||||
"americanEnglishGovern": "In the event of a discrepancy in the translations, the American English version governs.",
|
||||
"helpWithTranslation": "Would you like to help with the translation of Habitica? Great! Then visit <a href=\"/groups/guild/7732f64c-33ee-4cce-873c-fc28f147a6f7\">the Aspiring Linguists Guild</a>!",
|
||||
"stickyHeader": "Sticky header",
|
||||
|
||||
@@ -144,11 +144,5 @@
|
||||
"achievementBoneToPickText": "Hat alle klassischen und Quest-Skeletthaustiere ausgebrütet!",
|
||||
"achievementPolarProText": "Hat alle Standardfarben der Polar-Haustiere ausgebrütet: Bär, Fuchs, Pinguin, Wal und Wolf!",
|
||||
"achievementPolarPro": "Polar-Profi",
|
||||
"achievementPolarProModalText": "Du hast alle Polar-Haustiere gesammelt!",
|
||||
"achievementPlantParent": "Pflanzenzüchter",
|
||||
"achievementPlantParentModalText": "Du hast alle Pflanzen-Haustiere gesammelt!",
|
||||
"achievementPlantParentText": "Hat alle Standardfarben der Pflanzen-Haustiere ausgebrütet: Kaktus und Baumchen!",
|
||||
"achievementDinosaurDynastyText": "Hat alle Standardfarben der Vogel- und Dinosaurier-Haustiere ausgebrütet: Falke, Eule, Papagei, Pinguin, Hahn, Flugfinger, T-Rex, Triceratops, und Velociraptor!",
|
||||
"achievementDinosaurDynastyModalText": "Du hast alle Vogel- und Dinosaurier-Haustiere gesammelt!",
|
||||
"achievementDinosaurDynasty": "Dinosaurier Dynastie"
|
||||
"achievementPolarProModalText": "Du hast alle Polar-Haustiere gesammelt!"
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@
|
||||
"backgroundMysticalObservatoryNotes": "Deine Bestimmung steht in den Sternen; vom Mystischen Observatorium aus kannst Du sie lesen.",
|
||||
"backgroundMysticalObservatoryText": "Mystisches Observatorium",
|
||||
"backgrounds112020": "Set 78: Veröffentlicht im November 2020",
|
||||
"backgroundHolidayHearthNotes": "Entspanne, wärme und trockne deine Körperteile an einem Feierlichen Feuer.",
|
||||
"backgroundHolidayHearthNotes": "Entspanne, trockne und wärme Deine Glieder an einem Feierlichen Feuer.",
|
||||
"backgroundHolidayHearthText": "Feierliches Feuer",
|
||||
"backgroundInsideAnOrnamentNotes": "Lasse Deine Festtagsstimmung aus dem Inneren dieses Baumschmuckes erstrahlen.",
|
||||
"backgroundInsideAnOrnamentText": "Im Baumschmuck",
|
||||
@@ -756,43 +756,5 @@
|
||||
"backgroundSnowyTempleText": "Verschneiter Tempel",
|
||||
"backgroundSnowyTempleNotes": "Einen ruhigen verschneiten Tempel anschauen.",
|
||||
"backgroundSnowyVillageText": "Verschneites Dorf",
|
||||
"backgroundSnowyVillageNotes": "Ein verschneites Dorf bewundern.",
|
||||
"backgroundOldTimeyBasketballCourtText": "Altmodischer Basketballplatz",
|
||||
"backgroundOldTimeyBasketballCourtNotes": "Wirf Körbe auf einem altmodischen Basketballplatz.",
|
||||
"backgroundJungleWateringHoleText": "Dschungel-Wasserstelle",
|
||||
"backgroundJungleWateringHoleNotes": "Halte inne, um von der Dschungelwasserstelle zu trinken.",
|
||||
"backgroundMangroveForestText": "Mangrovenwald",
|
||||
"backgroundMangroveForestNotes": "Erkunde den Rand des Mangrovenwaldes.",
|
||||
"backgrounds052023": "Set 108: Veröffentlicht im Mai 2023",
|
||||
"backgroundInAPaintingText": "In einem Gemälde",
|
||||
"backgroundInAPaintingNotes": "Genieße die kreative Aktivität in einem Gemälde.",
|
||||
"backgroundFlyingOverHedgeMazeText": "Fliegen über Heckenlabyrinth",
|
||||
"backgroundFlyingOverHedgeMazeNotes": "Staune beim Fliegen über ein Heckenlabyrinth.",
|
||||
"backgroundCretaceousForestNotes": "Erlebe das uralte Grün eines Kreidewaldes.",
|
||||
"backgroundCretaceousForestText": "Kreidewald",
|
||||
"backgrounds042023": "Set 107: Veröffentlicht im April 2023",
|
||||
"backgroundLeafyTreeTunnelText": "Blättriger Baumtunnel",
|
||||
"backgroundSpringtimeShowerText": "Frühlingsschauer",
|
||||
"backgroundSpringtimeShowerNotes": "Sieh einen blühenden Frühlingsschauer.",
|
||||
"backgroundUnderWisteriaText": "Unter der Glyzinize",
|
||||
"backgroundUnderWisteriaNotes": "Entspanne unter der Glyzinie.",
|
||||
"backgroundInFrontOfFountainText": "Vor einem Sprinnbrunnen",
|
||||
"backgroundInFrontOfFountainNotes": "Schnlendere vor einem Springbrunnen.",
|
||||
"backgroundFancyBedroomText": "Schickes Schlafzimmer",
|
||||
"backgroundWinterLakeWithSwansNotes": "Genieße die Natur am winterlichen See mit Schwänen.",
|
||||
"backgroundWinterLakeWithSwansText": "winterlicher See mit Schwänen",
|
||||
"backgrounds062023": "Set 109: Veröffentlicht im Juni 2023",
|
||||
"backgroundInAnAquariumNotes": "Schwimme ein paar friedliche Runden mit den Fischen im Aquarium.",
|
||||
"backgroundInsideAdventurersHideoutText": "Das Versteck eines Abenteurers",
|
||||
"backgroundCraterLakeText": "Kratersee",
|
||||
"backgroundCraterLakeNotes": "Bewundere einen schönen Kratersee.",
|
||||
"backgroundInsideACrystalText": "In einem Kristall",
|
||||
"backgroundFancyBedroomNotes": "Schwelge in einem schicken Schlafzimmer.",
|
||||
"backgroundLeafyTreeTunnelNotes": "Wandere durch den bläätrigen Baumtunnel.",
|
||||
"backgroundInAnAquariumText": "In einem Aquarium",
|
||||
"backgroundInsideAdventurersHideoutNotes": "Plane eine Reise in ein Abenteurerversteck.",
|
||||
"backgroundBirthdayBashNotes": "Habitica feiert eine Geburtstagsparty und alle sind eingeladen!",
|
||||
"eventBackgrounds": "Ereignis-Hintergründe",
|
||||
"backgroundBirthdayBashText": "Geburtstagsparty",
|
||||
"backgroundInsideACrystalNotes": "Schaue aus einem Kristall hinaus."
|
||||
"backgroundSnowyVillageNotes": "Ein verschneites Dorf bewundern."
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
"commGuideHeadingWelcome": "Willkommen in Habitica!",
|
||||
"commGuidePara001": "Sei gegrüßt, Abenteurer! Willkommen in Habitica, dem Land der Produktivität, des gesunden Lebens und des gelegentlich randalierenden Greifs. Wir sind eine fröhliche Gemeinschaft voller hilfreicher Menschen, die sich auf ihrem Weg der persönlichen Entwicklung gegenseitig unterstützen. Alles was dazu gehört, ist eine positive Einstellung, ein respektvoller Umgang miteinander und etwas Verständnis dafür, dass jeder unterschiedliche Fähigkeiten und Grenzen hat - auch Du! Habiticaner gehen geduldig miteinander um und versuchen zu helfen, wo immer sie können.",
|
||||
"commGuidePara002": "Damit sich hier jeder sicher fühlen, glücklich und produktiv sein kann, gibt es ein paar Richtlinien. Wir haben uns große Mühe gegeben, sie möglichst nett und leicht verständlich zu formulieren. Bitte nimm Dir die Zeit, sie durchzulesen, bevor Du anfängst zu chatten.",
|
||||
"commGuidePara003": "Diese Regeln gelten an allen sozialen Orten, die wir verwenden, einschließlich (aber nicht nur) Trello, GitHub, Weblate und des Habitica Wiki auf Fandom. Wenn Gemeinschaften wachsen und sich verändern, können sich ihre Regeln von Zeit zu Zeit ändern. Bei wesentlichen Änderungen dieser Richtlinien wirst Du durch eine Bailey-Ankündigung und/oder in unseren sozialen Medien davon erfahren!",
|
||||
"commGuidePara003": "Diese Regeln gelten an allen sozialen Orten, die wir verwenden, bezogen (aber nicht unbedingt eingeschränkt) auf Trello, GitHub, Weblate und dem Habitica Wiki auf Fandom. Wenn Gemeinschaften wachsen und sich verändern, passen sich manchmal ihre Regeln von Zeit zu Zeit an. Wenn es wesentliche Änderungen dieser Richtlinien gibt, wirst Du dies durch eine Bailey-Ankündigung und/oder in unseren sozialen Medien hören!",
|
||||
"commGuideHeadingInteractions": "Interaktionen in Habitica",
|
||||
"commGuidePara015": "Habitica hat zwei Arten sozialer Orte: öffentliche und private. Öffentliche Orte sind die Taverne, öffentliche Gilden, GitHub, Trello und das Wiki. Private Orte sind private Gilden, der Partychat und private Nachrichten. Alle Anzeigenamen und @Usernamen müssen den Community-Richtlinien für öffentliche Orte entsprechen. Um Deinen Anzeigenamen oder @Usernamen zu ändern, wähle in der mobilen App Menü > Einstellungen > Profil. Und wähle auf der Webseite Benutzer Icon > Profil und klicke auf den \"Bearbeiten\"-Knopf.",
|
||||
"commGuidePara016": "Wenn Du Dich durch die öffentlichen Orte in Habitica bewegst, gibt es ein paar allgemeine Regeln, damit jeder sicher und glücklich ist.",
|
||||
"commGuideList02A": "<strong>Respektiert einander</strong>. Sei höflich, freundlich und hilfsbereit. Vergiss nicht: Habiticaner kommen aus den verschiedensten Hintergründen und haben sehr unterschiedliche Erfahrungen gemacht. Das macht Habitica so eigenartig! Es ist wichtig, dass man beim Aufbauen einer Community seine Unterschiede und Ähnlichkeiten respektieren, aber natürlich auch feiern kann.",
|
||||
"commGuideList02B": "<strong>Halte Dich an die <a href='/static/terms' target='_blank'>allgemeinen Geschäftsbedingungen</a></strong>, sowohl in öffentlichen als auch in privaten Bereichen.",
|
||||
"commGuideList02B": "<strong>Halte Dich an die <a href='/static/terms' target='_blank'>allgemeinen Geschäftsbedingungen</a></strong>, sowohl in öffentlichen als auch in privaten Umgebungen.",
|
||||
"commGuideList02C": "<strong>Poste keine Bilder oder Texte, die Gewalt darstellen, andere einschüchtern, oder eindeutig/indirekt sexuell sind, die Diskriminierung, Fanatismus, Rassismus, Sexismus, Hass, Belästigungen oder Hetze gegen jedwede Individuen oder Gruppen beinhalten.</strong> Auch nicht als Scherz oder Meme. Das bezieht sowohl Sprüche als auch Stellungnahmen mit ein. Nicht jeder hat den gleichen Humor, etwas, was Du als Witz wahrnimmst, kann für jemand anderen verletzend sein.",
|
||||
"commGuideList02D": "<strong>Halte die Diskussionen für alle Altersgruppen angemessen</strong>. Das heißt, Erwachsenenthemen in öffentlichen Bereichen zu vermeiden. Viele junge Habiticaner und Menschen mit verschiedenen Hintergründen nutzen diese Seite. Wir wollen unsere Gemeinschaft so angenehm und inklusiv wie möglich gestalten.",
|
||||
"commGuideList02E": "<strong>Vermeide vulgäre Ausdrücke. Dazu gehören auch mildere, religiöse Ausdrücke, die anderswo möglicherweise akzeptiert werden, oder verschleierte Schimpfwörter</strong>. Unter uns sind Menschen aus allen religiösen und kulturellen Hintergründen und wir wollen, dass sich alle im öffentlichen Raum wohl fühlen. <strong>Wenn Dir ein Moderator oder Mitarbeiter mitteilt, dass ein bestimmter Ausdruck in Habitica nicht erlaubt ist, selbst wenn er Dir vielleicht nicht problematisch vorkommt, ist diese Entscheidung endgültig</strong>. Zusätzlich werden verbale Angriffe jeder Art strenge Konsequenzen haben, da sie auch unsere Nutzungsbedingungen verletzen.",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -147,8 +147,5 @@
|
||||
"achievementPolarProModalText": "You collected all the Polar Pets!",
|
||||
"achievementPlantParent": "Plant Parent",
|
||||
"achievementPlantParentText": "Has hatched all standard colors of Plant pets: Cactus and Treeling!",
|
||||
"achievementPlantParentModalText": "You collected all the Plant Pets!",
|
||||
"achievementDinosaurDynasty": "Dinosaur Dynasty",
|
||||
"achievementDinosaurDynastyText": "Has hatched all standard colors of bird and dinosaur pets: Falcon, Owl, Parrot, Peacock, Penguin, Rooster, Pterodactyl, T-Rex, Triceratops, and Velociraptor!",
|
||||
"achievementDinosaurDynastyModalText": "You collected all the bird and dinosaur pets!"
|
||||
"achievementPlantParentModalText": "You collected all the Plant Pets!"
|
||||
}
|
||||
|
||||
@@ -883,22 +883,6 @@
|
||||
"backgroundCretaceousForestText": "Cretaceous Forest",
|
||||
"backgroundCretaceousForestNotes": "Take in the ancient greenery of a Cretaceous Forest.",
|
||||
|
||||
"backgrounds062023": "SET 109: Released June 2023",
|
||||
"backgroundInAnAquariumText": "In an Aquarium",
|
||||
"backgroundInAnAquariumNotes": "Take a peaceful swim with the fish In an Aquarium.",
|
||||
"backgroundInsideAdventurersHideoutText": "Inside an Adventurer's Hideout",
|
||||
"backgroundInsideAdventurersHideoutNotes": "Plan a journey inside an Adventurer's Hideout.",
|
||||
"backgroundCraterLakeText": "Crater Lake",
|
||||
"backgroundCraterLakeNotes": "Admire a lovely Crater Lake.",
|
||||
|
||||
"backgrounds072023": "SET 110: Released July 2023",
|
||||
"backgroundOnAPaddlewheelBoatText": "On a Paddlewheel Boat",
|
||||
"backgroundOnAPaddlewheelBoatNotes": "Ride on a Paddlewheel Boat.",
|
||||
"backgroundColorfulCoralText": "Colorful Coral",
|
||||
"backgroundColorfulCoralNotes": "Dive among Colorful Coral.",
|
||||
"backgroundBoardwalkIntoSunsetText": "Boardwalk into the Sunset",
|
||||
"backgroundBoardwalkIntoSunsetNotes": "Stroll on a Boardwalk into the Sunset.",
|
||||
|
||||
"timeTravelBackgrounds": "Steampunk Backgrounds",
|
||||
"backgroundAirshipText": "Airship",
|
||||
"backgroundAirshipNotes": "Become a sky sailor on board your very own Airship.",
|
||||
|
||||
@@ -150,8 +150,6 @@
|
||||
"youCastParty": "You cast <%= spell %> for the party.",
|
||||
"chatCastSpellParty": "<%= username %> casts <%= spell %> for the party.",
|
||||
"chatCastSpellUser": "<%= username %> casts <%= spell %> on <%= target %>.",
|
||||
"chatCastSpellPartyTimes": "<%= username %> casts <%= spell %> for the party <%= times %> times.",
|
||||
"chatCastSpellUserTimes": "<%= username %> casts <%= spell %> on <%= target %> <%= times %> times.",
|
||||
"critBonus": "Critical Hit! Bonus: ",
|
||||
"gainedGold": "You gained some Gold",
|
||||
"gainedMana": "You gained some Mana",
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
"webFaqAnswer8": "The blue bar that appeared when you hit level 10 and chose a Class is your Mana bar. As you continue to level up, you will unlock special Skills that cost Mana to use. Each Class has different Skills, which appear after level 11 in the action bar at the bottom of the screen. Unlike your Health bar, your Mana bar does not reset when you gain a level. Instead, Mana is gained when you complete good Habits, Dailies, and To Do's, and lost when you indulge bad Habits. You'll also regain some Mana overnight -- the more Dailies you completed, the more you will gain.",
|
||||
|
||||
"faqQuestion9": "How do I take on Quests?",
|
||||
"iosFaqAnswer9": "First, you need to join or start a Party by selecting \"Party\" in the navigation menu. Although you can take on Quests alone, we recommend playing with others to make the Quest faster and boost your motivation with extra accountability.\n\nOnce you’re in a Party, you can invite Party members to any Quest scrolls in your Inventory. After everyone accepts, the Quest will begin. To progress, complete your tasks as you normally would! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen your Party members do enough damage or collect all items, the Quest ends and everyone will receive their rewards!",
|
||||
"androidFaqAnswer9": "First, you need to join or start a Party by selecting \"Party\" in the navigation menu. Although you can take on Quests alone, we recommend playing with others to make the Quest faster and boost your motivation with extra accountability.\n\nOnce you’re in a Party, you can invite Party members to any Quest scrolls in your Inventory. After everyone accepts, the Quest will begin. To progress, complete your tasks as you normally would! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen your Party members do enough damage or collect all items, the Quest ends and everyone will receive their rewards!",
|
||||
"webFaqAnswer9": "First, you need to join or start a Party by selecting \"Party\" in the navigation menu. Although you can take on Quests alone, we recommend playing with others to make the Quest faster and boost your motivation with extra accountability.\n\nOnce you’re in a Party, you can invite Party members to any Quest scrolls in your Inventory. After everyone accepts, the Quest will begin. To progress, complete your tasks as you normally would! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen your Party members do enough damage or collect all items, the Quest ends and everyone will receive their rewards!",
|
||||
"iosFaqAnswer9": "First, you need to join or start a Party by selecting \"Party\" in the navigation. Although you can take on Quests alone, we recommend playing with others to make the Quest faster and boost your motivation with extra accountability.\n\nOnce you’re in a Party, you can invite Party members to any Quest scrolls in your Inventory. After everyone accepts, the Quest will begin. To progress, complete your tasks as you normally would! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen your Party members do enough damage or collect all items, the Quest ends and everyone will receive their rewards!",
|
||||
"androidFaqAnswer9": "First, you need to join or start a Party by selecting \"Party\" in the navigation. Although you can take on Quests alone, we recommend playing with others to make the Quest faster and boost your motivation with extra accountability.\n\nOnce you’re in a Party, you can invite Party members to any Quest scrolls in your Inventory. After everyone accepts, the Quest will begin. To progress, complete your tasks as you normally would! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen your Party members do enough damage or collect all items, the Quest ends and everyone will receive their rewards!",
|
||||
"webFaqAnswer9": "First, you need to join or start a Party by selecting \"Party\" in the navigation. Although you can take on Quests alone, we recommend playing with others to make the Quest faster and boost your motivation with extra accountability.\n\nOnce you’re in a Party, you can invite Party members to any Quest scrolls in your Inventory. After everyone accepts, the Quest will begin. To progress, complete your tasks as you normally would! You’ll either build up damage against a monster if you’re taking on a Boss Quest, or have a chance to find items if you’re taking on a Collection Quest. All pending progress is applied the next day.\n\nWhen your Party members do enough damage or collect all items, the Quest ends and everyone will receive their rewards!",
|
||||
|
||||
"faqQuestion10": "What are Gems, and how do I get them?",
|
||||
"iosFaqAnswer10": "Gems are purchased with real money from Menu > Purchase Gems. When you buy Gems, you are helping us to keep Habitica running. We’re very grateful for every bit of support!\n\n In addition to buying Gems directly, there are three other ways players can gain Gems:\n\n * Win a Challenge that has been set up by another player. Go to Menu > Challenges to join some.\n * Subscribe and unlock the ability to buy a certain number of Gems per month.\n * Contribute your skills to the Habitica project. See this wiki page for more details: [Contributing to Habitica](https://habitica.fandom.com/wiki/Contributing_to_Habitica).\n\n Keep in mind that items purchased with Gems do not offer any statistical advantages, so players can still make use of the app without them!",
|
||||
@@ -75,29 +75,29 @@
|
||||
"parties": "Parties",
|
||||
|
||||
"faqQuestion14": "How do I find a Party when I'm not in one?",
|
||||
"iosFaqAnswer14": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation menu, then choose the option that works for you.",
|
||||
"androidFaqAnswer14": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation menu, then choose the option that works for you.",
|
||||
"webFaqAnswer14": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation menu, then choose the option that works for you.",
|
||||
"iosFaqAnswer14": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation then choose the option that works for you.",
|
||||
"androidFaqAnswer14": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation then choose the option that works for you.",
|
||||
"webFaqAnswer14": "If you want to experience Habitica with others but don’t know other players, searching for a Party is your best option! If you already know other players that have a Party, you can share your @username with them to be invited. Alternatively, you can create a new Party and invite them with their @username or email address.\n\nTo create or search for a Party, select “Party” in the navigation then choose the option that works for you.",
|
||||
|
||||
"faqQuestion15": "How does searching for a Party work?",
|
||||
"iosFaqAnswer15": "After selecting “Look for a Party”, you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
"androidFaqAnswer15": "After selecting “Look for a Party”, you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
"webFaqAnswer15": "After selecting “Look for a Party”, you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
"iosFaqAnswer15": "After selecting “Look for a Party” in the Party pop-up, you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
"androidFaqAnswer15": "After selecting “Look for a Party” in the Party pop-up, you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
"webFaqAnswer15": "After selecting “Look for a Party” in the Party pop-up, you’ll be added to a list of players that want to join a Party. Party leaders can view this list and send invitations. Once you receive an invitation, you can accept it from your notifications to join the Party of your choosing!\n\nYou may get multiple invitations to different Parties. However, you can only be a member of one Party at a time.",
|
||||
|
||||
"faqQuestion16": "How long can I search for a Party after joining the list?",
|
||||
"iosFaqAnswer16": "You will remain in the list until you accept an invite to a Party or don’t login for 7 days, whichever comes first. If you log in after being inactive for 7 days, we’ll automatically add you back to the list as long as you don't have a pending invite.",
|
||||
"androidFaqAnswer16": "You will remain in the list until you accept an invite to a Party or don’t login for 7 days, whichever comes first. If you log in after being inactive for 7 days, we’ll automatically add you back to the list as long as you don't have a pending invite.",
|
||||
"webFaqAnswer16": "You will remain in the list until you accept an invite to a Party or don’t login for 7 days, whichever comes first. If you log in after being inactive for 7 days, we’ll automatically add you back to the list as long as you don't have a pending invite.",
|
||||
"iosFaqAnswer16": "You will remain in the list until you accept an invite to a Party or don’t login for 7 days, whichever comes first.",
|
||||
"androidFaqAnswer16": "You will remain in the list until you accept an invite to a Party or don’t login for 7 days, whichever comes first.",
|
||||
"webFaqAnswer16": "You will remain in the list until you accept an invite to a Party or don’t login for 7 days, whichever comes first.",
|
||||
|
||||
"faqQuestion17": "Can I stop searching for a Party?",
|
||||
"iosFaqAnswer17": "If you no longer want to find a Party, you can stop searching at any time.\n\nTo stop searching for a Party on Habitica’s website:\n\n1. Select the “Party” link in the navigation.\n2. Click “Leave” in the pop-up.\n\nTo stop searching for a Party on the Android app:\n1. Tap on “Party” from the menu.\n2. Tap “Leave” at the bottom of the screen.",
|
||||
"androidFaqAnswer17": "If you no longer want to find a Party, you can stop searching at any time.\n\nTo stop searching for a Party on Habitica’s website:\n\n1. Select the “Party” link in the navigation.\n2. Click “Leave” in the pop-up.\n\nTo stop searching for a Party on the Android app:\n1. Tap on “Party” from the menu.\n2. Tap “Leave” at the bottom of the screen.",
|
||||
"webFaqAnswer17": "If you no longer want to find a Party, you can stop searching at any time.\n\nTo stop searching for a Party on Habitica’s website:\n\n1. Select the “Party” link in the navigation.\n2. Click “Leave” in the pop-up.\n\nTo stop searching for a Party on the Android app:\n1. Tap on “Party” from the menu.\n2. Tap “Leave” at the bottom of the screen.",
|
||||
"iosFaqAnswer17": "You can leave the list at any time. To stop searching for Party on the website, select the “Party” link in the navigation then click “Leave” in the pop-up.",
|
||||
"androidFaqAnswer17": "You can leave the list at any time. To stop searching for Party on the website, select the “Party” link in the navigation then click “Leave” in the pop-up.",
|
||||
"webFaqAnswer17": "You can leave the list at any time. To stop searching for Party on the website, select the “Party” link in the navigation then click “Leave” in the pop-up.",
|
||||
|
||||
"faqQuestion18": "I have a Party, how do I find more members?",
|
||||
"iosFaqAnswer18": "If you are using Habitica’s website, select “Find Members” from the Party dropdown. If you’re using the Android app, tap “Find Members” above your Party’s member list. This will display a list of players that are actively looking for a Party and can be invited to join.\n\nTo help find a good fit for your Party, you'll see some information, such as language, class, level, and how many days they have used Habitica. If you’d like to chat with someone before sending an invite, you can view their Profile and send a message.",
|
||||
"androidFaqAnswer18": "If you are using Habitica’s website, select “Find Members” from the Party dropdown. If you’re using the Android app, tap “Find Members” above your Party’s member list. This will display a list of players that are actively looking for a Party and can be invited to join.\n\nTo help find a good fit for your Party, you'll see some information, such as language, class, level, and how many days they have used Habitica. If you’d like to chat with someone before sending an invite, you can view their Profile and send a message.",
|
||||
"webFaqAnswer18": "If you are using Habitica’s website, select “Find Members” from the Party dropdown. If you’re using the Android app, tap “Find Members” above your Party’s member list. This will display a list of players that are actively looking for a Party and can be invited to join.\n\nTo help find a good fit for your Party, you'll see some information, such as language, class, level, and how many days they have used Habitica. If you’d like to chat with someone before sending an invite, you can view their Profile and send a message.",
|
||||
"iosFaqAnswer18": "If you are using Habitica’s website, select “Find Members” from the Party dropdown. This will display a list of Habitica players that are actively looking for a Party and can be invited to join.\n\nYou'll see some information, such as language, class, level, and how many days they have used Habitica to help find a good fit for your Party. If you’d like to chat with someone before sending an invite, you can view their Profile and send a message.",
|
||||
"androidFaqAnswer18": "If you are using Habitica’s website, select “Find Members” from the Party dropdown. This will display a list of Habitica players that are actively looking for a Party and can be invited to join.\n\nYou'll see some information, such as language, class, level, and how many days they have used Habitica to help find a good fit for your Party. If you’d like to chat with someone before sending an invite, you can view their Profile and send a message.",
|
||||
"webFaqAnswer18": "If you are using Habitica’s website, select “Find Members” from the Party dropdown. This will display a list of Habitica players that are actively looking for a Party and can be invited to join.\n\nYou'll see some information, such as language, class, level, and how many days they have used Habitica to help find a good fit for your Party. If you’d like to chat with someone before sending an invite, you can view their Profile and send a message.",
|
||||
|
||||
"faqQuestion19": "How many members can I invite to my Party?",
|
||||
"iosFaqAnswer19": "Parties have a maximum limit of 30 members and a minimum of 1 member. Pending invites count towards the member count. For example, 29 members and 1 pending invite would count as 30 members. To clear a pending invite, the invited player must accept or decline, or the Party leader must cancel the invite.",
|
||||
@@ -105,19 +105,19 @@
|
||||
"webFaqAnswer19": "Parties have a maximum limit of 30 members and a minimum of 1 member. Pending invites count towards the member count. For example, 29 members and 1 pending invite would count as 30 members. To clear a pending invite, the invited player must accept or decline, or the Party leader must cancel the invite.",
|
||||
|
||||
"faqQuestion20": "Can I invite someone I already know?",
|
||||
"iosFaqAnswer20": "Yes! If you already have a Habitica player’s username or email address, you can invite them to join your Party. Here’s how to send an invite on the different platforms:\n\nOn Habitica’s website:\n\nNavigate to your Party and click “Invite to Party” on the right-hand side of the page.\n\nOn the Android app:\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Find Members” then tap the “By Invite” tab.\n\nOn the iOS app:\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Invite a Member”.",
|
||||
"androidFaqAnswer20": "Yes! If you already have a Habitica player’s username or email address, you can invite them to join your Party. Here’s how to send an invite on the different platforms:\n\nOn Habitica’s website:\n\nNavigate to your Party and click “Invite to Party” on the right-hand side of the page.\n\nOn the Android app:\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Find Members” then tap the “By Invite” tab.\n\nOn the iOS app:\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Invite a Member”.",
|
||||
"webFaqAnswer20": "Yes! If you already have a Habitica player’s username or email address, you can invite them to join your Party. Here’s how to send an invite on the different platforms:\n\nOn Habitica’s website:\n\nNavigate to your Party and click “Invite to Party” on the right-hand side of the page.\n\nOn the Android app:\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Find Members” then tap the “By Invite” tab.\n\nOn the iOS app:\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Invite a Member”.",
|
||||
"iosFaqAnswer20": "Yes! If you already have a Habitica player’s username or email address, you can invite them to join your Party. Here’s how to send an invite on the different platforms:\n\n## On Habitica’s website\n\nNavigate to your Party and click “Invite to Party” on the right-hand side of the page.\n\n## On iOS and Android\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Invite a Member”.",
|
||||
"androidFaqAnswer20": "Yes! If you already have a Habitica player’s username or email address, you can invite them to join your Party. Here’s how to send an invite on the different platforms:\n\n## On Habitica’s website\n\nNavigate to your Party and click “Invite to Party” on the right-hand side of the page.\n\n## On iOS and Android\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Invite a Member”.",
|
||||
"webFaqAnswer20": "Yes! If you already have a Habitica player’s username or email address, you can invite them to join your Party. Here’s how to send an invite on the different platforms:\n\n## On Habitica’s website\n\nNavigate to your Party and click “Invite to Party” on the right-hand side of the page.\n\n## On iOS and Android\n\nTap “Party” from the Menu. Scroll to the Members section and tap “Invite a Member”.",
|
||||
|
||||
"faqQuestion21": "How do I cancel a pending invitation to my Party?",
|
||||
"iosFaqAnswer21": "To cancel a pending invitation on Habitica’s website:\n\n1. Click on Member list when viewing your Party.\n2. Click the “Invites” tab.\n3. Click the three dots beside the user’s invite you wish to cancel.\n4. Choose “Cancel Invite”\n\nTo cancel a pending invitation on the Android app:\n\n1. Scroll down to your Member list when viewing your Party.\n2. At the bottom of the list, you’ll see your pending invites.\n3. Tap the “Cancel invitation” button.\n\nYou’ll be able to cancel a pending invitation from the iOS app soon as well!",
|
||||
"androidFaqAnswer21": "To cancel a pending invitation on Habitica’s website:\n\n1. Click on Member list when viewing your Party.\n2. Click the “Invites” tab.\n3. Click the three dots beside the user’s invite you wish to cancel.\n4. Choose “Cancel Invite”\n\nTo cancel a pending invitation on the Android app:\n\n1. Scroll down to your Member list when viewing your Party.\n2. At the bottom of the list, you’ll see your pending invites.\n3. Tap the “Cancel invitation” button.\n\nYou’ll be able to cancel a pending invitation from the iOS app soon as well!",
|
||||
"webFaqAnswer21": "To cancel a pending invitation on Habitica’s website:\n\n1. Click on Member list when viewing your Party.\n2. Click the “Invites” tab.\n3. Click the three dots beside the user’s invite you wish to cancel.\n4. Choose “Cancel Invite”\n\nTo cancel a pending invitation on the Android app:\n\n1. Scroll down to your Member list when viewing your Party.\n2. At the bottom of the list, you’ll see your pending invites.\n3. Tap the “Cancel invitation” button.\n\nYou’ll be able to cancel a pending invitation from the iOS app soon as well!",
|
||||
"iosFaqAnswer21": "To cancel a pending invitation on Habitica’s website:\n\n1. Click on Member list when viewing your Party\n\n2. Click the “Invites” tab\n\n3. Click the three dots beside the user’s invite you wish to cancel\n\n4. Choose “Cancel Invite”\n\n\n\nYou’ll be able to cancel a pending invitation from the mobile apps soon as well!",
|
||||
"androidFaqAnswer21": "To cancel a pending invitation on Habitica’s website:\n\n1. Click on Member list when viewing your Party\n\n2. Click the “Invites” tab\n\n3. Click the three dots beside the user’s invite you wish to cancel\n\n4. Choose “Cancel Invite”\n\n\n\nYou’ll be able to cancel a pending invitation from the mobile apps soon as well!",
|
||||
"webFaqAnswer21": "To cancel a pending invitation on Habitica’s website:\n\n1. Click on Member list when viewing your Party\n\n2. Click the “Invites” tab\n\n3. Click the three dots beside the user’s invite you wish to cancel\n\n4. Choose “Cancel Invite”\n\n\n\nYou’ll be able to cancel a pending invitation from the mobile apps soon as well!",
|
||||
|
||||
"faqQuestion22": "How do I stop unwanted invitations?",
|
||||
"iosFaqAnswer22": "Once you join a Party you’ll stop receiving any more invitations. If you want to prevent invites and future communications from a specific player, view their profile and click the Block button. On mobile profiles, tap the three dots in the top corner then select “Block”.\n\nIf you encounter a situation where you believe another player has broken our Community Guidelines in their name, profile, or a message they sent, please report any messages or reach out to us at admin@habitica.com.",
|
||||
"androidFaqAnswer22": "Once you join a Party you’ll stop receiving any more invitations. If you want to prevent invites and future communications from a specific player, view their profile and click the Block button. On mobile profiles, tap the three dots in the top corner then select “Block”.\n\nIf you encounter a situation where you believe another player has broken our Community Guidelines in their name, profile, or a message they sent, please report any messages or reach out to us at admin@habitica.com.",
|
||||
"webFaqAnswer22": "Once you join a Party you’ll stop receiving any more invitations. If you want to prevent invites and future communications from a specific player, view their profile and click the Block button. On mobile profiles, tap the three dots in the top corner then select “Block”.\n\nIf you encounter a situation where you believe another player has broken our Community Guidelines in their name, profile, or a message they sent, please report any messages or reach out to us at admin@habitica.com.",
|
||||
"iosFaqAnswer22": "Once you join a Party you’ll stop receiving any more invitations. If you want to prevent invites and future communications from a specific player, view their profile and click the Block button.\n\nIf you encounter a situation where you believe another player has broken our Community Guidelines in their name, profile, or a message they sent, please report any messages or reach out to us at admin@habitica.com.",
|
||||
"androidFaqAnswer22": "Once you join a Party you’ll stop receiving any more invitations. If you want to prevent invites and future communications from a specific player, view their profile and click the Block button.\n\nIf you encounter a situation where you believe another player has broken our Community Guidelines in their name, profile, or a message they sent, please report any messages or reach out to us at admin@habitica.com.",
|
||||
"webFaqAnswer22": "Once you join a Party you’ll stop receiving any more invitations. If you want to prevent invites and future communications from a specific player, view their profile and click the Block button.\n\nIf you encounter a situation where you believe another player has broken our Community Guidelines in their name, profile, or a message they sent, please report any messages or reach out to us at admin@habitica.com.",
|
||||
|
||||
"faqQuestion23": "How do I filter the list of members searching for a Party?",
|
||||
"iosFaqAnswer23": "At the moment there is no way to filter the list of members searching for a Party. However, we have plans to introduce filters in the future, such as class, level, and language.",
|
||||
@@ -125,9 +125,9 @@
|
||||
"webFaqAnswer23": "At the moment there is no way to filter the list of members searching for a Party. However, we have plans to introduce filters in the future, such as class, level, and language.",
|
||||
|
||||
"faqQuestion24": "How do I search for a Party on Android or iOS?",
|
||||
"iosFaqAnswer24": "We added the ability to look for a Party and find Party members in Android version 4.2! Be sure you’re updated to the latest version to check it out. Solo players can look for a Party from the Party screen when they aren’t in one. Party leaders can browse the list of players looking for an invite by tapping “Find Members” above their Party’s member list.\n\nSupport for the feature is coming to iOS in version 3.8, so keep an eye out soon!",
|
||||
"androidFaqAnswer24": "We added the ability to look for a Party and find Party members in Android version 4.2! Be sure you’re updated to the latest version to check it out. Solo players can look for a Party from the Party screen when they aren’t in one. Party leaders can browse the list of players looking for an invite by tapping “Find Members” above their Party’s member list.\n\nSupport for the feature is coming to iOS in version 3.8, so keep an eye out soon!",
|
||||
"webFaqAnswer24": "We added the ability to look for a Party and find Party members in Android version 4.2! Be sure you’re updated to the latest version to check it out. Solo players can look for a Party from the Party screen when they aren’t in one. Party leaders can browse the list of players looking for an invite by tapping “Find Members” above their Party’s member list.\n\nSupport for the feature is coming to iOS in version 3.8, so keep an eye out soon!",
|
||||
"iosFaqAnswer24": "We’re working on adding the ability to search for a Party and find Party members on mobile soon! Keep an eye out for Android version 4.2 and iOS version 3.8.",
|
||||
"androidFaqAnswer24": "We’re working on adding the ability to search for a Party and find Party members on mobile soon! Keep an eye out for Android version 4.2 and iOS version 3.8.",
|
||||
"webFaqAnswer24": "We’re working on adding the ability to search for a Party and find Party members on mobile soon! Keep an eye out for Android version 4.2 and iOS version 3.8.",
|
||||
|
||||
"iosFaqStillNeedHelp": "If you have a question that isn't on this list or on the [Wiki FAQ](https://habitica.fandom.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](https://habitica.fandom.com/wiki/FAQ), come ask in the Tavern chat under Menu > Tavern! We're happy to help.",
|
||||
|
||||
@@ -477,15 +477,6 @@
|
||||
"weaponSpecialSpring2023HealerText": "Lilium Pollen",
|
||||
"weaponSpecialSpring2023HealerNotes": "With a puff and a sparkle, you deploy new growth, joy, and color. Increases Intelligence by <%= int %>. Limited Edition 2023 Spring Gear.",
|
||||
|
||||
"weaponSpecialSummer2023RogueText": "Guppy Fan",
|
||||
"weaponSpecialSummer2023RogueNotes": "No gup, these things are tricky to learn. But impressive when you do! Increases Strength by <%= str %>. Limited Edition 2023 Summer Gear.",
|
||||
"weaponSpecialSummer2023WarriorText": "Water Elemental Sword",
|
||||
"weaponSpecialSummer2023WarriorNotes": "Summon powerful sprays of water to clear your path of obstacles. Increases Strength by <%= str %>. Limited Edition 2023 Summer Gear.",
|
||||
"weaponSpecialSummer2023MageText": "Fish",
|
||||
"weaponSpecialSummer2023MageNotes": "These friendly fish will stay by your side as the best accountability buddies in the ocean. Increases Intelligence by <%= int %>. Limited Edition 2023 Summer Gear.",
|
||||
"weaponSpecialSummer2023HealerText": "Swaying Kelp",
|
||||
"weaponSpecialSummer2023HealerNotes": "They may look frondly, but they get quite grumpy if you call them 'plants'. Increases Intelligence by <%= int %>. Limited Edition 2023 Summer Gear.",
|
||||
|
||||
"weaponMystery201411Text": "Pitchfork of Feasting",
|
||||
"weaponMystery201411Notes": "Stab your enemies or dig in to your favorite foods - this versatile pitchfork does it all! Confers no benefit. November 2014 Subscriber Item.",
|
||||
"weaponMystery201502Text": "Shimmery Winged Staff of Love and Also Truth",
|
||||
@@ -515,9 +506,7 @@
|
||||
"weaponMystery202211Text": "Electromancer Staff",
|
||||
"weaponMystery202211Notes": "Harness the awesome power of a lightning storm with this staff. Confers no benefit. November 2022 Subscriber Item.",
|
||||
"weaponMystery202212Text": "Glacial Wand",
|
||||
"weaponMystery202212Notes": "The glowing snowflake in this wand holds the power to warm hearts on even the coldest winter night! Confers no benefit. December 2022 Subscriber Item.",
|
||||
"weaponMystery202306Text": "Rainbow Umbrella",
|
||||
"weaponMystery202306Notes": "Shine proud and bring a shimmering prism of color wherever you go! Confers no benefit. June 2023 Subscriber Item.",
|
||||
"weaponMystery202212Notes": "The glowing snowflake in this wand holds the power to warm hearts on even the coldest winter night! Confers no benefit. December 2022 Subscriber Item.",
|
||||
"weaponMystery301404Text": "Steampunk Cane",
|
||||
"weaponMystery301404Notes": "Excellent for taking a turn about town. March 3015 Subscriber Item. Confers no benefit.",
|
||||
|
||||
@@ -1162,15 +1151,6 @@
|
||||
"armorSpecialSpring2023HealerText": "Lily Leaf Gown",
|
||||
"armorSpecialSpring2023HealerNotes": "A sweep of verdant glory to make you the envy of the Party. Increases Constitution by <%= con %>. Limited Edition 2023 Spring Gear.",
|
||||
|
||||
"armorSpecialSummer2023RogueText": "Guppy Wrap",
|
||||
"armorSpecialSummer2023RogueNotes": "Gup top! Down low! Too slow... Increases Perception by <%= per %>. Limited Edition 2023 Summer Gear.",
|
||||
"armorSpecialSummer2023WarriorText": "Goldfish Armor",
|
||||
"armorSpecialSummer2023WarriorNotes": "Goldfish Warriors actually have excellent memories because they always keep their Dailies and To Do's organized in lists. Increases Constitution by <%= con %>. Limited Edition 2023 Summer Gear.",
|
||||
"armorSpecialSummer2023MageText": "Coral Robes",
|
||||
"armorSpecialSummer2023MageNotes": "Feel protected and comfortable in these flowing robes, perfectly colored for underwater adventures. Increases Intelligence by <%= int %>. Limited Edition 2023 Summer Gear.",
|
||||
"armorSpecialSummer2023HealerText": "Kelp Kirtle",
|
||||
"armorSpecialSummer2023HealerNotes": "Hold fast to your goals and convictions in this elegant green gown. Increases Constitution by <%= con %>. Limited Edition 2023 Summer Gear.",
|
||||
|
||||
"armorMystery201402Text": "Messenger Robes",
|
||||
"armorMystery201402Notes": "Shimmering and strong, these robes have many pockets to carry letters. Confers no benefit. February 2014 Subscriber Item.",
|
||||
"armorMystery201403Text": "Forest Walker Armor",
|
||||
@@ -1287,10 +1267,6 @@
|
||||
"armorMystery202212Notes": "The universe can be cold, but this charming dress will keep you cozy as you fly. Confers no benefit. December 2022 Subscriber Item.",
|
||||
"armorMystery202304Text": "Tiptop Teapot Armor",
|
||||
"armorMystery202304Notes": "Here is your handle and here is your spout! Confers no benefit. April 2023 Subscriber Item.",
|
||||
"armorMystery202306Text": "Rainbow Parka",
|
||||
"armorMystery202306Notes": "No one’s going to rain on your parade! And if they try, you’ll stay colorful and dry! Confers no benefit. June 2023 Subscriber Item.",
|
||||
"armorMystery202307Text": "Kraken's Tentacles",
|
||||
"armorMystery202307Notes": "Suction cups have the best traction on the sea floor and on the sides of wayward ships. Confers no benefit. July 2023 Subscriber Item.",
|
||||
|
||||
"armorMystery301404Text": "Steampunk Suit",
|
||||
"armorMystery301404Notes": "Dapper and dashing, wot! Confers no benefit. February 3015 Subscriber Item.",
|
||||
@@ -1481,12 +1457,6 @@
|
||||
"armorArmoireBasketballUniformNotes": "Wondering what’s printed on the back of this uniform? It’s your lucky number, of course! Increases Perception by <% per %>. Enchanted Armoire: Old Timey Basketball Set (Item 1 of 2).",
|
||||
"armorArmoirePaintersApronText": "Painter's Apron",
|
||||
"armorArmoirePaintersApronNotes": "This apron can protect your clothes from paint and your creative projects from harsh critiques. Increases Constitution by <%= con %>. Enchanted Armoire: Painter Set (Item 1 of 4).",
|
||||
"armorArmoireStripedRainbowShirtText": "Striped Rainbow Shirt",
|
||||
"armorArmoireStripedRainbowShirtNotes": "The colors of the rainbow have never looked so good before. Be bold! Increases Strength and Intelligence by <%= attrs %> each. Enchanted Armoire: Rainbow Set (Item 1 of 2).",
|
||||
"armorArmoireDiagonalRainbowShirtText": "Diagonal Rainbow Shirt",
|
||||
"armorArmoireDiagonalRainbowShirtNotes": "A splash of color with a dash of style. Be joyful! Increases Constitution and Perception by <%= attrs %> each. Enchanted Armoire: Rainbow Set (Item 2 of 2).",
|
||||
"armorArmoireAdmiralsUniformText": "Admiral's Uniform",
|
||||
"armorArmoireAdmiralsUniformNotes": "We salute you! This naval uniform signals that you’re ready to take command of your tasks as well as a ship. Increases Constitution and Strength by <%= attrs %> each. Enchanted Armoire: Admiral’s Set (Item 2 of 2).",
|
||||
|
||||
"headgear": "helm",
|
||||
"headgearCapitalized": "Headgear",
|
||||
@@ -1937,15 +1907,6 @@
|
||||
"headSpecialSpring2023HealerText": "Lily Bloom",
|
||||
"headSpecialSpring2023HealerNotes": "This brilliant and colorful display shares a color scheme with the Orb of Rebirth! How symbolic! Increases Intelligence by <%= int %>. Limited Edition 2023 Spring Gear.",
|
||||
|
||||
"headSpecialSummer2023RogueText": "Guppy Cap",
|
||||
"headSpecialSummer2023RogueNotes": "Gup, two, three, four! Can't get eaten, got tasks to score! Increases Perception by <%= per %>. Limited Edition 2023 Summer Gear.",
|
||||
"headSpecialSummer2023WarriorText": "Goldfish Fin",
|
||||
"headSpecialSummer2023WarriorNotes": "This fabulous fin provides stability as you swim toward troublesome tasks ahead of you. Increases Strength by <%= str %>. Limited Edition 2023 Summer Gear.",
|
||||
"headSpecialSummer2023MageText": "Coral Antlers",
|
||||
"headSpecialSummer2023MageNotes": "The wisdom of an entire ecosystem is with you when you work your marine magic. Increases Perception by <%= per %>. Limited Edition 2023 Summer Gear.",
|
||||
"headSpecialSummer2023HealerText": "Kelp Crown",
|
||||
"headSpecialSummer2023HealerNotes": "They're not snakes! You can open your eyes, it's safe! Increases Intelligence by <%= int %>. Limited Edition 2023 Summer Gear.",
|
||||
|
||||
"headSpecialGaymerxText": "Rainbow Warrior Helm",
|
||||
"headSpecialGaymerxNotes": "In celebration of the GaymerX Conference, this special helmet is decorated with a radiant, colorful rainbow pattern! GaymerX is a game convention celebrating LGTBQ and gaming and is open to everyone.",
|
||||
|
||||
@@ -2095,8 +2056,6 @@
|
||||
"headMystery202303Notes": "What better way to let everyone know you’re the star of this tale than to have blue and improbably spiky hair? Confers no benefit. March 2023 Subscriber Item.",
|
||||
"headMystery202304Text": "Tiptop Teapot Lid",
|
||||
"headMystery202304Notes": "Wear this helm for your own safe-tea. Confers no benefit. April 2023 Subscriber Item.",
|
||||
"headMystery202308Text": "Purple Protagonist Hair",
|
||||
"headMystery202308Notes": "Does the unruly cowlick sticking up from the middle of your head represent your persistence or your penchant for mischief? Confers no benefit. August 2023 Subscriber Item.",
|
||||
|
||||
"headMystery301404Text": "Fancy Top Hat",
|
||||
"headMystery301404Notes": "A fancy top hat for the finest of gentlefolk! January 3015 Subscriber Item. Confers no benefit.",
|
||||
@@ -2278,9 +2237,7 @@
|
||||
"headArmoireBeaniePropellerHatText": "Beanie Propeller Hat",
|
||||
"headArmoireBeaniePropellerHatNotes": "This isn’t the time to keep your feet on the ground! Spin this little propeller and rise as high as your ambitions will take you. Increases all stats by <%= attrs %>. Enchanted Armoire: Independent Item.",
|
||||
"headArmoirePaintersBeretText": "Painter's Beret",
|
||||
"headArmoirePaintersBeretNotes": "See the world with a more artistic eye when you wear this jaunty beret. Increases Perception by <%= per %>. Enchanted Armoire: Painter Set (Item 2 of 4).",
|
||||
"headArmoireAdmiralsBicorneText": "Admiral's Bicorne Hat",
|
||||
"headArmoireAdmiralsBicorneNotes": "Hats off to you! Wearing this two-cornered hat will make you wiser, brighter, braver...and taller. Increases Intelligence and Perception by <%= attrs %> each. Enchanted Armoire: Admiral’s Set (Item 1 of 2).",
|
||||
"headArmoirePaintersBeretNotes": "See the world with a more artistic eye when you wear this jaunty beret. Increases Perception by <%= per %>. Enchanted Armoire: Painter Set (Item 2 of 4).",
|
||||
|
||||
"offhand": "off-hand item",
|
||||
"offHandCapitalized": "Off-Hand Item",
|
||||
@@ -2533,11 +2490,6 @@
|
||||
"shieldSpecialSpring2023HealerText": "Lily Corsage",
|
||||
"shieldSpecialSpring2023HealerNotes": "An accent for a healing visit, or part of a ritual for attending a springtime dance! Increases Constitution by <%= con %>. Limited Edition 2023 Spring Gear.",
|
||||
|
||||
"shieldSpecialSummer2023WarriorText": "Goldfish Spirit",
|
||||
"shieldSpecialSummer2023WarriorNotes": "Summon this goldfish spirit for an extra burst of reassurance and companionship during a fight. Increases Constitution by <%= con %>. Limited Edition 2023 Summer Gear.",
|
||||
"shieldSpecialSummer2023HealerText": "Sea Urchin",
|
||||
"shieldSpecialSummer2023HealerNotes": "You conceal and shelter it. It dissuades nosy monsters from coming too close. Perfect symbiosis! Increases Constitution by <%= con %>. Limited Edition 2023 Summer Gear.",
|
||||
|
||||
"shieldMystery201601Text": "Resolution Slayer",
|
||||
"shieldMystery201601Notes": "This blade can be used to parry away all distractions. Confers no benefit. January 2016 Subscriber Item.",
|
||||
"shieldMystery201701Text": "Time-Freezer Shield",
|
||||
@@ -2988,9 +2940,6 @@
|
||||
"headAccessoryMystery202302Notes": "The purr-fect accessory to set off your enchanting grin. Confers no benefit. February 2023 Subscriber Item.",
|
||||
"headAccessoryMystery202305Text": "Eventide Horns",
|
||||
"headAccessoryMystery202305Notes": "These horns glow with reflected moonlight. Confers no benefit. May 2023 Subscriber Item.",
|
||||
"headAccessoryMystery202307Text": "Kraken's Crown",
|
||||
"headAccessoryMystery202307Notes": "This mighty circlet summons cyclones and stormy weather! Confers no benefit. July 2023 Subscriber Item.",
|
||||
|
||||
"headAccessoryMystery301405Text": "Headwear Goggles",
|
||||
"headAccessoryMystery301405Notes": "\"Goggles are for your eyes,\" they said. \"Nobody wants goggles that you can only wear on your head,\" they said. Hah! You sure showed them! Confers no benefit. August 3015 Subscriber Item.",
|
||||
|
||||
@@ -3081,8 +3030,6 @@
|
||||
"eyewearMystery202208Notes": "Lull your enemies into a false sense of security with these terrifyingly cute peepers. Confers no benefit. August 2022 Subscriber Item.",
|
||||
"eyewearMystery202303Text": "Dreamy Eyes",
|
||||
"eyewearMystery202303Notes": "Let your nonchalant expression lure your enemies into a false sense of security. Confers no benefit. March 2023 Subscriber Item.",
|
||||
"eyewearMystery202308Text": "Sleepy Eyes",
|
||||
"eyewearMystery202308Notes": "Are you sleepy, or just resting your eyes in anticipation of your next amazing battle? Confers no benefit. August 2023 Subscriber Item.",
|
||||
"eyewearMystery301404Text": "Eyewear Goggles",
|
||||
"eyewearMystery301404Notes": "No eyewear could be fancier than a pair of goggles - except, perhaps, for a monocle. Confers no benefit. April 3015 Subscriber Item.",
|
||||
"eyewearMystery301405Text": "Monocle",
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> sent you a message",
|
||||
"letsgo": "Let's Go!",
|
||||
"selected": "Selected",
|
||||
"howManyToBuy": "How many would you like to purchase?",
|
||||
"howManyToBuy": "How many would you like to buy?",
|
||||
"contactForm": "Contact the Moderation Team",
|
||||
"loadEarlierMessages": "Load Earlier Messages",
|
||||
"askQuestion": "Ask a Question",
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
"sendGiftHeading": "Send Gift to <%= name %>",
|
||||
"sendGiftGemsBalance": "From <%= number %> Gems",
|
||||
"sendGiftCost": "Total: $<%= cost %> USD",
|
||||
"sendTotal": "Total:",
|
||||
"sendGiftTotal": "Total:",
|
||||
"sendGiftFromBalance": "From Balance",
|
||||
"sendGiftPurchase": "Purchase",
|
||||
"sendGiftLabel": "Would you like to send a gift message?",
|
||||
|
||||
@@ -199,10 +199,6 @@
|
||||
"spring2023HummingbirdWarriorSet": "Hummingbird (Warrior)",
|
||||
"spring2023MoonstoneMageSet": "Moonstone (Mage)",
|
||||
"spring2023LilyHealerSet": "Lily (Healer)",
|
||||
"summer2023GoldfishWarriorSet": "Goldfish (Warrior)",
|
||||
"summer2023GuppyRogueSet": "Guppy (Rogue)",
|
||||
"summer2023KelpHealerSet": "Kelp (Healer)",
|
||||
"summer2023CoralMageSet": "Coral (Mage)",
|
||||
"eventAvailability": "Available for purchase until <%= date(locale) %>.",
|
||||
"eventAvailabilityReturning": "Available for purchase until <%= availableDate(locale) %>. This potion was last available in <%= previousDate(locale) %>.",
|
||||
"dateEndJanuary": "January 31",
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
"howManyToSell": "How many would you like to sell?",
|
||||
"yourBalance": "Your balance:",
|
||||
"sell": "Sell",
|
||||
"sellItems": "Sell Items",
|
||||
"buyNow": "Buy Now",
|
||||
"sortByNumber": "Number",
|
||||
"featuredItems": "Featured Items!",
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
"questNudibranchUnlockText": "Unlocks Nudibranch Eggs for purchase in the Market",
|
||||
|
||||
"splashyPalsText": "Splashy Pals Quest Bundle",
|
||||
"splashyPalsNotes": "Contains 'The Dilatory Derby', 'Guide the Turtle', and 'Wail of the Whale'. Available until June 30.",
|
||||
"splashyPalsNotes": "Contains 'The Dilatory Derby', 'Guide the Turtle', and 'Wail of the Whale'. Available until July 31.",
|
||||
|
||||
"questHippoText": "What a Hippo-Crite",
|
||||
"questHippoNotes": "You and @awesomekitty collapse into the shade of a palm tree, exhausted. The sun beats down over the Sloensteadi Savannah, scorching the ground below. It’s been a productive day so far, conquering your Dailies, and this oasis looks like a nice place to take a break and refresh. Stooping near the water to get a drink, you stumble back in shock as a massive hippopotamus rises. “Resting so soon? Don’t be so lazy, get back to work.” You try and protest that you’ve been working hard and need a break, but the hippo isn’t having any of it.<br><br>@khdarkwolf whispers to you, “Notice how it’s lounging around all day but has the nerve to call you lazy? It’s the Hippo-Crite!”<br><br>Your friend @jumorales nods. “Let’s show it what hard work looks like!”",
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
"helpWithTranslation": "Would you like to help with the translation of Habitica? Great! Then visit <a href=\"/groups/guild/7732f64c-33ee-4cce-873c-fc28f147a6f7\">the Aspiring Linguists Guild</a>!",
|
||||
"stickyHeader": "Sticky header",
|
||||
"newTaskEdit": "Open new tasks in edit mode",
|
||||
"dailyDueDefaultView": "Set Dailies default to 'due' tab",
|
||||
"dailyDueDefaultViewPop": "With this option set, the Dailies tasks will default to 'due' instead of 'all'",
|
||||
"reverseChatOrder": "Show chat messages in reverse order",
|
||||
"startAdvCollapsed": "Advanced Settings in tasks start collapsed",
|
||||
"startAdvCollapsedPop": "With this option set, Advanced Settings will be hidden when you first open a task for editing.",
|
||||
|
||||
@@ -150,9 +150,6 @@
|
||||
"mysterySet202303": "Mane Character Set",
|
||||
"mysterySet202304": "Tiptop Teapot Set",
|
||||
"mysterySet202305": "Eventide Dragon Set",
|
||||
"mysterySet202306": "Razzle Dazzle Rainbow Set",
|
||||
"mysterySet202307": "Perilous Kraken Set",
|
||||
"mysterySet202308": "Purple Protagonist Set",
|
||||
"mysterySet301404": "Steampunk Standard Set",
|
||||
"mysterySet301405": "Steampunk Accessories Set",
|
||||
"mysterySet301703": "Peacock Steampunk Set",
|
||||
@@ -197,8 +194,8 @@
|
||||
"subscriptionBenefit5": "Receive the Royal Purple Jackalope pet when you become a new subscriber.",
|
||||
"subscriptionBenefit6": "Earn Mystic Hourglasses to purchase items in the Time Traveler’s Shop!",
|
||||
"purchaseAll": "Purchase Set",
|
||||
"gemsRemaining": "remaining",
|
||||
"notEnoughGemsToBuy": "No more Gems available for purchase this month. More will become available within the first 3 days of each month.",
|
||||
"gemsRemaining": "Gems remaining",
|
||||
"notEnoughGemsToBuy": "You are unable to buy that amount of Gems",
|
||||
"subscribersReceiveBenefits": "Subscribers receive these useful benefits!",
|
||||
"monthlyMysteryItems": "Monthly Mystery Items",
|
||||
"doubleDropCap": "Double the Drops",
|
||||
@@ -220,6 +217,5 @@
|
||||
"haveNonRecurringSub": "You have a non-recurring gift subscription.",
|
||||
"switchToRecurring": "Switch to a recurring subscription?",
|
||||
"continueGiftSubBenefits": "Want to continue your benefits? You can start a new subscription before your gifted one runs out to keep your benefits active.",
|
||||
"subscriptionCreditConversion": "Starting a new subscription will convert any remaining months to credit that will be used after the recurring subscription is canceled.",
|
||||
"monthlyGems": "Monthly Gems:"
|
||||
"subscriptionCreditConversion": "Starting a new subscription will convert any remaining months to credit that will be used after the recurring subscription is canceled."
|
||||
}
|
||||
|
||||
@@ -133,7 +133,5 @@
|
||||
"addTags": "Add tags...",
|
||||
"enterTag": "Enter a tag",
|
||||
"pressEnterToAddTag": "Press Enter to add tag: '<%= tagName %>'",
|
||||
"taskSummary": "<%= type %> Summary",
|
||||
"scoreUp": "Score up",
|
||||
"scoreDown": "Score down"
|
||||
"taskSummary": "<%= type %> Summary"
|
||||
}
|
||||
|
||||
@@ -3,45 +3,5 @@
|
||||
"background": "Bakground",
|
||||
"backgrounds": "Baekgroundz",
|
||||
"noBackground": "U has no choosd bakgrownd!1!",
|
||||
"backgroundShopText": "Bakgrownd Shop",
|
||||
"backgroundFairyRingText": "fairy ringz",
|
||||
"backgroundVolcanoText": "Volcaayno",
|
||||
"backgroundOpenWatersNotes": "Enjoy teh open waterrs.",
|
||||
"backgrounds072014": "SET 2: RELEASED JULY 2014",
|
||||
"backgroundAutumnForestText": "Autum Fores",
|
||||
"backgroundForestNotes": "Strollin thru teh summer forest.",
|
||||
"backgrounds082014": "SET 3: RELEASED AUGUST 2014",
|
||||
"backgrounds062014": "SET 1: RELEASED JUNE 2014",
|
||||
"backgroundVolcanoNotes": "Warm up inside teh volcaino.",
|
||||
"backgroundBeachNotes": "Lounging on warm beachz r teh best.",
|
||||
"backgroundCoralReefNotes": "SWIM IN DA CORAL REEF.",
|
||||
"backgroundThunderstormNotes": "Conduct teh lightnin in a thunder storrm.",
|
||||
"backgrounds092014": "SET 4: RELEASED SEPTEMBER 2014",
|
||||
"backgroundSeafarerShipNotes": "Sail on teh Seafairer Ship.",
|
||||
"backgroundCloudsNotes": "Soaring thru teh clouds.",
|
||||
"backgroundBeachText": "Beech",
|
||||
"backgroundDustyCanyonsText": "Dusty Caniyon",
|
||||
"backgroundThunderstormText": "Thunderstorrm",
|
||||
"backgroundForestText": "Forrest",
|
||||
"backgroundOpenWatersText": "Open Wateerrrs",
|
||||
"backgroundCoralReefText": "CORAL REEF",
|
||||
"backgroundCloudsText": "Clouuds",
|
||||
"backgroundSeafarerShipText": "Seafairer Ship",
|
||||
"hideLockedBackgrounds": "HIDE LOCKD BACKGROUNDZ",
|
||||
"backgroundFairyRingNotes": "Dancin in teh fairy ringz.",
|
||||
"backgroundHauntedHouseText": "hauunted haus",
|
||||
"backgroundHauntedHouseNotes": "snek thru teh haunted hous",
|
||||
"backgroundPumpkinPatchNotes": "carve teh jack-lanterrns in teh pumpkin patch.",
|
||||
"backgroundDustyCanyonsNotes": "Walk thru a Dursty Caneon.",
|
||||
"backgrounds102014": "SET 5: RELEASED OCTOBER 2014",
|
||||
"backgrounds112014": "SET 6: RELEASED NOVEMBER 2014",
|
||||
"backgroundHarvestFieldsText": "HARVEST DA FIELDS",
|
||||
"backgroundGraveyardNotes": "Visit a creepy graveyard, oh no.",
|
||||
"backgroundHarvestFieldsNotes": "Cultivat ur harvest felds.",
|
||||
"backgroundGraveyardText": "Graveyarrd",
|
||||
"backgroundPumpkinPatchText": "pumpkin pach",
|
||||
"backgroundHarvestFeastNotes": "Enjoy teh harvest feast.",
|
||||
"backgroundHarvestFeastText": "Harvest teh Feast",
|
||||
"backgroundAutumnForestNotes": "U will walk thru teh forst of autumn.",
|
||||
"backgroundStarrySkiesText": "starrry skes"
|
||||
"backgroundShopText": "Bakgrownd Shop"
|
||||
}
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
"playerTiersDesc": "Teh colrd usrnaemz u see n chat r 4 pplz contributr teer. Teh highr teh teer, teh moar teh persun haz helpd Habitica thru art, code, teh community, an moar!",
|
||||
"tier1": "Teer 1 (Fren)",
|
||||
"tier2": "Teer 2 (Fren)",
|
||||
"tier3": "Teer 3 (Eleete)",
|
||||
"tier4": "Teer 4 (Eleete)",
|
||||
"tier3": "Teer 3 (1337)",
|
||||
"tier4": "Teer 4 (1337)",
|
||||
"tier5": "Teer 5 (Champyon)",
|
||||
"tier6": "Teer 6 (Champyon)",
|
||||
"tier7": "Teer 7 (Legendareh)",
|
||||
"tierModerator": "Moderatr (Gardian)",
|
||||
"tierStaff": "Staf (Herowik)",
|
||||
"tierNPC": "Not teh Humaniod Characterrr",
|
||||
"friend": "Frien",
|
||||
"elite": "Eleete",
|
||||
"tierNPC": "NPC",
|
||||
"friend": "Frand",
|
||||
"elite": "1337",
|
||||
"champion": "Champyun",
|
||||
"legendary": "Legundareh",
|
||||
"moderator": "Moderatur",
|
||||
"guardian": "Gawrdiyun",
|
||||
"staff": "Stafff",
|
||||
"staff": "Staf",
|
||||
"heroic": "Heroik",
|
||||
"modalContribAchievement": "Contributar Acheevment!",
|
||||
"contribModal": "<%= name %>, u awsum persn! Ur now teer <%= level %> contributr 4 helpin Habitica.",
|
||||
@@ -53,6 +53,5 @@
|
||||
"surveysSingle": "Helpd Habitica groah, eithr by filin out survai or helpin wif majur testin efort. Thx!",
|
||||
"surveysMultiple": "Helpd Habitica groah on <%= count %> ocashunz, eithr by filin out survai or helpin wif majur testin efort. Thx!",
|
||||
"blurbHallPatrons": "Dis is teh Hal ov Patronz, where we honr teh nobl aventururz hoo backd Habiticaz originul Kickstarter. We thank dem 4 helpin us bring Habitica 2 laif!",
|
||||
"blurbHallContributors": "Tis is teh Haall of teh Contributors, tis wher teh open-surce contributors of Habitica r honourred. Weatherr thru coed, arrt, muusic, writingg, or evn just helpiing, zey have earned <a href='https://habitica.fandom.com/wiki/Contributor_Rewards' target='_blank'> geems, excluusive stuf</a>, and teh <a href='https://habitica.fandom.com/wiki/Contributor_Titles' target='_blank'>very rare titles</a>. U r able to contribut as well! <a href='https://habitica.fandom.com/wiki/Contributing_to_Habitica' target='_blank'> Learn moer heir.</a>",
|
||||
"noPrivAccess": "You no haz teh neded priviiligees."
|
||||
"blurbHallContributors": "This is the Hall of Contributors, where open-source contributors to Habitica are honored. Whether through code, art, music, writing, or even just helpfulness, they have earned <a href='https://habitica.fandom.com/wiki/Contributor_Rewards' target='_blank'> gems, exclusive equipment</a>, and <a href='https://habitica.fandom.com/wiki/Contributor_Titles' target='_blank'>prestigious titles</a>. You can contribute to Habitica, too! <a href='https://habitica.fandom.com/wiki/Contributing_to_Habitica' target='_blank'> Find out more here. </a>"
|
||||
}
|
||||
|
||||
@@ -122,6 +122,5 @@
|
||||
"achievementZodiacZookeeper": "12 Zodiac Zookeeper",
|
||||
"achievementZodiacZookeeperModalText": "You collected all the 12 zodiac pets!",
|
||||
"achievementShadyCustomer": "shadow man",
|
||||
"achievementShadeOfItAll": "The Beginning of the Shade",
|
||||
"achievementDomesticatedModalText": "Ye gathered ev'ry critter matey!"
|
||||
"achievementShadeOfItAll": "The Beginning of the Shade"
|
||||
}
|
||||
|
||||
@@ -147,8 +147,5 @@
|
||||
"achievementPolarProText": "¡Ha eclosionado todos los colores estándar para mascotas Polares: Osos, Zorros, Pinguinos, Ballenas y Lobos!",
|
||||
"achievementPlantParent": "Progenitor de las Plantas",
|
||||
"achievementPlantParentText": "¡Ha eclosionado todos los colores estándar para las mascotas Planta: Cáctus y Esqueje de árbol!",
|
||||
"achievementPlantParentModalText": "¡Has coleccionado todas las Mascotas Planta!",
|
||||
"achievementDinosaurDynasty": "Dinastía de Dinosaurios",
|
||||
"achievementDinosaurDynastyModalText": "¡Has recogido todas las mascotas de pájaros y dinosaurios!",
|
||||
"achievementDinosaurDynastyText": "Ha incubado todos los colores estándar de mascotas, de aves y dinosaurios: halcón, búho, loro, pavo real, pingüino, gallo, pterodáctilo, tiranosaurio rex, triceratops y velociraptor!"
|
||||
"achievementPlantParentModalText": "¡Has coleccionado todas las Mascotas Planta!"
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,14 +3,14 @@
|
||||
"stringNotFound": "No se encontró la cadena '<%= string %>'.",
|
||||
"habitica": "Habitica",
|
||||
"onward": "¡Adelante!",
|
||||
"done": "Completado",
|
||||
"done": "Hecho",
|
||||
"gotIt": "¡Recibido!",
|
||||
"titleTimeTravelers": "Viajeros del tiempo",
|
||||
"titleSeasonalShop": "Tienda de temporada",
|
||||
"saveEdits": "Guardar cambios",
|
||||
"showMore": "Mostrar más",
|
||||
"showLess": "Mostrar menos",
|
||||
"markdownHelpLink": "Ayuda con el formato Reducción",
|
||||
"markdownHelpLink": "Ayuda con el formato Markdown",
|
||||
"bold": "**Negrita**",
|
||||
"markdownImageEx": "",
|
||||
"code": "`código`",
|
||||
@@ -41,16 +41,16 @@
|
||||
"continue": "Continuar",
|
||||
"accept": "Aceptar",
|
||||
"reject": "Rechazar",
|
||||
"neverMind": "Olvídalo",
|
||||
"neverMind": "No importa",
|
||||
"notEnoughGems": "No tienes suficientes gemas",
|
||||
"alreadyHave": "Vaya! ya tienes este artículo. ¡No necesitas comprarlo otra vez!",
|
||||
"alreadyHave": "Vaya, ya tienes este artículo. ¡No necesitas comprarlo otra vez!",
|
||||
"delete": "Eliminar",
|
||||
"gemsPopoverTitle": "Gemas",
|
||||
"gems": "Gemas",
|
||||
"needMoreGems": "¿Necesitas más gemas?",
|
||||
"needMoreGemsInfo": "¡Compra Gemas ahora, o suscríbete para comprar Gemas con Oro, recibe objetos misteriosos mensualmente, disfruta botines mas fréquentes y más!",
|
||||
"needMoreGemsInfo": "¡Compra Gemas ahora, o suscríbete para comprar Gemas con Oro, conseguir objetos misteriosos mensuales, disfrutar mayores botines y más!",
|
||||
"veteran": "Veterano",
|
||||
"veteranText": "Ha sobrevivido a Habit The Grey (nuestro sito web pre-Angular) y ha recibido muchas cicatrices de sus fallos.",
|
||||
"veteranText": "Ha sobrevivido a Habit The Grey (nuestro sito web pre-Angular) y se ha ganado muchas cicatrices por sus fallos.",
|
||||
"originalUser": "¡Usuario original!",
|
||||
"originalUserText": "Uno de los <em>primerísimos</em> usuarios... ¡Este sí que es un alpha tester!",
|
||||
"habitBirthday": "Fiesta de cumpleaños de Habitica",
|
||||
@@ -58,11 +58,11 @@
|
||||
"habitBirthdayPluralText": "¡Participó en <%= count %> Fiestas de Cumpleaños de Habitica!",
|
||||
"habiticaDay": "Bautizo de Habitica",
|
||||
"habiticaDaySingularText": "¡Celebró el bautizo de Habitica! Gracias por ser un usuario magnífico.",
|
||||
"habiticaDayPluralText": "¡Participó en <%= count %> bautizos de Habitica! Gracias por ser un magnífico usuario.",
|
||||
"habiticaDayPluralText": "¡Participó en <%= count %> onomásticas de Habitica! Gracias por ser un magnífico usuario.",
|
||||
"achievementDilatory": "Salvador de Dilatoria",
|
||||
"achievementDilatoryText": "¡Ayudó a derrotar al Dread Drag'on de Dilatoria durante el evento Summer Splash del 2014!",
|
||||
"costumeContest": "Participante disfrazado",
|
||||
"costumeContestText": "Participo en el Concurso de Disfraces de Habitoween. ¡Mira algunas de las estupendas entradas en blog.habitrpg.com!",
|
||||
"costumeContestText": "Has participado en el Concurso de Disfraces de Habitoween. ¡Mira algunas de las estupendas entradas en blog.habitrpg.com!",
|
||||
"costumeContestTextPlural": "Has participado en <%= count %> Concursos de Disfraces de Habitoween. ¡Echa un vistazo a las estupendas entradas en blog.habitrpg.com!",
|
||||
"newPassSent": "Si tenemos constancia de tu correo electrónico, te hemos enviado un mensaje con las instrucciones a seguir para establecer una nueva contraseña.",
|
||||
"error": "Error",
|
||||
@@ -74,27 +74,27 @@
|
||||
"audioTheme": "Tema de audio",
|
||||
"audioTheme_off": "Desactivado",
|
||||
"audioTheme_danielTheBard": "Daniel el Bardo",
|
||||
"audioTheme_wattsTheme": "El tema de Watts",
|
||||
"audioTheme_gokulTheme": "El tema de Gokul",
|
||||
"audioTheme_luneFoxTheme": "El tema de LuneFox",
|
||||
"audioTheme_rosstavoTheme": "El tema de Rosstavo",
|
||||
"audioTheme_dewinTheme": "El tema de Dewin",
|
||||
"audioTheme_airuTheme": "El tema de Airu",
|
||||
"audioTheme_beatscribeNesTheme": "El tema de Beatscribe's NES",
|
||||
"audioTheme_arashiTheme": "El tema de Arashi",
|
||||
"audioTheme_triumphTheme": "El tema del Triunfo",
|
||||
"audioTheme_lunasolTheme": "El tema de Lunasol",
|
||||
"audioTheme_spacePenguinTheme": "El tema del Pingüino Espacial",
|
||||
"audioTheme_maflTheme": "El tema de MAFL",
|
||||
"audioTheme_pizildenTheme": "El tema de Pizilden",
|
||||
"audioTheme_farvoidTheme": "El tema de Farvoid",
|
||||
"reportBug": "Reportar un error",
|
||||
"audioTheme_wattsTheme": "Tema Watts",
|
||||
"audioTheme_gokulTheme": "Tema Gokul",
|
||||
"audioTheme_luneFoxTheme": "Tema LuneFox",
|
||||
"audioTheme_rosstavoTheme": "Tema Rosstavo",
|
||||
"audioTheme_dewinTheme": "El tema de Dewin´s",
|
||||
"audioTheme_airuTheme": "Tema Airu",
|
||||
"audioTheme_beatscribeNesTheme": "Tema Beatscribe's NES",
|
||||
"audioTheme_arashiTheme": "Tema Arashi",
|
||||
"audioTheme_triumphTheme": "Tema del Triunfo",
|
||||
"audioTheme_lunasolTheme": "Tema de Lunasol",
|
||||
"audioTheme_spacePenguinTheme": "Tema del Pingüino Espacial",
|
||||
"audioTheme_maflTheme": "Tema MAFL",
|
||||
"audioTheme_pizildenTheme": "Tema de Pizilden",
|
||||
"audioTheme_farvoidTheme": "Tema de Farvoid",
|
||||
"reportBug": "Notificar un error",
|
||||
"overview": "Introducción para nuevos usuarios",
|
||||
"dateFormat": "Formato de fecha",
|
||||
"achievementStressbeast": "Salvador de Stoïkalm",
|
||||
"achievementStressbeastText": "¡Ayudó a derrotar a la Bestia Abominable del Estrés durante el evento Paraíso Invernal de 2014!",
|
||||
"achievementStressbeastText": "¡Ayudó a derrotar a la Abominable Bestia del Estrés durante el evento Winter Wonderland de 2014!",
|
||||
"achievementBurnout": "Salvador de los Campos Florecientes",
|
||||
"achievementBurnoutText": "¡Ayudó a derrotar al Burnout y restaurar los Espíritus del Cansancio durante el evento Festival de Otoño de 2015!",
|
||||
"achievementBurnoutText": "¡Ayudó a derrotar al Burnout y restaurar los Espíritus del Cansancio durante el evento Fall Festival de 2015!",
|
||||
"achievementBewilder": "Salvador de Calavuelos",
|
||||
"achievementBewilderText": "¡Ayudó a derrotar al Apa-bullador durante el Evento de Primavera de 2016!",
|
||||
"achievementDysheartener": "Salvador de los Destrozados",
|
||||
@@ -104,19 +104,19 @@
|
||||
"cardReceived": "Recibiste una <span class=\"notification-bold-blue\"><%= card %></span>",
|
||||
"greetingCard": "Tarjeta de saludo",
|
||||
"greetingCardExplanation": "¡Ambos recibís el logro Alegres Amigotes!",
|
||||
"greetingCardNotes": "Enviar una tarjeta a un miembro del equipo.",
|
||||
"greetingCardNotes": "Enviar una tarjeta para mandar un saludo a un miembro del equipo.",
|
||||
"greeting0": "¡Hola!",
|
||||
"greeting1": "Solo quería saludar :)",
|
||||
"greeting2": "(saluda con emoción)",
|
||||
"greeting3": "¡Ey!",
|
||||
"greetingCardAchievementTitle": "Alegre Amigote",
|
||||
"greetingCardAchievementText": "¡Eh! ¡Hola! ¿Qué tal? <%= count %> tarjetas enviadas o recibidas.",
|
||||
"greetingCardAchievementText": "¡Eh! ¡Hola! ¿Qué tal? <%= count %> tarjetas de saludo enviadas o recibidas.",
|
||||
"thankyouCard": "Tarjeta de agradecimiento",
|
||||
"thankyouCardExplanation": "¡Ambos recibís el logro Agradablemente Agradecido!",
|
||||
"thankyouCardNotes": "Envía una tarjeta de agradecimiento a un miembro de tu equipo.",
|
||||
"thankyou0": "¡Muchas gracias!",
|
||||
"thankyou1": "¡Gracias, gracias, gracias!",
|
||||
"thankyou2": "Envíando mil gracias.",
|
||||
"thankyou2": "Te envío mil gracias.",
|
||||
"thankyou3": "Estoy muy agradecido: ¡gracias!",
|
||||
"thankyouCardAchievementTitle": "Agradablemente Agradecido",
|
||||
"thankyouCardAchievementText": "¡Gracias por ser agradecido! <%= count %> tarjetas de agradecimiento enviadas o recibidas.",
|
||||
@@ -126,31 +126,31 @@
|
||||
"birthday0": "¡Feliz cumpleaños!",
|
||||
"birthdayCardAchievementTitle": "Prosperidad Cumpleañera",
|
||||
"birthdayCardAchievementText": "¡Muchas felicidades! <%= count %> tarjetas de cumpleaños enviadas o recibidas.",
|
||||
"congratsCard": "Carta de felicitaciónes",
|
||||
"congratsCard": "Carta de Enhorabuena",
|
||||
"congratsCardExplanation": "¡Ambos habéis recibido el logro de Compañero Felicitador!",
|
||||
"congratsCardNotes": "Envía una Carta de felicitaciónes a un miembro del equipo.",
|
||||
"congrats0": "¡Felicitaciónes por tu éxito!",
|
||||
"congratsCardNotes": "Envía una Carta de Enhorabuena a un miembro del equipo.",
|
||||
"congrats0": "¡Enhorabuena por tu éxito!",
|
||||
"congrats1": "¡Estoy orgulloso de ti!",
|
||||
"congrats2": "¡Bien hecho!",
|
||||
"congrats3": "¡Aplauso para ti!",
|
||||
"congrats3": "¡Un aplauso para ti!",
|
||||
"congrats4": "¡Disfruta de tu bien merecido éxito!",
|
||||
"congratsCardAchievementTitle": "Compañero Congratulatorio",
|
||||
"congratsCardAchievementText": "¡Es genial celebrar los logros de tus amigos! Enviaste o recibiste <%= count %> cartas de felicitaciónes.",
|
||||
"getwellCard": "Carta de recupérate pronto",
|
||||
"congratsCardAchievementText": "¡Es genial celebrar los logros de tus amigos! Enviaste o recibiste <%= count %> cartas de enhorabuena.",
|
||||
"getwellCard": "Carta de Ponte Bueno",
|
||||
"getwellCardExplanation": "¡Ambos habéis recibido el logro de Confidente Solícito!",
|
||||
"getwellCardNotes": "Envía una carta de recupérate pronto a un miembro del equipo.",
|
||||
"getwellCardNotes": "Envía una carta de Ponte Bueno a un miembro del equipo.",
|
||||
"getwell0": "¡Espero que te recuperes pronto!",
|
||||
"getwell1": "¡Cuídate! <3",
|
||||
"getwell2": "¡Te tengo en mis pensamientos!",
|
||||
"getwell3": "¡Siento que no te encuentres bien!",
|
||||
"getwellCardAchievementTitle": "Confidente Cuidadoso",
|
||||
"getwellCardAchievementText": "Siempre son de agradecidos los deseos de salud. Enviaste o recibiste <%= count %> cartas de recupérate pronto.",
|
||||
"getwellCardAchievementText": "Siempre son de agrado los deseos de mejoría. Enviaste o recibiste <%= count %> cartas de Ponte Bueno.",
|
||||
"goodluckCard": "Carta de Buena Suerte",
|
||||
"goodluckCardExplanation": "¡Ambos recibís el logro Carta de la Suerte!",
|
||||
"goodluckCardNotes": "Envía una carta de Buena Suerte a un miembro del equipo.",
|
||||
"goodluck0": "¡Que la suerte te acompañe!",
|
||||
"goodluck1": "¡Te deseo un montón de suerte!",
|
||||
"goodluck2": "¡Espero que la suerte esté a tu lado hoy y siempre!",
|
||||
"goodluck2": "¡Espero que la suerte esté de lado hoy y siempre!",
|
||||
"goodluckCardAchievementTitle": "Carta de la Suerte",
|
||||
"goodluckCardAchievementText": "¡Los deseos de buena suerte son un gran estímulo! Enviaste o recibiste <%= count %> cartas de Buena Suerte.",
|
||||
"streakAchievement": "¡Has obtenido un logro de racha!",
|
||||
@@ -163,8 +163,8 @@
|
||||
"orderBy": "Ordenar por <%= item %>",
|
||||
"you": "(tú)",
|
||||
"loading": "Cargando...",
|
||||
"userIdRequired": "Es necesario un ID de usuario",
|
||||
"resetFilters": "Borrar todos los filtros",
|
||||
"userIdRequired": "Es necesaria un ID de usuario",
|
||||
"resetFilters": "Limpiar todos los filtros",
|
||||
"applyFilters": "Aplicar filtros",
|
||||
"wantToWorkOn": "Quiero trabajar en:",
|
||||
"categories": "Categorías",
|
||||
@@ -174,11 +174,11 @@
|
||||
"health_wellness": "Salud y Bienestar",
|
||||
"self_care": "Cuidado de ti mismo",
|
||||
"habitica_official": "Oficial de Habitica",
|
||||
"academics": "Académica",
|
||||
"academics": "Académico",
|
||||
"advocacy_causes": "Defensa + Causas",
|
||||
"entertainment": "Entretenimiento",
|
||||
"finance": "Finanzas",
|
||||
"health_fitness": "Salud + Ejercicio",
|
||||
"health_fitness": "Salud + Ejercicios",
|
||||
"hobbies_occupations": "Aficiones + Ocupaciones",
|
||||
"location_based": "Basado en la localización",
|
||||
"mental_health": "Salud Mental + Cuidado de ti mismo",
|
||||
@@ -186,11 +186,11 @@
|
||||
"self_improvement": "Autosuperación",
|
||||
"spirituality": "Espiritualidad",
|
||||
"time_management": "Manejo del Tiempo + Responsabilidad",
|
||||
"recovery_support_groups": "Recuperación + Grupos de Apoyo",
|
||||
"recovery_support_groups": "Recuperación + Grupos de Ayuda",
|
||||
"dismissAll": "Ignorar todas",
|
||||
"messages": "Mensajes",
|
||||
"emptyMessagesLine1": "No tienes ningún mensaje",
|
||||
"emptyMessagesLine2": "Puedes enviar un nuevo mensaje a un usuario visitando su perfil y presionando \"Mensaje\".",
|
||||
"emptyMessagesLine2": "Puedes enviar un nuevo mensaje a un usuario visitando su perfil y haciendo clic en el botón \"Mensaje\".",
|
||||
"userSentMessage": "<span class=\"notification-bold\"><%- user %></span> te ha enviado un mensaje",
|
||||
"letsgo": "¡Vamos!",
|
||||
"selected": "Seleccionado",
|
||||
@@ -199,8 +199,8 @@
|
||||
"options": "Opciones",
|
||||
"demo": "Demo",
|
||||
"loadEarlierMessages": "Cargar Mensajes Anteriores",
|
||||
"finish": "Finalizar",
|
||||
"congratulations": "¡Felicidades!",
|
||||
"finish": "Terminar",
|
||||
"congratulations": "¡Enhorabuena!",
|
||||
"onboardingAchievs": "Logros de incorporación",
|
||||
"reportEmailError": "Por favor, introduzca un correo electrónico válido",
|
||||
"reportDescription": "Descripción",
|
||||
@@ -212,10 +212,6 @@
|
||||
"reportEmailText": "Esto solo se utilizará para contactar contigo en relación con el informe de error.",
|
||||
"reportEmailPlaceholder": "Tu correo electrónico",
|
||||
"reportDescriptionText": "Si lo crees conveniente, incluye capturas de pantalla o errores de la consola de Javascript.",
|
||||
"reportSentDescription": "Nos pondremos en contacto contigo en cuanto nuestro equipo haya podido investigar. Gracias por informarnos del problema.",
|
||||
"askQuestion": "Haz una pregunta",
|
||||
"skipExternalLinkModal": "Mantenga presionada la tecla CTRL (Windows) o Comando (Mac) al hacer clic en un enlace para omitir este modal.",
|
||||
"refreshList": "Actualizar lista",
|
||||
"leaveHabitica": "Estás a punto de salir de Habitica.com",
|
||||
"leaveHabiticaText": "Habitica no es responsable del contenido de ningún sitio web vinculado que no sea propiedad ni esté operado por HabitRPG.<br>Tenga en cuenta que las prácticas de estos sitios web pueden diferir de las pautas de la comunidad de Habitica."
|
||||
"reportSentDescription": "Nos pondremos en contacto contigo en cuanto nuestro equipo haya podido estudiarlo. Gracias por informarnos del problema.",
|
||||
"askQuestion": "Haz una pregunta"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"commGuideHeadingWelcome": "¡Bienvenido a Habitica!",
|
||||
"commGuidePara001": "¡Saludos, aventurero! Bienvenido a Habitica, la tierra de la productividad, la vida sana y el ocasional grifo desbocado. Tenemos una comunidad alegre llena de personas útiles que se apoyan mutuamente en su camino hacia la superación personal. Para encajar, todo lo que se necesita es una actitud positiva, un trato respetuoso y la comprensión de que todos tienen diferentes habilidades y limitaciones, ¡incluido usted! Los habiticanos son pacientes entre sí y tratan de ayudar cuando pueden.",
|
||||
"commGuidePara002": "Para ayudar a mantenerlos a todos seguros, felices y productivos en la comunidad, tenemos algunas normas. Las hemos elaborado cuidadosamente para que sean lo más agradable y facil de leer posible. Por favor tómese el tiempo para leerlas antes de comenzar a conversar.",
|
||||
"commGuidePara003": "Estas reglas aplican a todos los espacios sociales que usamos, incluyendo (aunque no exclusivamente) Trello, GitHub, Weblate, y la Wiki de Habitica en Fandom. A medida de que las comunidades crecen y cambian, sus reglas pueden adaptarse con el tiempo. ¡Cuando haya cambios sustanciales a estas Reglas, lo sabrás por medio de un anuncio de Bailey y/o nuestras redes sociales!",
|
||||
"commGuidePara003": "Estas reglas aplican a todos los espacios sociales que usamos, incluyendo (aunque no exclusivamente) Trello, GitHub, Weblate, y la Wiki de Habitica en Fandom. A medida de que las comunidades crecen y cambian, sus reglas pueden adaptarse de vez en cuando. ¡Cuando haya cambios sustanciales a estas Reglas, lo sabrás por medio de un anuncio de Bailey y/o nuestras redes sociales!",
|
||||
"commGuideHeadingInteractions": "Interacciones en Habitica",
|
||||
"commGuidePara015": "Habitica tiene dos tipos de espacios sociales: públicos y privados. Los espacios públicos incluyen la Taberna, Gremios Públicos, GitHub, Trello y la Wiki. Los espacios privados son Gremios Privados, chat de Equipo y Mensajes Privados. Todos los Nombres Públicos y @nombresdeusuario deben cumplir con las normas de espacio publico. Para cambiar tu Nombre Público o @nombredeusuario, en dispositivos móviles ve a Menú > Ajustes > Perfil; en la página web ve a Usuario > Ajustes.",
|
||||
"commGuidePara016": "Al navegar los espacios públicos en Habitica, hay algunas reglas generales para mantener a todos seguros y felices.",
|
||||
@@ -127,5 +127,5 @@
|
||||
"commGuideList01B": "Prohibido: mensajes amenazantes, violentos, que promocionen la discriminación, etc. incluyendo memes, imágenes y bromas.",
|
||||
"commGuideList02M": "No pidas gemas, suscripciones o membresía en Planes de Grupo. Esto no está permitido en la Taberna, espacios de chat públicos o privados, ni en mensajes privados. Si recibes mensajes solicitando artículos de pago, por favor márcalos para reportarlos. Pedir gemas o suscripciones repetida o intensamente, especialmente después de una advertencia, puede resultar en la suspensión de tu cuenta.",
|
||||
"commGuideList01C": "Todas las discusiones deben ser aptas para todas las edades y estar libres de palabras ofensivas.",
|
||||
"commGuideList01E": "<strong>No inicies o participes en conversaciones polémicas en la Taberna.<strong>"
|
||||
"commGuideList01E": "No inicies o te unas a conversaciones polémicas en la Taberna."
|
||||
}
|
||||
|
||||
@@ -54,6 +54,5 @@
|
||||
"webFaqAnswer12": "Los Jefes Mundiales son monstruos especiales que aparecen en la Taberna. Todos los usuarios activos pasan automáticamente a luchar contra el Monstruo, y sus tareas y Habilidades harán daño al Monstruo, como es habitual. Puedes estar al mismo tiempo en una Misión normal. Tus tareas y Habilidades contarán tanto para el Monstruo Mundial como para la Misión de Jefe/Recolección en tu equipo. Un Monstruo Mundial nunca te hará daño en tu cuenta. En vez de eso, tiene una Barra de Ira que se llena cuando los usuarios se saltan tareas Diarias. Si esta barra se llena, atacará a uno de los Personajes No Jugadores de la web, y su imagen cambiará. Puedes leer más sobre [anteriores Jefes de Mundo](https://habitica.fandom.com/wiki/World_Bosses) en la wiki.",
|
||||
"iosFaqStillNeedHelp": "Si tienes una pregunta que no se encuentra en la lista o en las [Preguntas Frecuentes de la Wiki](https://habitica.fandom.com/wiki/FAQ), ¡pregúntanos en el chat de la Taberna en Menú > Taberna! Estaremos encantados de ayudarte.",
|
||||
"androidFaqStillNeedHelp": "Si tienes alguna pregunta que no esté en la lista o en las [preguntas frecuentes de la Wiki](https://habitica.fandom.com/wiki/FAQ), ¡ven a preguntar al chat de la Taberna, bajo el Menú > Taberna! Estaremos encantados de ayudar.",
|
||||
"webFaqStillNeedHelp": "Si tienes una pregunta que no está en esta lista o en [Wiki FAQ](https://habitica.fandom.com/wiki/FAQ), ¡ven y pregunta en el [gremio Habitica Help](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! Estamos felices de ayudar.",
|
||||
"general": "Información general"
|
||||
"webFaqStillNeedHelp": "Si tienes una pregunta que no está en esta lista o en [Wiki FAQ](https://habitica.fandom.com/wiki/FAQ), ¡ven y pregunta en el [gremio Habitica Help](https://habitica.com/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a)! Estamos felices de ayudar."
|
||||
}
|
||||
|
||||
@@ -147,8 +147,5 @@
|
||||
"achievementPolarProModalText": "Vous avez collecté tous les familiers polaires !",
|
||||
"achievementPlantParent": "Protecteur des plantes",
|
||||
"achievementPlantParentText": "A fait éclore toutes les couleurs standards de familiers plantes : Cactus et arbustes !",
|
||||
"achievementPlantParentModalText": "Vous avec collecté tous les familiers plantes !",
|
||||
"achievementDinosaurDynasty": "Dynastie des dinosaures",
|
||||
"achievementDinosaurDynastyText": "A fait éclore toutes les couleurs standard d'oiseaux et de dinosaures : faucon, hibou, perroquet, paon, pingouin, coq, ptérodactyle, T-Rex, tricératops et vélociraptor !",
|
||||
"achievementDinosaurDynastyModalText": "Vous avez collecté tous les animaux de compagnie d'oiseau et de dinosaure!"
|
||||
"achievementPlantParentModalText": "Vous avec collecté tous les familiers plantes !"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user