92 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import compose from 'lodash/fp/compose';
 | 
						|
import map from 'lodash/fp/map';
 | 
						|
import sortBy from 'lodash/fp/sortBy';
 | 
						|
import trans from 'lodash/fp/transform';
 | 
						|
import last from 'lodash/fp/last';
 | 
						|
import forEachRight from 'lodash/fp/forEachRight';
 | 
						|
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);
 | 
						|
}
 |