item pinning (#8918)

* toggle pinned state of items server + client

* pin quests / add pin src

* add officially pinned items and api to get in app rewards

* update schema and get items deatils

* update pin actions to the new logic

* show countBadge only with a number

* extract getPinKey - pin seasonal items

* togglePinned in buy-dialogs

* add pinKey to shop items

* wip

* wip

* fix path

* togglePinnedItem as common.op / use in client

* fix linting

* pinning: getItemInfo and save in db path and type

* make api more consistent, fix bugs

* updates

* fix bugs

* update actions to current api

* marketGear

* change to pinType

* add mystery_set to getItemInfo

* fix isPinned

* ignore animals

* list shopItems (initial)

* shopItem now has default popoverconent, itemclass and price / currency - list pinned items as rewards - attributes to gear

* show buyModal for the rewards

* show mystery_set icon

* add info whether item is suggested

* write migration, fix style issues

* pin potion and armoire

* make potion, armoire not unpinnable

* show notes for armoire and potion, add default items for new users

* show unpin notification

* add/remove pinned gear on class-change

* remove pinned & add new gear on purchase - refactoring pinning methods - fixes

* always allow to purchase armoire

* highlight item if suggested
This commit is contained in:
negue
2017-08-14 19:15:32 +02:00
committed by GitHub
parent fcea1ecbc2
commit 87f39b4273
34 changed files with 955 additions and 274 deletions
@@ -17,6 +17,17 @@
:isUser="isUser",
@editTask="editTask",
)
template(v-if="isUser === true && type === 'reward' && activeFilter.label !== 'custom'")
.reward-items
shopItem(
v-for="reward in inAppRewards",
:item="reward",
:key="reward.key",
:highlightBorder="reward.isSuggested",
@click="openBuyDialog(reward)"
)
.bottom-gradient
.column-background(
v-if="isUser === true",
:class="{'initial-description': tasks[`${type}s`].length === 0}",
@@ -34,6 +45,12 @@
height: 556px;
}
.reward-items {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.tasks-list {
border-radius: 4px;
background: $gray-600;
@@ -137,17 +154,20 @@
import Task from './task';
import { mapState, mapActions } from 'client/libs/store';
import { shouldDo } from 'common/script/cron';
import inAppRewards from 'common/script/libs/inAppRewards';
import habitIcon from 'assets/svg/habit.svg';
import dailyIcon from 'assets/svg/daily.svg';
import todoIcon from 'assets/svg/todo.svg';
import rewardIcon from 'assets/svg/reward.svg';
import bModal from 'bootstrap-vue/lib/components/modal';
import shopItem from '../shops/shopItem';
import throttle from 'lodash/throttle';
export default {
components: {
Task,
bModal,
shopItem,
},
props: ['type', 'isUser', 'searchText', 'selectedTags', 'taskListOverride'],
data () {
@@ -203,12 +223,16 @@ export default {
computed: {
...mapState({
tasks: 'tasks.data',
user: 'user.data',
userPreferences: 'user.data.preferences',
}),
taskList () {
if (this.taskListOverride) return this.taskListOverride;
return this.tasks[`${this.type}s`];
},
inAppRewards () {
return inAppRewards(this.user);
},
},
watch: {
taskList: {
@@ -240,6 +264,12 @@ export default {
Array.from(taskListEl.getElementsByClassName('task')).forEach(el => {
combinedTasksHeights += el.offsetHeight;
});
const rewardsList = taskListEl.getElementsByClassName('reward-items')[0];
if (rewardsList) {
combinedTasksHeights += rewardsList.offsetHeight;
}
const columnBackgroundStyle = this.$refs.columnBackground.style;
if (tasklistHeight - combinedTasksHeights < 150) {
@@ -279,6 +309,9 @@ export default {
return checklistItemIndex !== -1;
}
},
openBuyDialog (rewardItem) {
this.$emit('openBuyDialog', rewardItem);
},
},
};
</script>
+62
View File
@@ -74,7 +74,38 @@
:isUser="true", :searchText="searchTextThrottled",
:selectedTags="selectedTags",
@editTask="editTask",
@openBuyDialog="openBuyDialog($event)"
)
buyModal(
:item="selectedItemToBuy",
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
@change="resetItemToBuy($event)",
@buyPressed="buyItem($event)",
@togglePinned="togglePinned($event)"
)
template(slot="item", scope="ctx")
div(v-if="ctx.item.purchaseType === 'gear'")
avatar.inline(
:member="user",
:avatarOnly="true",
:withBackground="true",
:overrideAvatarGear="memberOverrideAvatarGear(ctx.item)"
)
item.flat(
:item="ctx.item",
:itemContentClass="ctx.item.class",
:showPopover="false",
v-else
)
template(slot="additionalInfo", scope="ctx")
equipmentAttributesGrid.bordered(
:item="ctx.item",
v-if="ctx.item.purchaseType === 'gear'"
)
</template>
<style lang="scss">
@@ -246,12 +277,21 @@ import cloneDeep from 'lodash/cloneDeep';
import { mapState, mapActions } from 'client/libs/store';
import taskDefaults from 'common/script/libs/taskDefaults';
import BuyModal from 'client/components/shops/buyModal.vue';
import Item from 'client/components/inventory/item.vue';
import Avatar from 'client/components/avatar';
import EquipmentAttributesGrid from 'client/components/shops/market/equipmentAttributesGrid.vue';
export default {
components: {
TaskColumn,
TaskModal,
bDropdown,
bDropdownItem,
BuyModal,
Item,
Avatar,
EquipmentAttributesGrid,
},
data () {
return {
@@ -275,6 +315,8 @@ export default {
newTag: null,
editingTask: null,
creatingTask: null,
selectedItemToBuy: null,
};
},
computed: {
@@ -393,6 +435,26 @@ export default {
if (this.temporarilySelectedTags.indexOf(tagId) !== -1) return true;
return false;
},
resetItemToBuy ($event) {
if (!$event) {
this.selectedItemToBuy = null;
}
},
memberOverrideAvatarGear (gear) {
return {
[gear.type]: gear.key,
};
},
buyItem (item) {
if (item.currency === 'gold') {
this.$store.dispatch('shops:buyItem', {key: item.key});
} else {
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
}
},
openBuyDialog (rewardItem) {
this.selectedItemToBuy = rewardItem;
},
},
};
</script>