Skip to content

Commit

Permalink
Replace then-chaining by async/await
Browse files Browse the repository at this point in the history
  • Loading branch information
jobisoft authored and Amunak committed Sep 3, 2024
1 parent 7d0986d commit c061778
Showing 1 changed file with 145 additions and 140 deletions.
285 changes: 145 additions & 140 deletions popup.js
Original file line number Diff line number Diff line change
@@ -1,159 +1,164 @@
browser.tabs.query({
active: true,
currentWindow: true,
}).then(tabs => {
browser.messageDisplay.getDisplayedMessage(tabs[0].id).then(message => {
browser.messages.getFull(message.id).then(fullMessage => {
console.log(fullMessage)
const headers = fullMessage.headers
const messageEl = document.getElementById('message')
const actionContainerEl = document.getElementById('action-container')

if (!headers.hasOwnProperty('list-unsubscribe')) {
messageEl.innerText = browser.i18n.getMessage('noUnsub')
return
}).then(handleActiveTabs)

async function handleActiveTabs(tabs) {
let message = await browser.messageDisplay.getDisplayedMessage(tabs[0].id);
let fullMessage = await browser.messages.getFull(message.id);

const headers = fullMessage.headers
const messageEl = document.getElementById('message')
const actionContainerEl = document.getElementById('action-container')

if (!headers.hasOwnProperty('list-unsubscribe')) {
messageEl.innerText = browser.i18n.getMessage('noUnsub')
return
}

let unsubEmail = null
let unsubLink = null
headers['list-unsubscribe'][0].split(',').forEach(link => {
let result
if (result = link.match(/^\s*<(mailto:.+)>/)) {
unsubEmail = result[1]
return
}
if (result = link.match(/^\s*<(https?:\/\/.+)>/)) {
unsubLink = result[1]
return
}
})

// validate link
if (unsubLink !== null) {
try {
unsubLink = new URL(unsubLink)
} catch (e) {
console.warn(e)
unsubLink = null
}
}

// validate and prepare email
let unsubEmailSubject = null
if (unsubEmail !== null) {
try {
unsubEmail = new URL(unsubEmail)

// extract subject
if (unsubEmail.searchParams.has('subject')) {
unsubEmailSubject = unsubEmail.searchParams.get('subject')
}

let unsubEmail = null
let unsubLink = null
headers['list-unsubscribe'][0].split(',').forEach(link => {
let result
if (result = link.match(/^\s*<(mailto:.+)>/)) {
unsubEmail = result[1]
return
}
if (result = link.match(/^\s*<(https?:\/\/.+)>/)) {
unsubLink = result[1]
return
}
})
unsubEmail = unsubEmail.pathname

// validate link
if (unsubLink !== null) {
try {
unsubLink = new URL(unsubLink)
} catch (e) {
console.warn(e)
unsubLink = null
}
if (!unsubEmail.match(/^[^@]+@[^@]+$/)) {
console.warn('invalid email address', unsubEmail)
unsubEmail = null
}
} catch (e) {
console.warn(e)
unsubEmail = null
}
}

if (unsubLink === null && unsubEmail === null) {
messageEl.innerText = browser.i18n.getMessage('noUnsub')
console.error('no valid unsubscribe link or email found')
return
}

// check if RFC 8058 is supported
let unsubCommand = null
if (headers.hasOwnProperty('list-unsubscribe-post')) {
unsubCommand = headers['list-unsubscribe-post'][0]
}

console.log('unsub link: ', unsubLink)
console.log('unsub email: ', unsubEmail)
console.log('unsub command: ', unsubCommand)

messageEl.innerText = browser.i18n.getMessage('unsubConfirmPrompt')
if (unsubLink !== null) {
const linkContainerEl = document.getElementById('unsub-link-container')
const linkEl = document.createElement('code')
linkEl.innerText = unsubLink
linkEl.addEventListener('click', () => {
navigator.clipboard.writeText(linkEl.innerText)
})

// validate and prepare email
let unsubEmailSubject = null
if (unsubEmail !== null) {
try {
unsubEmail = new URL(unsubEmail)

// extract subject
if (unsubEmail.searchParams.has('subject')) {
unsubEmailSubject = unsubEmail.searchParams.get('subject')
}
linkContainerEl.innerText = browser.i18n.getMessage('unsubLink')
linkContainerEl.appendChild(linkEl)

unsubEmail = unsubEmail.pathname
if (unsubCommand) {
const button = document.createElement('button')
button.innerText = browser.i18n.getMessage('confirmOneClick')
button.addEventListener('click', async () => {
linkContainerEl.style.display = 'none'
actionContainerEl.style.display = 'none'
messageEl.innerText = browser.i18n.getMessage('oneClickInProgress')

if (!unsubEmail.match(/^[^@]+@[^@]+$/)) {
console.warn('invalid email address', unsubEmail)
unsubEmail = null
}
try {
await fetch(unsubLink, {
method: 'POST',
body: unsubCommand,
});
messageEl.innerText = browser.i18n.getMessage(
'oneClickSuccess'
);
} catch (e) {
console.warn(e)
unsubEmail = null
messageEl.innerText = browser.i18n.getMessage(
'oneClickFailure',
e.message
);
}
}
})

if (unsubLink === null && unsubEmail === null) {
messageEl.innerText = browser.i18n.getMessage('noUnsub')
console.error('no valid unsubscribe link or email found')
return
}
actionContainerEl.appendChild(button)
}

// check if RFC 8058 is supported
let unsubCommand = null
if (headers.hasOwnProperty('list-unsubscribe-post')) {
unsubCommand = headers['list-unsubscribe-post'][0]
}
const button = document.createElement('button')
button.innerText = browser.i18n.getMessage('confirmOpenLink')
button.addEventListener('click', () => {
browser.tabs.create({
url: unsubLink.toString(),
})
})
actionContainerEl.appendChild(button)
}

if (unsubEmail !== null) {
const button = document.createElement('button')
button.innerText = browser.i18n.getMessage('confirmComposeEmail')
button.addEventListener('click', async () => {
const identityId = await (async (message) => {
// try to get identityId from the message
if (typeof message.folder === 'Object') {
const identities = await messenger.accounts.get(message.folder.accountId).identities
// we can use it only if there is only one identity
if (identities.length === 1) {
return identities[0].id
}
}

console.log('unsub link: ', unsubLink)
console.log('unsub email: ', unsubEmail)
console.log('unsub command: ', unsubCommand)

messageEl.innerText = browser.i18n.getMessage('unsubConfirmPrompt')
if (unsubLink !== null) {
const linkContainerEl = document.getElementById('unsub-link-container')
const linkEl = document.createElement('code')
linkEl.innerText = unsubLink
linkEl.addEventListener('click', () => {
navigator.clipboard.writeText(linkEl.innerText)
})

linkContainerEl.innerText = browser.i18n.getMessage('unsubLink')
linkContainerEl.appendChild(linkEl)

if (unsubCommand) {
const button = document.createElement('button')
button.innerText = browser.i18n.getMessage('confirmOneClick')
button.addEventListener('click', async () => {
linkContainerEl.style.display = 'none'
actionContainerEl.style.display = 'none'
messageEl.innerText = browser.i18n.getMessage('oneClickInProgress')


fetch(unsubLink, {
method: 'POST',
body: unsubCommand,
}).then(() => {
messageEl.innerText = browser.i18n.getMessage('oneClickSuccess')
}).catch((e) => {
messageEl.innerText = browser.i18n.getMessage('oneClickFailure', e.message)
})
})

actionContainerEl.appendChild(button)
// try match email address to identity
const identities = await messenger.identities.list()
const matching = identities.find(identity => message.recipients.some(email => identity.email === email))
if (matching === undefined) {
console.warn('no matching identity found, using default')
return identities[0].id
}

const button = document.createElement('button')
button.innerText = browser.i18n.getMessage('confirmOpenLink')
button.addEventListener('click', () => {
browser.tabs.create({
url: unsubLink.toString(),
})
})
actionContainerEl.appendChild(button)
}
return matching.id

if (unsubEmail !== null) {
const button = document.createElement('button')
button.innerText = browser.i18n.getMessage('confirmComposeEmail')
button.addEventListener('click', async () => {
const identityId = await (async (message) => {
// try to get identityId from the message
if (typeof message.folder === 'Object') {
const identities = await messenger.accounts.get(message.folder.accountId).identities
// we can use it only if there is only one identity
if (identities.length === 1) {
return identities[0].id
}
}

// try match email address to identity
const identities = await messenger.identities.list()
const matching = identities.find(identity => message.recipients.some(email => identity.email === email))
if (matching === undefined) {
console.warn('no matching identity found, using default')
return identities[0].id
}

return matching.id

})(message)
browser.compose.beginNew({
to: unsubEmail,
subject: unsubEmailSubject ?? 'unsubscribe',
identityId,
})
})
actionContainerEl.appendChild(button)
}
})(message)
browser.compose.beginNew({
to: unsubEmail,
subject: unsubEmailSubject ?? 'unsubscribe',
identityId,
})
})
})
})
actionContainerEl.appendChild(button)
}
}

0 comments on commit c061778

Please sign in to comment.