1
0
mirror of https://github.com/kihashi/stardew_community_checklist.git synced 2025-10-19 08:03:17 +00:00

Bundle and Room Completion (#115)

* Add methods for bundle completion

* Add markup for bundle completion

* Update bundle button to go white if bundle is complete

* Update method to max out at items required

* Add bundle progress bar

* Add room completion

* Add function to determine if the room is completed

* Fix icon style

* Add check for completed bundles and rooms
This commit is contained in:
John Cleaver 2019-03-10 18:01:51 -04:00 committed by GitHub
parent c9aa194cc1
commit f22f8345bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 12 deletions

View File

@ -5,20 +5,22 @@
<div class="column"> <div class="column">
<h3 class="title is-4"> <h3 class="title is-4">
{{bundle.name}} {{bundle.name}}
<span class="is-pulled-right">{{bundle.items_required}}</span> <span class="is-pulled-right">{{ GetBundleItemsRedeemed(bundle) }} / {{bundle.items_required}}</span>
</h3> </h3>
<h5 class="subtitle bundle-reward" v-if="!hideBundleItems"> <h5 class="subtitle bundle-reward" v-if="!hideBundleItems">
{{bundle.reward}} {{bundle.reward}}
</h5> </h5>
<progress class="progress is-info" :value="GetBundleItemsRedeemed(bundle)" :max="bundle.items_required" />
</div> </div>
<div class="column"> <div class="column">
<h3 class="title is-4"> <h3 class="title is-4">
{{bundle.room.name}} {{bundle.room.name}}
<span class="is-pulled-right">{{bundle.room.items_required}}</span> <span class="is-pulled-right">{{ GetRoomItemsRedeemed(bundle.room)}} / {{bundle.room.items_required}}</span>
</h3> </h3>
<h5 class="subtitle" v-if="!hideBundleItems"> <h5 class="subtitle" v-if="!hideBundleItems">
{{bundle.room.reward}} {{bundle.room.reward}}
</h5> </h5>
<progress class="progress is-info" :value="GetRoomItemsRedeemed(bundle.room)" :max="bundle.room.items_required" />
</div> </div>
</div> </div>
<!-- Room Progress --> <!-- Room Progress -->
@ -52,7 +54,9 @@ export default {
methods: { methods: {
isItemComplete: function (item) { isItemComplete: function (item) {
return item.item.bundles.every(this.$store.getters.IsBundleItemRedeemed) return item.item.bundles.every(this.$store.getters.IsBundleItemRedeemed)
} },
GetBundleItemsRedeemed: function (bundle) { return this.$store.getters.GetBundleItemsRedeemed(bundle) },
GetRoomItemsRedeemed: function (room) { return this.$store.getters.GetRoomItemsRedeemed(room) }
}, },
components: { components: {
ItemCard ItemCard

View File

@ -16,7 +16,8 @@
<div class="navbar-start"> <div class="navbar-start">
<div class="navbar-item has-dropdown is-hoverable" v-for="room in rooms" :key="room.id"> <div class="navbar-item has-dropdown is-hoverable" v-for="room in rooms" :key="room.id">
<a class="navbar-link"> <a class="navbar-link">
{{room.name}} <span class="icon has-text-success" v-if="IsRoomComplete(room)"><font-awesome-icon icon="check-circle"/></span>
<span>{{room.name}}</span>
</a> </a>
<div class="navbar-dropdown"> <div class="navbar-dropdown">
<router-link <router-link
@ -25,7 +26,9 @@
:key="bundle.id" :key="bundle.id"
@click.native="menu_active = false" @click.native="menu_active = false"
:to="{ name: 'bundle-items', params: { id: bundle.id }}"> :to="{ name: 'bundle-items', params: { id: bundle.id }}">
{{bundle.name}}
<span class="icon has-text-success" v-if="IsBundleComplete(bundle)"><font-awesome-icon icon="check-circle"/></span>
<span>{{bundle.name}}</span>
</router-link> </router-link>
</div> </div>
</div> </div>
@ -38,8 +41,14 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import FontAwesomeIcon from '@fortawesome/vue-fontawesome'
import { faCheckCircle } from '@fortawesome/fontawesome-free-solid'
export default { export default {
name: 'bundle_nav', name: 'bundle_nav',
components: {
FontAwesomeIcon,
faCheckCircle
},
data: function () { data: function () {
return { return {
menu_active: false menu_active: false
@ -47,6 +56,10 @@ export default {
}, },
computed: { computed: {
...mapState(['rooms']) ...mapState(['rooms'])
},
methods: {
IsBundleComplete: function (bundle) { return this.$store.getters.IsBundleComplete(bundle) },
IsRoomComplete: function (room) { return this.$store.getters.IsRoomComplete(room) }
} }
} }
</script> </script>

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="field has-addons"> <div class="field has-addons">
<div class="control is-expanded"> <div class="control is-expanded">
<a class="button is-rounded is-fullwidth" :class="ItemInBundle ? 'is-success' : 'is-danger'" <a class="button is-rounded is-fullwidth" :class="ButtonClass"
@click="ToggleItemInBundle"> @click="ToggleItemInBundle">
<span class="icon"> <span class="icon">
<font-awesome-icon :icon="ItemInBundle ? InBundleIcon : NotInBundleIcon"/> <font-awesome-icon :icon="ItemInBundle ? InBundleIcon : NotInBundleIcon"></font-awesome-icon>
</span> </span>
<span class="is-size-7-mobile">{{bundleItem.bundle.name}}{{numberInBundle}}</span> <span class="is-size-7-mobile">{{bundleItem.bundle.name}}{{numberInBundle}}</span>
</a> </a>
@ -12,7 +12,7 @@
<div class="control"> <div class="control">
<router-link class="button is-rounded is-light" :to="{ name: 'bundle-items', params: { id: bundleItem.bundle.id } }"> <router-link class="button is-rounded is-light" :to="{ name: 'bundle-items', params: { id: bundleItem.bundle.id } }">
<span class="icon"> <span class="icon">
<external-link/> <font-awesome-icon icon="link"></font-awesome-icon>
</span> </span>
</router-link> </router-link>
</div> </div>
@ -21,14 +21,13 @@
<script> <script>
import FontAwesomeIcon from '@fortawesome/vue-fontawesome' import FontAwesomeIcon from '@fortawesome/vue-fontawesome'
import faCheckSquare from '@fortawesome/fontawesome-free-regular/faCheckSquare' import { faCheckSquare, faSquare } from '@fortawesome/fontawesome-free-regular'
import faSquare from '@fortawesome/fontawesome-free-regular/faSquare' import { faLink } from '@fortawesome/fontawesome-free-solid'
import ExternalLink from 'mdi-vue/OpenInNewIcon'
export default { export default {
name: 'bundle-button', name: 'bundle-button',
components: { components: {
'font-awesome-icon': FontAwesomeIcon, 'font-awesome-icon': FontAwesomeIcon,
ExternalLink faLink
}, },
props: { props: {
bundleItem: { bundleItem: {
@ -46,6 +45,15 @@ export default {
NotInBundleIcon () { NotInBundleIcon () {
return faSquare return faSquare
}, },
ButtonClass () {
if (this.ItemInBundle) {
return 'is-success'
} else if (this.IsBundleComplete(this.bundleItem.bundle)) {
return ''
} else {
return 'is-danger'
}
},
numberInBundle () { numberInBundle () {
return this.bundleItem.count > 1 ? ` (${this.bundleItem.count})` : '' return this.bundleItem.count > 1 ? ` (${this.bundleItem.count})` : ''
} }
@ -57,6 +65,9 @@ export default {
} else { } else {
this.$store.commit('UndoRedeemItem', this.bundleItem) this.$store.commit('UndoRedeemItem', this.bundleItem)
} }
},
IsBundleComplete (bundle) {
return this.$store.getters.IsBundleComplete(bundle)
} }
} }
} }

View File

@ -56,6 +56,23 @@ export default new Vuex.Store({
}, },
GetSerializedState: (state) => { GetSerializedState: (state) => {
return btoa(JSON.stringify(state.StoredItems)) return btoa(JSON.stringify(state.StoredItems))
},
GetBundleItemsRedeemed: (state, getters) => (bundle) => {
return Math.min(bundle.items.reduce((redeemded, item) => {
if (getters.IsBundleItemRedeemed(item)) { redeemded++ }
return redeemded
}, 0), bundle.items_required)
},
IsBundleComplete: (state, getters) => (bundle) => {
return getters.GetBundleItemsRedeemed(bundle) >= bundle.items_required
},
GetRoomItemsRedeemed: (state, getters) => (room) => {
return room.bundles.reduce((redeemed, bundle) => {
return redeemed + getters.GetBundleItemsRedeemed(bundle)
}, 0)
},
IsRoomComplete: (state, getters) => (room) => {
return getters.GetRoomItemsRedeemed(room) >= room.items_required
} }
}, },
mutations: { mutations: {