mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-19 15:48:04 +01:00
starts fixing default tasks and use discriminator
This commit is contained in:
@@ -10,10 +10,10 @@ var ChallengeSchema = new Schema({
|
||||
shortName: String,
|
||||
description: String,
|
||||
official: {type: Boolean,'default':false},
|
||||
habits: [TaskSchemas.HabitSchema],
|
||||
dailys: [TaskSchemas.DailySchema],
|
||||
todos: [TaskSchemas.TodoSchema],
|
||||
rewards: [TaskSchemas.RewardSchema],
|
||||
//habits: [TaskSchemas.HabitSchema],
|
||||
//dailys: [TaskSchemas.DailySchema],
|
||||
//todos: [TaskSchemas.TodoSchema],
|
||||
//rewards: [TaskSchemas.RewardSchema],
|
||||
leader: {type: String, ref: 'User'},
|
||||
group: {type: String, ref: 'Group'},
|
||||
timestamp: {type: Date, 'default': Date.now},
|
||||
|
||||
@@ -5,9 +5,10 @@ import baseModel from '../libs/api-v3/baseModel';
|
||||
import _ from 'lodash';
|
||||
|
||||
let Schema = mongoose.Schema;
|
||||
let discriminatorOptions = () => {
|
||||
return {discriminatorKey: 'type'}; // the key that distinguishes task types
|
||||
let discriminatorOptions = {
|
||||
discriminatorKey: 'type', // the key that distinguishes task types
|
||||
};
|
||||
let subDiscriminatorOptions = _.defaults(_.cloneDeep(discriminatorOptions), {_id: false});
|
||||
|
||||
// TODO make sure a task can only update the fields belonging to its type
|
||||
// We could use discriminators but it looks like when loading from the parent
|
||||
@@ -29,10 +30,10 @@ export let TaskSchema = new Schema({
|
||||
broken: String, // CHALLENGE_DELETED, TASK_DELETED, UNSUBSCRIBED, CHALLENGE_CLOSED TODO enum
|
||||
winner: String, // user.profile.name TODO necessary?
|
||||
},
|
||||
}, _.default({
|
||||
}, _.defaults({
|
||||
minimize: true, // So empty objects are returned
|
||||
strict: true,
|
||||
}, discriminatorOptions()));
|
||||
}, discriminatorOptions));
|
||||
|
||||
TaskSchema.plugin(baseModel, {
|
||||
noSet: [],
|
||||
@@ -66,7 +67,7 @@ let dailyTodoSchema = () => {
|
||||
export let Habit = Task.discriminator('Habit', new Schema(_.defaults({
|
||||
up: {type: Boolean, default: true},
|
||||
down: {type: Boolean, default: true},
|
||||
}, habitDailySchema())), discriminatorOptions());
|
||||
}, habitDailySchema()), subDiscriminatorOptions));
|
||||
|
||||
export let Daily = Task.discriminator('Daily', new Schema(_.defaults({
|
||||
frequency: {type: String, default: 'weekly', enum: ['daily', 'weekly']},
|
||||
@@ -87,13 +88,13 @@ export let Daily = Task.discriminator('Daily', new Schema(_.defaults({
|
||||
su: {type: Boolean, default: true},
|
||||
},
|
||||
streak: {type: Number, default: 0},
|
||||
}, habitDailySchema(), dailyTodoSchema())), discriminatorOptions());
|
||||
}, habitDailySchema(), dailyTodoSchema()), subDiscriminatorOptions));
|
||||
|
||||
export let Todo = Task.discriminator('Todo', new Schema(_.defaults({
|
||||
dateCompleted: Date,
|
||||
// FIXME we're getting parse errors, people have stored as "today" and "3/13". Need to run a migration & put this back to type: Date
|
||||
// TODO change field name
|
||||
date: String, // due date for todos
|
||||
}, dailyTodoSchema())), discriminatorOptions());
|
||||
}, dailyTodoSchema()), subDiscriminatorOptions));
|
||||
|
||||
export let Reward = Task.discriminator('Reward', new Schema({}), discriminatorOptions());
|
||||
export let Reward = Task.discriminator('Reward', new Schema({}, subDiscriminatorOptions));
|
||||
|
||||
@@ -3,6 +3,7 @@ import shared from '../../../common';
|
||||
import _ from 'lodash';
|
||||
import validator from 'validator';
|
||||
import moment from 'moment';
|
||||
import Q from 'q';
|
||||
import { model as Task } from './task';
|
||||
import baseModel from '../libs/api-v3/baseModel';
|
||||
// import {model as Challenge} from './challenge';
|
||||
@@ -491,36 +492,37 @@ schema.post('init', function postInitUser (doc) {
|
||||
});
|
||||
|
||||
function _populateDefaultTasks (user, taskTypes) {
|
||||
_.each(taskTypes, (taskType) => {
|
||||
// TODO save in own documents
|
||||
user[taskType] = _.map(shared.content.userDefaults[taskType], (taskDefaults) => {
|
||||
let newTask;
|
||||
if ('tags' in taskTypes) {
|
||||
user.tags = _.map(shared.content.userDefaults.tags, function(tag){
|
||||
let newTag = _.cloneDeep(tag);
|
||||
|
||||
// Render task's text and notes in user's language
|
||||
if (taskType === 'tags') {
|
||||
newTask = _.cloneDeep(taskDefaults);
|
||||
// tasks automatically get id=helpers.uuid() from TaskSchema id.default, but tags are Schema.Types.Mixed - so we need to manually invoke here
|
||||
newTask.id = shared.uuid();
|
||||
newTask.name = newTask.name(user.preferences.language);
|
||||
} else {
|
||||
newTask = new Task(taskDefaults);
|
||||
newTask.userId = user._id;
|
||||
newTask.text = newTask.text(user.preferences.language);
|
||||
if (newTask.notes) {
|
||||
newTask.notes = newTask.notes(user.preferences.language);
|
||||
}
|
||||
|
||||
if (newTask.checklist) {
|
||||
newTask.checklist = _.map(newTask.checklist, (checklistItem) => {
|
||||
checklistItem.text = checklistItem.text(user.preferences.language);
|
||||
return checklistItem;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return newTask;
|
||||
// tasks automatically get _id=helpers.uuid() from TaskSchema id.default, but tags are Schema.Types.Mixed - so we need to manually invoke here
|
||||
newTag.id = shared.uuid();
|
||||
// Render tag's name in user's language
|
||||
newTag.name = newTag.name(user.preferences.language);
|
||||
return newTag;
|
||||
});
|
||||
}
|
||||
|
||||
let tasksToCreate = [];
|
||||
_.each(taskTypes, (taskType) => {
|
||||
let tasksOfType = _.map(shared.content.userDefaults[taskType], (taskDefaults) => {
|
||||
let newTask = new Task(taskDefaults);
|
||||
newTask.userId = user._id;
|
||||
newTask.text = newTask.text(user.preferences.language);
|
||||
if (newTask.notes) newTask.notes = newTask.notes(user.preferences.language);
|
||||
if (newTask.checklist) {
|
||||
newTask.checklist = _.map(newTask.checklist, (checklistItem) => {
|
||||
checklistItem.text = checklistItem.text(user.preferences.language);
|
||||
return checklistItem;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
tasksToCreate.push(...tasksOfType);
|
||||
});
|
||||
|
||||
return Task.create(tasksToCreate);
|
||||
}
|
||||
|
||||
function _populateDefaultsForNewUser (user) {
|
||||
@@ -543,7 +545,7 @@ function _populateDefaultsForNewUser (user) {
|
||||
});
|
||||
}
|
||||
|
||||
_populateDefaultTasks(user, taskTypes);
|
||||
return _populateDefaultTasks(user, taskTypes);
|
||||
}
|
||||
|
||||
function _setProfileName (user) {
|
||||
@@ -556,13 +558,10 @@ function _setProfileName (user) {
|
||||
return localUsername || facebookUsername || anonymous;
|
||||
}
|
||||
|
||||
schema.pre('save', function postSaveUser (next) {
|
||||
// Populate new users with default content
|
||||
if (this.isNew) {
|
||||
_populateDefaultsForNewUser(this);
|
||||
}
|
||||
schema.pre('save', function postSaveUser (next, done) {
|
||||
next();
|
||||
|
||||
// this.markModified('tasks');
|
||||
// TODO remove all unnecessary checks
|
||||
if (_.isNaN(this.preferences.dayStart) || this.preferences.dayStart < 0 || this.preferences.dayStart > 23) {
|
||||
this.preferences.dayStart = 0;
|
||||
}
|
||||
@@ -611,7 +610,12 @@ schema.pre('save', function postSaveUser (next) {
|
||||
if (_.isNaN(this._v) || !_.isNumber(this._v)) this._v = 0;
|
||||
this._v++;
|
||||
|
||||
next();
|
||||
// Populate new users with default content
|
||||
if (this.isNew) {
|
||||
_populateDefaultsForNewUser(this)
|
||||
.then((tasks) => done())
|
||||
.catch(done);
|
||||
}
|
||||
});
|
||||
|
||||
schema.methods.unlink = function unlink (options, cb) {
|
||||
|
||||
Reference in New Issue
Block a user