Skip to content

Commit 864b7cf

Browse files
authoredAug 15, 2023
Contact Support: Configure Chat Widget Design and Presentation logic (#21314)
* Configure chat bot appearance Wait for chatBot elements and shadow DOM to be loaded before: - Reseting history - Opening DocsBot - Hiding close button, header, floating button Use MutationObservers for observing elements appearing * Update chat color * Hide elements using css * Update support_chat_widget.js * Use docsBotId from ApiCredentials * Add css by appending a child to shadow root
1 parent 5959bfa commit 864b7cf

12 files changed

+102
-13
lines changed
 

‎.configure

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"project_name": "WordPress-iOS",
33
"branch": "trunk",
4-
"pinned_hash": "f0aaaf24805b0aa258e09ec85b6977194e514027",
4+
"pinned_hash": "91e71c2268b4df54591ff9cedbfd03ac93ba865d",
55
"files_to_copy": [
66
{
77
"file": "shared/google_cloud_keys.json",
@@ -42,4 +42,4 @@
4242
"file_dependencies": [
4343

4444
]
45-
}
45+
}
64 Bytes
Binary file not shown.
32 Bytes
Binary file not shown.
32 Bytes
Binary file not shown.

‎.configure-files/Secrets.swift.enc

32 Bytes
Binary file not shown.

‎.configure-files/project.env.enc

-80 Bytes
Binary file not shown.

‎WordPress/Classes/ViewRelated/Support/SupportChatBot/SupportChatBotViewController.swift

+4-5
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,20 @@ final class SupportChatBotViewController: UIViewController {
5252
private func createDocsBotInitCode() -> String {
5353
"""
5454
(function() {
55+
// support_chat_widget.js
56+
window.prepareDocsBotForPresentation();
57+
5558
DocsBotAI.init({
5659
id: '\(viewModel.id)',
5760
supportCallback: function (event, history) {
5861
event.preventDefault()
5962
window.webkit.messageHandlers.supportCallback.postMessage(history)
6063
},
6164
options: {
62-
horizontalMargin: 40,
63-
verticalMargin: 60,
65+
color: "#9dd977",
6466
supportLink: "#"
6567
},
6668
})
67-
setTimeout(() => {
68-
DocsBotAI.open()
69-
}, 200);
7069
})();
7170
"""
7271
}

‎WordPress/Classes/ViewRelated/Support/SupportChatBot/SupportChatBotViewModel.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Foundation
33
struct SupportChatBotViewModel {
44
private let zendeskUtils: ZendeskUtilsProtocol
55

6-
let id = "" // TODO: Update ApiCredentials
6+
let id = ApiCredentials.docsBotId
77
let url = Bundle.main.url(forResource: "support_chat_widget", withExtension: "html")
88

99
init(zendeskUtils: ZendeskUtilsProtocol = ZendeskUtils.sharedInstance) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.docsbot-chat-header,
2+
.mobile-close-button,
3+
a.floating-button {
4+
display: none !important;
5+
}

‎WordPress/Classes/ViewRelated/Support/SupportChatBot/support_chat_widget.html

-5
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,5 @@
44
<script type="text/javascript" src="support_chat_widget.js"></script>
55
</head>
66
<body>
7-
<script type="text/javascript">
8-
setTimeout(() => {
9-
DocsBotAI.open()
10-
}, 200);
11-
</script>
127
</body>
138
</html>

‎WordPress/Classes/ViewRelated/Support/SupportChatBot/support_chat_widget.js

+84
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,87 @@ DocsBotAI.init = function (c) {
4242
});
4343
});
4444
};
45+
46+
/**
47+
* Prepares the DocsBot for presentation by altering its appearance and behavior.
48+
*/
49+
window.prepareDocsBotForPresentation = function () {
50+
var chatBotSelector = "#docsbotai-root";
51+
52+
// Begin observation once chat bot is mounted
53+
onElementMounted(chatBotSelector, document, function (element) {
54+
waitForShadowRoot(element, function (shadowRoot) {
55+
resetDocsBotConversation();
56+
openDocsBot();
57+
58+
// Inject a custom css to hide unnecessary elements
59+
var linkElem = document.createElement("link");
60+
linkElem.setAttribute("rel", "stylesheet");
61+
linkElem.setAttribute("href", "support_chat_widget.css");
62+
shadowRoot.appendChild(linkElem);
63+
});
64+
});
65+
66+
/**
67+
* Clears the DocsBot conversation history.
68+
*/
69+
function resetDocsBotConversation() {
70+
localStorage.removeItem("docsbot_chat_history");
71+
}
72+
73+
/**
74+
* Opens the DocsBot chat.
75+
*/
76+
function openDocsBot() {
77+
DocsBotAI.open();
78+
}
79+
80+
/**
81+
* Observes for an element's appearance in the DOM and triggers a callback once it's found.
82+
*
83+
* @param {string} selector - The CSS selector of the element to watch for.
84+
* @param {function} callback - Function to call when the element is found.
85+
* @param {HTMLElement} root - The root DOM element to begin the search from (default is 'document').
86+
*/
87+
function onElementMounted(selector, root, callback) {
88+
var element = root.querySelector(selector);
89+
if (element) {
90+
callback(element);
91+
return;
92+
}
93+
94+
var observer = new MutationObserver(function (mutations, observer) {
95+
var element = root.querySelector(selector);
96+
if (element) {
97+
callback(element);
98+
observer.disconnect();
99+
}
100+
});
101+
102+
observer.observe(root, {
103+
childList: true,
104+
subtree: true,
105+
});
106+
}
107+
108+
/**
109+
* Waits for an element to have its shadow root loaded and triggers a callback once it's ready.
110+
*
111+
* @param {HTMLElement} element - The element with a shadow root.
112+
* @param {function} callback - Function to call when the shadow root is loaded.
113+
*/
114+
function waitForShadowRoot(element, callback) {
115+
var observer = new MutationObserver(function (mutations) {
116+
for (var i = 0; i < mutations.length; i++) {
117+
var mutation = mutations[i];
118+
if (mutation.type === "childList" && element.shadowRoot) {
119+
callback(element.shadowRoot);
120+
observer.disconnect();
121+
return;
122+
}
123+
}
124+
});
125+
126+
observer.observe(element, { childList: true });
127+
}
128+
};

‎WordPress/WordPress.xcodeproj/project.pbxproj

+6
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@
198198
019D699E2A5EA963003B676D /* RootViewCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019D699D2A5EA963003B676D /* RootViewCoordinatorTests.swift */; };
199199
019D69A02A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019D699F2A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift */; };
200200
019D69A12A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 019D699F2A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift */; };
201+
01A8508B2A8A126400BD8A97 /* support_chat_widget.css in Resources */ = {isa = PBXBuildFile; fileRef = 01A8508A2A8A126400BD8A97 /* support_chat_widget.css */; };
202+
01A8508C2A8A126400BD8A97 /* support_chat_widget.css in Resources */ = {isa = PBXBuildFile; fileRef = 01A8508A2A8A126400BD8A97 /* support_chat_widget.css */; };
201203
01CE5007290A889F00A9C2E0 /* TracksConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CE5006290A889F00A9C2E0 /* TracksConfiguration.swift */; };
202204
01CE5008290A88BD00A9C2E0 /* TracksConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CE5006290A889F00A9C2E0 /* TracksConfiguration.swift */; };
203205
01CE500C290A88BF00A9C2E0 /* TracksConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CE5006290A889F00A9C2E0 /* TracksConfiguration.swift */; };
@@ -5839,6 +5841,7 @@
58395841
018635912A85376700915532 /* SupportChatBotViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SupportChatBotViewModelTests.swift; sourceTree = "<group>"; };
58405842
019D699D2A5EA963003B676D /* RootViewCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootViewCoordinatorTests.swift; sourceTree = "<group>"; };
58415843
019D699F2A5EBF47003B676D /* WordPressAuthenticatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordPressAuthenticatorProtocol.swift; sourceTree = "<group>"; };
5844+
01A8508A2A8A126400BD8A97 /* support_chat_widget.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = support_chat_widget.css; sourceTree = "<group>"; };
58425845
01CE5006290A889F00A9C2E0 /* TracksConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracksConfiguration.swift; sourceTree = "<group>"; };
58435846
01CE5010290A890300A9C2E0 /* TracksConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TracksConfiguration.swift; sourceTree = "<group>"; };
58445847
01DBFD8629BDCBF200F3720F /* JetpackNativeConnectionService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackNativeConnectionService.swift; sourceTree = "<group>"; };
@@ -9732,6 +9735,7 @@
97329735
018635862A8109F900915532 /* SupportChatBotViewModel.swift */,
97339736
018635892A810A9600915532 /* support_chat_widget.html */,
97349737
0186358C2A810ABA00915532 /* support_chat_widget.js */,
9738+
01A8508A2A8A126400BD8A97 /* support_chat_widget.css */,
97359739
);
97369740
path = SupportChatBot;
97379741
sourceTree = "<group>";
@@ -19017,6 +19021,7 @@
1901719021
FA6FAB4725EF7C6A00666CED /* ReaderRelatedPostsSectionHeaderView.xib in Resources */,
1901819022
17222DA5261DDDF90047B163 /* spectrum-icon-app-60x60@3x.png in Resources */,
1901919023
1761F18926209AEE000815EF /* pride-icon-app-76x76@2x.png in Resources */,
19024+
01A8508B2A8A126400BD8A97 /* support_chat_widget.css in Resources */,
1902019025
9826AE8C21B5CC8D00C851FA /* PostingActivityMonth.xib in Resources */,
1902119026
08D499671CDD20450004809A /* Menus.storyboard in Resources */,
1902219027
9A3BDA1022944F4D00FBF510 /* CountriesMapView.xib in Resources */,
@@ -19467,6 +19472,7 @@
1946719472
FABB1FC92602FC2C00C8785C /* reader.css in Resources */,
1946819473
F41E4EE428F24623001880C6 /* 3d-icon-app-60@2x.png in Resources */,
1946919474
F46597F328E669D400D5F49A /* spectrum-on-white-icon-app-83.5@2x.png in Resources */,
19475+
01A8508C2A8A126400BD8A97 /* support_chat_widget.css in Resources */,
1947019476
FABB1FCC2602FC2C00C8785C /* SiteStatsTableHeaderView.xib in Resources */,
1947119477
F41E4EEF28F247D3001880C6 /* white-on-green-icon-app-60@2x.png in Resources */,
1947219478
FABB1FCD2602FC2C00C8785C /* Posts.storyboard in Resources */,

0 commit comments

Comments
 (0)
Please sign in to comment.