Feature: Introduce locale in web-widget SDK (#871)

* Introduce setLocale in SDK

Co-authored-by: Sojan <sojan@pepalo.com>
This commit is contained in:
Pranav Raj S
2020-05-17 16:15:53 +05:30
committed by GitHub
parent 2e8cd59a06
commit 59f4dd7ebe
10 changed files with 67 additions and 13 deletions

View File

@@ -29,7 +29,11 @@ class ApplicationController < ActionController::Base
end end
def switch_locale(account) def switch_locale(account)
I18n.locale = (I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil) || I18n.default_locale # priority is for locale set in query string (mostly for widget/from js sdk)
locale ||= (I18n.available_locales.map(&:to_s).include?(params[:locale]) ? params[:locale] : nil)
# if local is not set in param, lets try account
locale ||= (I18n.available_locales.map(&:to_s).include?(account.locale) ? account.locale : nil)
I18n.locale = locale || I18n.default_locale
end end
def account_accessible_for_user?(account) def account_accessible_for_user?(account)

View File

@@ -10,6 +10,7 @@ const runSDK = ({ baseUrl, websiteToken }) => {
isOpen: false, isOpen: false,
position: chatwootSettings.position === 'left' ? 'left' : 'right', position: chatwootSettings.position === 'left' ? 'left' : 'right',
websiteToken, websiteToken,
locale: chatwootSettings.locale || 'en',
toggle() { toggle() {
IFrameHelper.events.toggleBubble(); IFrameHelper.events.toggleBubble();
@@ -36,6 +37,10 @@ const runSDK = ({ baseUrl, websiteToken }) => {
IFrameHelper.sendMessage('remove-label', { label }); IFrameHelper.sendMessage('remove-label', { label });
}, },
setLocale(localeToBeUsed = 'en') {
IFrameHelper.sendMessage('set-locale', { locale: localeToBeUsed });
},
reset() { reset() {
if (window.$chatwoot.isOpen) { if (window.$chatwoot.isOpen) {
IFrameHelper.events.toggleBubble(); IFrameHelper.events.toggleBubble();

View File

@@ -76,7 +76,9 @@ export const IFrameHelper = {
expires: 365, expires: 365,
}); });
window.$chatwoot.hasLoaded = true; window.$chatwoot.hasLoaded = true;
IFrameHelper.sendMessage('config-set', {}); IFrameHelper.sendMessage('config-set', {
locale: window.$chatwoot.locale,
});
IFrameHelper.onLoad(message.config.channelConfig); IFrameHelper.onLoad(message.config.channelConfig);
IFrameHelper.setCurrentUrl(); IFrameHelper.setCurrentUrl();
IFrameHelper.toggleCloseButton(); IFrameHelper.toggleCloseButton();

View File

@@ -19,7 +19,7 @@ export default {
}, },
mounted() { mounted() {
const { websiteToken, locale } = window.chatwootWebChannel; const { websiteToken, locale } = window.chatwootWebChannel;
Vue.config.lang = locale; this.setLocale(locale);
if (IFrameHelper.isIFrame()) { if (IFrameHelper.isIFrame()) {
IFrameHelper.sendMessage({ IFrameHelper.sendMessage({
@@ -44,6 +44,7 @@ export default {
if (message.event === 'config-set') { if (message.event === 'config-set') {
this.fetchOldConversations(); this.fetchOldConversations();
this.fetchAvailableAgents(websiteToken); this.fetchAvailableAgents(websiteToken);
this.setLocale(message.locale);
} else if (message.event === 'widget-visible') { } else if (message.event === 'widget-visible') {
this.scrollConversationToBottom(); this.scrollConversationToBottom();
} else if (message.event === 'set-current-url') { } else if (message.event === 'set-current-url') {
@@ -58,6 +59,8 @@ export default {
this.$store.dispatch('conversationLabels/destroy', message.label); this.$store.dispatch('conversationLabels/destroy', message.label);
} else if (message.event === 'set-user') { } else if (message.event === 'set-user') {
this.$store.dispatch('contacts/update', message); this.$store.dispatch('contacts/update', message);
} else if (message.event === 'set-locale') {
this.setLocale(message.locale);
} }
}); });
@@ -71,6 +74,12 @@ export default {
const container = this.$el.querySelector('.conversation-wrap'); const container = this.$el.querySelector('.conversation-wrap');
container.scrollTop = container.scrollHeight; container.scrollTop = container.scrollHeight;
}, },
setLocale(locale) {
const { enabledLanguages } = window.chatwootWebChannel;
if (enabledLanguages.some(lang => lang.iso_639_1_code === locale)) {
Vue.config.lang = locale;
}
},
}, },
}; };
</script> </script>

View File

@@ -1,13 +1,26 @@
const sendMessage = content => ({ import Vue from 'vue';
url: `/api/v1/widget/messages${window.location.search}`,
params: { const sendMessage = content => {
message: { const locale = Vue.config.lang;
content, const refererURL = window.refererURL || '';
timestamp: new Date().toString(), let search = window.location.search;
referer_url: window.refererURL || '', if (search) {
search = `${search}&locale=${locale}`;
} else {
search = `?locale=${locale}`;
}
return {
url: `/api/v1/widget/messages${search}`,
params: {
message: {
content,
timestamp: new Date().toString(),
referer_url: refererURL,
},
}, },
}, };
}); };
const sendAttachment = ({ attachment }) => { const sendAttachment = ({ attachment }) => {
const { refererURL = '' } = window; const { refererURL = '' } = window;

View File

@@ -1,12 +1,14 @@
import endPoints from '../endPoints'; import endPoints from '../endPoints';
jest.mock('vue', () => ({ config: { lang: 'ar' } }));
describe('#sendMessage', () => { describe('#sendMessage', () => {
it('returns correct payload', () => { it('returns correct payload', () => {
const spy = jest.spyOn(global, 'Date').mockImplementation(() => ({ const spy = jest.spyOn(global, 'Date').mockImplementation(() => ({
toString: () => 'mock date', toString: () => 'mock date',
})); }));
expect(endPoints.sendMessage('hello')).toEqual({ expect(endPoints.sendMessage('hello')).toEqual({
url: `/api/v1/widget/messages`, url: `/api/v1/widget/messages?locale=ar`,
params: { params: {
message: { message: {
content: 'hello', content: 'hello',

View File

@@ -1,15 +1,23 @@
import { default as ar } from './locale/ar.json';
import { default as ca } from './locale/ca.json'; import { default as ca } from './locale/ca.json';
import { default as de } from './locale/de.json'; import { default as de } from './locale/de.json';
import { default as el } from './locale/el.json'; import { default as el } from './locale/el.json';
import { default as en } from './locale/en.json'; import { default as en } from './locale/en.json';
import { default as fr } from './locale/fr.json';
import { default as ml } from './locale/ml.json'; import { default as ml } from './locale/ml.json';
import { default as nl } from './locale/nl.json';
import { default as pt } from './locale/pt.json'; import { default as pt } from './locale/pt.json';
import { default as pt_BR } from './locale/pt_BR.json';
export default { export default {
ar,
ca, ca,
de, de,
el, el,
en, en,
fr,
ml, ml,
nl,
pt, pt,
pt_BR,
}; };

View File

@@ -5,6 +5,7 @@
window.chatwootSettings = { window.chatwootSettings = {
hideMessageBubble: false, hideMessageBubble: false,
position: 'left', position: 'left',
locale: 'fr',
}; };
(function(d,t) { (function(d,t) {

View File

@@ -17,6 +17,7 @@
welcomeTagline: '<%= @web_widget.welcome_tagline %>', welcomeTagline: '<%= @web_widget.welcome_tagline %>',
welcomeTitle: '<%= @web_widget.welcome_title %>', welcomeTitle: '<%= @web_widget.welcome_title %>',
widgetColor: '<%= @web_widget.widget_color %>', widgetColor: '<%= @web_widget.widget_color %>',
enabledLanguages: <%= available_locales_with_name.to_json.html_safe %>,
} }
window.chatwootWidgetDefaults = { window.chatwootWidgetDefaults = {
useInboxAvatarForBot: <%= ActiveModel::Type::Boolean.new.cast(ENV.fetch('USE_INBOX_AVATAR_FOR_BOT', false)) %>, useInboxAvatarForBot: <%= ActiveModel::Type::Boolean.new.cast(ENV.fetch('USE_INBOX_AVATAR_FOR_BOT', false)) %>,

View File

@@ -14,6 +14,7 @@ To hide the bubble, you can use the following setting. Please not if you use thi
window.chatwootSettings = { window.chatwootSettings = {
hideMessageBubble: false, hideMessageBubble: false,
position: 'left', // This can be left or right position: 'left', // This can be left or right
locale: 'en', // Language to be set
} }
``` ```
@@ -37,6 +38,14 @@ window.$chatwoot.setUser('identifier_key', {
Make sure that you reset the session when the user logouts of your app. Make sure that you reset the session when the user logouts of your app.
### To set language manually
```js
window.$chatwoot.setLocale('en')
```
To set the language manually use the setLocale function.
### To set labels on the conversation ### To set labels on the conversation
Please note that the labels will be set on a conversation, if the user has not started a conversation, then the following items will not have any effect. Please note that the labels will be set on a conversation, if the user has not started a conversation, then the following items will not have any effect.