Skip to content

Commit

Permalink
Merge pull request #55 from BagToad/dev-bagtoad-add-images-tab
Browse files Browse the repository at this point in the history
Add new "Images" tab for image attachment types
  • Loading branch information
BagToad authored Apr 25, 2024
2 parents fd3aeaf + 3e3d3a6 commit 2fae6bc
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 69 deletions.
50 changes: 38 additions & 12 deletions src/background/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ async function filterTicket() {
ticketStorage: {
links: [],
attachments: [],
images: [],
state: "loading",
},
});
Expand All @@ -81,6 +82,7 @@ async function filterTicket() {
let numComments = 0; // Number of comments received from Zendesk.
const linksArr = []; // Array of link objects to be displayed.
const attachmentsArr = []; // Array of attachment objects to be displayed.
const imagesArr = []; // Array of image objects to be displayed.

// Loop through all pages of comments until there are no more pages.
while (nextPage != "" && r <= rlimit) {
Expand Down Expand Up @@ -108,16 +110,16 @@ async function filterTicket() {
r++;

//Grab only the required fields from the JSON.
await commentData.comments.forEach(async (comments) => {
await commentData.comments.forEach(async (comment) => {
// Parse the HTML text and return an array of links.
const links = await parseAElementsFromHTMLText(comments.html_body);
const links = await parseAElementsFromHTMLText(comment.html_body);
// Push the required link information to the linksArr.
if (links.length > 0) {
links.forEach((link) => {
linksArr.push({
commentID: comments.id,
auditID: comments.audit_id,
createdAt: comments.created_at,
commentID: comment.id,
auditID: comment.audit_id,
createdAt: comment.created_at,
parent_text: link.parent_text,
text: link.text,
href: link.href,
Expand All @@ -127,14 +129,36 @@ async function filterTicket() {
}

// Push the required attachment information to the attachmentsArr.
if (comments.attachments.length > 0) {
attachmentsArr.push({
commentID: comments.id,
auditID: comments.audit_id,
created_at: comments.created_at,
attachments: comments.attachments,
if (comment.attachments.length > 0) {
const tempArr = [];
comment.attachments.forEach((attachment) => {
if (!attachment.content_type.startsWith("image/")) {
tempArr.push(attachment);
}
});
if (tempArr.length > 0) {
attachmentsArr.push({
commentID: comment.id,
auditID: comment.audit_id,
created_at: comment.created_at,
attachments: tempArr,
});
}
}

// Filter images out of attachments data and push to imagesArr
comment.attachments.forEach((attachment) => {
if (attachment.content_type.startsWith("image/")) {
imagesArr.push({
commentID: comment.id,
auditID: comment.audit_id,
createdAt: comment.created_at,
url: attachment.content_url,
mappedURL: attachment.mapped_content_url,
fileName: attachment.file_name,
});
}
});
});
}

Expand Down Expand Up @@ -228,12 +252,14 @@ async function filterTicket() {

console.log("filtered links: ", filteredLinks);
console.log("attachments: ", attachmentsArr);
console.log("images: ", imagesArr); // Log the images array

// Store the filtered links and attachments for the current ticket in the browser storage.
// Store the filtered links, attachments, and images for the current ticket in the browser storage.
browser.storage.local.set({
ticketStorage: {
links: filteredLinks,
attachments: attachmentsArr,
images: imagesArr, // Store the images array
state: "complete",
count: numComments,
ticketID: ticketID,
Expand Down
129 changes: 78 additions & 51 deletions src/content-scripts/contentscript.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,99 @@
console.log("Zendesk Link Collector - loaded content script");

// Message handler for messages from the background script.
browser.runtime.onMessage.addListener(function(request, sender, sendResponse) {
browser.runtime.onMessage.addListener(function (request, sender, sendResponse) {
// Scroll to the comment.
if (request.type == "scroll") {
const element = document.querySelector(`[data-comment-id="${request.commentID}"]`)
// Older Zendesk versions.
? document.querySelector(`[data-comment-id="${request.commentID}"]`)
// Newer Zendesk versions.
: document.querySelector(`[id="comment-${request.auditID}"]`);
const element = document.querySelector(
`[data-comment-id="${request.commentID}"]`
)
? // Older Zendesk versions.
document.querySelector(`[data-comment-id="${request.commentID}"]`)
: // Newer Zendesk versions.
document.querySelector(`[id="comment-${request.auditID}"]`);
if (element) {
element.scrollIntoView({ behavior: "smooth", block: "center" });
return;
}

// Last resort, sometimes zendesk does not add the data-comment-id or id attributes to the comments.
// Get the comment from the audits endpoint, find the comment with the same HTML in the DOM and scroll to it.
const url = new URL(document.URL);
const urlArr = url.href.split('/');
const urlArr = url.href.split("/");
const ticketID = urlArr[urlArr.length - 1];

fetch(`${url.protocol}//${url.hostname}/api/v2/tickets/${ticketID}/audits/${request.auditID}`).then(async function(response) {
const data = await response.json();
document.querySelectorAll('.zd-comment').forEach((comment) => {
data.audit.events.forEach((event) => {
if (event.type == 'Comment') {
if (comment.outerHTML == event.html_body) {
comment.scrollIntoView({ behavior: "smooth", block: "center" });
return;

fetch(
`${url.protocol}//${url.hostname}/api/v2/tickets/${ticketID}/audits/${request.auditID}`
).then(async function (response) {
const data = await response.json();
document.querySelectorAll(".zd-comment").forEach((comment) => {
data.audit.events.forEach((event) => {
if (event.type == "Comment") {
if (comment.outerHTML == event.html_body) {
comment.scrollIntoView({ behavior: "smooth", block: "center" });
return;
}
}
}
});
});
});
});
}
}

// Code from https://stackoverflow.com/questions/55214828/how-to-make-a-cross-origin-request-in-a-content-script-currently-blocked-by-cor/55215898#55215898
if (request.type == "fetch") {
fetch(request.input, request.init).then(
function (response) {
return response.text().then(function (text) {
sendResponse([
{
body: text,
status: response.status,
statusText: response.statusText,
},
null,
]);
});
},
function (error) {
sendResponse([null, error]);
}
);
}

// Code from https://stackoverflow.com/questions/55214828/how-to-make-a-cross-origin-request-in-a-content-script-currently-blocked-by-cor/55215898#55215898
if (request.type == 'fetch') {
fetch(request.input, request.init).then(function(response) {
return response.text().then(function(text) {
sendResponse([{
body: text,
status: response.status,
statusText: response.statusText,
}, null]);
// Background script does not have a DOM, so when it needs to parse links from HTML, it sends this message.
if (request.type == "parse-html-a") {
const parser = new DOMParser();
const doc = parser.parseFromString(request.htmlText, "text/html");
const links = doc.querySelectorAll(`a`);
const linksArr = [];
links.forEach((link) => {
linksArr.push({
parent_text: link.parentElement.innerHTML,
text: link.innerText,
href: link.href,
});
});
}, function(error) {
sendResponse([null, error]);
});
}
sendResponse(linksArr);
}

// Background script does not have a DOM, so when it needs to parse links from HTML, it sends this message.
if (request.type == 'parse-html-a') {
const parser = new DOMParser();
const doc = parser.parseFromString(request.htmlText, "text/html");
const links = doc.querySelectorAll(`a`);
const linksArr = [];
links.forEach((link) => {
linksArr.push(
{
parent_text: link.parentElement.innerHTML,
text: link.innerText,
href: link.href
// Try to open zendesk preview.
if (request.type == "image-preview") {
const imageURL = request.imageURL;
document.querySelectorAll("a").forEach((a) => {
if (a.href == imageURL) {
//Close any modal that are open.
const closeButton = document.querySelector(
'[data-garden-id="modals.close"]'
);
if (closeButton) {
closeButton.click();
}
if (a) {
a.click();
}
}
);
});
sendResponse(linksArr);
}
});
}

return true;
});
return true;
});
53 changes: 48 additions & 5 deletions src/popup/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ body {
flex-direction: column;
overflow: auto;
min-width: 350px;
max-width: 500px;
max-width: 800px;
min-height: 150px;
max-height: 500px;
}
Expand Down Expand Up @@ -220,20 +220,28 @@ h3.list-header {
}

/* Remove unused space between headers and the view buttons */
#list-container-links h3:first-of-type, #list-container-attachments ul:first-of-type {
#list-container-links h3:first-of-type, #list-container-attachments #list-container-images ul:first-of-type {
margin-top: 0;
}

ul.list-links, ul.list-attachments {
ul.list-links, ul.list-attachments, li.list-item-images {
display: flex;
flex-direction: column;
}

li.list-item-links, li.list-item-attachments {
li.list-item-links, li.list-item-attachments, li.list-item-images {
list-style: none;
margin-bottom: 2px;
}

li.list-item-images {
margin-bottom: 30px;
}

li.list-item-images i {
margin-bottom: 7px;
}

li.list-item-links {
display: flex;
flex-direction: row;
Expand Down Expand Up @@ -308,4 +316,39 @@ li.list-item-attachments ul li {

.icon-search {
background-image: url(../icons/search.svg);
}
}

/* New styles for the "Images" tab */
.button-images.checked {
background-color: var(--accent);
border-color: var(--accent-dark);
}

.button-images.checked:hover {
background-color: var(--accent-hover);
border-color: var(--accent-dark-hover);
}

#list-container-images {
display: none;
flex-direction: column;
padding: 20px;
white-space: nowrap;
}

.list-item-images {
margin-bottom: 30px;
max-width: 750px;
}

.list-item-images img {
max-width: 750px;
}

#list-container-images img:hover {
cursor: pointer;
}

#list-container-images.selected {
display: flex;
}
9 changes: 8 additions & 1 deletion src/popup/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<div class="row" id="viewOption">
<a href="#" class="button button-fill checked" id="button-links">Links</a>
<a href="#" class="button button-fill" id="button-attachments">Attachments</a>
<a href="#" class="button button-fill" id="button-images">Images</a>
<a href="#" class="button button-fill" id="button-options">
<img class="icon icon-invert" src="../icons/gear.svg" width="15px" height="15px">
</a>
Expand Down Expand Up @@ -42,7 +43,13 @@
<div>There doesn't seem to be any comments with attachments!</div>
</div>
</div>
<div id="list-container-images" class="list-container">
<div class="not-found-container hidden" id="not-found-container-images">
<img src="../icons/bufo-sad-but-ok.png" width="50px" height="50px">
<div>There doesn't seem to be any images!</div>
</div>
</div>
<script type="application/javascript" src="../lib/browser-polyfill.min.js"></script>
<script type="application/javascript" src="popup.js"></script>
</body>
</html>
</html>
Loading

0 comments on commit 2fae6bc

Please sign in to comment.