Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea20bd5070 | |||
| c98d7aae37 | |||
| 21d27d223c | |||
| b0bb537501 | |||
| 75783345aa | |||
| 931e2565b6 | |||
| 2f6584378d | |||
| 519a580b7b | |||
| c99d62228f | |||
| 581a40ffad | |||
| 61c78355bd | |||
| f82c93a9ec | |||
| e8c6340af8 | |||
| 1e66cc9193 | |||
| ef6d835391 | |||
| 51f7ce3280 | |||
| 2b7891e788 | |||
| c640a648b9 | |||
| 116f0446e5 | |||
| 065e8303df | |||
| 74d3c9366a | |||
| c9a56e8f3e | |||
| d28e1708c5 | |||
| e091072367 | |||
| 7b1032e898 | |||
| 855470ed25 | |||
| 631efd1adc | |||
| 2e227909a4 | |||
| e5c52625ad | |||
| 8f9f95fd84 | |||
| ff334d08e2 | |||
| 25b443a7c6 | |||
| 6724413ce9 | |||
| 684a615a07 | |||
| babceaff42 | |||
| c29e9ddfc6 | |||
| 0cd0bcf874 | |||
| 544a703df5 | |||
| 0b32692290 | |||
| 20fc233ad7 | |||
| adbe58a0da | |||
| b1b90d6dba | |||
| ef29247526 | |||
| 1c59e78ea9 | |||
| 18e4e11a95 | |||
| 82f34ed437 | |||
| 3b268287b1 | |||
| 0e253fbb06 | |||
| 043696c225 | |||
| 69c2b0378f | |||
| fcfc44fd13 | |||
| 76773d27c6 | |||
| b3e81177ec |
@@ -13,3 +13,8 @@ Habitica uses [Trello](https://trello.com/b/EpoYEYod/habitica) to track feature
|
||||
# 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).
|
||||
|
||||
|
||||
@@ -67,12 +67,6 @@
|
||||
"SLACK_FLAGGING_URL": "https://hooks.slack.com/services/id/id/id",
|
||||
"SLACK_SUBSCRIPTIONS_URL": "https://hooks.slack.com/services/id/id/id",
|
||||
"SLACK_URL": "https://hooks.slack.com/services/some-url",
|
||||
"SMTP_HOST": "example.com",
|
||||
"SMTP_PASS": "password",
|
||||
"SMTP_PORT": 587,
|
||||
"SMTP_SERVICE": "Gmail",
|
||||
"SMTP_TLS": "true",
|
||||
"SMTP_USER": "user@example.com",
|
||||
"STRIPE_API_KEY": "aaaabbbbccccddddeeeeffff00001111",
|
||||
"STRIPE_PUB_KEY": "22223333444455556666777788889999",
|
||||
"TEST_DB_URI": "mongodb://localhost/habitrpg_test",
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20190716_groups_fix';
|
||||
|
||||
import monk from 'monk';
|
||||
import nconf from 'nconf';
|
||||
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
let backupUsers;
|
||||
|
||||
async function updateUser (user) {
|
||||
count++;
|
||||
|
||||
let set = { migration: MIGRATION_NAME };
|
||||
let addToSet;
|
||||
|
||||
const monkPromise = new Promise((resolve, reject) => {
|
||||
backupUsers.findOne(
|
||||
{ _id: user._id },
|
||||
{ fields: { _id: 1, party: 1, guilds: 1 }},
|
||||
).then(foundUserInBackup => {
|
||||
resolve(foundUserInBackup);
|
||||
}).catch(e => {
|
||||
reject(e);
|
||||
})
|
||||
});
|
||||
let backupUser = await monkPromise;
|
||||
if (!backupUser) return;
|
||||
|
||||
if (!user.party._id) {
|
||||
set.party = backupUser.party;
|
||||
}
|
||||
addToSet = { guilds: { $each: backupUser.guilds }};
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
|
||||
|
||||
return User.update({ _id: user._id }, { $set: set, $addToSet: addToSet }).exec();
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
const query = {
|
||||
'auth.timestamps.loggedin': {$gt: new Date('2019-07-15')},
|
||||
};
|
||||
|
||||
let backupDb = monk(CONNECTION_STRING);
|
||||
const backupDbPromise = new Promise((resolve, reject) => {
|
||||
backupDb.then(() => resolve()).catch((e) => reject(e));
|
||||
});
|
||||
|
||||
await backupDbPromise;
|
||||
console.log('Connected to backup db');
|
||||
backupUsers = backupDb.get('users', { castIds: false });
|
||||
|
||||
const fields = {
|
||||
_id: 1,
|
||||
party: 1,
|
||||
guilds: 1,
|
||||
};
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const users = await User // eslint-disable-line no-await-in-loop
|
||||
.find(query)
|
||||
.limit(250)
|
||||
.sort({_id: 1})
|
||||
.select(fields)
|
||||
.lean()
|
||||
.exec();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
console.warn(`\n${count} users processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: users[users.length - 1],
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(users.map(updateUser)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,88 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = '20190717_groups_fix_2';
|
||||
|
||||
import monk from 'monk';
|
||||
import nconf from 'nconf';
|
||||
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
|
||||
|
||||
import { model as User } from '../../../website/server/models/user';
|
||||
import { sendTxn as sendTxnEmail } from '../../../website/server/libs/email';
|
||||
import shared from '../../../website/common';
|
||||
|
||||
const questScrolls = shared.content.quests;
|
||||
|
||||
const progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
async function updateGroup (group) {
|
||||
count++;
|
||||
|
||||
if (group && group.quest && group.quest.key && group.quest.leader) {
|
||||
const quest = questScrolls[group.quest.key];
|
||||
const leader = await User.findOne({_id: group.quest.leader}).exec();
|
||||
|
||||
if (leader && quest) {
|
||||
await User.update({
|
||||
_id: leader._id,
|
||||
migration: {$ne: MIGRATION_NAME},
|
||||
}, {
|
||||
$set: {migration: MIGRATION_NAME},
|
||||
$inc: {
|
||||
balance: 1,
|
||||
[`items.quests.${group.quest.key}`]: 1,
|
||||
},
|
||||
}).exec();
|
||||
|
||||
// unsubscribe from all is already checked by sendTxnEmail
|
||||
if (leader.preferences && leader.preferences.emailNotifications && leader.preferences.emailNotifications.majorUpdates !== false) {
|
||||
sendTxnEmail(leader, 'groups-outage');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count} ${group._id}`);
|
||||
}
|
||||
|
||||
module.exports = async function processUsers () {
|
||||
const query = {
|
||||
type: 'party'
|
||||
};
|
||||
|
||||
let backupDb = monk(CONNECTION_STRING);
|
||||
const backupDbPromise = new Promise((resolve, reject) => {
|
||||
backupDb.then(() => resolve()).catch((e) => reject(e));
|
||||
});
|
||||
|
||||
await backupDbPromise;
|
||||
console.log('Connected to backup db');
|
||||
const backupGroups = backupDb.get('groups', { castIds: false });
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
const groupsPromise = new Promise((resolve, reject) => {
|
||||
backupGroups
|
||||
.find(query, {
|
||||
limit: 250,
|
||||
sort: {_id: 1}
|
||||
})
|
||||
.then(foundGroupInBackup => {
|
||||
resolve(foundGroupInBackup);
|
||||
}).catch(e => {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
|
||||
const groups = await groupsPromise;
|
||||
|
||||
if (groups.length === 0) {
|
||||
console.warn('All appropriate groups found and modified.');
|
||||
console.warn(`\n${count} groups processed\n`);
|
||||
break;
|
||||
} else {
|
||||
query._id = {
|
||||
$gt: groups[groups.length - 1]._id,
|
||||
};
|
||||
}
|
||||
|
||||
await Promise.all(groups.map(updateGroup)); // eslint-disable-line no-await-in-loop
|
||||
}
|
||||
};
|
||||
@@ -17,7 +17,7 @@ function setUpServer () {
|
||||
setUpServer();
|
||||
|
||||
// Replace this with your migration
|
||||
const processUsers = require('./users/mystery-items.js');
|
||||
const processUsers = require('');
|
||||
processUsers()
|
||||
.then(function success () {
|
||||
process.exit(0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-console */
|
||||
const MIGRATION_NAME = 'mystery_items_201905';
|
||||
const MYSTERY_ITEMS = ['headAccessory_mystery_201905', 'back_mystery_201905'];
|
||||
const MIGRATION_NAME = 'mystery_items_201907';
|
||||
const MYSTERY_ITEMS = ['head_mystery_201907', 'armor_mystery_201907', 'eyewear_mystery_201907'];
|
||||
import { model as User } from '../../website/server/models/user';
|
||||
import { model as UserNotification } from '../../website/server/models/userNotification';
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "habitica",
|
||||
"description": "A habit tracker app which treats your goals like a Role Playing Game.",
|
||||
"version": "4.101.0",
|
||||
"version": "4.105.0",
|
||||
"main": "./website/server/index.js",
|
||||
"dependencies": {
|
||||
"@google-cloud/trace-agent": "^3.6.0",
|
||||
"@google-cloud/trace-agent": "^4.0.0",
|
||||
"@slack/client": "^3.8.1",
|
||||
"accepts": "^1.3.5",
|
||||
"amazon-payments": "^0.2.7",
|
||||
@@ -69,7 +69,6 @@
|
||||
"nconf": "^0.10.0",
|
||||
"node-gcm": "^1.0.2",
|
||||
"node-sass": "^4.9.0",
|
||||
"nodemailer": "^6.0.0",
|
||||
"ora": "^3.2.0",
|
||||
"pageres": "^5.1.0",
|
||||
"passport": "^0.4.0",
|
||||
@@ -89,7 +88,7 @@
|
||||
"stripe": "^5.9.0",
|
||||
"superagent": "^5.0.2",
|
||||
"svg-inline-loader": "^0.8.0",
|
||||
"svg-url-loader": "^2.3.2",
|
||||
"svg-url-loader": "^3.0.0",
|
||||
"svgo": "^1.2.0",
|
||||
"svgo-loader": "^2.1.0",
|
||||
"universal-analytics": "^0.4.17",
|
||||
@@ -152,7 +151,7 @@
|
||||
"chai": "^4.1.2",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"chalk": "^2.4.1",
|
||||
"chromedriver": "^73.0.0",
|
||||
"chromedriver": "^75.0.0",
|
||||
"connect-history-api-fallback": "^1.1.0",
|
||||
"coveralls": "^3.0.3",
|
||||
"cross-spawn": "^6.0.5",
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/* eslint-disable global-require */
|
||||
import got from 'got';
|
||||
import nconf from 'nconf';
|
||||
import nodemailer from 'nodemailer';
|
||||
import requireAgain from 'require-again';
|
||||
import logger from '../../../../website/server/libs/logger';
|
||||
import { TAVERN_ID } from '../../../../website/server/models/group';
|
||||
import { defer } from '../../../helpers/api-unit.helper';
|
||||
|
||||
@@ -35,42 +33,6 @@ function getUser () {
|
||||
describe('emails', () => {
|
||||
let pathToEmailLib = '../../../../website/server/libs/email';
|
||||
|
||||
describe('sendEmail', () => {
|
||||
let sendMailSpy;
|
||||
|
||||
beforeEach(() => {
|
||||
sendMailSpy = sandbox.stub().returns(defer().promise);
|
||||
sandbox.stub(nodemailer, 'createTransport').returns({
|
||||
sendMail: sendMailSpy,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
it('can send an email using the default transport', () => {
|
||||
let attachEmail = requireAgain(pathToEmailLib);
|
||||
attachEmail.send();
|
||||
expect(sendMailSpy).to.be.calledOnce;
|
||||
});
|
||||
|
||||
it('logs errors', (done) => {
|
||||
sandbox.stub(logger, 'error');
|
||||
|
||||
let attachEmail = requireAgain(pathToEmailLib);
|
||||
attachEmail.send();
|
||||
expect(sendMailSpy).to.be.calledOnce;
|
||||
defer().reject();
|
||||
|
||||
// wait for unhandledRejection event to fire
|
||||
setTimeout(() => {
|
||||
expect(logger.error).to.be.calledOnce;
|
||||
done();
|
||||
}, 20);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUserInfo', () => {
|
||||
it('returns an empty object if no field request', () => {
|
||||
let attachEmail = requireAgain(pathToEmailLib);
|
||||
@@ -84,7 +46,7 @@ describe('emails', () => {
|
||||
let user = getUser();
|
||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||
|
||||
expect(data).to.have.property('name', user.profile.name);
|
||||
expect(data).to.have.property('name', user.auth.local.username);
|
||||
expect(data).to.have.property('email', user.auth.local.email);
|
||||
expect(data).to.have.property('_id', user._id);
|
||||
expect(data).to.have.property('canSend', true);
|
||||
@@ -95,11 +57,11 @@ describe('emails', () => {
|
||||
let getUserInfo = attachEmail.getUserInfo;
|
||||
let user = getUser();
|
||||
delete user.profile.name;
|
||||
delete user.auth.local;
|
||||
delete user.auth.local.email;
|
||||
|
||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||
|
||||
expect(data).to.have.property('name', user.profile.name);
|
||||
expect(data).to.have.property('name', user.auth.local.username);
|
||||
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
||||
expect(data).to.have.property('_id', user._id);
|
||||
expect(data).to.have.property('canSend', true);
|
||||
@@ -114,7 +76,7 @@ describe('emails', () => {
|
||||
|
||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||
|
||||
expect(data).to.have.property('name', user.profile.name);
|
||||
expect(data).to.have.property('name', user.auth.local.username);
|
||||
expect(data).not.to.have.property('email');
|
||||
expect(data).to.have.property('_id', user._id);
|
||||
expect(data).to.have.property('canSend', true);
|
||||
|
||||
@@ -16,6 +16,7 @@ describe('payments/index', () => {
|
||||
beforeEach(async () => {
|
||||
user = new User();
|
||||
user.profile.name = 'sender';
|
||||
user.auth.local.username = 'sender';
|
||||
await user.save();
|
||||
|
||||
group = generateGroup({
|
||||
|
||||
@@ -6,7 +6,7 @@ describe('GET /inbox/messages', () => {
|
||||
let user;
|
||||
let otherUser;
|
||||
|
||||
before(async () => {
|
||||
beforeEach(async () => {
|
||||
[user, otherUser] = await Promise.all([generateUser(), generateUser()]);
|
||||
|
||||
await otherUser.post('/members/send-private-message', {
|
||||
|
||||
@@ -54,6 +54,21 @@ describe('POST /tasks/challenge/:challengeId', () => {
|
||||
expect(tasksOrder.habits).to.include(task.id);
|
||||
});
|
||||
|
||||
it('allows non-leader admin to add tasks to a challenge when not a member', async () => {
|
||||
const admin = await generateUser({'contributor.admin': true});
|
||||
let task = await admin.post(`/tasks/challenge/${challenge._id}`, {
|
||||
text: 'test habit from admin',
|
||||
type: 'habit',
|
||||
up: false,
|
||||
down: true,
|
||||
notes: 1976,
|
||||
});
|
||||
|
||||
let {tasksOrder} = await user.get(`/challenges/${challenge._id}`);
|
||||
|
||||
expect(tasksOrder.habits).to.include(task.id);
|
||||
});
|
||||
|
||||
it('returns error when user tries to create task with a alias', async () => {
|
||||
await expect(user.post(`/tasks/challenge/${challenge._id}`, {
|
||||
text: 'test habit',
|
||||
|
||||
@@ -44,7 +44,7 @@ describe('DELETE /inbox/messages/:messageId', () => {
|
||||
});
|
||||
|
||||
it('deletes one message', async () => {
|
||||
const messages = await user.get('/inbox/messages');
|
||||
const messages = await user.get('/inbox/paged-messages');
|
||||
|
||||
expect(messages.length).to.equal(3);
|
||||
|
||||
@@ -53,10 +53,10 @@ describe('DELETE /inbox/messages/:messageId', () => {
|
||||
expect(messages[2].text).to.equal('first');
|
||||
|
||||
await user.del(`/inbox/messages/${messages[1]._id}`);
|
||||
const updatedMessages = await user.get('/inbox/messages');
|
||||
const updatedMessages = await user.get('/inbox/paged-messages');
|
||||
expect(updatedMessages.length).to.equal(2);
|
||||
|
||||
expect(updatedMessages[0].text).to.equal('third');
|
||||
expect(updatedMessages[1].text).to.equal('first');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('GET /inbox/conversations', () => {
|
||||
let otherUser;
|
||||
let thirdUser;
|
||||
|
||||
before(async () => {
|
||||
beforeEach(async () => {
|
||||
[user, otherUser, thirdUser] = await Promise.all([generateUser(), generateUser(), generateUser()]);
|
||||
|
||||
await otherUser.post('/members/send-private-message', {
|
||||
@@ -41,4 +41,51 @@ describe('GET /inbox/conversations', () => {
|
||||
expect(result[0].user).to.be.equal(user.profile.name);
|
||||
expect(result[0].username).to.be.equal(user.auth.local.username);
|
||||
});
|
||||
|
||||
it('returns the user inbox messages as an array of ordered messages (from most to least recent)', async () => {
|
||||
const messages = await user.get('/inbox/paged-messages');
|
||||
|
||||
expect(messages.length).to.equal(5);
|
||||
|
||||
// message to yourself
|
||||
expect(messages[0].text).to.equal('fifth');
|
||||
expect(messages[0].sent).to.equal(false);
|
||||
expect(messages[0].uuid).to.equal(user._id);
|
||||
|
||||
expect(messages[1].text).to.equal('fourth');
|
||||
expect(messages[2].text).to.equal('third');
|
||||
expect(messages[3].text).to.equal('second');
|
||||
expect(messages[4].text).to.equal('first');
|
||||
});
|
||||
|
||||
it('returns four messages when using page-query ', async () => {
|
||||
const promises = [];
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
promises.push(user.post('/members/send-private-message', {
|
||||
toUserId: user.id,
|
||||
message: 'fourth',
|
||||
}));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const messages = await user.get('/inbox/paged-messages?page=1');
|
||||
|
||||
expect(messages.length).to.equal(5);
|
||||
});
|
||||
|
||||
it('returns only the messages of one conversation', async () => {
|
||||
const messages = await user.get(`/inbox/paged-messages?conversation=${otherUser.id}`);
|
||||
|
||||
expect(messages.length).to.equal(3);
|
||||
});
|
||||
|
||||
it('returns the correct message format', async () => {
|
||||
const messages = await otherUser.get(`/inbox/paged-messages?conversation=${user.id}`);
|
||||
|
||||
expect(messages[0].toUUID).to.equal(user.id); // from user
|
||||
expect(messages[1].toUUID).to.not.exist; // only filled if its from the chat partner
|
||||
expect(messages[2].toUUID).to.equal(user.id); // from user
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,10 +19,10 @@ describe('POST /members/flag-private-message/:messageId', () => {
|
||||
toUserId: receiver._id,
|
||||
});
|
||||
|
||||
let senderMessages = await userToSendMessage.get('/inbox/messages');
|
||||
let senderMessages = await userToSendMessage.get('/inbox/paged-messages');
|
||||
|
||||
let sendersMessageInSendersInbox = _.find(senderMessages, (message) => {
|
||||
return message.uuid === receiver._id && message.text === messageToSend;
|
||||
return message.toUUID === receiver._id && message.text === messageToSend;
|
||||
});
|
||||
|
||||
expect(sendersMessageInSendersInbox).to.exist;
|
||||
@@ -37,7 +37,7 @@ describe('POST /members/flag-private-message/:messageId', () => {
|
||||
toUserId: receiver._id,
|
||||
});
|
||||
|
||||
let receiversMessages = await receiver.get('/inbox/messages');
|
||||
let receiversMessages = await receiver.get('/inbox/paged-messages');
|
||||
|
||||
let sendersMessageInReceiversInbox = _.find(receiversMessages, (message) => {
|
||||
return message.uuid === userToSendMessage._id && message.text === messageToSend;
|
||||
@@ -55,7 +55,7 @@ describe('POST /members/flag-private-message/:messageId', () => {
|
||||
toUserId: receiver._id,
|
||||
});
|
||||
|
||||
let receiversMessages = await receiver.get('/inbox/messages');
|
||||
let receiversMessages = await receiver.get('/inbox/paged-messages');
|
||||
|
||||
let sendersMessageInReceiversInbox = _.find(receiversMessages, (message) => {
|
||||
return message.uuid === userToSendMessage._id && message.text === messageToSend;
|
||||
|
||||
@@ -83,12 +83,12 @@ context('avatar.vue', () => {
|
||||
expect(vm.paddingTop).to.equal('28px');
|
||||
});
|
||||
|
||||
it('is 24.5px if user has a pet', () => {
|
||||
it('is 24px if user has a pet', () => {
|
||||
vm.member.items = {
|
||||
currentPet: { name: 'Foo' },
|
||||
};
|
||||
|
||||
expect(vm.paddingTop).to.equal('24.5px');
|
||||
expect(vm.paddingTop).to.equal('24px');
|
||||
});
|
||||
|
||||
it('is 0px if user has a mount', () => {
|
||||
@@ -297,4 +297,4 @@ context('avatar.vue', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import ChallengeDetailComponent from 'client/components/challenges/challengeDetail.vue';
|
||||
import Store from 'client/libs/store';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Store);
|
||||
|
||||
describe('Challenge Detail', () => {
|
||||
let store;
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
store = new Store({
|
||||
state: {
|
||||
user: {
|
||||
data: {
|
||||
contributor: {
|
||||
admin: false,
|
||||
},
|
||||
challenges: [],
|
||||
stats: {
|
||||
},
|
||||
flags: {},
|
||||
preferences: {},
|
||||
party: {
|
||||
quest: {
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
'members:getChallengeMembers': () => {},
|
||||
'challenges:getChallenge': () => [
|
||||
{_id: '1', group: { name: '', type: ''}, memberCount: 1, name: '', summary: '', description: '', leader: '', price: 1},
|
||||
],
|
||||
'tasks:getChallengeTasks': () => [
|
||||
{_id: '1', type: 'habit'},
|
||||
{_id: '2', type: 'daily'},
|
||||
{_id: '3', type: 'reward'},
|
||||
{_id: '4', type: 'todo'},
|
||||
],
|
||||
},
|
||||
getters: {
|
||||
},
|
||||
});
|
||||
wrapper = shallowMount(ChallengeDetailComponent, {
|
||||
store,
|
||||
localVue,
|
||||
mocks: {
|
||||
$t: (string) => string,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('removes a destroyed task from task list', () => {
|
||||
let taskToRemove = {_id: '1', type: 'habit'};
|
||||
wrapper.vm.taskDestroyed(taskToRemove);
|
||||
expect(wrapper.vm.tasksByType[taskToRemove.type].length).to.eq(0);
|
||||
});
|
||||
});
|
||||
@@ -86,7 +86,7 @@ export async function generateGroup (leader, details = {}, update = {}) {
|
||||
// This is generate group + the ability to create
|
||||
// real users to populate it. The settings object
|
||||
// takes in:
|
||||
// members: Number - the number of group members to create. Defaults to 0.
|
||||
// members: Number - the number of group members to create. Defaults to 0. Does not include group leader.
|
||||
// inivtes: Number - the number of users to create and invite to the group. Defaults to 0.
|
||||
// groupDetails: Object - how to initialize the group
|
||||
// leaderDetails: Object - defaults for the leader, defaults with a gem balance so the user
|
||||
|
||||
@@ -80,7 +80,7 @@ export async function generateGroup (leader, details = {}, update = {}) {
|
||||
// This is generate group + the ability to create
|
||||
// real users to populate it. The settings object
|
||||
// takes in:
|
||||
// members: Number - the number of group members to create. Defaults to 0.
|
||||
// members: Number - the number of group members to create. Defaults to 0. Does not include group leader.
|
||||
// inivtes: Number - the number of users to create and invite to the group. Defaults to 0.
|
||||
// groupDetails: Object - how to initialize the group
|
||||
// leaderDetails: Object - defaults for the leader, defaults with a gem balance so the user
|
||||
|
||||
@@ -57,6 +57,7 @@ div
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#loading-screen-inapp {
|
||||
@@ -89,7 +90,6 @@ div
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
overflow-x: hidden;
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,72 +1,78 @@
|
||||
.promo_armoire_backgrounds_201906 {
|
||||
.promo_armoire_backgrounds_201907 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -720px;
|
||||
background-position: -776px 0px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_bronze_quest {
|
||||
.promo_glass_watery_potions {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -359px;
|
||||
width: 360px;
|
||||
height: 360px;
|
||||
}
|
||||
.promo_dolphin_quest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 553px;
|
||||
height: 358px;
|
||||
}
|
||||
.promo_floral_sunshine_potions {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -424px -720px;
|
||||
background-position: -776px -148px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_halfmoon_glasses {
|
||||
.promo_mystery_201907 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -963px -296px;
|
||||
width: 279px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_mystery_201905 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -963px -148px;
|
||||
background-position: -776px -444px;
|
||||
width: 282px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_oddballs_bundle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -963px 0px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
height: 144px;
|
||||
}
|
||||
.promo_orcas {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -963px -444px;
|
||||
background-position: -376px -286px;
|
||||
width: 219px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_seafoam {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -313px -473px;
|
||||
width: 425px;
|
||||
height: 148px;
|
||||
}
|
||||
.promo_seasonal_shop {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -1183px -444px;
|
||||
background-position: -596px -286px;
|
||||
width: 162px;
|
||||
height: 132px;
|
||||
}
|
||||
.promo_splashy_pals_bundle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -776px -296px;
|
||||
width: 423px;
|
||||
height: 147px;
|
||||
}
|
||||
.promo_splashy_skins {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px -286px;
|
||||
width: 375px;
|
||||
height: 186px;
|
||||
}
|
||||
.customize-option.promo_splashy_skins {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -25px -301px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.promo_summer_splash_2019 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -554px 0px;
|
||||
background-position: -367px 0px;
|
||||
width: 408px;
|
||||
height: 186px;
|
||||
}
|
||||
.promo_take_this {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -1246px -148px;
|
||||
background-position: -1059px -444px;
|
||||
width: 96px;
|
||||
height: 69px;
|
||||
}
|
||||
.scene_hiking {
|
||||
.scene_casting_spells {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: -554px -187px;
|
||||
width: 258px;
|
||||
height: 258px;
|
||||
background-position: 0px -473px;
|
||||
width: 312px;
|
||||
height: 222px;
|
||||
}
|
||||
.scene_tools {
|
||||
background-image: url('~assets/images/sprites/spritesmith-largeSprites-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 366px;
|
||||
height: 285px;
|
||||
}
|
||||
|
||||
@@ -364,769 +364,769 @@
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_apple_picking {
|
||||
.background_among_giant_anemones {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_aquarium {
|
||||
.background_apple_picking {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_archaeological_dig {
|
||||
.background_aquarium {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_archery_range {
|
||||
.background_archaeological_dig {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_at_the_docks {
|
||||
.background_archery_range {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_aurora {
|
||||
.background_at_the_docks {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_autumn_forest {
|
||||
.background_aurora {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_avalanche {
|
||||
.background_autumn_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_back_alley {
|
||||
.background_avalanche {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_back_of_giant_beast {
|
||||
.background_back_alley {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_bamboo_forest {
|
||||
.background_back_of_giant_beast {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_bayou {
|
||||
.background_bamboo_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_beach {
|
||||
.background_bayou {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_beehive {
|
||||
.background_beach {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_bell_tower {
|
||||
.background_beehive {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_beside_well {
|
||||
.background_bell_tower {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_birch_forest {
|
||||
.background_beside_well {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_blacksmithy {
|
||||
.background_birch_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_blizzard {
|
||||
.background_blacksmithy {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_blossoming_desert {
|
||||
.background_blizzard {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_blue {
|
||||
.background_blossoming_desert {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_bridge {
|
||||
.background_blue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_bug_covered_log {
|
||||
.background_bridge {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_buried_treasure {
|
||||
.background_bug_covered_log {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_champions_colosseum {
|
||||
.background_buried_treasure {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_cherry_trees {
|
||||
.background_champions_colosseum {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_chessboard_land {
|
||||
.background_cherry_trees {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_clouds {
|
||||
.background_chessboard_land {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_coral_reef {
|
||||
.background_clouds {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_cornfields {
|
||||
.background_coral_reef {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_cozy_barn {
|
||||
.background_cornfields {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_cozy_bedroom {
|
||||
.background_cozy_barn {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_cozy_library {
|
||||
.background_cozy_bedroom {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_creepy_castle {
|
||||
.background_cozy_library {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_crosscountry_ski_trail {
|
||||
.background_creepy_castle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_crystal_cave {
|
||||
.background_crosscountry_ski_trail {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dark_deep {
|
||||
.background_crystal_cave {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_deep_mine {
|
||||
.background_dark_deep {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_deep_sea {
|
||||
.background_deep_mine {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_desert_dunes {
|
||||
.background_deep_sea {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dilatory_castle {
|
||||
.background_desert_dunes {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dilatory_city {
|
||||
.background_dilatory_castle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dilatory_ruins {
|
||||
.background_dilatory_city {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_distant_castle {
|
||||
.background_dilatory_ruins {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dojo {
|
||||
.background_distant_castle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_drifting_raft {
|
||||
.background_dojo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_driving_a_coach {
|
||||
.background_drifting_raft {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_driving_a_sleigh {
|
||||
.background_driving_a_coach {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1278px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_duck_pond {
|
||||
.background_driving_a_sleigh {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dungeon {
|
||||
.background_duck_pond {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_dusty_canyons {
|
||||
.background_dungeon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_elegant_balcony {
|
||||
.background_dusty_canyons {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_fairy_ring {
|
||||
.background_elegant_balcony {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_fantastical_shoe_store {
|
||||
.background_fairy_ring {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_farmhouse {
|
||||
.background_fantastical_shoe_store {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_fiber_arts_room {
|
||||
.background_farmhouse {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_field_with_colored_eggs {
|
||||
.background_fiber_arts_room {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -1036px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_floating_islands {
|
||||
.background_field_with_colored_eggs {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -1184px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_floral_meadow {
|
||||
.background_floating_islands {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1562px -1332px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_flower_market {
|
||||
.background_floral_meadow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.customize-option.background_flower_market {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -25px -1495px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.background_flying_over_a_field_of_wildflowers {
|
||||
.background_flower_market {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.customize-option.background_flying_over_a_field_of_wildflowers {
|
||||
.customize-option.background_flower_market {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -167px -1495px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.background_flying_over_an_ancient_forest {
|
||||
.background_flying_over_a_field_of_wildflowers {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_flying_over_icy_steppes {
|
||||
.customize-option.background_flying_over_a_field_of_wildflowers {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -309px -1495px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
.background_flying_over_an_ancient_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_flying_over_rocky_canyon {
|
||||
.background_flying_over_icy_steppes {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_flying_over_snowy_mountains {
|
||||
.background_flying_over_rocky_canyon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_forest {
|
||||
.background_flying_over_snowy_mountains {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -1480px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_frigid_peak {
|
||||
.background_flying_over_tropical_islands {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1420px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_frosty_forest {
|
||||
.background_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_frozen_lake {
|
||||
.background_frigid_peak {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_garden_shed {
|
||||
.background_frosty_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_gazebo {
|
||||
.background_frozen_lake {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -1136px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_giant_birdhouse {
|
||||
.background_garden_shed {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_giant_book {
|
||||
.background_gazebo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_giant_florals {
|
||||
.background_giant_birdhouse {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_giant_seashell {
|
||||
.background_giant_book {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_giant_wave {
|
||||
.background_giant_florals {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_glowing_mushroom_cave {
|
||||
.background_giant_seashell {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_gorgeous_greenhouse {
|
||||
.background_giant_wave {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_grand_staircase {
|
||||
.background_glowing_mushroom_cave {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -888px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_graveyard {
|
||||
.background_gorgeous_greenhouse {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_green {
|
||||
.background_grand_staircase {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_guardian_statues {
|
||||
.background_graveyard {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_gumdrop_land {
|
||||
.background_green {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_habit_city_streets {
|
||||
.background_guardian_statues {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_halflings_house {
|
||||
.background_gumdrop_land {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -994px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_harvest_feast {
|
||||
.background_habit_city_streets {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_harvest_fields {
|
||||
.background_halflings_house {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_harvest_moon {
|
||||
.background_harvest_feast {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_haunted_house {
|
||||
.background_harvest_fields {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_ice_cave {
|
||||
.background_harvest_moon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_iceberg {
|
||||
.background_haunted_house {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_idyllic_cabin {
|
||||
.background_ice_cave {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -740px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_island_waterfalls {
|
||||
.background_iceberg {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_kelp_forest {
|
||||
.background_idyllic_cabin {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_lighthouse_shore {
|
||||
.background_island_waterfalls {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_lilypad {
|
||||
.background_kelp_forest {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_magic_beanstalk {
|
||||
.background_lake_with_floating_lanterns {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -852px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_magical_candles {
|
||||
.background_lighthouse_shore {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_magical_museum {
|
||||
.background_lilypad {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_marble_temple {
|
||||
.background_magic_beanstalk {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_market {
|
||||
.background_magical_candles {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_meandering_cave {
|
||||
.background_magical_museum {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_medieval_kitchen {
|
||||
.background_marble_temple {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -592px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_midnight_castle {
|
||||
.background_market {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_midnight_clouds {
|
||||
.background_meandering_cave {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_midnight_lake {
|
||||
.background_medieval_kitchen {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_mist_shrouded_mountain {
|
||||
.background_midnight_castle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -710px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_mistiflying_circus {
|
||||
.background_midnight_clouds {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_mountain_lake {
|
||||
.background_midnight_lake {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_mountain_pyramid {
|
||||
.background_mist_shrouded_mountain {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_night_dunes {
|
||||
.background_mistiflying_circus {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_ocean_sunrise {
|
||||
.background_mountain_lake {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -444px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_old_fashioned_bakery {
|
||||
.background_mountain_pyramid {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_on_tree_branch {
|
||||
.background_night_dunes {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_open_waters {
|
||||
.background_ocean_sunrise {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -568px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_orchard {
|
||||
.background_old_fashioned_bakery {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_pagodas {
|
||||
.background_on_tree_branch {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_park_with_statue {
|
||||
.background_open_waters {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_pirate_flag {
|
||||
.background_orchard {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -296px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_pixelists_workshop {
|
||||
.background_pagodas {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_pumpkin_patch {
|
||||
.background_park_with_statue {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -426px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_purple {
|
||||
.background_pirate_flag {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_pyramids {
|
||||
.background_pixelists_workshop {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_rainbow_meadow {
|
||||
.background_pumpkin_patch {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: 0px -148px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_rainbows_end {
|
||||
.background_purple {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -284px 0px;
|
||||
width: 141px;
|
||||
height: 147px;
|
||||
}
|
||||
.background_rainforest {
|
||||
.background_pyramids {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-0.png');
|
||||
background-position: -142px 0px;
|
||||
width: 141px;
|
||||
|
||||
@@ -1,36 +1,78 @@
|
||||
.quest_TEMPLATE_FOR_MISSING_IMAGE {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -502px -1510px;
|
||||
background-position: -502px -1546px;
|
||||
width: 221px;
|
||||
height: 39px;
|
||||
}
|
||||
.quest_dilatoryDistress3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dolphin {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1323px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_dustbunnies {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -883px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_egg {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -537px;
|
||||
width: 165px;
|
||||
height: 207px;
|
||||
}
|
||||
.quest_evilsanta {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1198px;
|
||||
width: 118px;
|
||||
height: 131px;
|
||||
}
|
||||
.quest_evilsanta2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_falcon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -663px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_ferret {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -232px;
|
||||
background-position: -663px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_frog {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -1112px;
|
||||
background-position: -1320px -1112px;
|
||||
width: 221px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_ghost_stag {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1323px -220px;
|
||||
background-position: -220px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -452px;
|
||||
background-position: -440px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_goldenknight2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -251px -1510px;
|
||||
background-position: -251px -1546px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
@@ -42,127 +84,127 @@
|
||||
}
|
||||
.quest_gryphon {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -657px -1332px;
|
||||
background-position: -1314px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_guineapig {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -663px 0px;
|
||||
background-position: -883px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_harpy {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -663px -220px;
|
||||
background-position: 0px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_hedgehog {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1102px -1112px;
|
||||
background-position: -220px -1332px;
|
||||
width: 219px;
|
||||
height: 186px;
|
||||
}
|
||||
.quest_hippo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -452px;
|
||||
background-position: -440px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_horse {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -452px;
|
||||
background-position: -660px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kangaroo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -452px;
|
||||
background-position: -880px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_kraken {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1091px -1332px;
|
||||
background-position: -1097px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_lostMasterclasser1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -883px -220px;
|
||||
background-position: -1103px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -883px -440px;
|
||||
background-position: -1103px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_lostMasterclasser3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -672px;
|
||||
background-position: -1103px -660px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -362px;
|
||||
background-position: -1760px -896px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_mayhemMistiflying2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -672px;
|
||||
background-position: -220px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_mayhemMistiflying3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -672px;
|
||||
background-position: -440px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_monkey {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -672px;
|
||||
background-position: -660px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1543px -217px;
|
||||
background-position: -1543px -868px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_moon2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1103px -220px;
|
||||
background-position: -1100px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moon3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1103px -440px;
|
||||
background-position: -1323px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1103px -660px;
|
||||
background-position: -1323px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -892px;
|
||||
background-position: -1323px -440px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_moonstone3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -892px;
|
||||
background-position: -443px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -174,67 +216,67 @@
|
||||
}
|
||||
.quest_octopus {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1332px;
|
||||
background-position: -440px -1332px;
|
||||
width: 222px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_owl {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -880px -892px;
|
||||
background-position: -220px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_peacock {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1543px -1085px;
|
||||
background-position: -1543px -217px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_penguin {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -178px;
|
||||
background-position: -1760px -353px;
|
||||
width: 190px;
|
||||
height: 183px;
|
||||
}
|
||||
.quest_pterodactyl {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -443px 0px;
|
||||
background-position: -880px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rat {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1323px -440px;
|
||||
background-position: -1100px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_rock {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1543px -434px;
|
||||
background-position: -1543px 0px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_rooster {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1525px -1332px;
|
||||
background-position: -1760px 0px;
|
||||
width: 213px;
|
||||
height: 174px;
|
||||
}
|
||||
.quest_sabretooth {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1112px;
|
||||
background-position: -660px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_seaserpent {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -1112px;
|
||||
background-position: -440px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_sheep {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -1112px;
|
||||
background-position: 0px -1112px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -246,103 +288,103 @@
|
||||
}
|
||||
.quest_sloth {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1323px -660px;
|
||||
background-position: -880px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_snail {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -882px -1112px;
|
||||
background-position: 0px -1332px;
|
||||
width: 219px;
|
||||
height: 213px;
|
||||
}
|
||||
.quest_snake {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -223px -1332px;
|
||||
background-position: -1543px -1085px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_spider {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -1510px;
|
||||
background-position: 0px -1546px;
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_squirrel {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1323px 0px;
|
||||
background-position: 0px -892px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -664px;
|
||||
background-position: -1760px -745px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_stoikalmCalamity2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1100px -892px;
|
||||
background-position: -1103px 0px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_stoikalmCalamity3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -660px -892px;
|
||||
background-position: -220px -672px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_taskwoodsTerror1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -513px;
|
||||
background-position: -1760px -1047px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.quest_taskwoodsTerror2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1543px -868px;
|
||||
background-position: -1543px -434px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_taskwoodsTerror3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -892px;
|
||||
background-position: -883px -220px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_treeling {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -1332px;
|
||||
background-position: -880px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_trex {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px 0px;
|
||||
background-position: -1760px -175px;
|
||||
width: 204px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_trex_undead {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1308px -1332px;
|
||||
background-position: -663px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_triceratops {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1103px 0px;
|
||||
background-position: -660px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_turtle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -220px -672px;
|
||||
background-position: 0px -452px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_unicorn {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -883px 0px;
|
||||
background-position: -220px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
@@ -354,265 +396,7 @@
|
||||
}
|
||||
.quest_vice1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -874px -1332px;
|
||||
background-position: -1531px -1332px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_vice2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -440px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_vice3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1322px -1112px;
|
||||
width: 216px;
|
||||
height: 177px;
|
||||
}
|
||||
.quest_whale {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: 0px -232px;
|
||||
width: 219px;
|
||||
height: 219px;
|
||||
}
|
||||
.quest_yarn {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1543px 0px;
|
||||
width: 216px;
|
||||
height: 216px;
|
||||
}
|
||||
.quest_atom1_soapBars {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -884px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_dilatoryDistress1_blueFins {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -1298px;
|
||||
width: 51px;
|
||||
height: 48px;
|
||||
}
|
||||
.quest_dilatoryDistress1_fireCoral {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -362px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_egg_plainEgg {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -414px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_evilsanta2_branches {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -513px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_evilsanta2_tracks {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -815px;
|
||||
width: 54px;
|
||||
height: 60px;
|
||||
}
|
||||
.quest_goldenknight1_testimony {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -953px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_lostMasterclasser1_ancientTome {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1436px;
|
||||
width: 33px;
|
||||
height: 42px;
|
||||
}
|
||||
.quest_lostMasterclasser1_forbiddenTome {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -1367px;
|
||||
width: 33px;
|
||||
height: 42px;
|
||||
}
|
||||
.quest_lostMasterclasser1_hiddenTome {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -768px;
|
||||
width: 33px;
|
||||
height: 42px;
|
||||
}
|
||||
.quest_mayhemMistiflying2_mistifly1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -565px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_mayhemMistiflying2_mistifly2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -664px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_mayhemMistiflying2_mistifly3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -716px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_moon1_shard {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -466px;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
}
|
||||
.quest_moonstone1_moonstone {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1932px -1367px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.quest_stoikalmCalamity2_icicleCoin {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -1022px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_taskwoodsTerror2_brownie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -1091px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_taskwoodsTerror2_dryad {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -1160px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_taskwoodsTerror2_pixie {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1898px -1229px;
|
||||
width: 48px;
|
||||
height: 51px;
|
||||
}
|
||||
.quest_vice2_lightCrystal {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1911px -617px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.inventory_quest_scroll_alligator {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1022px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_armadillo {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1091px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_atom1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -815px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_atom1_locked {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1091px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_atom2 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1229px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_atom2_locked {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1160px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_atom3 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1298px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_atom3_locked {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1229px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_axolotl {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1298px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_badger {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1367px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_basilist {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -1367px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_beetle {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1160px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_bronze {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1436px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_bunny {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -1022px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_butterfly {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -953px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_cheetah {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -953px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_cow {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -884px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_dilatoryDistress1 {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1829px -815px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
.inventory_quest_scroll_dilatory_derby {
|
||||
background-image: url('~assets/images/sprites/spritesmith-main-12.png');
|
||||
background-position: -1760px -884px;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 492 KiB After Width: | Height: | Size: 491 KiB |
|
Before Width: | Height: | Size: 592 KiB After Width: | Height: | Size: 610 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 182 KiB |
|
Before Width: | Height: | Size: 424 KiB After Width: | Height: | Size: 414 KiB |
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 173 KiB After Width: | Height: | Size: 166 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 153 KiB |
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 114 KiB |
@@ -1,13 +1,10 @@
|
||||
// Colors taken from the Habitica Color Palette
|
||||
// The palette is available at TODO ADD LINK TO PALETTE PDF
|
||||
// The palette is available at https://habitica.fandom.com/wiki/Guidance_for_Comrades?file=Color_palette_official.png
|
||||
// The colors are named from the darkest to the lightest
|
||||
|
||||
$white: #FFFFFF;
|
||||
$black: #1A181D;
|
||||
|
||||
$header-color: #D5C8FF;
|
||||
$header-dark-background: #271B3D;
|
||||
|
||||
$gray-10: #34313A;
|
||||
$gray-50: #4E4A57;
|
||||
$gray-100: #686274;
|
||||
@@ -18,13 +15,7 @@ $gray-500: #E1E0E3;
|
||||
$gray-600: #EDECEE;
|
||||
$gray-700: #F9F9F9;
|
||||
|
||||
$purple-50: #36205D;
|
||||
$purple-100: #432874;
|
||||
$purple-200: #4F2A93;
|
||||
$purple-300: #6133B4;
|
||||
$purple-400: #9A62FF;
|
||||
$purple-500: #BDA8FF;
|
||||
|
||||
$red-1: #6C0406;
|
||||
$red-10: #F23035;
|
||||
$red-50: #F74E52;
|
||||
$red-100: #FF6165;
|
||||
@@ -35,39 +26,55 @@ $maroon-50: #C92B2B;
|
||||
$maroon-100: #DE3F3F;
|
||||
$maroon-500: #F19595;
|
||||
|
||||
$yellow-5: #EE9109;
|
||||
$yellow-10: #FFA623;
|
||||
$yellow-50: #FFB445;
|
||||
$yellow-100: #FFBE5D;
|
||||
$yellow-500: #FFD9A0;
|
||||
|
||||
$orange-1: #7F3300;
|
||||
$orange-10: #F47825;
|
||||
$orange-50: #FA8537;
|
||||
$orange-100: #FF944C;
|
||||
$orange-500: #FFBF98;
|
||||
$orange-500: #FFC8A7;
|
||||
|
||||
$yellow-1: #794B00;
|
||||
$yellow-5: #EE9109;
|
||||
$yellow-10: #FFA624;
|
||||
$yellow-50: #FFB445;
|
||||
$yellow-100: #FFBE5D;
|
||||
$yellow-500: #FEDEAD;
|
||||
|
||||
$green-1: #005737;
|
||||
$green-10: #1CA372;
|
||||
$green-50: #20B780;
|
||||
$green-100: #24CC8F;
|
||||
$green-500: #77F4C7;
|
||||
|
||||
$teal-1: #005158;
|
||||
$teal-10: #26A0AB;
|
||||
$teal-50: #34B5C1;
|
||||
$teal-100: #3BCAD7;
|
||||
$teal-500: #8EEDF6;
|
||||
|
||||
$blue-1: #033F5E;
|
||||
$blue-10: #2995CD;
|
||||
$blue-50: #46A7D9;
|
||||
$blue-100: #50B5E9;
|
||||
$blue-500: #A9DCF6;
|
||||
|
||||
$teal-10: #20B2BF;
|
||||
$teal-50: #3BCAD7;
|
||||
$teal-100: #5EDDE9;
|
||||
$teal-500: #A5F7FF;
|
||||
$purple-50: #36205D;
|
||||
$purple-100: #432874;
|
||||
$purple-200: #4F2A93;
|
||||
$purple-300: #6133B4;
|
||||
$purple-400: #925CF3;
|
||||
$purple-500: #BDA8FF;
|
||||
$purple-600: #D5C8FF;
|
||||
|
||||
$green-10: #24CC8F;
|
||||
$green-50: #3FDAA2;
|
||||
$green-100: #5AEAB2;
|
||||
$green-500: #A6FFDF;
|
||||
$header-color: #D5C8FF;
|
||||
$header-dark-background: #271B3D;
|
||||
|
||||
$suggested-item-color: #D5C8FF;
|
||||
|
||||
$healer-color: #cf8229;
|
||||
$healer-color: #FFA624;
|
||||
$rogue-color: #4F2A93;
|
||||
$warrior-color: #B01515;
|
||||
$wizard-color: #1f6ea2;
|
||||
$warrior-color: #C92B2B;
|
||||
$wizard-color: #2995CD;
|
||||
|
||||
$gems-color: #24CC8F;
|
||||
$gold-color: #FFA623;
|
||||
$gold-color: #FFA624;
|
||||
$hourglass-color: #2995CD;
|
||||
|
||||
@@ -1,81 +1,86 @@
|
||||
.create-task-area {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
top: -23px;
|
||||
z-index: 999;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.slide-tasks-btns-leave-active, .slide-tasks-btns-enter-active {
|
||||
max-width: 240px;
|
||||
overflow-x: hidden;
|
||||
transition: all 0.3s cubic-bezier(0, 1, 0.5, 1);
|
||||
}
|
||||
|
||||
.slide-tasks-btns-enter, .slide-tasks-btns-leave-to {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.rounded-btn {
|
||||
margin-left: 8px;
|
||||
background: $white;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 100px;
|
||||
box-shadow: 0 2px 2px 0 rgba($black, 0.16), 0 1px 4px 0 rgba($black, 0.12);
|
||||
cursor: pointer;
|
||||
color: $gray-200;
|
||||
|
||||
&:hover:not(.create-btn) {
|
||||
color: $purple-400;
|
||||
box-shadow: 0 1px 8px 0 rgba($black, 0.12), 0 4px 4px 0 rgba($black, 0.16);
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
&.icon-habit {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
&.icon-daily {
|
||||
width: 21.6px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
&.icon-todo {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
&.icon-reward {
|
||||
width: 23.4px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.create-btn {
|
||||
color: $white;
|
||||
background-color: $green-10;
|
||||
|
||||
.svg-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transition: transform 0.3s cubic-bezier(0, 1, 0.5, 1);
|
||||
}
|
||||
|
||||
&.open {
|
||||
background: $gray-200 !important;
|
||||
|
||||
.svg-icon {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
.create-task-area {
|
||||
position: absolute;
|
||||
right: 24px;
|
||||
top: -24px;
|
||||
z-index: 999;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.slide-tasks-btns-leave-active, .slide-tasks-btns-enter-active {
|
||||
max-width: 320px;
|
||||
transition: all 0.3s cubic-bezier(0, 1, 0.5, 1);
|
||||
}
|
||||
|
||||
.slide-tasks-btns-enter, .slide-tasks-btns-leave-to {
|
||||
max-width: 0;
|
||||
opacity: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.diamond-btn {
|
||||
margin-left: 24px;
|
||||
background: $white;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 2px 0 rgba($black, 0.16), 0 1px 4px 0 rgba($black, 0.12);
|
||||
cursor: pointer;
|
||||
color: $gray-200;
|
||||
transform: rotate(45deg);
|
||||
|
||||
&:hover:not(.create-btn) {
|
||||
color: $purple-400;
|
||||
box-shadow: 0 1px 8px 0 rgba($black, 0.12), 0 4px 4px 0 rgba($black, 0.16);
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: rotate(-45deg);
|
||||
|
||||
&.icon-habit {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
&.icon-daily {
|
||||
width: 21.6px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
&.icon-todo {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
&.icon-reward {
|
||||
width: 23.4px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.create-btn {
|
||||
color: $white;
|
||||
background-color: $green-100;
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
|
||||
.svg-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transform: rotate(-45deg);
|
||||
transition: transform 0.3s cubic-bezier(0, 1, 0.5, 1);
|
||||
}
|
||||
|
||||
&.open {
|
||||
background: $gray-200 !important;
|
||||
|
||||
.svg-icon {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.popover-title-only {
|
||||
color: $white;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.popover-body {
|
||||
padding: 12px 16px;
|
||||
text-align: center;
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
&-good { // green
|
||||
&-control {
|
||||
&-bg {
|
||||
background: $green-10 !important;
|
||||
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; }
|
||||
@@ -151,7 +151,7 @@
|
||||
}
|
||||
|
||||
&-modal {
|
||||
&-bg { background: $green-10 !important; }
|
||||
&-bg { background: $green-100 !important; }
|
||||
&-icon { color: $green-10 !important; }
|
||||
&-text { color: #1ca372 !important; }
|
||||
&-option-disabled:hover {
|
||||
|
||||
@@ -113,11 +113,11 @@
|
||||
.footer-row {
|
||||
margin: 0;
|
||||
flex: 0 1 auto;
|
||||
z-index: 17;
|
||||
}
|
||||
|
||||
footer {
|
||||
color: #c3c0c7;
|
||||
z-index: 17;
|
||||
padding-bottom: 3em;
|
||||
|
||||
a {
|
||||
|
||||
@@ -139,7 +139,7 @@ export default {
|
||||
let val = '28px';
|
||||
|
||||
if (!this.avatarOnly) {
|
||||
if (this.member.items.currentPet) val = '24.5px';
|
||||
if (this.member.items.currentPet) val = '24px';
|
||||
if (this.member.items.currentMount) val = '0px';
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template lang="pug">
|
||||
.row
|
||||
challenge-modal(v-on:updatedChallenge='updatedChallenge')
|
||||
challenge-modal(@updatedChallenge='updatedChallenge')
|
||||
leave-challenge-modal(:challengeId='challenge._id')
|
||||
close-challenge-modal(:members='members', :challengeId='challenge._id', :prize='challenge.prize')
|
||||
challenge-member-progress-modal(:challengeId='challenge._id')
|
||||
@@ -47,8 +47,8 @@
|
||||
@cancel="cancelTaskModal()",
|
||||
ref="taskModal",
|
||||
:challengeId="challengeId",
|
||||
v-on:taskCreated='taskCreated',
|
||||
v-on:taskEdited='taskEdited',
|
||||
@taskCreated='taskCreated',
|
||||
@taskEdited='taskEdited',
|
||||
@taskDestroyed='taskDestroyed'
|
||||
)
|
||||
.row
|
||||
@@ -57,7 +57,8 @@
|
||||
:type="column",
|
||||
:key="column",
|
||||
:taskListOverride='tasksByType[column]',
|
||||
v-on:editTask="editTask",
|
||||
@editTask="editTask",
|
||||
@taskDestroyed="taskDestroyed",
|
||||
v-if='tasksByType[column].length > 0')
|
||||
.col-12.col-md-4.sidebar.standard-page
|
||||
.button-container(v-if='canJoin')
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
.autocomplete-results.d-flex.align-items-center(
|
||||
v-for='result in searchResults',
|
||||
@click='select(result)',
|
||||
@mouseenter='result.hover = true',
|
||||
@mouseleave='result.hover = false',
|
||||
@mouseenter='setHover(result)',
|
||||
@mouseleave='resetSelection()',
|
||||
:class='{"hover-background": result.hover}',
|
||||
)
|
||||
span
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
.hover-background {
|
||||
background-color: rgba(213, 200, 255, 0.32);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hover-foreground {
|
||||
@@ -86,6 +87,7 @@ export default {
|
||||
tier9,
|
||||
tierNPC,
|
||||
}),
|
||||
selected: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -120,12 +122,6 @@ export default {
|
||||
mounted () {
|
||||
this.grabUserNames();
|
||||
},
|
||||
created () {
|
||||
document.addEventListener('keyup', this.handleEsc);
|
||||
},
|
||||
destroyed () {
|
||||
document.removeEventListener('keyup', this.handleEsc);
|
||||
},
|
||||
watch: {
|
||||
text (newText) {
|
||||
if (!newText[newText.length - 1] || newText[newText.length - 1] === ' ') {
|
||||
@@ -154,6 +150,7 @@ export default {
|
||||
this.searchActive = false;
|
||||
this.searchEscaped = false;
|
||||
this.tmpSelections = [];
|
||||
this.resetSelection();
|
||||
},
|
||||
grabUserNames () {
|
||||
let usersThatMessage = groupBy(this.chat, 'user');
|
||||
@@ -189,13 +186,50 @@ export default {
|
||||
const targetName = `${result.username || result.displayName} `;
|
||||
newText = newText.replace(new RegExp(`${this.currentSearch}$`), targetName);
|
||||
this.$emit('select', newText);
|
||||
this.resetSelection();
|
||||
},
|
||||
handleEsc (e) {
|
||||
if (e.keyCode === 27) {
|
||||
this.searchActive = false;
|
||||
this.searchEscaped = true;
|
||||
setHover (result) {
|
||||
this.resetSelection();
|
||||
result.hover = true;
|
||||
},
|
||||
clearHover () {
|
||||
for (const selection of this.searchResults) {
|
||||
selection.hover = false;
|
||||
}
|
||||
},
|
||||
resetSelection () {
|
||||
this.clearHover();
|
||||
this.selected = null;
|
||||
},
|
||||
selectNext () {
|
||||
if (this.searchResults.length > 0) {
|
||||
this.clearHover();
|
||||
this.selected = this.selected === null ?
|
||||
0 :
|
||||
(this.selected + 1) % this.searchResults.length;
|
||||
this.searchResults[this.selected].hover = true;
|
||||
}
|
||||
},
|
||||
selectPrevious () {
|
||||
if (this.searchResults.length > 0) {
|
||||
this.clearHover();
|
||||
this.selected = this.selected === null ?
|
||||
this.searchResults.length - 1 :
|
||||
(this.selected - 1 + this.searchResults.length) % this.searchResults.length;
|
||||
this.searchResults[this.selected].hover = true;
|
||||
}
|
||||
},
|
||||
makeSelection () {
|
||||
if (this.searchResults.length > 0 && this.selected !== null) {
|
||||
const result = this.searchResults[this.selected];
|
||||
this.select(result);
|
||||
}
|
||||
},
|
||||
cancel () {
|
||||
this.searchActive = false;
|
||||
this.searchEscaped = true;
|
||||
this.resetSelection();
|
||||
},
|
||||
},
|
||||
mixins: [styleHelper],
|
||||
};
|
||||
|
||||
@@ -273,5 +273,8 @@ export default {
|
||||
return habiticaMarkdown.render(String(text));
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.$emit('chat-card-mounted', this.msg.id);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
<template lang="pug">
|
||||
.container-fluid
|
||||
.container-fluid(ref="container")
|
||||
.row
|
||||
.col-12
|
||||
copy-as-todo-modal(:group-type='groupType', :group-name='groupName', :group-id='groupId')
|
||||
.row.loadmore
|
||||
div(v-if="canLoadMore")
|
||||
.loadmore-divider
|
||||
button.btn.btn-secondary(@click='triggerLoad()') {{ $t('loadEarlierMessages') }}
|
||||
.loadmore-divider
|
||||
h2.col-12.loading(v-show="isLoading") {{ $t('loading') }}
|
||||
div(v-for="(msg, index) in messages", v-if='chat && canViewFlag(msg)', :class='{row: inbox}')
|
||||
.d-flex(v-if='user._id !== msg.uuid', :class='{"flex-grow-1": inbox}')
|
||||
avatar.avatar-left(
|
||||
@@ -21,7 +27,8 @@
|
||||
:groupId='groupId',
|
||||
@message-liked='messageLiked',
|
||||
@message-removed='messageRemoved',
|
||||
@show-member-modal='showMemberModal')
|
||||
@show-member-modal='showMemberModal',
|
||||
@chat-card-mounted='itemWasMounted')
|
||||
.d-flex(v-if='user._id === msg.uuid', :class='{"flex-grow-1": inbox}')
|
||||
.card(:class='{"col-10": inbox}')
|
||||
chat-card(
|
||||
@@ -30,7 +37,8 @@
|
||||
:groupId='groupId',
|
||||
@message-liked='messageLiked',
|
||||
@message-removed='messageRemoved',
|
||||
@show-member-modal='showMemberModal')
|
||||
@show-member-modal='showMemberModal',
|
||||
@chat-card-mounted='itemWasMounted')
|
||||
avatar(
|
||||
v-if='msg.userStyles || (cachedProfileData[msg.uuid] && !cachedProfileData[msg.uuid].rejected)',
|
||||
:member="msg.userStyles || cachedProfileData[msg.uuid]",
|
||||
@@ -49,6 +57,34 @@
|
||||
width: 10%;
|
||||
min-width: 7rem;
|
||||
}
|
||||
.loadmore {
|
||||
justify-content: center;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
text-align: center;
|
||||
color: $gray-50;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.loadmore-divider {
|
||||
height: 1px;
|
||||
background-color: $gray-500;
|
||||
flex: 1;
|
||||
margin-left: 24px;
|
||||
margin-right: 24px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-left {
|
||||
margin-left: -1.5rem;
|
||||
@@ -97,6 +133,8 @@
|
||||
.message-scroll .d-flex {
|
||||
min-width: 1px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@@ -120,6 +158,9 @@ export default {
|
||||
groupType: {},
|
||||
groupId: {},
|
||||
groupName: {},
|
||||
|
||||
isLoading: Boolean,
|
||||
canLoadMore: Boolean,
|
||||
},
|
||||
components: {
|
||||
copyAsTodoModal,
|
||||
@@ -142,6 +183,8 @@ export default {
|
||||
currentProfileLoadedCount: 0,
|
||||
currentProfileLoadedEnd: 10,
|
||||
loading: false,
|
||||
handleScrollBack: false,
|
||||
lastOffset: -1,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -153,15 +196,24 @@ export default {
|
||||
return this.chat;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
messages () {
|
||||
this.loadProfileCache();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleScroll () {
|
||||
this.loadProfileCache(window.scrollY / 1000);
|
||||
},
|
||||
async triggerLoad () {
|
||||
const container = this.$refs.container;
|
||||
|
||||
// get current offset
|
||||
this.lastOffset = container.scrollTop - (container.scrollHeight - container.clientHeight);
|
||||
// disable scroll
|
||||
container.style.overflowY = 'hidden';
|
||||
|
||||
const canLoadMore = this.inbox && !this.isLoading && this.canLoadMore;
|
||||
if (canLoadMore) {
|
||||
await this.$emit('triggerLoad');
|
||||
this.handleScrollBack = true;
|
||||
}
|
||||
},
|
||||
canViewFlag (message) {
|
||||
if (message.uuid === this.user._id) return true;
|
||||
if (!message.flagCount || message.flagCount < 2) return true;
|
||||
@@ -252,6 +304,20 @@ export default {
|
||||
this.$router.push({name: 'userProfile', params: {userId: profile._id}});
|
||||
}
|
||||
},
|
||||
itemWasMounted: debounce(function itemWasMounted () {
|
||||
if (this.handleScrollBack) {
|
||||
this.handleScrollBack = false;
|
||||
|
||||
const container = this.$refs.container;
|
||||
const offset = container.scrollHeight - container.clientHeight;
|
||||
|
||||
const newOffset = offset + this.lastOffset;
|
||||
|
||||
container.scrollTo(0, newOffset);
|
||||
// enable scroll again
|
||||
container.style.overflowY = 'scroll';
|
||||
}
|
||||
}, 50),
|
||||
messageLiked (message) {
|
||||
const chatIndex = findIndex(this.chat, chatMessage => {
|
||||
return chatMessage.id === message.id;
|
||||
|
||||
@@ -11,11 +11,17 @@
|
||||
:class='{"user-entry": newMessage}',
|
||||
@keydown='updateCarretPosition',
|
||||
@keyup.ctrl.enter='sendMessageShortcut()',
|
||||
@keydown.tab='handleTab($event)',
|
||||
@keydown.up='selectPreviousAutocomplete($event)',
|
||||
@keydown.down='selectNextAutocomplete($event)',
|
||||
@keydown.enter='selectAutocomplete($event)',
|
||||
@keydown.esc='handleEscape($event)',
|
||||
@paste='disableMessageSendShortcut()',
|
||||
maxlength='3000'
|
||||
)
|
||||
span {{ currentLength }} / 3000
|
||||
autocomplete(
|
||||
ref='autocomplete',
|
||||
:text='newMessage',
|
||||
v-on:select="selectedAutocomplete",
|
||||
:textbox='textbox',
|
||||
@@ -165,6 +171,45 @@
|
||||
}, 500);
|
||||
},
|
||||
|
||||
handleTab (e) {
|
||||
if (this.$refs.autocomplete.searchActive) {
|
||||
e.preventDefault();
|
||||
if (e.shiftKey) {
|
||||
this.$refs.autocomplete.selectPrevious();
|
||||
} else {
|
||||
this.$refs.autocomplete.selectNext();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleEscape (e) {
|
||||
if (this.$refs.autocomplete.searchActive) {
|
||||
e.preventDefault();
|
||||
this.$refs.autocomplete.cancel();
|
||||
}
|
||||
},
|
||||
|
||||
selectNextAutocomplete (e) {
|
||||
if (this.$refs.autocomplete.searchActive) {
|
||||
e.preventDefault();
|
||||
this.$refs.autocomplete.selectNext();
|
||||
}
|
||||
},
|
||||
|
||||
selectPreviousAutocomplete (e) {
|
||||
if (this.$refs.autocomplete.searchActive) {
|
||||
e.preventDefault();
|
||||
this.$refs.autocomplete.selectPrevious();
|
||||
}
|
||||
},
|
||||
|
||||
selectAutocomplete (e) {
|
||||
if (this.$refs.autocomplete.searchActive) {
|
||||
e.preventDefault();
|
||||
this.$refs.autocomplete.makeSelection();
|
||||
}
|
||||
},
|
||||
|
||||
selectedAutocomplete (newText) {
|
||||
this.newMessage = newText;
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
small.muted(v-html="$t('blurbHallContributors')")
|
||||
.well
|
||||
div(v-if='user.contributor.admin')
|
||||
h2 {{ $t('rewardUser') }}
|
||||
h2 Reward User
|
||||
|
||||
.row
|
||||
.form.col-6(v-if='!hero.profile')
|
||||
@@ -11,33 +11,33 @@
|
||||
input.form-control(type='text', v-model='heroID', :placeholder="'User ID or Username'")
|
||||
.form-group
|
||||
button.btn.btn-secondary(@click='loadHero(heroID)')
|
||||
| {{ $t('loadUser') }}
|
||||
| Load User
|
||||
|
||||
.row
|
||||
.form.col-6(v-if='hero && hero.profile', submit='saveHero(hero)')
|
||||
router-link(:to="{'name': 'userProfile', 'params': {'userId': hero._id}}")
|
||||
h3 {{hero.profile.name}}
|
||||
h3 @{{hero.auth.local.username}} / {{hero.profile.name}}
|
||||
.form-group
|
||||
input.form-control(type='text', v-model='hero.contributor.text', :placeholder="$t('contribTitle')")
|
||||
label Contributor Title
|
||||
input.form-control(type='text', v-model='hero.contributor.text')
|
||||
small Common titles: <strong>Ambassador, Artisan, Bard, Blacksmith, Challenger, Comrade, Fletcher, Linguist, Linguistic Scribe, Scribe, Socialite, Storyteller</strong>. Rare titles: Advisor, Chamberlain, Designer, Mathematician, Shirtster, Spokesperson, Statistician, Tinker, Transcriber, Troubadour.
|
||||
.form-group
|
||||
label {{ $t('contribLevel') }}
|
||||
label Contributor Tier
|
||||
input.form-control(type='number', v-model='hero.contributor.level')
|
||||
small {{ $t('contribHallText') }}
|
||||
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.
|
||||
|
|
||||
a(target='_blank', href='https://trello.com/c/wkFzONhE/277-contributor-gear') {{ $t('moreDetails') }}
|
||||
a(target='_blank', href='https://trello.com/c/wkFzONhE/277-contributor-gear') More details (1-7)
|
||||
|,
|
||||
a(target='_blank', href='https://github.com/HabitRPG/habitica/issues/3801') {{ $t('moreDetails2') }}
|
||||
a(target='_blank', href='https://github.com/HabitRPG/habitica/issues/3801') more details (8-9)
|
||||
.form-group
|
||||
textarea.form-control(cols=5, :placeholder="$t('contributions')", v-model='hero.contributor.contributions')
|
||||
//include ../../shared/formattiv-help
|
||||
hr
|
||||
label Contributions
|
||||
textarea.form-control(cols=5, v-model='hero.contributor.contributions')
|
||||
|
||||
.form-group
|
||||
label {{ $t('balance') }}
|
||||
label Balance
|
||||
input.form-control(type='number', step="any", v-model='hero.balance')
|
||||
small
|
||||
span ‘{{ hero.balance }}’
|
||||
span(v-html='$t("notGems")')
|
||||
span '{{ hero.balance }}' is in USD, <em>not</em> in Gems. E.g., if this number is 1, it means 4 Gems. Only use this option when manually granting Gems to players, don't use it when granting contributor tiers. Contrib tiers will automatically add Gems.
|
||||
.accordion
|
||||
.accordion-group(heading='Items')
|
||||
h4.expand-toggle(:class="{'open': expandItems}", @click="expandItems = !expandItems") Update Item
|
||||
@@ -71,7 +71,7 @@
|
||||
// Add backer stuff like tier, disable adds, etcs
|
||||
.form-group
|
||||
button.form-control.btn.btn-primary(@click='saveHero()')
|
||||
| {{ $t('save') }}
|
||||
| Save
|
||||
|
||||
.table-responsive
|
||||
table.table.table-striped
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
span.svg-icon.inline.icon-16.clock-icon(v-html="icons.clock")
|
||||
span.limitedString {{ limitedString }}
|
||||
|
||||
.free-rebirth.d-flex.align-items-center(v-if='item.key === "rebirth_orb" && item.value > 0')
|
||||
.free-rebirth.d-flex.align-items-center(v-if='item.key === "rebirth_orb" && item.value > 0 && user.stats.lvl >= 100')
|
||||
.m-auto
|
||||
span.svg-icon.inline.icon-16.mr-2.pt-015(v-html="icons.whiteClock")
|
||||
span(v-html='$t("nextFreeRebirth", {days: nextFreeRebirth})')
|
||||
@@ -402,13 +402,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.item.currency === 'gems' &&
|
||||
!confirm(this.$t('purchaseFor', { cost: this.item.value * this.selectedAmountToBuy }))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.item.currency === 'hourglasses' &&
|
||||
!confirm(this.$t('purchaseForHourglasses', { cost: this.item.value }))) {
|
||||
const shouldConfirmPurchase = this.item.currency === 'gems' || this.item.currency === 'hourglasses';
|
||||
if (shouldConfirmPurchase && !this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
h2(v-once) {{ $t('filter') }}
|
||||
.form-group
|
||||
checkbox(
|
||||
v-for="category in categories",
|
||||
:key="category.identifier",
|
||||
:id="`category-${category.identifier}`",
|
||||
:checked.sync="viewOptions[category.identifier].selected",
|
||||
:text="category.text"
|
||||
v-for="viewOptionKey in Object.keys(viewOptions)",
|
||||
:key="viewOptionKey",
|
||||
:id="`category-${viewOptionKey}`",
|
||||
:checked.sync="viewOptions[viewOptionKey].selected",
|
||||
:text="viewOptions[viewOptionKey].text"
|
||||
)
|
||||
div.form-group.clearfix
|
||||
h3.float-left(v-once) {{ $t('hideLocked') }}
|
||||
@@ -27,7 +27,7 @@
|
||||
import Checkbox from 'client/components/ui/checkbox';
|
||||
import toggleSwitch from 'client/components/ui/toggleSwitch';
|
||||
export default {
|
||||
props: ['hidePinned', 'hideLocked', 'categories', 'viewOptions'],
|
||||
props: ['hidePinned', 'hideLocked', 'viewOptions'],
|
||||
components: {
|
||||
Checkbox,
|
||||
toggleSwitch,
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
.form-group
|
||||
input.form-control.input-search(type="text", v-model="searchText", :placeholder="$t('search')")
|
||||
market-filter(
|
||||
:categories="categories",
|
||||
:hideLocked.sync="hideLocked",
|
||||
:hidePinned.sync="hidePinned",
|
||||
:viewOptions="viewOptions"
|
||||
@@ -39,7 +38,7 @@
|
||||
span.text {{ $t(ctx.item.id) }}
|
||||
div(
|
||||
v-for="category in categories",
|
||||
v-if="!anyFilterSelected || viewOptions[category.identifier].selected && category.identifier !== 'equipment'"
|
||||
v-if="!anyFilterSelected || viewOptions[category.identifier].selected"
|
||||
)
|
||||
h4 {{ category.text }}
|
||||
category-row(
|
||||
@@ -197,7 +196,12 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
viewOptions: {},
|
||||
viewOptions: {
|
||||
equipment: {
|
||||
selected: false,
|
||||
text: this.$t('equipment'),
|
||||
},
|
||||
},
|
||||
|
||||
searchText: null,
|
||||
searchTextThrottled: null,
|
||||
@@ -238,11 +242,6 @@ export default {
|
||||
...this.market.categories,
|
||||
];
|
||||
|
||||
categories.push({
|
||||
identifier: 'equipment',
|
||||
text: this.$t('equipment'),
|
||||
});
|
||||
|
||||
categories.push({
|
||||
identifier: 'cards',
|
||||
text: this.$t('cards'),
|
||||
@@ -291,6 +290,7 @@ export default {
|
||||
if (!this.viewOptions[category.identifier]) {
|
||||
this.$set(this.viewOptions, category.identifier, {
|
||||
selected: false,
|
||||
text: category.text,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -265,6 +265,9 @@
|
||||
this.$emit('change', $event);
|
||||
},
|
||||
buyItem () {
|
||||
if (!this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy)) {
|
||||
return;
|
||||
}
|
||||
this.makeGenericPurchase(this.item, 'buyQuestModal', this.selectedAmountToBuy);
|
||||
this.purchased(this.item.text);
|
||||
this.hideDialog();
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
.create-task-area.d-flex
|
||||
transition(name="slide-tasks-btns")
|
||||
.d-flex(v-if="openCreateBtn")
|
||||
.create-task-btn.rounded-btn(
|
||||
.create-task-btn.diamond-btn(
|
||||
v-for="type in columns",
|
||||
:key="type",
|
||||
@click="createTask(type)",
|
||||
@@ -83,7 +83,7 @@
|
||||
)
|
||||
.svg-icon(v-html="icons[type]", :class='`icon-${type}`')
|
||||
|
||||
#create-task-btn.create-btn.rounded-btn.btn.btn-success(
|
||||
#create-task-btn.create-btn.diamond-btn.btn.btn-success(
|
||||
@click="openCreateBtn = !openCreateBtn",
|
||||
:class="{open: openCreateBtn}",
|
||||
)
|
||||
|
||||
@@ -34,21 +34,25 @@
|
||||
.svg-icon(v-html="tierIcon(conversation)")
|
||||
.time
|
||||
span.mr-1(v-if='conversation.username') @{{ conversation.username }} •
|
||||
span {{ conversation.date | timeAgo }}
|
||||
span(v-if="conversation.date") {{ conversation.date | timeAgo }}
|
||||
div.messagePreview {{ conversation.lastMessageText ? removeTags(parseMarkdown(conversation.lastMessageText)) : '' }}
|
||||
.col-8.messages.d-flex.flex-column.justify-content-between
|
||||
.empty-messages.text-center(v-if='!selectedConversation.key')
|
||||
.svg-icon.envelope(v-html="icons.messageIcon")
|
||||
h4 {{placeholderTexts.title}}
|
||||
p(v-html="placeholderTexts.description")
|
||||
.empty-messages.text-center(v-if='selectedConversation.key && selectedConversationMessages.length === 0')
|
||||
.empty-messages.text-center(v-if='selectedConversation && selectedConversationMessages.length === 0')
|
||||
p {{ $t('beginningOfConversation', {userName: selectedConversation.name})}}
|
||||
chat-messages.message-scroll(
|
||||
v-if="selectedConversation.messages && selectedConversationMessages.length > 0",
|
||||
v-if="selectedConversation && selectedConversationMessages.length > 0",
|
||||
:chat='selectedConversationMessages',
|
||||
:inbox='true',
|
||||
@message-removed='messageRemoved',
|
||||
ref="chatscroll"
|
||||
ref="chatscroll",
|
||||
|
||||
:canLoadMore="canLoadMore",
|
||||
:isLoading="messagesLoading",
|
||||
@triggerLoad="infiniteScrollTrigger"
|
||||
)
|
||||
.pm-disabled-caption.text-center(v-if="user.inbox.optOut && selectedConversation.key")
|
||||
h4 {{$t('PMDisabledCaptionTitle')}}
|
||||
@@ -64,6 +68,12 @@
|
||||
span.ml-3 {{ currentLength }} / 3000
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
#inbox-modal .modal-body {
|
||||
padding-top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~client/assets/scss/colors.scss';
|
||||
@import '~client/assets/scss/tiers.scss';
|
||||
@@ -94,7 +104,7 @@
|
||||
|
||||
.sidebar {
|
||||
background-color: $gray-700;
|
||||
min-height: 600px;
|
||||
min-height: 540px;
|
||||
padding: 0;
|
||||
|
||||
.search-section {
|
||||
@@ -107,6 +117,7 @@
|
||||
position: relative;
|
||||
padding-left: 0;
|
||||
padding-bottom: 6em;
|
||||
height: 540px;
|
||||
}
|
||||
|
||||
.message-scroll {
|
||||
@@ -225,8 +236,8 @@
|
||||
import Vue from 'vue';
|
||||
import moment from 'moment';
|
||||
import filter from 'lodash/filter';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import groupBy from 'lodash/groupBy';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { mapState } from 'client/libs/store';
|
||||
import habiticaMarkdown from 'habitica-markdown';
|
||||
import styleHelper from 'client/mixins/styleHelper';
|
||||
@@ -308,8 +319,12 @@ export default {
|
||||
newMessage: '',
|
||||
showPopover: false,
|
||||
messages: [],
|
||||
messagesByConversation: {}, // cache {uuid: []}
|
||||
loadedConversations: [],
|
||||
loaded: false,
|
||||
messagesLoading: false,
|
||||
initiatedConversation: null,
|
||||
updateConversionsCounter: 0,
|
||||
};
|
||||
},
|
||||
filters: {
|
||||
@@ -319,8 +334,11 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState({user: 'user.data'}),
|
||||
canLoadMore () {
|
||||
return this.selectedConversation && this.selectedConversation.canLoadMore;
|
||||
},
|
||||
conversations () {
|
||||
const inboxGroup = groupBy(this.messages, 'uuid');
|
||||
const inboxGroup = groupBy(this.loadedConversations, 'uuid');
|
||||
|
||||
// Add placeholder for new conversations
|
||||
if (this.initiatedConversation && this.initiatedConversation.uuid) {
|
||||
@@ -328,6 +346,7 @@ export default {
|
||||
uuid: this.initiatedConversation.uuid,
|
||||
user: this.initiatedConversation.user,
|
||||
username: this.initiatedConversation.username,
|
||||
contributor: this.initiatedConversation.contributor,
|
||||
id: '',
|
||||
text: '',
|
||||
timestamp: new Date(),
|
||||
@@ -336,62 +355,56 @@ export default {
|
||||
// Create conversation objects
|
||||
const convos = [];
|
||||
for (let key in inboxGroup) {
|
||||
const convoSorted = sortBy(inboxGroup[key], [(o) => {
|
||||
return (new Date(o.timestamp)).getTime();
|
||||
}]);
|
||||
|
||||
// Fix poor inbox chat models
|
||||
const newChatModels = convoSorted.map(chat => {
|
||||
let newChat = Object.assign({}, chat);
|
||||
if (newChat.sent) {
|
||||
newChat.toUUID = newChat.uuid;
|
||||
newChat.toUser = newChat.user;
|
||||
newChat.toUserName = newChat.username;
|
||||
newChat.toUserContributor = newChat.contributor;
|
||||
newChat.toUserBacker = newChat.backer;
|
||||
newChat.uuid = this.user._id;
|
||||
newChat.user = this.user.profile.name;
|
||||
newChat.username = this.user.auth.local.username;
|
||||
newChat.contributor = this.user.contributor;
|
||||
newChat.backer = this.user.backer;
|
||||
}
|
||||
return newChat;
|
||||
});
|
||||
|
||||
// In case the last message is a placeholder, remove it
|
||||
const recentMessage = newChatModels[newChatModels.length - 1];
|
||||
if (!recentMessage.text) newChatModels.splice(newChatModels.length - 1, 1);
|
||||
const recentMessage = inboxGroup[key][0];
|
||||
|
||||
const convoModel = {
|
||||
key: recentMessage.toUUID ? recentMessage.toUUID : recentMessage.uuid,
|
||||
name: recentMessage.toUser ? recentMessage.toUser : recentMessage.user, // Handles case where from user sent the only message or the to user sent the only message
|
||||
key: recentMessage.uuid,
|
||||
name: recentMessage.user, // Handles case where from user sent the only message or the to user sent the only message
|
||||
username: !recentMessage.text ? recentMessage.username : recentMessage.toUserName,
|
||||
date: recentMessage.timestamp,
|
||||
lastMessageText: recentMessage.text,
|
||||
messages: newChatModels,
|
||||
canLoadMore: true,
|
||||
page: 0,
|
||||
};
|
||||
|
||||
convos.push(convoModel);
|
||||
}
|
||||
|
||||
// Sort models by most recent
|
||||
const conversations = sortBy(convos, [(o) => {
|
||||
return moment(o.date).toDate();
|
||||
}]);
|
||||
|
||||
return conversations.reverse();
|
||||
return convos;
|
||||
},
|
||||
// Separate from selectedConversation which is not coputed so messages don't update automatically
|
||||
// Separate from selectedConversation which is not computed so messages don't update automatically
|
||||
selectedConversationMessages () {
|
||||
// Vue-subscribe to changes
|
||||
const subScribeToUpdate = this.messagesLoading || this.updateConversionsCounter > -1;
|
||||
|
||||
|
||||
const selectedConversationKey = this.selectedConversation.key;
|
||||
const selectedConversation = this.conversations.find(c => c.key === selectedConversationKey);
|
||||
return selectedConversation ? selectedConversation.messages : [];
|
||||
const selectedConversation = this.messagesByConversation[selectedConversationKey];
|
||||
this.messages = selectedConversation || [];
|
||||
|
||||
const ordered = orderBy(this.messages, [(m) => {
|
||||
return m.timestamp;
|
||||
}], ['asc']);
|
||||
|
||||
if (subScribeToUpdate) {
|
||||
return ordered;
|
||||
}
|
||||
},
|
||||
filtersConversations () {
|
||||
if (!this.search) return this.conversations;
|
||||
return filter(this.conversations, (conversation) => {
|
||||
return conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1;
|
||||
});
|
||||
// Vue-subscribe to changes
|
||||
const subScribeToUpdate = this.updateConversionsCounter > -1;
|
||||
|
||||
const filtered = subScribeToUpdate && !this.search ?
|
||||
this.conversations :
|
||||
filter(this.conversations, (conversation) => {
|
||||
return conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1;
|
||||
});
|
||||
|
||||
const ordered = orderBy(filtered, [(o) => {
|
||||
return moment(o.date).toDate();
|
||||
}], ['desc']);
|
||||
|
||||
return ordered;
|
||||
},
|
||||
currentLength () {
|
||||
return this.newMessage.length;
|
||||
@@ -424,25 +437,34 @@ export default {
|
||||
methods: {
|
||||
async onModalShown () {
|
||||
this.loaded = false;
|
||||
const res = await axios.get('/api/v4/inbox/messages');
|
||||
this.messages = res.data.data;
|
||||
|
||||
const conversationRes = await axios.get('/api/v4/inbox/conversations');
|
||||
this.loadedConversations = conversationRes.data.data;
|
||||
|
||||
this.loaded = true;
|
||||
},
|
||||
onModalHide () {
|
||||
this.messages = [];
|
||||
// reset everything
|
||||
this.loadedConversations = [];
|
||||
this.loaded = false;
|
||||
this.initiatedConversation = null;
|
||||
this.messagesByConversation = {};
|
||||
this.selectedConversation = {};
|
||||
},
|
||||
messageRemoved (message) {
|
||||
const messageIndex = this.messages.findIndex(msg => msg.id === message.id);
|
||||
if (messageIndex !== -1) this.messages.splice(messageIndex, 1);
|
||||
if (this.selectedConversationMessages.length === 0) this.initiatedConversation = {
|
||||
uuid: this.selectedConversation.key,
|
||||
user: this.selectedConversation.name,
|
||||
username: this.selectedConversation.username,
|
||||
backer: this.selectedConversation.backer,
|
||||
contributor: this.selectedConversation.contributor,
|
||||
};
|
||||
const messages = this.messagesByConversation[this.selectedConversation.key];
|
||||
|
||||
const messageIndex = messages.findIndex(msg => msg.id === message.id);
|
||||
if (messageIndex !== -1) messages.splice(messageIndex, 1);
|
||||
if (this.selectedConversationMessages.length === 0) {
|
||||
this.initiatedConversation = {
|
||||
uuid: this.selectedConversation.key,
|
||||
user: this.selectedConversation.name,
|
||||
username: this.selectedConversation.username,
|
||||
backer: this.selectedConversation.backer,
|
||||
contributor: this.selectedConversation.contributor,
|
||||
};
|
||||
}
|
||||
},
|
||||
toggleClick () {
|
||||
this.displayCreate = !this.displayCreate;
|
||||
@@ -450,13 +472,17 @@ export default {
|
||||
toggleOpt () {
|
||||
this.$store.dispatch('user:togglePrivateMessagesOpt');
|
||||
},
|
||||
selectConversation (key) {
|
||||
async selectConversation (key) {
|
||||
let convoFound = this.conversations.find((conversation) => {
|
||||
return conversation.key === key;
|
||||
});
|
||||
|
||||
this.selectedConversation = convoFound || {};
|
||||
|
||||
if (!this.messagesByConversation[this.selectedConversation.key]) {
|
||||
await this.loadMessages();
|
||||
}
|
||||
|
||||
Vue.nextTick(() => {
|
||||
if (!this.$refs.chatscroll) return;
|
||||
let chatscroll = this.$refs.chatscroll.$el;
|
||||
@@ -466,18 +492,32 @@ export default {
|
||||
sendPrivateMessage () {
|
||||
if (!this.newMessage) return;
|
||||
|
||||
this.messages.push({
|
||||
const messages = this.messagesByConversation[this.selectedConversation.key];
|
||||
|
||||
messages.push({
|
||||
sent: true,
|
||||
text: this.newMessage,
|
||||
timestamp: new Date(),
|
||||
user: this.selectedConversation.name,
|
||||
username: this.selectedConversation.username,
|
||||
uuid: this.selectedConversation.key,
|
||||
toUser: this.selectedConversation.name,
|
||||
toUserName: this.selectedConversation.username,
|
||||
toUserContributor: this.selectedConversation.contributor,
|
||||
toUserBacker: this.selectedConversation.backer,
|
||||
toUUID: this.selectedConversation.uuid,
|
||||
|
||||
id: '-1', // will be updated once the result is back
|
||||
likes: {},
|
||||
ownerId: this.user._id,
|
||||
uuid: this.user._id,
|
||||
fromUUID: this.user._id,
|
||||
user: this.user.profile.name,
|
||||
username: this.user.auth.local.username,
|
||||
contributor: this.user.contributor,
|
||||
backer: this.user.backer,
|
||||
});
|
||||
|
||||
// Remove the placeholder message
|
||||
if (this.initiatedConversation && this.initiatedConversation.uuid === this.selectedConversation.key) {
|
||||
this.loadedConversations.unshift(this.initiatedConversation);
|
||||
this.initiatedConversation = null;
|
||||
}
|
||||
|
||||
@@ -495,7 +535,10 @@ export default {
|
||||
message: this.newMessage,
|
||||
}).then(response => {
|
||||
const newMessage = response.data.data.message;
|
||||
Object.assign(this.messages[this.messages.length - 1], newMessage);
|
||||
const messageToReset = messages[messages.length - 1];
|
||||
messageToReset.id = newMessage.id; // just set the id, all other infos already set
|
||||
Object.assign(messages[messages.length - 1], messageToReset);
|
||||
this.updateConversionsCounter++;
|
||||
});
|
||||
|
||||
this.newMessage = '';
|
||||
@@ -520,6 +563,36 @@ export default {
|
||||
if (!text) return;
|
||||
return habiticaMarkdown.render(String(text));
|
||||
},
|
||||
infiniteScrollTrigger () {
|
||||
// show loading and wait until the loadMore debounced
|
||||
// or else it would trigger on every scrolling-pixel (while not loading)
|
||||
if (this.canLoadMore) {
|
||||
this.messagesLoading = true;
|
||||
}
|
||||
|
||||
return this.loadMore();
|
||||
},
|
||||
loadMore () {
|
||||
this.selectedConversation.page += 1;
|
||||
return this.loadMessages();
|
||||
},
|
||||
async loadMessages () {
|
||||
this.messagesLoading = true;
|
||||
|
||||
const requestUrl = `/api/v4/inbox/paged-messages?conversation=${this.selectedConversation.key}&page=${this.selectedConversation.page}`;
|
||||
const res = await axios.get(requestUrl);
|
||||
const loadedMessages = res.data.data;
|
||||
|
||||
this.messagesByConversation[this.selectedConversation.key] = this.messagesByConversation[this.selectedConversation.key] || [];
|
||||
const loadedMessagesToAdd = loadedMessages
|
||||
.filter(m => this.messagesByConversation[this.selectedConversation.key].findIndex(mI => mI.id === m.id) === -1)
|
||||
;
|
||||
this.messagesByConversation[this.selectedConversation.key].push(...loadedMessagesToAdd);
|
||||
|
||||
// only show the load more Button if the max count was returned
|
||||
this.selectedConversation.canLoadMore = loadedMessages.length === 10;
|
||||
this.messagesLoading = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -152,11 +152,6 @@
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.gearTitle {
|
||||
color: white;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.progress-container > .progress {
|
||||
background-color: $gray-500 !important;
|
||||
height: 16px !important;
|
||||
@@ -329,11 +324,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.gearTitle {
|
||||
color: white;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.profile-section {
|
||||
h2 {
|
||||
overflow: hidden;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
:placement="'bottom'",
|
||||
:preventOverflow="false",
|
||||
)
|
||||
h4.gearTitle {{ getGearTitle(equippedItems[key]) }}
|
||||
h4.popover-title-only {{ getGearTitle(equippedItems[key]) }}
|
||||
attributesGrid.attributesGrid(
|
||||
:item="content.gear.flat[equippedItems[key]]",
|
||||
:user="user"
|
||||
@@ -49,7 +49,7 @@
|
||||
:placement="'bottom'",
|
||||
:preventOverflow="false",
|
||||
)
|
||||
h4.gearTitle {{ getGearTitle(costumeItems[key]) }}
|
||||
h4.popover-title-only {{ getGearTitle(costumeItems[key]) }}
|
||||
attributesGrid.attributesGrid(
|
||||
:item="content.gear.flat[costumeItems[key]]",
|
||||
:user="user"
|
||||
|
||||
@@ -32,5 +32,15 @@ export default {
|
||||
|
||||
this.$root.$emit('buyModal::boughtItem', item);
|
||||
},
|
||||
confirmPurchase (currency, cost) {
|
||||
const currencyToPurchaseForKey = {
|
||||
gems: 'purchaseFor',
|
||||
gold: 'purchaseForGold',
|
||||
hourglasses: 'purchaseForHourglasses',
|
||||
};
|
||||
|
||||
const purchaseForKey = currencyToPurchaseForKey[currency];
|
||||
return confirm(this.$t(purchaseForKey, { cost }));
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -505,5 +505,13 @@
|
||||
"backgroundSeasideCliffsText": "Seaside Cliffs",
|
||||
"backgroundSeasideCliffsNotes": "Stand on a beach with the beauty of Seaside Cliffs above.",
|
||||
"backgroundUnderwaterVentsText": "Underwater Vents",
|
||||
"backgroundUnderwaterVentsNotes": "Take a deep dive down, down to the Underwater Vents."
|
||||
"backgroundUnderwaterVentsNotes": "Take a deep dive down, down to the Underwater Vents.",
|
||||
|
||||
"backgrounds072019": "SET 62: Released July 2019",
|
||||
"backgroundLakeWithFloatingLanternsText": "Lake with Floating Lanterns",
|
||||
"backgroundLakeWithFloatingLanternsNotes": "Stargaze from the festival atmosphere of a Lake with Floating Lanterns.",
|
||||
"backgroundFlyingOverTropicalIslandsText": "Flying over Tropical Islands",
|
||||
"backgroundFlyingOverTropicalIslandsNotes": "Let the view take your breath away as you Fly over Tropical Islands.",
|
||||
"backgroundAmongGiantAnemonesText": "Among Giant Anemones",
|
||||
"backgroundAmongGiantAnemonesNotes": "Explore reef life, protected from predators Among Giant Anemones."
|
||||
}
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
"dieText": "You've lost a Level, all your Gold, and a random piece of Equipment. Arise, Habiteer, and try again! Curb those negative Habits, be vigilant in completion of Dailies, and hold death at arm's length with a Health Potion if you falter!",
|
||||
"sureReset": "Are you sure? This will reset your character's class and allocated Stat Points (you'll get them all back to re-allocate), and costs 3 Gems.",
|
||||
"purchaseFor": "Purchase for <%= cost %> Gems?",
|
||||
"purchaseForGold": "Purchase for <%= cost %> Gold?",
|
||||
"purchaseForHourglasses": "Purchase for <%= cost %> Hourglasses?",
|
||||
"notEnoughMana": "Not enough mana.",
|
||||
"invalidTarget": "You can't cast a skill on that.",
|
||||
|
||||
@@ -288,6 +288,7 @@
|
||||
"hatchingPotionVeggie": "Garden",
|
||||
"hatchingPotionSunshine": "Sunshine",
|
||||
"hatchingPotionBronze": "Bronze",
|
||||
"hatchingPotionWatery": "Watery",
|
||||
|
||||
"hatchingPotionNotes": "Pour this on an egg, and it will hatch as a <%= potText(locale) %> pet.",
|
||||
"premiumPotionAddlNotes": "Not usable on quest pet eggs.",
|
||||
|
||||
@@ -40,26 +40,18 @@
|
||||
"helpedText1": "Helped Habitica grow by filling out",
|
||||
"helpedText2": "this survey.",
|
||||
"hall": "Hall of Heroes",
|
||||
"contribTitle": "Contributor Title (eg, \"Blacksmith\")",
|
||||
"contribLevel": "Contrib Tier",
|
||||
"contribHallText": "1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available. Also determines name-tag coloring. Tiers 8 and 9 are automatically given admin status.",
|
||||
"hallContributors": "Hall of Contributors",
|
||||
"hallPatrons": "Hall of Patrons",
|
||||
"rewardUser": "Reward User",
|
||||
"UUID": "User ID",
|
||||
"loadUser": "Load User",
|
||||
"noAdminAccess": "You don't have admin access.",
|
||||
"userNotFound": "User not found.",
|
||||
"invalidUUID": "UUID must be valid",
|
||||
"title": "Title",
|
||||
"moreDetails": "More details (1-7)",
|
||||
"moreDetails2": "more details (8-9)",
|
||||
"contributions": "Contributions",
|
||||
"admin": "Admin",
|
||||
"notGems": "is in USD, <em>not</em> in Gems. Aka, if this number is 1, it means 4 gems. Only use this option when manually granting gems to players, don't use it when granting contributor tiers. Contrib tiers will automatically add gems.",
|
||||
"gamemaster": "Game Master (staff/moderator)",
|
||||
"backerTier": "Backer Tier",
|
||||
"balance": "Balance",
|
||||
"tierPop": "Click tier labels for details.",
|
||||
"playerTiers": "Player Tiers",
|
||||
"tier": "Tier",
|
||||
|
||||
@@ -278,9 +278,6 @@
|
||||
"passwordConfirmationMatch": "Password confirmation doesn't match password.",
|
||||
"passwordResetPage": "Reset Password",
|
||||
"passwordReset": "If we have your email on file, instructions for setting a new password have been sent to your email.",
|
||||
"passwordResetEmailSubject": "Password Reset for Habitica",
|
||||
"passwordResetEmailText": "If you requested a password reset for <%= username %> on Habitica, head to <%= passwordResetLink %> to set a new one. The link will expire after 24 hours. If you haven't requested a password reset, please ignore this email.",
|
||||
"passwordResetEmailHtml": "If you requested a password reset for <strong><%= username %></strong> on Habitica, <a href=\"<%= passwordResetLink %>\">click here</a> to set a new one. The link will expire after 24 hours.<br/><br>If you haven't requested a password reset, please ignore this email.",
|
||||
"invalidLoginCredentialsLong": "Uh-oh - your email address / username or password is incorrect.\n- Make sure they are typed correctly. Your username and password are case-sensitive.\n- You may have signed up with Facebook or Google-sign-in, not email so double-check by trying them.\n- If you forgot your password, click \"Forgot Password\".",
|
||||
"invalidCredentials": "There is no account that uses those credentials.",
|
||||
"accountSuspended": "This account, User ID \"<%= userId %>\", has been blocked for breaking the Community Guidelines (https://habitica.com/static/community-guidelines) or Terms of Service (https://habitica.com/static/terms). For details or to ask to be unblocked, please email our Community Manager at <%= communityManagerEmail %> or ask your parent or guardian to email them. Please include your @Username in the email.",
|
||||
|
||||