diff --git a/submissions/Listening to this/background.js b/submissions/Listening to this/background.js new file mode 100644 index 00000000..7bcdff79 --- /dev/null +++ b/submissions/Listening to this/background.js @@ -0,0 +1,36 @@ +chrome.runtime.onInstalled.addListener(() => { + chrome.storage.sync.set({ listenedItems: [] }); +}); + +function addItem(item) { + chrome.storage.sync.get(['listenedItems'], (result) => { + const items = result.listenedItems || []; + items.push(item); + chrome.storage.sync.set({ listenedItems: items }); + }); +} + +function removeItem(index) { + chrome.storage.sync.get(['listenedItems'], (result) => { + const items = result.listenedItems || []; + items.splice(index, 1); + chrome.storage.sync.set({ listenedItems: items }); + }); +} + +function getListenedItems(callback) { + chrome.storage.sync.get(['listenedItems'], (result) => { + callback(result.listenedItems || []); + }); +} + +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.action === 'addItem') { + addItem(request.item); + } else if (request.action === 'removeItem') { + removeItem(request.index); + } else if (request.action === 'getListenedItems') { + getListenedItems(sendResponse); + return true; // Keep the message channel open for sendResponse + } +}); diff --git a/submissions/Listening to this/icons/icon128.png b/submissions/Listening to this/icons/icon128.png new file mode 100644 index 00000000..5b8f52e4 Binary files /dev/null and b/submissions/Listening to this/icons/icon128.png differ diff --git a/submissions/Listening to this/icons/icon16.png b/submissions/Listening to this/icons/icon16.png new file mode 100644 index 00000000..3d5803f5 Binary files /dev/null and b/submissions/Listening to this/icons/icon16.png differ diff --git a/submissions/Listening to this/icons/icon48.png b/submissions/Listening to this/icons/icon48.png new file mode 100644 index 00000000..199a3fd2 Binary files /dev/null and b/submissions/Listening to this/icons/icon48.png differ diff --git a/submissions/Listening to this/manifest.json b/submissions/Listening to this/manifest.json new file mode 100644 index 00000000..e814a312 --- /dev/null +++ b/submissions/Listening to this/manifest.json @@ -0,0 +1,23 @@ +{ + "manifest_version": 3, + "name": "Track Listened Items", + "version": "1.0", + "description": "Save URLs or titles of audio files, music, podcasts, or YouTube videos you've listened to.", + "permissions": ["storage", "tabs"], + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } + }, + "background": { + "service_worker": "background.js" + }, + "icons": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } +} diff --git a/submissions/Listening to this/popup.html b/submissions/Listening to this/popup.html new file mode 100644 index 00000000..c5196814 --- /dev/null +++ b/submissions/Listening to this/popup.html @@ -0,0 +1,24 @@ + + + + Track Listened Items + + + +
+

Track Listened Items

+
+ + + +
+ +
+ + + diff --git a/submissions/Listening to this/popup.js b/submissions/Listening to this/popup.js new file mode 100644 index 00000000..2e420704 --- /dev/null +++ b/submissions/Listening to this/popup.js @@ -0,0 +1,45 @@ +document.getElementById('mark-as-listened').addEventListener('click', () => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + const tab = tabs[0]; + const category = document.getElementById('category').value; + const item = { title: tab.title, url: tab.url, timestamp: Date.now(), category: category }; + chrome.runtime.sendMessage({ action: 'addItem', item }, () => { + renderList(); + }); + }); +}); + +document.getElementById('search').addEventListener('input', (event) => { + renderList(); +}); + +document.getElementById('category').addEventListener('change', (event) => { + renderList(); +}); + +function renderList() { + const query = document.getElementById('search').value.toLowerCase(); + const category = document.getElementById('category').value; + chrome.runtime.sendMessage({ action: 'getListenedItems' }, (items) => { + const listElement = document.getElementById('listened-items'); + listElement.innerHTML = ''; + items.filter(item => + (item.title.toLowerCase().includes(query) || item.url.toLowerCase().includes(query)) && + (category === '' || item.category === category) + ).forEach((item, index) => { + const listItem = document.createElement('li'); + listItem.textContent = `${item.title} - ${item.url} (${item.category})`; + const deleteButton = document.createElement('button'); + deleteButton.textContent = 'Delete'; + deleteButton.addEventListener('click', () => { + chrome.runtime.sendMessage({ action: 'removeItem', index }, () => { + renderList(); + }); + }); + listItem.appendChild(deleteButton); + listElement.appendChild(listItem); + }); + }); +} + +renderList(); diff --git a/submissions/Listening to this/styles.css b/submissions/Listening to this/styles.css new file mode 100644 index 00000000..bb8f21f3 --- /dev/null +++ b/submissions/Listening to this/styles.css @@ -0,0 +1,76 @@ +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + padding: 10px; + width: 400px; + background-color: #f5f5f5; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + border-radius: 8px; +} + +h1 { + text-align: center; + color: #333; +} + +.controls { + display: flex; + justify-content: space-between; + margin-bottom: 10px; +} + +#mark-as-listened { + padding: 10px 20px; + background-color: #4CAF50; + color: white; + border: none; + cursor: pointer; + border-radius: 5px; + transition: background-color 0.3s; +} + +#mark-as-listened:hover { + background-color: #45a049; +} + +#search { + padding: 10px; + border: 1px solid #ccc; + border-radius: 5px; + width: 45%; + transition: border-color 0.3s; +} + +#search:focus { + border-color: #4CAF50; + outline: none; +} + +ul { + list-style-type: none; + padding: 0; +} + +li { + background-color: #fff; + margin: 5px 0; + padding: 10px; + border-radius: 5px; + display: flex; + justify-content: space-between; + align-items: center; + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.1); +} + +button { + padding: 5px 10px; + background-color: #f44336; + color: white; + border: none; + cursor: pointer; + border-radius: 5px; + transition: background-color 0.3s; +} + +button:hover { + background-color: #d32f2f; +}