Skip to content
1 change: 0 additions & 1 deletion src/content_scripts/content_script.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
display: flex;
align-items: center;
justify-content: center;
min-width: 150px;
text-align: center;
color: white;
background: #b31b1b;
Expand Down
196 changes: 133 additions & 63 deletions src/content_scripts/content_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ $.extend($.easing, {
},
});

var timeout = null;
var prevent = false;
var pdfTitleIters = 0;
var PDF_TITLE_ITERS = 0;

/**
* Centralizes HTML svg codes
Expand Down Expand Up @@ -160,6 +158,34 @@ const svg = (name) => {
}
};

const injectNotifCSS = () => {
let el = document.createElement("style");
el.type = "text/css";
el.innerText = `
.pm-notif-loader {
width: 24px;
height: 24px;
border: 2px solid #FFF;
border-bottom-color: transparent;
border-radius: 50%;
display: inline-block;
box-sizing: border-box;
animation: rotation 1s linear infinite;
}

@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
`;
document.head.appendChild(el);
return el;
};

const makePaperMemoryHTMLDiv = (paper) => {
return paper.venue
? /*html*/ `
Expand Down Expand Up @@ -238,7 +264,7 @@ const handleDefaultAction = async () => {
default:
warn("Unknown action:", action);
}
text && feedback(text);
text && feedback({ text });
};

/** Whether or not to ignore the current paper based on its `is` object
Expand Down Expand Up @@ -366,94 +392,136 @@ const contentScriptMain = async ({
const paper = global.state.papers[id];
const maxWait = 60 * 1000;
while (1) {
const waitTime = Math.min(maxWait, 250 * 2 ** pdfTitleIters);
const waitTime = Math.min(maxWait, 250 * 2 ** PDF_TITLE_ITERS);
await sleep(waitTime);
document.title = "";
document.title = paper.title;
pdfTitleIters++;
PDF_TITLE_ITERS++;
}
};
makeTitle(id);
}
};

const makeNotif = () => {
if (global.notif.element) return;
const notif = /*html*/ ` <div id="feedback-notif"></div> `;
document.body.insertAdjacentHTML("beforeend", notif);
global.notif.element = $("#feedback-notif");
style("feedback-notif", "padding", "0px");
};

const hideNotif = () =>
new Promise(async (resolve) => {
const end = ({ dontWait = false } = {}) => {
global.notif.prevent = false;
global.notif.isLoading = false;
setTimeout(resolve, dontWait ? 0 : 150);
};

if (!global.notif.element) {
warn("[PM][hideNotif] Notif element not found");
end({ dontWait: true });
return;
}

global.notif.element.animate(
{ right: "-200px", opacity: "0" },
global.notif.hideSpeed,
"easeInOutBack",
end
);
// sometimes animate does not call the callback
setTimeout(end, global.notif.hideSpeed + 50);
});

const setNotifContent = (text) => {
if (!global.notif.element) {
warn("[PM][setNotifContent] Notif element not found");
return;
}
global.notif.element.html(text);
};

const showNotif = () =>
new Promise((resolve) => {
if (!global.notif.element) {
console.warn("[PM][showNotif] Notif element not found");
makeNotif();
}
global.notif.element.animate(
{
right: "64px",
opacity: "1",
},
global.notif.showSpeed,
"easeInOutBack",
resolve
);
});

/**
* Slides a div in then out, bottom right, with some text to give the user
* a feedback on some action performed
* @param {string} text the text to display in the slider div
* @returns {void}
*/
const feedback = (text, paper = null) => {
const feedback = async ({
text,
paper = null,
displayDuration = global.notif.displayDuration,
loading = false,
}) => {
if (document.readyState === "loading") {
setTimeout(() => feedback(text, paper), 250);
setTimeout(() => feedback({ text, paper, displayDuration, loading }), 250);
return;
}
makeNotif();
if (global.notif.prevent && !global.notif.isLoading) {
setTimeout(() => feedback({ text, paper, displayDuration, loading }), 100);
return;
}
const notifTime = 3000;
try {
clearTimeout(timeout);
findEl({ element: "feedback-notif" }).remove();
prevent = true;
clearTimeout(global.notif.timeout);
await hideNotif();
global.notif.prevent = true;
} catch (error) {}

let content = "";
global.notif.isLoading = false;

if (paper) {
text = /*html*/ ` <div id="notif-text">
content = /*html*/ ` <div id="notif-text">
<div>${text}</div>
</div>
<div title="Cancel" id="notif-cancel">
<div>${svg("notif-cancel")}</div>
</div>`;
} else if (loading) {
global.notif.isLoading = true;
content = /*html*/ `<div id="notif-text"><span class="pm-notif-loader"></span></div>`;
} else {
text = /*html*/ ` <div id="notif-text">
<div>${text}</div>
content = /*html*/ ` <div id="notif-text">
<div style="display: flex;">${text}</div>
</div>`;
}
document.body.insertAdjacentHTML(
"beforeend",
/*html*/ ` <div id="feedback-notif">${text}</div> `
);
style("feedback-notif", "padding", "0px");
$("#feedback-notif").animate(
{
right: "64px",
opacity: "1",
},
400,
"easeInOutBack"
);
timeout = setTimeout(() => {
$("#feedback-notif").animate(
{ right: "-200px", opacity: "0" },
400,
"easeInOutBack",
() => {
!prevent && $("#feedback-notif").remove();
prevent = false;

setNotifContent(content);
await showNotif();
global.notif.timeout = setTimeout(hideNotif, displayDuration);

paper &&
addListener("notif-cancel", "click", async () => {
clearTimeout(global.notif.timeout);
await deletePaperInStorage(paper.id, global.state.papers);
if (!global.state.deleted) {
global.state.deleted = {};
}
);
}, notifTime);
addListener("notif-cancel", "click", async () => {
clearTimeout(timeout);
await deletePaperInStorage(paper.id, global.state.papers);
if (!global.state.deleted) {
global.state.deleted = {};
}
global.state.deleted[paper.id] = true;
setTimeout(() => {
delete global.state.deleted[paper.id];
}, 30 * 1000);
timeout = setTimeout(() => {
$("#feedback-notif").animate(
{ right: "-200px", opacity: "0" },
400,
"easeInOutBack",
() => {
!prevent && $("#feedback-notif").remove();
prevent = false;
}
);
}, notifTime);
setHTML("notif-text", "<div>Removed from memory</div>");
});
global.state.deleted[paper.id] = true;
setTimeout(() => delete global.state.deleted[paper.id], 30 * 1000);
global.notif.timeout = setTimeout(hideNotif, displayDuration);
setHTML("notif-text", "<div>Removed from memory</div>");
});
};

/**
Expand Down Expand Up @@ -694,7 +762,7 @@ const arxiv = async (checks) => {
});
});
copyTextToClipboard(findEl({ element: "pm-bibtex-textarea" }).innerText);
feedback("Bibtex Citation Copied!");
feedback({ text: "Bibtex Citation Copied!" });
});
addListener(querySelector("#markdown-header .copy-feedback"), "click", (e) => {
$("#markdown-header .copy-feedback").fadeOut(200, () => {
Expand All @@ -709,7 +777,7 @@ const arxiv = async (checks) => {
copyTextToClipboard(
findEl({ element: "markdown-link" }).innerText.replaceAll("\n", "")
);
feedback("Markdown Link Copied!");
feedback({ text: "Markdown Link Copied!" });
});
}
};
Expand Down Expand Up @@ -843,6 +911,7 @@ const tryArxivDisplay = async ({
// Promise resolved when the DOM is loaded
const domReadyPromise = new Promise((resolve) => {
document.addEventListener("DOMContentLoaded", () => {
injectNotifCSS();
resolve();
});
});
Expand All @@ -861,4 +930,5 @@ const tryArxivDisplay = async ({
}, 1000);
}
}
await hideNotif();
})();
10 changes: 10 additions & 0 deletions src/shared/js/utils/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,16 @@ global.englishStopWords = new Set([

global.journalAbbreviations = null;

global.notif = {
timeout: null,
prevent: false,
showSpeed: 400,
displayDuration: 3000,
hideSpeed: 400,
element: null,
isLoading: false,
};

// ----------------------------------------------------
// ----- TESTS: modules for node.js environment -----
// ----------------------------------------------------
Expand Down
17 changes: 12 additions & 5 deletions src/shared/js/utils/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ const logTrace = typeof LOGTRACE !== "undefined" && LOGTRACE;
* @returns {void}
*/
const log = (...args) => {
if (logTrace) {
const stack = new Error().stack;
args.push("\n\nLog trace:\n" + stack.split("\n").slice(2).join("\n"));
}
let messageConfig = "%c%s ";

let isInfo = false;
Expand All @@ -35,6 +31,17 @@ const log = (...args) => {
isDebug = true;
args = args.slice(1);
}

if (
(isError && logTrace >= 1) ||
(isWarn && logTrace >= 2) ||
(isInfo && logTrace >= 3) ||
(isDebug && logTrace >= 4) ||
logTrace >= 5
) {
const stack = new Error().stack;
args.push("\n\nLog trace:\n" + stack.split("\n").slice(2).join("\n"));
}
// https://stackoverflow.com/questions/55643825/how-to-apply-colors-to-console-log-when-using-multiple-arguments
args.forEach((argument) => {
const type = typeof argument;
Expand Down Expand Up @@ -984,7 +991,7 @@ const urlToWebsiteId = (url) => {
* @param {number} time The time after which to resolve the promise
* @returns {Promise} The wrapped promise
*/
const silentPromiseTimeout = (prom, time = 5000) => {
const silentPromiseTimeout = (prom, time = 2000) => {
// https://advancedweb.hu/how-to-add-timeout-to-a-promise-in-javascript/
let timer;
return Promise.race([
Expand Down
9 changes: 8 additions & 1 deletion src/shared/js/utils/logTrace.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// use in the log() function util
var LOGTRACE = false;
// 0 => no trace
// 1 => trace errors
// 2 => trace warnings
// 3 => trace info
// 4 => trace debug
// 5 => trace all
var LOGTRACE = 0;

if (typeof module !== "undefined" && module.exports != null) {
var dummyModule = module;
dummyModule.exports = {
Expand Down
10 changes: 7 additions & 3 deletions src/shared/js/utils/paper.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ const addOrUpdatePaper = async ({
global.state.papers = (await getStorage("papers")) ?? {};
const id = await parseIdFromUrl(url, tab);
const paperExists = global.state.papers.hasOwnProperty(id);
prefs && prefs.checkFeedback && feedback({ loading: true });

if (
id &&
Expand Down Expand Up @@ -620,7 +621,7 @@ const addOrUpdatePaper = async ({

if (!paper.codeLink || !paper.venue) {
try {
const pwcMatch = await tryPWCMatch(paper);
const pwcMatch = await silentPromiseTimeout(tryPWCMatch(paper));

const pwcCodeLink = !paper.codeLink && pwcMatch?.codeLink;
const pwcNote = pwcMatch?.note;
Expand Down Expand Up @@ -690,11 +691,14 @@ const addOrUpdatePaper = async ({
"<br/><div id='feedback-pwc'>(+ repo from PapersWithCode) </div>";
}

prefs && prefs.checkFeedback && store && feedback(notifText, paper);
prefs &&
prefs.checkFeedback &&
store &&
feedback({ text: notifText, paper });
} else {
// existing paper but new code repo
notifText = "Found a code repository on PapersWithCode!";
prefs && prefs.checkFeedback && store && feedback(notifText);
prefs && prefs.checkFeedback && store && feedback({ text: notifText });
}
} else {
store && logOk("Updated '" + paper.title + "' in your Memory");
Expand Down
Loading