diff --git a/app/imports/api/library/Libraries.js b/app/imports/api/library/Libraries.js index 696f0001..1cbb723e 100644 --- a/app/imports/api/library/Libraries.js +++ b/app/imports/api/library/Libraries.js @@ -29,6 +29,16 @@ let LibrarySchema = new SimpleSchema({ optional: true, max: STORAGE_LIMITS.summary, }, + showInMarket: { + index: 1, + type: Boolean, + optional: true, + }, + subscriberCount: { + index: 1, + type: Number, + optional: true, + }, }); LibrarySchema.extend(SharingSchema); @@ -104,6 +114,29 @@ const updateLibraryDescription = new ValidatedMethod({ }, }); +const updateLibraryShowInMarket = new ValidatedMethod({ + name: 'libraries.updateShowInMarket', + validate: new SimpleSchema({ + _id: { + type: String, + regEx: SimpleSchema.RegEx.id + }, + value: { + type: Boolean, + }, + }).validator(), + mixins: [RateLimiterMixin], + rateLimit: { + numRequests: 5, + timeInterval: 5000, + }, + run({ _id, value }) { + let library = Libraries.findOne(_id); + assertEditPermission(library, this.userId); + Libraries.update(_id, { $set: { showInMarket: value } }); + }, +}); + const removeLibrary = new ValidatedMethod({ name: 'libraries.remove', validate: new SimpleSchema({ @@ -130,4 +163,4 @@ export function removeLibaryWork(libraryId) { LibraryNodes.remove({ 'ancestors.id': libraryId }); } -export { LibrarySchema, insertLibrary, updateLibraryName, updateLibraryDescription, removeLibrary }; +export { LibrarySchema, insertLibrary, updateLibraryName, updateLibraryDescription, updateLibraryShowInMarket, removeLibrary }; diff --git a/app/imports/api/library/LibraryCollections.js b/app/imports/api/library/LibraryCollections.js index aec4d351..aff9fe20 100644 --- a/app/imports/api/library/LibraryCollections.js +++ b/app/imports/api/library/LibraryCollections.js @@ -32,6 +32,16 @@ const LibraryCollectionSchema = new SimpleSchema({ type: String, regEx: SimpleSchema.RegEx.Id, }, + showInMarket: { + index: 1, + type: Boolean, + optional: true, + }, + subscriberCount: { + index: 1, + type: Number, + optional: true, + }, }); LibraryCollectionSchema.extend(SharingSchema); @@ -48,12 +58,12 @@ const insertLibraryCollection = new ValidatedMethod({ run(libraryCollection) { if (!this.userId) { throw new Meteor.Error('LibraryCollections.methods.insert.denied', - 'You need to be logged in to insert a library'); + 'You need to be logged in to insert a library'); } let tier = getUserTier(this.userId); - if (!tier.paidBenefits){ + if (!tier.paidBenefits) { throw new Meteor.Error('LibraryCollections.methods.insert.denied', - `The ${tier.name} tier does not allow you to insert a library collection`); + `The ${tier.name} tier does not allow you to insert a library collection`); } libraryCollection.owner = this.userId; return LibraryCollections.insert(libraryCollection); @@ -72,7 +82,7 @@ const updateLibraryCollection = new ValidatedMethod({ }, update: { type: LibraryCollectionSchema - .pick('name', 'description', 'libraries') + .pick('name', 'description', 'libraries', 'showInMarket') .extend({ //make libraries optional libraries: { optional: true, @@ -85,7 +95,7 @@ const updateLibraryCollection = new ValidatedMethod({ numRequests: 5, timeInterval: 5000, }, - run({_id, update}){ + run({ _id, update }) { const libraryCollection = LibraryCollections.findOne(_id, { fields: { owner: 1, @@ -93,7 +103,7 @@ const updateLibraryCollection = new ValidatedMethod({ } }); assertEditPermission(libraryCollection, this.userId); - return LibraryCollections.update(_id, {$set: update}); + return LibraryCollections.update(_id, { $set: update }); }, }); @@ -110,7 +120,7 @@ const removeLibraryCollection = new ValidatedMethod({ numRequests: 5, timeInterval: 5000, }, - run({_id}){ + run({ _id }) { const libraryCollection = LibraryCollections.findOne(_id, { fields: { owner: 1, diff --git a/app/imports/api/users/Users.js b/app/imports/api/users/Users.js index 54328914..47f1f25d 100644 --- a/app/imports/api/users/Users.js +++ b/app/imports/api/users/Users.js @@ -1,11 +1,12 @@ import SimpleSchema from 'simpl-schema'; import { ValidatedMethod } from 'meteor/mdg:validated-method'; import { RateLimiterMixin } from 'ddp-rate-limiter-mixin'; +import Libraries from '/imports/api/library/Libraries.js'; +import LibraryCollections from '/imports/api/library/LibraryCollections.js'; import '/imports/api/users/methods/deleteMyAccount.js'; import '/imports/api/users/methods/addEmail.js'; import '/imports/api/users/methods/removeEmail.js'; import '/imports/api/users/methods/updateFileStorageUsed.js'; - import { some } from 'lodash'; const defaultLibraries = process.env.DEFAULT_LIBRARIES && process.env.DEFAULT_LIBRARIES.split(',') || []; const defaultLibraryCollections = process.env.DEFAULT_LIBRARY_COLLECTIONS && process.env.DEFAULT_LIBRARY_COLLECTIONS.split(',') || []; @@ -250,6 +251,29 @@ Meteor.users.setPreference = new ValidatedMethod({ }, }); +if (Meteor.isServer) { + Accounts.onCreateUser(() => { + if (defaultLibraries?.length) { + Libraries.update({ + _id: { $in: defaultLibraries } + }, { + $inc: { subscriberCount: 1 } + }, { + multi: true, + }, () => {/**/ }); + } + if (defaultLibraryCollections?.length) { + LibraryCollections.update({ + _id: { $in: defaultLibraryCollections } + }, { + $inc: { subscriberCount: 1 } + }, { + multi: true, + }, () => {/**/ }); + } + }); +} + Meteor.users.subscribeToLibrary = new ValidatedMethod({ name: 'users.subscribeToLibrary', validate: new SimpleSchema({ @@ -264,15 +288,17 @@ Meteor.users.subscribeToLibrary = new ValidatedMethod({ mixins: [RateLimiterMixin], rateLimit: { numRequests: 5, - timeInterval: 5000, + timeInterval: 2000, }, run({ libraryId, subscribe }) { if (!this.userId) throw 'Can only subscribe if logged in'; if (subscribe) { + Libraries.update({ _id: libraryId }, { $inc: { subscriberCount: 1 } }, () => {/**/ }); return Meteor.users.update(this.userId, { $addToSet: { subscribedLibraries: libraryId }, }); } else { + Libraries.update({ _id: libraryId }, { $inc: { subscriberCount: -1 } }, () => {/**/ }); return Meteor.users.update(this.userId, { $pullAll: { subscribedLibraries: libraryId }, }); @@ -299,10 +325,12 @@ Meteor.users.subscribeToLibraryCollection = new ValidatedMethod({ run({ libraryCollectionId, subscribe }) { if (!this.userId) throw 'Can only subscribe if logged in'; if (subscribe) { + LibraryCollections.update({ _id: libraryCollectionId }, { $inc: { subscriberCount: 1 } }, () => {/**/ }); return Meteor.users.update(this.userId, { $addToSet: { subscribedLibraryCollections: libraryCollectionId }, }); } else { + LibraryCollections.update({ _id: libraryCollectionId }, { $inc: { subscriberCount: -1 } }, () => {/**/ }); return Meteor.users.update(this.userId, { $pullAll: { subscribedLibraryCollections: libraryCollectionId }, }); diff --git a/app/imports/client/ui/components/global/SmartBtn.vue b/app/imports/client/ui/components/global/SmartBtn.vue index e423e22d..c4fb5e03 100644 --- a/app/imports/client/ui/components/global/SmartBtn.vue +++ b/app/imports/client/ui/components/global/SmartBtn.vue @@ -3,7 +3,7 @@ v-bind="$attrs" :disabled="isDisabled" :loading="loading" - @click.stop="click" + @click.stop.prevent="click" > diff --git a/app/imports/client/ui/creature/slots/SlotFillDialog.vue b/app/imports/client/ui/creature/slots/SlotFillDialog.vue index 7eeddf22..75af7420 100644 --- a/app/imports/client/ui/creature/slots/SlotFillDialog.vue +++ b/app/imports/client/ui/creature/slots/SlotFillDialog.vue @@ -147,11 +147,27 @@ + Can't find what you're looking for? + + + + Browse community libraries + - Create custom + Create custom filler @@ -41,6 +49,7 @@ import LibraryCollections from '/imports/api/library/LibraryCollections.js'; import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions.js'; import { mapMutations } from 'vuex'; +import formatter from '/imports/client/ui/utility/numberFormatter.js'; export default { data() { @@ -87,6 +96,9 @@ export default { ...mapMutations([ 'toggleDrawer', ]), + formatNumber(num) { + return formatter.format(num); + }, subscribe(value) { this.loading = true; Meteor.users.subscribeToLibraryCollection.call({ @@ -103,6 +115,9 @@ export default { data: { _id: this.$route.params.id }, }); }, + back() { + return window.history.length > 2 ? this.$router.back() : this.$router.push('/library'); + }, }, } diff --git a/app/imports/client/ui/library/LibraryEditDialog.vue b/app/imports/client/ui/library/LibraryEditDialog.vue index 36decbbc..29bd535c 100644 --- a/app/imports/client/ui/library/LibraryEditDialog.vue +++ b/app/imports/client/ui/library/LibraryEditDialog.vue @@ -31,6 +31,11 @@ :value="model.description" @change="updateDescription" /> +