mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Merge develop to release (#9115)
* Some random quick (#9111) * Switch group button directions * Allowed admins to export challenges * Added scoping to some stable styles * Fixed challenge cloning * Tasks tags (#9112) * Added auto apply and exit * Add challenge tag editing * Fixed lint * Skill fixes (#9113) * Added local storage setting for spell drawer * Added new spell styles * Fixed typo * Reset local creds if access is denied (#9114)
This commit is contained in:
@@ -144,6 +144,16 @@ export default {
|
|||||||
return response;
|
return response;
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
if (error.response.status >= 400) {
|
if (error.response.status >= 400) {
|
||||||
|
// Check for conditions to reset the user auth
|
||||||
|
const invalidUserMessage = [this.$t('invalidCredentials'), 'Missing authentication headers.'];
|
||||||
|
if (invalidUserMessage.indexOf(error.response.data.message) !== -1) {
|
||||||
|
localStorage.removeItem('habit-mobile-settings');
|
||||||
|
localStorage.removeItem('hello');
|
||||||
|
this.$store.state.isUserLoggedIn = false;
|
||||||
|
window.location.href = '/static/home';
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
// Don't show errors from getting user details. These users have delete their account,
|
// Don't show errors from getting user details. These users have delete their account,
|
||||||
// but their chat message still exists.
|
// but their chat message still exists.
|
||||||
let configExists = Boolean(error.response) && Boolean(error.response.config);
|
let configExists = Boolean(error.response) && Boolean(error.response.config);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
button.btn.btn-secondary(v-once, @click='edit()') {{$t('editChallenge')}}
|
button.btn.btn-secondary(v-once, @click='edit()') {{$t('editChallenge')}}
|
||||||
div(v-if='isLeader')
|
div(v-if='isLeader')
|
||||||
button.btn.btn-danger(v-once, @click='closeChallenge()') {{$t('endChallenge')}}
|
button.btn.btn-danger(v-once, @click='closeChallenge()') {{$t('endChallenge')}}
|
||||||
div(v-if='isLeader')
|
div(v-if='isLeader || isAdmin')
|
||||||
button.btn.btn-secondary(v-once, @click='exportChallengeCsv()') {{$t('exportChallengeCsv')}}
|
button.btn.btn-secondary(v-once, @click='exportChallengeCsv()') {{$t('exportChallengeCsv')}}
|
||||||
div(v-if='isLeader')
|
div(v-if='isLeader')
|
||||||
button.btn.btn-secondary(v-once, @click='cloneChallenge()') {{$t('clone')}}
|
button.btn.btn-secondary(v-once, @click='cloneChallenge()') {{$t('clone')}}
|
||||||
@@ -246,6 +246,9 @@ export default {
|
|||||||
if (!this.challenge.leader) return false;
|
if (!this.challenge.leader) return false;
|
||||||
return this.user._id === this.challenge.leader._id;
|
return this.user._id === this.challenge.leader._id;
|
||||||
},
|
},
|
||||||
|
isAdmin () {
|
||||||
|
return Boolean(this.user.contributor.admin);
|
||||||
|
},
|
||||||
canJoin () {
|
canJoin () {
|
||||||
return !this.isMember;
|
return !this.isMember;
|
||||||
},
|
},
|
||||||
@@ -403,6 +406,7 @@ export default {
|
|||||||
cloneChallenge () {
|
cloneChallenge () {
|
||||||
this.cloning = true;
|
this.cloning = true;
|
||||||
this.$store.state.challengeOptions.tasksToClone = this.tasksByType;
|
this.$store.state.challengeOptions.tasksToClone = this.tasksByType;
|
||||||
|
this.$store.state.challengeOptions.workingChallenge = Object.assign({}, this.$store.state.challengeOptions.workingChallenge, this.challenge);
|
||||||
this.$root.$emit('show::modal', 'challenge-modal');
|
this.$root.$emit('show::modal', 'challenge-modal');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,11 +31,13 @@
|
|||||||
.row.new-message-row
|
.row.new-message-row
|
||||||
textarea(:placeholder="!isParty ? $t('chatPlaceholder') : $t('partyChatPlaceholder')", v-model='newMessage', @keydown='updateCarretPosition')
|
textarea(:placeholder="!isParty ? $t('chatPlaceholder') : $t('partyChatPlaceholder')", v-model='newMessage', @keydown='updateCarretPosition')
|
||||||
autocomplete(:text='newMessage', v-on:select="selectedAutocomplete", :coords='coords', :chat='group.chat')
|
autocomplete(:text='newMessage', v-on:select="selectedAutocomplete", :coords='coords', :chat='group.chat')
|
||||||
button.btn.btn-secondary.send-chat.float-left(v-once, @click='sendMessage()') {{ $t('send') }}
|
|
||||||
.row
|
.row
|
||||||
.col-6
|
.col-6
|
||||||
button.btn.btn-secondary.float-left.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }}
|
button.btn.btn-secondary.float-left.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }}
|
||||||
button.btn.btn-secondary.float-left(v-once, @click='reverseChat()') {{ $t('reverseChat') }}
|
button.btn.btn-secondary.float-left(v-once, @click='reverseChat()') {{ $t('reverseChat') }}
|
||||||
|
.col-6
|
||||||
|
button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }}
|
||||||
|
|
||||||
.row.community-guidelines(v-if='!communityGuidelinesAccepted')
|
.row.community-guidelines(v-if='!communityGuidelinesAccepted')
|
||||||
div.col-8(v-once, v-html="$t('communityGuidelinesIntro')")
|
div.col-8(v-once, v-html="$t('communityGuidelinesIntro')")
|
||||||
@@ -301,13 +303,6 @@
|
|||||||
.new-message-row {
|
.new-message-row {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-chat {
|
|
||||||
z-index: 10;
|
|
||||||
position: absolute;
|
|
||||||
right: 1em;
|
|
||||||
bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-up .svg-icon, .toggle-down .svg-icon {
|
.toggle-up .svg-icon, .toggle-down .svg-icon {
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
|
|
||||||
.row
|
.row
|
||||||
.col-6
|
.col-6
|
||||||
button.btn.btn-secondary.send-chat.float-left(v-once, @click='sendMessage()') {{ $t('send') }}
|
button.btn.btn-secondary.float-left.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }}
|
||||||
|
button.btn.btn-secondary.float-left(v-once, @click='reverseChat()') {{ $t('reverseChat') }}
|
||||||
.col-6
|
.col-6
|
||||||
button.btn.btn-secondary.float-right.fetch(v-once, @click='fetchRecentMessages()') {{ $t('fetchRecentMessages') }}
|
button.btn.btn-secondary.send-chat.float-right(v-once, @click='sendMessage()') {{ $t('send') }}
|
||||||
button.btn.btn-secondary.float-right(v-once, @click='reverseChat()') {{ $t('reverseChat') }}
|
|
||||||
|
|
||||||
.row.community-guidelines(v-if='!communityGuidelinesAccepted')
|
.row.community-guidelines(v-if='!communityGuidelinesAccepted')
|
||||||
div.col-8(v-once, v-html="$t('communityGuidelinesIntro')")
|
div.col-8(v-once, v-html="$t('communityGuidelinesIntro')")
|
||||||
|
|||||||
@@ -248,6 +248,22 @@
|
|||||||
div.popover-content {{ $t('clickOnPetToFeed', {foodName: currentDraggingFood.text() }) }}
|
div.popover-content {{ $t('clickOnPetToFeed', {foodName: currentDraggingFood.text() }) }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
.group {
|
||||||
|
height: 130px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pet-row {
|
||||||
|
max-width: 100%;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
margin-right: .5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '~client/assets/scss/colors.scss';
|
@import '~client/assets/scss/colors.scss';
|
||||||
@import '~client/assets/scss/modal.scss';
|
@import '~client/assets/scss/modal.scss';
|
||||||
@@ -274,20 +290,6 @@
|
|||||||
top: -16px !important;
|
top: -16px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.group {
|
|
||||||
height: 130px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pet-row {
|
|
||||||
max-width: 100%;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
margin-right: .5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hatchablePopover {
|
.hatchablePopover {
|
||||||
width: 180px
|
width: 180px
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,16 +21,13 @@ div(v-if='user.stats.lvl > 10')
|
|||||||
@click='castStart(skill)',
|
@click='castStart(skill)',
|
||||||
v-for='(skill, key) in spells[user.stats.class]',
|
v-for='(skill, key) in spells[user.stats.class]',
|
||||||
v-if='user.stats.lvl >= skill.lvl',
|
v-if='user.stats.lvl >= skill.lvl',
|
||||||
popover-trigger='mouseenter',
|
v-b-popover.hover.auto='skill.notes()')
|
||||||
popover-placement='top',
|
|
||||||
:popover='skillNotes(skill)')
|
|
||||||
.spell.col-12.row
|
.spell.col-12.row
|
||||||
.col-8.details
|
.col-8.details
|
||||||
a(:class='{"disabled": spellDisabled(key)}')
|
a(:class='{"disabled": spellDisabled(key)}')
|
||||||
p.title {{skill.text()}}
|
div.img(:class='`shop_${skill.key} shop-sprite item-img`')
|
||||||
p.notes {{skill.notes()}}
|
span.title {{skill.text()}}
|
||||||
.col-4.mana
|
.col-4.mana
|
||||||
.img(:class='`shop_${skill.key} shop-sprite item-img`')
|
|
||||||
.mana-text
|
.mana-text
|
||||||
.svg-icon(v-html="icons.mana")
|
.svg-icon(v-html="icons.mana")
|
||||||
div {{skill.mana}}
|
div {{skill.mana}}
|
||||||
@@ -52,23 +49,33 @@ div(v-if='user.stats.lvl > 10')
|
|||||||
|
|
||||||
.spell:hover {
|
.spell:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
border: solid 2px #50b5e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spell {
|
.spell {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
border: solid 2px transparent;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||||
border-radius: 2px;
|
border-radius: 1000px;
|
||||||
color: #4e4a57;
|
color: #4e4a57;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
.details {
|
.details {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-top: .5em;
|
padding-top: .5em;
|
||||||
|
|
||||||
p {
|
.img {
|
||||||
margin-bottom: .5em;
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 50%;
|
||||||
|
padding-bottom: .7em;
|
||||||
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notes {
|
.notes {
|
||||||
@@ -83,6 +90,7 @@ div(v-if='user.stats.lvl > 10')
|
|||||||
|
|
||||||
.mana-text {
|
.mana-text {
|
||||||
margin-bottom: .2em;
|
margin-bottom: .2em;
|
||||||
|
padding-top: 1.1em;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -142,6 +150,7 @@ div(v-if='user.stats.lvl > 10')
|
|||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import isArray from 'lodash/isArray';
|
import isArray from 'lodash/isArray';
|
||||||
|
import bPopover from 'bootstrap-vue/lib/directives/popover';
|
||||||
|
|
||||||
import spells from '../../../common/script/content/spells';
|
import spells from '../../../common/script/content/spells';
|
||||||
|
|
||||||
@@ -152,6 +161,7 @@ import MouseMoveDirective from 'client/directives/mouseposition.directive';
|
|||||||
|
|
||||||
import mana from 'assets/svg/mana.svg';
|
import mana from 'assets/svg/mana.svg';
|
||||||
import quests from 'common/script/content/quests';
|
import quests from 'common/script/content/quests';
|
||||||
|
import { CONSTANTS, setLocalSetting, getLocalSetting } from 'client/libs/userlocalManager';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [notifications],
|
mixins: [notifications],
|
||||||
@@ -160,6 +170,7 @@ export default {
|
|||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
mousePosition: MouseMoveDirective,
|
mousePosition: MouseMoveDirective,
|
||||||
|
bPopover,
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -183,6 +194,11 @@ export default {
|
|||||||
if (keyEvent.keyCode !== 27) return;
|
if (keyEvent.keyCode !== 27) return;
|
||||||
this.castCancel();
|
this.castCancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const spellDrawerState = getLocalSetting(CONSTANTS.keyConstants.SPELL_DRAWER_STATE);
|
||||||
|
if (spellDrawerState === CONSTANTS.valueConstants.SPELL_DRAWER_CLOSED) {
|
||||||
|
this.$store.state.spellOptions.spellDrawOpen = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({user: 'user.data'}),
|
...mapState({user: 'user.data'}),
|
||||||
@@ -191,8 +207,15 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
drawerToggled (openChanged) {
|
drawerToggled (newState) {
|
||||||
this.$store.state.spellOptions.spellDrawOpen = openChanged;
|
this.$store.state.spellOptions.spellDrawOpen = newState;
|
||||||
|
|
||||||
|
if (newState) {
|
||||||
|
setLocalSetting(CONSTANTS.keyConstants.SPELL_DRAWER_STATE, CONSTANTS.valueConstants.SPELL_DRAWER_OPEN);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLocalSetting(CONSTANTS.keyConstants.SPELL_DRAWER_STATE, CONSTANTS.valueConstants.SPELL_DRAWER_CLOSED);
|
||||||
},
|
},
|
||||||
spellDisabled (skill) {
|
spellDisabled (skill) {
|
||||||
if (skill === 'frost' && this.user.stats.buffs.streaks) {
|
if (skill === 'frost' && this.user.stats.buffs.streaks) {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
.col-4.offset-4
|
.col-4.offset-4
|
||||||
.input-group
|
.input-group
|
||||||
input.form-control.input-search(type="text", :placeholder="$t('search')", v-model="searchText")
|
input.form-control.input-search(type="text", :placeholder="$t('search')", v-model="searchText")
|
||||||
.filter-panel(v-if="isFilterPanelOpen")
|
.filter-panel(v-if="isFilterPanelOpen", v-on:mouseleave="checkMouseOver")
|
||||||
.tags-category.d-flex(
|
.tags-category.d-flex(
|
||||||
v-for="tagsType in tagsByType",
|
v-for="tagsType in tagsByType",
|
||||||
v-if="tagsType.tags.length > 0 || tagsType.key === 'tags'",
|
v-if="tagsType.tags.length > 0 || tagsType.key === 'tags'",
|
||||||
@@ -19,17 +19,17 @@
|
|||||||
)
|
)
|
||||||
.tags-header
|
.tags-header
|
||||||
strong(v-once) {{ $t(tagsType.key) }}
|
strong(v-once) {{ $t(tagsType.key) }}
|
||||||
a.d-block(v-if="tagsType.key === 'tags' && !editingTags", @click="editTags()") {{ $t('editTags2') }}
|
a.d-block(v-if="tagsType.key !== 'groups' && !editingTags", @click="editTags(tagsType.key)") {{ $t('editTags2') }}
|
||||||
.tags-list.container
|
.tags-list.container
|
||||||
.row(:class="{'no-gutters': !editingTags}")
|
.row(:class="{'no-gutters': !editingTags}")
|
||||||
template(v-if="editingTags && tagsType.key === 'tags'")
|
template(v-if="editingTags && tagsType.key !== 'groups'")
|
||||||
.col-6(v-for="(tag, tagIndex) in tagsSnap")
|
.col-6(v-for="(tag, tagIndex) in tagsSnap[tagsType.key]")
|
||||||
.inline-edit-input-group.tag-edit-item.input-group
|
.inline-edit-input-group.tag-edit-item.input-group
|
||||||
input.tag-edit-input.inline-edit-input.form-control(type="text", v-model="tag.name")
|
input.tag-edit-input.inline-edit-input.form-control(type="text", v-model="tag.name")
|
||||||
span.input-group-btn(@click="removeTag(tagIndex)")
|
span.input-group-btn(@click="removeTag(tagIndex, tagsType.key)")
|
||||||
.svg-icon.destroy-icon(v-html="icons.destroy")
|
.svg-icon.destroy-icon(v-html="icons.destroy")
|
||||||
.col-6
|
.col-6(v-if="tagsType.key === 'tags'")
|
||||||
input.new-tag-item.edit-tag-item.inline-edit-input.form-control(type="text", :placeholder="$t('newTag')", @keydown.enter="addTag($event)", v-model="newTag")
|
input.new-tag-item.edit-tag-item.inline-edit-input.form-control(type="text", :placeholder="$t('newTag')", @keydown.enter="addTag($event, tagsType.key)", v-model="newTag")
|
||||||
template(v-else)
|
template(v-else)
|
||||||
.col-6(v-for="(tag, tagIndex) in tagsType.tags")
|
.col-6(v-for="(tag, tagIndex) in tagsType.tags")
|
||||||
label.custom-control.custom-checkbox
|
label.custom-control.custom-checkbox
|
||||||
@@ -50,7 +50,6 @@
|
|||||||
.float-left
|
.float-left
|
||||||
a.btn-filters-danger(@click="resetFilters()", v-once) {{ $t('resetFilters') }}
|
a.btn-filters-danger(@click="resetFilters()", v-once) {{ $t('resetFilters') }}
|
||||||
.float-right
|
.float-right
|
||||||
a.mr-3.btn-filters-primary(@click="applyFilters()", v-once) {{ $t('applyFilters') }}
|
|
||||||
a.btn-filters-secondary(@click="closeFilterPanel()", v-once) {{ $t('cancel') }}
|
a.btn-filters-secondary(@click="closeFilterPanel()", v-once) {{ $t('cancel') }}
|
||||||
span.input-group-btn
|
span.input-group-btn
|
||||||
button.btn.btn-secondary.filter-button(
|
button.btn.btn-secondary.filter-button(
|
||||||
@@ -322,7 +321,10 @@ export default {
|
|||||||
}),
|
}),
|
||||||
selectedTags: [],
|
selectedTags: [],
|
||||||
temporarilySelectedTags: [],
|
temporarilySelectedTags: [],
|
||||||
tagsSnap: null, // tags snapshot when being edited
|
tagsSnap: {
|
||||||
|
tags: [],
|
||||||
|
challenges: [],
|
||||||
|
}, // tags snapshot when being edited
|
||||||
editingTags: false,
|
editingTags: false,
|
||||||
newTag: null,
|
newTag: null,
|
||||||
editingTask: null,
|
editingTask: null,
|
||||||
@@ -368,26 +370,37 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({setUser: 'user:set'}),
|
...mapActions({setUser: 'user:set'}),
|
||||||
|
checkMouseOver: throttle(function throttleSearch () {
|
||||||
|
this.closeFilterPanel();
|
||||||
|
}, 250),
|
||||||
editTags () {
|
editTags () {
|
||||||
// clone the arrays being edited so that we can revert if needed
|
// clone the arrays being edited so that we can revert if needed
|
||||||
this.tagsSnap = this.tagsByType.user.tags.slice();
|
this.tagsSnap.tags = this.tagsByType.user.tags.slice();
|
||||||
|
this.tagsSnap.challenges = this.tagsByType.challenges.tags.slice();
|
||||||
this.editingTags = true;
|
this.editingTags = true;
|
||||||
},
|
},
|
||||||
addTag () {
|
addTag (eventObj, key) {
|
||||||
this.tagsSnap.push({id: uuid.v4(), name: this.newTag});
|
this.tagsSnap[key].push({id: uuid.v4(), name: this.newTag});
|
||||||
this.newTag = null;
|
this.newTag = null;
|
||||||
},
|
},
|
||||||
removeTag (index) {
|
removeTag (index, key) {
|
||||||
this.tagsSnap.splice(index, 1);
|
this.$delete(this.tagsSnap[key], index);
|
||||||
},
|
},
|
||||||
saveTags () {
|
saveTags () {
|
||||||
if (this.newTag) this.addTag();
|
if (this.newTag) this.addTag();
|
||||||
this.setUser({tags: this.tagsSnap});
|
|
||||||
|
this.tagsByType.user.tags = this.tagsSnap.tags;
|
||||||
|
this.tagsByType.challenges.tags = this.tagsSnap.challenges;
|
||||||
|
|
||||||
|
this.setUser({tags: this.tagsSnap.tags.concat(this.tagsSnap.challenges)});
|
||||||
this.cancelTagsEditing();
|
this.cancelTagsEditing();
|
||||||
},
|
},
|
||||||
cancelTagsEditing () {
|
cancelTagsEditing () {
|
||||||
this.editingTags = false;
|
this.editingTags = false;
|
||||||
this.tagsSnap = null;
|
this.tagsSnap = {
|
||||||
|
tags: [],
|
||||||
|
challenges: [],
|
||||||
|
};
|
||||||
this.newTag = null;
|
this.newTag = null;
|
||||||
},
|
},
|
||||||
editTask (task) {
|
editTask (task) {
|
||||||
@@ -430,7 +443,6 @@ export default {
|
|||||||
applyFilters () {
|
applyFilters () {
|
||||||
const temporarilySelectedTags = this.temporarilySelectedTags;
|
const temporarilySelectedTags = this.temporarilySelectedTags;
|
||||||
this.selectedTags = temporarilySelectedTags.slice();
|
this.selectedTags = temporarilySelectedTags.slice();
|
||||||
this.closeFilterPanel();
|
|
||||||
},
|
},
|
||||||
toggleTag (tag) {
|
toggleTag (tag) {
|
||||||
const temporarilySelectedTags = this.temporarilySelectedTags;
|
const temporarilySelectedTags = this.temporarilySelectedTags;
|
||||||
@@ -440,6 +452,8 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
temporarilySelectedTags.splice(tagI, 1);
|
temporarilySelectedTags.splice(tagI, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.applyFilters();
|
||||||
},
|
},
|
||||||
isTagSelected (tag) {
|
isTagSelected (tag) {
|
||||||
const tagId = tag.id;
|
const tagId = tag.id;
|
||||||
|
|||||||
23
website/client/libs/userlocalManager.js
Normal file
23
website/client/libs/userlocalManager.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
const CONSTANTS = {
|
||||||
|
keyConstants: {
|
||||||
|
SPELL_DRAWER_STATE: 'spell-drawer-state',
|
||||||
|
},
|
||||||
|
valueConstants: {
|
||||||
|
SPELL_DRAWER_CLOSED: 'spell-drawer-closed',
|
||||||
|
SPELL_DRAWER_OPEN: 'spell-drawer-open',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function setLocalSetting (key, value) {
|
||||||
|
localStorage.setItem(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalSetting (key) {
|
||||||
|
return localStorage.getItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
CONSTANTS,
|
||||||
|
getLocalSetting,
|
||||||
|
setLocalSetting,
|
||||||
|
};
|
||||||
@@ -26,7 +26,7 @@ export async function set (store, changes) {
|
|||||||
if (key === 'tags') {
|
if (key === 'tags') {
|
||||||
// Keep challenge and group tags
|
// Keep challenge and group tags
|
||||||
const oldTags = user.tags.filter(t => {
|
const oldTags = user.tags.filter(t => {
|
||||||
return t.group || t.challenge;
|
return t.group;
|
||||||
});
|
});
|
||||||
|
|
||||||
user.tags = changes[key].concat(oldTags);
|
user.tags = changes[key].concat(oldTags);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ let AUTH_SETTINGS = localStorage.getItem('habit-mobile-settings');
|
|||||||
|
|
||||||
if (AUTH_SETTINGS) {
|
if (AUTH_SETTINGS) {
|
||||||
AUTH_SETTINGS = JSON.parse(AUTH_SETTINGS);
|
AUTH_SETTINGS = JSON.parse(AUTH_SETTINGS);
|
||||||
|
|
||||||
|
if (AUTH_SETTINGS.auth && AUTH_SETTINGS.auth.apiId && AUTH_SETTINGS.auth.apiToken) {
|
||||||
axios.defaults.headers.common['x-api-user'] = AUTH_SETTINGS.auth.apiId;
|
axios.defaults.headers.common['x-api-user'] = AUTH_SETTINGS.auth.apiId;
|
||||||
axios.defaults.headers.common['x-api-key'] = AUTH_SETTINGS.auth.apiToken;
|
axios.defaults.headers.common['x-api-key'] = AUTH_SETTINGS.auth.apiToken;
|
||||||
|
|
||||||
@@ -29,6 +31,7 @@ if (AUTH_SETTINGS) {
|
|||||||
|
|
||||||
isUserLoggedIn = true;
|
isUserLoggedIn = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const i18nData = window && window['habitica-i18n'];
|
const i18nData = window && window['habitica-i18n'];
|
||||||
|
|
||||||
@@ -57,7 +60,7 @@ export default function () {
|
|||||||
isUserLoaded: false, // Means the user and the user's tasks are ready
|
isUserLoaded: false, // Means the user and the user's tasks are ready
|
||||||
isAmazonReady: false, // Whether the Amazon Payments lib can be used
|
isAmazonReady: false, // Whether the Amazon Payments lib can be used
|
||||||
user: asyncResourceFactory(),
|
user: asyncResourceFactory(),
|
||||||
credentials: AUTH_SETTINGS ? {
|
credentials: isUserLoggedIn ? {
|
||||||
API_ID: AUTH_SETTINGS.auth.apiId,
|
API_ID: AUTH_SETTINGS.auth.apiId,
|
||||||
API_TOKEN: AUTH_SETTINGS.auth.apiToken,
|
API_TOKEN: AUTH_SETTINGS.auth.apiToken,
|
||||||
} : {},
|
} : {},
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import {
|
|||||||
} from '../../libs/email';
|
} from '../../libs/email';
|
||||||
import nconf from 'nconf';
|
import nconf from 'nconf';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { model as Tag } from '../../models/tag';
|
|
||||||
|
|
||||||
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS:TECH_ASSISTANCE_EMAIL');
|
||||||
const DELETE_CONFIRMATION = 'DELETE';
|
const DELETE_CONFIRMATION = 'DELETE';
|
||||||
@@ -305,7 +304,7 @@ api.updateUser = {
|
|||||||
|
|
||||||
// Keep challenge and group tags
|
// Keep challenge and group tags
|
||||||
user.tags.forEach(t => {
|
user.tags.forEach(t => {
|
||||||
if (t.group || t.challenge) {
|
if (t.group) {
|
||||||
oldTags.push(t);
|
oldTags.push(t);
|
||||||
} else {
|
} else {
|
||||||
removedTagsIds.push(t.id);
|
removedTagsIds.push(t.id);
|
||||||
@@ -320,7 +319,7 @@ api.updateUser = {
|
|||||||
removedTagsIds.splice(oldI, 1);
|
removedTagsIds.splice(oldI, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.tags.push(Tag.sanitize(t));
|
user.tags.push(t);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove from all the tasks
|
// Remove from all the tasks
|
||||||
|
|||||||
Reference in New Issue
Block a user