Extension: support right click saveurl and shortcut key to save current tab
This commit is contained in:
@ -22,7 +22,7 @@
|
|||||||
"256": "/images/extension/icon-256.png"
|
"256": "/images/extension/icon-256.png"
|
||||||
},
|
},
|
||||||
|
|
||||||
"permissions": ["activeTab", "storage", "https://*/**", "http://*/**"],
|
"permissions": ["activeTab", "storage", "contextMenus", "https://*/**", "http://*/**"],
|
||||||
|
|
||||||
"background": {
|
"background": {
|
||||||
"page": "/views/background.html",
|
"page": "/views/background.html",
|
||||||
@ -72,5 +72,14 @@
|
|||||||
"default_title": "Omnivore Save Article"
|
"default_title": "Omnivore Save Article"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"commands": {
|
||||||
|
"_execute_browser_action": {
|
||||||
|
"suggested_key": {
|
||||||
|
"default": "Alt + O"
|
||||||
|
},
|
||||||
|
"description": "Save the current tab to Omnivore"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"web_accessible_resources": ["views/cta-popup.html"]
|
"web_accessible_resources": ["views/cta-popup.html"]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,17 @@ function removeStorage (itemsToRemove) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentTab () {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
browserApi.tabs.query({
|
||||||
|
active: true,
|
||||||
|
currentWindow: true
|
||||||
|
}, function (tabs) {
|
||||||
|
resolve(tabs[0] || null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function setupConnection(xhr) {
|
function setupConnection(xhr) {
|
||||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
if (authToken) {
|
if (authToken) {
|
||||||
@ -164,6 +175,119 @@ function clearClickCompleteState () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleSaveResponse (tab, xhr) {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
const { data } = JSON.parse(xhr.response);
|
||||||
|
if ('createArticle' in data) {
|
||||||
|
if ('errorCodes' in data.createArticle) {
|
||||||
|
const messagePayload = {
|
||||||
|
text: descriptions[data.createArticle.errorCodes[0]] || 'Unable to save page',
|
||||||
|
type: 'error'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data.createArticle.errorCodes[0] === 'UNAUTHORIZED') {
|
||||||
|
messagePayload.errorCode = 401;
|
||||||
|
messagePayload.url = omnivoreURL;
|
||||||
|
|
||||||
|
clearClickCompleteState();
|
||||||
|
}
|
||||||
|
|
||||||
|
browserApi.tabs.sendMessage(tab.id, {
|
||||||
|
action: ACTIONS.ShowMessage,
|
||||||
|
payload: messagePayload
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const article = data.createArticle.createdArticle;
|
||||||
|
const user = data.createArticle.user;
|
||||||
|
const link = omnivoreURL + (article.hasContent ? (`/${user.profile.username}/` + article.slug) : '/home');
|
||||||
|
browserApi.tabs.sendMessage(tab.id, {
|
||||||
|
action: ACTIONS.ShowMessage,
|
||||||
|
payload: {
|
||||||
|
text: 'Saved to Omnivore',
|
||||||
|
link: link,
|
||||||
|
linkText: 'View',
|
||||||
|
type: 'success'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ('errorCodes' in data.createArticleSavingRequest) {
|
||||||
|
browserApi.tabs.sendMessage(tab.id, {
|
||||||
|
action: ACTIONS.ShowMessage,
|
||||||
|
payload: {
|
||||||
|
text: descriptions[data.createArticleSavingRequest.errorCodes[0]] || 'Unable to save page',
|
||||||
|
type: 'error'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const articleSavingRequest = data.createArticleSavingRequest.articleSavingRequest;
|
||||||
|
const link = omnivoreURL + '/article/sr/' + articleSavingRequest.id;
|
||||||
|
browserApi.tabs.sendMessage(tab.id, {
|
||||||
|
action: ACTIONS.ShowMessage,
|
||||||
|
payload: {
|
||||||
|
text: 'Saved to Omnivore',
|
||||||
|
link: link,
|
||||||
|
linkText: 'View',
|
||||||
|
type: 'success'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (xhr.status === 400) {
|
||||||
|
browserApi.tabs.sendMessage(tab.id, {
|
||||||
|
action: ACTIONS.ShowMessage,
|
||||||
|
payload: {
|
||||||
|
text: 'Unable to save page',
|
||||||
|
type: 'error'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveUrl (currentTab, url) {
|
||||||
|
browserApi.tabs.sendMessage(currentTab.id, {
|
||||||
|
action: ACTIONS.ShowMessage,
|
||||||
|
payload: {
|
||||||
|
type: 'loading',
|
||||||
|
text: 'Saving...'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', omnivoreGraphqlURL + 'graphql', true);
|
||||||
|
setupConnection(xhr);
|
||||||
|
xhr.onerror = (err) => {
|
||||||
|
resolve(null);
|
||||||
|
};
|
||||||
|
xhr.onload = (res) => {
|
||||||
|
try {
|
||||||
|
handleSaveResponse(currentTab, xhr)
|
||||||
|
} catch (err) {
|
||||||
|
console.log('response error', err)
|
||||||
|
}
|
||||||
|
resolve({});
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = JSON.stringify({
|
||||||
|
query: CREATE_ARTICLE_SAVING_REQUEST_QUERY,
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
xhr.send(data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('error saving url', err)
|
||||||
|
return undefined
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function saveArticle (tab) {
|
function saveArticle (tab) {
|
||||||
browserApi.tabs.sendMessage(tab.id, {
|
browserApi.tabs.sendMessage(tab.id, {
|
||||||
action: ACTIONS.ShowMessage,
|
action: ACTIONS.ShowMessage,
|
||||||
@ -183,72 +307,7 @@ function saveArticle (tab) {
|
|||||||
};
|
};
|
||||||
xhr.onreadystatechange = function () {
|
xhr.onreadystatechange = function () {
|
||||||
if (xhr.readyState === 4) {
|
if (xhr.readyState === 4) {
|
||||||
if (xhr.status === 200) {
|
handleSaveResponse(tab, xhr)
|
||||||
const { data } = JSON.parse(xhr.response);
|
|
||||||
if ('createArticle' in data) {
|
|
||||||
if ('errorCodes' in data.createArticle) {
|
|
||||||
const messagePayload = {
|
|
||||||
text: descriptions[data.createArticle.errorCodes[0]] || 'Unable to save page',
|
|
||||||
type: 'error'
|
|
||||||
};
|
|
||||||
|
|
||||||
if (data.createArticle.errorCodes[0] === 'UNAUTHORIZED') {
|
|
||||||
messagePayload.errorCode = 401;
|
|
||||||
messagePayload.url = omnivoreURL;
|
|
||||||
|
|
||||||
clearClickCompleteState();
|
|
||||||
}
|
|
||||||
|
|
||||||
browserApi.tabs.sendMessage(tab.id, {
|
|
||||||
action: ACTIONS.ShowMessage,
|
|
||||||
payload: messagePayload
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const article = data.createArticle.createdArticle;
|
|
||||||
const user = data.createArticle.user;
|
|
||||||
const link = omnivoreURL + (article.hasContent ? (`/${user.profile.username}/` + article.slug) : '/home');
|
|
||||||
browserApi.tabs.sendMessage(tab.id, {
|
|
||||||
action: ACTIONS.ShowMessage,
|
|
||||||
payload: {
|
|
||||||
text: 'Saved to Omnivore',
|
|
||||||
link: link,
|
|
||||||
linkText: 'View',
|
|
||||||
type: 'success'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ('errorCodes' in data.createArticleSavingRequest) {
|
|
||||||
browserApi.tabs.sendMessage(tab.id, {
|
|
||||||
action: ACTIONS.ShowMessage,
|
|
||||||
payload: {
|
|
||||||
text: descriptions[data.createArticleSavingRequest.errorCodes[0]] || 'Unable to save page',
|
|
||||||
type: 'error'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const articleSavingRequest = data.createArticleSavingRequest.articleSavingRequest;
|
|
||||||
const link = omnivoreURL + '/article/sr/' + articleSavingRequest.id;
|
|
||||||
browserApi.tabs.sendMessage(tab.id, {
|
|
||||||
action: ACTIONS.ShowMessage,
|
|
||||||
payload: {
|
|
||||||
text: 'Saved to Omnivore',
|
|
||||||
link: link,
|
|
||||||
linkText: 'View',
|
|
||||||
type: 'success'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (xhr.status === 400) {
|
|
||||||
browserApi.tabs.sendMessage(tab.id, {
|
|
||||||
action: ACTIONS.ShowMessage,
|
|
||||||
payload: {
|
|
||||||
text: 'Unable to save page',
|
|
||||||
type: 'error'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -484,18 +543,13 @@ function checkAuthOnFirstClickPostInstall (tabId) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentTab () {
|
function handleActionClick () {
|
||||||
return new Promise((resolve) => {
|
executeAction(function (currentTab) {
|
||||||
browserApi.tabs.query({
|
onExtensionClick(currentTab.id);
|
||||||
active: true,
|
})
|
||||||
currentWindow: true
|
|
||||||
}, function (tabs) {
|
|
||||||
resolve(tabs[0] || null);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleActionClick () {
|
function executeAction(action) {
|
||||||
getCurrentTab().then((currentTab) => {
|
getCurrentTab().then((currentTab) => {
|
||||||
browserApi.tabs.sendMessage(currentTab.id, {
|
browserApi.tabs.sendMessage(currentTab.id, {
|
||||||
action: ACTIONS.Ping
|
action: ACTIONS.Ping
|
||||||
@ -504,7 +558,7 @@ function handleActionClick () {
|
|||||||
// Content script ready
|
// Content script ready
|
||||||
const isSignedUp = await checkAuthOnFirstClickPostInstall(currentTab.id);
|
const isSignedUp = await checkAuthOnFirstClickPostInstall(currentTab.id);
|
||||||
if (isSignedUp) {
|
if (isSignedUp) {
|
||||||
onExtensionClick(currentTab.id);
|
action(currentTab);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const extensionManifest = browserApi.runtime.getManifest();
|
const extensionManifest = browserApi.runtime.getManifest();
|
||||||
@ -518,7 +572,7 @@ function handleActionClick () {
|
|||||||
executeScripts(currentTab.id, scriptFiles, async function () {
|
executeScripts(currentTab.id, scriptFiles, async function () {
|
||||||
const isSignedUp = await checkAuthOnFirstClickPostInstall(currentTab.id);
|
const isSignedUp = await checkAuthOnFirstClickPostInstall(currentTab.id);
|
||||||
if (isSignedUp) {
|
if (isSignedUp) {
|
||||||
onExtensionClick(currentTab.id);
|
action(currentTab);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -644,6 +698,17 @@ function init () {
|
|||||||
browserActionApi.setIcon({
|
browserActionApi.setIcon({
|
||||||
path: getIconPath(true)
|
path: getIconPath(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
browserApi.contextMenus.create({
|
||||||
|
id: "log-selection",
|
||||||
|
title: "Save to Omnivore",
|
||||||
|
contexts: ["link"],
|
||||||
|
onclick: async function(obj) {
|
||||||
|
executeAction(async function (currentTab) {
|
||||||
|
await saveUrl(currentTab, obj.linkUrl)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
browserApi.runtime.onMessage.addListener(({ action, payload }, sender, sendResponse) => {
|
browserApi.runtime.onMessage.addListener(({ action, payload }, sender, sendResponse) => {
|
||||||
/* async actions */
|
|
||||||
if (action === ACTIONS.GetContent) {
|
if (action === ACTIONS.GetContent) {
|
||||||
prepareContent().then((pageContent) => {
|
prepareContent().then((pageContent) => {
|
||||||
sendResponse({
|
sendResponse({
|
||||||
|
|||||||
Reference in New Issue
Block a user