mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-14 21:27:23 +01:00
finish linting client
This commit is contained in:
@@ -72,7 +72,7 @@
|
||||
"npm": "^6"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .js --fix ./website/server",
|
||||
"lint": "eslint --ext .js --fix .",
|
||||
"test": "npm run lint && gulp test && gulp apidoc",
|
||||
"test:build": "gulp test:prepare:build",
|
||||
"test:api-v3": "gulp test:api-v3",
|
||||
|
||||
139
website/client/package-lock.json
generated
139
website/client/package-lock.json
generated
@@ -6253,6 +6253,12 @@
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
|
||||
@@ -7868,6 +7874,127 @@
|
||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||
"dev": true
|
||||
},
|
||||
"nconf": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/nconf/-/nconf-0.10.0.tgz",
|
||||
"integrity": "sha512-fKiXMQrpP7CYWJQzKkPPx9hPgmq+YLDyxcG9N8RpiE9FoCkCbzD0NyW0YhE3xn3Aupe7nnDeIx4PFzYehpHT9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async": "^1.4.0",
|
||||
"ini": "^1.3.0",
|
||||
"secure-keys": "^1.0.0",
|
||||
"yargs": "^3.19.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
|
||||
"integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
|
||||
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wrap-ansi": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
|
||||
"integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"lcid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
|
||||
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"invert-kv": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
|
||||
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lcid": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
|
||||
"integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^2.0.1",
|
||||
"cliui": "^3.0.3",
|
||||
"decamelize": "^1.1.1",
|
||||
"os-locale": "^1.4.0",
|
||||
"string-width": "^1.0.1",
|
||||
"window-size": "^0.1.4",
|
||||
"y18n": "^3.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
@@ -9857,6 +9984,12 @@
|
||||
"ajv-keywords": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"secure-keys": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/secure-keys/-/secure-keys-1.0.0.tgz",
|
||||
"integrity": "sha1-8MgtmKOxOah3aogIBQuCRDEIf8o=",
|
||||
"dev": true
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
@@ -12050,6 +12183,12 @@
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"window-size": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz",
|
||||
"integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=",
|
||||
"dev": true
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit --opts ../../test/mocha.opts",
|
||||
"lint": "vue-cli-service lint"
|
||||
"lint": "vue-cli-service lint --quiet"
|
||||
},
|
||||
"dependencies": {
|
||||
"amplitude-js": "^5.3.1",
|
||||
@@ -42,7 +42,7 @@
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"inspectpack": "^4.2.2",
|
||||
"pug": "^2.0.4",
|
||||
"nconf": "^0.10.0",
|
||||
"sass": "^1.19.0",
|
||||
"sass-loader": "^8.0.0",
|
||||
"svg-inline-loader": "^0.8.0",
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
></div>
|
||||
{{ $t('share') }}
|
||||
</a>
|
||||
<!-- @TODO: Still want this? .col-4a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')-->
|
||||
<!-- @TODO: Still want this?
|
||||
.col-4a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="heroClass in classes"
|
||||
:key="heroClass"
|
||||
class="col-md-3"
|
||||
>
|
||||
<div @click="selectedClass = heroClass">
|
||||
@@ -36,6 +37,7 @@
|
||||
<br>
|
||||
<div
|
||||
v-for="heroClass in classes"
|
||||
:key="heroClass"
|
||||
class="d-flex justify-content-center"
|
||||
>
|
||||
<div
|
||||
@@ -56,7 +58,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="heroClass in classes">
|
||||
<div
|
||||
v-for="heroClass in classes"
|
||||
:key="heroClass"
|
||||
>
|
||||
<div
|
||||
v-if="selectedClass === heroClass"
|
||||
class="class-explanation text-center"
|
||||
|
||||
@@ -53,7 +53,8 @@ label(style='display:inline-block') {{ $t('dontShowAgain') }}
|
||||
{{ $t('share') }}
|
||||
</a>
|
||||
</div>
|
||||
<!-- @TODO: Still want this? .col-4a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')-->
|
||||
<!-- @TODO: Still want this? .col-4a.tumblr
|
||||
-share-button(:data-href='socialLevelLink', data-notes='none')-->
|
||||
</div>
|
||||
</div>
|
||||
</b-modal>
|
||||
|
||||
@@ -35,12 +35,15 @@
|
||||
v-if="nextReward.rewardKey.length === 1"
|
||||
:class="nextReward.rewardKey[0]"
|
||||
></div>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="reward in nextReward.rewardKey"
|
||||
v-if="nextReward.rewardKey.length > 1"
|
||||
:key="reward"
|
||||
class="reward"
|
||||
:class="reward"
|
||||
></div>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
</div>
|
||||
<div
|
||||
v-if="data.rewardText"
|
||||
@@ -50,12 +53,15 @@
|
||||
v-if="data.rewardKey.length === 1"
|
||||
:class="data.rewardKey[0]"
|
||||
></div>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="reward in data.rewardKey"
|
||||
v-if="data.rewardKey.length > 1"
|
||||
:key="reward"
|
||||
class="reward"
|
||||
:class="reward"
|
||||
></div>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -79,7 +85,10 @@
|
||||
v-if="data && data.nextRewardAt"
|
||||
class="col-12 text-center"
|
||||
>
|
||||
<h3>{{ $t('nextRewardUnlocksIn', {numberOfCheckinsLeft: data.nextRewardAt - user.loginIncentives}) }}</h3>
|
||||
<h3>
|
||||
{{ $t('nextRewardUnlocksIn', {
|
||||
numberOfCheckinsLeft: data.nextRewardAt - user.loginIncentives}) }}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div ng-if="quests[user.party.quest.key].collect">
|
||||
<p ng-repeat="(k,v) in quests[user.party.quest.key].collect">
|
||||
<strong>{{ $t('collect') }} + ': '</strong>
|
||||
{{ quests[user.party.quest.key].collect[k].count }} {{ quests[user.party.quest.key].collect[k].text() }}
|
||||
{{ quests[user.party.quest.key].collect[k].count }} {{ quests[user.party.quest.key].collect[k].text() }} <!-- eslint-disable-line max-len -->
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
<!-- @TODO: +achievementAvatar('sun',0)--><achievement-avatar class="avatar" />
|
||||
</div><div class="col-6 offset-3 text-center">
|
||||
<div v-if="user.achievements.rebirthLevel < 100">
|
||||
{{ $t('rebirthAchievement', {number: user.achievements.rebirths, level: user.achievements.rebirthLevel}) }}
|
||||
{{ $t('rebirthAchievement', {
|
||||
number: user.achievements.rebirths,
|
||||
level: user.achievements.rebirthLevel}) }}
|
||||
</div><div v-if="user.achievements.rebirthLevel >= 100">
|
||||
{{ $t('rebirthAchievement100', {number: user.achievements.rebirths}) }}
|
||||
</div><br><button
|
||||
|
||||
@@ -47,7 +47,10 @@
|
||||
</table>
|
||||
<br>
|
||||
<div
|
||||
v-if="!(user.achievements.ultimateGearSets.healer && user.achievements.ultimateGearSets.wizard && user.achievements.ultimateGearSets.rogue && user.achievements.ultimateGearSets.warrior)"
|
||||
v-if="!user.achievements.ultimateGearSets.healer
|
||||
&& user.achievements.ultimateGearSets.wizard
|
||||
&& user.achievements.ultimateGearSets.rogue
|
||||
&& user.achievements.ultimateGearSets.warrior"
|
||||
>
|
||||
<p v-html="$t('moreGearAchievements')"></p>
|
||||
<br>
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
class="svg-icon social-icon"
|
||||
v-html="icons.facebookIcon"
|
||||
></div>
|
||||
<span>{{ registering ? $t('signUpWithSocial', {social: 'Facebook'}) : $t('loginWithSocial', {social: 'Facebook'}) }}</span>
|
||||
<span>{{ registering
|
||||
? $t('signUpWithSocial', {social: 'Facebook'})
|
||||
: $t('loginWithSocial', {social: 'Facebook'}) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
@@ -22,7 +24,9 @@
|
||||
class="svg-icon social-icon"
|
||||
v-html="icons.googleIcon"
|
||||
></div>
|
||||
<span>{{ registering ? $t('signUpWithSocial', {social: 'Google'}) : $t('loginWithSocial', {social: 'Google'}) }}</span>
|
||||
<span>{{ registering
|
||||
? $t('signUpWithSocial', {social: 'Google'})
|
||||
: $t('loginWithSocial', {social: 'Google'}) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
<div
|
||||
class="text"
|
||||
>
|
||||
{{ registering ? $t('signUpWithSocial', {social: 'Facebook'}) : $t('loginWithSocial', {social: 'Facebook'}) }}
|
||||
{{ registering
|
||||
? $t('signUpWithSocial', {social: 'Facebook'})
|
||||
: $t('loginWithSocial', {social: 'Facebook'}) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +51,9 @@
|
||||
<div
|
||||
class="text"
|
||||
>
|
||||
{{ registering ? $t('signUpWithSocial', {social: 'Google'}) : $t('loginWithSocial', {social: 'Google'}) }}
|
||||
{{ registering
|
||||
? $t('signUpWithSocial', {social: 'Google'})
|
||||
: $t('loginWithSocial', {social: 'Google'}) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -72,6 +76,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="issue in usernameIssues"
|
||||
:key="issue"
|
||||
class="input-error"
|
||||
>
|
||||
{{ issue }}
|
||||
|
||||
@@ -7,7 +7,12 @@
|
||||
v-for="option in items"
|
||||
:key="option.key"
|
||||
class="outer-option-background"
|
||||
:class="{locked: option.gemLocked || option.goldLocked, premium: Boolean(option.gem), active: option.active || currentValue === option.key, none: option.none, hide: option.hide }"
|
||||
:class="{
|
||||
locked: option.gemLocked || option.goldLocked,
|
||||
premium: Boolean(option.gem),
|
||||
active: option.active || currentValue === option.key,
|
||||
none: option.none,
|
||||
hide: option.hide }"
|
||||
@click="option.click(option)"
|
||||
>
|
||||
<div class="option">
|
||||
|
||||
@@ -17,10 +17,13 @@
|
||||
:items="freeHairColors"
|
||||
:current-value="user.preferences.hair.color"
|
||||
/>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="set in seasonalHairColors"
|
||||
v-if="editing && set.key !== 'undefined'"
|
||||
:key="set.key"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<customize-options
|
||||
:items="set.options"
|
||||
:current-value="user.preferences.skin"
|
||||
@@ -33,6 +36,7 @@
|
||||
v-if="activeSubPage === 'style'"
|
||||
id="style"
|
||||
>
|
||||
<!-- eslint-disable vue/require-v-for-key NO KEY AVAILABLE HERE -->
|
||||
<div v-for="set in styleSets">
|
||||
<customize-options
|
||||
:items="set.options"
|
||||
@@ -40,6 +44,7 @@
|
||||
@unlock="set.unlock()"
|
||||
/>
|
||||
</div>
|
||||
<!-- eslint-enable vue/require-v-for-key -->
|
||||
</div>
|
||||
<div
|
||||
v-if="activeSubPage === 'bangs'"
|
||||
@@ -58,12 +63,14 @@
|
||||
v-if="editing"
|
||||
:items="mustacheList"
|
||||
/>
|
||||
<!-- eslint-disable max-len -->
|
||||
<customize-options
|
||||
v-if="editing"
|
||||
:items="beardList"
|
||||
:full-set="isPurchaseAllNeeded('hair', ['baseHair5', 'baseHair6'], ['mustache', 'beard'])"
|
||||
@unlock="unlock(`hair.mustache.${baseHair5Keys.join(',hair.mustache.')},hair.beard.${baseHair6Keys.join(',hair.beard.')}`)"
|
||||
/>
|
||||
<!-- eslint-enable max-len -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -13,10 +13,13 @@
|
||||
:items="freeSkins"
|
||||
:current-value="user.preferences.skin"
|
||||
/>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="set in seasonalSkins"
|
||||
v-if="editing && set.key !== 'undefined'"
|
||||
:key="set.key"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<customize-options
|
||||
:items="set.options"
|
||||
:current-value="user.preferences.skin"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
>{{ $t('joined') }}</span>
|
||||
<span
|
||||
v-for="category in categories"
|
||||
:key="category.slug"
|
||||
class="category-label"
|
||||
:class="{'category-label-purple':isOfficial(category)}"
|
||||
>{{ $t(category.name) }}</span>
|
||||
|
||||
@@ -30,8 +30,10 @@
|
||||
:group="challenge.group"
|
||||
/>
|
||||
</span>
|
||||
<!-- @TODO: make challenge.author a variable inside the createdBy string (helps with RTL languages)-->
|
||||
<!-- @TODO: Implement in V2 strong.margin-left(v-once).svg-icon.calendar-icon(v-html="icons.calendarIcon")
|
||||
<!-- @TODO: make challenge.author a variable inside the
|
||||
createdBy string (helps with RTL languages)-->
|
||||
<!-- @TODO: Implement in V2 strong.margin-left
|
||||
(v-once).svg-icon.calendar-icon(v-html="icons.calendarIcon")
|
||||
| {{$t('endDate')}}
|
||||
// "endDate": "End Date: <% endDate %>",-->
|
||||
<!-- span {{challenge.endDate}}-->
|
||||
@@ -39,6 +41,7 @@
|
||||
<div class="tags">
|
||||
<span
|
||||
v-for="tag in challenge.tags"
|
||||
:key="tag"
|
||||
class="tag"
|
||||
>{{ tag }}</span>
|
||||
</div>
|
||||
@@ -112,6 +115,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<task-column
|
||||
v-for="column in columns"
|
||||
v-if="tasksByType[column].length > 0"
|
||||
@@ -123,6 +127,7 @@
|
||||
@editTask="editTask"
|
||||
@taskDestroyed="taskDestroyed"
|
||||
/>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 sidebar standard-page">
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
<div class="well">
|
||||
<div
|
||||
v-for="task in tasksData"
|
||||
:key="task.label"
|
||||
:class="{'muted': task.value === 0}"
|
||||
>
|
||||
<div class="number">
|
||||
@@ -413,7 +414,8 @@ export default {
|
||||
return this.user.challenges.indexOf(this.challenge._id) !== -1;
|
||||
},
|
||||
isOfficial () {
|
||||
return this.challenge.official || this.challenge.categories.map(category => category.slug).includes('habitica_official');
|
||||
return this.challenge.official
|
||||
|| this.challenge.categories.map(category => category.slug).includes('habitica_official');
|
||||
},
|
||||
tasksData () {
|
||||
return [
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="group in groups"
|
||||
:key="group._id"
|
||||
:value="group._id"
|
||||
>
|
||||
{{ group.name }}
|
||||
@@ -91,6 +92,7 @@
|
||||
>{{ $t('none') }}</span>
|
||||
<div
|
||||
v-for="category in workingChallenge.categories"
|
||||
:key="category"
|
||||
class="category-label"
|
||||
>
|
||||
{{ $t(categoriesHashByKey[category]) }}
|
||||
@@ -100,12 +102,14 @@
|
||||
v-if="showCategorySelect && creating"
|
||||
class="category-box"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="group in categoryOptions"
|
||||
v-if="group.key !== 'habitica_official' || user.contributor.admin"
|
||||
:key="group.key"
|
||||
class="form-check"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input
|
||||
:id="`challenge-modal-cat-${group.key}`"
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<!-- @TODO: implement sorting span.dropdown-label {{ $t('sortBy') }}b-dropdown(:text="$t('sort')", right=true)
|
||||
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}-->
|
||||
<!-- @TODO: implement sorting span.dropdown-label
|
||||
{{ $t('sortBy') }}b-dropdown(:text="$t('sort')", right=true)
|
||||
b-dropdown-item(v-for='sortOption in sortOptions',
|
||||
:key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}-->
|
||||
<button
|
||||
class="btn btn-secondary create-challenge-button float-right"
|
||||
@click="createChallenge()"
|
||||
@@ -40,6 +42,7 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="challenge in filteredChallenges"
|
||||
:key="challenge._id"
|
||||
class="col-12 col-md-6"
|
||||
>
|
||||
<challenge-item :challenge="challenge" />
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<!-- @TODO: implement sorting span.dropdown-label {{ $t('sortBy') }}b-dropdown(:text="$t('sort')", right=true)
|
||||
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}-->
|
||||
<!-- @TODO: implement sorting span.dropdown-label
|
||||
{{ $t('sortBy') }}b-dropdown(:text="$t('sort')", right=true)
|
||||
b-dropdown-item(v-for='sortOption in sortOptions',
|
||||
:key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}-->
|
||||
<button
|
||||
class="btn btn-secondary create-challenge-button float-right"
|
||||
@click="createChallenge()"
|
||||
@@ -60,6 +62,7 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="challenge in filteredChallenges"
|
||||
:key="challenge._id"
|
||||
class="col-12 col-md-6"
|
||||
>
|
||||
<challenge-item :challenge="challenge" />
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="result in searchResults"
|
||||
:key="result.username"
|
||||
class="autocomplete-results d-flex align-items-center"
|
||||
:class="{'hover-background': result.hover}"
|
||||
@click="select(result)"
|
||||
@@ -134,7 +135,11 @@ export default {
|
||||
this.currentSearch = this.currentSearch.substring(1, this.currentSearch.length); // eslint-disable-line vue/no-side-effects-in-computed-properties, max-len
|
||||
|
||||
return this.tmpSelections
|
||||
.filter(option => option.displayName.toLowerCase().indexOf(this.currentSearch.toLowerCase()) !== -1 || option.username && option.username.toLowerCase().indexOf(this.currentSearch.toLowerCase()) !== -1)
|
||||
.filter(option => { // eslint-disable-line arrow-body-style
|
||||
return option.displayName.toLowerCase().indexOf(this.currentSearch.toLowerCase()) !== -1
|
||||
|| (option.username
|
||||
&& option.username.toLowerCase().indexOf(this.currentSearch.toLowerCase()) !== -1);
|
||||
})
|
||||
.slice(0, 4);
|
||||
},
|
||||
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
<div>{{ $t('copyAsTodo') }}</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="(inbox || (user.flags.communityGuidelinesAccepted && msg.uuid !== 'system')) && (!isMessageReported || user.contributor.admin)"
|
||||
v-if="(inbox || (user.flags.communityGuidelinesAccepted && msg.uuid !== 'system'))
|
||||
&& (!isMessageReported || user.contributor.admin)"
|
||||
class="action d-flex align-items-center"
|
||||
@click="report(msg)"
|
||||
>
|
||||
@@ -273,7 +274,10 @@ export default {
|
||||
const messageText = message.text.toLowerCase();
|
||||
const displayName = user.profile.name;
|
||||
const username = user.auth.local && user.auth.local.username;
|
||||
const mentioned = max([messageText.indexOf(username.toLowerCase()), messageText.indexOf(displayName.toLowerCase())]);
|
||||
const mentioned = max([
|
||||
messageText.indexOf(username.toLowerCase()),
|
||||
messageText.indexOf(displayName.toLowerCase()),
|
||||
]);
|
||||
if (mentioned === -1) return message.highlight;
|
||||
|
||||
const escapedDisplayName = escapeRegExp(displayName);
|
||||
|
||||
@@ -30,18 +30,22 @@
|
||||
{{ $t('loading') }}
|
||||
</h2>
|
||||
</div>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="(msg, index) in messages"
|
||||
v-for="msg in messages"
|
||||
v-if="chat && canViewFlag(msg)"
|
||||
:key="msg.id"
|
||||
:class="{row: inbox}"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-if="user._id !== msg.uuid"
|
||||
class="d-flex"
|
||||
:class="{'flex-grow-1': inbox}"
|
||||
>
|
||||
<avatar
|
||||
v-if="msg.userStyles || (cachedProfileData[msg.uuid] && !cachedProfileData[msg.uuid].rejected)"
|
||||
v-if="msg.userStyles
|
||||
|| (cachedProfileData[msg.uuid] && !cachedProfileData[msg.uuid].rejected)"
|
||||
class="avatar-left"
|
||||
:member="msg.userStyles || cachedProfileData[msg.uuid]"
|
||||
:avatar-only="true"
|
||||
@@ -85,7 +89,8 @@
|
||||
/>
|
||||
</div>
|
||||
<avatar
|
||||
v-if="msg.userStyles || (cachedProfileData[msg.uuid] && !cachedProfileData[msg.uuid].rejected)"
|
||||
v-if="msg.userStyles
|
||||
|| (cachedProfileData[msg.uuid] && !cachedProfileData[msg.uuid].rejected)"
|
||||
:member="msg.userStyles || cachedProfileData[msg.uuid]"
|
||||
:avatar-only="true"
|
||||
:hide-class-badge="true"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<span class="glyphicon glyphicon-forward"></span>
|
||||
{{ $t('consecutiveSubscription') }}
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ $t('consecutiveMonths') }} {{ group.purchased.plan.consecutive.count + group.purchased.plan.consecutive.offset }}</li>
|
||||
<li>{{ $t('consecutiveMonths') }} {{ group.purchased.plan.consecutive.count + group.purchased.plan.consecutive.offset }}</li> <!-- eslint-disable-line max-len -->
|
||||
<li>{{ $t('gemCapExtra') }} {{ group.purchased.plan.consecutive.gemCapExtra }}</li>
|
||||
<li>{{ $t('mysticHourglasses') }} {{ group.purchased.plan.consecutive.trinkets }}</li>
|
||||
</ul>
|
||||
@@ -50,7 +50,8 @@
|
||||
{{ $t('upgrade') }}
|
||||
</button>
|
||||
<div
|
||||
v-if="!group.purchased.plan.dateTerminated && group.purchased.plan.paymentMethod === 'Stripe'"
|
||||
v-if="!group.purchased.plan.dateTerminated
|
||||
&& group.purchased.plan.paymentMethod === 'Stripe'"
|
||||
class="btn btn-primary"
|
||||
@click="showStripeEdit({groupId: group.id})"
|
||||
>
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
</h1>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<!-- @TODO: Add when we implement recent activity .float-rightspan.dropdown-label {{ $t('sortBy') }}
|
||||
<!-- @TODO: Add when we implement recent activity
|
||||
.float-rightspan.dropdown-label {{ $t('sortBy') }}
|
||||
b-dropdown(:text="$t('sort')", right=true)
|
||||
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}-->
|
||||
b-dropdown-item(v-for='sortOption in sortOptions',
|
||||
:key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}-->
|
||||
<button
|
||||
class="btn btn-secondary create-group-button float-right"
|
||||
@click="createGroup()"
|
||||
@@ -51,7 +53,7 @@ b-dropdown(:text="$t('sort')", right=true)
|
||||
<mugen-scroll
|
||||
v-show="loading"
|
||||
:handler="fetchGuilds"
|
||||
:should-handle="!loading && !this.hasLoadedAllGuilds"
|
||||
:should-handle="!loading && !hasLoadedAllGuilds"
|
||||
:handle-on-mount="true"
|
||||
>
|
||||
<span v-once>{{ $t('loading') }}</span>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
class="row"
|
||||
>
|
||||
<group-form-modal v-if="isParty" />
|
||||
<start-quest-modal :group="this.group" />
|
||||
<quest-details-modal :group="this.group" />
|
||||
<participant-list-modal :group="this.group" />
|
||||
<start-quest-modal :group="group" />
|
||||
<quest-details-modal :group="group" />
|
||||
<participant-list-modal :group="group" />
|
||||
<group-gems-modal />
|
||||
<div class="col-12 col-sm-8 standard-page">
|
||||
<div class="row">
|
||||
@@ -141,13 +141,22 @@
|
||||
>
|
||||
{{ $t('invite') }}
|
||||
</button>
|
||||
<!-- @TODO: hide the invitation button if there's an active group plan and the player is not the leader-->
|
||||
<!-- @TODO: hide the invitation button
|
||||
if there's an active group plan and the player is not the leader-->
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<!-- @TODO: V2 button.btn.btn-primary(v-once, v-if='!isLeader') {{$t('messageGuildLeader')}} // Suggest making the button visible to the leader too - useful for them to test how the feature works or to send a note to themself. -- Alys-->
|
||||
<!-- @TODO: V2 button.btn.btn-primary(v-once, v-if='!isLeader')
|
||||
{{$t('messageGuildLeader')}} // Suggest making the button
|
||||
visible to the leader too - useful for them to test how
|
||||
the feature works or to send a note to themself. -- Alys-->
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<!-- @TODO: V2 button.btn.btn-primary(v-once, v-if='isMember && !isParty') {{$t('donateGems')}} // Suggest removing the isMember restriction - it's okay if non-members donate to a public guild. Also probably allow it for parties if parties can buy imagery. -- Alys-->
|
||||
<!-- @TODO: V2 button.btn.btn-primary(v-once,
|
||||
v-if='isMember && !isParty') {{$t('donateGems')}}
|
||||
// Suggest removing the isMember restriction
|
||||
- it's okay if non-members donate to a public
|
||||
guild. Also probably allow it for parties
|
||||
if parties can buy imagery. -- Alys-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -379,7 +388,6 @@ import groupUtilities from '@/mixins/groupsUtilities';
|
||||
import styleHelper from '@/mixins/styleHelper';
|
||||
import { mapState } from '@/libs/store';
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
import membersModal from './membersModal';
|
||||
import startQuestModal from './startQuestModal';
|
||||
import questDetailsModal from './questDetailsModal';
|
||||
import participantListModal from './participantListModal';
|
||||
@@ -406,7 +414,6 @@ import bronzeGuildBadgeIcon from '@/assets/svg/bronze-guild-badge-small.svg';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
membersModal,
|
||||
startQuestModal,
|
||||
groupFormModal,
|
||||
groupChallenges,
|
||||
|
||||
@@ -49,14 +49,15 @@
|
||||
/>
|
||||
</div>
|
||||
<!-- br-->
|
||||
<!-- @TODO Implement in V2 .custom-control.custom-checkboxinput.custom-control-input(type="checkbox", v-model="workingGroup.guildLeaderCantBeMessaged")
|
||||
<!-- @TODO Implement in V2 .custom-control.custom-checkboxinput.custom
|
||||
-control-input(type="checkbox", v-model="workingGroup.guildLeaderCantBeMessaged")
|
||||
label.custom-control-label(v-once) {{ $t('guildLeaderCantBeMessaged') }}
|
||||
// "guildLeaderCantBeMessaged": "Leader can not be messaged directly",
|
||||
// @TODO discuss the impact of this with moderators before implementing
|
||||
-->
|
||||
<br>
|
||||
<div
|
||||
v-if="!isParty && !this.workingGroup.id"
|
||||
v-if="!isParty && !workingGroup.id"
|
||||
class="custom-control custom-checkbox"
|
||||
>
|
||||
<input
|
||||
@@ -86,7 +87,9 @@ label.custom-control-label(v-once) {{ $t('guildLeaderCantBeMessaged') }}
|
||||
/>
|
||||
</div>
|
||||
<!-- br-->
|
||||
<!-- @TODO: Implement in v2 .custom-control.custom-checkbox(v-if='!creatingParty')input.custom-control-input(type="checkbox", v-model="workingGroup.allowGuildInvitationsFromNonMembers")
|
||||
<!-- @TODO: Implement in v2 .custom-control.custom-checkbox(v-if='!creatingParty')
|
||||
input.custom-control-input(type="checkbox", v-model="workingGroup.allowG
|
||||
uildInvitationsFromNonMembers")
|
||||
label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers') }}
|
||||
// "allowGuildInvitationsFromNonMembers": "Allow Guild invitations from non-members",
|
||||
-->
|
||||
@@ -123,7 +126,8 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
class="form-control description-textarea"
|
||||
type="text"
|
||||
textarea="textarea"
|
||||
:placeholder="isParty ? $t('partyDescriptionPlaceholder') : $t('guildDescriptionPlaceholder')"
|
||||
:placeholder="isParty
|
||||
? $t('partyDescriptionPlaceholder') : $t('guildDescriptionPlaceholder')"
|
||||
></textarea>
|
||||
</div>
|
||||
<div
|
||||
@@ -155,6 +159,7 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
>{{ $t('none') }}</span>
|
||||
<div
|
||||
v-for="category in workingGroup.categories"
|
||||
:key="category"
|
||||
class="category-label"
|
||||
>
|
||||
{{ $t(categoriesHashByKey[category]) }}
|
||||
@@ -164,12 +169,14 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
v-if="showCategorySelect"
|
||||
class="category-box"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="group in categoryOptions"
|
||||
v-if="group.key !== 'habitica_official' || user.contributor.admin"
|
||||
:key="group.key"
|
||||
class="form-check"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input
|
||||
:id="`category-${group.key}`"
|
||||
@@ -192,7 +199,8 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
{{ $t('close') }}
|
||||
</button>
|
||||
</div>
|
||||
<!-- @TODO: need categories only for PUBLIC GUILDS, not for tavern, private guilds, or party-->
|
||||
<!-- @TODO: need categories only for PUBLIC GUILDS,
|
||||
not for tavern, private guilds, or party-->
|
||||
</div>
|
||||
<div
|
||||
v-if="inviteMembers && !workingGroup.id"
|
||||
@@ -203,6 +211,7 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
<p v-once>{{ $t('inviteMembersHowTo') }} *</p>
|
||||
</label>
|
||||
<div>
|
||||
<!-- eslint-disable-next-line vue/require-v-for-key -->
|
||||
<div v-for="(member, index) in membersToInvite">
|
||||
<input
|
||||
v-model="member.value"
|
||||
@@ -226,7 +235,7 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
</div>
|
||||
<div class="form-group text-center">
|
||||
<div
|
||||
v-if="!this.workingGroup.id"
|
||||
v-if="!workingGroup.id"
|
||||
class="item-with-icon"
|
||||
>
|
||||
<div
|
||||
@@ -250,7 +259,7 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
{{ isParty ? $t('updateParty') : $t('updateGuild') }}
|
||||
</button>
|
||||
<div
|
||||
v-if="!this.workingGroup.id"
|
||||
v-if="!workingGroup.id"
|
||||
v-once
|
||||
class="gem-description"
|
||||
>
|
||||
@@ -324,7 +333,6 @@ label.custom-control-label(v-once) {{ $t('allowGuildInvitationsFromNonMembers')
|
||||
<script>
|
||||
import { mapState } from '@/libs/store';
|
||||
import toggleSwitch from '@/components/ui/toggleSwitch';
|
||||
import groupMemberSearchDropdown from '@/components/members/groupMemberSearchDropdown';
|
||||
import markdownDirective from '@/directives/markdown';
|
||||
import gemIcon from '@/assets/svg/gem.svg';
|
||||
import informationIcon from '@/assets/svg/information.svg';
|
||||
@@ -340,7 +348,6 @@ import { MAX_SUMMARY_SIZE_FOR_GUILDS } from '@/../../common/script/constants';
|
||||
export default {
|
||||
components: {
|
||||
toggleSwitch,
|
||||
groupMemberSearchDropdown,
|
||||
},
|
||||
directives: {
|
||||
markdown: markdownDirective,
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
>
|
||||
<hr>
|
||||
<h2>{{ $t('teamBasedTasks') }}</h2>
|
||||
<p>Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!</p>
|
||||
<p>Set up an easily-viewed shared task list for the group. Assign tasks to your fellow group members, or let them claim their own tasks to make it clear what everyone is working on!</p><!-- eslint-disable-line max-len -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@@ -35,7 +35,7 @@
|
||||
>
|
||||
<hr>
|
||||
<h2>Group Management Controls</h2>
|
||||
<p>Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.</p>
|
||||
<p>Use task approvals to verify that a task that was really completed, add Group Managers to share responsibilities, and enjoy a private group chat for all team members.</p><!-- eslint-disable-line max-len -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
@@ -46,7 +46,7 @@
|
||||
>
|
||||
<hr>
|
||||
<h2>In-Game Benefits</h2>
|
||||
<p>Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.</p>
|
||||
<p>Group members get an exclusive Jackalope Mount, as well as full subscription benefits, including special monthly equipment sets and the ability to buy gems with gold.</p><!-- eslint-disable-line max-len -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<div class="small">
|
||||
{{ $t('inviteEmailUsernameInfo') }}
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/require-v-for-key -->
|
||||
<div v-for="(invite, index) in invites">
|
||||
<div class="input-group">
|
||||
<div
|
||||
@@ -25,7 +26,8 @@
|
||||
class="form-control"
|
||||
type="text"
|
||||
:placeholder="$t('emailOrUsernameInvite')"
|
||||
:class="{'input-valid': invite.valid, 'is-invalid input-invalid': invite.valid === false}"
|
||||
:class="{
|
||||
'input-valid': invite.valid, 'is-invalid input-invalid': invite.valid === false}"
|
||||
@keyup="expandInviteList"
|
||||
@change="checkInviteList"
|
||||
>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<remove-member-modal
|
||||
:member-to-remove="memberToRemove"
|
||||
:group-id="this.groupId"
|
||||
:group-id="groupId"
|
||||
@member-removed="memberRemoved"
|
||||
/>
|
||||
<b-modal
|
||||
@@ -49,6 +49,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="sortOption in sortOptions"
|
||||
:key="sortOption.value"
|
||||
:value="sortOption.value"
|
||||
>
|
||||
{{ sortOption.text }}
|
||||
@@ -62,6 +63,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="sortDirection in sortDirections"
|
||||
:key="sortDirection.value"
|
||||
:value="sortDirection.value"
|
||||
>
|
||||
{{ sortDirection.text }}
|
||||
@@ -100,6 +102,7 @@
|
||||
<div v-if="selectedPage === 'members'">
|
||||
<div
|
||||
v-for="(member, index) in sortedMembers"
|
||||
:key="member._id"
|
||||
class="row"
|
||||
>
|
||||
<div class="col-11 no-padding-left">
|
||||
@@ -201,6 +204,7 @@
|
||||
<div v-if="selectedPage === 'invites'">
|
||||
<div
|
||||
v-for="(member, index) in invites"
|
||||
:key="member._id"
|
||||
class="row"
|
||||
>
|
||||
<div class="col-11 no-padding-left">
|
||||
|
||||
@@ -28,9 +28,11 @@
|
||||
></div>
|
||||
<span v-once>{{ $t('createGuild2') }}</span>
|
||||
</button>
|
||||
<!-- @TODO: Add when we implement recent activity .float-rightspan.dropdown-label {{ $t('sortBy') }}
|
||||
<!-- @TODO: Add when we implement recent activity
|
||||
.float-rightspan.dropdown-label {{ $t('sortBy') }}
|
||||
b-dropdown(:text="$t('sort')", right=true)
|
||||
b-dropdown-item(v-for='sortOption in sortOptions', :key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}
|
||||
b-dropdown-item(v-for='sortOption in sortOptions',
|
||||
:key="sortOption.value", @click='sort(sortOption.value)') {{sortOption.text}}
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
@@ -107,7 +109,6 @@ b-dropdown(:text="$t('sort')", right=true)
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import MugenScroll from 'vue-mugen-scroll';
|
||||
import { mapState } from '@/libs/store';
|
||||
import groupUtilities from '@/mixins/groupsUtilities';
|
||||
|
||||
@@ -119,7 +120,7 @@ import greyBadgeIcon from '@/assets/svg/grey-badge.svg';
|
||||
import positiveIcon from '@/assets/svg/positive.svg';
|
||||
|
||||
export default {
|
||||
components: { PublicGuildItem, MugenScroll, Sidebar },
|
||||
components: { PublicGuildItem, Sidebar },
|
||||
mixins: [groupUtilities],
|
||||
data () {
|
||||
return {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-for="member in participants"
|
||||
:key="member._id"
|
||||
class="row"
|
||||
>
|
||||
<div class="col-12 no-padding-left">
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
<div class="col-md-2 badge-column">
|
||||
<div
|
||||
class="shield-wrap"
|
||||
:class="{gold: guild.memberCount >= 1000, silver: guild.memberCount >= 100 && guild.memberCount < 1000}"
|
||||
:class="{
|
||||
gold: guild.memberCount >= 1000,
|
||||
silver: guild.memberCount >= 100 && guild.memberCount < 1000}"
|
||||
>
|
||||
<div
|
||||
v-if="guild.memberCount >= 1000"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="member in members"
|
||||
:key="member._id"
|
||||
class="col-12 member"
|
||||
>
|
||||
<strong :class="{'declined-name': member.accepted === false}">{{ member.name }}</strong>
|
||||
@@ -60,7 +61,9 @@
|
||||
>
|
||||
{{ $t('begin') }}
|
||||
</button>
|
||||
<!-- @TODO don't allow the party leader to start the quest until the leader has accepted or rejected the invitation (users get confused and think "begin" means "join quest")-->
|
||||
<!-- @TODO don't allow the party leader to
|
||||
start the quest until the leader has accepted
|
||||
or rejected the invitation (users get confused and think "begin" means "join quest")-->
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
@@ -243,6 +246,7 @@ export default {
|
||||
return partyMembers.map(member => ({
|
||||
name: member.profile.name,
|
||||
accepted: this.group.quest.members[member._id],
|
||||
_id: member._id,
|
||||
}));
|
||||
},
|
||||
canEditQuest () {
|
||||
|
||||
@@ -92,6 +92,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-for="(value, key) in questData.collect"
|
||||
:key="key"
|
||||
class="row"
|
||||
>
|
||||
<div class="col-2">
|
||||
@@ -148,19 +149,22 @@
|
||||
<div class="row boss-details">
|
||||
<div class="col-6">
|
||||
<span class="float-left">
|
||||
{{ Math.ceil(parseFloat(group.quest.progress.hp) * 100) / 100 }} / {{ parseFloat(questData.boss.hp).toFixed(2) }}
|
||||
<!-- current boss hp uses ceil so you don't underestimate damage needed to end quest-->
|
||||
{{ Math.ceil(parseFloat(group.quest.progress.hp) * 100) / 100 }} / {{ parseFloat(questData.boss.hp).toFixed(2) }} <!-- eslint-disable-line max-len -->
|
||||
<!-- current boss hp uses ceil so
|
||||
you don't underestimate damage needed to end quest-->
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="userIsOnQuest"
|
||||
class="col-6"
|
||||
>
|
||||
<!-- @TODO: Why do we not sync quest progress on the group doc? Each user could have different progress.-->
|
||||
<!-- @TODO: Why do we not sync quest
|
||||
progress on the group doc? Each user could have different progress.-->
|
||||
<span
|
||||
class="float-right"
|
||||
>{{ user.party.quest.progress.up | floor(10) }} {{ $t('pendingDamageLabel') }}</span>
|
||||
<!-- player's pending damage uses floor so you don't overestimate damage you've already done-->
|
||||
>{{ user.party.quest.progress.up | floor(10) }} {{ $t('pendingDamageLabel') }}</span> <!-- eslint-disable-line max-len -->
|
||||
<!-- player's pending damage uses floor so you
|
||||
don't overestimate damage you've already done-->
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -171,7 +175,8 @@
|
||||
<div class="grey-progress-bar">
|
||||
<div
|
||||
class="boss-health-bar rage-bar"
|
||||
:style="{width: (group.quest.progress.rage / questData.boss.rage.value) * 100 + '%'}"
|
||||
:style="{
|
||||
width: (group.quest.progress.rage / questData.boss.rage.value) * 100 + '%'}"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -183,7 +188,7 @@
|
||||
<div class="col-6">
|
||||
<span
|
||||
class="float-left"
|
||||
>{{ $t('rage') }} {{ parseFloat(group.quest.progress.rage).toFixed(2) }} / {{ questData.boss.rage.value }}</span>
|
||||
>{{ $t('rage') }} {{ parseFloat(group.quest.progress.rage).toFixed(2) }} / {{ questData.boss.rage.value }}</span> <!-- eslint-disable-line max-len -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,13 +11,16 @@
|
||||
Quests
|
||||
</h3>
|
||||
<div class="row">
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="(value, key, index) in user.items.quests"
|
||||
v-for="(value, key) in user.items.quests"
|
||||
v-if="value > 0"
|
||||
:key="key"
|
||||
class="col-4 quest-col"
|
||||
:class="{selected: key === selectedQuest}"
|
||||
@click="selectQuest({key})"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div class="quest-wrapper">
|
||||
<b-popover
|
||||
:target="`inventory_quest_scroll_${key}`"
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
<div
|
||||
v-if="group && group.quest && group.quest.active"
|
||||
class="world-boss"
|
||||
:style="{background: questData.colors.dark, 'border-color': questData.colors.extralight, 'outline-color': questData.colors.light}"
|
||||
:style="{
|
||||
background: questData.colors.dark,
|
||||
'border-color': questData.colors.extralight,
|
||||
'outline-color': questData.colors.light}"
|
||||
>
|
||||
<div
|
||||
class="corner-decoration"
|
||||
@@ -105,7 +108,9 @@
|
||||
></div>
|
||||
<span
|
||||
class="reduce ml-1 pt-1"
|
||||
>{{ $t('bossHealth', {currentHealth: bossCurrentHealth(), maxHealth: questData.boss.hp.toLocaleString()}) }}</span>
|
||||
>{{ $t('bossHealth', {
|
||||
currentHealth: bossCurrentHealth(),
|
||||
maxHealth: questData.boss.hp.toLocaleString()}) }}</span>
|
||||
</span>
|
||||
<div class="mt-3 mb-2">
|
||||
<strong class="mr-1">{{ $t('rageAttack') }}</strong>
|
||||
@@ -114,7 +119,8 @@
|
||||
<div class="grey-progress-bar mb-1">
|
||||
<div
|
||||
class="boss-health-bar rage-bar"
|
||||
:style="{width: (group.quest.progress.rage / questData.boss.rage.value) * 100 + '%'}"
|
||||
:style="{
|
||||
width: (group.quest.progress.rage / questData.boss.rage.value) * 100 + '%'}"
|
||||
></div>
|
||||
</div>
|
||||
<span class="d-flex align-items-center">
|
||||
@@ -124,7 +130,9 @@
|
||||
></div>
|
||||
<span
|
||||
class="reduce ml-1 pt-1"
|
||||
>{{ $t('bossRage', {currentRage: bossCurrentRage(), maxRage: questData.boss.rage.value.toLocaleString()}) }}</span>
|
||||
>{{ $t('bossRage', {
|
||||
currentRage: bossCurrentRage(),
|
||||
maxRage: questData.boss.rage.value.toLocaleString()}) }}</span>
|
||||
</span>
|
||||
<div class="row d-flex align-items-center mb-2 mt-2">
|
||||
<div class="col-sm-4 d-flex">
|
||||
@@ -217,7 +225,8 @@
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- .text-center.mt-4.world-boss-info-button(@click="showWorldBossInfo()") {{$t('whatIsWorldBoss') }}
|
||||
<!-- .text-center.mt-4.world-boss
|
||||
-info-button(@click="showWorldBossInfo()") {{$t('whatIsWorldBoss') }}
|
||||
-->
|
||||
</div>
|
||||
<div class="sleep below-header-sections">
|
||||
@@ -259,8 +268,12 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="user in staff"
|
||||
:key="user.uuid"
|
||||
class="col-4 staff"
|
||||
:class="{staff: user.type === 'Staff', moderator: user.type === 'Moderator', bailey: user.name === 'It's Bailey'}"
|
||||
:class="{
|
||||
staff: user.type === 'Staff',
|
||||
moderator: user.type === 'Moderator',
|
||||
bailey: user.name === 'It\'s Bailey'}"
|
||||
>
|
||||
<div>
|
||||
<router-link
|
||||
@@ -275,12 +288,12 @@
|
||||
v-html="icons.tierStaff"
|
||||
></div>
|
||||
<div
|
||||
v-if="user.type === 'Moderator' && user.name !== 'It's Bailey'"
|
||||
v-if="user.type === 'Moderator' && user.name !== 'It\'s Bailey'"
|
||||
class="svg-icon mod-icon"
|
||||
v-html="icons.tierMod"
|
||||
></div>
|
||||
<div
|
||||
v-if="user.name === 'It's Bailey'"
|
||||
v-if="user.name === 'It\'s Bailey'"
|
||||
class="svg-icon npc-icon"
|
||||
v-html="icons.tierNPC"
|
||||
></div>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
>
|
||||
<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.
|
||||
<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. <!-- eslint-disable-line max-len -->
|
||||
</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
@@ -59,7 +59,7 @@
|
||||
type="number"
|
||||
>
|
||||
<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.
|
||||
1-7 for normal contributors, 8 for moderators, 9 for staff. This determines which items, pets, and mounts are available, and name-tag coloring. Tiers 8 and 9 are automatically given admin status. <!-- eslint-disable-line max-len -->
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://trello.com/c/wkFzONhE/277-contributor-gear"
|
||||
@@ -89,7 +89,7 @@
|
||||
<small>
|
||||
<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.
|
||||
<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. <!-- eslint-disable-line max-len -->
|
||||
</span>
|
||||
</small>
|
||||
</div>
|
||||
@@ -134,7 +134,7 @@
|
||||
<strong>item value</strong>. E.g.,
|
||||
<code>5</code> or
|
||||
<code>false</code> or
|
||||
<code>head_warrior_3</code>. All values are listed in the All Item Paths section below.
|
||||
<code>head_warrior_3</code>. All values are listed in the All Item Paths section below. <!-- eslint-disable-line max-len -->
|
||||
</small>
|
||||
<div class="accordion">
|
||||
<div
|
||||
@@ -229,7 +229,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(hero, index) in heroes">
|
||||
<tr
|
||||
v-for="(hero, index) in heroes"
|
||||
:key="hero._id"
|
||||
>
|
||||
<td>
|
||||
<user-link
|
||||
v-if="hero.contributor && hero.contributor.admin"
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="patron in patrons">
|
||||
<tr
|
||||
v-for="patron in patrons"
|
||||
:key="patron._id"
|
||||
>
|
||||
<td>
|
||||
<a
|
||||
v-class="userLevelStyle(patron)"
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
class="party-members d-flex"
|
||||
@resized="setPartyMembersWidth($event)"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<member-details
|
||||
v-for="(member, $index) in sortedPartyMembers"
|
||||
v-if="member._id !== user._id && $index < membersToShow"
|
||||
@@ -44,6 +45,7 @@
|
||||
:class-badge-position="'hidden'"
|
||||
@onHover="expandMember(member._id)"
|
||||
/>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
|
||||
@@ -57,7 +57,9 @@
|
||||
</b-nav-item>
|
||||
<li
|
||||
class="topbar-item droppable"
|
||||
:class="{'active': $route.path.startsWith('/inventory'), 'down': $route.path.startsWith('/inventory') && this.isDesktop()}"
|
||||
:class="{
|
||||
'active': $route.path.startsWith('/inventory'),
|
||||
'down': $route.path.startsWith('/inventory') && isDesktop()}"
|
||||
>
|
||||
<div
|
||||
class="chevron rotate"
|
||||
@@ -99,7 +101,9 @@
|
||||
</li>
|
||||
<li
|
||||
class="topbar-item droppable"
|
||||
:class="{'active': $route.path.startsWith('/shop'), 'down': $route.path.startsWith('/shop') && this.isDesktop()}"
|
||||
:class="{
|
||||
'active': $route.path.startsWith('/shop'),
|
||||
'down': $route.path.startsWith('/shop') && isDesktop()}"
|
||||
>
|
||||
<div
|
||||
class="chevron rotate"
|
||||
@@ -146,7 +150,7 @@
|
||||
</div>
|
||||
</li>
|
||||
<b-nav-item
|
||||
v-if="this.user.party._id"
|
||||
v-if="user.party._id"
|
||||
class="topbar-item"
|
||||
:class="{'active': $route.path.startsWith('/party')}"
|
||||
tag="li"
|
||||
@@ -155,7 +159,7 @@
|
||||
{{ $t('party') }}
|
||||
</b-nav-item>
|
||||
<b-nav-item
|
||||
v-if="!this.user.party._id"
|
||||
v-if="!user.party._id"
|
||||
class="topbar-item"
|
||||
:class="{'active': $route.path.startsWith('/party')}"
|
||||
@click="openPartyModal()"
|
||||
@@ -164,7 +168,9 @@
|
||||
</b-nav-item>
|
||||
<li
|
||||
class="topbar-item droppable"
|
||||
:class="{'active': $route.path.startsWith('/groups'), 'down': $route.path.startsWith('/groups') && this.isDesktop()}"
|
||||
:class="{
|
||||
'active': $route.path.startsWith('/groups'),
|
||||
'down': $route.path.startsWith('/groups') && isDesktop()}"
|
||||
>
|
||||
<div
|
||||
class="chevron rotate"
|
||||
@@ -205,7 +211,9 @@
|
||||
</li>
|
||||
<li
|
||||
class="topbar-item droppable"
|
||||
:class="{'active': $route.path.startsWith('/group-plans'), 'down': $route.path.startsWith('/group-plans') && this.isDesktop()}"
|
||||
:class="{
|
||||
'active': $route.path.startsWith('/group-plans'),
|
||||
'down': $route.path.startsWith('/group-plans') && isDesktop()}"
|
||||
>
|
||||
<div
|
||||
v-if="groupPlans.length > 0"
|
||||
@@ -237,7 +245,9 @@
|
||||
</li>
|
||||
<li
|
||||
class="topbar-item droppable"
|
||||
:class="{'active': $route.path.startsWith('/challenges'), 'down': $route.path.startsWith('/challenges') && this.isDesktop()}"
|
||||
:class="{
|
||||
'active': $route.path.startsWith('/challenges'),
|
||||
'down': $route.path.startsWith('/challenges') && isDesktop()}"
|
||||
>
|
||||
<div
|
||||
class="chevron rotate"
|
||||
@@ -272,7 +282,9 @@
|
||||
</li>
|
||||
<li
|
||||
class="topbar-item droppable"
|
||||
:class="{'active': $route.path.startsWith('/help'), 'down': $route.path.startsWith('/help') && this.isDesktop()}"
|
||||
:class="{
|
||||
'active': $route.path.startsWith('/help'),
|
||||
'down': $route.path.startsWith('/help') && isDesktop()}"
|
||||
>
|
||||
<div
|
||||
class="chevron rotate"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<template lang="pug" functional>
|
||||
span.message-count(
|
||||
<template functional>
|
||||
<span
|
||||
class="message-count"
|
||||
:class="{'top-count': props.top === true, 'top-count-gray': props.gray === true}"
|
||||
) {{props.count}}
|
||||
> {{ props.count }} </span>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<template lang="pug" functional>
|
||||
div {{ props.notification }}
|
||||
<template functional>
|
||||
<div>{{ props.notification }}</div>
|
||||
</template>
|
||||
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm(this.$t('confirmNeedsWork'))) return;
|
||||
if (!window.confirm(this.$t('confirmNeedsWork'))) return;
|
||||
|
||||
await this.$store.dispatch('tasks:needsWork', {
|
||||
taskId: this.notification.data.groupTaskId,
|
||||
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
async accept () {
|
||||
const group = this.notification.data;
|
||||
|
||||
if (group.cancelledPlan && !confirm(this.$t('aboutToJoinCancelledGroupPlan'))) {
|
||||
if (group.cancelledPlan && !window.confirm(this.$t('aboutToJoinCancelledGroupPlan'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ export default {
|
||||
async accept () {
|
||||
const group = this.notification.data;
|
||||
|
||||
if (group.cancelledPlan && !confirm(this.$t('aboutToJoinCancelledGroupPlan'))) {
|
||||
if (group.cancelledPlan && !window.confirm(this.$t('aboutToJoinCancelledGroupPlan'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
</base-notification>
|
||||
</template>
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
<style lang="scss" scoped>
|
||||
.background {
|
||||
position: relative;
|
||||
@@ -157,6 +158,7 @@
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
<!-- eslint-enable max-len -->
|
||||
|
||||
<script>
|
||||
import * as quests from '@/../../common/script/content/quests';
|
||||
@@ -183,10 +185,6 @@ export default {
|
||||
worldBoss: {},
|
||||
};
|
||||
},
|
||||
async mounted () {
|
||||
const result = await this.$store.dispatch('worldState:getWorldState');
|
||||
this.worldBoss = result.worldBoss;
|
||||
},
|
||||
computed: {
|
||||
...mapState({ user: 'user.data' }),
|
||||
bossHp () {
|
||||
@@ -196,6 +194,10 @@ export default {
|
||||
return this.questData.boss.hp.toLocaleString();
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
const result = await this.$store.dispatch('worldState:getWorldState');
|
||||
this.worldBoss = result.worldBoss;
|
||||
},
|
||||
methods: {
|
||||
action () {
|
||||
this.$router.push({ name: 'tavern' });
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
</div>
|
||||
<div slot="dropdown-content">
|
||||
<div
|
||||
class="dropdown-item dropdown-separated d-flex justify-content-between dropdown-inactive align-items-center"
|
||||
class="dropdown-item dropdown-separated
|
||||
d-flex justify-content-between dropdown-inactive align-items-center"
|
||||
@click.stop
|
||||
>
|
||||
<h4
|
||||
@@ -49,7 +50,8 @@
|
||||
/>
|
||||
<div
|
||||
v-if="notificationsCount === 0"
|
||||
class="dropdown-item dropdown-separated d-flex justify-content-center dropdown-inactive no-notifications flex-column"
|
||||
class="dropdown-item dropdown-separated
|
||||
d-flex justify-content-center dropdown-inactive no-notifications flex-column"
|
||||
>
|
||||
<div
|
||||
class="svg-icon"
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
<span class="small-text">{{ $t('editAvatar') }}</span>
|
||||
</a>
|
||||
<a
|
||||
class="nav-link dropdown-item dropdown-separated d-flex justify-content-between align-items-center"
|
||||
class="nav-link dropdown-item
|
||||
dropdown-separated d-flex justify-content-between align-items-center"
|
||||
@click.prevent="showInbox()"
|
||||
>
|
||||
<div>{{ $t('messages') }}</div>
|
||||
@@ -73,7 +74,7 @@
|
||||
@click.prevent="logout()"
|
||||
>{{ $t('logout') }}</a>
|
||||
<li
|
||||
v-if="!this.user.purchased.plan.customerId"
|
||||
v-if="!user.purchased.plan.customerId"
|
||||
@click="showBuyGemsModal('subscribe')"
|
||||
>
|
||||
<div class="dropdown-item text-center">
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<h2 v-once>
|
||||
{{ $t('filter') }}
|
||||
</h2>
|
||||
<h3>{{ this.groupBy === 'type' ? $t('equipmentType') : $t('class') }}</h3>
|
||||
<h3>{{ groupBy === 'type' ? $t('equipmentType') : $t('class') }}</h3>
|
||||
<div class="form-group">
|
||||
<div
|
||||
v-for="group in itemsGroups"
|
||||
@@ -122,11 +122,14 @@
|
||||
:key="flatGear[activeItems[group]] ? flatGear[activeItems[group]].key : group"
|
||||
class="pointer"
|
||||
:item="flatGear[activeItems[group]]"
|
||||
:item-content-class="flatGear[activeItems[group]] ? 'shop_' + flatGear[activeItems[group]].key : null"
|
||||
:empty-item="!flatGear[activeItems[group]] || flatGear[activeItems[group]].key.indexOf('_base_0') !== -1"
|
||||
:item-content-class="flatGear[activeItems[group]]
|
||||
? 'shop_' + flatGear[activeItems[group]].key : null"
|
||||
:empty-item="!flatGear[activeItems[group]]
|
||||
|| flatGear[activeItems[group]].key.indexOf('_base_0') !== -1"
|
||||
:label="label"
|
||||
:popover-position="'top'"
|
||||
:show-popover="flatGear[activeItems[group]] && Boolean(flatGear[activeItems[group]].text)"
|
||||
:show-popover="flatGear[activeItems[group]]
|
||||
&& Boolean(flatGear[activeItems[group]].text)"
|
||||
@click="equipItem(flatGear[activeItems[group]])"
|
||||
>
|
||||
<template
|
||||
@@ -148,12 +151,14 @@
|
||||
</item>
|
||||
</div>
|
||||
</drawer>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="group in itemsGroups"
|
||||
v-if="!anyFilterSelected || viewOptions[group.key].selected"
|
||||
:key="group.key"
|
||||
:class="group.key"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<h2 class="mb-3">
|
||||
{{ group.label }}
|
||||
<span
|
||||
|
||||
@@ -72,11 +72,14 @@
|
||||
</b-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="group in groups"
|
||||
v-if="!anyFilterSelected || group.selected"
|
||||
:key="group.key"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<h2 class="mb-3">
|
||||
{{ $t(group.key) }}
|
||||
<span
|
||||
@@ -472,7 +475,7 @@ export default {
|
||||
quantity: this.user.purchased.plan.mysteryItems.length,
|
||||
});
|
||||
|
||||
for (const type in this.content.cardTypes) {
|
||||
for (const type of Object.keys(this.content.cardTypes)) {
|
||||
const card = this.user.items.special[`${type}Received`] || [];
|
||||
if (this.user.items.special[type] > 0 || card.length > 0) {
|
||||
specialArray.push({
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
</h4>
|
||||
<div
|
||||
class="text"
|
||||
v-html="$t('hatchDialogText', { potionName: hatchablePet.potionName, eggName: hatchablePet.eggName, petName: hatchablePet.name })"
|
||||
v-html="$t('hatchDialogText', {
|
||||
potionName: hatchablePet.potionName,
|
||||
eggName: hatchablePet.eggName, petName: hatchablePet.name })"
|
||||
></div>
|
||||
</div>
|
||||
<span
|
||||
|
||||
@@ -134,21 +134,27 @@
|
||||
class="badge badge-pill badge-default"
|
||||
>{{ countOwnedAnimals(petGroups[0], 'pet') }}</span>
|
||||
</h2>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="(petGroup, index) in petGroups"
|
||||
v-for="(petGroup) in petGroups"
|
||||
v-if="!anyFilterSelected || viewOptions[petGroup.key].selected"
|
||||
:key="petGroup.key"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<h4 v-if="viewOptions[petGroup.key].animalCount !== 0">
|
||||
{{ petGroup.label }}
|
||||
</h4>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for, max-len -->
|
||||
<div
|
||||
v-for="(group, key, index) in pets(petGroup, hideMissing, selectedSortBy, searchTextThrottled)"
|
||||
v-if="index === 0 || $_openedItemRows_isToggled(petGroup.key)"
|
||||
:key="key"
|
||||
class="pet-row d-flex"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="item in group"
|
||||
:key="item.key"
|
||||
v-drag.drop.food="item.key"
|
||||
class="pet-group"
|
||||
:class="{'last': item.isLastInRow}"
|
||||
@@ -190,21 +196,27 @@
|
||||
class="badge badge-pill badge-default"
|
||||
>{{ countOwnedAnimals(mountGroups[0], 'mount') }}</span>
|
||||
</h2>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="mountGroup in mountGroups"
|
||||
v-if="!anyFilterSelected || viewOptions[mountGroup.key].selected"
|
||||
:key="mountGroup.key"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<h4 v-if="viewOptions[mountGroup.key].animalCount != 0">
|
||||
{{ mountGroup.label }}
|
||||
</h4>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for, max-len -->
|
||||
<div
|
||||
v-for="(group, key, index) in mounts(mountGroup, hideMissing, selectedSortBy, searchTextThrottled)"
|
||||
v-if="index === 0 || $_openedItemRows_isToggled(mountGroup.key)"
|
||||
:key="key"
|
||||
class="pet-row d-flex"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="item in group"
|
||||
:key="item.key"
|
||||
class="pet-group"
|
||||
>
|
||||
<mountItem
|
||||
@@ -219,7 +231,6 @@
|
||||
</span>
|
||||
<template
|
||||
slot="itemBadge"
|
||||
slot-scope="context"
|
||||
>
|
||||
<starBadge
|
||||
:selected="item.key === currentMount"
|
||||
@@ -459,8 +470,6 @@ import _throttle from 'lodash/throttle';
|
||||
import groupBy from 'lodash/groupBy';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
import Item from '../item';
|
||||
import ItemRows from '@/components/ui/itemRows';
|
||||
import PetItem from './petItem';
|
||||
import MountItem from './mountItem.vue';
|
||||
import FoodItem from './foodItem';
|
||||
@@ -468,11 +477,8 @@ import HatchedPetDialog from './hatchedPetDialog';
|
||||
import MountRaisedModal from './mountRaisedModal';
|
||||
import WelcomeModal from './welcomeModal';
|
||||
import HatchingModal from './hatchingModal';
|
||||
import Drawer from '@/components/ui/drawer';
|
||||
import toggleSwitch from '@/components/ui/toggleSwitch';
|
||||
import StarBadge from '@/components/ui/starBadge';
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
import DrawerSlider from '@/components/ui/drawerSlider';
|
||||
import InventoryDrawer from '@/components/shared/inventoryDrawer';
|
||||
|
||||
import ResizeDirective from '@/directives/resize.directive';
|
||||
@@ -500,15 +506,10 @@ let lastMouseMoveEvent = {};
|
||||
export default {
|
||||
components: {
|
||||
PetItem,
|
||||
Item,
|
||||
ItemRows,
|
||||
FoodItem,
|
||||
MountItem,
|
||||
Drawer,
|
||||
toggleSwitch,
|
||||
StarBadge,
|
||||
CountBadge,
|
||||
DrawerSlider,
|
||||
HatchedPetDialog,
|
||||
MountRaisedModal,
|
||||
WelcomeModal,
|
||||
|
||||
@@ -92,7 +92,7 @@ export default {
|
||||
|
||||
this.$set(this.amazonPayments, 'loggedIn', true);
|
||||
|
||||
this.$root.$emit('habitica::pay-with-amazon', this.amazonPayments);
|
||||
return this.$root.$emit('habitica::pay-with-amazon', this.amazonPayments);
|
||||
},
|
||||
authorization: () => {
|
||||
if (this.amazonDisabled === true) return;
|
||||
|
||||
@@ -670,7 +670,6 @@ import amazonButton from '@/components/payments/amazonButton';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
planGemLimits,
|
||||
amazonButton,
|
||||
},
|
||||
directives: {
|
||||
@@ -705,7 +704,8 @@ export default {
|
||||
},
|
||||
userReachedGemCap () {
|
||||
return this.user.purchased.plan.customerId
|
||||
&& this.user.purchased.plan.gemsBought >= this.user.purchased.plan.consecutive.gemCapExtra + this.planGemLimits.convCap;
|
||||
&& this.user.purchased.plan.gemsBought
|
||||
>= (this.user.purchased.plan.consecutive.gemCapExtra + this.planGemLimits.convCap);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -78,11 +78,14 @@
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="block in subscriptionBlocks"
|
||||
v-if="block.target !== 'group' && block.canSubscribe === true"
|
||||
:key="block.key"
|
||||
class="radio"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<label>
|
||||
<input
|
||||
v-model="gift.subscription.key"
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
</div>
|
||||
</template>
|
||||
<template
|
||||
v-if="paymentData.paymentType === 'gift-gems' || paymentData.paymentType === 'gift-gems-balance'"
|
||||
v-if="paymentData.paymentType === 'gift-gems'
|
||||
|| paymentData.paymentType === 'gift-gems-balance'"
|
||||
>
|
||||
<span v-html="$t('paymentYouSentGems', {name: paymentData.giftReceiver})"></span>
|
||||
<div class="details-block gems">
|
||||
@@ -52,29 +53,34 @@
|
||||
</template>
|
||||
<template v-if="paymentData.paymentType === 'gift-subscription'">
|
||||
<span
|
||||
v-html="$t('paymentYouSentSubscription', {name: paymentData.giftReceiver, months: paymentData.subscription.months})"
|
||||
v-html="$t('paymentYouSentSubscription', {
|
||||
name: paymentData.giftReceiver, months: paymentData.subscription.months})"
|
||||
></span>
|
||||
</template>
|
||||
<template v-if="paymentData.paymentType === 'subscription'">
|
||||
<strong v-once>{{ $t('nowSubscribed') }}</strong>
|
||||
<div class="details-block">
|
||||
<span
|
||||
v-html="$t('paymentSubBilling', {amount: paymentData.subscription.price, months: paymentData.subscription.months})"
|
||||
v-html="$t('paymentSubBilling', {
|
||||
amount: paymentData.subscription.price, months: paymentData.subscription.months})"
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="paymentData.paymentType === 'groupPlan'">
|
||||
<span
|
||||
v-html="$t(paymentData.newGroup ? 'groupPlanCreated' : 'groupPlanUpgraded', {groupName: paymentData.group.name})"
|
||||
v-html="$t(paymentData.newGroup
|
||||
? 'groupPlanCreated' : 'groupPlanUpgraded', {groupName: paymentData.group.name})"
|
||||
></span>
|
||||
<div class="details-block">
|
||||
<span
|
||||
v-html="$t('paymentSubBilling', {amount: groupPlanCost, months: paymentData.subscription.months})"
|
||||
v-html="$t('paymentSubBilling', {
|
||||
amount: groupPlanCost, months: paymentData.subscription.months})"
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
<template
|
||||
v-if="paymentData.paymentType === 'groupPlan' || paymentData.paymentType === 'subscription'"
|
||||
v-if="paymentData.paymentType === 'groupPlan'
|
||||
|| paymentData.paymentType === 'subscription'"
|
||||
>
|
||||
<span
|
||||
v-once
|
||||
|
||||
@@ -68,7 +68,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(webhook, index) in user.webhooks">
|
||||
<tr
|
||||
v-for="(webhook, index) in user.webhooks"
|
||||
:key="webhook.id"
|
||||
>
|
||||
<td>
|
||||
<input
|
||||
v-model="webhook.enabled"
|
||||
|
||||
@@ -38,7 +38,10 @@
|
||||
<span>{{ $t('push') }}</span>
|
||||
</th>
|
||||
</tr>
|
||||
<tr v-for="notification in notificationsIds">
|
||||
<tr
|
||||
v-for="notification in notificationsIds"
|
||||
:key="notification"
|
||||
>
|
||||
<td>
|
||||
<span>{{ $t(notification) }}</span>
|
||||
</td>
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
data-for="stats.gp"
|
||||
>
|
||||
</div>
|
||||
<!--input.form-control(type='number', step="any", data-for='stats.gp', v-model='restoreValues.stats.gp',disabled)-->
|
||||
<!--input.form-control(type='number',
|
||||
step="any", data-for='stats.gp', v-model='restoreValues.stats.gp',disabled)-->
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-3">
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="lang in availableLanguages"
|
||||
:key="lang.code"
|
||||
:value="lang.code"
|
||||
>
|
||||
{{ lang.name }}
|
||||
@@ -37,6 +38,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="dateFormat in availableFormats"
|
||||
:key="dateFormat"
|
||||
:value="dateFormat"
|
||||
>
|
||||
{{ dateFormat }}
|
||||
@@ -54,6 +56,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="sound in availableAudioThemes"
|
||||
:key="sound"
|
||||
:value="sound"
|
||||
>
|
||||
{{ $t(`audioTheme_${sound}`) }}
|
||||
@@ -217,6 +220,7 @@
|
||||
>
|
||||
<option
|
||||
v-for="option in dayStartOptions"
|
||||
:key="option.value"
|
||||
:value="option.value"
|
||||
>
|
||||
{{ option.name }}
|
||||
@@ -252,7 +256,10 @@
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
<ul class="list-inline">
|
||||
<li v-for="network in SOCIAL_AUTH_NETWORKS">
|
||||
<li
|
||||
v-for="network in SOCIAL_AUTH_NETWORKS"
|
||||
:key="network.key"
|
||||
>
|
||||
<button
|
||||
v-if="!user.auth[network.key].id"
|
||||
class="btn btn-primary mb-2"
|
||||
@@ -343,6 +350,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="issue in displayNameIssues"
|
||||
:key="issue"
|
||||
class="input-error"
|
||||
>
|
||||
{{ issue }}
|
||||
@@ -390,6 +398,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="issue in usernameIssues"
|
||||
:key="issue"
|
||||
class="input-error"
|
||||
>
|
||||
{{ issue }}
|
||||
@@ -754,10 +763,10 @@ export default {
|
||||
return true;
|
||||
}
|
||||
|
||||
return find(this.SOCIAL_AUTH_NETWORKS, network => {
|
||||
return this.SOCIAL_AUTH_NETWORKS.find(network => {
|
||||
if (network.key !== networkKeyToCheck) {
|
||||
if (this.user.auth[network.key]) {
|
||||
return this.user.auth[network.key].id;
|
||||
return !!this.user.auth[network.key].id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,9 +103,9 @@
|
||||
<span class="glyphicon glyphicon-forward"></span>
|
||||
{{ $t('consecutiveSubscription') }}
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ $t('consecutiveMonths') }} {{ user.purchased.plan.consecutive.count + user.purchased.plan.consecutive.offset }}</li>
|
||||
<li>{{ $t('consecutiveMonths') }} {{ user.purchased.plan.consecutive.count + user.purchased.plan.consecutive.offset }}</li> <!-- eslint-disable-line max-len -->
|
||||
<li>{{ $t('gemCapExtra') }} {{ user.purchased.plan.consecutive.gemCapExtra }}</li>
|
||||
<li>{{ $t('mysticHourglasses') }} {{ user.purchased.plan.consecutive.trinkets }}</li>
|
||||
<li>{{ $t('mysticHourglasses') }} {{ user.purchased.plan.consecutive.trinkets }}</li> <!-- eslint-disable-line max-len -->
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -115,11 +115,14 @@
|
||||
{{ $t("resubscribe") }}
|
||||
</h4>
|
||||
<div class="form-group reduce-top-margin">
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="block in subscriptionBlocksOrdered"
|
||||
v-if="block.target !== 'group' && block.canSubscribe === true"
|
||||
:key="block.key"
|
||||
class="radio"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<label>
|
||||
<input
|
||||
v-model="subscription.key"
|
||||
@@ -207,7 +210,8 @@
|
||||
</button>
|
||||
<amazon-button
|
||||
class="payment-item"
|
||||
:amazon-data="{type: 'subscription', subscription: this.subscription.key, coupon: this.subscription.coupon}"
|
||||
:amazon-data="{
|
||||
type: 'subscription', subscription: subscription.key, coupon: subscription.coupon}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
class="form-control"
|
||||
type="text"
|
||||
:placeholder="$t('newDisplayName')"
|
||||
:class="{'is-invalid input-invalid': displayNameInvalid, 'input-valid': displayNameValid, 'text-darker': temporaryDisplayName.length > 0}"
|
||||
:class="{
|
||||
'is-invalid input-invalid': displayNameInvalid,
|
||||
'input-valid': displayNameValid, 'text-darker': temporaryDisplayName.length > 0}"
|
||||
@blur="restoreEmptyDisplayName()"
|
||||
>
|
||||
</div>
|
||||
@@ -25,6 +27,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="issue in displayNameIssues"
|
||||
:key="issue"
|
||||
class="input-error text-center"
|
||||
>
|
||||
{{ issue }}
|
||||
@@ -45,7 +48,9 @@
|
||||
class="form-control"
|
||||
type="text"
|
||||
:placeholder="$t('newUsername')"
|
||||
:class="{'is-invalid input-invalid': usernameInvalid, 'input-valid': usernameValid, 'text-darker': temporaryUsername.length > 0}"
|
||||
:class="{
|
||||
'is-invalid input-invalid': usernameInvalid,
|
||||
'input-valid': usernameValid, 'text-darker': temporaryUsername.length > 0}"
|
||||
@blur="restoreEmptyUsername()"
|
||||
>
|
||||
</div>
|
||||
@@ -58,6 +63,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="issue in usernameIssues"
|
||||
:key="issue"
|
||||
class="input-error text-center"
|
||||
>
|
||||
{{ issue }}
|
||||
|
||||
@@ -65,16 +65,12 @@ import { mapState } from '@/libs/store';
|
||||
import inventoryUtils from '@/mixins/inventoryUtils';
|
||||
import svgInformation from '@/assets/svg/information.svg';
|
||||
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
import Item from '@/components/inventory/item';
|
||||
import Drawer from '@/components/ui/drawer';
|
||||
import DrawerSlider from '@/components/ui/drawerSlider';
|
||||
import DrawerHeaderTabs from '@/components/ui/drawerHeaderTabs';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Item,
|
||||
CountBadge,
|
||||
Drawer,
|
||||
DrawerSlider,
|
||||
DrawerHeaderTabs,
|
||||
|
||||
@@ -11,8 +11,8 @@ export default {
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
enoughCurrency (currency, amount) {
|
||||
switch (currency) {
|
||||
enoughCurrency (currency, amount) { // eslint-disable-line consistent-return
|
||||
switch (currency) { // eslint-disable-line default-case
|
||||
case 'gold':
|
||||
return this.userGold >= amount;
|
||||
case 'gems':
|
||||
|
||||
@@ -123,7 +123,8 @@
|
||||
{{ $t('notEnoughGemsToBuy') }}
|
||||
</div>
|
||||
<button
|
||||
v-if="getPriceClass() === 'gems' && !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)"
|
||||
v-if="getPriceClass() === 'gems'
|
||||
&& !enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)"
|
||||
class="btn btn-primary"
|
||||
@click="purchaseGems()"
|
||||
>
|
||||
@@ -132,8 +133,10 @@
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-primary"
|
||||
:disabled="item.key === 'gem' && gemsLeft === 0 || attemptingToPurchaseMoreGemsThanAreLeft || numberInvalid"
|
||||
:class="{'notEnough': !preventHealthPotion || !this.enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)}"
|
||||
:disabled="item.key === 'gem' && gemsLeft === 0 ||
|
||||
attemptingToPurchaseMoreGemsThanAreLeft || numberInvalid"
|
||||
:class="{'notEnough': !preventHealthPotion ||
|
||||
!enoughCurrency(getPriceClass(), item.value * selectedAmountToBuy)}"
|
||||
@click="buyItem()"
|
||||
>
|
||||
{{ $t('buyNow') }}
|
||||
@@ -406,6 +409,21 @@ export default {
|
||||
Avatar,
|
||||
},
|
||||
mixins: [buyMixin, currencyMixin, notifications, numberInvalid, spellsMixin],
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
},
|
||||
priceType: {
|
||||
type: String,
|
||||
},
|
||||
withPin: {
|
||||
type: Boolean,
|
||||
},
|
||||
genericPurchase: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
icons: Object.freeze({
|
||||
@@ -595,20 +613,5 @@ export default {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
},
|
||||
priceType: {
|
||||
type: String,
|
||||
},
|
||||
withPin: {
|
||||
type: Boolean,
|
||||
},
|
||||
genericPurchase: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -52,10 +52,13 @@
|
||||
</filter-dropdown>
|
||||
</div>
|
||||
</layout-section>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="category in categories"
|
||||
v-if="!anyFilterSelected || viewOptions[category.identifier].selected"
|
||||
:key="category.identifier"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<h4>{{ category.text }}</h4>
|
||||
<category-row
|
||||
:hide-pinned="hidePinned"
|
||||
@@ -160,14 +163,11 @@ import _map from 'lodash/map';
|
||||
import _throttle from 'lodash/throttle';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
import ShopItem from '../shopItem';
|
||||
import KeysToKennel from './keysToKennel';
|
||||
import EquipmentSection from './equipmentSection';
|
||||
import CategoryRow from './categoryRow';
|
||||
import Item from '@/components/inventory/item';
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
import ItemRows from '@/components/ui/itemRows';
|
||||
import Avatar from '@/components/avatar';
|
||||
import InventoryDrawer from '@/components/shared/inventoryDrawer';
|
||||
import FeaturedItemsHeader from '../featuredItemsHeader';
|
||||
import PageLayout from '@/components/ui/pageLayout';
|
||||
@@ -176,8 +176,6 @@ import FilterDropdown from '@/components/ui/filterDropdown';
|
||||
import MarketFilter from './filter';
|
||||
|
||||
import SellModal from './sellModal.vue';
|
||||
import EquipmentAttributesGrid from '../../inventory/equipment/attributesGrid.vue';
|
||||
import SelectMembersModal from '@/components/selectMembersModal.vue';
|
||||
|
||||
import svgPin from '@/assets/svg/pin.svg';
|
||||
import svgGem from '@/assets/svg/gem.svg';
|
||||
@@ -197,16 +195,11 @@ const sortItems = ['AZ', 'sortByNumber'].map(g => ({ id: g }));
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ShopItem,
|
||||
KeysToKennel,
|
||||
Item,
|
||||
CountBadge,
|
||||
|
||||
ItemRows,
|
||||
|
||||
SellModal,
|
||||
EquipmentAttributesGrid,
|
||||
Avatar,
|
||||
|
||||
InventoryDrawer,
|
||||
FeaturedItemsHeader,
|
||||
@@ -216,8 +209,6 @@ export default {
|
||||
EquipmentSection,
|
||||
CategoryRow,
|
||||
MarketFilter,
|
||||
|
||||
SelectMembersModal,
|
||||
},
|
||||
mixins: [notifications, buyMixin, currencyMixin, inventoryUtils, pinUtils],
|
||||
data () {
|
||||
|
||||
@@ -52,7 +52,8 @@
|
||||
>{{ item.value }}</span>
|
||||
</div>
|
||||
<button
|
||||
v-if="priceType === 'gems' && !this.enoughCurrency(priceType, item.value * selectedAmountToBuy)"
|
||||
v-if="priceType === 'gems'
|
||||
&& !enoughCurrency(priceType, item.value * selectedAmountToBuy)"
|
||||
class="btn btn-primary"
|
||||
@click="purchaseGems()"
|
||||
>
|
||||
@@ -61,7 +62,7 @@
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-primary"
|
||||
:class="{'notEnough': !this.enoughCurrency(priceType, item.value * selectedAmountToBuy)}"
|
||||
:class="{'notEnough': !enoughCurrency(priceType, item.value * selectedAmountToBuy)}"
|
||||
:disabled="numberInvalid"
|
||||
@click="buyItem()"
|
||||
>
|
||||
@@ -247,7 +248,6 @@ import svgHourglasses from '@/assets/svg/hourglass.svg';
|
||||
|
||||
import BalanceInfo from '../balanceInfo.vue';
|
||||
import currencyMixin from '../_currencyMixin';
|
||||
import QuestInfo from './questInfo.vue';
|
||||
import notifications from '@/mixins/notifications';
|
||||
import buyMixin from '@/mixins/buy';
|
||||
import numberInvalid from '@/mixins/numberInvalid';
|
||||
@@ -258,7 +258,6 @@ import questDialogContent from './questDialogContent';
|
||||
export default {
|
||||
components: {
|
||||
BalanceInfo,
|
||||
QuestInfo,
|
||||
questDialogDrops,
|
||||
questDialogContent,
|
||||
},
|
||||
|
||||
@@ -139,13 +139,17 @@
|
||||
</b-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="category in categories"
|
||||
v-if="!anyFilterSelected || viewOptions[category.identifier].selected"
|
||||
:key="category.identifier"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<h2 class="mb-3">
|
||||
{{ category.text }}
|
||||
</h2>
|
||||
<!-- eslint-disable max-len -->
|
||||
<itemRows
|
||||
v-if="category.identifier === 'pet'"
|
||||
:items="questItems(category, selectedSortItemsBy, searchTextThrottled, hideLocked, hidePinned)"
|
||||
@@ -153,6 +157,7 @@
|
||||
:item-margin="24"
|
||||
:type="'pet_quests'"
|
||||
>
|
||||
<!-- eslint-enable max-len -->
|
||||
<template
|
||||
slot="item"
|
||||
slot-scope="ctx"
|
||||
@@ -201,11 +206,14 @@
|
||||
v-else-if="category.identifier === 'unlockable' || category.identifier === 'gold'"
|
||||
class="grouped-parent"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for, max-len -->
|
||||
<div
|
||||
v-for="(items, key) in getGrouped(questItems(category, selectedSortItemsBy,searchTextThrottled, hideLocked, hidePinned))"
|
||||
v-if="key !== 'questGroupEarnable'"
|
||||
:key="key"
|
||||
class="group"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for, max-len -->
|
||||
<h3>{{ $t(key) }}</h3>
|
||||
<div class="items">
|
||||
<shopItem
|
||||
@@ -233,9 +241,11 @@
|
||||
class="popover-content-text"
|
||||
>{{ `${$t('questUnlockLostMasterclasser')}` }}</div>
|
||||
<div
|
||||
v-if="item.locked && item.unlockCondition && item.unlockCondition.incentiveThreshold"
|
||||
v-if="item.locked && item.unlockCondition
|
||||
&& item.unlockCondition.incentiveThreshold"
|
||||
class="popover-content-text"
|
||||
>{{ `${$t('loginIncentiveQuest', {count: item.unlockCondition.incentiveThreshold})}` }}</div>
|
||||
>{{ `${$t('loginIncentiveQuest', {
|
||||
count: item.unlockCondition.incentiveThreshold})}` }}</div>
|
||||
<div
|
||||
v-if="item.locked && item.previous && isBuyingDependentOnPrevious(item)"
|
||||
class="popover-content-text"
|
||||
@@ -278,7 +288,8 @@
|
||||
class="items"
|
||||
>
|
||||
<shopItem
|
||||
v-for="item in questItems(category, selectedSortItemsBy, searchTextThrottled, hideLocked, hidePinned)"
|
||||
v-for="item in questItems(category, selectedSortItemsBy,
|
||||
searchTextThrottled, hideLocked, hidePinned)"
|
||||
:key="item.key"
|
||||
:item="item"
|
||||
:price="item.value"
|
||||
@@ -484,7 +495,6 @@ import Item from '@/components/inventory/item';
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
import ItemRows from '@/components/ui/itemRows';
|
||||
import toggleSwitch from '@/components/ui/toggleSwitch';
|
||||
import Avatar from '@/components/avatar';
|
||||
import buyMixin from '@/mixins/buy';
|
||||
import pinUtils from '@/mixins/pinUtils';
|
||||
import currencyMixin from '../_currencyMixin';
|
||||
@@ -507,7 +517,6 @@ export default {
|
||||
ItemRows,
|
||||
toggleSwitch,
|
||||
|
||||
Avatar,
|
||||
BuyModal,
|
||||
QuestInfo,
|
||||
},
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-for="drop in getDropsList(item.drop.items, false)"
|
||||
:key="drop.key"
|
||||
class="reward-item"
|
||||
>
|
||||
<span class="icon">
|
||||
@@ -46,6 +47,7 @@
|
||||
</h3>
|
||||
<div
|
||||
v-for="drop in getDropsList(item.drop.items, true)"
|
||||
:key="drop.key"
|
||||
class="reward-item"
|
||||
>
|
||||
<span class="icon">
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
>
|
||||
<dt>{{ $t('collect') + ':' }}</dt>
|
||||
<dd>
|
||||
<div v-for="(collect, key) of quest.collect">
|
||||
<div
|
||||
v-for="(collect, key) of quest.collect"
|
||||
:key="key"
|
||||
>
|
||||
<span>{{ collect.count }} {{ getCollectText(collect) }}</span>
|
||||
</div>
|
||||
</dd>
|
||||
@@ -26,6 +29,7 @@
|
||||
<dd>
|
||||
<div
|
||||
v-for="star of stars()"
|
||||
:key="star"
|
||||
class="svg-icon inline"
|
||||
:class="smallVersion ? 'icon-12' : 'icon-16'"
|
||||
v-html="icons[star]"
|
||||
|
||||
@@ -139,7 +139,10 @@
|
||||
</b-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(groupSets, categoryGroup) in getGroupedCategories(categories)">
|
||||
<div
|
||||
v-for="(groupSets, categoryGroup) in getGroupedCategories(categories)"
|
||||
:key="categoryGroup"
|
||||
>
|
||||
<h3
|
||||
v-if="categoryGroup !== 'spells' && categoryGroup !== 'quests'"
|
||||
class="classgroup"
|
||||
@@ -156,10 +159,12 @@
|
||||
<div class="grouped-parent">
|
||||
<div
|
||||
v-for="category in groupSets"
|
||||
:key="category.identifier"
|
||||
class="group"
|
||||
>
|
||||
<h3>{{ category.text }}</h3>
|
||||
<div class="items">
|
||||
<!-- eslint-disable max-len -->
|
||||
<shopItem
|
||||
v-for="item in seasonalItems(category, selectedSortItemsBy, searchTextThrottled, viewOptions, hidePinned)"
|
||||
:key="item.key"
|
||||
@@ -170,6 +175,7 @@
|
||||
:show-event-badge="false"
|
||||
@click="itemSelected(item)"
|
||||
>
|
||||
<!-- eslint-enable max-len -->
|
||||
<template
|
||||
slot="itemBadge"
|
||||
slot-scope="ctx"
|
||||
@@ -194,6 +200,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
<style lang="scss">
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
@import '~@/assets/scss/variables.scss';
|
||||
@@ -366,6 +373,7 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- eslint-enable max-len -->
|
||||
|
||||
<style scoped>
|
||||
.margin-center {
|
||||
@@ -385,12 +393,8 @@ import _reverse from 'lodash/reverse';
|
||||
import { mapState } from '@/libs/store';
|
||||
|
||||
import ShopItem from '../shopItem';
|
||||
import Item from '@/components/inventory/item';
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
import ItemRows from '@/components/ui/itemRows';
|
||||
import Checkbox from '@/components/ui/checkbox';
|
||||
import toggleSwitch from '@/components/ui/toggleSwitch';
|
||||
import Avatar from '@/components/avatar';
|
||||
import buyMixin from '@/mixins/buy';
|
||||
import currencyMixin from '../_currencyMixin';
|
||||
import pinUtils from '@/mixins/pinUtils';
|
||||
@@ -412,13 +416,8 @@ import shops from '@/../../common/script/libs/shops';
|
||||
export default {
|
||||
components: {
|
||||
ShopItem,
|
||||
Item,
|
||||
CountBadge,
|
||||
ItemRows,
|
||||
toggleSwitch,
|
||||
Checkbox,
|
||||
|
||||
Avatar,
|
||||
},
|
||||
mixins: [buyMixin, currencyMixin, pinUtils],
|
||||
data () {
|
||||
|
||||
@@ -92,11 +92,15 @@
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</div>
|
||||
</div><div
|
||||
</div>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="category in categories"
|
||||
v-if="!anyFilterSelected || (!closed && viewOptions[category.identifier].selected)"
|
||||
:key="category.identifier"
|
||||
:class="category.identifier"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<h2 class="mb-3">
|
||||
{{ category.text }}
|
||||
</h2><itemRows
|
||||
@@ -121,11 +125,15 @@
|
||||
v-if="category !== 'quests'"
|
||||
slot="popoverContent"
|
||||
slot-scope="ctx"
|
||||
><div><h4 class="popover-content-title">{{ ctx.item.text }}</h4></div></span><span
|
||||
><div><h4 class="popover-content-title">{{ ctx.item.text }}</h4></div></span>
|
||||
<span
|
||||
v-if="category === 'quests'"
|
||||
slot="popoverContent"
|
||||
slot-scope="ctx"
|
||||
><div class="questPopover"><h4 class="popover-content-title">{{ item.text }}</h4><questInfo :quest="item" /></div></span><template
|
||||
><div class="questPopover">
|
||||
<h4 class="popover-content-title">{{ item.text }}</h4>
|
||||
<questInfo :quest="item" />
|
||||
</div></span>
|
||||
<template
|
||||
slot="itemBadge"
|
||||
slot-scope="ctx"
|
||||
>
|
||||
@@ -164,6 +172,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
<style lang="scss">
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
@import '~@/assets/scss/variables.scss';
|
||||
@@ -297,7 +306,7 @@
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- eslint-enable max-len -->
|
||||
|
||||
<script>
|
||||
import _filter from 'lodash/filter';
|
||||
@@ -309,13 +318,10 @@ import { mapState } from '@/libs/store';
|
||||
|
||||
import ShopItem from '../shopItem';
|
||||
import Item from '@/components/inventory/item';
|
||||
import CountBadge from '@/components/ui/countBadge';
|
||||
import ItemRows from '@/components/ui/itemRows';
|
||||
import toggleSwitch from '@/components/ui/toggleSwitch';
|
||||
import Avatar from '@/components/avatar';
|
||||
import QuestInfo from '../quests/questInfo.vue';
|
||||
|
||||
import BuyModal from '../buyModal.vue';
|
||||
import BuyQuestModal from '../quests/buyQuestModal.vue';
|
||||
|
||||
import svgPin from '@/assets/svg/pin.svg';
|
||||
@@ -331,13 +337,10 @@ export default {
|
||||
components: {
|
||||
ShopItem,
|
||||
Item,
|
||||
CountBadge,
|
||||
ItemRows,
|
||||
toggleSwitch,
|
||||
QuestInfo,
|
||||
|
||||
Avatar,
|
||||
BuyModal,
|
||||
BuyQuestModal,
|
||||
},
|
||||
mixins: [pinUtils],
|
||||
|
||||
@@ -186,8 +186,17 @@
|
||||
<ul>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'Beffymaroo', realName: 'Beth'}) }}</li>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'Viirus', realName: 'Phillip'}) }}</li>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'redphoenix', realName: 'Vicky'}) }} ({{ $t('commGuideOnTrello', {trelloName: 'caffeinatedvee'}) }}, {{ $t('commGuideOnGitHub', {gitHubName: 'veeeeeee'}) }})</li>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'Lemoness', realName: 'Leslie'}) }} ({{ $t('commGuideOnTrello', {trelloName: 'lemonesstree'}) }})</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {
|
||||
habitName: 'redphoenix', realName: 'Vicky'}) }} ({{ $t('commGuideOnTrello', {
|
||||
trelloName: 'caffeinatedvee'}) }}, {{ $t('commGuideOnGitHub', {
|
||||
gitHubName: 'veeeeeee'}) }})
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('commGuideAKA', {
|
||||
habitName: 'Lemoness', realName: 'Leslie'}) }} ({{ $t('commGuideOnTrello', {
|
||||
trelloName: 'lemonesstree'}) }})
|
||||
</li>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'SabreCat', realName: 'Sabe'}) }}</li>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'paglias', realName: 'Matteo'}) }}</li>
|
||||
<li>{{ $t('commGuideAKA', {habitName: 'TheHollidayInn', realName: 'Keith'}) }}</li>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
target="_blank"
|
||||
href="https://github.com/HabitRPG/habitica/issues?q=is%3Aopen"
|
||||
>GitHub</a>
|
||||
<span v-if="this.user">
|
||||
<span v-if="user">
|
||||
<br>
|
||||
{{ $t('reportCommunityIssues') }}
|
||||
:
|
||||
|
||||
@@ -249,7 +249,6 @@
|
||||
import * as Analytics from '@/libs/analytics';
|
||||
import { setup as setupPayments } from '@/libs/payments';
|
||||
import amazonPaymentsModal from '@/components/payments/amazonModal';
|
||||
import StaticHeader from './header.vue';
|
||||
import AuthForm from '../auth/authForm.vue';
|
||||
import CreateGroupModalPages from '../group-plans/createGroupModalPages.vue';
|
||||
|
||||
@@ -257,7 +256,6 @@ import party from '../../assets/images/group-plans-static/party.svg';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
StaticHeader,
|
||||
AuthForm,
|
||||
CreateGroupModalPages,
|
||||
amazonPaymentsModal,
|
||||
|
||||
@@ -68,10 +68,12 @@
|
||||
:placeholder="$t('username')"
|
||||
:class="{'input-valid': usernameValid, 'input-invalid': usernameInvalid}"
|
||||
>
|
||||
<!-- eslint-disable vue/require-v-for-key -->
|
||||
<div
|
||||
v-for="issue in usernameIssues"
|
||||
class="input-error"
|
||||
>
|
||||
<!-- eslint-enable vue/require-v-for-key -->
|
||||
{{ issue }}
|
||||
</div>
|
||||
<input
|
||||
@@ -93,7 +95,9 @@
|
||||
class="form-control"
|
||||
type="password"
|
||||
:placeholder="$t('confirmPassword')"
|
||||
:class="{'input-invalid': passwordConfirmInvalid, 'input-valid': passwordConfirmValid}"
|
||||
:class="{
|
||||
'input-invalid': passwordConfirmInvalid,
|
||||
'input-valid': passwordConfirmValid}"
|
||||
>
|
||||
<p
|
||||
v-once
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-3">
|
||||
<h1>{{ $t('merch') }}</h1>
|
||||
<!-- @TODO: Visual experience: Separate each merch items with new line? Or to show items in a table?-->
|
||||
<!-- @TODO: Visual experience: Separate each
|
||||
merch items with new line? Or to show items in a table?-->
|
||||
<div
|
||||
v-for="(merchant, index) in merchants"
|
||||
v-for="(merchant) in merchants"
|
||||
:key="merchant.key"
|
||||
class="col-lg-6 col-md-6 col-sm-12"
|
||||
>
|
||||
<div class="merch-block">
|
||||
|
||||
@@ -4,13 +4,19 @@
|
||||
<div class="col-md-6 offset-3">
|
||||
<h1>{{ $t('overview') }}</h1>
|
||||
<p>{{ $t('needTips') }}</p>
|
||||
<div v-for="step in stepsNum">
|
||||
<div
|
||||
v-for="step in stepsNum"
|
||||
:key="step"
|
||||
>
|
||||
<h3>{{ $t('step'+step) }}</h3>
|
||||
<p v-markdown="$t('webStep'+step+'Text', stepVars[step])"></p>
|
||||
<hr>
|
||||
</div>
|
||||
<p
|
||||
v-markdown="$t('overviewQuestions', {faqUrl: '/static/faq/', helpGuildUrl: '/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a'})"
|
||||
v-markdown="$t('overviewQuestions', {
|
||||
faqUrl: '/static/faq/',
|
||||
helpGuildUrl: '/groups/guild/5481ccf3-5d2d-48a9-a871-70a7380cee5a'
|
||||
})"
|
||||
></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,10 +8,16 @@
|
||||
href="/static/presskit/presskit.zip"
|
||||
>presskit.zip</a>
|
||||
</p>
|
||||
<div v-for="(images, category) in imgs">
|
||||
<div
|
||||
v-for="(images, category) in imgs"
|
||||
:key="category"
|
||||
>
|
||||
<h2>{{ $t('pk' + category) }}</h2>
|
||||
<div v-if="Array.isArray(images)">
|
||||
<div v-for="img in images">
|
||||
<div
|
||||
v-for="img in images"
|
||||
:key="img"
|
||||
>
|
||||
<img
|
||||
class="img-fluid img-rendering-auto press-img"
|
||||
:src="`/static/presskit/${category}/${img}`"
|
||||
@@ -19,9 +25,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-for="(images, secondaryCategory) in images">
|
||||
<div
|
||||
v-for="(images, secondaryCategory) in images"
|
||||
:key="secondaryCategory"
|
||||
>
|
||||
<h3>{{ $t('pk' + secondaryCategory) }}</h3>
|
||||
<div v-for="img in images">
|
||||
<div
|
||||
v-for="img in images"
|
||||
:key="img"
|
||||
>
|
||||
<img
|
||||
class="img-fluid img-rendering-auto press-img"
|
||||
:src="`/static/presskit/${category}/${secondaryCategory}/${img}`"
|
||||
@@ -37,6 +49,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="(QA, index) in faq"
|
||||
:key="index"
|
||||
class="faq-question"
|
||||
>
|
||||
<h2
|
||||
@@ -70,7 +83,7 @@ const PRESS_ENQUIRY_EMAIL = 'admin@habitica.com';
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
return Object.freeze({
|
||||
PRESS_ENQUIRY_EMAIL,
|
||||
imgs: {
|
||||
Promo: [
|
||||
@@ -157,7 +170,7 @@ export default {
|
||||
answer: 'pkAnswer8',
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<!-- eslint-disable max-len -->
|
||||
<div class="container-fluid">
|
||||
<h1>Privacy Policy</h1>
|
||||
<p class="pagemeta">
|
||||
@@ -317,4 +318,5 @@
|
||||
<a href="mailto:admin@habitica.com">admin@habitica.com</a>
|
||||
</address>
|
||||
</div>
|
||||
<!-- eslint-enable max-len -->
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
<div>
|
||||
<static-header
|
||||
v-if="showContentWrap"
|
||||
:class="{'home-header': ['home', 'front'].indexOf($route.name) !== -1, 'white-header': this.$route.name === 'plans'}"
|
||||
:class="{
|
||||
'home-header': ['home', 'front'].indexOf($route.name) !== -1,
|
||||
'white-header': this.$route.name === 'plans'
|
||||
}"
|
||||
/>
|
||||
<div class="static-wrapper">
|
||||
<router-view />
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<template>
|
||||
<!-- eslint-disable max-len -->
|
||||
<div class="container-fluid">
|
||||
<h1>Terms of Use</h1>
|
||||
<p class="pagemeta">
|
||||
@@ -599,4 +600,5 @@
|
||||
<a href="mailto:admin@habitica.com">admin@habitica.com</a>
|
||||
</p>
|
||||
</div>
|
||||
<!-- eslint-enable max-len -->
|
||||
</template>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss", scoped>
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
.claim-bottom-message {
|
||||
background-color: $gray-700;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
:hide-footer="true"
|
||||
>
|
||||
<div class="modal-body">
|
||||
<!-- eslint-disable-next-line vue/require-v-for-key -->
|
||||
<div
|
||||
v-for="(approval, index) in task.approvals"
|
||||
class="row approval"
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
class="modal-body"
|
||||
>
|
||||
<div
|
||||
v-if="brokenChallengeTask.challenge.broken === 'TASK_DELETED' || brokenChallengeTask.challenge.broken === 'CHALLENGE_TASK_NOT_FOUND'"
|
||||
v-if="brokenChallengeTask.challenge.broken === 'TASK_DELETED'
|
||||
|| brokenChallengeTask.challenge.broken === 'CHALLENGE_TASK_NOT_FOUND'"
|
||||
>
|
||||
<h2>{{ $t('brokenTask') }}</h2>
|
||||
<div>
|
||||
@@ -63,7 +64,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- @TODO: I ported this over, but do we use it anymore?-->
|
||||
<!--div(v-if='brokenChallengeTask.challenge.broken === "UNSUBSCRIBED"')p {{ $t('unsubChallenge') }}
|
||||
<!--div(v-if='brokenChallengeTask.challenge.broken
|
||||
=== "UNSUBSCRIBED"')p {{ $t('unsubChallenge') }}
|
||||
p
|
||||
a(@click="unlink('keep-all')") {{ $t('keepThem') }}
|
||||
| |
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<div class="filters d-flex justify-content-end">
|
||||
<div
|
||||
v-for="filter in typeFilters"
|
||||
:key="filter"
|
||||
class="filter small-text"
|
||||
:class="{active: activeFilter.label === filter}"
|
||||
@click="activateFilter(type, filter)"
|
||||
@@ -341,7 +342,7 @@ import {
|
||||
getTypeLabel,
|
||||
getFilterLabels,
|
||||
getActiveFilter,
|
||||
} from '@/libs/store/helpers/filterTasks.js';
|
||||
} from '@/libs/store/helpers/filterTasks';
|
||||
|
||||
import svgPin from '@/assets/svg/pin.svg';
|
||||
import habitIcon from '@/assets/svg/habit.svg';
|
||||
@@ -484,7 +485,11 @@ export default {
|
||||
return this.taskList.length;
|
||||
} if (this.activeFilter.label === 'all') {
|
||||
return this.taskList
|
||||
.reduce((count, t) => (!t.completed && shouldDo(new Date(), t, this.getUserPreferences) ? count + 1 : count), 0);
|
||||
.reduce(
|
||||
(count, t) => (!t.completed
|
||||
&& shouldDo(new Date(), t, this.getUserPreferences) ? count + 1 : count),
|
||||
0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,14 +705,15 @@ export default {
|
||||
filteredTaskList = taskList.filter(
|
||||
task =>
|
||||
// eslint rule disabled for block to allow nested binary expression
|
||||
/* eslint-disable no-extra-parens */
|
||||
/* eslint-disable no-extra-parens, implicit-arrow-linebreak, max-len */
|
||||
(
|
||||
task.text.toLowerCase().indexOf(searchTextLowerCase) > -1
|
||||
|| (task.notes && task.notes.toLowerCase().indexOf(searchTextLowerCase) > -1)
|
||||
|| (task.checklist && task.checklist.length > 0
|
||||
&& task.checklist.some(checkItem => checkItem.text.toLowerCase().indexOf(searchTextLowerCase) > -1))
|
||||
&& task.checklist
|
||||
.some(checkItem => checkItem.text.toLowerCase().indexOf(searchTextLowerCase) > -1))
|
||||
),
|
||||
/* eslint-enable no-extra-parens */
|
||||
/* eslint-enable no-extra-parens, implicit-arrow-linebreak, max-len */
|
||||
);
|
||||
}
|
||||
return filteredTaskList;
|
||||
|
||||
@@ -35,13 +35,16 @@
|
||||
<div slot="drawer-slider">
|
||||
<div class="container spell-container">
|
||||
<div class="row">
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="(skill, key) in spells[user.stats.class]"
|
||||
v-if="user.stats.lvl >= skill.lvl"
|
||||
:key="key"
|
||||
v-b-popover.hover.auto="skill.notes()"
|
||||
class="col-12 col-md-3"
|
||||
@click="castStart(skill)"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div class="spell col-12 row">
|
||||
<div class="col-8 details">
|
||||
<a :class="{'disabled': spellDisabled(key)}"></a>
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
<template>
|
||||
<div class="tags-popup">
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="tagsType in tagsByType"
|
||||
v-if="tagsType.tags.length > 0 || tagsType.key === 'tags'"
|
||||
:key="tagsType.key"
|
||||
class="tags-category d-flex"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div class="tags-header">
|
||||
<strong v-once>{{ $t(tagsType.key) }}</strong>
|
||||
</div>
|
||||
<div class="tags-list container">
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="(tag, tagIndex) in tagsType.tags"
|
||||
v-for="(tag) in tagsType.tags"
|
||||
:key="tag.id"
|
||||
class="col-4"
|
||||
>
|
||||
<div class="custom-control custom-checkbox">
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
<div
|
||||
v-if="task.type === 'habit'"
|
||||
class="left-control d-flex align-items-center justify-content-center"
|
||||
:class="[{'control-bottom-box': this.task.group.id, 'control-top-box': approvalsClass}, controlClass.up.bg]"
|
||||
:class="[{
|
||||
'control-bottom-box': task.group.id,
|
||||
'control-top-box': approvalsClass
|
||||
}, controlClass.up.bg]"
|
||||
>
|
||||
<div
|
||||
class="task-control habit-control"
|
||||
@@ -26,7 +29,7 @@
|
||||
@click="(isUser && task.up) ? score('up') : null"
|
||||
>
|
||||
<div
|
||||
v-if="this.task.group.id && !isUser"
|
||||
v-if="task.group.id && !isUser"
|
||||
class="svg-icon lock"
|
||||
:class="controlClass.up.icon"
|
||||
v-html="icons.lock"
|
||||
@@ -42,7 +45,9 @@
|
||||
<div
|
||||
v-if="task.type === 'daily' || task.type === 'todo'"
|
||||
class="left-control d-flex justify-content-center"
|
||||
:class="[{'control-bottom-box': this.task.group.id, 'control-top-box': approvalsClass}, controlClass.bg]"
|
||||
:class="[{
|
||||
'control-bottom-box': task.group.id,
|
||||
'control-top-box': approvalsClass}, controlClass.bg]"
|
||||
>
|
||||
<div
|
||||
class="task-control daily-todo-control"
|
||||
@@ -50,7 +55,7 @@
|
||||
@click="isUser ? score(task.completed ? 'down' : 'up') : null"
|
||||
>
|
||||
<div
|
||||
v-if="this.task.group.id && !isUser && !task.completed"
|
||||
v-if="task.group.id && !isUser && !task.completed"
|
||||
class="svg-icon lock"
|
||||
:class="controlClass.icon"
|
||||
v-html="icons.lock"
|
||||
@@ -161,7 +166,8 @@
|
||||
<div class="d-inline-flex">
|
||||
<div
|
||||
v-if="isUser"
|
||||
v-b-tooltip.hover.bottom="$t(`${task.collapseChecklist ? 'expand': 'collapse'}Checklist`)"
|
||||
v-b-tooltip.hover.bottom="$t(`${task.collapseChecklist
|
||||
? 'expand': 'collapse'}Checklist`)"
|
||||
class="collapse-checklist d-flex align-items-center expand-toggle"
|
||||
:class="{open: !task.collapseChecklist}"
|
||||
@click="collapseChecklist(task)"
|
||||
@@ -173,12 +179,15 @@
|
||||
<span>{{ checklistProgress }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="item in task.checklist"
|
||||
v-if="!task.collapseChecklist"
|
||||
:key="item.id"
|
||||
class="custom-control custom-checkbox checklist-item"
|
||||
:class="{'checklist-item-done': item.completed}"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<input
|
||||
:id="`checklist-${item.id}-${random}`"
|
||||
class="custom-control-input"
|
||||
@@ -277,6 +286,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-for="tag in getTagsFor(task)"
|
||||
:key="tag"
|
||||
v-markdown="tag"
|
||||
class="tag-label"
|
||||
></div>
|
||||
@@ -290,7 +300,9 @@
|
||||
<div
|
||||
v-if="task.type === 'habit'"
|
||||
class="right-control d-flex align-items-center justify-content-center"
|
||||
:class="[{'control-bottom-box': this.task.group.id, 'control-top-box': approvalsClass}, controlClass.down.bg]"
|
||||
:class="[{
|
||||
'control-bottom-box': task.group.id,
|
||||
'control-top-box': approvalsClass}, controlClass.down.bg]"
|
||||
>
|
||||
<div
|
||||
class="task-control habit-control"
|
||||
@@ -298,7 +310,7 @@
|
||||
@click="(isUser && task.down) ? score('down') : null"
|
||||
>
|
||||
<div
|
||||
v-if="this.task.group.id && !isUser"
|
||||
v-if="task.group.id && !isUser"
|
||||
class="svg-icon lock"
|
||||
:class="controlClass.down.icon"
|
||||
v-html="icons.lock"
|
||||
@@ -335,6 +347,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- eslint-disable max-len -->
|
||||
<style lang="scss" scoped>
|
||||
@import '~@/assets/scss/colors.scss';
|
||||
|
||||
@@ -769,7 +782,7 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- eslint-enable max-len -->
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
@@ -992,7 +1005,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (this.task.type) {
|
||||
switch (this.task.type) { // eslint-disable-line default-case
|
||||
case 'habit':
|
||||
this.$root.$emit('playSound', direction === 'up' ? 'Plus_Habit' : 'Minus_Habit');
|
||||
break;
|
||||
@@ -1010,7 +1023,8 @@ export default {
|
||||
|
||||
Analytics.updateUser();
|
||||
const response = await axios.post(`/api/v4/tasks/${task._id}/score/${direction}`);
|
||||
const tmp = response.data.data._tmp || {}; // used to notify drops, critical hits and other bonuses
|
||||
// used to notify drops, critical hits and other bonuses
|
||||
const tmp = response.data.data._tmp || {};
|
||||
const { crit } = tmp;
|
||||
const { drop } = tmp;
|
||||
const { quest } = tmp;
|
||||
@@ -1025,7 +1039,7 @@ export default {
|
||||
if (quest.progressDelta && userQuest.boss) {
|
||||
this.quest('questDamage', quest.progressDelta.toFixed(1));
|
||||
} else if (quest.collection && userQuest.collect) {
|
||||
user.party.quest.progress.collectedItems++;
|
||||
user.party.quest.progress.collectedItems += 1;
|
||||
this.quest('questCollection', quest.collection);
|
||||
}
|
||||
}
|
||||
@@ -1052,7 +1066,7 @@ export default {
|
||||
if (!user.items[type][drop.key]) {
|
||||
Vue.set(user, `items.${type}.${drop.key}`, 0);
|
||||
}
|
||||
user.items[type][drop.key]++;
|
||||
user.items[type][drop.key] += 1;
|
||||
}
|
||||
|
||||
if (drop.type === 'HatchingPotion') {
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="(item, $index) in checklist"
|
||||
:key="item.id"
|
||||
class="inline-edit-input-group checklist-group input-group"
|
||||
>
|
||||
<span class="grippy"></span>
|
||||
@@ -455,6 +456,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="tagName in truncatedSelectedTags"
|
||||
:key="tagName"
|
||||
v-markdown="tagName"
|
||||
class="category-label"
|
||||
:title="tagName"
|
||||
@@ -512,7 +514,8 @@
|
||||
:text="$t(sharedCompletion)"
|
||||
>
|
||||
<b-dropdown-item
|
||||
v-for="completionOption in ['recurringCompletion', 'singleCompletion', 'allAssignedCompletion']"
|
||||
v-for="completionOption in [
|
||||
'recurringCompletion', 'singleCompletion', 'allAssignedCompletion']"
|
||||
:key="completionOption"
|
||||
:class="{active: sharedCompletion === completionOption}"
|
||||
@click="sharedCompletion = completionOption"
|
||||
@@ -541,6 +544,7 @@
|
||||
>
|
||||
<span
|
||||
v-for="memberId in assignedMembers"
|
||||
:key="memberId"
|
||||
class="mr-1"
|
||||
>{{ memberNamesById[memberId] }}</span>
|
||||
</span>
|
||||
@@ -640,7 +644,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="task.type === 'habit' && isUserTask && purpose === 'edit' && (task.up || task.down)"
|
||||
v-if="task.type === 'habit'
|
||||
&& isUserTask && purpose === 'edit' && (task.up || task.down)"
|
||||
class="option"
|
||||
>
|
||||
<div class="form-group">
|
||||
@@ -692,11 +697,17 @@
|
||||
<!--.option(v-if="isUserTask && task.type !== 'reward'").form-group
|
||||
label(v-once)
|
||||
span.float-left {{ $t('attributeAllocation') }}
|
||||
.svg-icon.info-icon(v-html="icons.information", v-b-tooltip.hover.righttop.html="$t('attributeAllocationHelp')")
|
||||
.svg-icon.info-icon(v-html="ic
|
||||
ons.information", v-b-tooltip.hover.righttop.html="$t('attributeAllocationHelp')")
|
||||
.attributes
|
||||
.custom-control.custom-radio.custom-control-inline(v-for="attr in ATTRIBUTES", :key="attr")
|
||||
input.custom-control-input(:id="`attribute-${attr}`", type="radio", :value="attr", v-model="task.attribute", :disabled="user.preferences.allocationMode !== 'taskbased'")
|
||||
label.custom-control-label.attr-description(:for="`attribute-${attr}`", v-once, v-b-popover.hover="$t(`${attr}Text`)") {{ $t(attributesStrings[attr]) }}-->
|
||||
.custom-control.custom-radio.custom-
|
||||
control-inline(v-for="attr in ATTRIBUTES", :key="attr")
|
||||
input.custom-control-input(:id="`attribute-${a
|
||||
ttr}`", type="radio", :value="attr", v-model="task.attribute", :disabled="us
|
||||
er.preferences.allocationMode !== 'taskbased'")
|
||||
label.custom-control-label.attr-
|
||||
description(:for="`attribute-${attr}`", v-once, v-b-pop
|
||||
over.hover="$t(`${attr}Text`)") {{ $t(attributesStrings[attr]) }}-->
|
||||
</div>
|
||||
</b-collapse>
|
||||
</div>
|
||||
|
||||
@@ -35,12 +35,14 @@
|
||||
class="filter-panel"
|
||||
@mouseleave="checkMouseOver"
|
||||
>
|
||||
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
|
||||
<div
|
||||
v-for="tagsType in tagsByType"
|
||||
v-if="tagsType.tags.length > 0 || tagsType.key === 'tags'"
|
||||
:key="tagsType.key"
|
||||
class="tags-category d-flex"
|
||||
>
|
||||
<!-- eslint-enable vue/no-use-v-if-with-v-for -->
|
||||
<div class="tags-header">
|
||||
<strong v-once>{{ $t(tagsType.key) }}</strong>
|
||||
<a
|
||||
@@ -62,6 +64,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="(tag, tagIndex) in tagsSnap[tagsType.key]"
|
||||
:key="tag.id"
|
||||
class="col-6"
|
||||
>
|
||||
<div class="inline-edit-input-group tag-edit-item input-group">
|
||||
@@ -99,6 +102,7 @@
|
||||
<template v-if="editingTags && tagsType.key === 'challenges'">
|
||||
<div
|
||||
v-for="(tag, tagIndex) in tagsSnap[tagsType.key]"
|
||||
:key="tag.id"
|
||||
class="col-6"
|
||||
>
|
||||
<div class="inline-edit-input-group tag-edit-item input-group">
|
||||
@@ -121,7 +125,8 @@
|
||||
</template>
|
||||
<template v-if="!editingTags || tagsType.key === 'groups'">
|
||||
<div
|
||||
v-for="(tag, tagIndex) in tagsType.tags"
|
||||
v-for="(tag) in tagsType.tags"
|
||||
:key="tag.id"
|
||||
class="col-6"
|
||||
>
|
||||
<div class="custom-control custom-checkbox">
|
||||
@@ -414,13 +419,10 @@ import { mapState, mapActions } from '@/libs/store';
|
||||
import taskDefaults from '@/../../common/script/libs/taskDefaults';
|
||||
import brokenTaskModal from './brokenTaskModal';
|
||||
|
||||
import Item from '@/components/inventory/item.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TaskColumn,
|
||||
TaskModal,
|
||||
Item,
|
||||
spells,
|
||||
brokenTaskModal,
|
||||
draggable,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<ul class="drawer-tab-container">
|
||||
<li
|
||||
v-for="(tab, index) in tabs"
|
||||
:key="tab.key"
|
||||
class="drawer-tab"
|
||||
>
|
||||
<a
|
||||
|
||||
@@ -31,9 +31,12 @@
|
||||
@resized="currentWidth = $event.width - 120"
|
||||
>
|
||||
<div class="items items-one-line">
|
||||
<template v-for="item in showItems">
|
||||
<template
|
||||
v-for="item in showItems"
|
||||
>
|
||||
<div
|
||||
v-if="shouldAddVerticalLine(item)"
|
||||
:key="item.key"
|
||||
class="vertical-divider"
|
||||
:style="dividerMargins"
|
||||
></div>
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
<div class="standard-page container">
|
||||
<div
|
||||
v-for="(category, key) in achievements"
|
||||
:key="key"
|
||||
class="row"
|
||||
>
|
||||
<h2 class="col-12">
|
||||
{{ $t(key+'Achievs') }}
|
||||
</h2>
|
||||
<div
|
||||
v-for="achievment in category.achievements"
|
||||
v-for="(achievment, achievmentKey) in category.achievements"
|
||||
:key="achievmentKey"
|
||||
class="col-3 text-center"
|
||||
>
|
||||
<div
|
||||
@@ -46,13 +48,19 @@
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<h2>Challeges Won</h2>
|
||||
<div v-for="chal in user.achievements.challenges">
|
||||
<div
|
||||
v-for="chal in user.achievements.challenges"
|
||||
:key="chal"
|
||||
>
|
||||
<span>{{ chal }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<h2>Quests Completed</h2>
|
||||
<div v-for="(value, key) in user.achievements.quests">
|
||||
<div
|
||||
v-for="(value, key) in user.achievements.quests"
|
||||
:key="key"
|
||||
>
|
||||
<span>{{ content.quests[k].text() }}</span>
|
||||
<span>{{ value }}</span>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<toggle-switch
|
||||
class="float-right"
|
||||
:label="optTextSet.switchDescription"
|
||||
:checked="!this.user.inbox.optOut"
|
||||
:checked="!user.inbox.optOut"
|
||||
:hover-text="optTextSet.popoverText"
|
||||
@change="toggleOpt()"
|
||||
/>
|
||||
@@ -80,6 +80,7 @@
|
||||
>
|
||||
<div
|
||||
v-for="conversation in filtersConversations"
|
||||
:key="conversation.key"
|
||||
class="conversation"
|
||||
:class="{active: selectedConversation.key === conversation.key}"
|
||||
@click="selectConversation(conversation.key)"
|
||||
@@ -103,7 +104,8 @@
|
||||
<div
|
||||
class="messagePreview"
|
||||
>
|
||||
{{ conversation.lastMessageText ? removeTags(parseMarkdown(conversation.lastMessageText)) : '' }}
|
||||
{{ conversation.lastMessageText
|
||||
? removeTags(parseMarkdown(conversation.lastMessageText)) : '' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -421,12 +423,14 @@ export default {
|
||||
}
|
||||
// Create conversation objects
|
||||
const convos = [];
|
||||
for (const key in inboxGroup) {
|
||||
for (const key of Object.keys(inboxGroup)) {
|
||||
const recentMessage = inboxGroup[key][0];
|
||||
|
||||
const convoModel = {
|
||||
key: recentMessage.uuid,
|
||||
name: recentMessage.user, // Handles case where from user sent the only message or the to user sent the only message
|
||||
// Handles case where from user sent
|
||||
// the only message or the to user sent the only message
|
||||
name: recentMessage.user,
|
||||
username: !recentMessage.text ? recentMessage.username : recentMessage.toUserName,
|
||||
date: recentMessage.timestamp,
|
||||
lastMessageText: recentMessage.text,
|
||||
@@ -439,14 +443,15 @@ export default {
|
||||
|
||||
return convos;
|
||||
},
|
||||
// Separate from selectedConversation which is not computed 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.messagesByConversation[selectedConversationKey];
|
||||
this.messages = selectedConversation || []; // eslint-disable-line vue/no-side-effects-in-computed-properties
|
||||
this.messages = selectedConversation || []; // eslint-disable-line vue/no-side-effects-in-computed-properties, max-len
|
||||
|
||||
const ordered = orderBy(this.messages, [m => m.timestamp], ['asc']);
|
||||
|
||||
@@ -462,7 +467,10 @@ export default {
|
||||
|
||||
const filtered = subScribeToUpdate && !this.search
|
||||
? this.conversations
|
||||
: filter(this.conversations, conversation => conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1);
|
||||
: filter(
|
||||
this.conversations,
|
||||
conversation => conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1,
|
||||
);
|
||||
|
||||
const ordered = orderBy(filtered, [o => moment(o.date).toDate()], ['desc']);
|
||||
|
||||
@@ -677,9 +685,9 @@ export default {
|
||||
const res = await axios.get(requestUrl);
|
||||
const loadedMessages = res.data.data;
|
||||
|
||||
this.messagesByConversation[this.selectedConversation.key] = this.messagesByConversation[this.selectedConversation.key] || [];
|
||||
this.messagesByConversation[this.selectedConversation.key] = this.messagesByConversation[this.selectedConversation.key] || []; // eslint-disable-line max-len
|
||||
const loadedMessagesToAdd = loadedMessages
|
||||
.filter(m => this.messagesByConversation[this.selectedConversation.key].findIndex(mI => mI.id === m.id) === -1);
|
||||
.filter(m => this.messagesByConversation[this.selectedConversation.key].findIndex(mI => mI.id === m.id) === -1); // eslint-disable-line max-len
|
||||
this.messagesByConversation[this.selectedConversation.key].push(...loadedMessagesToAdd);
|
||||
|
||||
// only show the load more Button if the max count was returned
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
></div>
|
||||
</button>
|
||||
<button
|
||||
v-if="user._id !== this.userLoggedIn._id && userLoggedIn.inbox.blocks.indexOf(user._id) === -1"
|
||||
v-if="user._id !== userLoggedIn._id && userLoggedIn.inbox.blocks.indexOf(user._id) === -1"
|
||||
v-b-tooltip.hover.right="$t('blockWarning')"
|
||||
class="btn btn-secondary remove-icon"
|
||||
@click="blockUser()"
|
||||
@@ -37,7 +37,7 @@
|
||||
></div>
|
||||
</button>
|
||||
<button
|
||||
v-if="user._id !== this.userLoggedIn._id && userLoggedIn.inbox.blocks.indexOf(user._id) !== -1"
|
||||
v-if="user._id !== userLoggedIn._id && userLoggedIn.inbox.blocks.indexOf(user._id) !== -1"
|
||||
v-b-tooltip.hover.right="$t('unblock')"
|
||||
class="btn btn-secondary positive-icon"
|
||||
@click="unblockUser()"
|
||||
@@ -48,7 +48,7 @@
|
||||
></div>
|
||||
</button>
|
||||
<button
|
||||
v-if="this.userLoggedIn.contributor.admin"
|
||||
v-if="userLoggedIn.contributor.admin"
|
||||
v-b-tooltip.hover.right="'Admin - Toggle Tools'"
|
||||
class="btn btn-secondary positive-icon"
|
||||
@click="toggleAdminTools()"
|
||||
@@ -60,7 +60,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-if="this.userLoggedIn.contributor.admin && adminToolsLoaded"
|
||||
v-if="userLoggedIn.contributor.admin && adminToolsLoaded"
|
||||
class="row admin-profile-actions"
|
||||
>
|
||||
<div class="col-12 text-right">
|
||||
@@ -299,22 +299,24 @@
|
||||
>
|
||||
<div
|
||||
v-for="(category, key) in achievements"
|
||||
:key="key"
|
||||
class="row"
|
||||
>
|
||||
<h2 class="col-12 text-center">
|
||||
{{ $t(key+'Achievs') }}
|
||||
</h2>
|
||||
<div
|
||||
v-for="(achievement, key) in category.achievements"
|
||||
v-for="(achievement, achievKey) in category.achievements"
|
||||
:key="achievKey"
|
||||
class="col-12 col-md-3 text-center"
|
||||
>
|
||||
<div
|
||||
:id="key + '-achievement'"
|
||||
:id="achievKey + '-achievement'"
|
||||
class="box achievement-container"
|
||||
:class="{'achievement-unearned': !achievement.earned}"
|
||||
>
|
||||
<b-popover
|
||||
:target="'#' + key + '-achievement'"
|
||||
:target="'#' + achievKey + '-achievement'"
|
||||
triggers="hover"
|
||||
placement="top"
|
||||
>
|
||||
@@ -355,7 +357,10 @@
|
||||
<h2 class="text-center">
|
||||
{{ $t('challengesWon') }}
|
||||
</h2>
|
||||
<div v-for="chal in user.achievements.challenges">
|
||||
<div
|
||||
v-for="chal in user.achievements.challenges"
|
||||
:key="chal"
|
||||
>
|
||||
<span v-markdown="chal"></span>
|
||||
<hr>
|
||||
</div>
|
||||
@@ -368,7 +373,10 @@
|
||||
<h2 class="text-center">
|
||||
{{ $t('questsCompleted') }}
|
||||
</h2>
|
||||
<div v-for="(value, key) in user.achievements.quests">
|
||||
<div
|
||||
v-for="(value, key) in user.achievements.quests"
|
||||
:key="key"
|
||||
>
|
||||
<span>{{ content.quests[key].text() }} ({{ value }})</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -781,7 +789,7 @@ export default {
|
||||
},
|
||||
selectPage (page) {
|
||||
this.selectedPage = page;
|
||||
history.replaceState(null, null, '');
|
||||
window.history.replaceState(null, null, '');
|
||||
},
|
||||
sendMessage () {
|
||||
this.$root.$emit('habitica::new-inbox-message', {
|
||||
@@ -810,7 +818,8 @@ export default {
|
||||
if (!currentLoginDay) return 0;
|
||||
const previousRewardDay = currentLoginDay.prevRewardKey;
|
||||
const { nextRewardAt } = currentLoginDay;
|
||||
return ((this.user.loginIncentives - previousRewardDay) / (nextRewardAt - previousRewardDay)) * 100;
|
||||
return ((this.user.loginIncentives - previousRewardDay)
|
||||
/ (nextRewardAt - previousRewardDay)) * 100;
|
||||
},
|
||||
save () {
|
||||
const values = {};
|
||||
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onShown () {
|
||||
history.pushState('', null, this.path);
|
||||
window.history.pushState('', null, this.path);
|
||||
},
|
||||
onHidden () {
|
||||
if (this.$route.path !== window.location.pathname) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<div class="well">
|
||||
<div
|
||||
v-for="(label, key) in equipTypes"
|
||||
:key="key"
|
||||
class="col-12 col-md-4 item-wrapper"
|
||||
>
|
||||
<div
|
||||
@@ -22,7 +23,8 @@
|
||||
<div :class="`shop_${equippedItems[key]}`"></div>
|
||||
</div>
|
||||
<b-popover
|
||||
v-if="label !== 'skip' && equippedItems[key] && equippedItems[key].indexOf('base_0') === -1"
|
||||
v-if="label !== 'skip'
|
||||
&& equippedItems[key] && equippedItems[key].indexOf('base_0') === -1"
|
||||
:target="key"
|
||||
triggers="hover"
|
||||
:placement="'bottom'"
|
||||
@@ -51,6 +53,7 @@
|
||||
<!-- Use similar for loop for costume items, except show background if label is 'skip'.-->
|
||||
<div
|
||||
v-for="(label, key) in equipTypes"
|
||||
:key="key"
|
||||
class="col-12 col-md-4 item-wrapper"
|
||||
>
|
||||
<!-- Append a "C" to the key name since HTML IDs have to be unique.-->
|
||||
@@ -72,7 +75,8 @@
|
||||
<div :class="'icon_background_' + user.preferences.background"></div>
|
||||
</div>
|
||||
<b-popover
|
||||
v-if="label !== 'skip' && costumeItems[key] && costumeItems[key].indexOf('base_0') === -1"
|
||||
v-if="label !== 'skip'
|
||||
&& costumeItems[key] && costumeItems[key].indexOf('base_0') === -1"
|
||||
:target="key + 'C'"
|
||||
triggers="hover"
|
||||
:placement="'bottom'"
|
||||
@@ -177,6 +181,7 @@
|
||||
</h2>
|
||||
<div
|
||||
v-for="(statInfo, stat) in stats"
|
||||
:key="stat"
|
||||
class="col-12 col-md-6"
|
||||
>
|
||||
<div class="row col-12 stats-column">
|
||||
@@ -257,6 +262,7 @@
|
||||
<div class="row">
|
||||
<div
|
||||
v-for="(statInfo, stat) in allocateStatsList"
|
||||
:key="stat"
|
||||
class="col-12 col-md-3"
|
||||
>
|
||||
<div class="box white row col-12">
|
||||
@@ -300,7 +306,7 @@
|
||||
:disabled="loading"
|
||||
@click="saveAttributes()"
|
||||
>
|
||||
{{ this.loading ? $t('loading') : $t('save') }}
|
||||
{{ loading ? $t('loading') : $t('save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -424,21 +430,23 @@ export default {
|
||||
},
|
||||
formatAnimal (animalName, type) {
|
||||
if (type === 'pet') {
|
||||
if (Content.petInfo.hasOwnProperty(animalName)) {
|
||||
if (Content.petInfo[animalName]) {
|
||||
return Content.petInfo[animalName].text();
|
||||
}
|
||||
return this.$t('noActivePet');
|
||||
} if (type === 'mount') {
|
||||
if (Content.mountInfo.hasOwnProperty(animalName)) {
|
||||
if (Content.mountInfo[animalName]) {
|
||||
return Content.mountInfo[animalName].text();
|
||||
}
|
||||
return this.$t('noActiveMount');
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
formatBackground (background) {
|
||||
const bg = Content.appearances.background;
|
||||
|
||||
if (bg.hasOwnProperty(background)) {
|
||||
if (bg[background]) {
|
||||
return `${bg[background].text()} (${this.$t(bg[background].set.text)})`;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user