Skip to content

Commit b690bc3

Browse files
committedFeb 11, 2024·
fix: Bug fix for mobile view on most major browsers
1 parent 313e677 commit b690bc3

File tree

2 files changed

+78
-77
lines changed

2 files changed

+78
-77
lines changed
 

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"files": [
1212
"./dist"
1313
],
14-
"version": "1.1.0",
14+
"version": "1.2.0",
1515
"description": "Enrich Conversations - Power & Flexibility at Your Fingertips!",
1616
"type": "module",
1717
"main": "./dist/index.cjs",

‎src/components/ChatBotContainer.tsx

+77-76
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,20 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => {
8181
// tracks count of unread messages
8282
const [unreadCount, setUnreadCount] = useState<number>(0);
8383

84-
// tracks view port height (for auto-resizing on mobile view)
84+
// tracks view port height and width (for auto-resizing on mobile view)
8585
const [viewportHeight, setViewportHeight] = useState<number>(window.visualViewport?.height as number
8686
|| window.innerHeight);
87+
const [viewportWidth, setViewportWidth] = useState<number>(window.visualViewport?.width as number
88+
|| window.innerWidth);
8789

8890
// tracks previous window scroll position to go back to on mobile
89-
const [windowScrollPos, setWindowScrollPos] = useState(0);
91+
const scrollPositionRef = useRef<number>(0);
9092

9193
// adds listeners and render chat history button if enabled
9294
useEffect(() => {
9395
window.addEventListener("click", handleFirstInteraction);
9496
window.addEventListener("keydown", handleFirstInteraction);
9597
window.addEventListener("touchstart", handleFirstInteraction);
96-
if ("visualViewport" in window && !isDesktop && !botOptions.theme?.embedded) {
97-
window.visualViewport?.addEventListener("resize", handleResize);
98-
}
9998

10099
setUpNotifications();
101100
setTextAreaDisabled(botOptions.chatInput?.disabled as boolean);
@@ -120,42 +119,82 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => {
120119
window.removeEventListener("click", handleFirstInteraction);
121120
window.removeEventListener("keydown", handleFirstInteraction);
122121
window.removeEventListener("touchstart", handleFirstInteraction);
123-
if ("visualViewport" in window && !isDesktop && !botOptions.theme?.embedded) {
124-
window.visualViewport?.removeEventListener("resize", handleResize);
125-
}
126122
};
127123
}, []);
128124

125+
// used to handle virtualkeyboard api (if supported on browser)
126+
useEffect(() => {
127+
// if is desktop or is embedded bot, nothing to resize
128+
if (isDesktop || botOptions.theme?.embedded) {
129+
return;
130+
}
131+
132+
if ("virtualKeyboard" in navigator) {
133+
// @ts-ignore
134+
navigator.virtualKeyboard.overlaysContent = true;
135+
// @ts-ignore
136+
navigator.virtualKeyboard.addEventListener("geometrychange", (event) => {
137+
const { x, y, width, height } = event.target.boundingRect;
138+
// width does not need adjustments so only height is adjusted
139+
if (x == 0 && y == 0 && width == 0 && height == 0) {
140+
setTimeout(() => {
141+
setViewportHeight(window.visualViewport?.height as number);
142+
}, 501);
143+
} else {
144+
setTimeout(() => {
145+
setViewportHeight(window.visualViewport?.height as number - height);
146+
}, 501);
147+
}
148+
});
149+
}
150+
}, [])
151+
129152
// triggers check for notifications
130153
useEffect(() => {
131154
handleNotifications();
132155
}, [messages]);
133156

134-
// resets unread count when chat window is opened
157+
// resets unread count on opening chat and handles scrolling/resizing window on mobile devices
135158
useEffect(() => {
136159
if (botOptions.isOpen) {
137160
setUnreadCount(0);
138-
if (!isDesktop) {
139-
setWindowScrollPos(window.scrollY);
140-
if (document.documentElement.scrollWidth > document.documentElement.clientWidth) {
141-
return;
142-
}
161+
setViewportHeight(window.visualViewport?.height as number);
162+
setViewportWidth(window.visualViewport?.width as number);
163+
}
143164

144-
// only use scroll event to scroll to top if page is not scrollable horizontally
145-
// currently unable to resolve bug with chat window view on mobile when page is scrollable horizontally
146-
window.addEventListener("scroll", handleScroll);
165+
if (isDesktop) {
166+
return;
167+
}
147168

148-
return () => {
149-
if (document.documentElement.scrollWidth > document.documentElement.clientWidth) {
150-
return;
151-
}
152-
window.removeEventListener("scroll", handleScroll);
153-
};
154-
}
169+
// handles scrolling of window when chat is open (only for mobile view).
170+
const handleMobileScrollOpened = () => window.scrollTo({top: 0, left: 0, behavior: "auto"});
171+
// handles scrolling of window when chat is closed (only for mobile view).
172+
const handleMobileScrollClosed = () => scrollPositionRef.current = window.scrollY;
173+
const handleResize = () => {
174+
setViewportHeight(window.visualViewport?.height as number);
175+
setViewportWidth(window.visualViewport?.width as number);
176+
}
177+
178+
if (botOptions.isOpen) {
179+
window.removeEventListener('scroll', handleMobileScrollClosed);
180+
document.body.style.position = "fixed";
181+
window.addEventListener("scroll", handleMobileScrollOpened);
182+
window.visualViewport?.addEventListener("resize", handleResize);
183+
184+
return () => {
185+
window.removeEventListener("scroll", handleMobileScrollOpened);
186+
window.visualViewport?.removeEventListener("resize", handleResize);
187+
};
155188
} else {
156-
if (!isDesktop) {
157-
window.scrollTo({top: windowScrollPos, left: 0, behavior: "auto"});
158-
}
189+
document.body.style.position = "static";
190+
window.removeEventListener("scroll", handleMobileScrollOpened);
191+
window.scrollTo({top: scrollPositionRef.current, left: 0, behavior: "auto"});
192+
window.addEventListener('scroll', handleMobileScrollClosed);
193+
window.visualViewport?.removeEventListener("resize", handleResize);
194+
195+
return () => {
196+
window.removeEventListener("scroll", handleMobileScrollClosed);
197+
};
159198
}
160199
}, [botOptions.isOpen]);
161200

@@ -190,30 +229,6 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => {
190229
setIsBotTyping(false);
191230
}
192231

193-
/**
194-
* Handles resizing of view port (only for mobile view). KIV - Refer to comments below.
195-
*/
196-
const handleResize = () => {
197-
// if not mobile, nothing to do
198-
if (isDesktop || document.documentElement.scrollWidth > document.documentElement.clientWidth) {
199-
return;
200-
}
201-
// only resize viewport if page is not scrollable horizontally (remove this condition if fix is found)
202-
// currently unable to resolve bug with chat window view on mobile when page is scrollable horizontally
203-
setViewportHeight(window.visualViewport?.height as number);
204-
};
205-
206-
/**
207-
* Handles scrolling of window when chat is open (only for mobile view). KIV - Refer to comments below.
208-
*/
209-
const handleScroll = () => {
210-
// if not mobile or chat window is close, nothing to do
211-
if (isDesktop) {
212-
return;
213-
}
214-
window.scrollTo({top: 0, left: 0, behavior: "auto"});
215-
}
216-
217232
/**
218233
* Sets up the notifications feature (initial toggle status and sound).
219234
*/
@@ -440,15 +455,15 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => {
440455
* Retrieves styles for chat window.
441456
*/
442457
const getChatWindowStyle = () => {
443-
if (!isDesktop) {
458+
if (!isDesktop && !botOptions.theme?.embedded) {
444459
return {
445460
...botOptions.chatWindowStyle,
446461
borderRadius: '0px',
447462
left: '0px',
448463
right: 'auto',
449464
top: '0px',
450465
bottom: 'auto',
451-
width: '100%',
466+
width: `${viewportWidth}px`,
452467
height: `${viewportHeight}px`,
453468
}
454469
} else {
@@ -471,29 +486,15 @@ const ChatBotContainer = ({ flow }: { flow: Flow }) => {
471486
<ChatBotTooltip/>
472487
<ChatBotButton unreadCount={unreadCount}/>
473488
{/* styles and prevents background from scrolling on mobile when chat window is open */}
474-
{botOptions.isOpen && !isDesktop &&
475-
<>
476-
<style>
477-
{`
478-
html, body {
479-
overflow: hidden;
480-
touch-action: none;
481-
}
482-
`}
483-
</style>
484-
<div
485-
style={{
486-
position: "fixed",
487-
top: 0,
488-
left: 0,
489-
width: "100%",
490-
height: "100%",
491-
backgroundColor: "#fff",
492-
zIndex: 9999
493-
}}
494-
>
495-
</div>
496-
</>
489+
{botOptions.isOpen && !isDesktop && !botOptions.theme?.embedded &&
490+
<style>
491+
{`
492+
body {
493+
overflow: hidden;
494+
touch-action: none;
495+
}
496+
`}
497+
</style>
497498
}
498499
<div
499500
style={getChatWindowStyle()}

0 commit comments

Comments
 (0)
Please sign in to comment.