| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 | // simple version, only toggle watch / unwatchconst simpleWatchable = collection => {  collection.attachSchema({    watchers: {      type: [String],      optional: true,    },  });  collection.helpers({    getWatchLevels() {      return [true, false];    },    watcherIndex(userId) {      return this.watchers.indexOf(userId);    },    findWatcher(userId) {      return _.contains(this.watchers, userId);    },  });  collection.mutations({    setWatcher(userId, level) {      // if level undefined or null or false, then remove      if (!level) return { $pull: { watchers: userId } };      return { $addToSet: { watchers: userId } };    },  });};// more complex version of same interface, with 3 watching levelsconst complexWatchOptions = ['watching', 'tracking', 'muted'];const complexWatchDefault = 'muted';const complexWatchable = collection => {  collection.attachSchema({    'watchers.$.userId': {      type: String,    },    'watchers.$.level': {      type: String,      allowedValues: complexWatchOptions,    },  });  collection.helpers({    getWatchOptions() {      return complexWatchOptions;    },    getWatchDefault() {      return complexWatchDefault;    },    watcherIndex(userId) {      return _.pluck(this.watchers, 'userId').indexOf(userId);    },    findWatcher(userId) {      return _.findWhere(this.watchers, { userId });    },    getWatchLevel(userId) {      const watcher = this.findWatcher(userId);      return watcher ? watcher.level : complexWatchDefault;    },  });  collection.mutations({    setWatcher(userId, level) {      // if level undefined or null or false, then remove      if (level === complexWatchDefault) level = null;      if (!level) return { $pull: { watchers: { userId } } };      const index = this.watcherIndex(userId);      if (index < 0) return { $push: { watchers: { userId, level } } };      return {        $set: {          [`watchers.${index}.level`]: level,        },      };    },  });};complexWatchable(Boards);simpleWatchable(Lists);simpleWatchable(Cards);
 |