Use new API methods for saving
This commit is contained in:
@ -13,6 +13,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
let authToken = undefined;
|
||||
const omnivoreURL = process.env.OMNIVORE_URL;
|
||||
const omnivoreGraphqlURL = process.env.OMNIVORE_GRAPHQL_URL;
|
||||
@ -76,7 +78,7 @@ function uploadFile ({ id, uploadSignedUrl }, contentType, contentObjUrl) {
|
||||
xhr.setRequestHeader('Content-Type', contentType);
|
||||
|
||||
xhr.onerror = () => {
|
||||
resolve(null);
|
||||
resolve(undefined);
|
||||
};
|
||||
xhr.onload = () => {
|
||||
// Uploaded.
|
||||
@ -91,14 +93,13 @@ function uploadFile ({ id, uploadSignedUrl }, contentType, contentObjUrl) {
|
||||
});
|
||||
}
|
||||
|
||||
function savePdfFile (tab, url, contentType, contentObjUrl) {
|
||||
function savePdfFile(tab, url, contentType, contentObjUrl) {
|
||||
return new Promise(resolve => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = async function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
const { data } = JSON.parse(xhr.response);
|
||||
|
||||
if ('errorCodes' in data.uploadFileRequest) {
|
||||
if (data.uploadFileRequest.errorCodes[0] === 'UNAUTHORIZED') {
|
||||
clearClickCompleteState();
|
||||
@ -114,7 +115,7 @@ function savePdfFile (tab, url, contentType, contentObjUrl) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!data.uploadFileRequest || !data.uploadFileRequest.id || 'errorCodes' in data.uploadFileRequest) {
|
||||
if (!data.uploadFileRequest || !data.uploadFileRequest.id || !data.uploadFileRequest.createdPageId || 'errorCodes' in data.uploadFileRequest) {
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
@ -123,9 +124,26 @@ function savePdfFile (tab, url, contentType, contentObjUrl) {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const uploadFileId = await uploadFile(data.uploadFileRequest, contentType, contentObjUrl);
|
||||
const result = await uploadFile(data.uploadFileRequest, contentType, contentObjUrl);
|
||||
URL.revokeObjectURL(contentObjUrl);
|
||||
return resolve(uploadFileId);
|
||||
|
||||
if (!result) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const createdPageId = data.uploadFileRequest.createdPageId
|
||||
const url = omnivoreURL + '/article/sr/' + createdPageId
|
||||
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
text: 'Saved to Omnivore',
|
||||
link: url,
|
||||
linkText: 'Read Now',
|
||||
type: 'success'
|
||||
}
|
||||
})
|
||||
return resolve(data.uploadFileRequest);
|
||||
}
|
||||
} else if (xhr.status === 400) {
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
@ -148,6 +166,7 @@ function savePdfFile (tab, url, contentType, contentObjUrl) {
|
||||
}
|
||||
... on UploadFileRequestSuccess {
|
||||
id
|
||||
createdPageId
|
||||
uploadSignedUrl
|
||||
}
|
||||
}
|
||||
@ -155,7 +174,8 @@ function savePdfFile (tab, url, contentType, contentObjUrl) {
|
||||
variables: {
|
||||
input: {
|
||||
url,
|
||||
contentType
|
||||
contentType,
|
||||
createPageEntry: true,
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -175,65 +195,47 @@ function clearClickCompleteState () {
|
||||
});
|
||||
}
|
||||
|
||||
function handleSaveResponse (tab, xhr) {
|
||||
function handleSaveResponse(tab, field, 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'
|
||||
}
|
||||
});
|
||||
}
|
||||
const item = data[field]
|
||||
if (!item) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if ('errorCodes' in item) {
|
||||
const messagePayload = {
|
||||
text: descriptions[data.createArticle.errorCodes[0]] || 'Unable to save page',
|
||||
type: 'error'
|
||||
}
|
||||
|
||||
if (item.errorCodes[0] === 'UNAUTHORIZED') {
|
||||
messagePayload.errorCode = 401
|
||||
messagePayload.url = omnivoreURL
|
||||
clearClickCompleteState()
|
||||
}
|
||||
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: messagePayload
|
||||
})
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const url = item['url']
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
text: 'Saved to Omnivore',
|
||||
link: url ?? omnivoreURL + '/home',
|
||||
linkText: 'Read Now',
|
||||
type: 'success'
|
||||
}
|
||||
})
|
||||
|
||||
return item
|
||||
} else if (xhr.status === 400) {
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
@ -241,12 +243,22 @@ function handleSaveResponse (tab, xhr) {
|
||||
text: 'Unable to save page',
|
||||
type: 'error'
|
||||
}
|
||||
});
|
||||
})
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function saveUrl (currentTab, url) {
|
||||
async function saveUrl(currentTab, url) {
|
||||
const requestId = uuidv4()
|
||||
await saveApiRequest(currentTab, SAVE_URL_QUERY, 'saveUrl', {
|
||||
source: 'extension',
|
||||
clientRequestId: requestId,
|
||||
url: encodeURI(url),
|
||||
})
|
||||
}
|
||||
|
||||
async function saveApiRequest(currentTab, query, field, input) {
|
||||
browserApi.tabs.sendMessage(currentTab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
@ -256,61 +268,47 @@ async function saveUrl (currentTab, url) {
|
||||
});
|
||||
|
||||
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) => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.open('POST', omnivoreGraphqlURL + 'graphql', true)
|
||||
setupConnection(xhr)
|
||||
|
||||
xhr.onerror = (err) => { reject(err) }
|
||||
|
||||
xhr.onload = () => {
|
||||
try {
|
||||
handleSaveResponse(currentTab, xhr)
|
||||
const res = handleSaveResponse(currentTab, field, xhr)
|
||||
if (!res) {
|
||||
return reject()
|
||||
}
|
||||
resolve(res);
|
||||
} catch (err) {
|
||||
console.log('response error', err)
|
||||
reject(err)
|
||||
}
|
||||
resolve({});
|
||||
};
|
||||
}
|
||||
|
||||
const data = JSON.stringify({
|
||||
query: CREATE_ARTICLE_SAVING_REQUEST_QUERY,
|
||||
query,
|
||||
variables: {
|
||||
input: {
|
||||
url
|
||||
}
|
||||
input
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
xhr.send(data);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('error saving url', err)
|
||||
console.log('error saving page', err)
|
||||
browserApi.tabs.sendMessage(currentTab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
text: 'Unable to save page',
|
||||
type: 'error',
|
||||
}
|
||||
});
|
||||
return undefined
|
||||
});
|
||||
}
|
||||
|
||||
function saveArticle (tab) {
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
type: 'loading',
|
||||
text: 'Saving...'
|
||||
}
|
||||
});
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
const descriptions = {
|
||||
BAD_DATA: 'Unable to save page',
|
||||
NOT_ALLOWED_TO_PARSE: 'Not allowed to parse this article',
|
||||
UNAUTHORIZED: 'Please login to Omnivore to authorize this action',
|
||||
UNABLE_TO_FETCH: 'Unable to fetch page',
|
||||
PAYLOAD_TOO_LARGE: 'This article is too large'
|
||||
};
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
handleSaveResponse(tab, xhr)
|
||||
}
|
||||
};
|
||||
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.GetContent
|
||||
}, async (response) => {
|
||||
@ -319,56 +317,42 @@ function saveArticle (tab) {
|
||||
return;
|
||||
}
|
||||
|
||||
const requestId = uuidv4()
|
||||
const { type, pageInfo, doc, uploadContentObjUrl } = response;
|
||||
|
||||
let uploadResult = null;
|
||||
|
||||
switch(type) {
|
||||
case 'pdf': {
|
||||
// For PDFs, we first upload the PDF file before passing the upload file ID in createArticle
|
||||
uploadResult = await savePdfFile(tab, encodeURI(tab.url), pageInfo.contentType, uploadContentObjUrl);
|
||||
if (!uploadResult || !uploadResult.id) {
|
||||
browserApi.tabs.sendMessage(tab.id, {
|
||||
action: ACTIONS.ShowMessage,
|
||||
payload: {
|
||||
text: 'Unable to save page',
|
||||
type: 'error'
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
case 'html': {
|
||||
await saveApiRequest(tab, SAVE_PAGE_QUERY, 'savePage', {
|
||||
source: 'extension',
|
||||
clientRequestId: requestId,
|
||||
originalContent: doc,
|
||||
title: pageInfo.title,
|
||||
url: encodeURI(tab.url),
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'url': {
|
||||
// We don't have to special case URL, it will fall through
|
||||
// and be handled when isContentAvailable returns false
|
||||
await saveApiRequest(tab, SAVE_URL_QUERY, 'saveUrl', {
|
||||
source: 'extension',
|
||||
clientRequestId: requestId,
|
||||
url: encodeURI(tab.url),
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'pdf': {
|
||||
const uploadResult = await savePdfFile(tab, encodeURI(tab.url), pageInfo.contentType, uploadContentObjUrl);
|
||||
if (!uploadResult || !uploadResult.id) {
|
||||
// If the upload failed for any reason, try to save the PDF URL instead
|
||||
await saveApiRequest(tab, SAVE_URL_QUERY, 'saveUrl', {
|
||||
source: 'extension',
|
||||
clientRequestId: requestId,
|
||||
url: encodeURI(tab.url),
|
||||
})
|
||||
return;
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const isContentAvailable = (doc && doc.length) || uploadResult;
|
||||
const query = isContentAvailable ? CREATE_ARTICLE_QUERY : CREATE_ARTICLE_SAVING_REQUEST_QUERY;
|
||||
const input = {
|
||||
url: encodeURI(tab.url)
|
||||
};
|
||||
|
||||
if (isContentAvailable) {
|
||||
input.preparedDocument = {
|
||||
document: doc,
|
||||
pageInfo
|
||||
};
|
||||
input.uploadFileId = (uploadResult && uploadResult.id) || null;
|
||||
}
|
||||
|
||||
const data = JSON.stringify({
|
||||
query,
|
||||
variables: {
|
||||
input
|
||||
}
|
||||
});
|
||||
|
||||
xhr.open('POST', omnivoreGraphqlURL + 'graphql', true);
|
||||
setupConnection(xhr);
|
||||
|
||||
xhr.send(data);
|
||||
});
|
||||
}
|
||||
|
||||
@ -700,7 +684,7 @@ function init () {
|
||||
});
|
||||
|
||||
browserApi.contextMenus.create({
|
||||
id: "log-selection",
|
||||
id: "save-selection",
|
||||
title: "Save to Omnivore",
|
||||
contexts: ["link"],
|
||||
onclick: async function(obj) {
|
||||
|
||||
Reference in New Issue
Block a user