Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0bab99c95 | |||
| 1405cf3ca5 | |||
| 048b60f79d | |||
| 5cd9528b77 | |||
| bceccd55bf | |||
| 0116c56abb | |||
| e6b65871e7 | |||
| 873ac53e27 | |||
| 51d20ef7e8 | |||
| 692d02984b | |||
| e31ce11052 | |||
| c4688b77fd | |||
| 9ab79ef225 | |||
| 7e4c8938e5 | |||
| 604b866113 | |||
| c0afae1e84 | |||
| 61dc94ada0 | |||
| f71ee7be18 | |||
| 8935885637 | |||
| 1ebda8281b | |||
| eae8ed946f | |||
| d7fe140012 | |||
| c317d1d040 | |||
| d63aafc7f1 | |||
| 08b2be684b | |||
| 4c653aa511 | |||
| 0896837528 | |||
| 8a1c1af461 | |||
| db7d1d0e14 | |||
| 6253359d31 | |||
| ce4bbe5552 | |||
| 3a4abac8b0 | |||
| 44eb245184 | |||
| 050fd15c97 | |||
| e1f1a264b4 | |||
| 3bfcc4a605 | |||
| 4beac98383 | |||
| 4da794271d | |||
| b18eb0d3f8 | |||
| 79f6f47b16 | |||
| 6ff8254137 | |||
| 1c00d7de5b | |||
| 61d970db86 | |||
| b911ecdcf0 | |||
| 74d0b25c54 | |||
| 830c4fb926 | |||
| 8aad136622 | |||
| 8d80792093 | |||
| 79f83d87d0 | |||
| c9bf157c23 | |||
| 3be42e9545 | |||
| 8a7b8f92d4 | |||
| e54425f947 | |||
| d953ea14da | |||
| 0c179fee2f | |||
| 05e229ccb0 | |||
| b29d937806 | |||
| 670b6a1563 | |||
| 44ded945dd | |||
| 08f1e2b273 | |||
| ca80f4ee33 | |||
| 65cbee9e75 | |||
| 0f8563c14e | |||
| c4117f99ed | |||
| 27aca19c8c | |||
| 80c18ffadd | |||
| bf2c4eb501 | |||
| ab1828c914 | |||
| b32f79f682 | |||
| 7b69289069 | |||
| a1fb80868f | |||
| 9d4fb80d15 | |||
| 43392f4952 | |||
| 6e46794822 | |||
| 43cad86201 | |||
| 734eae64a5 | |||
| 032c95d5c8 | |||
| b40411e219 | |||
| 86410f6bb7 | |||
| 8d2ada1463 | |||
| 95a3c932c5 | |||
| 51d1f6b86a | |||
| 809bacd10b | |||
| b0f29211a8 | |||
| 26f5bf554e | |||
| a1ec42c0b2 | |||
| 8674ea55f9 | |||
| c421da34cc | |||
| c9bed96077 | |||
| 1ccff7f1dd | |||
| 36461cbbdf | |||
| 85d290a1fa | |||
| 1bc756ee93 | |||
| ea44af0929 | |||
| 739963762e | |||
| b02ae35b28 | |||
| ace8e2f0bd | |||
| e90175b5d6 | |||
| 403fa18511 | |||
| ebd22296df | |||
| 613895e294 | |||
| 26437e7e2e |
@@ -10,6 +10,7 @@ dist/
|
||||
dist-client/
|
||||
apidoc_build/
|
||||
content_cache/
|
||||
i18n_cache/
|
||||
node_modules/
|
||||
|
||||
# Old migrations, disabled
|
||||
|
||||
@@ -8,13 +8,8 @@
|
||||
|
||||
# Requesting a feature
|
||||
|
||||
Habitica uses [Trello](https://trello.com/b/EpoYEYod/habitica) to track feature requests. [Read more](https://trello.com/c/odmhIqyW/440-read-first-table-of-contents).
|
||||
Habitica uses [this Google form](https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link) to track feature requests. Please post there rather than creating an issue.
|
||||
|
||||
# Contributing Code
|
||||
|
||||
See [Contributing to Habitica](http://habitica.fandom.com/wiki/Contributing_to_Habitica#Coders_.28Web_.26_Mobile.29)
|
||||
|
||||
## Issue Triage [](https://www.codetriage.com/habitrpg/habitica)
|
||||
|
||||
You can triage issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to habitrpg on CodeTriage](https://www.codetriage.com/habitrpg/habitica).
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Habitica  [](https://codeclimate.com/github/HabitRPG/habitrpg) [](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE) [](https://www.codetriage.com/habitrpg/habitica)
|
||||
Habitica  [](https://codeclimate.com/github/HabitRPG/habitrpg) [](https://www.bountysource.com/trackers/68393-habitrpg?utm_source=68393&utm_medium=shield&utm_campaign=TRACKER_BADGE)
|
||||
===============
|
||||
|
||||
[Habitica](https://habitica.com) is an open source habit building program which treats your life like a Role Playing Game. Level up as you succeed, lose HP as you fail, earn money to buy weapons and armor.
|
||||
|
||||
@@ -160,7 +160,7 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
|
||||
pipe(runner);
|
||||
}));
|
||||
|
||||
gulp.task('test:api:unit', done => {
|
||||
gulp.task('test:api:unit:run', done => {
|
||||
const runner = exec(
|
||||
testBin('istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
|
||||
err => {
|
||||
@@ -174,7 +174,7 @@ gulp.task('test:api:unit', done => {
|
||||
pipe(runner);
|
||||
});
|
||||
|
||||
gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done())));
|
||||
gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit:run', done => done())));
|
||||
|
||||
gulp.task('test:api-v3:integration', done => {
|
||||
const runner = exec(
|
||||
@@ -235,14 +235,22 @@ gulp.task('test', gulp.series(
|
||||
'test:sanity',
|
||||
'test:content',
|
||||
'test:common',
|
||||
'test:api:unit',
|
||||
'test:prepare:mongo',
|
||||
'test:api:unit:run',
|
||||
'test:api-v3:integration',
|
||||
'test:api-v4:integration',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
gulp.task('test:api-v3', gulp.series(
|
||||
'test:api:unit',
|
||||
'test:prepare:mongo',
|
||||
'test:api:unit:run',
|
||||
'test:api-v3:integration',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
gulp.task('test:api:unit', gulp.series(
|
||||
'test:prepare:mongo',
|
||||
'test:api:unit:run',
|
||||
done => done(),
|
||||
));
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.142.1",
|
||||
"version": "4.146.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.6",
|
||||
"@babel/preset-env": "^7.9.6",
|
||||
"@babel/register": "^7.9.0",
|
||||
"@google-cloud/trace-agent": "^4.2.5",
|
||||
"@babel/core": "^7.10.2",
|
||||
"@babel/preset-env": "^7.10.2",
|
||||
"@babel/register": "^7.10.1",
|
||||
"@google-cloud/trace-agent": "^5.0.0",
|
||||
"@slack/client": "^4.12.0",
|
||||
"accepts": "^1.3.5",
|
||||
"amazon-payments": "^0.2.8",
|
||||
@@ -36,8 +36,8 @@
|
||||
"gulp-imagemin": "^6.2.0",
|
||||
"gulp-nodemon": "^2.5.0",
|
||||
"gulp.spritesmith": "^6.9.0",
|
||||
"habitica-markdown": "^2.0.0",
|
||||
"helmet": "^3.22.0",
|
||||
"habitica-markdown": "^2.0.2",
|
||||
"helmet": "^3.23.0",
|
||||
"image-size": "^0.8.3",
|
||||
"in-app-purchase": "^1.11.3",
|
||||
"js2xmlparser": "^4.0.1",
|
||||
@@ -46,9 +46,9 @@
|
||||
"lodash": "^4.17.15",
|
||||
"merge-stream": "^2.0.0",
|
||||
"method-override": "^3.0.0",
|
||||
"moment": "^2.25.3",
|
||||
"moment": "^2.26.0",
|
||||
"moment-recur": "^1.0.7",
|
||||
"mongoose": "^5.9.13",
|
||||
"mongoose": "^5.9.18",
|
||||
"morgan": "^1.10.0",
|
||||
"nconf": "^0.10.0",
|
||||
"node-gcm": "^1.0.2",
|
||||
@@ -112,7 +112,7 @@
|
||||
"expect.js": "^0.3.1",
|
||||
"istanbul": "^1.1.0-alpha.1",
|
||||
"mocha": "^5.1.1",
|
||||
"monk": "^7.2.0",
|
||||
"monk": "^7.3.0",
|
||||
"require-again": "^2.0.0",
|
||||
"sinon": "^7.2.4",
|
||||
"sinon-chai": "^3.5.0",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
import highlightMentions from '../../../../website/server/libs/highlightMentions';
|
||||
|
||||
describe('highlightMentions', () => {
|
||||
@@ -100,6 +101,29 @@ describe('highlightMentions', () => {
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal('http://www.medium.com/@user/blog [@user](/profile/111)');
|
||||
});
|
||||
|
||||
// https://spec.commonmark.org/0.29/#example-483
|
||||
it('doesn\'t highlight user in a link without url', async () => {
|
||||
const text = '[@user2]()';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
// https://github.com/HabitRPG/habitica/issues/12217
|
||||
it('doesn\'t highlight user in link with url-escapable characters', async () => {
|
||||
const text = '[test](https://habitica.fandom.com/ru/@wiki/Снаряжение)';
|
||||
const result = await highlightMentions(text);
|
||||
expect(result[0]).to.equal(text);
|
||||
});
|
||||
|
||||
// https://github.com/HabitRPG/habitica/issues/12223
|
||||
it('matches a link in between two the same links', async () => {
|
||||
const text = '[here](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)\n@user\n[hier](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)';
|
||||
|
||||
const result = await highlightMentions(text);
|
||||
|
||||
expect(result[0]).to.equal('[here](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)\n[@user](/profile/111)\n[hier](http://habitica.wikia.com/wiki/The_Keep:Pirate_Cove/FAQ)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('exceptions in code blocks', () => {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"test": {
|
||||
plugins: [
|
||||
["istanbul"],
|
||||
],
|
||||
},
|
||||
},
|
||||
"presets": [
|
||||
["es2015", { modules: false }],
|
||||
],
|
||||
"plugins": [
|
||||
"transform-object-rest-spread",
|
||||
],
|
||||
"comments": false,
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// TODO verify if it's needed, added because Axios require Promise in the global scope
|
||||
// and babel-runtime doesn't affect external libraries
|
||||
require('babel-polyfill');
|
||||
|
||||
// Automatically setup SinonJS' sandbox for each test
|
||||
beforeEach(() => {
|
||||
global.sandbox = sinon.createSandbox();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.sandbox.restore();
|
||||
});
|
||||
|
||||
// require all test files
|
||||
const testsContext = require.context('./specs', true, /\.js$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
|
||||
// require all .vue and .js files except main.js for coverage.
|
||||
const srcContext = require.context('../../../website/client', true, /^\.\/(?=(?!main(\.js)?$))(?=(.*\.(vue|js)$))/);
|
||||
srcContext.keys().forEach(srcContext);
|
||||
@@ -1,40 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// This is a karma config file. For more details see
|
||||
// http://karma-runner.github.io/0.13/config/configuration-file.html
|
||||
// we are also using it with karma-webpack
|
||||
// https://github.com/webpack/karma-webpack
|
||||
|
||||
// Necessary for babel to respect the env version of .babelrc which is necessary
|
||||
// Because inject-loader does not work with ["es2015", { modules: false }] that we use
|
||||
// in order to let webpack2 handle the imports
|
||||
process.env.CHROME_BIN = require('puppeteer').executablePath();
|
||||
// eslint-disable-line no-process-env
|
||||
process.env.BABEL_ENV = process.env.NODE_ENV; // eslint-disable-line no-process-env
|
||||
const webpackConfig = require('../../../webpack/webpack.test.conf');
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
// to run in additional browsers:
|
||||
// 1. install corresponding karma launcher
|
||||
// http://karma-runner.github.io/0.13/config/browsers.html
|
||||
// 2. add it to the `browsers` array below.
|
||||
browsers: ['ChromeHeadless'],
|
||||
frameworks: ['mocha', 'sinon-stub-promise', 'sinon-chai', 'chai-as-promised', 'chai'],
|
||||
reporters: ['spec', 'coverage'],
|
||||
files: ['./index.js'],
|
||||
preprocessors: {
|
||||
'./index.js': ['webpack', 'sourcemap'],
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {
|
||||
noInfo: true,
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: '../../../coverage/client-unit',
|
||||
reporters: [
|
||||
{ type: 'lcov', subdir: '.' },
|
||||
{ type: 'text-summary' },
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -88,7 +88,14 @@ describe('shared.ops.buyMysterySet', () => {
|
||||
expect(user.items.gear.owned).to.have.property('armor_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('head_mystery_301404', true);
|
||||
expect(user.items.gear.owned).to.have.property('eyewear_mystery_301404', true);
|
||||
expect(analytics.track).to.be.called;
|
||||
expect(analytics.track).to.be.calledOnce;
|
||||
expect(analytics.track).to.be.calledWithMatch('acquire item', {
|
||||
uuid: user._id,
|
||||
itemKey: '301404',
|
||||
itemType: 'Subscriber Gear',
|
||||
acquireMethod: 'Hourglass',
|
||||
category: 'behavior',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import get from 'lodash/get';
|
||||
import unlock from '../../../website/common/script/ops/unlock';
|
||||
import i18n from '../../../website/common/script/i18n';
|
||||
import { generateUser } from '../../helpers/common.helper';
|
||||
@@ -8,8 +9,10 @@ describe('shared.ops.unlock', () => {
|
||||
const unlockPath = 'shirt.convict,shirt.cross,shirt.fire,shirt.horizon,shirt.ocean,shirt.purple,shirt.rainbow,shirt.redblue,shirt.thunder,shirt.tropical,shirt.zombie';
|
||||
const unlockGearSetPath = 'items.gear.owned.headAccessory_special_bearEars,items.gear.owned.headAccessory_special_cactusEars,items.gear.owned.headAccessory_special_foxEars,items.gear.owned.headAccessory_special_lionEars,items.gear.owned.headAccessory_special_pandaEars,items.gear.owned.headAccessory_special_pigEars,items.gear.owned.headAccessory_special_tigerEars,items.gear.owned.headAccessory_special_wolfEars';
|
||||
const backgroundUnlockPath = 'background.giant_florals';
|
||||
const unlockCost = 1.25;
|
||||
const usersStartingGems = 5;
|
||||
const backgroundSetUnlockPath = 'background.archery_range,background.giant_florals,background.rainbows_end';
|
||||
const hairUnlockPath = 'hair.color.rainbow,hair.color.yellow,hair.color.green,hair.color.purple,hair.color.blue,hair.color.TRUred';
|
||||
const facialHairUnlockPath = 'hair.mustache.1,hair.mustache.2,hair.beard.1,hair.beard.2,hair.beard.3';
|
||||
const usersStartingGems = 50 / 4;
|
||||
|
||||
beforeEach(() => {
|
||||
user = generateUser();
|
||||
@@ -48,32 +51,100 @@ describe('shared.ops.unlock', () => {
|
||||
});
|
||||
|
||||
it('returns an error when user already owns a full set', done => {
|
||||
let expectedBalance;
|
||||
|
||||
try {
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
expectedBalance = user.balance;
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
expect(err.message).to.equal(i18n.t('alreadyUnlocked'));
|
||||
expect(user.balance).to.equal(3.75);
|
||||
expect(user.balance).to.equal(expectedBalance);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns an error when user already owns a full set of gear', done => {
|
||||
let expectedBalance;
|
||||
|
||||
try {
|
||||
unlock(user, { query: { path: unlockGearSetPath } });
|
||||
expectedBalance = user.balance;
|
||||
unlock(user, { query: { path: unlockGearSetPath } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
expect(err.message).to.equal(i18n.t('alreadyUnlocked'));
|
||||
expect(user.balance).to.equal(3.75);
|
||||
expect(user.balance).to.equal(expectedBalance);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
xit('returns an error when user already owns items in a full set', done => {
|
||||
it('returns an error if an item does not exists', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: unlockPath.split(',').splice(2).join(',') } });
|
||||
unlock(user, { query: { path: 'background.invalid_background' } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns an error if there are items from multiple sets', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: 'shirt.convict,skin.0ff591' } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns an error if gear is not from the animal set', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: 'items.gear.owned.back_mystery_202004' } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns an error if the item is free', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: 'shirt.black' } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns an error if an item does not belong to a set (appearances)', done => {
|
||||
try {
|
||||
unlock(user, { query: { path: 'shirt.pink' } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(BadRequest);
|
||||
expect(err.message).to.equal(i18n.t('invalidUnlockSet'));
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
it('returns an error when user already owns items in a full set and it would be more expensive to buy the entire set', done => {
|
||||
try {
|
||||
// There are 11 shirts in the set, each cost 2 gems, the full set 5 gems
|
||||
// In order for the full purchase not to be worth, we must own 9
|
||||
const partialUnlockPaths = unlockPath.split(',');
|
||||
unlock(user, { query: { path: partialUnlockPaths[0] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[1] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[2] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[3] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[4] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[5] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[6] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[7] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[8] } });
|
||||
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
} catch (err) {
|
||||
expect(err).to.be.an.instanceof(NotAuthorized);
|
||||
@@ -82,6 +153,22 @@ describe('shared.ops.unlock', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('does not return an error when user already owns items in a full set and it would not be more expensive to buy the entire set', () => {
|
||||
// There are 11 shirts in the set, each cost 2 gems, the full set 5 gems
|
||||
// In order for the full purchase to be worth, we can own already 8
|
||||
const partialUnlockPaths = unlockPath.split(',');
|
||||
unlock(user, { query: { path: partialUnlockPaths[0] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[1] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[2] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[3] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[4] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[5] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[6] } });
|
||||
unlock(user, { query: { path: partialUnlockPaths[7] } });
|
||||
|
||||
unlock(user, { query: { path: unlockPath } });
|
||||
});
|
||||
|
||||
it('equips an item already owned', () => {
|
||||
expect(user.purchased.background.giant_florals).to.not.exist;
|
||||
|
||||
@@ -107,31 +194,143 @@ describe('shared.ops.unlock', () => {
|
||||
expect(user.preferences.background).to.equal('');
|
||||
});
|
||||
|
||||
it('unlocks a full set', () => {
|
||||
it('unlocks a full set of appearance items', () => {
|
||||
const initialShirts = Object.keys(user.purchased.shirt).length;
|
||||
const [, message] = unlock(user, { query: { path: unlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(user.purchased.shirt.convict).to.be.true;
|
||||
const individualPaths = unlockPath.split(',');
|
||||
individualPaths.forEach(path => {
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
});
|
||||
expect(Object.keys(user.purchased.shirt).length)
|
||||
.to.equal(initialShirts + individualPaths.length);
|
||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||
});
|
||||
|
||||
it('unlocks a full set of hair items', () => {
|
||||
user.purchased.hair.color = {};
|
||||
|
||||
const initialHairColors = Object.keys(user.purchased.hair.color).length;
|
||||
const [, message] = unlock(user, { query: { path: hairUnlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
const individualPaths = hairUnlockPath.split(',');
|
||||
individualPaths.forEach(path => {
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
});
|
||||
expect(Object.keys(user.purchased.hair.color).length)
|
||||
.to.equal(initialHairColors + individualPaths.length);
|
||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||
});
|
||||
|
||||
it('unlocks the facial hair set', () => {
|
||||
user.purchased.hair.mustache = {};
|
||||
user.purchased.hair.beard = {};
|
||||
|
||||
const initialMustache = Object.keys(user.purchased.hair.mustache).length;
|
||||
const initialBeard = Object.keys(user.purchased.hair.mustache).length;
|
||||
const [, message] = unlock(user, { query: { path: facialHairUnlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
const individualPaths = facialHairUnlockPath.split(',');
|
||||
individualPaths.forEach(path => {
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
});
|
||||
expect(Object.keys(user.purchased.hair.mustache).length + Object.keys(user.purchased.hair.beard).length) // eslint-disable-line max-len
|
||||
.to.equal(initialMustache + initialBeard + individualPaths.length);
|
||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||
});
|
||||
|
||||
it('unlocks a full set of gear', () => {
|
||||
const initialGear = Object.keys(user.items.gear.owned).length;
|
||||
const [, message] = unlock(user, { query: { path: unlockGearSetPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(user.items.gear.owned.headAccessory_special_wolfEars).to.be.true;
|
||||
|
||||
const individualPaths = unlockGearSetPath.split(',');
|
||||
individualPaths.forEach(path => {
|
||||
expect(get(user, path)).to.be.true;
|
||||
});
|
||||
expect(Object.keys(user.items.gear.owned).length)
|
||||
.to.equal(initialGear + individualPaths.length);
|
||||
expect(user.balance).to.equal(usersStartingGems - 1.25);
|
||||
});
|
||||
|
||||
it('unlocks an item', () => {
|
||||
it('unlocks a full set of backgrounds', () => {
|
||||
const initialBackgrounds = Object.keys(user.purchased.background).length;
|
||||
const [, message] = unlock(user, { query: { path: backgroundSetUnlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
const individualPaths = backgroundSetUnlockPath.split(',');
|
||||
individualPaths.forEach(path => {
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
});
|
||||
expect(Object.keys(user.purchased.background).length)
|
||||
.to.equal(initialBackgrounds + individualPaths.length);
|
||||
expect(user.balance).to.equal(usersStartingGems - 3.75);
|
||||
});
|
||||
|
||||
it('unlocks an item (appearance)', () => {
|
||||
const path = unlockPath.split(',')[0];
|
||||
const initialShirts = Object.keys(user.purchased.shirt).length;
|
||||
const [, message] = unlock(user, { query: { path } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(Object.keys(user.purchased.shirt).length).to.equal(initialShirts + 1);
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||
});
|
||||
|
||||
it('unlocks an item (hair color)', () => {
|
||||
user.purchased.hair.color = {};
|
||||
|
||||
const path = hairUnlockPath.split(',')[0];
|
||||
const initialColorHair = Object.keys(user.purchased.hair.color).length;
|
||||
const [, message] = unlock(user, { query: { path } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(Object.keys(user.purchased.hair.color).length).to.equal(initialColorHair + 1);
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||
});
|
||||
|
||||
it('unlocks an item (facial hair)', () => {
|
||||
user.purchased.hair.mustache = {};
|
||||
user.purchased.hair.beard = {};
|
||||
|
||||
const path = facialHairUnlockPath.split(',')[0];
|
||||
const initialMustache = Object.keys(user.purchased.hair.mustache).length;
|
||||
const initialBeard = Object.keys(user.purchased.hair.beard).length;
|
||||
const [, message] = unlock(user, { query: { path } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
|
||||
expect(Object.keys(user.purchased.hair.mustache).length).to.equal(initialMustache + 1);
|
||||
expect(Object.keys(user.purchased.hair.beard).length).to.equal(initialBeard);
|
||||
|
||||
expect(get(user.purchased, path)).to.be.true;
|
||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||
});
|
||||
|
||||
it('unlocks an item (gear)', () => {
|
||||
const path = unlockGearSetPath.split(',')[0];
|
||||
const initialGear = Object.keys(user.items.gear.owned).length;
|
||||
const [, message] = unlock(user, { query: { path } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(Object.keys(user.items.gear.owned).length).to.equal(initialGear + 1);
|
||||
expect(get(user, path)).to.be.true;
|
||||
expect(user.balance).to.equal(usersStartingGems - 0.5);
|
||||
});
|
||||
|
||||
it('unlocks an item (background)', () => {
|
||||
const initialBackgrounds = Object.keys(user.purchased.background).length;
|
||||
const [, message] = unlock(user, { query: { path: backgroundUnlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(user.purchased.background.giant_florals).to.be.true;
|
||||
});
|
||||
|
||||
it('reduces a user\'s balance', () => {
|
||||
const [, message] = unlock(user, { query: { path: unlockPath } });
|
||||
|
||||
expect(message).to.equal(i18n.t('unlocked'));
|
||||
expect(user.balance).to.equal(usersStartingGems - unlockCost);
|
||||
expect(Object.keys(user.purchased.background).length).to.equal(initialBackgrounds + 1);
|
||||
expect(get(user.purchased, backgroundUnlockPath)).to.be.true;
|
||||
expect(user.balance).to.equal(usersStartingGems - 1.75);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,46 +5,46 @@
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit --require ./tests/unit/helpers.js",
|
||||
"lint": "vue-cli-service lint .",
|
||||
"lint-no-fix": "vue-cli-service lint --no-fix .",
|
||||
"postinstall": "node ./scripts/npm-postinstall.js",
|
||||
"storybook:build": "vue-cli-service storybook:build -c config/storybook -o dist/storybook",
|
||||
"storybook:serve": "vue-cli-service storybook:serve -p 6006 -c config/storybook",
|
||||
"test:unit": "vue-cli-service test:unit --require ./tests/unit/helpers.js"
|
||||
"storybook:serve": "vue-cli-service storybook:serve -p 6006 -c config/storybook"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.3.1",
|
||||
"@vue/cli-plugin-eslint": "^4.3.1",
|
||||
"@vue/cli-plugin-router": "^4.3.1",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.3.1",
|
||||
"@vue/cli-service": "^4.3.1",
|
||||
"@storybook/addon-actions": "^5.3.18",
|
||||
"@storybook/addon-knobs": "^5.3.18",
|
||||
"@storybook/addon-links": "^5.3.18",
|
||||
"@storybook/addon-notes": "^5.3.18",
|
||||
"@storybook/vue": "^5.3.18",
|
||||
"@storybook/addon-actions": "^5.3.19",
|
||||
"@storybook/addon-knobs": "^5.3.19",
|
||||
"@storybook/addon-links": "^5.3.19",
|
||||
"@storybook/addon-notes": "^5.3.19",
|
||||
"@storybook/vue": "^5.3.19",
|
||||
"@vue/cli-plugin-babel": "^4.4.4",
|
||||
"@vue/cli-plugin-eslint": "^4.4.4",
|
||||
"@vue/cli-plugin-router": "^4.4.4",
|
||||
"@vue/cli-plugin-unit-mocha": "^4.4.4",
|
||||
"@vue/cli-service": "^4.4.4",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"amplitude-js": "^5.11.0",
|
||||
"axios": "^0.19.2",
|
||||
"axios-progress-bar": "^1.2.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"bootstrap": "^4.4.1",
|
||||
"bootstrap-vue": "^2.13.1",
|
||||
"bootstrap": "^4.5.0",
|
||||
"bootstrap-vue": "^2.15.0",
|
||||
"chai": "^4.1.2",
|
||||
"core-js": "^3.6.5",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-habitrpg": "^6.2.0",
|
||||
"eslint-plugin-mocha": "^5.3.0",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"habitica-markdown": "^2.0.0",
|
||||
"habitica-markdown": "^2.0.2",
|
||||
"hellojs": "^1.18.4",
|
||||
"inspectpack": "^4.4.0",
|
||||
"inspectpack": "^4.5.2",
|
||||
"intro.js": "^2.9.3",
|
||||
"jquery": "^3.5.1",
|
||||
"lodash": "^4.17.15",
|
||||
"moment": "^2.25.3",
|
||||
"moment": "^2.26.0",
|
||||
"nconf": "^0.10.0",
|
||||
"sass": "^1.26.5",
|
||||
"sass": "^1.26.8",
|
||||
"sass-loader": "^8.0.2",
|
||||
"smartbanner.js": "^1.15.0",
|
||||
"svg-inline-loader": "^0.8.2",
|
||||
@@ -56,9 +56,9 @@
|
||||
"vue": "^2.6.11",
|
||||
"vue-cli-plugin-storybook": "^0.6.1",
|
||||
"vue-mugen-scroll": "^0.2.6",
|
||||
"vue-router": "^3.1.6",
|
||||
"vue-router": "^3.3.4",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuedraggable": "^2.23.1",
|
||||
"vuedraggable": "^2.23.2",
|
||||
"vuejs-datepicker": "git://github.com/habitrpg/vuejs-datepicker.git#5d237615463a84a23dd6f3f77c6ab577d68593ec",
|
||||
"webpack": "^4.43.0"
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(['isUserLoggedIn', 'browserTimezoneOffset', 'isUserLoaded']),
|
||||
...mapState(['isUserLoggedIn', 'browserTimezoneOffset', 'isUserLoaded', 'notificationsRemoved']),
|
||||
...mapState({ user: 'user.data' }),
|
||||
isStaticPage () {
|
||||
return this.$route.meta.requiresLogin === false;
|
||||
@@ -361,13 +361,55 @@ export default {
|
||||
showSpinner: false,
|
||||
});
|
||||
|
||||
// Set up Error interceptors
|
||||
axios.interceptors.response.use(response => {
|
||||
if (this.user && response.data && response.data.notifications) {
|
||||
this.$set(this.user, 'notifications', response.data.notifications);
|
||||
axios.interceptors.response.use(response => { // Set up Response interceptors
|
||||
// Verify that the user was not updated from another browser/app/client
|
||||
// If it was, sync
|
||||
const { url } = response.config;
|
||||
const { method } = response.config;
|
||||
|
||||
const isApiCall = url.indexOf('api/v4') !== -1;
|
||||
const userV = response.data && response.data.userV;
|
||||
const isCron = url.indexOf('/api/v4/cron') === 0 && method === 'post';
|
||||
|
||||
if (this.isUserLoaded && isApiCall && userV) {
|
||||
const oldUserV = this.user._v;
|
||||
this.user._v = userV;
|
||||
|
||||
// Do not sync again if already syncing
|
||||
const isUserSync = url.indexOf('/api/v4/user') === 0 && method === 'get';
|
||||
const isTasksSync = url.indexOf('/api/v4/tasks/user') === 0 && method === 'get';
|
||||
// exclude chat seen requests because with real time chat they would be too many
|
||||
const isChatSeen = url.indexOf('/chat/seen') !== -1 && method === 'post';
|
||||
// exclude POST /api/v4/cron because the user is synced automatically after cron runs
|
||||
|
||||
// Something has changed on the user object that was not tracked here, sync the user
|
||||
if (userV - oldUserV > 1 && !isCron && !isChatSeen && !isUserSync && !isTasksSync) {
|
||||
Promise.all([
|
||||
this.$store.dispatch('user:fetch', { forceLoad: true }),
|
||||
this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true }),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the app version from the server
|
||||
const serverAppVersion = response.data && response.data.appVersion;
|
||||
|
||||
if (serverAppVersion && this.$store.state.serverAppVersion !== response.data.appVersion) {
|
||||
this.$store.state.serverAppVersion = serverAppVersion;
|
||||
}
|
||||
|
||||
// Store the notifications, filtering those that have already been read
|
||||
// See store/index.js on why this is necessary
|
||||
if (this.user && response.data && response.data.notifications) {
|
||||
const filteredNotifications = response.data.notifications.filter(serverNotification => {
|
||||
if (this.notificationsRemoved.includes(serverNotification.id)) return false;
|
||||
return true;
|
||||
});
|
||||
this.$set(this.user, 'notifications', filteredNotifications);
|
||||
}
|
||||
|
||||
return response;
|
||||
}, error => {
|
||||
}, error => { // Set up Error interceptors
|
||||
if (error.response.status >= 400) {
|
||||
const isBanned = this.checkForBannedUser(error);
|
||||
if (isBanned === true) return null; // eslint-disable-line consistent-return
|
||||
@@ -425,51 +467,6 @@ export default {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
axios.interceptors.response.use(response => {
|
||||
// Verify that the user was not updated from another browser/app/client
|
||||
// If it was, sync
|
||||
const { url } = response.config;
|
||||
const { method } = response.config;
|
||||
|
||||
const isApiCall = url.indexOf('api/v4') !== -1;
|
||||
const userV = response.data && response.data.userV;
|
||||
const isCron = url.indexOf('/api/v4/cron') === 0 && method === 'post';
|
||||
|
||||
if (this.isUserLoaded && isApiCall && userV) {
|
||||
const oldUserV = this.user._v;
|
||||
this.user._v = userV;
|
||||
|
||||
// Do not sync again if already syncing
|
||||
const isUserSync = url.indexOf('/api/v4/user') === 0 && method === 'get';
|
||||
const isTasksSync = url.indexOf('/api/v4/tasks/user') === 0 && method === 'get';
|
||||
// exclude chat seen requests because with real time chat they would be too many
|
||||
const isChatSeen = url.indexOf('/chat/seen') !== -1 && method === 'post';
|
||||
// exclude POST /api/v4/cron because the user is synced automatically after cron runs
|
||||
|
||||
// Something has changed on the user object that was not tracked here, sync the user
|
||||
if (userV - oldUserV > 1 && !isCron && !isChatSeen && !isUserSync && !isTasksSync) {
|
||||
Promise.all([
|
||||
this.$store.dispatch('user:fetch', { forceLoad: true }),
|
||||
this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true }),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the client is updated
|
||||
// const serverAppVersion = response.data.appVersion;
|
||||
// let serverAppVersionState = this.$store.state.serverAppVersion;
|
||||
// if (isApiCall && !serverAppVersionState) {
|
||||
// this.$store.state.serverAppVersion = serverAppVersion;
|
||||
// } else if (isApiCall && serverAppVersionState !== serverAppVersion) {
|
||||
// if (document.activeElement.tagName !== 'INPUT'
|
||||
// || confirm(this.$t('habiticaHasUpdated'))) {
|
||||
// location.reload(true);
|
||||
// }
|
||||
// }
|
||||
|
||||
return response;
|
||||
});
|
||||
|
||||
// Setup listener for title
|
||||
this.$store.watch(state => state.title, title => {
|
||||
document.title = title;
|
||||
@@ -745,5 +742,6 @@ export default {
|
||||
<style src="@/assets/css/sprites/spritesmith-main-25.css"></style>
|
||||
<style src="@/assets/css/sprites/spritesmith-main-26.css"></style>
|
||||
<style src="@/assets/css/sprites/spritesmith-main-27.css"></style>
|
||||
<style src="@/assets/css/sprites/spritesmith-main-28.css"></style>
|
||||
<style src="@/assets/css/sprites.css"></style>
|
||||
<style src="smartbanner.js/dist/smartbanner.min.css"></style>
|
||||
|
||||
@@ -1,42 +1,48 @@
|
||||
.promo_armoire_backgrounds_202005 {
|
||||
.promo_armoire_backgrounds_202006 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -391px 0px;
|
||||
background-position: -259px -386px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_fairy_sunshine_potions {
|
||||
.promo_mystery_202006 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -391px -148px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_jungle_buddies_bundle {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -434px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_mystery_202005 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -424px -434px;
|
||||
background-position: -785px -148px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_sand_sculpture_potions {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -785px 0px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_summer_splash_2019 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -199px;
|
||||
width: 408px;
|
||||
height: 186px;
|
||||
}
|
||||
.promo_summer_splash_2020 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 444px;
|
||||
height: 198px;
|
||||
}
|
||||
.promo_take_this {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -391px -296px;
|
||||
background-position: -1068px -148px;
|
||||
width: 96px;
|
||||
height: 69px;
|
||||
}
|
||||
.scene_casting_spells {
|
||||
.scene_achievement {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -211px;
|
||||
width: 312px;
|
||||
height: 222px;
|
||||
}
|
||||
.scene_pets_resting {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 390px;
|
||||
background-position: -445px 0px;
|
||||
width: 339px;
|
||||
height: 210px;
|
||||
}
|
||||
.scene_hiking {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -386px;
|
||||
width: 258px;
|
||||
height: 258px;
|
||||
}
|
||||
|
||||
@@ -1,78 +1,150 @@
|
||||
.quest_TEMPLATE_FOR_MISSING_IMAGE {
|
||||
.quest_atom1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -502px -1546px;
|
||||
width: 221px;
|
||||
height: 39px;
|
||||
background-position: -1082px -1332px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_dilatory {
|
||||
.quest_atom2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -642px -1534px;
|
||||
width: 207px;
|
||||
height: 138px;
|
||||
}
|
||||
.quest_atom3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -211px -1534px;
|
||||
width: 216px;
|
||||
height: 180px;
|
||||
}
|
||||
.quest_axolotl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatoryDistress1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -1332px;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.quest_dilatoryDistress2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -567px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_dilatoryDistress3 {
|
||||
.quest_badger {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatory_derby {
|
||||
.quest_basilist {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
background-position: -191px -1721px;
|
||||
width: 189px;
|
||||
height: 141px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
.quest_beetle {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
background-position: 0px -1332px;
|
||||
width: 204px;
|
||||
height: 201px;
|
||||
}
|
||||
.quest_dustbunnies {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_egg {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -359px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -1171px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
.quest_bronze {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_bunny {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1534px;
|
||||
width: 210px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_butterfly {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_cheetah {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_cow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px 0px;
|
||||
width: 174px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_dilatory {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatoryDistress1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -1082px;
|
||||
width: 210px;
|
||||
height: 210px;
|
||||
}
|
||||
.quest_dilatoryDistress2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -422px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_dilatoryDistress3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dilatory_derby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dustbunnies {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_egg {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -214px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -724px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_falcon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -220px;
|
||||
background-position: -1100px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -452px;
|
||||
background-position: -1100px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_fluorite {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -84,19 +156,19 @@
|
||||
}
|
||||
.quest_ghost_stag {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -452px;
|
||||
background-position: -220px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -452px;
|
||||
background-position: -440px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1546px;
|
||||
background-position: -1333px -1332px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
@@ -108,175 +180,175 @@
|
||||
}
|
||||
.quest_gryphon {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -874px -1332px;
|
||||
background-position: -648px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_guineapig {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -452px;
|
||||
background-position: -1320px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_harpy {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px 0px;
|
||||
background-position: -1320px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_hedgehog {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -431px -1332px;
|
||||
background-position: -205px -1332px;
|
||||
width: 219px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_hippo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -220px;
|
||||
background-position: -1320px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_horse {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -440px;
|
||||
background-position: -1320px -880px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kangaroo {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -672px;
|
||||
background-position: 0px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kraken {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1091px -1332px;
|
||||
background-position: -865px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_lostMasterclasser1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -672px;
|
||||
background-position: -440px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -672px;
|
||||
background-position: -660px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -672px;
|
||||
background-position: -880px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -718px;
|
||||
background-position: -1762px -573px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_mayhemMistiflying2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -672px;
|
||||
background-position: -1320px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px 0px;
|
||||
background-position: -220px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_monkey {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -220px;
|
||||
background-position: -1100px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -214px;
|
||||
background-position: -1540px -648px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_moon2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -440px;
|
||||
background-position: -880px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -660px;
|
||||
background-position: -880px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -892px;
|
||||
background-position: -440px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -892px;
|
||||
background-position: -880px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -892px;
|
||||
background-position: -1100px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_nudibranch {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -431px;
|
||||
background-position: -1540px -214px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_octopus {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -651px -1332px;
|
||||
background-position: -425px -1332px;
|
||||
width: 222px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_owl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -892px;
|
||||
background-position: -1320px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_peacock {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -648px;
|
||||
background-position: -1540px -431px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_penguin {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -175px;
|
||||
background-position: 0px -1721px;
|
||||
width: 190px;
|
||||
height: 183px;
|
||||
}
|
||||
.quest_pterodactyl {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -892px;
|
||||
background-position: -660px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rat {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -892px;
|
||||
background-position: -880px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_robot {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px 0px;
|
||||
background-position: -660px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -288,115 +360,37 @@
|
||||
}
|
||||
.quest_rooster {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px 0px;
|
||||
background-position: -428px -1534px;
|
||||
width: 213px;
|
||||
height: 174px;
|
||||
}
|
||||
.quest_ruby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -220px;
|
||||
background-position: -440px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sabretooth {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -440px;
|
||||
background-position: -660px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_seaserpent {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -660px;
|
||||
background-position: -220px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sheep {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -880px;
|
||||
background-position: 0px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_silver {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1112px;
|
||||
background-position: -220px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_slime {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -220px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sloth {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -440px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_snail {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: 0px -1332px;
|
||||
width: 219px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_snake {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1308px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_spider {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -251px -1546px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_squirrel {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -660px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -869px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_stoikalmCalamity2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -880px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1100px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_taskwoodsTerror1 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1762px -1020px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_taskwoodsTerror2 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1540px -1082px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_taskwoodsTerror3 {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1320px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_treeling {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-13.png');
|
||||
background-position: -1525px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,348 @@
|
||||
.Pet-Wolf-Thunderstorm {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -82px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Veggie {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px -300px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Veteran {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Watery {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -164px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-White {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Wolf-Zombie {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -82px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Base {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -164px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-CottonCandyBlue {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -246px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-CottonCandyPink {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -246px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Desert {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Golden {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -82px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Red {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -164px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Shade {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -246px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Skeleton {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -328px 0px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-White {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -328px -100px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet-Yarn-Zombie {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -328px -200px;
|
||||
width: 81px;
|
||||
height: 99px;
|
||||
}
|
||||
.Pet_HatchingPotion_Amber {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -82px -300px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Aquatic {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -151px -300px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Aurora {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -220px -300px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Base {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -289px -300px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_BirchBark {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -410px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Bronze {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -410px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Celestial {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -410px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_CottonCandyBlue {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -410px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_CottonCandyPink {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -410px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Cupid {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Desert {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -69px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ember {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -138px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Fairy {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -207px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Floral {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -414px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Fluorite {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -345px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Frost {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -479px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ghost {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -479px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Glass {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -479px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Glow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -479px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Golden {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -479px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Holly {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -479px -345px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_IcySnow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Peppermint {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -69px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Purple {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -138px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Rainbow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -207px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Red {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -276px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_RoseQuartz {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -345px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_RoyalPurple {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -414px -469px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Ruby {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px 0px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_SandSculpture {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px -69px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shade {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px -138px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shadow {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px -207px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Shimmer {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px -276px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Silver {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px -345px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Skeleton {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -548px -414px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Spooky {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: 0px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_StarryNight {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -69px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Sunshine {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -138px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Thunderstorm {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -207px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Watery {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -276px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_White {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -345px -538px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.Pet_HatchingPotion_Zombie {
|
||||
background-image: url('~@/assets/images/sprites/spritesmith-main-28.png');
|
||||
background-position: -276px -400px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 470 KiB After Width: | Height: | Size: 470 KiB |
|
Before Width: | Height: | Size: 615 KiB After Width: | Height: | Size: 603 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 431 KiB After Width: | Height: | Size: 403 KiB |
|
Before Width: | Height: | Size: 223 KiB After Width: | Height: | Size: 294 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 156 KiB |
|
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 162 KiB After Width: | Height: | Size: 168 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 170 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 151 KiB |
@@ -1,92 +1,193 @@
|
||||
@mixin btn-focus-hover-shadow () {
|
||||
box-shadow: 0 4px 4px 0 rgba($black, 0.16), 0 1px 8px 0 rgba($black, 0.12);
|
||||
}
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
font-size: 16px;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
line-height: 1.5;
|
||||
border: 1px solid transparent !important;
|
||||
padding: 7.5px 15.5px;
|
||||
line-height: 1.71;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.25rem 1rem;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 2px 0 rgba($black, 0.16), 0 1px 4px 0 rgba($black, 0.12);
|
||||
box-shadow: 0 1px 3px 0 rgba($black, 0.12), 0 1px 2px 0 rgba($black, 0.24);
|
||||
color: $white;
|
||||
|
||||
&:focus:not(.btn-flat) {
|
||||
outline: none;
|
||||
&:hover, &:focus {
|
||||
box-shadow: 0 3px 6px 0 rgba($black, 0.16), 0 3px 6px 0 rgba($black, 0.24);
|
||||
|
||||
&:disabled, &.disabled, &.btn-flat {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $purple-400;
|
||||
@include btn-focus-hover-shadow();
|
||||
}
|
||||
|
||||
&:hover:not(.btn-flat):not(.disabled):not(:disabled) {
|
||||
@include btn-focus-hover-shadow();
|
||||
border-color: transparent;
|
||||
&:active, &.active:not(.btn-flat), &:disabled, &.disabled {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:active:not(.btn-flat), &.active:not(.btn-flat) {
|
||||
box-shadow: none !important;
|
||||
border: 1px solid transparent;
|
||||
&:disabled, &.disabled {
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-warning:hover, .btn-warning:focus, .btn-warning:active {
|
||||
color: $white !important;
|
||||
}
|
||||
|
||||
.btn:disabled, .btn.disabled {
|
||||
box-shadow: none;
|
||||
cursor: default;
|
||||
opacity: 0.64;
|
||||
border-color: transparent;
|
||||
.btn-front {
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
padding: 7.5px 15.5px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: $purple-200;
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:disabled {
|
||||
&:hover:not(:disabled):not(.disabled) {
|
||||
background: #5d3b9c;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: $purple-200;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled):not(.disabled), &:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled), &:focus:not(:disabled):not(.disabled) {
|
||||
background: #5d3b9c !important;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary, .dropdown > .btn-secondary {
|
||||
color: $gray-50;
|
||||
background: $white !important;
|
||||
|
||||
&:hover:not(:disabled):not(.disabled), &:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled), &:focus:not(:disabled):not(.disabled) {
|
||||
color: $purple-200 !important;
|
||||
&:not(:disabled):not(.disabled):active:focus, &:not(:disabled):not(.disabled).active:focus {
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:active, &:focus, &.active {
|
||||
border-color: $purple-500 !important;
|
||||
&:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active {
|
||||
background: $purple-200;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
background: $gray-500 !important;
|
||||
color: $gray-100 !important;
|
||||
background: $purple-200;
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-secondary,
|
||||
.dropdown > .btn-secondary.dropdown-toggle:not(.btn-success),
|
||||
.show > .btn-secondary.dropdown-toggle:not(.btn-success)
|
||||
{
|
||||
background: $white;
|
||||
border: 1px solid transparent;
|
||||
color: $gray-50;
|
||||
|
||||
&:focus, &:active {
|
||||
color: $gray-50;
|
||||
background: $white;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled) {
|
||||
&:active:focus,
|
||||
&.active:focus {
|
||||
color: $purple-300;
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
color: $purple-300;
|
||||
|
||||
&.dropdown-toggle {
|
||||
color: $gray-50;
|
||||
}
|
||||
|
||||
|
||||
background: $white;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $purple-300;
|
||||
|
||||
&.dropdown-toggle {
|
||||
color: $gray-50;
|
||||
}
|
||||
|
||||
background: $white !important;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
color: $gray-50;
|
||||
background: $white;
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: $maroon-100;
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:hover:not(:disabled):not(.disabled) {
|
||||
background: #e14e4e;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: $maroon-100;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active:focus, &:not(:disabled):not(.disabled).active:focus {
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active {
|
||||
background: $maroon-100;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
background: $maroon-100;
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: $green-100;
|
||||
|
||||
&:disabled {
|
||||
background: $green-100;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled):not(.disabled), &:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled) {
|
||||
background: $green-50;
|
||||
}
|
||||
}
|
||||
|
||||
.show > .btn-success.dropdown-toggle {
|
||||
background: $green-50;
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:hover:not(:disabled):not(.disabled) {
|
||||
background: #32bd8a;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: $green-50;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active:focus, &:not(:disabled):not(.disabled).active:focus {
|
||||
box-shadow: none;
|
||||
border-color: $purple-400;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active {
|
||||
background: $green-50;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:disabled, &.disabled {
|
||||
background: $green-50;
|
||||
border: 1px solid transparent;
|
||||
cursor: default;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-info {
|
||||
@@ -105,22 +206,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: $red-50;
|
||||
|
||||
&:disabled {
|
||||
background: $red-50;
|
||||
}
|
||||
|
||||
&:hover:not(:disabled):not(.disabled) {
|
||||
background: $red-100;
|
||||
}
|
||||
|
||||
&:active:not(:disabled):not(.disabled), &.active:not(:disabled):not(.disabled) {
|
||||
background: $red-100;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-show-more {
|
||||
display: block;
|
||||
width: 50%;
|
||||
|
||||
@@ -41,4 +41,9 @@
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 0 16px;
|
||||
border-left: 4px solid #e1e0e3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,56 @@
|
||||
@mixin habit-controls($disabled-color, $active-color) {
|
||||
&-habit-control-disabled {
|
||||
.habit-option-button {
|
||||
border: 2px solid $disabled-color;
|
||||
}
|
||||
&:hover {
|
||||
.habit-option-button {
|
||||
border: 2px solid $active-color;
|
||||
}
|
||||
.habit-option-icon, .habit-option-label { color: $active-color !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin modal-text-input($color) {
|
||||
&-text::placeholder { color: $color !important; }
|
||||
&-input {
|
||||
border: 0 !important;
|
||||
|
||||
&:focus, &:active {
|
||||
box-shadow: 0 0 0 1px $color !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.task {
|
||||
&-worst { // dark red
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $maroon-100 !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($black, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $maroon-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: $maroon-500 !important; }
|
||||
&-checkbox { color: $maroon-100 !important; }
|
||||
&-icon { color: #6c0406 !important; }
|
||||
&-bg-noninteractive { background: $maroon-100 !important; }
|
||||
&-inner-habit { background: rgba($black, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($red-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $red-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $maroon-100 !important; }
|
||||
&-icon { color: $maroon-100 !important; }
|
||||
&-text { color: $maroon-50 !important; }
|
||||
&-text { color: $red-1 !important; }
|
||||
&-content {
|
||||
--svg-color: #{$maroon-100};
|
||||
}
|
||||
@include modal-text-input($red-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $maroon-100 !important; }
|
||||
.option-item-label { color: $maroon-50 !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $maroon-100 !important; }
|
||||
.option-item-label { color: $maroon-50 !important; }
|
||||
}
|
||||
@include habit-controls($gray-300, $maroon-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,32 +58,30 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $red-100 !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($black, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $red-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: $red-500 !important; }
|
||||
&-checkbox { color: $red-100 !important; }
|
||||
&-icon { color: #6c0406 !important; }
|
||||
&-bg-noninteractive { background: $red-100 !important; }
|
||||
&-inner-habit { background: rgba($black, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($red-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $red-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $red-100 !important; }
|
||||
&-icon { color: $red-100 !important; }
|
||||
&-text { color: $red-10 !important; }
|
||||
&-text { color: $red-1 !important; }
|
||||
&-content {
|
||||
--svg-color: #{$red-100};
|
||||
}
|
||||
@include modal-text-input($red-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $red-100 !important; }
|
||||
.option-item-label { color: $red-10 !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $red-100 !important; }
|
||||
.option-item-label { color: $red-10 !important; }
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $red-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,43 +89,30 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $orange-100 !important;
|
||||
|
||||
&:hover {
|
||||
.habit-control { background: #b75a1c !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($orange-1, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $orange-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(183, 90, 28, 0.4) !important; }
|
||||
&-inner-daily-todo { background: $orange-500 !important; }
|
||||
&-checkbox { color: $orange-100 !important; }
|
||||
&-icon { color: #7f3300 !important; }
|
||||
&-bg-noninteractive { background: $orange-100 !important; }
|
||||
&-inner-habit { background: rgba($orange-1, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($orange-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $orange-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg {
|
||||
background: $orange-100 !important;
|
||||
|
||||
.form-control {
|
||||
background: rgba(183, 90, 28, 0.4) !important;
|
||||
|
||||
&:focus, &:active, &:hover {
|
||||
background-color: #b75a1c !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-bg { background: $orange-100 !important; }
|
||||
&-icon { color: $orange-100 !important; }
|
||||
&-text { color: #b75a1c !important; }
|
||||
&-text { color: $orange-1 !important; }
|
||||
&-content {
|
||||
--svg-color: #{$orange-100};
|
||||
}
|
||||
@include modal-text-input($orange-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $orange-100 !important; }
|
||||
.option-item-label { color: #b75a1c !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $orange-100 !important; }
|
||||
.option-item-label { color: #b75a1c !important; }
|
||||
.option-item-label { color: $orange-1 !important; }
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $orange-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,42 +120,30 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $yellow-100 !important;
|
||||
&:hover {
|
||||
.habit-control { background: #bf7d1a !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($yellow-1, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $yellow-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(183, 90, 28, 0.32) !important; }
|
||||
&-inner-daily-todo { background: $yellow-500 !important; }
|
||||
&-checkbox { color: $yellow-100 !important; }
|
||||
&-icon { color: #794b00 !important; }
|
||||
&-bg-noninteractive { background: $yellow-100 !important; }
|
||||
&-inner-habit { background: rgba($yellow-1, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($yellow-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $yellow-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg {
|
||||
background: $yellow-100 !important;
|
||||
|
||||
.form-control {
|
||||
background: rgba(183, 90, 28, 0.4) !important;
|
||||
|
||||
&:focus, &:active, &:hover {
|
||||
background-color: #bf7d1a !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
&-bg { background: $yellow-100 !important; }
|
||||
&-icon { color: $yellow-100 !important; }
|
||||
&-text { color: #bf7d1a !important; }
|
||||
&-text { color: $yellow-1 !important; }
|
||||
@include modal-text-input($yellow-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $yellow-100 !important; }
|
||||
.option-item-label { color: #bf7d1a !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $yellow-100 !important; }
|
||||
.option-item-label { color: #bf7d1a !important; }
|
||||
&-content {
|
||||
--svg-color: #{$yellow-100};
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $yellow-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,32 +151,31 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $green-100 !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($black, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $green-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: #77f4c7 !important; }
|
||||
&-checkbox { color: $green-10 !important; }
|
||||
&-icon { color: #005737 !important; }
|
||||
&-bg-noninteractive { background: $green-100 !important; }
|
||||
&-inner-habit { background: rgba($black, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($green-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $green-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $green-100 !important; }
|
||||
&-icon { color: $green-10 !important; }
|
||||
&-text { color: #1ca372 !important; }
|
||||
&-text { color: $green-1 !important; }
|
||||
&-content {
|
||||
--svg-color: #{$green-100};
|
||||
}
|
||||
|
||||
@include modal-text-input($green-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $green-10 !important; }
|
||||
.option-item-label { color: #1ca372 !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $green-10 !important; }
|
||||
.option-item-label { color: #1ca372 !important; }
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $green-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,32 +183,30 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $teal-100 !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($black, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $teal-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: #8dedf6 !important; }
|
||||
&-checkbox { color: $teal-100 !important; }
|
||||
&-icon { color: #005158 !important; }
|
||||
&-bg-noninteractive { background: $teal-100 !important; }
|
||||
&-inner-habit { background: rgba($black, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($teal-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $teal-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $teal-100 !important; }
|
||||
&-icon { color: $teal-100 !important; }
|
||||
&-text { color: $teal-10 !important; }
|
||||
&-text { color: $teal-1 !important; }
|
||||
&-content {
|
||||
--svg-color: #{$teal-100};
|
||||
}
|
||||
@include modal-text-input($teal-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $teal-100 !important; }
|
||||
.option-item-label { color: $teal-10 !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $teal-100 !important; }
|
||||
.option-item-label { color: $teal-10 !important; }
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $teal-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,32 +214,31 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $blue-100 !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($black, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: $blue-100 !important;
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: $blue-500 !important; }
|
||||
&-checkbox { color: $blue-100 !important; }
|
||||
&-icon { color: #033f5e !important; }
|
||||
&-bg-noninteractive { background: $blue-100 !important; }
|
||||
&-inner-habit { background: rgba($black, 0.25) !important; }
|
||||
&-inner-habit-noninteractive { border: 1px solid rgba($blue-1, 0.5) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox, &-icon { color: $blue-1 !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $blue-100 !important; }
|
||||
&-icon { color: $blue-100 !important; }
|
||||
&-text { color: $blue-10 !important; }
|
||||
&-text { color: $blue-1 !important; }
|
||||
&-content {
|
||||
--svg-color: #{$blue-100};
|
||||
}
|
||||
|
||||
@include modal-text-input($blue-1);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $blue-50 !important; }
|
||||
.option-item-label { color: $blue-10 !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $blue-50 !important; }
|
||||
.option-item-label { color: $blue-10 !important; }
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $blue-100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,42 +246,43 @@
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $purple-task !important;
|
||||
&:hover {
|
||||
.habit-control { background: rgba(26, 24, 29, 0.48) !important; }
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
.habit-control:hover { background: rgba($black, 0.5) !important; }
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-inner-habit { background: rgba(26, 24, 29, 0.24) !important; }
|
||||
&-inner-daily-todo { background: #ffffff80 !important; }
|
||||
&-inner-habit { background: rgba($black, 0.25) !important; }
|
||||
&-inner-daily-todo { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox { color: $purple-task !important; }
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $purple-300 !important; }
|
||||
&-icon { color: $purple-300 !important; }
|
||||
&-text { color: $purple-200 !important; }
|
||||
&-text { color: $black !important; }
|
||||
&-content {
|
||||
--svg-color: #{$purple-300};
|
||||
}
|
||||
|
||||
@include modal-text-input($black);
|
||||
&-option-disabled:hover {
|
||||
.svg-icon { color: $purple-300 !important; }
|
||||
.option-item-label { color: $purple-200 !important; }
|
||||
}
|
||||
&-habit-control-disabled:hover {
|
||||
.habit-control { background: $purple-300 !important; }
|
||||
.option-item-label { color: $purple-200 !important; }
|
||||
}
|
||||
|
||||
@include habit-controls($gray-300, $purple-300);
|
||||
}
|
||||
}
|
||||
|
||||
&-reward {
|
||||
&-control {
|
||||
&-bg {
|
||||
background: rgba(255, 217, 160, 0.32) !important;
|
||||
.small-text { color: $orange-10 !important; }
|
||||
background: rgba($yellow-100, 0.15) !important;
|
||||
.small-text { color: $yellow-1 !important; }
|
||||
|
||||
&:hover { background: rgba(255, 217, 160, 0.48) !important; }
|
||||
&:hover { background: rgba($yellow-100, 0.25) !important; }
|
||||
}
|
||||
&-bg-noninteractive {
|
||||
background: rgba(255, 217, 160, 0.32) !important;
|
||||
.small-text { color: $orange-10 !important; }
|
||||
background: rgba($yellow-100, 0.15) !important;
|
||||
.small-text { color: $yellow-1 !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,8 +292,12 @@
|
||||
&-control {
|
||||
&-bg { background: $gray-600; }
|
||||
&-inner {
|
||||
color: rgba(26, 24, 29, 0.12) !important;
|
||||
border: 1px solid rgba(26, 24, 29, 0.12);
|
||||
border: 1px solid $gray-300;
|
||||
opacity: 0.75;
|
||||
|
||||
.negative, .positive {
|
||||
color: $gray-200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,13 +305,14 @@
|
||||
&-daily-todo {
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $gray-400 !important;
|
||||
&:hover {
|
||||
.daily-todo-control { background: rgba(255, 255, 255, 0.72) !important; }
|
||||
}
|
||||
background: $gray-200 !important;
|
||||
.daily-todo-control:hover { background: rgba($white, 0.75) !important; }
|
||||
}
|
||||
&-inner { background: $gray-500 !important; }
|
||||
&-checkbox { color: $gray-400 !important; }
|
||||
&-bg-noninteractive {
|
||||
background: $gray-200 !important;
|
||||
}
|
||||
&-inner { background: rgba($white, 0.5) !important; }
|
||||
&-checkbox { color: $gray-10 !important; }
|
||||
&-content {
|
||||
background: $gray-600;
|
||||
|
||||
@@ -337,6 +334,24 @@
|
||||
border-radius: 100px;
|
||||
color: $white;
|
||||
|
||||
&-negative {
|
||||
&-enabled {
|
||||
padding-top: 13px;
|
||||
}
|
||||
&-disabled {
|
||||
padding-top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&-positive {
|
||||
&-enabled {
|
||||
padding-top: 9px;
|
||||
}
|
||||
&-disabled {
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
@@ -347,14 +362,10 @@
|
||||
margin-top: 7px;
|
||||
height: 12px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.positive {
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
.negative {
|
||||
margin-top: 13px;
|
||||
&.disabled {
|
||||
color: $gray-10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
// possible values are: normal, fall, habitoween, thanksgiving, winter, nye, birthday, valentines, normal, summer
|
||||
// more to be added on future seasons
|
||||
|
||||
$npc_market_flavor: 'normal';
|
||||
$npc_quests_flavor: 'normal';
|
||||
$npc_seasonal_flavor: 'normal';
|
||||
$npc_timetravelers_flavor: 'normal';
|
||||
$npc_tavern_flavor: 'normal';
|
||||
$npc_market_flavor: 'summer';
|
||||
$npc_quests_flavor: 'summer';
|
||||
$npc_seasonal_flavor: 'summer';
|
||||
$npc_timetravelers_flavor: 'summer';
|
||||
$npc_tavern_flavor: 'summer';
|
||||
|
||||
$restingToolbarHeight: 40px;
|
||||
$menuToolbarHeight: 56px;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="heroClass in classes"
|
||||
:key="heroClass"
|
||||
:key="`${heroClass}-avatar`"
|
||||
class="col-md-3"
|
||||
>
|
||||
<div @click="selectedClass = heroClass">
|
||||
@@ -60,7 +60,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-for="heroClass in classes"
|
||||
:key="heroClass"
|
||||
:key="`${heroClass}-explanation`"
|
||||
>
|
||||
<div
|
||||
v-if="selectedClass === heroClass"
|
||||
@@ -225,30 +225,30 @@ export default {
|
||||
classGear (heroClass) {
|
||||
if (heroClass === 'rogue') {
|
||||
return {
|
||||
armor: 'armor_rogue_5',
|
||||
head: 'head_rogue_5',
|
||||
shield: 'shield_rogue_6',
|
||||
weapon: 'weapon_rogue_6',
|
||||
armor: 'armor_special_summer2020Rogue',
|
||||
head: 'head_special_summer2020Rogue',
|
||||
shield: 'shield_special_summer2020Rogue',
|
||||
weapon: 'weapon_special_summer2020Rogue',
|
||||
};
|
||||
} if (heroClass === 'wizard') {
|
||||
return {
|
||||
armor: 'armor_wizard_5',
|
||||
head: 'head_wizard_5',
|
||||
weapon: 'weapon_wizard_6',
|
||||
armor: 'armor_special_summer2020Mage',
|
||||
head: 'head_special_summer2020Mage',
|
||||
weapon: 'weapon_special_summer2020Mage',
|
||||
};
|
||||
} if (heroClass === 'healer') {
|
||||
return {
|
||||
armor: 'armor_healer_5',
|
||||
head: 'head_healer_5',
|
||||
shield: 'shield_healer_5',
|
||||
weapon: 'weapon_healer_6',
|
||||
armor: 'armor_special_summer2020Healer',
|
||||
head: 'head_special_summer2020Healer',
|
||||
shield: 'shield_special_summer2020Healer',
|
||||
weapon: 'weapon_special_summer2020Healer',
|
||||
};
|
||||
}
|
||||
return {
|
||||
armor: 'armor_warrior_5',
|
||||
head: 'head_warrior_5',
|
||||
shield: 'shield_warrior_5',
|
||||
weapon: 'weapon_warrior_6',
|
||||
armor: 'armor_special_summer2020Warrior',
|
||||
head: 'head_special_summer2020Warrior',
|
||||
shield: 'shield_special_summer2020Warrior',
|
||||
weapon: 'weapon_special_summer2020Warrior',
|
||||
};
|
||||
},
|
||||
selectionBox (selectedClass, heroClass) {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
class="avatar"
|
||||
:member="user"
|
||||
:avatar-only="true"
|
||||
:hide-class-badge="true"
|
||||
:with-background="true"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@ export default {
|
||||
this.html = response.data.html;
|
||||
});
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
this.$root.$off('bv::show::modal');
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents"
|
||||
href="https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link"
|
||||
target="_blank"
|
||||
>{{ $t('requestFeature') }}</a>
|
||||
</li>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
<div class="col-12 col-md-6 text-right">
|
||||
<div
|
||||
class="box"
|
||||
class="box member-count"
|
||||
@click="showMemberModal()"
|
||||
>
|
||||
<div
|
||||
@@ -93,6 +93,7 @@
|
||||
:members="members"
|
||||
:challenge-id="challengeId"
|
||||
@member-selected="openMemberProgressModal"
|
||||
@opened="initialMembersLoad()"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 text-right">
|
||||
@@ -279,6 +280,10 @@
|
||||
font-size: 20px;
|
||||
vertical-align: bottom;
|
||||
|
||||
&.member-count:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
@@ -364,6 +369,7 @@ export default {
|
||||
}),
|
||||
challenge: {},
|
||||
members: [],
|
||||
membersLoaded: false,
|
||||
tasksByType: {
|
||||
habit: [],
|
||||
daily: [],
|
||||
@@ -427,8 +433,6 @@ export default {
|
||||
this.$router.push('/challenges/findChallenges');
|
||||
return;
|
||||
}
|
||||
this.members = await this
|
||||
.loadMembers({ challengeId: this.searchId, includeAllPublicFields: true });
|
||||
const tasks = await this.$store.dispatch('tasks:getChallengeTasks', { challengeId: this.searchId });
|
||||
this.tasksByType = {
|
||||
habit: [],
|
||||
@@ -454,7 +458,22 @@ export default {
|
||||
}
|
||||
return this.$store.dispatch('members:getChallengeMembers', payload);
|
||||
},
|
||||
initialMembersLoad () {
|
||||
this.$store.state.memberModalOptions.loading = true;
|
||||
if (!this.membersLoaded) {
|
||||
this.membersLoaded = true;
|
||||
|
||||
this.loadMembers({
|
||||
challengeId: this.searchId,
|
||||
includeAllPublicFields: true,
|
||||
}).then(m => {
|
||||
this.members.push(...m);
|
||||
this.$store.state.memberModalOptions.loading = false;
|
||||
});
|
||||
} else {
|
||||
this.$store.state.memberModalOptions.loading = false;
|
||||
}
|
||||
},
|
||||
editTask (task) {
|
||||
this.taskFormPurpose = 'edit';
|
||||
this.editingTask = cloneDeep(task);
|
||||
@@ -489,6 +508,8 @@ export default {
|
||||
this.tasksByType[task.type].splice(index, 1);
|
||||
},
|
||||
showMemberModal () {
|
||||
this.initialMembersLoad();
|
||||
|
||||
this.$root.$emit('habitica:show-member-modal', {
|
||||
challengeId: this.challenge._id,
|
||||
groupId: 'challenge', // @TODO: change these terrible settings
|
||||
@@ -501,8 +522,8 @@ export default {
|
||||
async joinChallenge () {
|
||||
this.user.challenges.push(this.searchId);
|
||||
this.challenge = await this.$store.dispatch('challenges:joinChallenge', { challengeId: this.searchId });
|
||||
this.members = await this
|
||||
.loadMembers({ challengeId: this.searchId, includeAllPublicFields: true });
|
||||
this.membersLoaded = false;
|
||||
this.members = [];
|
||||
|
||||
await this.$store.dispatch('tasks:fetchUserTasks', { forceLoad: true });
|
||||
},
|
||||
@@ -511,10 +532,11 @@ export default {
|
||||
},
|
||||
async updateChallenge () {
|
||||
this.challenge = await this.$store.dispatch('challenges:getChallenge', { challengeId: this.searchId });
|
||||
this.members = await this
|
||||
.loadMembers({ challengeId: this.searchId, includeAllPublicFields: true });
|
||||
this.membersLoaded = false;
|
||||
this.members = [];
|
||||
},
|
||||
closeChallenge () {
|
||||
this.initialMembersLoad();
|
||||
this.$root.$emit('bv::show::modal', 'close-challenge-modal');
|
||||
},
|
||||
edit () {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</p>
|
||||
<div
|
||||
ref="markdownContainer"
|
||||
class="text"
|
||||
class="text markdown"
|
||||
v-html="parseMarkdown(msg.text)"
|
||||
></div>
|
||||
<hr>
|
||||
@@ -166,7 +166,6 @@
|
||||
color: #4e4a57;
|
||||
text-align: left !important;
|
||||
min-height: 0rem;
|
||||
margin-bottom: -0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ export default {
|
||||
created () {
|
||||
window.addEventListener('scroll', this.handleScroll);
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('scroll', this.handleScroll);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
this.$root.$emit('bv::show::modal', 'copyAsTodo');
|
||||
});
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
this.$root.$off('habitica::copy-as-todo');
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -122,10 +122,10 @@ export default {
|
||||
};
|
||||
},
|
||||
},
|
||||
created () {
|
||||
mounted () {
|
||||
this.$root.$on('habitica::report-chat', this.handleReport);
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
this.$root.$off('habitica::report-chat', this.handleReport);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -385,7 +385,7 @@
|
||||
import extend from 'lodash/extend';
|
||||
import groupUtilities from '@/mixins/groupsUtilities';
|
||||
import styleHelper from '@/mixins/styleHelper';
|
||||
import { mapState } from '@/libs/store';
|
||||
import { mapState, mapGetters } from '@/libs/store';
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
import startQuestModal from './startQuestModal';
|
||||
import questDetailsModal from './questDetailsModal';
|
||||
@@ -447,6 +447,7 @@ export default {
|
||||
bronzeGuildBadgeIcon,
|
||||
}),
|
||||
members: [],
|
||||
membersLoaded: false,
|
||||
selectedQuest: {},
|
||||
chat: {
|
||||
submitDisable: false,
|
||||
@@ -455,7 +456,12 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
...mapState({
|
||||
user: 'user.data',
|
||||
}),
|
||||
...mapGetters({
|
||||
partyMembers: 'party:members',
|
||||
}),
|
||||
partyStore () {
|
||||
return this.$store.state.party;
|
||||
},
|
||||
@@ -487,10 +493,15 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
async mounted () {
|
||||
if (this.isParty) this.searchId = 'party';
|
||||
if (!this.searchId) this.searchId = this.groupId;
|
||||
this.load();
|
||||
await this.fetchGuild();
|
||||
|
||||
this.$root.$on('updatedGroup', this.onGroupUpdate);
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$root.$off('updatedGroup', this.onGroupUpdate);
|
||||
},
|
||||
beforeRouteUpdate (to, from, next) {
|
||||
this.$set(this, 'searchId', to.params.groupId);
|
||||
@@ -501,19 +512,9 @@ export default {
|
||||
acceptCommunityGuidelines () {
|
||||
this.$store.dispatch('user:set', { 'flags.communityGuidelinesAccepted': true });
|
||||
},
|
||||
async load () {
|
||||
if (this.isParty) {
|
||||
this.searchId = 'party';
|
||||
// @TODO: Set up from old client. Decide what we need and what we don't
|
||||
// Check Desktop notifs
|
||||
// Load invites
|
||||
}
|
||||
await this.fetchGuild();
|
||||
|
||||
this.$root.$on('updatedGroup', group => {
|
||||
const updatedGroup = extend(this.group, group);
|
||||
this.$set(this.group, updatedGroup);
|
||||
});
|
||||
onGroupUpdate (group) {
|
||||
const updatedGroup = extend(this.group, group);
|
||||
this.$set(this.group, updatedGroup);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -531,6 +532,26 @@ export default {
|
||||
return this.$store.dispatch('members:getGroupMembers', payload);
|
||||
},
|
||||
showMemberModal () {
|
||||
this.$store.state.memberModalOptions.loading = true;
|
||||
|
||||
if (this.isParty) {
|
||||
this.membersLoaded = true;
|
||||
this.members = this.partyMembers;
|
||||
this.$store.state.memberModalOptions.loading = false;
|
||||
} else if (!this.membersLoaded) {
|
||||
this.membersLoaded = true;
|
||||
|
||||
this.loadMembers({
|
||||
groupId: this.group._id,
|
||||
includeAllPublicFields: true,
|
||||
}).then(m => {
|
||||
this.members.push(...m);
|
||||
this.$store.state.memberModalOptions.loading = false;
|
||||
});
|
||||
} else {
|
||||
this.$store.state.memberModalOptions.loading = false;
|
||||
}
|
||||
|
||||
this.$root.$emit('habitica:show-member-modal', {
|
||||
groupId: this.group._id,
|
||||
group: this.group,
|
||||
@@ -565,19 +586,13 @@ export default {
|
||||
|
||||
const groupId = this.searchId === 'party' ? this.user.party._id : this.searchId;
|
||||
if (this.hasUnreadMessages(groupId)) {
|
||||
// Delay by 1sec to make sure it returns after
|
||||
// other requests that don't have the notification marked as read
|
||||
setTimeout(() => {
|
||||
this.$store.dispatch('chat:markChatSeen', { groupId });
|
||||
this.$delete(this.user.newMessages, groupId);
|
||||
}, 1000);
|
||||
const notification = this.user
|
||||
.notifications.find(n => n.type === 'NEW_CHAT_MESSAGE' && n.data.group.id === groupId);
|
||||
const notificationId = notification && notification.id;
|
||||
this.$store.dispatch('chat:markChatSeen', { groupId, notificationId });
|
||||
}
|
||||
|
||||
this.members = await this.loadMembers({
|
||||
groupId: this.group._id,
|
||||
includeAllPublicFields: true,
|
||||
});
|
||||
},
|
||||
// returns the notification id or false
|
||||
hasUnreadMessages (groupId) {
|
||||
if (this.user.newMessages[groupId]) return true;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<b-form-input
|
||||
v-model="workingGroup.name"
|
||||
type="text"
|
||||
:placeholder="$t('newGuildPlaceholder')"
|
||||
:placeholder="isParty ? $t('newPartyPlaceholder') : $t('newGuildPlaceholder')"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -99,14 +99,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="selectedPage === 'members'">
|
||||
<loading-gryphon v-if="loading" />
|
||||
<div
|
||||
v-if="selectedPage === 'members' && !loading"
|
||||
:class="{'mt-1': invites.length === 0}"
|
||||
>
|
||||
<div
|
||||
v-for="(member, index) in sortedMembers"
|
||||
:key="member._id"
|
||||
class="row"
|
||||
>
|
||||
<div class="col-11 no-padding-left">
|
||||
<member-details :member="member" />
|
||||
<member-details
|
||||
:member="member"
|
||||
:class-badge-position="'next-to-name'"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-1 actions">
|
||||
<b-dropdown right="right">
|
||||
@@ -201,7 +208,7 @@
|
||||
class="row gradient"
|
||||
></div>
|
||||
</div>
|
||||
<div v-if="selectedPage === 'invites'">
|
||||
<div v-if="selectedPage === 'invites' && !loading">
|
||||
<div
|
||||
v-for="(member, index) in invites"
|
||||
:key="member._id"
|
||||
@@ -234,14 +241,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="close()"
|
||||
>
|
||||
{{ $t('close') }}
|
||||
</button>
|
||||
</div>
|
||||
</b-modal>
|
||||
</div>
|
||||
</template>
|
||||
@@ -254,11 +253,6 @@
|
||||
box-shadow: 0 1px 2px 0 rgba(26, 24, 29, 0.24);
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
background-color: #edecee;
|
||||
border-radius: 0 0 8px 8px;
|
||||
}
|
||||
|
||||
.small-text, .character-name {
|
||||
color: #878190;
|
||||
}
|
||||
@@ -270,6 +264,8 @@
|
||||
.modal-body {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.member-details {
|
||||
@@ -378,6 +374,7 @@ import isEmpty from 'lodash/isEmpty';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
import removeMemberModal from '@/components/members/removeMemberModal';
|
||||
import loadingGryphon from '@/components/ui/loadingGryphon';
|
||||
import MemberDetails from '../memberDetails';
|
||||
import removeIcon from '@/assets/members/remove.svg';
|
||||
import messageIcon from '@/assets/members/message.svg';
|
||||
@@ -388,6 +385,7 @@ export default {
|
||||
components: {
|
||||
MemberDetails,
|
||||
removeMemberModal,
|
||||
loadingGryphon,
|
||||
},
|
||||
props: ['hideBadge'],
|
||||
data () {
|
||||
@@ -474,6 +472,9 @@ export default {
|
||||
challengeId () {
|
||||
return this.$store.state.memberModalOptions.challengeId;
|
||||
},
|
||||
loading () {
|
||||
return this.$store.state.memberModalOptions.loading;
|
||||
},
|
||||
sortedMembers () {
|
||||
let sortedMembers = this.members.slice(); // shallow clone to avoid infinite loop
|
||||
|
||||
@@ -504,16 +505,6 @@ export default {
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
groupId () {
|
||||
// @TODO: We might not need this since groupId is computed now
|
||||
this.getMembers();
|
||||
},
|
||||
challengeId () {
|
||||
this.getMembers();
|
||||
},
|
||||
group () {
|
||||
this.getMembers();
|
||||
},
|
||||
// Watches `searchTerm` and if present, performs a `searchMembers` action
|
||||
// and usual `getMembers` otherwise
|
||||
searchTerm () {
|
||||
@@ -537,7 +528,7 @@ export default {
|
||||
this.getMembers();
|
||||
});
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
this.$root.$off('habitica:show-member-modal');
|
||||
},
|
||||
methods: {
|
||||
@@ -558,8 +549,9 @@ export default {
|
||||
});
|
||||
},
|
||||
async getMembers () {
|
||||
const { groupId } = this;
|
||||
this.members = this.$store.state.memberModalOptions.viewingMembers;
|
||||
|
||||
const { groupId } = this;
|
||||
if (groupId && groupId !== 'challenge') {
|
||||
const invites = await this.$store.dispatch('members:getGroupInvites', {
|
||||
groupId,
|
||||
@@ -567,8 +559,6 @@ export default {
|
||||
});
|
||||
this.invites = invites;
|
||||
}
|
||||
|
||||
this.members = this.$store.state.memberModalOptions.viewingMembers;
|
||||
},
|
||||
async clickMember (uid, forceShow) {
|
||||
const user = this.$store.state.user.data;
|
||||
|
||||
@@ -209,7 +209,7 @@ export default {
|
||||
|
||||
this.$root.$on('selectQuest', this.selectQuest);
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
this.$root.$off('selectQuest', this.selectQuest);
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -365,7 +365,7 @@
|
||||
<li>
|
||||
<a
|
||||
v-once
|
||||
href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents"
|
||||
href="https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link"
|
||||
target="_blank"
|
||||
>{{ $t('requestFeature') }}</a>
|
||||
</li>
|
||||
|
||||
@@ -61,13 +61,9 @@
|
||||
<small>
|
||||
1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available, and name-tag coloring. Tiers 8 and 9 are automatically given admin status. <!-- eslint-disable-line max-len -->
|
||||
<a
|
||||
href="https://habitica.fandom.com/wiki/Contributor_Rewards"
|
||||
target="_blank"
|
||||
href="https://trello.com/c/wkFzONhE/277-contributor-gear"
|
||||
>More details (1-7)</a>,
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/HabitRPG/habitica/issues/3801"
|
||||
>more details (8-9)</a>
|
||||
>More details</a>
|
||||
</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
/>
|
||||
<div
|
||||
v-if="hasParty"
|
||||
class="view-party d-flex align-items-center"
|
||||
class="view-party d-none d-md-flex align-items-center"
|
||||
>
|
||||
<button
|
||||
class="btn btn-primary view-party-button"
|
||||
class="btn btn-primary"
|
||||
@click="showPartyMembers()"
|
||||
>
|
||||
{{ $t('viewParty') }}
|
||||
@@ -32,7 +32,7 @@
|
||||
v-if="hasParty"
|
||||
ref="partyMembersDiv"
|
||||
v-resize="1500"
|
||||
class="party-members d-flex"
|
||||
class="party-members d-none d-md-flex "
|
||||
@resized="setPartyMembersWidth($event)"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
@@ -51,7 +51,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="no-party d-flex justify-content-center text-center"
|
||||
class="no-party d-none d-md-flex justify-content-center text-center mr-4"
|
||||
>
|
||||
<div class="align-self-center">
|
||||
<h3>{{ $t('battleWithFriends') }}</h3>
|
||||
@@ -119,12 +119,6 @@
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.view-party-button {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@@ -222,8 +216,8 @@ export default {
|
||||
this.$root.$emit('bv::show::modal', 'invite-modal');
|
||||
});
|
||||
},
|
||||
destroyed () {
|
||||
this.$root.off('inviteModal::inviteToGroup');
|
||||
beforeDestroy () {
|
||||
this.$root.$off('inviteModal::inviteToGroup');
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
@@ -250,6 +244,7 @@ export default {
|
||||
groupId: party.data._id,
|
||||
viewingMembers: this.partyMembers,
|
||||
group: party.data,
|
||||
fetchMoreMembers: p => this.$store.dispatch('members:getGroupMembers', p),
|
||||
});
|
||||
},
|
||||
setPartyMembersWidth ($event) {
|
||||
|
||||
@@ -323,7 +323,7 @@
|
||||
</router-link>
|
||||
<a
|
||||
class="topbar-dropdown-item dropdown-item"
|
||||
href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents"
|
||||
href="https://docs.google.com/forms/d/e/1FAIpQLScPhrwq_7P1C6PTrI3lbvTsvqGyTNnGzp1ugi1Ml0PFee_p5g/viewform?usp=sf_link"
|
||||
target="_blank"
|
||||
>{{ $t('requestAF') }}</a>
|
||||
<a
|
||||
|
||||
@@ -182,10 +182,10 @@ export default {
|
||||
remove () {
|
||||
if (this.notification.type === 'NEW_CHAT_MESSAGE') {
|
||||
const groupId = this.notification.data.group.id;
|
||||
this.$store.dispatch('chat:markChatSeen', { groupId });
|
||||
if (this.user.newMessages[groupId]) {
|
||||
this.$delete(this.user.newMessages, groupId);
|
||||
}
|
||||
this.$store.dispatch('chat:markChatSeen', {
|
||||
groupId,
|
||||
notificationId: this.notification.id,
|
||||
});
|
||||
} else {
|
||||
this.readNotification({ notificationId: this.notification.id });
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<base-notification
|
||||
v-if="worldBoss.active"
|
||||
v-if="worldBoss && worldBoss.active"
|
||||
:can-remove="false"
|
||||
:notification="{}"
|
||||
:read-after-click="false"
|
||||
@@ -11,10 +11,16 @@
|
||||
class="background"
|
||||
>
|
||||
<div class="text">
|
||||
<div class="title">
|
||||
<div
|
||||
v-once
|
||||
class="title"
|
||||
>
|
||||
{{ $t('worldBoss') }}
|
||||
</div>
|
||||
<div class="sub-title">
|
||||
<div
|
||||
v-once
|
||||
class="sub-title"
|
||||
>
|
||||
{{ $t('questDysheartenerText') }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,6 +46,7 @@
|
||||
</div>
|
||||
<div class="pending-damage">
|
||||
<div
|
||||
v-once
|
||||
class="svg-icon"
|
||||
v-html="icons.sword"
|
||||
></div>
|
||||
@@ -182,11 +189,13 @@ export default {
|
||||
sword,
|
||||
}),
|
||||
questData,
|
||||
worldBoss: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
...mapState({
|
||||
user: 'user.data',
|
||||
worldBoss: 'worldState.data.worldBoss',
|
||||
}),
|
||||
bossHp () {
|
||||
if (this.worldBoss && this.worldBoss.progress) {
|
||||
return this.worldBoss.progress.hp;
|
||||
@@ -195,8 +204,7 @@ export default {
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
const result = await this.$store.dispatch('worldState:getWorldState');
|
||||
this.worldBoss = result.worldBoss;
|
||||
await this.$store.dispatch('worldState:getWorldState');
|
||||
},
|
||||
methods: {
|
||||
action () {
|
||||
|
||||
@@ -419,6 +419,11 @@ export default {
|
||||
cardType: '',
|
||||
messageOptions: 0,
|
||||
},
|
||||
quantitySnapshot: {
|
||||
eggs: null,
|
||||
hatchingPotions: null,
|
||||
food: null,
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -443,7 +448,9 @@ export default {
|
||||
if (itemQuantity > 0 && isAllowed) {
|
||||
const item = contentItems[itemKey];
|
||||
|
||||
const isSearched = !searchText || item.text().toLowerCase().indexOf(searchText) !== -1;
|
||||
const isSearched = !searchText || item.text()
|
||||
.toLowerCase()
|
||||
.indexOf(searchText) !== -1;
|
||||
if (isSearched) {
|
||||
itemsArray.push({
|
||||
...item,
|
||||
@@ -458,12 +465,16 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
itemsArray.sort((a, b) => {
|
||||
if (this.sortBy === 'quantity') {
|
||||
return b.quantity - a.quantity;
|
||||
} // AZ
|
||||
return a.text.localeCompare(b.text);
|
||||
});
|
||||
if (this.sortBy === 'quantity') {
|
||||
// Store original quantities, to avoid reordering when using items.
|
||||
const quantitySnapshot = this.quantitySnapshot[groupKey] || Object.fromEntries(
|
||||
itemsArray.map(item => [item.key, item.quantity]),
|
||||
);
|
||||
itemsArray.sort((a, b) => quantitySnapshot[b.key] - quantitySnapshot[a.key]);
|
||||
this.quantitySnapshot[groupKey] = quantitySnapshot;
|
||||
} else {
|
||||
itemsArray.sort((a, b) => a.text.localeCompare(b.text));
|
||||
}
|
||||
});
|
||||
|
||||
const specialArray = itemsByType.special;
|
||||
|
||||
@@ -124,7 +124,7 @@ export default {
|
||||
mounted () {
|
||||
this.$root.$on('hatchedPet::open', this.openDialog);
|
||||
},
|
||||
destroyed () {
|
||||
beforeDestroy () {
|
||||
this.$root.$off('hatchedPet::open', this.openDialog);
|
||||
},
|
||||
methods: {
|
||||
|
||||