Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iPadOS Card rendering issue since HA 2024.8.0 #2908

Closed
PRProd opened this issue Aug 8, 2024 · 51 comments
Closed

iPadOS Card rendering issue since HA 2024.8.0 #2908

PRProd opened this issue Aug 8, 2024 · 51 comments
Assignees

Comments

@PRProd
Copy link

PRProd commented Aug 8, 2024

iOS device model, version and app version
Model Name: iPad (7th generation)
Software Version: 17.6
App version: (2024.730)

Home Assistant Core Version
2024.8.0

Describe the bug
After upgrading Home Assistant core to 2024.8.0, the rendering of some cards inside the iOS companion app has changed. Rendering in Chrome, Firefox, Safari, and the Android app still behave as expected after the upgrade to HA 2024.8.0.

To Reproduce

  • Use HA Core 2024.8.0
  • Download HA-Firemote available through HACS
  • Add one or more Firemote cards to your dashboard

Expected behavior
Rendering should look the same in the iPad companion app as it does everywhere else.

Screenshots

iPad Rendering through Safari

image

iPad Rendering through Home Assistant iOS Companion App

Image

Additional context
I have seen this behavior on a couple of other HACS cards as well, so I know it's not just limited to Firemote. I am the author of the Firemote card, so if any card design changes need to be made, please let me know.

@bgoncal
Copy link
Member

bgoncal commented Aug 9, 2024

Companion App Settings >> Debugging >> Reset frontend cache let me know if it helps, no change was done on the App side.

@bgoncal bgoncal self-assigned this Aug 9, 2024
@PRProd
Copy link
Author

PRProd commented Aug 9, 2024

@bgoncal ~

Thank you for your reply. I should have mentioned that I tried that multiple times before submitting the report. I also restarted my iPad a few times too.

I just tried again. I reset the frontend cache 4 times. Stopped and restarted the iPad app. Powered off, then powered on the iPad. Pulled down on the dashboard to see the refresh throbber a frew times. No change.

Since the iPad software hasn't changed on your end, I can only assume that something was changed in HA Core 2024.8.0 that somehow is affecting the way css, sizing, and spacing is being rendered by the iPad app. That's just a guess on my part though.

@PRProd
Copy link
Author

PRProd commented Aug 9, 2024

This issue is not unique to me. I just received this issue report from another Firemote user:
PRProd/HA-Firemote#478

@PRProd
Copy link
Author

PRProd commented Aug 9, 2024

Another example of the rendering issue affecting a different card
vasqued2/ha-teamtracker-card#95

@Kanecaine
Copy link

Having some problems with custom "weather chart card" within the companion app only. It seems that variable values are not rendered correctly. More infos are described here:

mlamberts78/weather-chart-card#222 (comment)

@vasqued2
Copy link

vasqued2 commented Aug 9, 2024

I can confirm it is impacting cards rendered using variables in css styles. Cards only using variables for content (i.e. icons or text) render fine.

vasqued2/ha-teamtracker#171

@mjaksn
Copy link

mjaksn commented Aug 10, 2024

In my case, configuring a custom user-agent string in Kiosk Pro that matches Safari on a fully updated iPad fixed the layout issues. I also reproduced the layout issue in a previously unaffected browser by intentionally sending an outdated UA string. These observations make me wonder if the problems could be related to home-assistant/frontend#16506.

@PRProd
Copy link
Author

PRProd commented Aug 10, 2024

As a status update, it appears that this issue still persists in 2024.8.1

@vasqued2
Copy link

The order of the cards on a dashboard tab change how the cards behave.

I render different a version of my card based on the state of a TeamTracker sensor. The state can be PRE (before a game), IN (during a game), or POST (after the game). If I have multiple cards on the same tab, the first card using variables in the style section will not render correctly. Additionally, any other cards with the same state as the first card will also not render correctly. However, cards with a different state will render correctly, even though they also use variables.

If I change the order of the cards on the tab so that a card with a different state is first. Suddenly, that card (and any other cards with the same state will stop working) and whatever card used to be first magically starts working.

@vasqued2
Copy link

Here is a workaround that takes advantage of card order impacting behavior. It appears to work for my Team Tracker card. Given that most cards use the same approach for invalid entities, I suspect it could work for other cards as well.

  1. Create a new Team Tracker card on the same dashboard tab that your other Team Tracker card/cards are on. If they are on multiple dashboard tabs, you must repeat this on each dashboard tab. The new card should contain a single line of YAML.
type: custom:teamtracker-card
  1. This should create a text visual for the card that simply says "Unknown entity:"
  2. Move this new card so it is the first one on the dashboard.
  3. Refresh the dashboard on the device having problems so the "Unknown entity:" card displays as the first card.
  4. All the other cards should magically render correctly once refreshed.
  5. OPTIONAL: Once you have confirmed this corrected the problem, if you have card-mod installed, you can change the YAML of the first card to hide the card with "Unknown entity:" As long as this card is first on the dashboard tab, the other cards should render correctly even if nothing is displayed.
type: custom:teamtracker-card
card_mod:
  style: |
    ha-card {
     display: none;
    }

Hopefully this helps others and also helps ID the root cause.

@Maddin1684
Copy link

This workaround doesn’t work with weather-chart-card

@vasqued2
Copy link

The problem is weather-chart-card has logic that auto-corrects bad YAML. I was able to get it to work by adding a manual card and pasting the YAML below and immediately saving. But if I go back in to re-edit the card, it auto-corrects the bad entity in the YAML and the workaround doesn't work any more.

Try pasting this code in and immediately savings before it has a chance to auto-correct it.

type: custom:weather-chart-card
entity: bad
forecast:
  precipitation_type: ''
units:
  pressure: ''
  speed: ''
card_mod:
  style: |
    ha-card {
     display: none;
    }

The card-mod is optional and can only be used if you have card-mod installed. If you do, it will hide the card with the error while still enabling the other cards to render correctly.

@Kanecaine
Copy link

Thanks @vasqued2 … can confirm the workaround works. At least this is enough:

type: custom:weather-chart-card
entity: 'bad'

Copied this in a new card and all weather-chart-cards after this one are beeing rendered fine. Thanks again!

@PRProd
Copy link
Author

PRProd commented Aug 11, 2024

@bgoncal ~ Do you need any more diagnostic help from any of us, or are you able to reproduce the issue on your end?

@bgoncal
Copy link
Member

bgoncal commented Aug 11, 2024

@bgoncal ~ Do you need any more diagnostic help from any of us, or are you able to reproduce the issue on your end?

I haven't checked those comments yet, I'm not working during the weekend, I'll follow up during this week, the only thing I did till now was to install firemote on my device and it rendered correctly, perhaps it is only in iPad?

@PRProd
Copy link
Author

PRProd commented Aug 11, 2024

perhaps it is only in iPad?

Yes. From all of the reports/issues I've found in other GitHub repositories, this seems to be ONLY happening on iPad.

@bgoncal
Copy link
Member

bgoncal commented Aug 11, 2024

perhaps it is only in iPad?

Yes. From all of the reports/issues I've found in other GitHub repositories, this seems to be ONLY happening on iPad.

Very weird since the code is shared, anyways, I'll have more details to you during the week, enjoy your Sunday ☀️

@vasqued2
Copy link

I haven't checked those comments yet, I'm not working during the weekend, I'll follow up during this week, the only thing I did till now was to install firemote on my device and it rendered correctly, perhaps it is only in iPad?

I was able to recreate it in Chrome Version 127.0.6533.100 (Official Build) (64-bit) on Windows by changing the User Agent in Developer Tools from 'Use browser default' to 'Chrome - iPad' in the drop down, which was 'Mozilla/5.0 (iPad; CPU OS 13_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/127.0.0.0 Mobile/15E148 Safari/604.1'.

That's where I was able to run some side-by-side comparisons in different tabs under different user agents and confirmed variables were coming into both correctly and the html that should have been generated from the template was the same even though what was actually being rendered was different. This is also where I was eventually able to figure out that changing the order of the cards changes which cards are impacted.

So far, it seems like the workaround which takes advantage of that fact works for the Firemote card, my Team Tracker card, and the Weather Chart card. So it looks like pretty consistent behavior across the cards reporting the issue.

I also did some quick tests with some other User Agents and was able to recreate with some of them, but I can't remember which ones. That, combined with the fact that it arose when I upgraded to HA 2024.8.0 and saw the problem on multiple iPads w/ different versions of the Apple app makes me think it was introduced with a Front End change in 2024.8.0, and not something w/ the Apple app itself.

Thanks for your help and let me know if you need anything else to help track it down.

@mjaksn
Copy link

mjaksn commented Aug 11, 2024

I just wanted to mention that I opened #2913, which I believe would resolve these layout issues seen in the iPad companion app. (Sorry, I accidentally included a GitHub keyword where I shouldn't have in the PR summary, which I edited out, but it looks like GitHub already acted on it)

@bgoncal
Copy link
Member

bgoncal commented Aug 12, 2024

I forwarded this issue to my peers from frontend to see if they know what could be causing that, somehow, as said in previous comments, the user-agent is breaking the card rendering.

@mjaksn while your PR may fix the issue for iPad, we still have the problem for macOS App, so I prefer to have a permanent fix instead since this wasn't happening before 2024.8 update.

I'll update you all as soon as I have more information.

@mjaksn
Copy link

mjaksn commented Aug 12, 2024

Thank you for the feedback, @bgoncal; the PR is closed. I was short-sighted there and appreciate your work investigating the issue with the frontend team.

@bgoncal
Copy link
Member

bgoncal commented Aug 12, 2024

@mjaksn Thank you for the proactivity 💪

@piitaya
Copy link
Member

piitaya commented Aug 13, 2024

I'd speculate this is probably a bug in the legacy build?

Yeah, it's a bug in the legacy build we should fix. I will check if we already had it few releases ago.

@piitaya
Copy link
Member

piitaya commented Aug 13, 2024

I just checked and the bug is present for legacy build for more than one year (tested with 2023.7).

@steverep
Copy link
Member

Okay, to level set, it sounds like we've got 2 problems here:

  1. The legacy build has a CSS variable issue we need to fix. We should open a frontend issue for that to keep it separate.
  2. The user agent string coming from the apps is being marked as legacy. My assumption would be that we need to fix that in this repo. I can dig into that.

As a related aside, the android app also modifies the user agent string. I don't have a setup to check, but I'll have to check that as well. If anyone could confirm or deny the legacy build being served on a modern device there, it would help.

@piitaya
Copy link
Member

piitaya commented Aug 13, 2024

Exactly! For the user agent modification, the iPhone one works, only the iPad one is broken. I will check with @bgoncal if we can improve that point!
And I will open a front end issue for the lit issue.

@steverep
Copy link
Member

So it looks like we already have some custom code in the iOS app to handle some sniffing that CodeMirror does.

@bgoncal can you educate me on why we modify the user agent string in the first place for the apps? I think it's fine to add to it, but in general to avoid any issues with the frontend or any of its dependencies, we should only add to it. Requests should contain the entire string as set by the webkit web view.

For completeness, here's the equivalent code in the android app.

@steverep
Copy link
Member

BTW, here's the current regex, which does return false for the app string above because it's just too different from what the browser would otherwise send (e.g. incorrectly identifying itself as OSX):

/Edge?\/(1{2}[6-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Firefox\/(1{2}[5-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Chrom(ium|e)\/(109|1[1-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|(Maci|X1{2}).+ Version\/(17\.\d+|(1[89]|[2-9]\d|\d{3,})\.\d+)([,.]\d+|)( \(\w+\)|)( Mobile\/\w+|) Safari\/|Chrome.+OPR\/(10[2-9]|1[1-9]\d|[2-9]\d{2}|\d{4,})\.\d+\.\d+|(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(15[._]([6-9]|\d{2,})|(1[6-9]|[2-9]\d|\d{3,})[._]\d+)([._]\d+|)|Android:?[ /-](1{2}[6-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})(\.\d+|)(\.\d+|)|Mobile Safari.+OPR\/([89]\d|\d{3,})\.\d+\.\d+|Android.+Firefox\/(1{2}[7-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|Android.+Chrom(ium|e)\/(1{2}[6-9]|1[2-9]\d|[2-9]\d{2}|\d{4,})\.\d+(\.\d+|)|SamsungBrowser\/(2[3-9]|[3-9]\d|\d{3,})\.\d+/.test(navigator.userAgent)

@steverep
Copy link
Member

@piitaya I'm assuming those strings are from the same device? What's interesting is that the browser is presenting itself as mobile, but the app webview is presenting itself as desktop. And the desktop string is missing the pieces that give the version, which can be seen by breaking down the regex:

// Safari (version comes from "Version/<version>" and also needs "Safari/")
/(Maci|X1{2}).+ Version\/(17\.\d+|(1[89]|[2-9]\d|\d{3,})\.\d+)([,.]\d+|)( \(\w+\)|)( Mobile\/\w+|) Safari\//

// iOS (version interpreted from platform part of string)
/(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(15[._]([6-9]|\d{2,})|(1[6-9]|[2-9]\d|\d{3,})[._]\d+)([._]\d+|)/

Whether or not the webview sends the desktop or mobile version looks to be controlled by WKWebpagePreferences.

@bgoncal
Copy link
Member

bgoncal commented Aug 14, 2024

So it looks like we already have some custom code in the iOS app to handle some sniffing that CodeMirror does.

@bgoncal can you educate me on why we modify the user agent string in the first place for the apps? I think it's fine to add to it, but in general to avoid any issues with the frontend or any of its dependencies, we should only add to it. Requests should contain the entire string as set by the webkit web view.

For completeness, here's the equivalent code in the android app.

I dont know exactly the background for this change but as you can see in this PR we are not overriding the user agent and instead appending to it, so the WKWebView itself presents as macOS on iPad. (More details here, as said in this thread, it can be tweaked)

The problem is that even if I fix this for iPad somehow and make it present itself as iPad, our macOS App suffers from the same issue, so we need a fix for it too.

@bgoncal
Copy link
Member

bgoncal commented Aug 14, 2024

This is a fresh new project with no modification of user agent at all and it is broken as well
CleanShot 2024-08-14 at 10 49 47@2x

@bgoncal
Copy link
Member

bgoncal commented Aug 14, 2024

user agent for the sample project above "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)"

@bgoncal
Copy link
Member

bgoncal commented Aug 14, 2024

This fixes the issue for iPad #2918, but not for macOS App, but I shouldn't have to set this preferredContentMode, Apples handle it, if it is an iPad mini it gets mobile websites content mode, if the iPad screen is bigger it gets desktop-class websites, mobile gets "iPad" in user agent, desktop gets "Macintosh".

In my opinion the regex needs to be updated to handle WKWebView and not the otherway around

@steverep
Copy link
Member

This fixes the issue for iPad #2918, but not for macOS App, but I shouldn't have to set this preferredContentMode, Apples handle it, if it is an iPad mini it gets mobile websites content mode, if the iPad screen is bigger it gets desktop-class websites, mobile gets "iPad" in user agent, desktop gets "Macintosh".

I think that change is perfectly fine for iPad, because it basically undoes the spoofing that Apple is performing internally. I do agree it's not ideal for Mac because then it just creates another spoof. For the HA frontend though, it's mostly a moot point because we don't use the user agent string to decide anything about what content to display. It's done based on screen size as it should be.

In my opinion the regex needs to be updated to handle WKWebView and not the otherway around

Actually, I'm going to blame Apple here, and looking around the web there are plenty of folks frustrated with this choice to spoof their own devices. The problem is that the starter string for Mac is void of any useful information on the underlying Safari version. It includes the Webkit build version, but no one uses that to distinguish support for any given feature, so it's ignored by parsers.

As I said on the frontend PR, I'm still researching the best solution here.

@slipx06
Copy link

slipx06 commented Aug 14, 2024

This issue was also reported to be present on a Galaxy Tab with Kiosk 6.1.0 and Huawei Matepad 7

@steverep
Copy link
Member

This issue was also reported to be present on a Galaxy Tab with Kiosk 6.1.0 and Huawei Matepad 7

@slipx06 where is that reported? What is the user agent string?

@slipx06
Copy link

slipx06 commented Aug 16, 2024

Hi @steverep. It was reported slipx06/sunsynk-power-flow-card#500 (comment)

@jzielke84 can you confirm the user agent strings

@jzielke84
Copy link

jzielke84 commented Aug 16, 2024

@jzielke84 can you confirm the user agent strings

Sniffing on http traffic from the Huawei MatePad running Fully Kiosk Browser, which causes problems:

User-Agent: Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36\r\n

Useragent on Homeassistant desktop app with also causes problems:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Home Assistant/2024.7 (io.robbie.HomeAssistant; build:2024.730; macOS 13.6.7) Mobile/HomeAssistant, like Safari

@slipx06
Copy link

slipx06 commented Aug 16, 2024

Thanks @jzielke84 I can confirm that both those user agents are causing an issue

These are some of the other user agent strings that dont work.

Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Mozilla/5.0 (Linux; U; Android 2.3.6; en-us; Nexus S Build/GRK39F) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
Mozilla/5.0 (iPhone; CPU iPhone OS 13_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/127.0.0.0 Mobile/15E148 Safari/604.1
Mozilla/5.0 (iPad; CPU OS 13_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/127.0.0.0 Mobile/15E148 Safari/604.1
Mozilla/5.0 (Android 4.4; Mobile; rv:70.0) Gecko/70.0 Firefox/70.0
Mozilla/5.0 (Android 4.4; Tablet; rv:70.0) Gecko/70.0 Firefox/70.0
Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4
Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:70.0) Gecko/20100101 Firefox/70.0
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 EdgiOS/44.5.0.10 Mobile/15E148 Safari/604.1

@piitaya
Copy link
Member

piitaya commented Aug 16, 2024

@slipx06, @jzielke84 Those are considered as legacy according to the new rules. Here's the new browser minimal versions to support the modern build :

Browser Legacy Current Modern New Modern
Android 60 63 115
Chrome 60 63 109
Edge 16 79 115
Firefox 52 67 115
iOS 10.3 13 15.6
Safari 11 13 16.6
Opera 47 50 101
Opera Mobile* - 80 80
Samsung 4 8.2 22

But even if it's legacy, all the HA feature should work. We did that change to reduce the bundle size for modern browser.

Also, good news : I found why these custom card have rendering issue when using legacy build 🎉
With HA 2024.8, more devices are considered as legacy so this issue wasn't often visible before but was still present.
The legacy build comes with ShadyCSS polyfill to support scoped CSS. One of the limitation is that doesn't support dynamic CSS : (source: https://github.com/webcomponents/polyfills/blob/master/packages/shadycss/README.md#dynamically-created-styles-are-not-supported).

I open a PR on Weather chart card repository. Same fix can be used for every custom card that have the same issue.

As a fix, The custom card code needs to use static styles and adapt the style using css variables and classes (classMap and styleMap) instead of using dynamic style with template literals. I don't think we can fix it on the HA side.

@jzielke84
Copy link

@piitaya Thank you for your research on this one. Maybe this should be published as a breaking change?

@bgoncal
Copy link
Member

bgoncal commented Aug 16, 2024

I'll be closing the issue in iOS repo since no App change is needed, feel free to keep discussing or move the conversation to frontend if needed.

Thanks @piitaya and @steverep !

@steverep
Copy link
Member

As a fix, The custom card code needs to use static styles and adapt the style using css variables and classes (classMap and styleMap) instead of using dynamic style with template literals. I don't think we can fix it on the HA side.

While making those template changes is definitely the best option, I researched more about what's going on here and there's more we can do. See home-assistant/frontend#21748, and let's move further discussion there.

@piitaya Thank you for your research on this one. Maybe this should be published as a breaking change?

This has already been mostly reversed by @bgoncal's change in this repo and home-assistant/frontend#21724 pending in the frontend. Given we are later in the month now, I'd expect you'd see those in 2024.9. I can also fix it further on everything but the oldest of old devices (see the frontend issue).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants