MagicMirrorOrg / MagicMirror

MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant.
http://magicmirror.builders
MIT License
19.72k stars 4.2k forks source link

Calendar module: Vertical alignment with wrapping #3053

Closed MikeBishop closed 1 year ago

MikeBishop commented 1 year ago

Platform: MM2 running on Raspberry Pi 4, Bullseye

Node Version: 16.19.0

MagicMirror² Version: 2.22.0

Description: When calendar events are long enough to wrap, the event name does not have the same vertical alignment as the icon and the time string. image

Steps to Reproduce: Add an event with a long name and/or using relative time, enable icons for calendar events

Expected Results: Consistent vertical alignment between elements, regardless of whether that's top-aligned or centered.

Actual Results: Icon is top-aligned, event name is center-aligned.

Configuration:

var config = {
    address: "0.0.0.0", // Address to listen on, can be:
    // - "localhost", "127.0.0.1", "::1" to listen on loopback interface
    // - another specific IPv4/6 to listen on a specific interface
    // - "", "0.0.0.0", "::" to listen on any interface
    // Default, when address config is left out, is "localhost"
    port: 8080,
    ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1",
        "192.168.0.0/16"], // Set [] to allow all IP addresses
    // or add a specific IPv4 of 192.168.1.5 :
    // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"],
    // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format :
    // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"],

    language: "en",
    timeFormat: 12,
    modules: [
        {
            module: "alert",
        },
        // {
        //  module: "updatenotification",
        //  position: "top_bar"
        // },
        {
            module: "clock",
            position: "top_left"
        },
        {
            module: 'calendar_monthly',
            position: 'top_right',
            config: {}
        },
        {
            module: 'uptimerobot',
            position: 'top_center',
            config: {
                api_key: "XXXXXXXXX",
                useIcons: true,
                useColors: true
            }
        },
        {
            module: 'calendar',
            position: 'top_left',
            config: {
                calendars: [
                    {
                        url: 'webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics',
                        symbol: 'flag',
                        color: '#e42217'
                    },
                    {
                        url: 'XXXXXXXXX',
                        symbol: 'user-friends',
                        color: '#fff380'
                    },
                    {
                        url: 'XXXXXXXXX',
                        symbol: 'chalkboard-user',
                        color: '#047832'
                    },
                    {
                        url: 'XXXXXXXXX',
                        symbol: 'globe',
                        color: '#f93'
                    }
                ],
                fadePoint: 0.4,
                hideTime: true,
                showTimeToday: true,
                maximumNumberOfDays: 90,
                maximumEntries: 8,
                displaySymbol: true,
                colored: true,
                coloredSymbolOnly: true,
                wrapEvents: true,
                timeFormat: "relative",
                nextDaysRelative: true,
                hideOngoing: false,
                getRelative: 0
            }
        },
        {
            module: 'MMM-WeatherOrNot',
            position: 'bottom_bar',
            config: {
                location: 'XXXXX',
                locationCode: 'XXXXXXXXX',
                languages: 'en',
                tempUnits: 'F',
                days: '7',
                icons: 'Climacons Animated',
                theme: 'weather_one'
            }
        },
        {
            module: 'MMM-Dad-Jokes',
            position: 'top_bar',
            config: {
                updateInterval: 185001,
                filters: [
                    'damn',
                    'Hans free',
                    'Zimbabwe'
                ]
            }
        },
        {
            module: 'MMM-Wallpaper',
            position: 'fullscreen_below',
            config: {
                source: [
                    'bing',
                    '/r/EarthPorn',
                    '/r/spaceporn',
                    '/r/WaterPorn',
                    '/r/AnimalPorn',
                    '/r/NaturePorn',
                    '/r/NatureIsFuckingLit',
                    '/r/ITookAPicture',
                    '/r/ArchitecturalRevival',
                    '/r/naturepics',
                    '/r/ruralporn',
                    '/r/telephotolandscapes',
                ],
                maximumEntries: 20,
                filter: 'none',
                nsfw: false
            },
            header: ''
        },
        {
            module: 'MMM-Remote-Control',
            config: {
                customCommand: {
                    monitorOnCommand: 'vcgencmd display_power 1',
                    monitorOffCommand: 'vcgencmd display_power 0',
                    monitorStatusCommand: 'vcgencmd display_power -1 | grep -q ' +
                        '"display_power=1" && echo "true" || echo ' +
                        '"false"'
                },
                pm2ProcessName: "MagicMirror",
                apiKey: "XXXXXXXXX"
            }
        },
        {
            module: 'MMM-Powerwall',
            position: 'lower_third',
            config: {
                powerwallIP: 'XXXXXXXXX',
                powerwallPassword: 'XXXXXXXXX',
                teslaAPIUsername: 'XXXXXXXXX',
                teslaAPIPassword: 'XXXXXXXXX',
                home: [
                    XXXXXXXXX,
                    -XXXXXXXXX
                ],
                twcManagerIP: 'XXXXXXXXX',
                teslamate: {
                    url: "mqtt://XXXXXXXXX"
                },
                debug: true
            }
        },
        {
            module: 'MMM-WatchDog'
        }
    ]

};

/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") { module.exports = config; }

Additional Notes: The second emoji that appears in the screenshot is part of the event name.

khassel commented 1 year ago

cannot reproduce this with this calendar config:

                {
                        module: "calendar",
                        header: "German Holidays",
                        position: "top_left",
                        config: {
                                fadePoint: 0.4,
                                hideTime: true,
                                showTimeToday: true,
                                maximumNumberOfDays: 90,
                                maximumEntries: 8,
                                displaySymbol: true,
                                colored: true,
                                coloredSymbolOnly: true,
                                wrapEvents: true,
                                timeFormat: "relative",
                                nextDaysRelative: true,
                                hideOngoing: false,
                                getRelative: 0,
                                calendars: [
                                        {
                                                symbol: 'user-friends',
                                                color: '#fff380',
                                                url: "https://calendar.google.com/calendar/ical/de.german%23holiday%40group.v.calendar.google.com/public/basic.ics"
                                        }
                                ]
                        }
                },

grafik

Did you change css via custom.css?

MikeBishop commented 1 year ago

I'll grab the CSS when I'm at a keyboard, but in your repro attempt the event name wraps and the date string doesn't. In what I'm seeing, the date string is wrapped and the event name isn't. (Note the second line, which matches yours.)

khassel commented 1 year ago

Can now reproduce with this ics:

BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:xxx@gmail.com
X-WR-TIMEZONE:Europe/Zurich
BEGIN:VTIMEZONE
TZID:Etc/UTC
X-LIC-LOCATION:Etc/UTC
BEGIN:STANDARD
TZOFFSETFROM:+0000
TZOFFSETTO:+0000
TZNAME:GMT
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;VALUE=DATE:20230227
DTEND;VALUE=DATE:20230313
DTSTAMP:20210421T154106Z
UID:zzz@google.com
REATED:20200831T200244Z
DESCRIPTION:
LAST-MODIFIED:20200831T200244Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Birthday
TRANSP:OPAQUE
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:This is an event reminder
TRIGGER:-P0DT7H0M0S
END:VALARM
END:VEVENT
MikeBishop commented 1 year ago

Here's my custom.css:

.module:not(.MMM-WeatherOrNot),
.MMM-Wallpaper .title {
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 8px;
  padding: 8px;
}

.MMM-Wallpaper .title {
  bottom: 10px;
}

.region.top {
  top: -40px;
}

.region.left {
  max-width: 40%
}

.module.calendar_monthly {
  min-width: 300px;
}

iframe.iframe {
  width: 100%;
  max-height: 100px;
}

.region.lower.third {
  top: 62%;
}

.uptimerobot .friendlyName {
  text-align: left;
}

I don't see anything there I would expect to affect this. It looks like it happens when the date wraps, and the default rendering of a single-day event doesn't do that very often.

sdetweil commented 1 year ago

the calendar content is rows and columns in and html table

how does tr/td handle wrap?

khassel commented 1 year ago

grafik

grafik

grafik

Seems to be an edge case when the width is very small, I thinks its caused by the default calendar css but I'm not good in css stuff ...

sdetweil commented 1 year ago

the row (tr)expands to wrap the largest element in the table. default td centering is centered. horizontal & vertical td does not left/right expand, but wraps text symbol is forced up

khassel commented 1 year ago

this can be fixed by adding

.calendar .table {
  vertical-align: top;
}

in the custom.css file.

I'm not sure if this should be done in calendar.css because I don't know if this would have side effects on other calendar setups.

sdetweil commented 1 year ago

nice. think it should be custom.css

MikeBishop commented 1 year ago

While I'm certainly happy to fix my edge-case locally, it seems unfortunate to leave a bug in because it's difficult to do CSS targeting. Is that an existing concern with the calendar module, that CSS changes can impact other modules by accident?

khassel commented 1 year ago

didn't mean other modules but may others are happy with the horizontal centering. And may there is another reason that this is the default. If there is a majority to do this change in calender.css I can make a PR.

So @sdetweil @rejas whats your opinion?

MikeBishop commented 1 year ago

didn't mean other modules but may others are happy with the horizontal centering. And may there is another reason that this is the default. If there is a majority to do this change in calender.css I can make a PR.

I'd be perfectly happy with center-alignment, too, so long as they're all the same. The weird part is two columns aligning top and one aligning center; I think either way looks fine if they're consistent.

sdetweil commented 1 year ago

the time column is not aligning top, what u see is a side affect of the need to wrap the text. which centers the wrapped result vertically

if this is a bug, it's the symbol alignment

khassel commented 1 year ago

removing the first 3 lines (display, flex-direction, justify-content) in this section in calendar.css seems to solve this:

.calendar .symbol {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  padding-left: 0;
  padding-right: 10px;
  font-size: var(--font-size-small);
}
khassel commented 1 year ago

maybe @rejas remembers why he introduced this

grafik

MikeBishop commented 1 year ago

the time column is not aligning top, what u see is a side affect of the need to wrap the text. which centers the wrapped result vertically

I could certainly be using the wrong terms, but if you look at the case where the event name wraps and the time doesn't, the time string (and the icon) aligns with the first line of the wrapped event name.

sdetweil commented 1 year ago

@MikeBishop just an accident of the table expansion the tallest column wins

rejas commented 1 year ago

maybe @rejas remembers why he introduced this

most probably because vertical-align: top is such an old css and flex the way to position element these days (and grid too but for that I'd have to check the support with our browsers).

anyway, I'd go for more flex alignements in the normal css to have a general good look in our calendar.

khassel commented 1 year ago

thanks, so I looked where the vertical-align: top was introduced and found this PR.

Here one picture from this PR: with_wrap

The Icon was set to vertical-align: top but not the other columns as you can see in the time column. The time columns was set to top in a following commit so at the moment only the title colum is not.

So I think we should align all columns to top which would fix this issue.

CarJem commented 1 year ago

hope my accepted #3033 pr doesn't break things further...

rejas commented 1 year ago

hope my accepted #3033 pr doesn't break things further...

I think your PR did just fine :-)

looolz commented 1 year ago

I'm having an issue where the maxTitleLength: '29', isn't respected. Doesn't matter what number I put in there. The full title length is displayed. Anyone have any ideas?

Here the max title length displayed is more than 29 characters, making the entire mirror misalign.

image

`

{ module: 'calendar', header: '', position: 'top_left', config: { maximumEntries: '12', maximumNumberOfDays: '31', maxTitleLength: '29', hidePrivate: true, fade: false, displaySymbol: false, calendars: [ { symbol: 'calendar-check-o ', url: 'https://calendar.google.com/calendar/ical/URLURLURL/basic.ics' }, { symbol: 'cog ', url: 'https://racingnews365.com/ics/download/calendar-formula-2023.ics' }

          ]
      }
  },

`

sdetweil commented 1 year ago

please remove the quotes from the numeric values.

maximumEntries: '12',
maximumNumberOfDays: '31',
maxTitleLength: '29',

numbers should not have quotes, true/false should not have quotes if it has a letter or symbol in the value, then it needs quotes

rejas commented 1 year ago

I'm having an issue where the maxTitleLength: '29', isn't respected. Doesn't matter what number I put in there. The full title length is displayed. Anyone have any ideas?

Please open a new issue if this is still a problem for you @looolz