mirror of
https://github.com/chatwoot/chatwoot.git
synced 2026-06-13 21:01:16 +08:00
157 lines
5.0 KiB
JavaScript
157 lines
5.0 KiB
JavaScript
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
|
import { registerVueWebComponents } from '../vue-components/registerWebComponents';
|
|
import store from '../../../dashboard/store';
|
|
import constants from '../../../dashboard/constants/globals';
|
|
import axios from 'axios';
|
|
import createAxios from '../../../ui/axios';
|
|
import commonHelpers from '../../../dashboard/helper/commons';
|
|
import vueActionCable from '../../../dashboard/helper/actionCable';
|
|
|
|
const ChatwootContext = createContext();
|
|
|
|
export const ChatwootProvider = ({
|
|
baseURL,
|
|
accountId,
|
|
userToken,
|
|
websocketURL,
|
|
pubsubToken,
|
|
conversationId,
|
|
disableUpload,
|
|
disableEditor,
|
|
disableSignature,
|
|
signature,
|
|
signatureReadOnly,
|
|
children,
|
|
}) => {
|
|
const isInitialized = useRef(false);
|
|
const [initializationComplete, setInitializationComplete] = useState(false);
|
|
|
|
// Validate required props
|
|
if (!baseURL) {
|
|
throw new Error('ChatwootProvider: baseURL is required');
|
|
}
|
|
if (!userToken) {
|
|
throw new Error('ChatwootProvider: userToken is required');
|
|
}
|
|
|
|
// Configuration object passed to all child components
|
|
const config = {
|
|
baseURL: baseURL.replace(/\/$/, ''), // Remove trailing slash
|
|
userToken,
|
|
accountId: Number(accountId),
|
|
conversationId: Number(conversationId),
|
|
disableEditor: disableEditor || false,
|
|
disableUpload: disableUpload || false,
|
|
disableSignature: disableSignature || false,
|
|
websocketURL: websocketURL,
|
|
pubsubToken: pubsubToken,
|
|
signature: signature || '',
|
|
signatureReadOnly: signatureReadOnly || false,
|
|
};
|
|
|
|
function initializeChatwootGlobals() {
|
|
// Register Web Components
|
|
registerVueWebComponents();
|
|
|
|
// Set up global variables that Vue components expect
|
|
/* eslint-disable no-underscore-dangle */
|
|
window.__WOOT_API_HOST__ = config.baseURL;
|
|
window.__WOOT_ACCOUNT_ID__ = config.accountId;
|
|
window.__WOOT_ACCESS_TOKEN__ = config.userToken;
|
|
window.__WEBSOCKET_URL__ = config.websocketURL;
|
|
window.__PUBSUB_TOKEN__ = config.pubsubToken;
|
|
window.__WOOT_CONVERSATION_ID__ = config.conversationId;
|
|
window.__EDITOR_DISABLE_UPLOAD__ = config.disableUpload;
|
|
window.__DISABLE_EDITOR__ = config.disableEditor;
|
|
window.__WOOT_DISABLE_SIGNATURE__ = config.disableSignature;
|
|
window.__WOOT_CUSTOM_SIGNATURE__ = config.signature || undefined;
|
|
window.__WOOT_SIGNATURE_READ_ONLY__ = config.signatureReadOnly;
|
|
window.__WOOT_ISOLATED_SHELL__ = true;
|
|
/* eslint-enable no-underscore-dangle */
|
|
|
|
// Initialize common helpers
|
|
commonHelpers();
|
|
|
|
// Set up global objects
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
window.WootConstants = constants;
|
|
window.axios = createAxios(axios);
|
|
|
|
// Initialize user in store and ActionCable
|
|
store.dispatch('setUser').then(async () => {
|
|
// Fetch inboxes once per session. Guarded against the shared Vuex store
|
|
// so remounting the provider (e.g. when the consumer re-keys per
|
|
// conversation) doesn't trigger redundant /inboxes requests.
|
|
const hasInboxes = store.getters['inboxes/getInboxes'].length > 0;
|
|
if (!hasInboxes) {
|
|
await store.dispatch('inboxes/get');
|
|
}
|
|
vueActionCable.init(store, config.pubsubToken);
|
|
setInitializationComplete(true);
|
|
});
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (isInitialized.current) return;
|
|
|
|
initializeChatwootGlobals();
|
|
isInitialized.current = true;
|
|
}, [
|
|
config.baseURL,
|
|
config.userToken,
|
|
config.websocketURL,
|
|
config.pubsubToken,
|
|
]);
|
|
|
|
// Keep signature global in sync when the prop changes after init
|
|
useEffect(() => {
|
|
const value = signature || undefined;
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
window.__WOOT_CUSTOM_SIGNATURE__ = value;
|
|
window.dispatchEvent(
|
|
new CustomEvent('chatwoot:signature-change', { detail: value || '' })
|
|
);
|
|
}, [signature]);
|
|
|
|
// Keep signatureReadOnly global in sync when the prop changes after init
|
|
useEffect(() => {
|
|
const value = signatureReadOnly === true;
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
window.__WOOT_SIGNATURE_READ_ONLY__ = value;
|
|
window.dispatchEvent(
|
|
new CustomEvent('chatwoot:signature-read-only-change', { detail: value })
|
|
);
|
|
}, [signatureReadOnly]);
|
|
|
|
// Keep signature toggle global in sync when the prop changes after init
|
|
useEffect(() => {
|
|
const value = disableSignature === true;
|
|
// eslint-disable-next-line no-underscore-dangle
|
|
window.__WOOT_DISABLE_SIGNATURE__ = value;
|
|
window.dispatchEvent(
|
|
new CustomEvent('chatwoot:disable-signature-change', { detail: value })
|
|
);
|
|
}, [disableSignature]);
|
|
|
|
if (!initializationComplete) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<ChatwootContext.Provider value={config}>
|
|
{children}
|
|
</ChatwootContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useChatwoot = () => {
|
|
const context = useContext(ChatwootContext);
|
|
if (!context) {
|
|
throw new Error('useChatwoot must be used within ChatwootProvider');
|
|
}
|
|
return context;
|
|
};
|
|
|
|
// For backwards compatibility and explicit configuration access
|
|
export const useChawootConfig = useChatwoot;
|