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);
 | |
| }
 |