Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f65353974 | |||
| ab7c4015a2 | |||
| 6d509ae1f8 | |||
| 14714f9e1c | |||
| b17c9a33a5 | |||
| 31d0cb5a91 | |||
| 163eb55dbb | |||
| 8661716c23 | |||
| fd37ee90da | |||
| a4cfb97dbf | |||
| ea766251c2 | |||
| f196ff2e24 | |||
| cc901fe085 | |||
| f257488b39 | |||
| 48dbe547c0 | |||
| b15462596b | |||
| 2a98b5b7bf | |||
| f7667fcf79 | |||
| 05aaad8743 | |||
| 5e1f2c16f8 | |||
| 82b6a14d5b | |||
| f9cfd9fb5e | |||
| 60bef56577 | |||
| af87185bfa | |||
| f8c8be4f4c | |||
| 5d220544e0 | |||
| c4fd9daa90 | |||
| fc8f9cbaa0 | |||
| e39d3e52e2 | |||
| 625b4a4ad7 | |||
| f2bcdd21de | |||
| ad51675ac6 | |||
| 869d2df4fa | |||
| 734e997345 | |||
| 4fc260e552 | |||
| fa22a47b7a | |||
| 0366245fab | |||
| f342eff70b | |||
| 84eb39fde2 | |||
| d6fe2c76e2 | |||
| f19e9dd57e | |||
| 13566e8a39 | |||
| 7d3dd9f157 | |||
| 92f283f6a2 | |||
| 5d24d584d4 | |||
| 0320827f7e | |||
| faa49b1412 | |||
| c3decc3951 | |||
| 084adf8b0d | |||
| 04574dad69 | |||
| 6526a6317e | |||
| c778e5e84e | |||
| b5dacdf9ea | |||
| e05d1dae43 | |||
| 864db644e3 | |||
| 5ddd4ec564 | |||
| 2d7d4af2b8 | |||
| bad3f82dfb | |||
| 8595641d12 | |||
| 9bb3e17995 | |||
| 1d7e02428b | |||
| eee04255f8 | |||
| 7f30385c09 | |||
| 5b6eeef290 | |||
| 9953c9346d | |||
| d62930b9da | |||
| 093bcbb715 | |||
| 1f5992ccc5 | |||
| 2d598c9933 | |||
| b4be8286e2 | |||
| 96b985a191 | |||
| a196a0cae2 | |||
| 8f9043e4f1 | |||
| 1cace198a1 | |||
| 0275636f46 | |||
| ea7ae4bb2f | |||
| 9f32a879e3 | |||
| 665200b49d | |||
| c63e92c8f2 | |||
| ba5b79855f | |||
| 97051bb3ae | |||
| 29e3cae0a6 | |||
| 274c582af8 | |||
| 4a7f40ea37 | |||
| 97ad0fae26 | |||
| b7b91caef1 | |||
| daa3458760 | |||
| 2cfc765e39 | |||
| 7cd9f800cc | |||
| 9a1cadd49f | |||
| b3285db5b0 | |||
| 8b1c009990 | |||
| 9061a59fc2 | |||
| cbfed9c0d3 | |||
| 77447f7096 | |||
| 361bb92b3b | |||
| e50d5f514c | |||
| a7ac4633a8 | |||
| 31b53fd6ed | |||
| 3e31223812 |
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Award Habitoween ladder items to participants in this month's Habitoween festivities
|
||||
*/
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const MIGRATION_NAME = '20201029_habitoween_ladder'; // Update when running in future years
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const set = {};
|
||||
const inc = {
|
||||
'items.food.Candy_Skeleton': 1,
|
||||
'items.food.Candy_Base': 1,
|
||||
'items.food.Candy_CottonCandyBlue': 1,
|
||||
'items.food.Candy_CottonCandyPink': 1,
|
||||
'items.food.Candy_Shade': 1,
|
||||
'items.food.Candy_White': 1,
|
||||
'items.food.Candy_Golden': 1,
|
||||
'items.food.Candy_Zombie': 1,
|
||||
'items.food.Candy_Desert': 1,
|
||||
'items.food.Candy_Red': 1,
|
||||
};
|
||||
|
||||
set.migration = MIGRATION_NAME;
|
||||
|
||||
if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Glow']) {
|
||||
set['items.pets.JackOLantern-RoyalPurple'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Glow']) {
|
||||
set['items.mounts.JackOLantern-Glow'] = true;
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Ghost']) {
|
||||
set['items.pets.JackOLantern-Glow'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Ghost']) {
|
||||
set['items.mounts.JackOLantern-Ghost'] = true;
|
||||
} else if (user && user.items && user.items.mounts && user.items.mounts['JackOLantern-Base']) {
|
||||
set['items.pets.JackOLantern-Ghost'] = 5;
|
||||
} else if (user && user.items && user.items.pets && user.items.pets['JackOLantern-Base']) {
|
||||
set['items.mounts.JackOLantern-Base'] = true;
|
||||
} else {
|
||||
set['items.pets.JackOLantern-Base'] = 5;
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
return await User.update({_id: user._id}, {$inc: inc, $set: set}).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
let query = {
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2020-10-01')},
|
||||
};
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
items: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.166.0",
|
||||
"version": "4.168.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.11.6",
|
||||
"@babel/preset-env": "^7.11.5",
|
||||
"@babel/register": "^7.11.5",
|
||||
"@babel/core": "^7.12.3",
|
||||
"@babel/preset-env": "^7.12.1",
|
||||
"@babel/register": "^7.12.1",
|
||||
"@google-cloud/trace-agent": "^5.1.1",
|
||||
"@slack/client": "^4.12.0",
|
||||
"accepts": "^1.3.5",
|
||||
@@ -30,7 +30,7 @@
|
||||
"express-basic-auth": "^1.1.5",
|
||||
"express-validator": "^5.2.0",
|
||||
"glob": "^7.1.6",
|
||||
"got": "^11.7.0",
|
||||
"got": "^11.8.0",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-babel": "^8.0.0",
|
||||
"gulp-imagemin": "^7.1.0",
|
||||
@@ -38,17 +38,17 @@
|
||||
"gulp.spritesmith": "^6.9.0",
|
||||
"habitica-markdown": "^3.0.0",
|
||||
"helmet": "^3.23.3",
|
||||
"image-size": "^0.9.1",
|
||||
"image-size": "^0.9.2",
|
||||
"in-app-purchase": "^1.11.3",
|
||||
"js2xmlparser": "^4.0.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jwks-rsa": "^1.10.1",
|
||||
"jwks-rsa": "^1.11.0",
|
||||
"lodash": "^4.17.20",
|
||||
"merge-stream": "^2.0.0",
|
||||
"method-override": "^3.0.0",
|
||||
"moment": "^2.29.1",
|
||||
"moment-recur": "^1.0.7",
|
||||
"mongoose": "^5.10.9",
|
||||
"mongoose": "^5.10.10",
|
||||
"morgan": "^1.10.0",
|
||||
"nconf": "^0.10.0",
|
||||
"node-gcm": "^1.0.3",
|
||||
@@ -60,7 +60,7 @@
|
||||
"paypal-rest-sdk": "^1.8.1",
|
||||
"pp-ipn": "^1.1.0",
|
||||
"ps-tree": "^1.0.0",
|
||||
"rate-limiter-flexible": "^2.1.10",
|
||||
"rate-limiter-flexible": "^2.1.13",
|
||||
"redis": "^3.0.2",
|
||||
"regenerator-runtime": "^0.13.7",
|
||||
"remove-markdown": "^0.3.0",
|
||||
@@ -109,7 +109,7 @@
|
||||
"apidoc": "gulp apidoc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"axios": "^0.21.0",
|
||||
"chai": "^4.1.2",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chai-moment": "^0.1.0",
|
||||
|
||||
@@ -8,5 +8,10 @@ describe('stringUtils', () => {
|
||||
const matches = getMatchesByWordArray(message, bannedWords);
|
||||
expect(matches.length).to.equal(bannedWords.length);
|
||||
});
|
||||
it('doesn\'t flag names with accented characters', () => {
|
||||
const name = 'TESTPLACEHOLDERSWEARWORDHEREé';
|
||||
const matches = getMatchesByWordArray(name, bannedWords);
|
||||
expect(matches.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -311,25 +311,8 @@ describe('cron middleware', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not enroll 50% of users', async () => {
|
||||
sandbox.stub(Math, 'random').returns(0.6);
|
||||
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||
await user.save();
|
||||
req.headers['x-client'] = 'habitica-web';
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
cronMiddleware(req, res, async err => {
|
||||
if (err) return reject(err);
|
||||
user = await User.findById(user._id).exec();
|
||||
expect(user._ABtests.dropCapNotif).to.be.equal('drop-cap-notif-not-enrolled');
|
||||
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('enables the new notification for 25% of users', async () => {
|
||||
sandbox.stub(Math, 'random').returns(0.25);
|
||||
it('enables the new notification for 50% of users', async () => {
|
||||
sandbox.stub(Math, 'random').returns(0.5);
|
||||
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||
await user.save();
|
||||
req.headers['x-client'] = 'habitica-web';
|
||||
@@ -345,8 +328,8 @@ describe('cron middleware', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('disables the new notification for 25% of users', async () => {
|
||||
sandbox.stub(Math, 'random').returns(0.5);
|
||||
it('disables the new notification for 50% of users', async () => {
|
||||
sandbox.stub(Math, 'random').returns(0.51);
|
||||
user.lastCron = moment(new Date()).subtract({ days: 2 });
|
||||
await user.save();
|
||||
req.headers['x-client'] = 'habitica-web';
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
generateUser,
|
||||
requester,
|
||||
translate as t,
|
||||
} from '../../../../helpers/api-integration/v3';
|
||||
import { mockAnalyticsService as analytics } from '../../../../../website/server/libs/analyticsService';
|
||||
|
||||
describe('POST /analytics/track/:eventName', () => {
|
||||
it('requires authentication', async () => {
|
||||
await expect(requester().post('/analytics/track/event')).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('missingAuthHeaders'),
|
||||
});
|
||||
});
|
||||
|
||||
it('calls res.analytics', async () => {
|
||||
const user = await generateUser();
|
||||
sandbox.spy(analytics, 'track');
|
||||
|
||||
const requestWithHeaders = requester(user, { 'x-client': 'habitica-web' });
|
||||
await requestWithHeaders.post('/analytics/track/eventName', { data: 'example' }, { 'x-client': 'habitica-web' });
|
||||
expect(analytics.track).to.be.calledOnce;
|
||||
expect(analytics.track).to.be.calledWith('eventName', sandbox.match({ data: 'example' }));
|
||||
|
||||
sandbox.restore();
|
||||
});
|
||||
});
|
||||
@@ -251,6 +251,29 @@ describe('POST /groups/:groupId/removeMember/:memberId', () => {
|
||||
expect(party.quest.members[partyMember._id]).to.not.exist;
|
||||
});
|
||||
|
||||
it('prevents user from being removed if they are the quest owner', async () => {
|
||||
const petQuest = 'whale';
|
||||
await partyMember.update({
|
||||
[`items.quests.${petQuest}`]: 1,
|
||||
});
|
||||
|
||||
await partyMember.post(`/groups/${party._id}/quests/invite/${petQuest}`);
|
||||
await partyLeader.post(`/groups/${party._id}/quests/accept`);
|
||||
|
||||
await party.sync();
|
||||
|
||||
expect(party.quest.members[partyLeader._id]).to.be.true;
|
||||
expect(party.quest.members[partyMember._id]).to.be.true;
|
||||
|
||||
await party.sync();
|
||||
|
||||
expect(leader.post(`/groups/${party._id}/removeMember/${partyMember._id}`))
|
||||
.to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
text: t('cannotRemoveQuestOwner'),
|
||||
});
|
||||
});
|
||||
|
||||
it('sends email to user with rescinded invite', async () => {
|
||||
await partyLeader.post(`/groups/${party._id}/removeMember/${partyInvitedUser._id}`);
|
||||
|
||||
|
||||
@@ -83,22 +83,6 @@ describe('POST /groups/:groupId/quests/invite/:questKey', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not issue invites if the user is of insufficient Level', async () => {
|
||||
const LEVELED_QUEST = 'atom1';
|
||||
const LEVELED_QUEST_REQ = questScrolls[LEVELED_QUEST].lvl;
|
||||
const leaderUpdate = {};
|
||||
leaderUpdate[`items.quests.${LEVELED_QUEST}`] = 1;
|
||||
leaderUpdate['stats.lvl'] = LEVELED_QUEST_REQ - 1;
|
||||
|
||||
await leader.update(leaderUpdate);
|
||||
|
||||
await expect(leader.post(`/groups/${questingGroup._id}/quests/invite/${LEVELED_QUEST}`)).to.eventually.be.rejected.and.eql({
|
||||
code: 401,
|
||||
error: 'NotAuthorized',
|
||||
message: t('questLevelTooHigh', { level: LEVELED_QUEST_REQ }),
|
||||
});
|
||||
});
|
||||
|
||||
it('does not issue invites if a quest is already underway', async () => {
|
||||
const QUEST_IN_PROGRESS = 'atom1';
|
||||
const leaderUpdate = {};
|
||||
@@ -212,6 +196,18 @@ describe('POST /groups/:groupId/quests/invite/:questKey', () => {
|
||||
expect(returnedGroup.chat[0]._meta).to.be.undefined;
|
||||
});
|
||||
|
||||
it('successfully issues a quest invitation when quest level is higher than user level', async () => {
|
||||
const LEVELED_QUEST = 'atom1';
|
||||
const LEVELED_QUEST_REQ = questScrolls[LEVELED_QUEST].lvl;
|
||||
const leaderUpdate = {};
|
||||
leaderUpdate[`items.quests.${LEVELED_QUEST}`] = 1;
|
||||
leaderUpdate['stats.lvl'] = LEVELED_QUEST_REQ - 1;
|
||||
|
||||
await leader.update(leaderUpdate);
|
||||
|
||||
await leader.post(`/groups/${questingGroup._id}/quests/invite/${LEVELED_QUEST}`);
|
||||
});
|
||||
|
||||
context('sending quest activity webhooks', () => {
|
||||
before(async () => {
|
||||
await server.start();
|
||||
|
||||
@@ -91,7 +91,9 @@ describe('POST /tasks/:taskId/move/to/:position', () => {
|
||||
|
||||
const taskToMove = tasks[1];
|
||||
expect(taskToMove.text).to.equal('habit 2');
|
||||
const newOrder = await user.post(`/tasks/${tasks[1]._id}/move/to/-1`);
|
||||
await user.post(`/tasks/${tasks[1]._id}/move/to/-1`);
|
||||
await user.sync();
|
||||
const newOrder = user.tasksOrder.habits;
|
||||
expect(newOrder[4]).to.equal(taskToMove._id);
|
||||
expect(newOrder.length).to.equal(5);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../../helpers/api-integration/v4';
|
||||
import { UNEQUIP_EQUIPPED } from '../../../../website/common/script/ops/unequip';
|
||||
|
||||
describe('POST /user/unequip', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(async () => {
|
||||
user = await generateUser({
|
||||
preferences: {
|
||||
background: 'violet',
|
||||
},
|
||||
items: {
|
||||
currentMount: 'BearCub-Base',
|
||||
currentPet: 'BearCub-Base',
|
||||
gear: {
|
||||
owned: {
|
||||
weapon_warrior_0: true,
|
||||
weapon_warrior_1: true,
|
||||
weapon_warrior_2: true,
|
||||
weapon_wizard_1: true,
|
||||
weapon_wizard_2: true,
|
||||
shield_base_0: true,
|
||||
shield_warrior_1: true,
|
||||
},
|
||||
equipped: {
|
||||
weapon: 'weapon_warrior_2',
|
||||
shield: 'shield_warrior_1',
|
||||
},
|
||||
costume: {
|
||||
weapon: 'weapon_warrior_2',
|
||||
shield: 'shield_warrior_1',
|
||||
},
|
||||
},
|
||||
},
|
||||
stats: { gp: 200 },
|
||||
});
|
||||
});
|
||||
|
||||
// More tests in common code unit tests
|
||||
|
||||
context('Gear', () => {
|
||||
it('should unequip all battle gear items', async () => {
|
||||
await user.post(`/user/unequip/${UNEQUIP_EQUIPPED}`);
|
||||
await user.sync();
|
||||
|
||||
expect(user.items.gear.equipped.weapon).to.eq('weapon_base_0');
|
||||
expect(user.items.gear.equipped.shield).to.eq('shield_base_0');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,100 @@
|
||||
/* eslint-disable camelcase */
|
||||
|
||||
import {
|
||||
generateUser,
|
||||
} from '../../helpers/common.helper';
|
||||
import {
|
||||
UNEQUIP_ALL,
|
||||
UNEQUIP_BACKGROUND,
|
||||
UNEQUIP_COSTUME,
|
||||
UNEQUIP_EQUIPPED,
|
||||
UNEQUIP_PET_MOUNT,
|
||||
unEquipByType,
|
||||
} from '../../../website/common/script/ops/unequip';
|
||||
|
||||
describe('shared.ops.unequip', () => {
|
||||
let user;
|
||||
|
||||
beforeEach(() => {
|
||||
user = generateUser({
|
||||
preferences: {
|
||||
background: 'violet',
|
||||
},
|
||||
items: {
|
||||
currentMount: 'BearCub-Base',
|
||||
currentPet: 'BearCub-Base',
|
||||
gear: {
|
||||
owned: {
|
||||
weapon_warrior_0: true,
|
||||
weapon_warrior_1: true,
|
||||
weapon_warrior_2: true,
|
||||
weapon_wizard_1: true,
|
||||
weapon_wizard_2: true,
|
||||
shield_base_0: true,
|
||||
shield_warrior_1: true,
|
||||
},
|
||||
equipped: {
|
||||
weapon: 'weapon_warrior_2',
|
||||
shield: 'shield_warrior_1',
|
||||
},
|
||||
costume: {
|
||||
weapon: 'weapon_warrior_2',
|
||||
shield: 'shield_warrior_1',
|
||||
},
|
||||
},
|
||||
},
|
||||
stats: { gp: 200 },
|
||||
});
|
||||
});
|
||||
|
||||
context('Gear', () => {
|
||||
it('should unequip all battle gear items', () => {
|
||||
unEquipByType(user, { params: { type: UNEQUIP_EQUIPPED } });
|
||||
|
||||
expect(user.items.gear.equipped.weapon).to.eq('weapon_base_0');
|
||||
expect(user.items.gear.equipped.shield).to.eq('shield_base_0');
|
||||
});
|
||||
});
|
||||
|
||||
context('Costume', () => {
|
||||
it('should unequip all costume items', () => {
|
||||
unEquipByType(user, { params: { type: UNEQUIP_COSTUME } });
|
||||
|
||||
expect(user.items.gear.costume.weapon).to.eq('weapon_base_0');
|
||||
expect(user.items.gear.costume.shield).to.eq('shield_base_0');
|
||||
});
|
||||
});
|
||||
|
||||
context('Pet and Mount', () => {
|
||||
it('should unequip Pet and Mount', () => {
|
||||
unEquipByType(user, { params: { type: UNEQUIP_PET_MOUNT } });
|
||||
|
||||
expect(user.items.currentMount).to.eq('');
|
||||
expect(user.items.currentPet).to.eq('');
|
||||
});
|
||||
});
|
||||
|
||||
context('Background', () => {
|
||||
it('should unequip Background', () => {
|
||||
unEquipByType(user, { params: { type: UNEQUIP_BACKGROUND } });
|
||||
|
||||
expect(user.preferences.background).to.eq('');
|
||||
});
|
||||
});
|
||||
|
||||
context('All Items', () => {
|
||||
it('should unequip all Items', () => {
|
||||
unEquipByType(user, { params: { type: UNEQUIP_ALL } });
|
||||
|
||||
expect(user.items.gear.equipped.weapon).to.eq('weapon_base_0');
|
||||
expect(user.items.gear.equipped.shield).to.eq('shield_base_0');
|
||||
|
||||
expect(user.items.gear.costume.weapon).to.eq('weapon_base_0');
|
||||
expect(user.items.gear.costume.shield).to.eq('shield_base_0');
|
||||
|
||||
expect(user.items.currentMount).to.eq('');
|
||||
expect(user.items.currentPet).to.eq('');
|
||||
expect(user.preferences.background).to.eq('');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -41,6 +41,7 @@ function _requestMaker (user, method, additionalSets = {}) {
|
||||
|| route.indexOf('/amazon') === 0
|
||||
|| route.indexOf('/stripe') === 0
|
||||
|| route.indexOf('/qr-code') === 0
|
||||
|| route.indexOf('/analytics') === 0
|
||||
) {
|
||||
url += `${route}`;
|
||||
} else {
|
||||
|
||||
@@ -50,4 +50,5 @@ function loadStories () {
|
||||
req.keys().forEach(filename => req(filename));
|
||||
}
|
||||
|
||||
|
||||
configure(loadStories, module);
|
||||
|
||||
@@ -18,18 +18,18 @@
|
||||
"@storybook/addon-links": "^5.3.19",
|
||||
"@storybook/addon-notes": "^5.3.21",
|
||||
"@storybook/vue": "^5.3.19",
|
||||
"@vue/cli-plugin-babel": "^4.5.7",
|
||||
"@vue/cli-plugin-eslint": "^4.5.7",
|
||||
"@vue/cli-plugin-router": "^4.5.7",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.5.7",
|
||||
"@vue/cli-service": "^4.5.7",
|
||||
"@vue/cli-plugin-babel": "^4.5.8",
|
||||
"@vue/cli-plugin-eslint": "^4.5.8",
|
||||
"@vue/cli-plugin-router": "^4.5.8",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.5.8",
|
||||
"@vue/cli-service": "^4.5.8",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"amplitude-js": "^7.2.2",
|
||||
"axios": "^0.19.2",
|
||||
"amplitude-js": "^7.3.0",
|
||||
"axios": "^0.21.0",
|
||||
"axios-progress-bar": "^1.2.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"bootstrap": "^4.5.2",
|
||||
"bootstrap-vue": "^2.17.3",
|
||||
"bootstrap": "^4.5.3",
|
||||
"bootstrap-vue": "^2.18.1",
|
||||
"chai": "^4.1.2",
|
||||
"core-js": "^3.6.5",
|
||||
"eslint": "^6.8.0",
|
||||
@@ -56,9 +56,9 @@
|
||||
"vue": "^2.6.12",
|
||||
"vue-cli-plugin-storybook": "^0.6.1",
|
||||
"vue-mugen-scroll": "^0.2.6",
|
||||
"vue-router": "^3.4.6",
|
||||
"vue-router": "^3.4.8",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"vuedraggable": "^2.24.1",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#153d339e4dbebb73733658aeda1d5b7fcc55b0a0",
|
||||
"webpack": "^4.44.2"
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 555 KiB After Width: | Height: | Size: 545 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 322 KiB |
|
Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 352 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 173 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 349 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 172 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 187 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 150 KiB |
@@ -2,13 +2,15 @@
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
color: $gray-200;
|
||||
padding: 4px 8px;
|
||||
text-align: center;
|
||||
color: $gray-100;
|
||||
|
||||
padding: 0.25rem 0.5rem;
|
||||
box-shadow: 0 1px 3px 0 rgba($black, 0.12), 0 1px 2px 0 rgba($black, 0.24);
|
||||
}
|
||||
|
||||
.badge-pill {
|
||||
border-radius: 100px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.badge-round {
|
||||
@@ -18,7 +20,7 @@
|
||||
}
|
||||
|
||||
.badge-default {
|
||||
background: $gray-500;
|
||||
background: $gray-600;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
font-weight: bold;
|
||||
line-height: 1.71;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.219rem 1rem;
|
||||
padding: 0.219rem 0.75rem;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 3px 0 rgba($black, 0.12), 0 1px 2px 0 rgba($black, 0.24);
|
||||
color: $white;
|
||||
@@ -22,7 +22,7 @@
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:active, &.active:not(.btn-flat), &:disabled, &.disabled {
|
||||
&:active, &.active:not(.btn-flat) {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
&.with-icon {
|
||||
height: 2rem; // otherwise would something set the height to 33px
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-front {
|
||||
@@ -41,34 +48,49 @@
|
||||
.btn-primary {
|
||||
background: $purple-200;
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:hover:not(:disabled):not(.disabled) {
|
||||
background: #5d3b9c;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
--icon-color: #{$purple-500};
|
||||
|
||||
&:focus {
|
||||
background: $purple-200;
|
||||
border-color: $purple-400;
|
||||
--icon-color: #{$white};
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled) {
|
||||
&:hover {
|
||||
background: #5d3b9c;
|
||||
border: 1px solid transparent;
|
||||
|
||||
--icon-color: #{$white};
|
||||
}
|
||||
|
||||
&:active, &.active {
|
||||
background: $purple-200;
|
||||
border: 1px solid transparent;
|
||||
|
||||
--icon-color: #{$white};
|
||||
}
|
||||
|
||||
&:active:focus, &.active:focus {
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active {
|
||||
background: $purple-200;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
background: $purple-200;
|
||||
background: $gray-700;
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
color: $gray-50;
|
||||
|
||||
--icon-color: #{$gray-300};
|
||||
}
|
||||
|
||||
|
||||
&.with-icon {
|
||||
.svg-icon.color {
|
||||
color: var(--icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,29 +102,27 @@
|
||||
border: 1px solid transparent;
|
||||
color: $gray-50;
|
||||
|
||||
--icon-color: #{$gray-200};
|
||||
|
||||
&:focus, &:active {
|
||||
color: $gray-50;
|
||||
background: $white;
|
||||
border-color: $purple-400;
|
||||
|
||||
--icon-color: #{$purple-300};
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled) {
|
||||
&:active:focus,
|
||||
&.active:focus {
|
||||
&:active, &.active {
|
||||
color: $purple-300;
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
--icon-color: #{$purple-300};
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
color: $purple-300;
|
||||
|
||||
&.dropdown-toggle {
|
||||
color: $gray-50;
|
||||
&:focus {
|
||||
color: $purple-300;
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
|
||||
background: $white;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
@@ -110,12 +130,10 @@
|
||||
&:hover {
|
||||
color: $purple-300;
|
||||
|
||||
&.dropdown-toggle {
|
||||
color: $gray-50;
|
||||
}
|
||||
|
||||
background: $white !important;
|
||||
border: 1px solid transparent;
|
||||
|
||||
--icon-color: #{$purple-300};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +143,14 @@
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
|
||||
--icon-color: #{$gray-300};
|
||||
}
|
||||
|
||||
&.with-icon {
|
||||
.svg-icon.color {
|
||||
color: var(--icon-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
.dropdown > .btn {
|
||||
padding: 0.25rem 0.75rem;
|
||||
padding: 0.219rem 0.75rem;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 1.43;
|
||||
}
|
||||
|
||||
.dropdown-toggle:hover {
|
||||
@@ -25,6 +24,8 @@
|
||||
border-right: 5px solid transparent;
|
||||
border-left: 5px solid transparent;
|
||||
vertical-align: 0;
|
||||
margin-left: 1rem;
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@@ -54,8 +55,8 @@
|
||||
|
||||
|
||||
&:active, &:hover, &:focus, &.active {
|
||||
background-color: rgba($purple-600, 0.32) !important;
|
||||
color: $purple-200 !important;
|
||||
background-color: rgba($purple-600, 0.25) !important;
|
||||
color: $purple-300 !important;
|
||||
}
|
||||
|
||||
&.dropdown-inactive {
|
||||
@@ -75,10 +76,17 @@
|
||||
.dropdown-label {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
line-height: 1.43;
|
||||
color: $gray-10;
|
||||
line-height: 1.71;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
|
||||
height: 1.5rem;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
text-align: right;
|
||||
|
||||
margin-top: calc(0.25rem + 1px); // Padding of the dropdown buttons + button border width
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.dropdown-icon-item {
|
||||
|
||||
@@ -42,11 +42,16 @@ input, textarea, input.form-control, textarea.form-control {
|
||||
}
|
||||
|
||||
&.input-search {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left 16px;
|
||||
background-size: 16px 16px;
|
||||
background-image: url(~@/assets/svg/for-css/search.svg);
|
||||
padding-left: 40px;
|
||||
height: 2rem;
|
||||
border-radius: 2px;
|
||||
border: solid 1px $gray-400;
|
||||
background-color: $white;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: 1.71;
|
||||
color: $gray-200;
|
||||
|
||||
padding: 0.25rem 1rem 0.25rem 0.75rem;
|
||||
}
|
||||
|
||||
&.input-valid, &.input-invalid {
|
||||
@@ -170,7 +175,7 @@ input, textarea, input.form-control, textarea.form-control {
|
||||
}
|
||||
|
||||
.form-check {
|
||||
margin-bottom: 0.5rem;
|
||||
margin-bottom: 0.875rem;
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
@@ -182,17 +187,21 @@ $bg-disabled-control: #34303a;
|
||||
margin-bottom: .5rem;
|
||||
|
||||
&-label {
|
||||
padding-top: 3px;
|
||||
padding-top: 2px;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.custom-control-label::before {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-size: 75% 75%;
|
||||
background-color: transparent;
|
||||
border: 2px solid $gray-200;
|
||||
transition-property: box-shadow;
|
||||
font-size: 14px;
|
||||
line-height: 1.71;
|
||||
color: $gray-50;
|
||||
|
||||
&::before {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-size: 75% 75%;
|
||||
background-color: transparent;
|
||||
border: 2px solid $gray-200;
|
||||
transition-property: box-shadow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.items > div:last-of-type {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.item-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@@ -45,14 +41,13 @@
|
||||
position: relative;
|
||||
width: 94px;
|
||||
height: 92px;
|
||||
border-radius: 2px;
|
||||
border-radius: 4px;
|
||||
background: $white;
|
||||
box-shadow: 0 1px 3px 0 rgba($black, 0.12), 0 1px 2px 0 rgba($black, 0.24);
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
|
||||
&-empty {
|
||||
background: $gray-10;
|
||||
box-shadow: none;
|
||||
cursor: auto;
|
||||
}
|
||||
@@ -85,7 +80,7 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.drawer-content .item:hover {
|
||||
.drawer-content .item.item-empty:hover {
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
@@ -20,5 +20,18 @@ body {
|
||||
}
|
||||
|
||||
.page-header {
|
||||
color: $purple-200;
|
||||
color: $purple-300;
|
||||
|
||||
height: 2rem;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1.33;
|
||||
}
|
||||
|
||||
.sub-header {
|
||||
height: 1.75rem;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 1.4;
|
||||
color: $gray-10;
|
||||
}
|
||||
|
||||
@@ -46,12 +46,16 @@ a, a:not([href]):not([tabindex]) {
|
||||
}
|
||||
|
||||
// Headers
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
h1, h2, h5, h6 {
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
font-weight: bold;
|
||||
color: $gray-10;
|
||||
}
|
||||
|
||||
h3, h4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
line-height: 1.67;
|
||||
@@ -65,15 +69,15 @@ h2 {
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
color: $gray-50;
|
||||
margin-bottom: 4px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.71;
|
||||
color: $gray-10;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
line-height: 1.43;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.71;
|
||||
color: $gray-100;
|
||||
}
|
||||
|
||||
.textCondensed {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
// possible values are: normal, fall, habitoween, thanksgiving, winter, nye, birthday, valentines, normal, normal
|
||||
// more to be added on future seasons
|
||||
|
||||
$npc_market_flavor: 'fall';
|
||||
$npc_quests_flavor: 'fall';
|
||||
$npc_seasonal_flavor: 'fall';
|
||||
$npc_timetravelers_flavor: 'fall';
|
||||
$npc_tavern_flavor: 'fall';
|
||||
$npc_market_flavor: 'normal';
|
||||
$npc_quests_flavor: 'normal';
|
||||
$npc_seasonal_flavor: 'normal';
|
||||
$npc_timetravelers_flavor: 'normal';
|
||||
$npc_tavern_flavor: 'normal';
|
||||
|
||||
$menuToolbarHeight: 56px;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#878190;" d="M12,7.9h2c0,4.1-3,7.5-7,8.1h0h0c-4-0.6-7-4-7-8.1V3l7-3v2.2
|
||||
L2,4.3v3.6c0,2.9,2.1,5.5,5,6C9.9,13.4,12,10.9,12,7.9z M14,2V0h-2v2h-2v2h2v2h2V4h2V2H14z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 570 B |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#878190;" d="M12,7.9h2c0,4.1-3,7.5-7,8.1h0h0c-4-0.6-7-4-7-8.1V3l7-3v2.2
|
||||
L2,4.3v3.6c0,2.9,2.1,5.5,5,6C9.9,13.4,12,10.9,12,7.9z M10,6h6V4h-6V6z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 552 B |
@@ -225,31 +225,30 @@ export default {
|
||||
classGear (heroClass) {
|
||||
if (heroClass === 'rogue') {
|
||||
return {
|
||||
armor: 'armor_special_fall2020Rogue',
|
||||
head: 'head_special_fall2020Rogue',
|
||||
shield: 'shield_special_fall2020Rogue',
|
||||
weapon: 'weapon_special_fall2020Rogue',
|
||||
armor: 'armor_rogue_5',
|
||||
head: 'head_rogue_5',
|
||||
shield: 'shield_rogue_6',
|
||||
weapon: 'weapon_rogue_6',
|
||||
};
|
||||
} if (heroClass === 'wizard') {
|
||||
return {
|
||||
armor: 'armor_special_fall2020Mage',
|
||||
head: 'head_special_fall2020Mage',
|
||||
weapon: 'weapon_special_fall2020Mage',
|
||||
shield: 'shield_warrior_0',
|
||||
armor: 'armor_wizard_5',
|
||||
head: 'head_wizard_5',
|
||||
weapon: 'weapon_wizard_6',
|
||||
};
|
||||
} if (heroClass === 'healer') {
|
||||
return {
|
||||
armor: 'armor_special_fall2020Healer',
|
||||
head: 'head_special_fall2020Healer',
|
||||
shield: 'shield_special_fall2020Healer',
|
||||
weapon: 'weapon_special_fall2020Healer',
|
||||
armor: 'armor_healer_5',
|
||||
head: 'head_healer_5',
|
||||
shield: 'shield_healer_5',
|
||||
weapon: 'weapon_healer_6',
|
||||
};
|
||||
}
|
||||
return {
|
||||
armor: 'armor_special_fall2020Warrior',
|
||||
head: 'head_special_fall2020Warrior',
|
||||
shield: 'shield_special_fall2020Warrior',
|
||||
weapon: 'weapon_special_fall2020Warrior',
|
||||
armor: 'armor_warrior_5',
|
||||
head: 'head_warrior_5',
|
||||
shield: 'shield_warrior_5',
|
||||
weapon: 'weapon_warrior_6',
|
||||
};
|
||||
},
|
||||
selectionBox (selectedClass, heroClass) {
|
||||
|
||||
@@ -232,7 +232,7 @@ export default {
|
||||
eventCategory: 'drop-cap-reached',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Drop Cap Reached > Modal > Wiki',
|
||||
});
|
||||
}, { trackOnServer: true });
|
||||
},
|
||||
toLearnMore () {
|
||||
Analytics.track({
|
||||
@@ -240,7 +240,7 @@ export default {
|
||||
eventCategory: 'drop-cap-reached',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Drop Cap Reached > Modal > Subscriptions',
|
||||
});
|
||||
}, { trackOnServer: true });
|
||||
|
||||
this.close();
|
||||
this.$router.push('/user/settings/subscription');
|
||||
|
||||
@@ -745,6 +745,7 @@ export default {
|
||||
watch: {
|
||||
$route: {
|
||||
handler () {
|
||||
this.setTitle();
|
||||
if (this.resetPasswordSetNewOne) {
|
||||
const { query } = this.$route;
|
||||
const { code } = query;
|
||||
@@ -760,7 +761,6 @@ export default {
|
||||
this.$router.push({ name: 'login' });
|
||||
return;
|
||||
}
|
||||
|
||||
this.resetPasswordSetNewOneData.code = query.code;
|
||||
this.resetPasswordSetNewOneData.hasError = hasError;
|
||||
}
|
||||
@@ -898,6 +898,18 @@ export default {
|
||||
window.location.href = redirectTo;
|
||||
}
|
||||
},
|
||||
setTitle () {
|
||||
if (this.resetPasswordSetNewOne) {
|
||||
return;
|
||||
}
|
||||
let title = 'login';
|
||||
if (this.registering) {
|
||||
title = 'register';
|
||||
}
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t(title),
|
||||
});
|
||||
},
|
||||
handleSubmit () {
|
||||
if (this.registering) {
|
||||
this.register();
|
||||
|
||||
@@ -384,6 +384,16 @@ export default {
|
||||
memberResults: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'challenge.name': {
|
||||
handler (newVal) {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t('challenge'),
|
||||
subSection: newVal.name,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
isMember () {
|
||||
@@ -433,6 +443,10 @@ export default {
|
||||
this.$router.push('/challenges/findChallenges');
|
||||
return;
|
||||
}
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.challenge.name,
|
||||
section: this.$t('challenges'),
|
||||
});
|
||||
const tasks = await this.$store.dispatch('tasks:getChallengeTasks', { challengeId: this.searchId });
|
||||
this.tasksByType = {
|
||||
habit: [],
|
||||
|
||||
@@ -175,6 +175,10 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.$t('findChallenges'),
|
||||
section: this.$t('challenges'),
|
||||
});
|
||||
this.loadChallenges();
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -218,6 +218,10 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.$t('myChallenges'),
|
||||
section: this.$t('challenges'),
|
||||
});
|
||||
this.loadChallenges();
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<div
|
||||
ref="markdownContainer"
|
||||
class="text markdown"
|
||||
dir="auto"
|
||||
v-html="parseMarkdown(msg.text)"
|
||||
></div>
|
||||
<hr>
|
||||
@@ -164,7 +165,7 @@
|
||||
.text {
|
||||
font-size: 14px;
|
||||
color: #4e4a57;
|
||||
text-align: left !important;
|
||||
text-align: initial;
|
||||
min-height: 0rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,10 @@ export default {
|
||||
this.group = await this.$store.dispatch('guilds:getGroup', {
|
||||
groupId: this.searchId,
|
||||
});
|
||||
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.group.name,
|
||||
section: this.$t('group'),
|
||||
});
|
||||
const members = await this.$store.dispatch('members:getGroupMembers', { groupId: this.searchId });
|
||||
this.group.members = members;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<textarea
|
||||
ref="user-entry"
|
||||
v-model="newMessage"
|
||||
dir="auto"
|
||||
:placeholder="placeholder"
|
||||
:class="{'user-entry': newMessage}"
|
||||
:maxlength="MAX_MESSAGE_LENGTH"
|
||||
|
||||
@@ -155,6 +155,12 @@ export default {
|
||||
return this.guilds.filter(guild => filterGuild(guild, filters, search, user));
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.$t('guildsDiscovery'),
|
||||
section: this.$t('guilds'),
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async updateSearch (eventData) {
|
||||
// this.search = eventData.searchTerm; @TODO: Probably don't need this anymore
|
||||
|
||||
@@ -500,7 +500,10 @@ export default {
|
||||
if (this.isParty) this.searchId = 'party';
|
||||
if (!this.searchId) this.searchId = this.groupId;
|
||||
await this.fetchGuild();
|
||||
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t('groupPlans'),
|
||||
subSection: this.group.name,
|
||||
});
|
||||
this.$root.$on('updatedGroup', this.onGroupUpdate);
|
||||
},
|
||||
beforeDestroy () {
|
||||
@@ -508,7 +511,6 @@ export default {
|
||||
},
|
||||
beforeRouteUpdate (to, from, next) {
|
||||
this.$set(this, 'searchId', to.params.groupId);
|
||||
|
||||
next();
|
||||
},
|
||||
methods: {
|
||||
@@ -518,6 +520,10 @@ export default {
|
||||
onGroupUpdate (group) {
|
||||
const updatedGroup = extend(this.group, group);
|
||||
this.$set(this.group, updatedGroup);
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t('groupPlans'),
|
||||
subSection: group.name,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -486,6 +486,9 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
this.activePage = this.PAGES.BENEFITS;
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
section: this.$t('groupPlans'),
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
launchModal () {
|
||||
|
||||
@@ -165,6 +165,12 @@ export default {
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.$t('myGuilds'),
|
||||
section: this.$t('guilds'),
|
||||
});
|
||||
},
|
||||
created () {
|
||||
this.fetchGuilds();
|
||||
},
|
||||
|
||||
@@ -843,6 +843,10 @@ export default {
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
this.$store.dispatch('common:setTitle', {
|
||||
subSection: this.$t('tavern'),
|
||||
section: this.$t('guilds'),
|
||||
});
|
||||
this.group = await this.$store.dispatch('guilds:getGroup', { groupId: TAVERN_ID });
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -36,7 +36,7 @@ export default {
|
||||
eventCategory: 'drop-cap-reached',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'Drop Cap Reached > Notification Click',
|
||||
});
|
||||
}, { trackOnServer: true });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -183,7 +183,7 @@ export default {
|
||||
eventCategory: 'button',
|
||||
eventAction: 'click',
|
||||
eventLabel: 'User Dropdown > Subscriptions',
|
||||
});
|
||||
}, { trackOnServer: true });
|
||||
|
||||
this.$router.push({ name: 'subscription' });
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
v-for="attr in ATTRIBUTES"
|
||||
:key="attr"
|
||||
class="popover-content-attr"
|
||||
:class="`attr-${attr}`"
|
||||
>
|
||||
<div class="group-content">
|
||||
<span
|
||||
@@ -11,7 +12,7 @@
|
||||
:class="{'hasValue': hasSumValue(attr) }"
|
||||
>{{ `${$t(attr)}: ` }}</span>
|
||||
<span
|
||||
class="popover-content-attr-cell label value"
|
||||
class="popover-content-attr-cell label key-value value"
|
||||
:class="{'green': hasSumValue(attr) }"
|
||||
>{{ `${stats.sum[attr]}` }}</span>
|
||||
<span
|
||||
@@ -53,6 +54,16 @@
|
||||
width: calc(50% - 1px);
|
||||
background-color: $gray-50;
|
||||
|
||||
.attr-str, .attr-int {
|
||||
padding-top: 0.25rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.attr-con, .attr-per {
|
||||
padding-bottom: 0.75rem;
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
&:nth-of-type(even) {
|
||||
margin-left: 1px;
|
||||
}
|
||||
@@ -70,12 +81,12 @@
|
||||
}
|
||||
|
||||
.popover-content-attr-cell {
|
||||
width: 70%;
|
||||
width: 65%;
|
||||
text-align: left;
|
||||
|
||||
&:nth-of-type(even) {
|
||||
text-align: right;
|
||||
width: 30%;
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
&.key {
|
||||
@@ -115,7 +126,7 @@
|
||||
.modal-body {
|
||||
|
||||
.group-content {
|
||||
padding: 8px 17px;
|
||||
padding: 0.25rem 1rem;
|
||||
}
|
||||
|
||||
.popover-content-attr {
|
||||
@@ -129,32 +140,43 @@
|
||||
|
||||
.popover-content-attr-cell {
|
||||
&.key {
|
||||
color: $gray-400;
|
||||
font-size: 16px;
|
||||
color: $gray-100;
|
||||
font-size: 0.875rem;
|
||||
font-weight: bold;
|
||||
line-height: 1.25;
|
||||
line-height: 1.71;
|
||||
|
||||
opacity: 0.5;
|
||||
|
||||
&.hasValue {
|
||||
color: $gray-50;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.label {
|
||||
color: $gray-400;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: $gray-100;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.33;
|
||||
opacity: 0.5;
|
||||
|
||||
&.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&.key-value {
|
||||
line-height: 1.71;
|
||||
}
|
||||
|
||||
&.hasValue {
|
||||
color: $gray-200;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.label.value {
|
||||
text-align: right;
|
||||
|
||||
&.green {
|
||||
color: $green-10;
|
||||
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,11 @@
|
||||
id="equipgear-modal"
|
||||
:visible="true"
|
||||
:hide-header="true"
|
||||
:hide-footer="true"
|
||||
@change="onChange($event)"
|
||||
>
|
||||
<div class="close">
|
||||
<span
|
||||
class="svg-icon inline icon-10"
|
||||
aria-hidden="true"
|
||||
@click="hideDialog()"
|
||||
v-html="icons.close"
|
||||
></span>
|
||||
<div class="dialog-close">
|
||||
<close-icon @click="hideDialog()" />
|
||||
</div>
|
||||
<div
|
||||
v-if="item != null"
|
||||
@@ -23,11 +19,12 @@
|
||||
:member="user"
|
||||
:avatar-only="true"
|
||||
:with-background="true"
|
||||
:hide-class-badge="true"
|
||||
:override-avatar-gear="memberOverrideAvatarGear(item)"
|
||||
:sprites-margin="'0px auto auto -1px'"
|
||||
:show-visual-buffs="false"
|
||||
/>
|
||||
<h4 class="title">
|
||||
<h4 class="title mt-3">
|
||||
{{ itemText }}
|
||||
</h4>
|
||||
<div
|
||||
@@ -36,14 +33,14 @@
|
||||
></div>
|
||||
<span
|
||||
v-if="showClassTag"
|
||||
class="classTag"
|
||||
class="classTag mt-3"
|
||||
>
|
||||
<span
|
||||
class="svg-icon inline icon-24"
|
||||
class="svg-icon inline icon-16"
|
||||
v-html="icons[itemClass]"
|
||||
></span>
|
||||
<span
|
||||
class="className textCondensed"
|
||||
class="className"
|
||||
:class="itemClass"
|
||||
>{{ getClassName(itemClass) }}</span>
|
||||
</span>
|
||||
@@ -54,10 +51,17 @@
|
||||
:item="item"
|
||||
/>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
class="btn with-icon mt-4"
|
||||
:class="{'btn-primary': !isEquipped, 'btn-secondary': isEquipped }"
|
||||
@click="equipItem()"
|
||||
>
|
||||
{{ $t(isEquipped ? 'unequip' : 'equip') }}
|
||||
<span
|
||||
class="svg-icon color inline icon-16 mr-2"
|
||||
v-html="isEquipped ? icons.unEquip : icons.equip"
|
||||
></span>
|
||||
<span class="button-label">
|
||||
{{ $t(isEquipped ? 'unequip' : 'equip') }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -69,15 +73,38 @@
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
@import '~@/assets/scss/mixins.scss';
|
||||
|
||||
#equipgear-modal {
|
||||
@include centeredModal();
|
||||
|
||||
.modal-content {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 14px 28px 0 #1a181d3d, 0 10px 10px 0 #1a181d47;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 2rem 1.5rem;
|
||||
}
|
||||
|
||||
.dialog-close {
|
||||
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
width: 330px;
|
||||
|
||||
.text {
|
||||
min-height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.71;
|
||||
text-align: center;
|
||||
color: $gray-50;
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -89,7 +116,6 @@
|
||||
}
|
||||
|
||||
.inner-content {
|
||||
margin: 33px auto auto;
|
||||
width: 282px;
|
||||
}
|
||||
|
||||
@@ -102,10 +128,11 @@
|
||||
|
||||
.className {
|
||||
height: 24px;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.71;
|
||||
text-align: left;
|
||||
margin-left: 8px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.healer {
|
||||
@@ -124,10 +151,15 @@
|
||||
color: $wizard-color;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: $gray-10;
|
||||
}
|
||||
|
||||
.attributesGrid {
|
||||
background-color: $gray-500;
|
||||
|
||||
margin: 10px 0 24px;
|
||||
margin: 1rem 0 0;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #f4f4f4;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
@@ -139,9 +171,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
button.btn.btn-primary {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
button.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -154,14 +186,18 @@ import svgWarrior from '@/assets/svg/warrior.svg';
|
||||
import svgWizard from '@/assets/svg/wizard.svg';
|
||||
import svgRogue from '@/assets/svg/rogue.svg';
|
||||
import svgHealer from '@/assets/svg/healer.svg';
|
||||
import svgEquipIcon from '@/assets/svg/equip.svg';
|
||||
import svgUnEquipIcon from '@/assets/svg/unequip.svg';
|
||||
|
||||
import Avatar from '@/components/avatar';
|
||||
import attributesGrid from '@/components/inventory/equipment/attributesGrid.vue';
|
||||
import closeIcon from '@/components/shared/closeIcon';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Avatar,
|
||||
attributesGrid,
|
||||
closeIcon,
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
@@ -185,6 +221,8 @@ export default {
|
||||
wizard: svgWizard,
|
||||
rogue: svgRogue,
|
||||
healer: svgHealer,
|
||||
equip: svgEquipIcon,
|
||||
unEquip: svgUnEquipIcon,
|
||||
}),
|
||||
};
|
||||
},
|
||||
|
||||