Simplify status updating code, start to add edit labels

This commit is contained in:
Jackson Harper
2023-03-20 13:36:11 +08:00
parent 74c2969b03
commit 93c19ecdea
6 changed files with 287 additions and 96 deletions

View File

@ -86,3 +86,44 @@ function updatePageTitle(apiUrl, pageId, title) {
console.log('updated title: ', data)
})
}
function setLabels(apiUrl, pageId, labelIds) {
console.log('setting labels: ', apiUrl, pageId, labelIds)
const mutation = JSON.stringify({
query: `mutation SetLabels($input: SetLabelsInput!) {
setLabels(input: $input) {
... on SetLabelsSuccess {
labels {
id
}
}
... on SetLabelsError {
errorCodes
}
}
}
`,
variables: {
input: {
pageId,
labelIds,
},
},
})
return fetch(apiUrl, {
method: 'POST',
redirect: 'follow',
credentials: 'include',
mode: 'cors',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: mutation,
})
.then((response) => response.json())
.then((data) => {
console.log('updated labels: ', data)
})
}

View File

@ -118,6 +118,7 @@ function savePdfFile(tab, url, contentType, contentObjUrl) {
action: ACTIONS.UpdateStatus,
payload: {
status: 'success',
target: 'page',
requestId: createdPageId,
},
})
@ -212,6 +213,7 @@ function handleSaveResponse(tab, field, xhr) {
action: ACTIONS.UpdateStatus,
payload: {
status: 'success',
target: 'page',
link: url ?? omnivoreURL + '/home',
},
})
@ -770,12 +772,35 @@ function init() {
}
if (request.action === ACTIONS.EditTitle) {
console.log('EDITING TITLE REQUEST: ')
updatePageTitle(
omnivoreGraphqlURL + 'graphql',
request.payload.pageId,
request.payload.title
)
).then(() => {
browserApi.tabs.sendMessage(sender.tab.id, {
action: ACTIONS.UpdateStatus,
payload: {
target: 'title',
status: 'success',
},
})
})
}
if (request.action === ACTIONS.SetLabels) {
setLabels(
omnivoreGraphqlURL + 'graphql',
request.payload.pageId,
request.payload.labelIds
).then(() => {
browserApi.tabs.sendMessage(sender.tab.id, {
action: ACTIONS.UpdateStatus,
payload: {
target: 'labels',
status: 'success',
},
})
})
}
})

View File

@ -36,6 +36,7 @@ window.ACTIONS = {
UpdateStatus: 'UPDATE_STATUS',
EditTitle: 'EDIT_TITLE',
SetLabels: 'SET_LABELS',
}
window.DONT_REMOVE_ELEMENTS = ['meta', 'script', 'title']

View File

@ -35,7 +35,7 @@
return true
}
handleMessage(action, payload)
window.handleMessage(action, payload)
if (action === ACTIONS.Ping) {
sendResponse({ pong: true })

View File

@ -60,11 +60,21 @@
const file = await fetch(browserApi.runtime.getURL('views/toast.html'))
const html = await file.text()
const root = document.createElement('div')
root.attachShadow({ mode: 'open' })
if (root.shadowRoot) {
root.shadowRoot.innerHTML = `<style>:host {all initial;}</style>`
}
const toastEl = document.createElement('div')
toastEl.id = '#omnivore-toast'
toastEl.innerHTML = html
root.shadowRoot.appendChild(toastEl)
return toastEl
document.body.appendChild(root)
connectButtons(root)
return root
}
function createCtaModal(url) {
@ -83,16 +93,14 @@
}
function hideToastAfter(timeInMs) {
console.log('hiding toast in: ', timeInMs)
if (hideToastTimeout) clearTimeout(hideToastTimeout)
hideToastTimeout = setTimeout(function () {
console.log('clearing currentToastEl:', currentToastEl)
currentToastEl.remove()
currentToastEl = undefined
}, timeInMs)
}
function cancelAutoDismiss() {
console.log('canceling auto dismiss')
if (hideToastTimeout) clearTimeout(hideToastTimeout)
}
@ -102,19 +110,44 @@
return
}
const statusBox = currentToastEl.querySelector('.omnivore-toast-statusBox')
switch (payload.status) {
case 'loading':
statusBox.innerHTML = systemIcons.animatedLoader
switch (payload.target) {
case 'page':
{
const statusBox = currentToastEl.shadowRoot.querySelector(
'.omnivore-toast-statusBox'
)
switch (payload.status) {
case 'loading':
statusBox.innerHTML = systemIcons.animatedLoader
break
case 'success':
statusBox.innerHTML = systemIcons.success
break
}
}
break
case 'success':
statusBox.innerHTML = systemIcons.success
case 'title':
updateStatusBox(
'#omnivore-edit-title-status',
payload.status,
payload.message,
payload.status == 'success' ? 2500 : undefined
)
break
case 'labels':
updateStatusBox(
'#omnivore-edit-labels-status',
payload.status,
payload.message,
payload.status == 'success' ? 2500 : undefined
)
break
}
}
// Called for all messages
function handleMessage(action, payload) {
console.log('handling message: ', action, payload)
if (payload && 'requestId' in payload && payload.requestId) {
requestId = payload.requestId ?? requestId
}
@ -151,8 +184,10 @@
// let styleAsError = false
if (payload.type === 'loading') {
duration = 5000
const image = currentToastEl.querySelector('.omnivore-toast-statusBox')
image.innerHTML = systemIcons.animatedLoader
updateStatus({
status: 'loading',
target: 'page',
})
}
// } else if (payload.type !== 'error') {
// currentIconEl.innerHTML = systemIcons.success
@ -170,11 +205,6 @@
// updateToastText(payload)
// }
if (currentToastEl.parentNode !== bodyEl) {
bodyEl.appendChild(currentToastEl)
connectButtons()
}
hideToastAfter(duration)
// remove any existing toasts not created by current content script
@ -186,10 +216,37 @@
})
}
function updateStatusBox(boxId, state, message, dismissAfter) {
const statusBox = currentToastEl.shadowRoot.querySelector(boxId)
const image = (() => {
switch (state) {
case 'loading':
return systemIcons.animatedLoader
case 'success':
return systemIcons.success
default:
return undefined
}
})()
if (image) {
statusBox.innerHTML = `<span style='padding-right: 10px'>${image}</span><span style='line-height: 20px'>${message}</span>`
} else {
statusBox.innerText = message
}
if (dismissAfter) {
setTimeout(() => {
statusBox.innerHTML = null
}, dismissAfter)
}
}
function toggleRow(rowId) {
const container = document.getElementById(rowId)
const container = currentToastEl.shadowRoot.querySelector(rowId)
console.log(' toggling', rowId, container)
const initialState = container?.getAttribute('data-state')
const rows = document.querySelectorAll('.omnivore-toast-func-row')
const rows = currentToastEl.shadowRoot.querySelectorAll(
'.omnivore-toast-func-row'
)
rows.forEach((r) => {
r.setAttribute('data-state', 'closed')
@ -201,17 +258,19 @@
}
}
function connectButtons() {
function connectButtons(root) {
const btns = [
{ id: 'omnivore-toast-edit-title-btn', func: editTitle },
{ id: 'omnivore-toast-edit-labels-btn', func: editLabels },
{ id: 'omnivore-toast-read-now-btn', func: readNow },
{ id: 'omnivore-open-menu-btn', func: openMenu },
{ id: 'omnivore-toast-close-button', func: closeToast },
{ id: '#omnivore-toast-edit-title-btn', func: editTitle },
{ id: '#omnivore-toast-edit-labels-btn', func: editLabels },
{ id: '#omnivore-toast-read-now-btn', func: readNow },
{ id: '#omnivore-open-menu-btn', func: openMenu },
{ id: '#omnivore-toast-close-button', func: closeToast },
]
for (const btnInfo of btns) {
const btn = document.getElementById(btnInfo.id)
console.log('root', root, 'shadowRoot', root.shadowRoot)
const btn = root.shadowRoot.querySelector(btnInfo.id)
console.log(' connecting btn', btn, 'tp', btnInfo.func)
if (btn) {
btn.addEventListener('click', btnInfo.func)
}
@ -219,7 +278,6 @@
}
function createLabelRow(label, idx) {
console.log('createLabelRow, ', label, idx)
const element = document.createElement('button')
const dot = document.createElement('span')
dot.style = 'width:10px;height:10px;border-radius:1000px;'
@ -232,10 +290,10 @@
check.style = 'margin-left: auto;pointer-events: none;'
check.className = 'checkbox'
check.innerHTML = `
<svg width="14" height="11" viewBox="0 0 14 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.7411 1.75864L4.79692 10.7028L0.69751 6.60341L1.74845 5.55246L4.79692 8.59348L12.6902 0.707703L13.7411 1.75864Z" fill="#888888"/>
</svg>
`
<svg width="14" height="11" viewBox="0 0 14 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.7411 1.75864L4.79692 10.7028L0.69751 6.60341L1.74845 5.55246L4.79692 8.59348L12.6902 0.707703L13.7411 1.75864Z" fill="#888888"/>
</svg>
`
element.appendChild(dot)
element.appendChild(title)
@ -243,6 +301,7 @@
element.onclick = labelClick
element.onkeydown = labelKeyDown
element.setAttribute('data-label-id', label.id)
element.setAttribute('data-label-idx', idx)
element.setAttribute('data-label-selected', 'off')
element.setAttribute('tabIndex', '-1')
@ -264,7 +323,6 @@
}
function labelKeyDown(event) {
console.log('event.key.toLowerCase(): ', event.key.toLowerCase())
switch (event.key.toLowerCase()) {
case 'arrowup': {
if (
@ -276,13 +334,6 @@
const idx = event.target.getAttribute('data-label-idx')
let prevIdx = idx && Number(idx) != NaN ? Number(idx) - 1 : 0
console.log(
' prevIdx: ',
prevIdx,
'is save',
event.target ==
event.target.form.querySelector('#omnivore-save-button')
)
if (
event.target ==
event.target.form.querySelector('#omnivore-save-button')
@ -290,7 +341,7 @@
// Focus the last label index
const maxItemIdx = Math.max(
...Array.from(
document.querySelectorAll(`button[data-label-idx]`)
event.target.form.querySelectorAll(`button[data-label-idx]`)
).map((b) => Number(b.getAttribute('data-label-idx')))
)
if (maxItemIdx != NaN) {
@ -298,7 +349,7 @@
}
}
const prev = document.querySelector(
const prev = event.target.form.querySelector(
`button[data-label-idx='${prevIdx}']`
)
if (prev) {
@ -313,7 +364,7 @@
case 'arrowdown': {
const idx = event.target.getAttribute('data-label-idx')
const nextIdx = idx && Number(idx) != NaN ? Number(idx) + 1 : 0
const next = document.querySelector(
const next = event.target.form.querySelector(
`button[data-label-idx='${nextIdx}']`
)
if (next) {
@ -334,10 +385,6 @@
'data-label-selected',
labelSelected == 'on' ? 'off' : 'on'
)
console.log(
'data-label-selected:',
event.target.getAttribute('data-label-selected')
)
event.preventDefault()
break
}
@ -346,18 +393,29 @@
function editTitle() {
cancelAutoDismiss()
toggleRow('omnivore-edit-title-row')
document.getElementById('omnivore-edit-title-textarea')?.focus()
toggleRow('#omnivore-edit-title-row')
currentToastEl.shadowRoot
.querySelector('#omnivore-edit-title-textarea')
?.focus()
currentToastEl.shadowRoot.querySelector(
'#omnivore-edit-title-form'
).onsubmit = (event) => {
updateStatusBox(
'#omnivore-edit-title-status',
'loading',
'Updating title...'
)
document.getElementById('omnivore-edit-title-form').onsubmit = (event) => {
event.preventDefault()
browserApi.runtime.sendMessage({
action: ACTIONS.EditTitle,
payload: {
pageId: requestId,
title: document.getElementById('omnivore-edit-title-textarea').value,
title: event.target.elements.title.value,
},
})
event.preventDefault()
}
}
@ -368,16 +426,22 @@
labels = cachedLabels
})
toggleRow('omnivore-edit-labels-row')
document.getElementById('omnivore-edit-label-text')?.focus()
const list = document.getElementById('omnivore-edit-labels-list')
document
.getElementById('omnivore-edit-label-text')
toggleRow('#omnivore-edit-labels-row')
currentToastEl.shadowRoot
.querySelector('#omnivore-edit-label-text')
?.focus()
const list = currentToastEl.shadowRoot.querySelector(
'#omnivore-edit-labels-list'
)
currentToastEl.shadowRoot
.querySelector('#omnivore-edit-label-text')
.addEventListener('input', function () {
updateLabels(this.value)
})
document.getElementById('omnivore-edit-label-text').onkeydown = labelKeyDown
currentToastEl.shadowRoot.querySelector(
'#omnivore-edit-label-text'
).onkeydown = labelKeyDown
if (list) {
list.innerHTML = ''
@ -387,19 +451,35 @@
})
}
document.getElementById('omnivore-edit-labels-form').onsubmit = (event) => {
currentToastEl.shadowRoot.querySelector(
'#omnivore-edit-labels-form'
).onsubmit = (event) => {
event.preventDefault()
const statusBox = currentToastEl.shadowRoot.querySelector(
'#omnivore-edit-labels-status'
)
statusBox.innerText = 'Updating labels...'
const labelIds = Array.from(
currentToastEl.shadowRoot.querySelectorAll(
`button[data-label-selected="on"]`
)
).map((e) => e.getAttribute('data-label-id'))
console.log('selected label ids: ', labelIds)
browserApi.runtime.sendMessage({
action: ACTIONS.EditTitle,
action: ACTIONS.SetLabels,
payload: {
labels: [],
pageId: requestId,
labelIds: labelIds,
},
})
}
}
async function updateLabels(filterValue) {
const list = document.getElementById('omnivore-edit-labels-list')
const list = currentToastEl.shadowRoot.querySelector(
'#omnivore-edit-labels-list'
)
if (list) {
list.innerHTML = ''
if (filterValue) {
@ -422,7 +502,9 @@
function readNow() {
cancelAutoDismiss()
const container = document.getElementById('omnivore-toast-container')
const container = currentToastEl.shadowRoot.querySelector(
'#omnivore-toast-container'
)
container.setAttribute('data-state', 'open')
if (finalURL) {
@ -442,8 +524,8 @@
}
function closeToast() {
console.log('closing toast')
currentToastEl.remove()
currentToastEl = undefined
}
window.showToolbar = showToolbar

View File

@ -1,27 +1,30 @@
<style>
#omnivore-toast-container {
display: flex !important;
position: fixed !important;
position: fixed;
top: 20px;
right: 30px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
top: 20px !important;
right: 30px !important;
align-items: flex-start !important;
justify-content: flex-end !important;
overflow: hidden !important;
border-radius: 4px !important;
background: #fff !important;
font: 400 12px Inter, sans-serif !important;
align-items: flex-start;
justify-content: flex-end;
overflow: hidden;
border-radius: 4px;
background: #fff;
font: 400 12px Inter, sans-serif;
line-height: 20px;
box-shadow: 0px 5px 20px rgba(32, 31, 29, 0.12) !important;
transition: all 300ms ease !important;
z-index: 9999999 !important;
box-shadow: 0px 5px 20px rgba(32, 31, 29, 0.12);
transition: all 300ms ease;
z-index: 9999999;
width: 455px;
}
#omnivore-toast-container .omnivore-toast-func-row {
display: flex;
width: 100%;
padding-top: 0px;
padding-left: 15px;
padding-right: 15px;
padding-bottom: 10px;
@ -33,11 +36,23 @@
#omnivore-toast-container .omnivore-toast-func-row[data-state="closed"] {
display: none;
}
#omnivore-toast-container .omnivore-toast-func-status {
display: flex;
align-items: flex-start;
justify-content: center;
width: 100%;
color:#898989;
font-style: normal;
font-weight: 400;
font-size: 12px;
line-height: 20px;
text-align: center;
}
#omnivore-toast-button-row {
gap: 5px;
align-items: center;
padding-top: 7px;
padding-bottom: 7px;
padding-top: 7px;
padding-bottom: 7px;
display: flex;
width: 100%;
padding-left: 15px;
@ -58,6 +73,9 @@
#omnivore-toast-container button:hover {
background-color: #EBEBEB;
}
#omnivore-toast-container .omnivore-save-button button {
background-color: rgb(255, 210, 52)
}
#omnivore-toast-container #omnivore-toast-close-button:hover {
background-color: unset;
}
@ -68,11 +86,16 @@
fill: #D9D9D9;
stroke: white;
}
#omnivore-toast-container form {
display: block;
margin: 0px;
}
.omnivore-toast-divider {
height:20px;
border-right: 1px solid #D9D9D9;
}
.omnivore-toast-statusBox {
display: flex;
width: 20px;
margin-left: 0px;
margin-right: 7px;
@ -94,6 +117,8 @@
resize: none;
border: 1px solid #8E8E93;
border-radius: 4px;
box-sizing: border-box;
background-color: transparent;
}
#omnivore-toast-container .omnivore-toast-func-row button {
@ -117,6 +142,8 @@
padding: 10px;
border: 1px solid #8E8E93;
border-radius: 4px;
box-sizing: border-box;
background-color: transparent;
}
#omnivore-extra-buttons-row {
@ -185,22 +212,34 @@
<div id="omnivore-toast-container">
<div id="omnivore-toast-button-row">
<span class="omnivore-toast-statusBox">
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.74048 17.2104C14.711 17.2104 18.7405 13.4049 18.7405 8.71045C18.7405 4.01603 14.711 0.210449 9.74048 0.210449C4.76992 0.210449 0.740479 4.01603 0.740479 8.71045C0.740479 13.4049 4.76992 17.2104 9.74048 17.2104ZM9.74048 15.7938C13.8826 15.7938 17.2405 12.6225 17.2405 8.71045C17.2405 4.79843 13.8826 1.62712 9.74048 1.62712C5.59834 1.62712 2.24048 4.79843 2.24048 8.71045C2.24048 12.6225 5.59834 15.7938 9.74048 15.7938Z" fill="#32D74B"/>
<path d="M13.178 6.52295L8.59462 10.8979L6.30298 8.71045" stroke="#32D74B" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<animateTransform
from="0 0 0"
to="360 0 0"
attributeName="transform"
type="rotate"
repeatCount="indefinite"
dur="1300ms"
/>
</svg>
<style>
.loading-spinner {
/* control spinner size with setting font-size */
font-size: 3rem;
border: 2px solid #FFD234;
border-top-color: transparent;
border-radius: 50%;
width: 18px;
height: 18px;
animation: loading-spinner 1.5s linear infinite;
margin: 0 auto;
box-sizing: border-box;
}
@keyframes loading-spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<div class="loading-spinner"></div>
</span>
<span class="omnivore-toast-divider"></span>
<button id="omnivore-toast-edit-title-btn">
<button class="omnivore-top-button" id="omnivore-toast-edit-title-btn">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.5625 4.50004L13.5 8.43754M6.71406 15.1516L2.84828 11.2858M6.517 15.1875H3.375C3.22582 15.1875 3.08274 15.1283 2.97725 15.0228C2.87176 14.9173 2.8125 14.7742 2.8125 14.625V11.483C2.8125 11.4092 2.82705 11.336 2.85532 11.2678C2.88359 11.1995 2.92502 11.1375 2.97725 11.0853L11.4148 2.64778C11.5202 2.5423 11.6633 2.48303 11.8125 2.48303C11.9617 2.48303 12.1048 2.5423 12.2102 2.64778L15.3523 5.78979C15.4577 5.89528 15.517 6.03835 15.517 6.18754C15.517 6.33672 15.4577 6.4798 15.3523 6.58528L6.91475 15.0228C6.86252 15.075 6.80051 15.1165 6.73226 15.1447C6.66402 15.173 6.59087 15.1875 6.517 15.1875Z" stroke="#6A6968" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
@ -245,12 +284,15 @@
</div>
<div id="omnivore-edit-title-row" class="omnivore-toast-func-row" data-state="closed">
<span id="omnivore-edit-title-status" class="omnivore-toast-func-status"></span>
<form id="omnivore-edit-title-form">
<textarea id="omnivore-edit-title-textarea"> </textarea>
<button>Save</button>
<textarea id="omnivore-edit-title-textarea" name="title"></textarea>
<button class="omnivore-save-button">Save</button>
</form>
</div>
<div id="omnivore-edit-labels-row" class="omnivore-toast-func-row" data-state="closed">
<span id="omnivore-edit-labels-status" class="omnivore-toast-func-status"></span>
<form id="omnivore-edit-labels-form">
<input type="text" id="omnivore-edit-label-text" placeholder="Filter for labels" tabindex="0"> </input>
<div id="omnivore-edit-labels-list">