Files
NotionNext/components/FacebookMessenger.js
tangly1024.com 3b181f3069 load 优化
2023-12-01 12:50:54 +08:00

283 lines
7.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Component, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import { siteConfig } from '@/lib/config'
export default function Messenger() {
const pageId = siteConfig('FACEBOOK_PAGE_ID')
const appId = siteConfig('FACEBOOK_APP_ID')
const language = siteConfig('LANG').replace('-', '_')
// 新增一个状态变量用于追踪是否已经滚动过
const [showMessenger, setShowMessenger] = useState(false);
const showTheComponent = () => {
window.removeEventListener('scroll', showTheComponent);
if (!showMessenger) {
setShowMessenger(true);
}
};
// 延时7秒或页面滚动时加载该组件
useEffect(() => {
window.addEventListener('scroll', showTheComponent);
setTimeout(() => {
showTheComponent()
}, 7000);
return () => {
window.removeEventListener('scroll', showTheComponent);
};
}, []);
return <>
{showMessenger && <MessengerCustomerChat
pageId={pageId}
appId={appId}
language={language}
shouldShowDialog={true}
/>}
</>
}
/**
* @see https://github.com/Yoctol/react-messenger-customer-chat
*/
class MessengerCustomerChat extends Component {
constructor(props) {
super(props)
this.state = {
fbLoaded: false,
shouldShowDialog: undefined
}
}
/**
* 初始化
*/
componentDidMount() {
this.setFbAsyncInit()
this.reloadSDKAsynchronously()
}
componentDidUpdate(prevProps) {
if (
prevProps.pageId !== this.props.pageId ||
prevProps.appId !== this.props.appId ||
prevProps.shouldShowDialog !== this.props.shouldShowDialog ||
prevProps.htmlRef !== this.props.htmlRef ||
prevProps.minimized !== this.props.minimized ||
prevProps.themeColor !== this.props.themeColor ||
prevProps.loggedInGreeting !== this.props.loggedInGreeting ||
prevProps.loggedOutGreeting !== this.props.loggedOutGreeting ||
prevProps.greetingDialogDisplay !== this.props.greetingDialogDisplay ||
prevProps.greetingDialogDelay !== this.props.greetingDialogDelay ||
prevProps.autoLogAppEvents !== this.props.autoLogAppEvents ||
prevProps.xfbml !== this.props.xfbml ||
prevProps.version !== this.props.version ||
prevProps.language !== this.props.language
) {
this.setFbAsyncInit()
this.reloadSDKAsynchronously()
}
}
componentWillUnmount() {
if (window.FB !== undefined) {
window.FB.CustomerChat.hide()
}
}
/**
* 初始化
*/
setFbAsyncInit() {
const { appId, autoLogAppEvents, xfbml, version } = this.props
window.fbAsyncInit = () => {
window.FB.init({
appId,
autoLogAppEvents,
xfbml,
version: `v${version}`
})
this.setState({ fbLoaded: true })
}
}
loadSDKAsynchronously() {
const { language } = this.props;
/* eslint-disable */
(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = `https://connect.facebook.net/${language}/sdk/xfbml.customerchat.js`;
fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');
/* eslint-enable */
}
removeFacebookSDK() {
removeElementByIds(['facebook-jssdk', 'fb-root'])
delete window.FB
}
reloadSDKAsynchronously() {
this.removeFacebookSDK()
this.loadSDKAsynchronously()
}
controlPlugin() {
const { shouldShowDialog } = this.props
if (shouldShowDialog) {
window.FB.CustomerChat.showDialog()
} else {
window.FB.CustomerChat.hideDialog()
}
}
subscribeEvents() {
const { onCustomerChatDialogShow, onCustomerChatDialogHide } = this.props
if (onCustomerChatDialogShow) {
window.FB.Event.subscribe(
'customerchat.dialogShow',
onCustomerChatDialogShow
)
}
if (onCustomerChatDialogHide) {
window.FB.Event.subscribe(
'customerchat.dialogHide',
onCustomerChatDialogHide
)
}
}
createMarkup() {
const {
pageId,
htmlRef,
minimized,
themeColor,
loggedInGreeting,
loggedOutGreeting,
greetingDialogDisplay,
greetingDialogDelay
} = this.props
const refAttribute = htmlRef !== undefined ? `ref="${htmlRef}"` : ''
const minimizedAttribute =
minimized !== undefined ? `minimized="${minimized}"` : ''
const themeColorAttribute =
themeColor !== undefined ? `theme_color="${themeColor}"` : ''
const loggedInGreetingAttribute =
loggedInGreeting !== undefined
? `logged_in_greeting="${loggedInGreeting}"`
: ''
const loggedOutGreetingAttribute =
loggedOutGreeting !== undefined
? `logged_out_greeting="${loggedOutGreeting}"`
: ''
const greetingDialogDisplayAttribute =
greetingDialogDisplay !== undefined
? `greeting_dialog_display="${greetingDialogDisplay}"`
: ''
const greetingDialogDelayAttribute =
greetingDialogDelay !== undefined
? `greeting_dialog_delay="${greetingDialogDelay}"`
: ''
return {
__html: `<div
class="fb-customerchat"
page_id="${pageId}"
${refAttribute}
${minimizedAttribute}
${themeColorAttribute}
${loggedInGreetingAttribute}
${loggedOutGreetingAttribute}
${greetingDialogDisplayAttribute}
${greetingDialogDelayAttribute}
></div>`
}
}
render() {
const { fbLoaded, shouldShowDialog } = this.state
if (fbLoaded && shouldShowDialog !== this.props.shouldShowDialog) {
document.addEventListener(
'DOMNodeInserted',
(event) => {
const element = event.target
if (
element.className &&
typeof element.className === 'string' &&
element.className.includes('fb_dialog')
) {
this.controlPlugin()
}
},
false
)
this.subscribeEvents()
}
// Add a random key to rerender. Reference:
// https://stackoverflow.com/questions/30242530/dangerouslysetinnerhtml-doesnt-update-during-render
return <div key={Date()} dangerouslySetInnerHTML={this.createMarkup()} />
}
}
const removeElementByIds = (ids) => {
ids.forEach((id) => {
const element = document.getElementById(id)
if (element && element.parentNode) {
element.parentNode.removeChild(element)
}
})
}
MessengerCustomerChat.propTypes = {
pageId: PropTypes.string.isRequired,
appId: PropTypes.string,
shouldShowDialog: PropTypes.bool,
htmlRef: PropTypes.string,
minimized: PropTypes.bool,
themeColor: PropTypes.string,
loggedInGreeting: PropTypes.string,
loggedOutGreeting: PropTypes.string,
greetingDialogDisplay: PropTypes.oneOf(['show', 'hide', 'fade']),
greetingDialogDelay: PropTypes.number,
autoLogAppEvents: PropTypes.bool,
xfbml: PropTypes.bool,
version: PropTypes.string,
language: PropTypes.string,
onCustomerChatDialogShow: PropTypes.func,
onCustomerChatDialogHide: PropTypes.func
}
MessengerCustomerChat.defaultProps = {
appId: null,
shouldShowDialog: false,
htmlRef: undefined,
minimized: undefined,
themeColor: undefined,
loggedInGreeting: undefined,
loggedOutGreeting: undefined,
greetingDialogDisplay: undefined,
greetingDialogDelay: undefined,
autoLogAppEvents: true,
xfbml: true,
version: '11.0',
language: 'en_US',
onCustomerChatDialogShow: undefined,
onCustomerChatDialogHide: undefined
}