Skip to content
This repository has been archived by the owner on Sep 18, 2020. It is now read-only.

Commit

Permalink
fix multi days
Browse files Browse the repository at this point in the history
  • Loading branch information
ljmerza committed Jan 31, 2020
1 parent 4a838cf commit ac0435e
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 70 deletions.
16 changes: 6 additions & 10 deletions dist/calendar-card.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/calendar-card.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "calendar-card",
"version": "3.108.1",
"version": "3.108.2",
"description": "A calendar card for Home Assistant Lovelace UI",
"keywords": [
"home-assistant",
Expand Down
90 changes: 64 additions & 26 deletions src/calendar-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export default class CalendarEvent {
const date = this.rawEvent.start && this.rawEvent.start.date || this.rawEvent.start.dateTime || this.rawEvent.start || '';
this._startDateTime = this._processDate(date);
}
return this._startDateTime;

return this._startDateTime.clone();
}

/**
Expand All @@ -64,7 +65,8 @@ export default class CalendarEvent {
const date = this.rawEvent.end && this.rawEvent.end.date || this.rawEvent.end.dateTime || this.rawEvent.end;
this._endDateTime = this._processDate(date, true);
}
return this._endDateTime;

return this._endDateTime.clone();
}

get addDays(){
Expand All @@ -76,11 +78,11 @@ export default class CalendarEvent {
}

get isFirstDay(){
return this.rawEvent.addDays === 0;
return this.rawEvent._isFirstDay;
}

get isLastDay(){
return this.rawEvent.addDays === (this.rawEvent.daysLong - 1);
return this.rawEvent._isLastDay;
}

/**
Expand Down Expand Up @@ -137,8 +139,64 @@ export default class CalendarEvent {
* @return {Boolean}
*/
get isMultiDay() {
if (this.endDateTime.diff(this.startDateTime, 'hours') <= 24 && this.startDateTime.hour() === 0) return false;
if (this.startDateTime.date() !== this.endDateTime.date()) return true;
// if more than 24 hours we automatically know it's multi day
if (this.endDateTime.diff(this.startDateTime, 'hours') > 24) return true;

// end date could be at midnight which is not multi day but is seen as the next day
// subtract one minute and if that made it one day then its NOT one day
const daysDifference = Math.abs(this.startDateTime.date() - this.endDateTime.subtract(1, 'minute').date());
if (daysDifference === 1 && this.endDateTime.hours() === 0 && this.endDateTime.minutes() === 0) return false;

return !!daysDifference;
}

/**
* is the event a full day event?
* @return {Boolean}
*/
get isAllDayEvent() {
const isMidnightStart = this.startDateTime.startOf('day').diff(this.startDateTime) === 0;
const isMidnightEnd = this.endDateTime.startOf('day').diff(this.endDateTime) === 0;
if (isMidnightStart && isMidnightEnd) return true;

// check for days that are between multi days - they ARE all day
if(!this.isFirstDay && !this.isLastDay && this.daysLong) return true;

return isMidnightStart && isMidnightEnd;
}

/**
* split this event into a multi day event
* @param {*} newEvent
*/
splitIntoMultiDay(newEvent) {
const partialEvents = [];

// multi days start at two days
// every 24 hours is a day. if we do get some full days then just add to 1 daysLong
let daysLong = 2;
const fullDays = parseInt(this.endDateTime.subtract(1, 'minutes').diff(this.startDateTime, 'hours') / 24);
if (fullDays) daysLong = fullDays + 1;

for (let i = 0; i < daysLong; i++) {
// copy event then add the current day/total days to 'new' event
const copiedEvent = JSON.parse(JSON.stringify(newEvent.rawEvent));
copiedEvent.addDays = i;
copiedEvent.daysLong = daysLong;

copiedEvent._isFirstDay = i === 0;
copiedEvent._isLastDay = i === (daysLong - 1);

const partialEvent = new CalendarEvent(copiedEvent, this._config);

// only add event if starting before the config numberOfDays
const endDate = moment().startOf('day').add(this._config.numberOfDays, 'days');
if (endDate.isAfter(partialEvent.startDateTime)) {
partialEvents.push(partialEvent)
}
}

return partialEvents;
}

/**
Expand Down Expand Up @@ -188,24 +246,4 @@ export default class CalendarEvent {
const address = this.rawEvent.location.substring(this.rawEvent.location.indexOf(',') + 1);
return address.split(' ').join('+');
}

/**
* is the event a full day event?
* @return {Boolean}
*/
get isAllDayEvent() {

// if multiday then only full day is first day is all day
if (this.isFirstDay && (this.startDateTime.hour() || this.startDateTime.minutes())) return false;
else if (this.isFirstDay) return true;
// same for last day
if (this.isLastDay && (this.endDateTime.hour() || this.endDateTime.minutes())) return false;
else if (this.isLastDay) return true;

// if we got this far and add days is true then it's a middle day of a multi day event so its all day
if(this.addDays) return true;

//
if (this.endDateTime.diff(this.startDateTime, 'hours') <= 24 && this.startDateTime.hour() === 0) return true;
}
}
28 changes: 2 additions & 26 deletions src/event.tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ export async function sendNotificationForNewEvents(config, hass, events, oldEven
* @return {String}
*/
export const getEventDateTime = (event, config, timeFormat) => {
if (event.isAllDayEvent){
return config.fullDayEventText;
}
if (event.isAllDayEvent) return config.fullDayEventText;

const start = event.startDateTime && event.startDateTime.format(timeFormat);
const end = event.endDateTime && event.endDateTime.format(timeFormat);
Expand Down Expand Up @@ -193,29 +191,7 @@ export function processEvents(allEvents, config) {
* then add as 'new' event
*/
if (config.showMultiDay && newEvent.isMultiDay) {
const today = moment().startOf('day');
const endDate = today.add(config.numberOfDays, 'days');

let daysLong = (newEvent.endDateTime.diff(newEvent.startDateTime, 'days') + 1);
const partialEvents = [];

// if we are all day events then we don't need that last day ending at 12am
if (newEvent.endDateTime.hour() === 0 && newEvent.endDateTime.minutes() === 0) daysLong -= 1;

for (let i = 0; i < daysLong; i++) {
// copy event then add the current day/total days to 'new' event
const copiedEvent = JSON.parse(JSON.stringify(newEvent.rawEvent));
copiedEvent.addDays = i;
copiedEvent.daysLong = daysLong;

const partialEvent = new CalendarEvent(copiedEvent, config);

// only add event if starting before the config numberOfDays
if (endDate.isAfter(partialEvent.startDateTime)) {
partialEvents.push(partialEvent)
}
}

const partialEvents = newEvent.splitIntoMultiDay(newEvent);
events = events.concat(partialEvents);

} else {
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class CalendarCard extends LitElement {
moment.locale(this.hass.language);

// dont update if we dont need it to conserve api calls
if (!this.cardNeedsUpdating && moment().diff(this.lastEventsUpdate, 'seconds') < 60) return;
if (!this.cardNeedsUpdating && moment().diff(this.lastEventsUpdate, 'seconds') < 600) return;

this.lastEventsUpdate = moment();
this.cardNeedsUpdating = false;
Expand Down Expand Up @@ -154,8 +154,8 @@ class CalendarCard extends LitElement {
</td>
<td class="overview ${disableLink ? 'no-pointer' : ''}" @click=${e => openLink(e, event.htmlLink, this.config)}>
<div class="title">${event.title}</div>
${getEventOrigin(event, this.config)}
${getTimeHtml(event, this.config)}
${getEventOrigin(event, this.config)}
${this.config.progressBar ? getProgressBar(event) : ''}
</td>
<td class="location">
Expand Down
4 changes: 0 additions & 4 deletions src/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,6 @@ const style = css`
color: var(--accent-color);
}
.event-origin {
float: right;
}
.event-origin span {
color: var(--accent-color);
margin-right: -4px;
Expand Down

0 comments on commit ac0435e

Please sign in to comment.