import { isEmpty } from 'lodash'; import compose from 'lodash/fp/compose'; import forEachRight from 'lodash/fp/forEachRight'; import last from 'lodash/fp/last'; import map from 'lodash/fp/map'; import sortBy from 'lodash/fp/sortBy'; import trans from 'lodash/fp/transform'; import loopback from 'loopback'; import moment from 'moment-timezone'; import { dayCount } from '../utils/date-utils'; const transform = trans.convert({ cap: false }); const hoursBetween = 24; const hoursDay = 24; export function prepUniqueDaysByHours(cals, tz = 'UTC') { let prev = null; // compose goes bottom to top (map > sortBy > transform) return compose( transform((data, cur, i) => { if (i < 1) { data.push(cur); prev = cur; } else if ( moment(cur).tz(tz).diff(moment(prev).tz(tz).startOf('day'), 'hours') >= hoursDay ) { data.push(cur); prev = cur; } }, []), sortBy(e => e), map(ts => moment(ts).tz(tz).startOf('hours').valueOf()) )(cals); } export function calcCurrentStreak(cals, tz = 'UTC') { let prev = last(cals); if ( moment().tz(tz).startOf('day').diff(moment(prev).tz(tz), 'hours') > hoursBetween ) { return 0; } let currentStreak = 0; let streakContinues = true; forEachRight(cur => { if ( moment(prev).tz(tz).startOf('day').diff(moment(cur).tz(tz), 'hours') <= hoursBetween ) { prev = cur; currentStreak++; } else { // current streak found streakContinues = false; } return streakContinues; })(cals); return currentStreak; } export function calcLongestStreak(cals, tz = 'UTC') { let tail = cals[0]; const longest = cals.reduce( (longest, head, index) => { const last = cals[index === 0 ? 0 : index - 1]; // is streak broken if ( moment(head).tz(tz).startOf('day').diff(moment(last).tz(tz), 'hours') > hoursBetween ) { tail = head; } if (dayCount(longest, tz) < dayCount([head, tail], tz)) { return [head, tail]; } return longest; }, [cals[0], cals[0]] ); return dayCount(longest, tz); } export function getUserById(id, User = loopback.getModelByType('User')) { return new Promise((resolve, reject) => User.findById(id, (err, instance) => { if (err || isEmpty(instance)) { return reject(err || 'No user instance found'); } let completedChallengeCount = 0; if ('completedChallenges' in instance) { completedChallengeCount = instance.completedChallenges.length; } instance.completedChallengeCount = completedChallengeCount; instance.points = (instance.progressTimestamps && instance.progressTimestamps.length) || 1; return resolve(instance); }) ); }