Moved slot filler search to server side, limited docs in subscription
This commit is contained in:
@@ -53,3 +53,4 @@ peerlibrary:reactive-publish
|
||||
simple:rest
|
||||
simple:rest-method-mixin
|
||||
mikowals:batch-insert
|
||||
peerlibrary:subscription-data
|
||||
|
||||
@@ -95,11 +95,15 @@ ongoworks:speakingurl@9.0.0
|
||||
ordered-dict@1.1.0
|
||||
patreon-oauth@0.1.0
|
||||
peerlibrary:assert@0.3.0
|
||||
peerlibrary:check-extension@0.7.0
|
||||
peerlibrary:computed-field@0.10.0
|
||||
peerlibrary:data-lookup@0.3.0
|
||||
peerlibrary:extend-publish@0.6.0
|
||||
peerlibrary:fiber-utils@0.10.0
|
||||
peerlibrary:reactive-mongo@0.4.0
|
||||
peerlibrary:reactive-publish@0.10.0
|
||||
peerlibrary:server-autorun@0.8.0
|
||||
peerlibrary:subscription-data@0.8.0
|
||||
percolate:migrations@0.9.8
|
||||
percolate:synced-cron@1.3.2
|
||||
promise@0.11.2
|
||||
|
||||
@@ -32,6 +32,14 @@ let LibraryNodeSchema = new SimpleSchema({
|
||||
}
|
||||
});
|
||||
|
||||
// Set up server side search index
|
||||
if (Meteor.isServer) {
|
||||
LibraryNodes._ensureIndex({
|
||||
'name': 'text',
|
||||
'tags': 'text',
|
||||
});
|
||||
}
|
||||
|
||||
for (let key in propertySchemasIndex){
|
||||
let schema = new SimpleSchema({});
|
||||
schema.extend(LibraryNodeSchema);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { check } from 'meteor/check';
|
||||
import Libraries from '/imports/api/library/Libraries.js';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||
|
||||
Meteor.publish('slotFillers', function(slotId){
|
||||
let self = this;
|
||||
this.autorun(function (){
|
||||
let userId = this.userId;
|
||||
if (!userId) {
|
||||
@@ -46,6 +48,44 @@ Meteor.publish('slotFillers', function(slotId){
|
||||
slotFillerType: slot.slotType,
|
||||
}];
|
||||
}
|
||||
return LibraryNodes.find(filter);
|
||||
this.autorun(function(){
|
||||
// Get the limit of the documents the user can fetch
|
||||
var limit = self.data('limit') || 16;
|
||||
check(limit, Number);
|
||||
|
||||
// Get the search term
|
||||
let searchTerm = self.data('searchTerm') || '';
|
||||
check(searchTerm, String);
|
||||
|
||||
let options = undefined;
|
||||
if (searchTerm){
|
||||
filter.$text = {$search: searchTerm};
|
||||
options = {
|
||||
// relevant documents have a higher score.
|
||||
fields: {
|
||||
score: { $meta: 'textScore' }
|
||||
},
|
||||
sort: {
|
||||
// `score` property specified in the projection fields above.
|
||||
score: { $meta: 'textScore' },
|
||||
name: 1,
|
||||
order: 1,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
options = {sort: {
|
||||
name: 1,
|
||||
order: 1,
|
||||
}};
|
||||
}
|
||||
options.limit = limit;
|
||||
|
||||
self.autorun(function () {
|
||||
self.setData('countAll', LibraryNodes.find(filter).count());
|
||||
});
|
||||
self.autorun(function () {
|
||||
return LibraryNodes.find(filter, options);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
regular
|
||||
hide-details
|
||||
:value="searchValue"
|
||||
:debounce="200"
|
||||
:debounce="300"
|
||||
@change="searchChanged"
|
||||
@keyup.enter="insert"
|
||||
/>
|
||||
@@ -22,49 +22,60 @@
|
||||
class="library-nodes"
|
||||
>
|
||||
<v-fade-transition mode="out-in">
|
||||
<column-layout
|
||||
v-if="$subReady.slotFillers && libraryNodes && libraryNodes.length"
|
||||
wide-columns
|
||||
>
|
||||
<div
|
||||
v-for="node in libraryNodes"
|
||||
:key="node._id"
|
||||
<div v-if="libraryNodes && libraryNodes.length">
|
||||
<column-layout
|
||||
wide-columns
|
||||
>
|
||||
<v-card
|
||||
hover
|
||||
ripple
|
||||
class="slot-card"
|
||||
:class="{'primary': node._id === (selectedNode && selectedNode._id)}"
|
||||
:dark="node._id === (selectedNode && selectedNode._id)"
|
||||
@click="selectedNode = node"
|
||||
<div
|
||||
v-for="node in libraryNodes"
|
||||
:key="node._id"
|
||||
>
|
||||
<v-img
|
||||
v-if="node.picture"
|
||||
:src="node.picture"
|
||||
:height="200"
|
||||
contain
|
||||
/>
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="title mb-0">
|
||||
<tree-node-view
|
||||
class="mr-2"
|
||||
:class="{'theme--dark': node._id === (selectedNode && selectedNode._id)}"
|
||||
:hide-icon="node.picture"
|
||||
:model="node"
|
||||
:color="node.color"
|
||||
<v-card
|
||||
hover
|
||||
ripple
|
||||
class="slot-card"
|
||||
:class="{'primary': node._id === (selectedNode && selectedNode._id)}"
|
||||
:dark="node._id === (selectedNode && selectedNode._id)"
|
||||
@click="selectedNode = node"
|
||||
>
|
||||
<v-img
|
||||
v-if="node.picture"
|
||||
:src="node.picture"
|
||||
:height="200"
|
||||
contain
|
||||
/>
|
||||
<v-card-title primary-title>
|
||||
<div>
|
||||
<h3 class="title mb-0">
|
||||
<tree-node-view
|
||||
class="mr-2"
|
||||
:class="{'theme--dark': node._id === (selectedNode && selectedNode._id)}"
|
||||
:hide-icon="node.picture"
|
||||
:model="node"
|
||||
:color="node.color"
|
||||
/>
|
||||
</h3>
|
||||
<property-description
|
||||
:string="model.description"
|
||||
:calculations="model.descriptionCalculations"
|
||||
:inactive="model.inactive"
|
||||
/>
|
||||
</h3>
|
||||
<property-description
|
||||
:string="model.description"
|
||||
:calculations="model.descriptionCalculations"
|
||||
:inactive="model.inactive"
|
||||
/>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</div>
|
||||
</column-layout>
|
||||
<div class="layout row justify-center">
|
||||
<v-btn
|
||||
v-if="currentLimit < countAll"
|
||||
:loading="!$subReady.slotFillers"
|
||||
class="primary"
|
||||
@click="loadMore"
|
||||
>
|
||||
Load More
|
||||
</v-btn>
|
||||
</div>
|
||||
</column-layout>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="$subReady.slotFillers"
|
||||
class="ma-4"
|
||||
@@ -94,8 +105,10 @@
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</v-fade-transition>
|
||||
<v-fade-transition mode="out-in">
|
||||
<div
|
||||
v-else
|
||||
v-if="!$subReady.slotFillers"
|
||||
key="character-loading"
|
||||
class="fill-height layout justify-center align-center"
|
||||
>
|
||||
@@ -179,10 +192,16 @@ export default {
|
||||
return prop && prop.name;
|
||||
},
|
||||
searchChanged(val, ack){
|
||||
this._subs['slotFillers'].setData('searchTerm', val);
|
||||
this._subs['slotFillers'].setData('limit', undefined);
|
||||
this.selectedNode = undefined;
|
||||
this.searchValue = val;
|
||||
setTimeout(ack, 200);
|
||||
},
|
||||
loadMore(){
|
||||
if (this.currentLimit >= this.countAll) return;
|
||||
this._subs['slotFillers'].setData('limit', this.currentLimit + 16);
|
||||
},
|
||||
insert(){
|
||||
if (!this.selectedNode) return;
|
||||
this.$store.dispatch('popDialogStack', this.selectedNode);
|
||||
@@ -200,16 +219,16 @@ export default {
|
||||
creature(){
|
||||
return Creatures.findOne(this.creatureId);
|
||||
},
|
||||
currentLimit(){
|
||||
return this._subs['slotFillers'].data('limit') || 16;
|
||||
},
|
||||
countAll(){
|
||||
return this._subs['slotFillers'].data('countAll');
|
||||
},
|
||||
libraryNodes(){
|
||||
let filter = {
|
||||
removed: {$ne: true},
|
||||
};
|
||||
if (this.searchValue){
|
||||
filter.name = {
|
||||
$regex: this.searchValue.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'),
|
||||
$options: 'i'
|
||||
};
|
||||
}
|
||||
if (this.model.slotTags && this.model.slotTags.length){
|
||||
filter.tags = {$all: this.model.slotTags};
|
||||
}
|
||||
@@ -221,7 +240,9 @@ export default {
|
||||
slotFillerType: this.model.slotType,
|
||||
}];
|
||||
}
|
||||
let nodes = LibraryNodes.find(filter).fetch();
|
||||
let nodes = LibraryNodes.find(filter, {
|
||||
sort: {name: 1, order: 1}
|
||||
}).fetch();
|
||||
// Filter out slotFillers whose condition isn't met or are too big to fit
|
||||
// the quantity to fill
|
||||
nodes = nodes.filter(node => {
|
||||
|
||||
Reference in New Issue
Block a user