-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #912 from City-of-Helsinki/UHF-11448
UHF-11448
- Loading branch information
Showing
2 changed files
with
169 additions
and
166 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,195 +1,198 @@ | ||
// eslint-disable-next-line func-names | ||
(function (Drupal, drupalSettings) { | ||
class TeliaAceLeijuke { | ||
constructor(teliaAceData) { | ||
this.static = { | ||
chatId: teliaAceData.chat_id, | ||
selector: `leijuke_${teliaAceData.chat_id}`, | ||
chatTitle: teliaAceData.chat_title, | ||
scriptUrl: teliaAceData.script_url, | ||
scriptSri: teliaAceData.script_sri | ||
}; | ||
this.state = { | ||
cookies: this.cookieCheck(), | ||
chatLoading: false, | ||
chatLoaded: false, | ||
chatOpened: false, | ||
busy: false | ||
}; | ||
} | ||
|
||
// eslint-disable-next-line class-methods-use-this | ||
cookieCheck() { | ||
return Drupal.cookieConsent.getConsentStatus(['chat']); | ||
} | ||
|
||
// eslint-disable-next-line class-methods-use-this | ||
cookieSet() { | ||
if (Drupal.cookieConsent.getConsentStatus(['chat'])) return; | ||
|
||
Drupal.cookieConsent.setAcceptedCategories(['chat']); | ||
} | ||
|
||
init() { | ||
if (this.state.cookies) { | ||
// Cookies already set so chat assets can be loaded. | ||
this.loadChat(); | ||
} | ||
|
||
this.initWrapper(); | ||
this.render(); | ||
} | ||
|
||
loadChat() { | ||
const { scriptUrl, scriptSri } = this.static; | ||
const leijuke = this; | ||
const chatScript = document.createElement('script'); | ||
chatScript.src = scriptUrl; | ||
chatScript.type = 'text/javascript'; | ||
chatScript.setAttribute('async', ''); | ||
|
||
if (scriptSri) { | ||
chatScript.integrity = scriptSri; | ||
chatScript.crossOrigin = 'anonymous'; | ||
} | ||
|
||
// eslint-disable-next-line func-names | ||
chatScript.onload = function() { | ||
leijuke.loaded(); | ||
}; | ||
Drupal.behaviors.telia_ace = { | ||
attach: function attach() { | ||
setTimeout(() => { | ||
if (drupalSettings.telia_ace_data.initialized) { | ||
return; | ||
} | ||
|
||
// Insert chatScript into head | ||
const head = document.querySelector('head'); | ||
head.appendChild(chatScript); | ||
this.state.chatLoading = true; | ||
} | ||
let chatSettings = {}; | ||
try { | ||
chatSettings = new ChatSettings(drupalSettings.telia_ace_data ?? {}); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
return; | ||
} | ||
|
||
loaded() { | ||
this.state = { | ||
...this.state, | ||
chatLoaded: true, | ||
}; | ||
this.openChat(); | ||
this.render(); | ||
new TeliaAceWidget(chatSettings); | ||
drupalSettings.telia_ace_data.initialized = true; | ||
}); | ||
} | ||
}; | ||
})(Drupal, drupalSettings); | ||
|
||
initWrapper() { | ||
let teliaAceLeijukeWrapper = document.getElementById('telia-ace-leijuke'); | ||
if (!teliaAceLeijukeWrapper) { | ||
teliaAceLeijukeWrapper = document.createElement('aside'); | ||
teliaAceLeijukeWrapper.id = 'telia-ace-leijuke'; | ||
document.body.append(teliaAceLeijukeWrapper); | ||
} | ||
|
||
const teliaAceLeijukeInstance = document.createElement('button'); | ||
teliaAceLeijukeInstance.id = this.static.selector; | ||
teliaAceLeijukeInstance.classList.add('chat-leijuke'); | ||
teliaAceLeijukeInstance.classList.add('telia-chat-leijuke'); | ||
class TeliaAceWidget { | ||
constructor(chatSettings) { | ||
this.static = { | ||
chatId: chatSettings.chat_id, | ||
selector: `leijuke_${chatSettings.chat_id}`, | ||
chatTitle: chatSettings.chat_title, | ||
scriptUrl: chatSettings.script_url, | ||
}; | ||
this.state = { | ||
cookies: this.cookieCheck(), | ||
chatLoading: false, | ||
chatLoaded: false, | ||
chatOpened: false, | ||
busy: false | ||
}; | ||
this.init(); | ||
} | ||
|
||
teliaAceLeijukeWrapper.append(teliaAceLeijukeInstance); | ||
/** | ||
* Initialize the chat libraries and elements. | ||
*/ | ||
init = () => { | ||
const chatButton = this.createChatWidget(); | ||
this.addEventListener(chatButton); | ||
this.render(); | ||
} | ||
|
||
this.prepButton(teliaAceLeijukeInstance); | ||
/** | ||
* Set up the chat button elements. | ||
*/ | ||
createChatWidget = () => { | ||
let teliaAceWidgetWrapper = document.getElementById('telia-ace-leijuke'); | ||
if (!teliaAceWidgetWrapper) { | ||
teliaAceWidgetWrapper = document.createElement('aside'); | ||
teliaAceWidgetWrapper.id = 'telia-ace-leijuke'; | ||
document.body.append(teliaAceWidgetWrapper); | ||
} | ||
|
||
prepButton(button) { | ||
const teliaAceWidgetInstance = document.createElement('button'); | ||
teliaAceWidgetInstance.id = this.static.selector; | ||
teliaAceWidgetInstance.classList.add('chat-leijuke'); | ||
teliaAceWidgetInstance.classList.add('telia-chat-leijuke'); | ||
|
||
button.addEventListener('click', () => { | ||
teliaAceWidgetWrapper.append(teliaAceWidgetInstance); | ||
|
||
// Debounce button. | ||
if (this.state.busy) { | ||
return; | ||
} | ||
this.state = { | ||
...this.state, | ||
busy: true, | ||
}; | ||
|
||
// If chat was loaded, cookies are ok. | ||
if (this.state.chatLoaded) { | ||
this.openChat(true); | ||
return; | ||
} | ||
return teliaAceWidgetInstance; | ||
} | ||
|
||
if (!this.state.cookies) { | ||
// Implicitly allow chat cookies if clicking Leijuke. | ||
this.cookieSet(); | ||
} | ||
/** | ||
* Adds self-removing event-listener to the chat button. | ||
* | ||
* Automatically accept the chat cookies and load the chat script | ||
* when user clicks the chat button. Then open the chat on "onloaad". | ||
* | ||
* @param chatButton | ||
*/ | ||
addEventListener = (chatButton) => { | ||
chatButton.addEventListener('click', () => { | ||
if (!this.cookieCheck()) { | ||
this.cookieSet(); | ||
} | ||
this.loadChatScript(); | ||
this.openChat(true); | ||
}, { once: true }); | ||
} | ||
|
||
this.state = { | ||
...this.state, | ||
cookies: this.cookieCheck() | ||
}; | ||
/** | ||
* Load the chat script. | ||
*/ | ||
loadChatScript = () => { | ||
const chatScript = document.createElement('script'); | ||
chatScript.src = this.static.scriptUrl; | ||
chatScript.type = 'text/javascript'; | ||
chatScript.setAttribute('async', ''); | ||
|
||
// If the cookieCheck returns false, it means they could not be set | ||
// implicitly, which means something is wrong in the config. | ||
if (this.state.cookies) { | ||
this.loadChat(); | ||
this.openChat(true); | ||
} | ||
chatScript.onload = this.loaded; | ||
|
||
}); | ||
} | ||
const head = document.querySelector('head'); | ||
head.appendChild(chatScript); | ||
this.state.chatLoading = true; | ||
} | ||
|
||
openChat(openWidget) { | ||
const leijuke = this; | ||
|
||
const teliaAceWidgetInitialized = setInterval(() => { | ||
if(typeof window.humany !== 'undefined' && typeof window.humany.widgets !== 'undefined' && window.humany.widgets.find(leijuke.static.chatId)){ | ||
if (openWidget) { | ||
const myWidget = window.humany.widgets.find(leijuke.static.chatId); | ||
myWidget.activate(); | ||
myWidget.invoke('show'); | ||
} | ||
clearInterval(teliaAceWidgetInitialized); | ||
leijuke.state = { | ||
...leijuke.state, | ||
chatLoading: false, | ||
chatOpened: true, | ||
busy: false, | ||
}; | ||
leijuke.render(); | ||
} | ||
// Interval is set to 50 milliseconds here. | ||
// This doesn't poll the variables too often but should seem quick to users. | ||
}, 50); | ||
/** | ||
* Render the chat element. | ||
*/ | ||
render = () => { | ||
const { chatOpened, chatLoading } = this.state; | ||
const label = chatLoading ? Drupal.t('Loading chat...', {}, {context: 'Telia ACE chat'}) : this.static.chatTitle; | ||
const element = document.getElementById(this.static.selector); | ||
if (!element) { | ||
return; | ||
} | ||
|
||
render() { | ||
const { chatOpened, chatLoading } = this.state; | ||
const label = chatLoading ? Drupal.t('Loading chat...', {}, {context: 'Telia ACE chat'}) : this.static.chatTitle; | ||
const element = document.getElementById(this.static.selector); | ||
if (!element) { | ||
return; | ||
} | ||
const innerHTML = ` | ||
const innerHTML = ` | ||
<span class="hel-icon hel-icon--speechbubble-text"></span> | ||
<span>${label}</span> | ||
<span class="hel-icon hel-icon--angle-up"></span> | ||
`; | ||
|
||
if (element.innerHTML !== innerHTML) { | ||
element.innerHTML = innerHTML; | ||
} | ||
element.classList.toggle('loading', chatLoading); | ||
element.classList.toggle('hidden', chatOpened); | ||
if (element.innerHTML !== innerHTML) { | ||
element.innerHTML = innerHTML; | ||
} | ||
element.classList.toggle('loading', chatLoading); | ||
element.classList.toggle('hidden', chatOpened); | ||
} | ||
|
||
cookieCheck = () => { | ||
return Drupal.cookieConsent.getConsentStatus(['chat']); | ||
} | ||
|
||
Drupal.behaviors.telia_ace = { | ||
attach: function attach() { | ||
const teliaAceData = drupalSettings.telia_ace_data; | ||
cookieSet = () => { | ||
if (Drupal.cookieConsent.getConsentStatus(['chat'])) return; | ||
Drupal.cookieConsent.setAcceptedCategories(['chat']); | ||
} | ||
|
||
setTimeout(() => { | ||
// Only load any leijuke once, in case of ajax triggers. | ||
if (teliaAceData.initialized) { | ||
return; | ||
/** | ||
* Onload callback for the chat script. | ||
*/ | ||
loaded = () => { | ||
this.state = { | ||
...this.state, | ||
chatLoaded: true, | ||
}; | ||
this.openChat(); | ||
this.render(); | ||
} | ||
|
||
/** | ||
* Call the humany activation method if chat is loaded. | ||
* | ||
* @param openWidget | ||
* To open the chat session or not. | ||
*/ | ||
openChat = (openWidget) => { | ||
const teliaAceWidgetInitialized = setInterval(() => { | ||
if(typeof window.humany !== 'undefined' && typeof window.humany.widgets !== 'undefined' && window.humany.widgets.find(this.static.chatId)){ | ||
if (openWidget) { | ||
const myWidget = window.humany.widgets.find(this.static.chatId); | ||
myWidget.activate(); | ||
myWidget.invoke('show'); | ||
} | ||
clearInterval(teliaAceWidgetInitialized); | ||
this.state = { | ||
...this.state, | ||
chatLoading: false, | ||
chatOpened: true, | ||
busy: false, | ||
}; | ||
this.render(); | ||
} | ||
}, 50); | ||
} | ||
} | ||
|
||
class ChatSettings { | ||
constructor(settings) { | ||
const requiredSettings = [ | ||
'chat_title', | ||
'chat_id', | ||
'script_url' | ||
]; | ||
|
||
// Check that the required settings exist. | ||
requiredSettings.forEach(value => { | ||
if (!settings.hasOwnProperty(value) || !settings[value]) { | ||
throw new Error(`Missing expected ace chat setting ${value}`); | ||
} | ||
}); | ||
|
||
const teliaAce = new TeliaAceLeijuke(teliaAceData); | ||
teliaAce.init(); | ||
drupalSettings.telia_ace_data.initialized = true; | ||
}); | ||
} | ||
}; | ||
})(Drupal, drupalSettings); | ||
this.chat_title = settings.chat_title | ||
this.chat_id = settings.chat_id | ||
this.script_url = settings.script_url | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters