Commit fa57490c authored by Curtis Adam's avatar Curtis Adam

Refactor the rating system

parent e28c668c
......@@ -18,7 +18,7 @@ function getCardsetInfo(cardset) {
[TAPi18n.__('set-list.cardsetInfoStatic', {}, "de"), ""],
[TAPi18n.__('set-list.name', {}, "de"), cardset.name],
[TAPi18n.__('modal-dialog.kind', {}, "de"), cardset.kind],
[TAPi18n.__('cardset.info.rating', {}, "de"), cardset.relevance],
[TAPi18n.__('cardset.info.rating', {}, "de"), cardset.rating],
[TAPi18n.__('cardset.info.quantity', {}, "de"), cardset.quantity],
[TAPi18n.__('cardset.info.author', {}, "de"), getAuthorName(cardset.owner)],
[TAPi18n.__('cardset.info.release', {}, "de"), moment(cardset.date).locale("de").format('LL')],
......
......@@ -147,6 +147,11 @@ const CardsetsSchema = new SimpleSchema({
type: Boolean
},
relevance: {
type: Number,
decimal: true,
optional: true
},
rating: {
type: Number,
decimal: true
},
......@@ -314,7 +319,7 @@ Meteor.methods({
reviewed: false,
reviewer: 'undefined',
request: false,
relevance: 0,
rating: 0,
raterCount: 0,
quantity: quantity,
license: [],
......@@ -638,39 +643,6 @@ Meteor.methods({
}
}
},
updateRelevance: function (cardset_id) {
check(cardset_id, String);
let relevance = 0;
let ratings = Ratings.find({cardset_id: cardset_id});
let count = ratings.count();
if (count !== 0) {
let amount = 0;
ratings.forEach(function (rate) {
amount = amount + rate.rating;
});
let result = (amount / count).toFixed(2);
relevance = Number(result);
}
let kind = Cardsets.findOne(cardset_id).kind;
switch (kind) {
case 'free':
break;
case 'edu':
relevance += 0.1;
break;
case 'pro':
relevance += 0.2;
break;
default:
break;
}
return relevance;
},
publishCardset: function (id, kind, price, visible) {
check(id, String);
check(kind, String);
......@@ -679,17 +651,11 @@ Meteor.methods({
// Make sure only the task owner can make a task private
let cardset = Cardsets.findOne(id);
if (UserPermissions.isAdmin() || UserPermissions.isOwner(cardset.owner)) {
Meteor.call("updateRelevance", id, function (error, relevance) {
if (!error) {
Cardsets.update(id, {
$set: {
kind: kind,
price: price.toString().replace(",", "."),
visible: visible,
relevance: relevance,
raterCount: Number(Ratings.find({cardset_id: id}).count())
}
});
Cardsets.update(id, {
$set: {
kind: kind,
price: price.toString().replace(",", "."),
visible: visible
}
});
if (kind !== "personal") {
......
......@@ -174,7 +174,7 @@ Meteor.methods({
reviewed: false,
reviewer: 'undefined',
request: false,
relevance: 0,
rating: 0,
raterCount: 0,
quantity: data[0].quantity,
license: [],
......@@ -289,7 +289,7 @@ Meteor.methods({
reviewed: false,
reviewer: 'undefined',
request: false,
relevance: 0,
rating: 0,
raterCount: 0,
quantity: cardset[0].quantity,
license: [],
......@@ -332,7 +332,7 @@ Meteor.methods({
reviewed: false,
reviewer: 'undefined',
request: false,
relevance: 0,
rating: 0,
raterCount: 0,
quantity: totalQuantity,
license: [],
......
......@@ -2,83 +2,59 @@ import {Meteor} from "meteor/meteor";
import {Mongo} from "meteor/mongo";
import {Cardsets} from "./cardsets.js";
import {check} from "meteor/check";
import {UserPermissions} from "./permissions";
export const Ratings = new Mongo.Collection("ratings");
if (Meteor.isServer) {
Meteor.publish("ratings", function () {
if (this.userId && !Roles.userIsInRole(this.userId, ["firstLogin", "blocked"])) {
return Ratings.find();
} else {
return [];
Meteor.publish("cardsetUserRating", function (cardset_id) {
if (this.userId && UserPermissions.isNotBlocked()) {
return Ratings.find({cardset_id: cardset_id, user_id: this.userId});
}
});
}
Meteor.methods({
addRating: function (cardset_id, rating) {
rateCardset: function (cardset_id, rating) {
check(cardset_id, String);
check(rating, Number);
// Make sure the user is logged in
if (!Meteor.userId() || Roles.userIsInRole(this.userId, ["firstLogin", "blocked"])) {
throw new Meteor.Error("not-authorized");
}
if (Cardsets.findOne({_id: cardset_id}).owner === Meteor.userId()) {
throw new Meteor.Error("not-authorized");
}
Ratings.insert({
cardset_id: cardset_id,
user: Meteor.userId(),
rating: rating
});
Meteor.call("updateRelevance", cardset_id, function (error, relevance) {
if (!error) {
Cardsets.update(cardset_id, {
if (this.userId && UserPermissions.isNotBlocked() && !UserPermissions.isOwner(Cardsets.findOne({_id: cardset_id}).owner)) {
if (Ratings.findOne({cardset_id: cardset_id, user_id: this.userId})) {
Ratings.update({cardset_id: cardset_id, user_id: this.userId}, {
$set: {
relevance: Number(relevance),
raterCount: Number(Ratings.find({cardset_id: cardset_id}).count())
rating: rating
}
});
} else {
Ratings.insert({
cardset_id: cardset_id,
user_id: this.userId,
rating: rating
});
}
});
},
updateRating: function (cardset_id, rating) {
check(cardset_id, String);
check(rating, Number);
// Make sure the user is logged in
if (!Meteor.userId() || Roles.userIsInRole(this.userId, ["firstLogin", "blocked"])) {
throw new Meteor.Error("not-authorized");
}
if (Cardsets.findOne({_id: cardset_id}).owner === Meteor.userId()) {
Meteor.call('updateCardsetRating', cardset_id);
} else {
throw new Meteor.Error("not-authorized");
}
Ratings.update({
cardset_id: cardset_id,
user: Meteor.userId()
},
{
$set: {
rating: rating
}
},
updateCardsetRating: function (cardset_id) {
check(cardset_id, String);
if (Meteor.isServer) {
let ratings = Ratings.find({cardset_id: cardset_id}).fetch();
let sum = 0;
for (let i = 0; i < ratings.length; i++) {
sum += ratings[i].rating;
}
);
Meteor.call("updateRelevance", cardset_id, function (error, relevance) {
if (!error) {
Cardsets.update(cardset_id, {
$set: {
relevance: Number(relevance),
raterCount: Number(Ratings.find({cardset_id: cardset_id}).count())
}
});
if (sum !== 0) {
sum = (sum / ratings.length).toFixed(2);
}
});
Cardsets.update(cardset_id, {
$set: {
rating: sum,
raterCount: ratings.length
}
});
}
}
});
......@@ -431,7 +431,7 @@ Meteor.methods({
}
Ratings.remove({
user: user_id
user_id: user_id
});
WebPushSubscriptions.remove({
......
......@@ -285,7 +285,7 @@ Router.route('/cardset/:_id', {
name: 'cardsetdetailsid',
template: 'cardsetAccess',
subscriptions: function () {
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id), Meteor.subscribe('cardsetCards', this.params._id), Meteor.subscribe('cardsetLeitner', this.params._id), Meteor.subscribe('cardsetWozniak', this.params._id)];
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetUserRating', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id), Meteor.subscribe('cardsetCards', this.params._id), Meteor.subscribe('cardsetLeitner', this.params._id), Meteor.subscribe('cardsetWozniak', this.params._id)];
},
data: function () {
MarkdeepEditor.changeMobilePreview(true);
......@@ -306,7 +306,7 @@ Router.route('/cardset/:_id/card/:card_id', {
name: 'cardsetcard',
template: 'cardsetAccess',
subscriptions: function () {
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id), Meteor.subscribe('cardsetCards', this.params._id), Meteor.subscribe('cardsetLeitner', this.params._id), Meteor.subscribe('cardsetWozniak', this.params._id)];
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetUserRating', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id), Meteor.subscribe('cardsetCards', this.params._id), Meteor.subscribe('cardsetLeitner', this.params._id), Meteor.subscribe('cardsetWozniak', this.params._id)];
},
data: function () {
MarkdeepEditor.changeMobilePreview(true);
......@@ -367,7 +367,7 @@ Router.route('/cardset/:_id/stats', {
name: 'cardsetstats',
template: 'cardsetLearnActivityStatistic',
subscriptions: function () {
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id)];
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetUserRating', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id)];
},
data: function () {
Session.set('helpFilter', "workloadProgress");
......@@ -390,7 +390,7 @@ Router.route('/cardsetlist/:_id', {
name: 'cardsetlistid',
template: 'cardsetAccess',
subscriptions: function () {
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id), Meteor.subscribe('cardsetCards', this.params._id), Meteor.subscribe('cardsetLeitner', this.params._id), Meteor.subscribe('cardsetWozniak', this.params._id)];
return [Meteor.subscribe('cardset', this.params._id), Meteor.subscribe('cardsetUserRating', this.params._id), Meteor.subscribe('cardsetWorkload', this.params._id), Meteor.subscribe('cardsetCards', this.params._id), Meteor.subscribe('cardsetLeitner', this.params._id), Meteor.subscribe('cardsetWozniak', this.params._id)];
},
data: function () {
Session.set('helpFilter', "cardset");
......
......@@ -35,7 +35,7 @@ var initTestNotificationsCardset = function () {
"reviewed": false,
"reviewer": "undefined",
"request": false,
"relevance": 0,
"rating": 0,
"raterCount": 0,
"quantity": 5,
"license": [
......@@ -328,6 +328,7 @@ function setupDatabaseIndex() {
Workload._ensureIndex({cardset_id: 1, user_id: 1});
Cards._ensureIndex({cardset_id: 1, subject: 1});
WebPushSubscriptions._ensureIndex({userId: 1});
Ratings._ensureIndex({cardset_id: 1, user_id: 1});
}
Meteor.startup(function () {
......@@ -744,6 +745,24 @@ Meteor.startup(function () {
);
}
cardsets = Cardsets.find({relevance: {$exists: true}}, {fields: {_id: 1}}).fetch();
for (let i = 0; i < cardsets.length; i++) {
Cardsets.update({
_id: cardsets[i]._id
},
{
$unset: {
relevance: ""
}
}
);
}
cardsets = Cardsets.find({}, {fields: {_id: 1}}).fetch();
for (let i = 0; i < cardsets.length; i++) {
Meteor.call('updateCardsetRating', cardsets[i]._id);
}
let wozniak;
wozniak = Wozniak.find({skipped: {$exists: true}}).fetch();
for (let i = 0; i < wozniak.length; i++) {
......
......@@ -29,10 +29,6 @@ Meteor.subscribe("notifications");
*/
Template.cardset.onCreated(function () {
Session.set('ratingsLoaded', false);
Meteor.subscribe('ratings', function () {
Session.set('ratingsLoaded', true);
});
if (Session.get('activeCardset') === undefined || Session.get('activeCardset')._id !== Router.current().params._id) {
Session.set('activeCardset', Cardsets.findOne(Router.current().params._id));
Session.set('activeCard', undefined);
......
......@@ -4,24 +4,25 @@
<tr>
<td>{{_ "cardset.info.rating"}}:</td>
<td>
{{#if canRateCardset}}
{{#if isActiveRoute regex="cardsetdetailsid|cardsetlistid"}}
{{> starsRating id="rating" class='star-ratings' rating=getAverageRating mutable=true}}
{{#if isActiveRoute regex="cardsetdetailsid|cardsetlistid"}}
{{#if canRateCardset}}
{{> starsRating id="rating" class='star-ratings' rating=this.rating mutable=true}}
{{else}}
{{> starsRating class='star-ratings' rating=getAverageRating mutable=false}}
{{> starsRating class='star-ratings' rating=this.rating mutable=false}}
{{/if}}
{{else}}
{{> starsRating class='star-ratings' rating=getAverageRating mutable=false}}
{{> starsRating class='star-ratings' rating=this.rating mutable=false}}
{{/if}} ({{this.raterCount}})
</td>
</tr>
<tr>
{{#if isActiveRoute regex="cardsetdetailsid|cardsetlistid"}}
{{#if canRateCardset}}
<td>{{_ "cardset.info.userRating"}}:</td>
<td><span id="userRating">{{getUserRating}}</span></td>
<tr>
<td>{{_ "cardset.info.userRating"}}:</td>
<td><span id="userRating">{{getUserRating}}</span></td>
</tr>
{{/if}}
</tr>
{{/if}}
{{/if}}
{{/unless}}
</template>
//------------------------ IMPORTS
import {Meteor} from "meteor/meteor";
import {Template} from "meteor/templating";
import {Cardsets} from "../../../../../api/cardsets";
import {Ratings} from "../../../../../api/ratings";
import {UserPermissions} from "../../../../../api/permissions";
import "./ratings.html";
/*
......@@ -15,25 +17,12 @@ Template.cardsetInfoBoxItemRatings.helpers({
return this.ratings === true;
},
canRateCardset: function () {
let result = Cardsets.findOne({_id: this._id}, {fields: {owner: 1}});
if (result !== undefined) {
return result.owner !== Meteor.userId();
} else {
return false;
}
},
getAverageRating: function () {
let ratings = Ratings.find({cardset_id: this._id}).fetch();
let averageRating = 0;
for (let i = 0; i < ratings.length; i++) {
averageRating += ratings[i].rating;
}
return averageRating / ratings.length;
return !UserPermissions.isOwner(Cardsets.findOne({_id: this._id}).owner);
},
getUserRating: function () {
var userrating = Ratings.findOne({
cardset_id: this._id,
user: Meteor.userId()
user_id: Meteor.userId()
});
if (userrating) {
return userrating.rating;
......@@ -42,3 +31,9 @@ Template.cardsetInfoBoxItemRatings.helpers({
}
}
});
Template.cardsetInfoBoxItemRatings.events({
'click #rating': function () {
Meteor.call("rateCardset", Router.current().params._id, Number($('#rating').data('userrating')));
}
});
//------------------------ IMPORTS
import {Meteor} from "meteor/meteor";
import {Template} from "meteor/templating";
import {Ratings} from "../../../../../api/ratings";
import "./reviewer.html";
/*
......@@ -15,19 +15,3 @@ Template.cardsetInfoBoxItemReviewer.helpers({
return (reviewer !== undefined) ? reviewer.profile.name : undefined;
}
});
Template.cardsetInfoBoxItemReviewer.events({
'click #rating': function () {
var cardset_id = Template.parentData(1)._id;
var rating = $('#rating').data('userrating');
var count = Ratings.find({
cardset_id: cardset_id,
user: Meteor.userId()
}).count();
if (count === 0) {
Meteor.call("addRating", cardset_id, rating);
} else {
Meteor.call("updateRating", cardset_id, rating);
}
}
});
......@@ -343,10 +343,6 @@ Template.filterIndexShuffle.onCreated(function () {
*/
Template.filterIndex.onCreated(function () {
Session.set('ratingsLoaded', false);
Meteor.subscribe('ratings', function () {
Session.set('ratingsLoaded', true);
});
Session.set("selectingCardsetToLearn", false);
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment