MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    1. Home
    2. Ragged4310
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.
    R
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 7
    • Groups 0

    Ragged4310

    @Ragged4310

    0
    Reputation
    4
    Profile views
    7
    Posts
    0
    Followers
    0
    Following
    Joined
    Last Online

    Ragged4310 Unfollow Follow

    Latest posts made by Ragged4310

    • RE: MMM-CalendarExt3

      @MMRIZE said in MMM-CalendarExt3:

      @Ragged4310

      See the green events
      0771ed78-ac78-4934-a294-ffb5c971240e-image.png

      b4009779-62fa-4c74-975d-5d5460f16111-image.png

      eventPayload in CX3 config;

      /* CX3 config section in `config/config.js` */
      eventPayload: (payload) => {
      	const targetCalendar = "Reservation"
      	const divideGap = 1000 * 60 * 60 * 1
      	const locale = 'en-US'
      	const timeStyle = { timeStyle: 'short' }
      
      	const condition = (ev) => { return (ev.calendarName === targetCalendar && ev.fullDayEvent === false) }
      	const target = payload.filter(condition).sort((a, b) => a.endDate - b.endDate)
      	const result = payload.filter(e => !condition(e))
      	const dateStr = (dateValue) => Intl.DateTimeFormat(locale, timeStyle).format(new Date(+dateValue))
      	const collapse = (template, ev) => {
      		if (!template?.["title"]) template = { ...ev, collapseCount: 0, description: '', location: '' }
      		template.collapseCount++
      		template.startDate = String(Math.min(+template.startDate, +ev.startDate))
      		template.endDate = String(Math.max(+template.endDate, +ev.endDate))
      		template.title = `${dateStr(template.startDate)} - ${dateStr(template.endDate)}`
      		if (template.collapseCount > 1) template.title += ` <span class="count">${template.collapseCount}</span>`
      		template.description += `<div class="collapsedEvent">
      			<p class="title">${ev.title}</p>
      			<p class="period">${dateStr(ev.startDate)} - ${dateStr(ev.endDate)}</p>`
      		if (ev.description) template.description += `<p class="description">${ev.description}</p>`
      		if (ev.location) template.description += `<p class="location">${ev.location}</p>`
      		template.description += '</div>'
      		return template
      	}
      	const dateKey = (dateValue) => new Date(+dateValue).toLocaleDateString('en-CA')
      	let collapsedEvent = {}
      	for (const ev of target) {
      		const currentKey = dateKey(ev.startDate)
      		if (!collapsedEvent?.[ 'title' ]) {
      			collapsedEvent = collapse(collapsedEvent, ev)
      			continue
      		}
      		const collapsedKey = dateKey(collapsedEvent.startDate)
      		if (collapsedKey !== currentKey || +ev.startDate - +collapsedEvent.endDate > divideGap) {
      			result.push(collapsedEvent)
      			collapsedEvent = collapse({}, ev)
      		} else {
      			collapsedEvent = collapse(collapsedEvent, ev)
      		}
      	}
      	if (collapsedEvent?.[ 'title' ]) result.push(collapsedEvent)
      	return result
      }
      

      You can modify targetCalendar, divideGap, locale ande timeStyle for your purpose.

      To beautify;

      /* css/custom.css */
      .CX3 .event.calendar_Reservation .headline .time {
        display: none;
      }
      
      #CX3_POPOVER .title .count,
      .CX3 .calendar_Reservation .title .count {
        font-weight: bold;
        color: gray;
      }
      
      #CX3_POPOVER .title .count::before,
      .CX3 .calendar_Reservation .title .count::before {
        content: "[";
      }
      
      #CX3_POPOVER .title .count::after,
      .CX3 .calendar_Reservation .title .count::after {
        content: "]";
      }
      
      #CX3_POPOVER .description .collapsedEvent {
        line-height: 115%;
        border-bottom: 2px solid silver;
      
        p {
          margin-top: 0;
          margin-bottom: 0;
        }
      
        .title {
          font-weight: bold;
        }
      
        .period {
          text-align: right;
        }
      
        .description {
          font-style: italic;
          white-space: pre;
          padding-left: 20px;
        }
      
        .location {
          font-style: italic;
          text-align: right;
        }
      }
      

      I had to play around with it a bit to get it just right, but you nailed it!

      alt text

      My calendar is a lot less cluttered now. Thank you for all your help!

      posted in Utilities
      R
      Ragged4310
    • RE: MMM-CalendarExt3

      @MMRIZE said in MMM-CalendarExt3:

      @Ragged4310
      According to the conditions you provided, the previous code cannot be used. Clear definition of the conditions is essential to come up with an appropriate solution.

      First, we need to clearly define the events that need to be collapsed. Based on your description, it seems they are in the form of “Person’s Name - Task.” Are you looking to group them by “Person’s Name”? However, it also seems that you do not want the “Person’s Name” to be exposed. In that case, how should they be displayed? For example, would you like them to be labeled sequentially as “Reservation 1,” “Reservation 2,” and so on?

      Please provide more details about the AS-IS and TO-BE states.

      Alternatively, assigning additional properties to the events to be grouped might also be a good approach. For instance, you could write the person’s name (e.g., Jane Doe) in the location or description field, and only include the task (e.g., Deep Tissue Massage) in the event title. Then, you could group events with the same description together.

      AS IS:
      My Google Calendar currently looks like the examples below. I transform event names containing keywords related to my wife’s services into a format that shows only the start and end time of each service, along with a small icon indicating it’s related to her work (massage therapy) on CX3.

      Example Events:

      Jane Smith: 60 - Custom Massage
      Event Time: 12:30pm - 2:00pm
      Location: <My wife’s business address>
      Description: Name of service / client’s phone number / client’s email

      John Doe: 90 - Custom Massage
      Event Time: 2:00pm - 4:00pm
      Location: <My wife’s business address>
      Description: Name of service / client’s phone number / client’s email

      Mike Example: 120 - Deep Tissue Massage
      Event Time: 4:00pm - 6:30pm
      Location: <My wife’s business address>
      Description: Name of service / client’s phone number / client’s email

      Johnny Smith: 30 - Deep Tissue Massage
      Event Time: 10:00pm - 10:30pm
      Location: <My wife’s business address>
      Description: Name of service / client’s phone number / client’s email

      TO BE:
      I’d prefer if the title in CX3 could show the time range of merged events only, along with the colored icon I’ve assigned for keywords (e.g., massage, reiki, trade, break, etc.) using ev.originalTitle.match.

      Example Output:

      12:30pm - 6:30pm [3]

      10:00pm - 10:30pm

      The 12:30 represents the start of the first service, and 6:30 represents the end of the last service. The [3] indicates the total number of collapsed events.

      The final event, 10:00pm - 10:30pm, would ideally remain separate due to the large gap. However, if separating it is too complex, it’s fine to merge all events into one block.

      The only consistent attribute across these events is the location. All events are synced from her booking software into her Google Calendar.

      I cannot group by Person’s Name because each client appears only once per day (I realize I could have used different names for clarity in the examples).

      I understand this request may be complex, and if a solution isn’t feasible, I can continue with my current setup. However, it would be great to have this functionality implemented as described.

      posted in Utilities
      R
      Ragged4310
    • RE: MMM-CalendarExt3

      @MMRIZE Thanks for the reply! I haven’t had too much time to play around with it just yet. Would I be completely replacing the event transformer with the payload, or would I be using both? If I’m using both, does the order matter?

      I currently use the transformer to set the icons and transform the title. Does your code only account for stuff that has the same name? With my wife’s schedule, her bookings are all something like this:

      Jane Doe: 60 - Deep Tissue Massage
      Jane Doe: 60 - Reflexology
      Break
      Jane Doe: 30 - Reiki

      etc., but I transform it to hide her client’s names on our calendar since it’s visible to whoever is in the house.

              eventTransformer: (ev) => {
                  
                const formatTime = (date) => new Intl.DateTimeFormat("en-US", {
                  hour: "numeric",
                  minute: "numeric",
                  hour12: true,
                }).format(new Date(date));
              
                const startTime = formatTime(ev.startDate);
                const endTime = formatTime(ev.endDate);
              
                if (!ev.originalTitle) {
                  ev.originalTitle = ev.title;
                }
              
                const titleParts = ev.originalTitle.split(":");
                const eventTitle = titleParts.length > 1 ? titleParts[1].trim() : ev.originalTitle;
              
                // Set default icon
                ev.symbol = ["fluent:vehicle-car-profile-ltr-clock-16-filled"];
              
                // Check if the event is not an all-day event
                if (!ev.isFullday) {
                  ev.title = `${startTime} ${eventTitle}`;
                } else {
                  ev.title = eventTitle;
                }
              
                // Rest of your existing conditions
                if (ev.originalTitle.toLowerCase().includes('work')) {
                  ev.symbol = ["material-symbols:work-history-outline-sharp"];
                  ev.title = `${startTime} - ${endTime}`;
                }
              
                if (ev.calendarName === "Family" && ev.originalTitle.toLowerCase().includes('windcreek')) {
                  ev.symbol = ["mdi:casino"];
                }
              
                if (ev.calendarName === "Family" && ev.originalTitle.toLowerCase().includes('board')) {
                  ev.symbol = ["mdi:cards-playing-spade-multiple"];
                }
              
                if (ev.calendarName === "Abigail") {
                  if (ev.originalTitle.match(/kung fu|tai chi/i)) {
                    ev.symbol = ["icon-park-solid:kungfu"];
                    ev.title = `${startTime} - ${endTime}`;
                  } else if (ev.originalTitle.match(/massage|reiki|trade|break|reflexology|deep|initial visit/i)) {
                    ev.symbol = ["tabler:massage"];
                    ev.title = `${startTime} - ${endTime}`;
                  }
                } else if (ev.calendarName === "Sebastian") {
                  ev.title = `${startTime} - ${endTime}`;
                } else if (ev.calendarName == "Birthday") {
                  ev.symbol = ["mingcute:cake-fill"];
                } else if (ev.calendarName == "Appointment") {
                  ev.symbol = ["lsicon:work-order-appointment-outline"];
                } else if (ev.calendarName == "Holiday") {
                  ev.symbol = ["openmoji:flag-us-outlying-islands"];
                }
              
                return ev;
              }
      

      Instead of checking the title directly, could I use some a contains check to see if it contains the character ‘:’ or ‘-’? I’ll be playing around with this tomorrow once I have some free time available.

      posted in Utilities
      R
      Ragged4310
    • RE: MMM-CalendarExt3

      @MMRIZE said in MMM-CalendarExt3:

      @Ragged4310
      Could you show me the example of the events?

      alt text

      I would like to consolidate the events with the little yellow massage person if its possible since she is gone for the whole time and it hogs up the event space. I tried using chatgpt and perplexity, but everytime they gave me something the calendar would not load.

      For Dec 11 she has 3 appointments back to back, instead of it taking up 3 lines I would prefer if I could get it to show 2:00PM - 7:00PM for one event.

      For Dec 23, she currently only has 2 appointments and there’s a small gap. Since the gap is < 2 hours I would like if I could consolidate that as well so it would show 10:00AM - 2:00PM.

      I don’t know the event transformer too well, so I’m not sure if it can handle something like that.

      Edit- Another thing I thought of… if it is possible to merge…
      Is there a way to store how many events were merged? I’ll use the Dec 11 for the example again. If I can merge all 3 events into one, could I have it stored in a variable where I can display (3) at the end of the event to indicate there were 3 events?

      posted in Utilities
      R
      Ragged4310
    • RE: MMM-CalendarExt3 How can I increase my cell height?

      @sdetweil said in MMM-CalendarExt3 How can I increase my cell height?:

      @Ragged4310 you didn’t change event-height or total height

      You could use the css media screen value to get the screen size to adjust

      Thanks for the advice. I solved my problem when I tweaked my display by adding more event lines and a legend so I didn’t end up needing to mess with the CSS.

      posted in Custom CSS
      R
      Ragged4310
    • RE: MMM-CalendarExt3

      My wife takes appointments for her business, so she has a lot of events each day she works. I want to be able to merge back-to-back events and show the start time of the first event and the end time of the last event to reduce the number of entries on the calendar.

      Ideally, I would like something that could account for gaps between appointments as well since she will still be at work. Ie) I can set the transformer to combine all events that are <= 2 hours apart, and it will show me the start time of the first event and the end time of the last event. I know it’s asking for a lot, and it’s probably not even possible, but I wanted to ask.

      posted in Utilities
      R
      Ragged4310
    • MMM-CalendarExt3 How can I increase my cell height?

      Hello,

      I would like to increase the cell height of my calendar, mainly when it’s in full-screen mode. I’ve tried messing with the cell-body, cell height, and tried getting chatGPT to help me but I cannot figure out how to do it.

      Here’s my CSS:

      /* Global Settings */
      body {
          margin: 0;
          height: 100%;
          width: 100%;
          background: rgb(0 0 0 / 100%);
          color: white;
        }
        
        .dimmed,
        .normal,
        .bright {
          color: white;
        }
        
        /* Region Definitions */
        .region.top.right,
        .region.bottom.right {
          position: absolute;
          width: 79%;
        }
        
        .region.top.left,
        .region.bottom.left,
        .region.middle.center {
          position: absolute;
          width: 20.5%;
        }
        
        .region.fullscreen.below {
          position: absolute;
          width: 24.25%;
        }
        
        /* Clock Options */
        .clock {
          float: right;
          text-align: right;
        }
        
        .clock .time {
          font-size: 90px;
        }
        
        /* MMM-GoogleTrafficTimes - Horizontal Layout */
        .MMM-GoogleTrafficTimes {
          position: absolute; /* Prevents it from affecting layout */
          top: 50px; /* Adjust this value to align with MMM-CoinMarketCap */
          left: 50%;
          transform: translateX(-50%); /* Centers horizontally */
          display: flex;
          justify-content: center; /* Center horizontally */
          align-items: center;
          flex-wrap: wrap;
          margin: 0; /* Remove any margins */
          padding: 0;
          width: auto; /* Prevents it from taking unnecessary width */
          height: auto; /* Ensures no vertical overflow */
          z-index: 10; /* Makes it appear above other modules if needed */
        }
        
        .MMM-GoogleTrafficTimes .destination {
          margin: 0 10px;
          text-align: center;
          font-size: 16px;
        }
        
        .MMM-GoogleTrafficTimes .destination .label {
          font-weight: bold;
          font-size: 14px;
        }
        
        /* MMM-CoinMarketCap Adjustments */
        .MMM-CoinMarketCap {
          position: absolute; /* Prevents it from being pushed */
          top: 50px; /* Matches the vertical position of MMM-GoogleTrafficTimes */
          right: 0;
          padding: 0;
          margin: 0;
        }
        
        .MMM-CoinMarketCap .graphWithChanges {
          display: inline-block; /* Ensures proper alignment */
        }
        
        /* MMM-CalendarExt3 Options */
        .CX3 {
          --celllinecolor: #333;
          --cellbgcolor: rgba(0, 0, 0, 0.2);
          --cellheaderheight: 25px;
          --cellfooterheight: 2px;
          --defaultcolor: #FFF;
          --eventheight: calc(var(--fontsize) + 4px);
          --totalheight: calc(var(--eventheight) * var(--maxeventlines));
          font-size: var(--fontsize);
          color: var(--defaultcolor);
          line-height: calc(var(--eventheight));
        }
        
        .MMM-CalendarExt3 {
          margin-top: 100px;
          height: calc(100% - 100px);
        }
        
        .CX3 .cellContainer {
          display: grid;
          grid-template-columns: repeat(7, 1fr);
          grid-template-rows: repeat(5, var(--cellheight));
          gap: 2px;
        }
        
        .CX3 .cell {
          height: var(--cellheight);
          overflow: hidden;
        }
        
        .CX3 .weekGridRow {
          margin-bottom: 0;
        }
        
        .CX3 .event {
          height: var(--eventheight);
        }
        
        .CX3 .event .headline {
          display: flex;
          align-items: center;
        }
        
        .CX3 .event .symbol {
          margin-right: 4px;
        }
        
        .CX3 .event .time {
          margin-right: 4px;
        }
        
        .CX3 .cellHeader {
          height: var(--cellheaderheight);
          display: flex;
          justify-content: space-between;
          align-items: center;
        }
        
        .CX3 .cellHeader .cellDate {
          font-weight: bold;
        }
        
        .CX3 .cellFooter {
          height: var(--cellfooterheight);
        }
        
        .CX3 .weekend {
          background-color: rgba(255, 255, 255, 0.1);
        }
        
        .CX3 .today {
          background-color: rgba(255, 255, 255, 0.2);
        }
        
        .CX3 .passed {
          opacity: 0.6;
        }
        
        .CX3 .multiday {
          border-radius: 4px;
        }
        
        .CX3 .fullday {
          background-color: rgba(255, 255, 255, 0.1);
          border-radius: 4px;
        }
        
        .CX3 .legends {
          display: flex;
          justify-content: flex-end;
          margin-top: 8px;
        }
        
        .CX3 .legends .legend {
          margin-left: 8px;
          display: flex;
          align-items: center;
        }
        
        .CX3 .legends .legend .symbol {
          margin-right: 4px;
        }
        
        /* MMM-OpenWeatherForecast */
        .MMM-OpenWeatherForecast {
          display: flex;
          flex-direction: column;
          align-items: center;
          text-align: center;
        }
        
        .MMM-OpenWeatherForecast .weather-icon {
          margin: 0 auto;
        }
        
        /* MMM-Todoist Centering */
        .MMM-Todoist {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          text-align: center;
          margin: 0 auto;
          width: 100%;
          max-width: 95%;
          overflow: hidden;
          box-sizing: border-box;
        }
      

      Here is my fullscreen view:
      alt text

      Here is my view when it is not full screen:
      alt text

      I would like if the full screen view had the same gap as it does when its not in full screen, just have the module / cells stretched up so more events can be displayed.

      posted in Custom CSS
      R
      Ragged4310