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

Opening Livechat React widget resets CSS variables #40

Closed
leo-petrucci opened this issue May 10, 2022 · 7 comments
Closed

Opening Livechat React widget resets CSS variables #40

leo-petrucci opened this issue May 10, 2022 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@leo-petrucci
Copy link

I'm currently experiencing a problem with React's LiveChat widget, I hope someone can shed some light and possibly suggest a fix.

Our app currently runs in a native web view, which allows us to use React (HTML, JS and CSS) as a frontend for our native app.

When running the web view, iOS exposes CSS env() variables like safe-area-inset-top, which is a non-zero value in case the phone has a notch. This variable is used to define a safe area so that content isn't rendered behind the notch.

This works pretty well except when we open the LiveChat widget, which seemingly sets all the values to 0.

How the App usually looks:
Screenshot 2022-05-10 at 14 18 11

How the chat looks when the LiveChat component is open:
Screenshot 2022-05-10 at 14 22 23

You can see the minimise button is being rendered behind the notch. And if I increase the padding of the iframe rendering he chat, I can take a peek behind to reveal the CSS variables setting the safe areas have been reset:
Screenshot 2022-05-10 at 14 23 58

If I go look at my inspector, I can tell that --safe-area-inset-top (which I previously assigned to env(safe-area-inset-top) has been set to 0.

The strange thing is that before opening LiveChat, I can see that #chat-widget-container actually has a non-zero value assigned to the variable, which is then set to 0 the moment I click on the button to open LiveChat.

Our implementation is pretty standard:

      <LiveChatWidget
        license={liveChatLicense}
        visibility={visibility}
        customerEmail={user.data?.data.email}
        customerName={user.data?.data.firstName}
      />

Any idea how we can work around this issue?

@leo-petrucci
Copy link
Author

I don't know if anyone will ever see this but my workaround ended up being this:

Save CSS variables in a local ref:

  const safeAreaRef = useRef({
    top: getComputedStyle(document.documentElement).getPropertyValue(
      '--ion-safe-area-top'
    ),
    bottom: getComputedStyle(document.documentElement).getPropertyValue(
      '--ion-safe-area-bottom'
    ),
  });

Then inject them into the CSS with something like emotion:

import { css, Global } from '@emotion/react';

// ...

      <Global
        styles={css`
          #chat-widget-container iframe {
            padding-top: ${safeAreaRef.current.top} !important;
            padding-bottom: ${safeAreaRef.current.bottom} !important;
          }
        `}
      />

@walaszczykm
Copy link
Collaborator

Hello @creativiii 👋
Thanks for the report. Sad to hear you have encountered an issue with the library.

For the future, please use dedicated Issue templates as they provide questions for all necessary information we need for problem investigation. Also, they automatically assign our team, which notifies us about reports much quicker 🙂

In the case of safe-area-inset-top nowhere in our code, we are setting this value explicitly, nor we are affecting the host CSS variables. I wonder if the issue is not related to the native webview behavior itself, changing the safe-area-inset-top to 0 for maximized absolute content of Chat Widget. At the moment your workaround looks very solid. We will take a look if we can do something about it in a more pleasant way for you as an Application Developer 🙂

@walaszczykm walaszczykm self-assigned this May 25, 2022
@walaszczykm walaszczykm added the bug Something isn't working label May 25, 2022
@leo-petrucci
Copy link
Author

leo-petrucci commented May 25, 2022

Thank you for the reply @walaszczykm!

The issue templates didn't pop-up when opening a new issue so I assumed there were none, sorry 😅

I had a look at the source and I couldn't find any code related to CSS variables either which was pretty strange. It could have something to do with the chat being rendered in an iframe, and the html within it overriding the CSS variables of the containing html tag?

No idea. I'll create a reproduction as soon as I have time!

@Saqib92
Copy link

Saqib92 commented May 31, 2022

For ionic / Angular / CapacitorJs:

in html add Events:

<livechat-widget license="123456789" visibility="minimized" (onVisibilityChanged)="visiChange($event)"></livechat-widget>

in ts:

 visiChange(event: EventHandlerPayload<'onVisibilityChanged'>) {
    if (Capacitor.getPlatform() == 'ios') {
      if (event.visibility == 'minimized') {
        let a = document.getElementById('chat-widget-container') as HTMLElement;
        setTimeout(() => {
          let b = a.firstChild as HTMLElement;
          b.style.margin = "0";
        }, 500)
      }else{
        let a = document.getElementById('chat-widget-container') as HTMLElement;
        setTimeout(() => {
          let b = a.firstChild as HTMLElement;
          b.style.margin = "56px 0"
        }, 500)
      }
    }
  }

@leo-petrucci
Copy link
Author

For ionic / Angular / CapacitorJs:

in html add Events:

<livechat-widget license="123456789" visibility="minimized" (onVisibilityChanged)="visiChange($event)"></livechat-widget>

in ts:

 visiChange(event: EventHandlerPayload<'onVisibilityChanged'>) {
    if (Capacitor.getPlatform() == 'ios') {
      if (event.visibility == 'minimized') {
        let a = document.getElementById('chat-widget-container') as HTMLElement;
        setTimeout(() => {
          let b = a.firstChild as HTMLElement;
          b.style.margin = "0";
        }, 500)
      }else{
        let a = document.getElementById('chat-widget-container') as HTMLElement;
        setTimeout(() => {
          let b = a.firstChild as HTMLElement;
          b.style.margin = "56px 0"
        }, 500)
      }
    }
  }

Careful with setting hardcoded margins, not all iPhone screens have notches, and the ones that don't are quite small!

@Saqib92
Copy link

Saqib92 commented May 31, 2022

For ionic / Angular / CapacitorJs:
in html add Events:
<livechat-widget license="123456789" visibility="minimized" (onVisibilityChanged)="visiChange($event)"></livechat-widget>
in ts:

 visiChange(event: EventHandlerPayload<'onVisibilityChanged'>) {
    if (Capacitor.getPlatform() == 'ios') {
      if (event.visibility == 'minimized') {
        let a = document.getElementById('chat-widget-container') as HTMLElement;
        setTimeout(() => {
          let b = a.firstChild as HTMLElement;
          b.style.margin = "0";
        }, 500)
      }else{
        let a = document.getElementById('chat-widget-container') as HTMLElement;
        setTimeout(() => {
          let b = a.firstChild as HTMLElement;
          b.style.margin = "56px 0"
        }, 500)
      }
    }
  }

Careful with setting hardcoded margins, not all iPhone screens have notches, and the ones that don't are quite small!

Yes i know. But my Targeted Devices are new. and i think all new devices have notches. But thanks for the tip.

@walaszczykm
Copy link
Collaborator

The issue comes directly from the native web view behavior, and we are not going to implement any web view-specific CSS style fixes atm. The proposed workaround #40 (comment) looks solid and can be easily used while embedding the Chat Widget into a native webview.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants