mirror of
https://github.com/MichMich/MagicMirror.git
synced 2026-04-25 23:32:10 +00:00
Closes #4053 This started as a small fix. After feedback and more debugging, I found more issues and inconsistencies and went a bit down the rabbit hole. The PR is bigger now, but I think the result is better: behavior is more predictable, and the output is more consistent. ## Changes - Multi-day full-day events now show an end date in `relative` and `dateheaders` when `showEnd` is enabled. - With `absolute` + `nextDaysRelative`, full-day events now keep the end date when the start is replaced by TODAY/TOMORROW/etc. - Timed events in `absolute` now also respect `showEndsOnlyWithDuration`. - Tests were expanded and refactored to cover more showEnd cases and keep the setup easier to maintain. - I also refactored parts of the calendar time rendering to reduce duplicate logic. ## Before <img width="1816" height="756" alt="before" src="https://github.com/user-attachments/assets/ebec81fd-0c4a-4f9f-bbe3-e2b32ef6756e" /> ## After <img width="1816" height="756" alt="after" src="https://github.com/user-attachments/assets/8a2c652d-dddc-4f6b-9074-fbef3411f9ed" />
362 lines
7.9 KiB
JavaScript
362 lines
7.9 KiB
JavaScript
const calendarShowEndConfigs = {
|
|
event_with_time_over_multiple_days_non_repeating_display_end: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM, HH:mm",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "absolute",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_over_multiple_days_non_repeating.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_over_multiple_days_non_repeating_display_end_dateheaders: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM, HH:mm",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "dateheaders",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_over_multiple_days_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_over_multiple_days_non_repeating_display_end_relative: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM, HH:mm",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "relative",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_over_multiple_days_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_over_multiple_days_non_repeating_no_display_end: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM, HH:mm",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "absolute",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
showEndsOnlyWithDuration: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_over_multiple_days_non_repeating.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_same_day_yearly_display_end_absolute: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "absolute",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_same_day_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_same_day_yearly_display_end_absolute_dateformat_lll: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
language: "en",
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "LLL",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "absolute",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_same_day_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_same_day_yearly_display_end_absolute_dateformat_with_time: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM, HH:mm",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "absolute",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_same_day_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_same_day_yearly_display_end_dateheaders: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "dateheaders",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_same_day_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_same_day_yearly_display_end_relative: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "relative",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_same_day_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
event_with_time_same_day_yearly_display_end_relative_hide_time: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
dateFormat: "Do.MMM",
|
|
dateEndFormat: "Do.MMM, HH:mm",
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "relative",
|
|
getRelative: 0,
|
|
hideTime: true,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/event_with_time_same_day_yearly.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
fullday_multiday_showend_dateheaders: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "dateheaders",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/fullday_event_over_multiple_days_nonrepeating.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
fullday_multiday_showend_nextdaysrelative: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "absolute",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
nextDaysRelative: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/fullday_event_over_multiple_days_nonrepeating.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
fullday_multiday_showend_relative: {
|
|
address: "0.0.0.0",
|
|
ipWhitelist: [],
|
|
timeFormat: 24,
|
|
modules: [
|
|
{
|
|
module: "calendar",
|
|
position: "bottom_bar",
|
|
config: {
|
|
fade: false,
|
|
urgency: 0,
|
|
fullDayEventDateFormat: "Do.MMM",
|
|
timeFormat: "relative",
|
|
getRelative: 0,
|
|
showEnd: true,
|
|
calendars: [
|
|
{
|
|
maximumEntries: 100,
|
|
url: "http://localhost:8080/tests/mocks/fullday_event_over_multiple_days_nonrepeating.ics"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
const defaultScenario = "event_with_time_over_multiple_days_non_repeating_display_end";
|
|
const selectedScenario = process.env.MM_CALENDAR_SHOWEND_SCENARIO || defaultScenario;
|
|
const config = calendarShowEndConfigs[selectedScenario];
|
|
|
|
if (!config) {
|
|
throw new Error(`Unknown MM_CALENDAR_SHOWEND_SCENARIO: ${selectedScenario}`);
|
|
}
|
|
|
|
module.exports = config;
|