Skip to content

Commit

Permalink
refactor: improvements after removing simplebar dep (#2903)
Browse files Browse the repository at this point in the history
This is a continuation of: #2900
Several things done here:
* Remove `scrollable-content` generic component and create it for each
scrollable div.
* Add notable refs (`webchatRef`, `chatAreaRef`, `headerRef`) in
`WebchatContext` to be accessed from different parts of the coee
* Remove JS commented code already migrated to TS.
* Reduce `util/dom.js` in favour of using new hooks.
* Migrate from JS to TS:
   * `device-adapter`
   * `scrollbar-controller`
   * `webchat-resizer`
* Simplify `WebchatHeader` component
* New hooks:
* `useScrollToBottom`: centralize logic for scrolling to the end of
scrollable messages list container
* `useVirtualKeyboardDetection`: detect whether virtual keyboard is open
or not (iOS/Safari)
* `useWebchatDimensions`: recalculation of webchat / chat area heights
* Create a new component `WebchatChatArea`
* Set textarea fontsize to 16px to be consistent with the rest of styles
and avoid auto-focusing issues on iOS.

---------

Co-authored-by: Oriol Raventos <[email protected]>
  • Loading branch information
vanbasten17 and Iru89 committed Oct 3, 2024
1 parent 24dd467 commit 64b9c00
Show file tree
Hide file tree
Showing 27 changed files with 539 additions and 430 deletions.
10 changes: 7 additions & 3 deletions packages/botonic-react/src/components/carousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import RightArrow from '../assets/rightArrow.svg'
import { COLORS, WEBCHAT } from '../constants'
import { WebchatContext } from '../contexts'
import { resolveImage } from '../util/environment'
import { ScrollableContent } from '../webchat/components/scrollable-content'
import { ButtonsDisabler } from './buttons-disabler'
import { Message } from './message'

const ScrollableCarousel = styled.div`
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
`

const StyledCarousel = styled.div`
padding: 10px 0px;
display: flex;
Expand Down Expand Up @@ -147,15 +151,15 @@ export const Carousel = props => {

if (isBrowser()) {
content = (
<ScrollableContent>
<ScrollableCarousel>
<StyledCarousel
ref={carouselRef}
carouselArrowsEnabled={carouselArrowsEnabled}
>
<StyledItems>{carouselProps.children}</StyledItems>
{carouselArrowsEnabled && getArrows()}
</StyledCarousel>
</ScrollableContent>
</ScrollableCarousel>
)
}

Expand Down
6 changes: 6 additions & 0 deletions packages/botonic-react/src/contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,10 @@ export const WebchatContext = createContext<WebchatContextProps>({
trackEvent: async () => {
return
},
webchatRef: { current: null },
chatAreaRef: { current: null },
inputPanelRef: { current: null },
headerRef: { current: null },
scrollableMessagesListRef: { current: null },
repliesRef: { current: null },
})
57 changes: 6 additions & 51 deletions packages/botonic-react/src/index-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,51 +55,6 @@ export interface CustomMessageType {
customTypeName: string
}

// TODO: Reuse types to be reused in respective components
// export class WebchatApp {
// constructor(options: WebchatAppArgs)
// addBotMessage(message: WebchatMessage): void
// addBotText(text: string): void
// addUserMessage(message: WebchatMessage): void
// addUserPayload(payload: string): void
// addUserText(text: string): void
// clearMessages(): void
// close(): void
// closeCoverComponent(): void
// destroy(): void
// getComponent(
// host: HTMLElement,
// optionsAtRuntime?: WebchatAppArgs
// ): React.ForwardRefExoticComponent<any>
// getLastMessageUpdate(): string
// getMessages(): WebchatMessage[]
// getVisibility(): Promise<boolean>
// isWebchatVisible({ appId: string }): Promise<boolean>
// onCloseWebchat(args: any): void
// onInitWebchat(args: any): void
// onOpenWebchat(args: any): void
// onServiceEvent(event: Event): void
// onStateChange(args: OnStateChangeArgs): void
// onUserInput(args: OnUserInputArgs): Promise<void>
// open(): void
// openCoverComponent(): void
// render(dest?: HTMLElement, optionsAtRuntime?: WebchatAppArgs): void
// resendUnsentInputs(): Promise<void>
// resolveWebchatVisibility(optionsAtRuntime: {
// appId: string
// visibility: () => boolean
// }): Promise<boolean>
// setTyping(enable: boolean): void
// toggle(): void
// toggleCoverComponent(): void
// updateMessageInfo(msgId: string, messageInfo: MessageInfo): void
// updateLastMessageDate(date: string): void
// updateUser(user: Partial<CoreSessionUser>): void
// updateWebchatSettings(settings: WebchatSettingsProps): void
// renderCustomComponent(customComponent: React.ReactNode): void
// unmountCustomComponent(): void
// }

export interface WebchatArgs {
blockInputs?: BlockInputOption[]
coverComponent?: CoverComponentOptions
Expand Down Expand Up @@ -216,10 +171,10 @@ export interface WebchatContextProps {
updateWebchatDevSettings: (settings: WebchatSettingsProps) => void
webchatState: WebchatState
trackEvent: TrackEventFunction
webchatRef: React.MutableRefObject<HTMLDivElement | null>
chatAreaRef: React.MutableRefObject<HTMLDivElement | null>
inputPanelRef: React.MutableRefObject<HTMLDivElement | null>
headerRef: React.MutableRefObject<HTMLDivElement | null>
scrollableMessagesListRef: React.MutableRefObject<HTMLDivElement | null>
repliesRef: React.MutableRefObject<HTMLDivElement | null>
}

// export class DevApp extends WebchatApp {
// constructor(args: WebchatAppArgs)
// onUserInput(args: OnUserInputArgs): Promise<void>
// render(dest: HTMLElement, optionsAtRuntime: WebchatAppArgs): void
// }
31 changes: 0 additions & 31 deletions packages/botonic-react/src/util/dom.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,5 @@
import { WEBCHAT } from '../constants'
import { BotonicContainerId } from '../webchat/constants'

export const getScrollableContent = webchatElement => {
return webchatElement.querySelector(
`#${BotonicContainerId.ScrollableContent}`
)
}

export const getScrollableArea = webchatElement => {
return {
full: document.getElementById(BotonicContainerId.ScrollableContent),
visible: document.getElementById(BotonicContainerId.ChatArea),
}
}

export const scrollToBottom = ({
timeout = 200,
behavior = 'smooth',
host,
} = {}) => {
const webchatElement = getWebchatElement(host)
if (!webchatElement) return
const frame = getScrollableArea(webchatElement).full

if (frame) {
setTimeout(
() => frame.scrollTo({ top: frame.scrollHeight, behavior: behavior }),
timeout
)
}
}

export const getWebchatElement = host =>
host && host.querySelector(`#${BotonicContainerId.Webchat}`)

Expand Down

This file was deleted.

3 changes: 2 additions & 1 deletion packages/botonic-react/src/webchat/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const BotonicContainerId = {
Webchat: 'botonic-webchat',
Header: 'botonic-header',
ChatArea: 'botonic-chat-area',
ScrollableContent: 'botonic-scrollable-content',
ScrollableMessagesList: 'botonic-scrollable-messages-list',
RepliesContainer: 'botonic-replies-container',
InputPanel: 'botonic-input-panel',
}
43 changes: 0 additions & 43 deletions packages/botonic-react/src/webchat/devices/device-adapter.js

This file was deleted.

109 changes: 0 additions & 109 deletions packages/botonic-react/src/webchat/devices/scrollbar-controller.js

This file was deleted.

Loading

0 comments on commit 64b9c00

Please sign in to comment.