diff --git a/background.js b/background.js index 3b87c25..f74ce76 100644 --- a/background.js +++ b/background.js @@ -51,6 +51,9 @@ chrome.runtime.onInstalled.addListener(details => { // }); // }; +// This updates the popup icon based on whether +// the tab has a saved scroll or not when the user +// is switching between tabs chrome.tabs.onActivated.addListener(() => { chrome.tabs.query({ active: true, currentWindow: true }, tabs => { const url = getUrlWithoutHash(tabs[0].url); @@ -66,13 +69,22 @@ chrome.tabs.onActivated.addListener(() => { }); }); -chrome.tabs.onUpdated.addListener(tabId => { +// This runs when a page on a tab is loaded and +// if it has a saved scroll then fetch the latest +// scroll +chrome.tabs.onUpdated.addListener((tabId, changeInfo) => { chrome.tabs.get(tabId, tab => { const url = getUrlWithoutHash(tab.url); - if (url) { + if (url && changeInfo.status === 'complete') { chrome.storage.local.get('scroll-mark', data => { const scrollMarkData = data['scroll-mark']; + + chrome.scripting.insertCSS({ + target: { tabId }, + files: ['contentScripts/index.css'], + }); + if (scrollMarkData && scrollMarkData[url] !== undefined) { executeGetScroll(tabId, null, true); setActiveIcon(); @@ -84,6 +96,8 @@ chrome.tabs.onUpdated.addListener(tabId => { }); }); +// This listens for messages from content scripts +// and updates popup icon accordingly chrome.runtime.onMessage.addListener(request => { if (request === 'setActive') { setActiveIcon(); @@ -92,6 +106,8 @@ chrome.runtime.onMessage.addListener(request => { } }); +// This listends for keyboard shortcuts and +// performs actions accordingly chrome.commands.onCommand.addListener(command => { chrome.tabs.query({ active: true, currentWindow: true }, tabs => { const currentTabId = tabs[0].id; diff --git a/contentScripts/delete.js b/contentScripts/delete.js index a01427a..6444a94 100644 --- a/contentScripts/delete.js +++ b/contentScripts/delete.js @@ -1,4 +1,4 @@ -import { getURL, getItemFromStorage } from './index'; +import { getURL, getItemFromStorage, showToast } from './index'; (async function () { const url = getURL(); @@ -9,12 +9,15 @@ import { getURL, getItemFromStorage } from './index'; let updatedURLData; + let scrollName = ''; + const shouldClearAll = (await getItemFromStorage('clear-all'))['clear-all']; if (Array.isArray(urlData) && !shouldClearAll) { const currentScrollData = await getItemFromStorage('current-scroll-id'); const id = currentScrollData['current-scroll-id']; + scrollName = urlData.find(item => item.uuid === id).scrollName; updatedURLData = urlData.filter(item => item.uuid !== id); if (updatedURLData.length === 0) { @@ -28,6 +31,7 @@ import { getURL, getItemFromStorage } from './index'; if (updatedURLData === undefined) { chrome.runtime.sendMessage('setInactive'); } + showToast(`Deleted Scrroll ${scrollName}`, 'red'); }); } })(); diff --git a/contentScripts/get.js b/contentScripts/get.js index dcf222c..7625333 100644 --- a/contentScripts/get.js +++ b/contentScripts/get.js @@ -1,4 +1,4 @@ -import { getURL, getItemFromStorage } from './index'; +import { getURL, getItemFromStorage, showToast } from './index'; (async function () { const url = getURL(); @@ -6,6 +6,7 @@ import { getURL, getItemFromStorage } from './index'; const scrollMarkData = data['scroll-mark']; let offset = null; + let item = null; const urlData = scrollMarkData[url]; if (typeof urlData.offset === 'number') { @@ -14,8 +15,6 @@ import { getURL, getItemFromStorage } from './index'; const latestScroll = await getItemFromStorage('fetch-latest-item'); const shouldFetchLatestItem = latestScroll['fetch-latest-item']; - let item = null; - if (shouldFetchLatestItem) { item = urlData.reduce((prev, current) => (prev.offset > current.offset ? prev : current), { offset: 0 }); } else { @@ -31,5 +30,6 @@ import { getURL, getItemFromStorage } from './index'; if (offset) { window.scrollTo({ left: 0, top: offset, behavior: 'smooth' }); + showToast(`Fetching scrroll ${item && item.scrollName ? item.scrollName : ''}`, 'green'); } })(); diff --git a/contentScripts/index.css b/contentScripts/index.css new file mode 100644 index 0000000..b9e0d62 --- /dev/null +++ b/contentScripts/index.css @@ -0,0 +1,87 @@ +#scrroll-in-snackbar { + visibility: hidden; + min-width: 250px; + transform: translate(-50%); + color: #fff; + text-align: center; + border-radius: 32px; + font-family: system-ui; + font-weight: 600; + padding: 16px; + position: fixed; + z-index: 1; + left: 50%; + bottom: 30px; + font-size: 18px; + display: flex; + align-items: center; +} + +#scrroll-in-snackbar b { + font-weight: 900; + margin-left: 6px; +} + +#scrroll-in-snackbar.show { + visibility: visible; + -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s; + animation: fadein 0.5s, fadeout 0.5s 2.5s; +} + +#scrroll-in-snackbar.orange { + background-color: #e67e22; +} + +#scrroll-in-snackbar.red { + background-color: #e74c3c; +} + +#scrroll-in-snackbar.green { + background-color: #2ecc71; +} + + + +@-webkit-keyframes fadein { + from { + bottom: 0; + opacity: 0; + } + to { + bottom: 30px; + opacity: 1; + } +} + +@keyframes fadein { + from { + bottom: 0; + opacity: 0; + } + to { + bottom: 30px; + opacity: 1; + } +} + +@-webkit-keyframes fadeout { + from { + bottom: 30px; + opacity: 1; + } + to { + bottom: 0; + opacity: 0; + } +} + +@keyframes fadeout { + from { + bottom: 30px; + opacity: 1; + } + to { + bottom: 0; + opacity: 0; + } +} diff --git a/contentScripts/index.js b/contentScripts/index.js index 91d06e8..c901fe4 100644 --- a/contentScripts/index.js +++ b/contentScripts/index.js @@ -37,3 +37,18 @@ export const executeUpdateScroll = (tabId, scrollId) => { chrome.storage.local.set({ 'current-scroll-id': scrollId }); executeScript(tabId, 'contentScripts/update.js'); }; + +export const showToast = (content, color) => { + const svgIcon = ``; + document.body.innerHTML += `
${svgIcon} ${content}
`; + + const x = document.getElementById('scrroll-in-snackbar'); + x.className += ' show'; + setTimeout(() => { + x.className = x.className.replace('show', ''); + // Wait for animation to complete before removing from dom + setTimeout(() => { + x.remove(); + }, 600); + }, 3000); +}; diff --git a/contentScripts/save.js b/contentScripts/save.js index 606954e..4316a12 100644 --- a/contentScripts/save.js +++ b/contentScripts/save.js @@ -1,5 +1,5 @@ import { v4 as uuidv4 } from 'uuid'; -import { getURL, MAX_SCROLLS } from './index'; +import { getURL, MAX_SCROLLS, showToast } from './index'; const url = getURL(); @@ -52,5 +52,6 @@ chrome.storage.local.get('scroll-mark', data => { const newData = scrollMarkData ? { ...scrollMarkData, [url]: updatedURLData } : { [url]: updatedURLData }; chrome.storage.local.set({ 'scroll-mark': newData }, () => { chrome.runtime.sendMessage('setActive'); + showToast(`Saved scrroll ${scrollName}`, 'green'); }); }); diff --git a/contentScripts/update.js b/contentScripts/update.js index 8914ee0..43cc69d 100644 --- a/contentScripts/update.js +++ b/contentScripts/update.js @@ -1,5 +1,5 @@ import { v4 as uuidv4 } from 'uuid'; -import { getURL, getItemFromStorage } from './index'; +import { getURL, getItemFromStorage, showToast } from './index'; (async function () { const url = getURL(); @@ -22,8 +22,11 @@ import { getURL, getItemFromStorage } from './index'; const currentScrollData = await getItemFromStorage('current-scroll-id'); const id = currentScrollData['current-scroll-id']; + let scrollName = ''; + items = items.map(currentItem => { if (currentItem.uuid === id) { + scrollName = currentItem.scrollName; return { ...currentItem, offset, @@ -36,5 +39,6 @@ import { getURL, getItemFromStorage } from './index'; const newData = { ...scrollMarkData, [url]: items }; chrome.storage.local.set({ 'scroll-mark': newData }, () => { chrome.runtime.sendMessage('setActive'); + showToast(`Updated scrroll ${scrollName}`, 'orange'); }); })(); diff --git a/rollup.config.js b/rollup.config.js index 67d4081..0006248 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -67,6 +67,10 @@ export default [ src: ['images', 'manifest.json', 'utils'], dest: ['build'], }, + { + src: ['contentScripts/index.css'], + dest: ['build/contentScripts'], + }, ], verbose: true, }),