From a451afcbaf60a4426b604cbec354208a8cfc843a Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Mon, 21 Jun 2021 16:06:10 +0200 Subject: [PATCH] Prevented new characters being added if you are at your character limit --- .../api/creature/creatures/methods/index.js | 1 + .../creatures/methods/insertCreature.js | 18 ++++- .../CharacterListToolbarItems.vue | 30 +++++++++ app/imports/ui/pages/CharacterList.vue | 65 +++++++++++++------ app/imports/ui/router.js | 2 + 5 files changed, 94 insertions(+), 22 deletions(-) create mode 100644 app/imports/ui/creature/creatureList/CharacterListToolbarItems.vue diff --git a/app/imports/api/creature/creatures/methods/index.js b/app/imports/api/creature/creatures/methods/index.js index 42e9c99e..2cd1b752 100644 --- a/app/imports/api/creature/creatures/methods/index.js +++ b/app/imports/api/creature/creatures/methods/index.js @@ -1,4 +1,5 @@ import '/imports/api/creature/creatures/methods/insertCreature.js'; import '/imports/api/creature/creatures/methods/removeCreature.js'; import '/imports/api/creature/creatures/methods/restCreature.js'; +import '/imports/api/creature/creatures/methods/transferCreatureOwnership.js'; import '/imports/api/creature/creatures/methods/updateCreature.js'; diff --git a/app/imports/api/creature/creatures/methods/insertCreature.js b/app/imports/api/creature/creatures/methods/insertCreature.js index c0cc80c9..41a8c83f 100644 --- a/app/imports/api/creature/creatures/methods/insertCreature.js +++ b/app/imports/api/creature/creatures/methods/insertCreature.js @@ -2,7 +2,7 @@ import { ValidatedMethod } from 'meteor/mdg:validated-method'; import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; import Creatures from '/imports/api/creature/creatures/Creatures.js'; import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js'; -import { assertUserHasPaidBenefits } from '/imports/api/users/patreon/tiers.js'; +import { getUserTier } from '/imports/api/users/patreon/tiers.js'; import defaultCharacterProperties from '/imports/api/creature/creatures/defaultCharacterProperties.js'; import insertPropertyFromLibraryNode from '/imports/api/creature/creatureProperties/methods/insertPropertyFromLibraryNode.js'; @@ -23,7 +23,21 @@ const insertCreature = new ValidatedMethod({ throw new Meteor.Error('Creatures.methods.insert.denied', 'You need to be logged in to insert a creature'); } - assertUserHasPaidBenefits(this.userId); + let tier = getUserTier(this.userId); + + let currentCharacterCount = Creatures.find({ + owner: this.userId, + }, { + fields: {_id: 1}, + }).count(); + + if ( + tier.characterSlots !== -1 && + currentCharacterCount >= tier.characterSlots + ){ + throw new Meteor.Error('Creatures.methods.insert.denied', + `You are already at your limit of ${tier.characterSlots} characters`) + } // Create the creature document let creatureId = Creatures.insert({ diff --git a/app/imports/ui/creature/creatureList/CharacterListToolbarItems.vue b/app/imports/ui/creature/creatureList/CharacterListToolbarItems.vue new file mode 100644 index 00000000..7cc764c5 --- /dev/null +++ b/app/imports/ui/creature/creatureList/CharacterListToolbarItems.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/app/imports/ui/pages/CharacterList.vue b/app/imports/ui/pages/CharacterList.vue index e6509cc3..04bd7720 100644 --- a/app/imports/ui/pages/CharacterList.vue +++ b/app/imports/ui/pages/CharacterList.vue @@ -3,6 +3,13 @@ class="card-background pa-4" style="height: 100%" > + + You have exceeded your maximum number of character slots, archive or delete + some characters. + @@ -76,6 +83,7 @@ bottom right data-id="new-character-button" + :disabled="!hasCharacterSpace" @click="insertCharacter" > mdi-plus @@ -143,6 +151,28 @@ {sort: {name: 1}} ).map(characterTransform); }, + creatureCount(){ + let userId = Meteor.userId(); + return Creatures.find({ + owner: userId, + }, { + fields: {_id: 1}, + }).count(); + }, + tier(){ + let userId = Meteor.userId(); + return getUserTier(userId); + }, + hasCharacterSpace(){ + let tier = this.tier; + let currentCharacterCount = this.creatureCount; + return tier.characterSlots === -1 || currentCharacterCount < tier.characterSlots + }, + exceededCharacterSpace(){ + let tier = this.tier; + let currentCharacterCount = this.creatureCount; + return tier.characterSlots !== -1 && currentCharacterCount > tier.characterSlots + } }, watch:{ renamingFolder(newId){ @@ -156,26 +186,21 @@ }, methods: { insertCharacter(){ - let tier = getUserTier(Meteor.userId()); - if (tier.paidBenefits){ - insertCreature.call((error, result) => { - if (error){ - console.error(error); - } else { - this.$store.commit( - 'setTabForCharacterSheet', - {id: result, tab: 4} - ); - this.$store.commit('setShowDetailsDialog', true); - this.$router.push({ path: `/character/${result}`}); - } - }); - } else { - this.$store.commit('pushDialogStack', { - component: 'tier-too-low-dialog', - elementId: 'new-character-button', - }); - } + insertCreature.call((error, result) => { + if (error){ + console.error(error); + snackbar({ + text: error.reason, + }); + } else { + this.$store.commit( + 'setTabForCharacterSheet', + {id: result, tab: 4} + ); + this.$store.commit('setShowDetailsDialog', true); + this.$router.push({ path: `/character/${result}`}); + } + }); }, insertFolder(){ this.loadingInsertFolder = true; diff --git a/app/imports/ui/router.js b/app/imports/ui/router.js index 591f7045..8590f16c 100644 --- a/app/imports/ui/router.js +++ b/app/imports/ui/router.js @@ -5,6 +5,7 @@ import { acceptInviteToken } from '/imports/api/users/Invites.js'; import Home from '/imports/ui/pages/Home.vue'; import About from '/imports/ui/pages/About.vue'; import CharacterList from '/imports/ui/pages/CharacterList.vue'; +import CharacterListToolbarItems from '/imports/ui/creature/creatureList/CharacterListToolbarItems.vue'; import Library from '/imports/ui/pages/Library.vue'; import SingleLibraryToolbar from '/imports/ui/library/SingleLibraryToolbar.vue'; import CharacterSheetPage from '/imports/ui/pages/CharacterSheetPage.vue'; @@ -104,6 +105,7 @@ RouterFactory.configure(factory => { path: '/characterList', components: { default: CharacterList, + toolbarItems: CharacterListToolbarItems, }, meta: { title: 'Character List',