import { DatePipe } from '@angular/common' ; import { Inject , Injectable , InjectionToken , Optional } from '@angular/core' ; import { select , Store } from '@ngrx/store' ; import { take } from 'rxjs/operators' ; import { ContributionMeasurement } from '../../../core/contribution' ; import { datetime , DateUnits } from '../../../libs/datetime' ; import { toPromise } from '../../../libs/rx' ; import { NoteStateWithRoot } from '../note.state' ; import { NoteContributionTable } from './note-collection.state' ; export enum NoteContributionLevel { NONE = 'NONE' , LOW = 'LOW' , MEDIUM = 'MEDIUM' , HIGH = 'HIGH' } export const NOTE_CONTRIBUTION_MEASUREMENT = new InjectionToken < ContributionMeasurement < Date > > ( 'NoteContributionMeasurement' ) ; @ Injectable ( ) export class NoteContributionService { static readonly keyFormat = 'y.MM.dd' ; /** NOTE(@seokju-na): Will change in future. */ static getContributionLevel ( count ) { if ( count <= 0 ) { return NoteContributionLevel . NONE ; } else if ( count > 0 && count < 3 ) { return NoteContributionLevel . LOW ; } else if ( count >= 3 && count < 7 ) { return NoteContributionLevel . MEDIUM ; } else if ( count >= 7 ) { return NoteContributionLevel . HIGH ; } } /** NOTE(@seokju-na): Will change in future. */ static getColorForContributionLevel ( level ) { switch ( level ) { case NoteContributionLevel . NONE : return 'transparent' ; case NoteContributionLevel . LOW : return '#81c784' ; case NoteContributionLevel . MEDIUM : return '#4caf50' ; case NoteContributionLevel . HIGH : return '#2e7d32' ; } } readonly keyGenerator : ( key : Date ) => string ; constructor ( private store , private datePipe , @ Optional ( ) @ Inject ( NOTE_CONTRIBUTION_MEASUREMENT ) private measurement ) { this . keyGenerator = ( key ) => this . datePipe . transform ( key , NoteContributionService . keyFormat ) ; } async measure ( ) { const collectionState = await toPromise ( this . store . pipe ( select ( state => state . note . collection ) , take ( 1 ) ) ) ; const { year , month } = collectionState . selectedMonth ; const indexDate = datetime . getFirstDateOfMonth ( year , month ) ; const keys = [ ] ; for ( let i = 0 ; i < datetime . getDaysInMonth ( year , month ) ; i ++ ) { keys . push ( datetime . copy ( indexDate ) ) ; datetime . add ( indexDate , DateUnits . DAY , 1 ) ; } const contribution = await this . measurement . measure ( keys , this . keyGenerator ) ; return contribution . items as NoteContributionTable ; } }