1import { diffByUnit, diffDay, diffDayTime } from '../../util' 2import EventDateProfile from './EventDateProfile' 3 4 5export default class EventDefDateMutation { 6 7 clearEnd: boolean = false 8 forceTimed: boolean = false 9 forceAllDay: boolean = false 10 11 // Durations. if 0-ms duration, will be null instead. 12 // Callers should not set this directly. 13 dateDelta: any 14 startDelta: any 15 endDelta: any 16 17 18 static createFromDiff(dateProfile0, dateProfile1, largeUnit) { 19 let clearEnd = dateProfile0.end && !dateProfile1.end 20 let forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay() 21 let forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay() 22 let dateDelta 23 let endDiff 24 let endDelta 25 let mutation 26 27 // subtracts the dates in the appropriate way, returning a duration 28 function subtractDates(date1, date0) { // date1 - date0 29 if (largeUnit) { 30 return diffByUnit(date1, date0, largeUnit) // poorly named 31 } else if (dateProfile1.isAllDay()) { 32 return diffDay(date1, date0) // poorly named 33 } else { 34 return diffDayTime(date1, date0) // poorly named 35 } 36 } 37 38 dateDelta = subtractDates(dateProfile1.start, dateProfile0.start) 39 40 if (dateProfile1.end) { 41 // use unzonedRanges because dateProfile0.end might be null 42 endDiff = subtractDates( 43 dateProfile1.unzonedRange.getEnd(), 44 dateProfile0.unzonedRange.getEnd() 45 ) 46 endDelta = endDiff.subtract(dateDelta) 47 } 48 49 mutation = new EventDefDateMutation() 50 mutation.clearEnd = clearEnd 51 mutation.forceTimed = forceTimed 52 mutation.forceAllDay = forceAllDay 53 mutation.setDateDelta(dateDelta) 54 mutation.setEndDelta(endDelta) 55 56 return mutation 57 } 58 59 60 /* 61 returns an undo function. 62 */ 63 buildNewDateProfile(eventDateProfile, calendar) { 64 let start = eventDateProfile.start.clone() 65 let end = null 66 let shouldRezone = false 67 68 if (eventDateProfile.end && !this.clearEnd) { 69 end = eventDateProfile.end.clone() 70 } else if (this.endDelta && !end) { 71 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start) 72 } 73 74 if (this.forceTimed) { 75 shouldRezone = true 76 77 if (!start.hasTime()) { 78 start.time(0) 79 } 80 81 if (end && !end.hasTime()) { 82 end.time(0) 83 } 84 } else if (this.forceAllDay) { 85 86 if (start.hasTime()) { 87 start.stripTime() 88 } 89 90 if (end && end.hasTime()) { 91 end.stripTime() 92 } 93 } 94 95 if (this.dateDelta) { 96 shouldRezone = true 97 98 start.add(this.dateDelta) 99 100 if (end) { 101 end.add(this.dateDelta) 102 } 103 } 104 105 // do this before adding startDelta to start, so we can work off of start 106 if (this.endDelta) { 107 shouldRezone = true 108 109 end.add(this.endDelta) 110 } 111 112 if (this.startDelta) { 113 shouldRezone = true 114 115 start.add(this.startDelta) 116 } 117 118 if (shouldRezone) { 119 start = calendar.applyTimezone(start) 120 121 if (end) { 122 end = calendar.applyTimezone(end) 123 } 124 } 125 126 // TODO: okay to access calendar option? 127 if (!end && calendar.opt('forceEventDuration')) { 128 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start) 129 } 130 131 return new EventDateProfile(start, end, calendar) 132 } 133 134 135 setDateDelta(dateDelta) { 136 if (dateDelta && dateDelta.valueOf()) { 137 this.dateDelta = dateDelta 138 } else { 139 this.dateDelta = null 140 } 141 } 142 143 144 setStartDelta(startDelta) { 145 if (startDelta && startDelta.valueOf()) { 146 this.startDelta = startDelta 147 } else { 148 this.startDelta = null 149 } 150 } 151 152 153 setEndDelta(endDelta) { 154 if (endDelta && endDelta.valueOf()) { 155 this.endDelta = endDelta 156 } else { 157 this.endDelta = null 158 } 159 } 160 161 162 isEmpty() { 163 return !this.clearEnd && !this.forceTimed && !this.forceAllDay && 164 !this.dateDelta && !this.startDelta && !this.endDelta 165 } 166 167} 168