-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
vikash
committed
Dec 27, 2022
1 parent
089ebe7
commit 3a0da48
Showing
12 changed files
with
285 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
chrome.tabs.onUpdated.addListener((tabId, tab) => { | ||
if (tab.url && tab.url.includes("youtube.com/watch")) { | ||
const queryParameters = tab.url.split("?")[1]; | ||
const urlParameters = new URLSearchParams(queryParameters); | ||
|
||
chrome.tabs.sendMessage(tabId, { | ||
type: "NEW", | ||
videoId: urlParameters.get("v"), | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
(() => { | ||
let youtubeLeftControls, youtubePlayer; | ||
let currentVideo = ""; | ||
let currentVideoBookmarks = []; | ||
|
||
const fetchBookmarks = () => { | ||
return new Promise((resolve) => { | ||
chrome.storage.sync.get([currentVideo], (obj) => { | ||
resolve(obj[currentVideo] ? JSON.parse(obj[currentVideo]) : []); | ||
}); | ||
}); | ||
}; | ||
|
||
const addNewBookmarkEventHandler = async () => { | ||
const currentTime = youtubePlayer.currentTime; | ||
const newBookmark = { | ||
time: currentTime, | ||
desc: "Bookmark at " + getTime(currentTime), | ||
}; | ||
|
||
currentVideoBookmarks = await fetchBookmarks(); | ||
|
||
chrome.storage.sync.set({ | ||
[currentVideo]: JSON.stringify([...currentVideoBookmarks, newBookmark].sort((a, b) => a.time - b.time)) | ||
}); | ||
}; | ||
|
||
const newVideoLoaded = async () => { | ||
const bookmarkBtnExists = document.getElementsByClassName("bookmark-btn")[0]; | ||
|
||
currentVideoBookmarks = await fetchBookmarks(); | ||
|
||
if (!bookmarkBtnExists) { | ||
const bookmarkBtn = document.createElement("img"); | ||
|
||
bookmarkBtn.src = chrome.runtime.getURL("assets/bookmark.png"); | ||
bookmarkBtn.className = "ytp-button " + "bookmark-btn"; | ||
bookmarkBtn.title = "Click to bookmark current timestamp"; | ||
|
||
youtubeLeftControls = document.getElementsByClassName("ytp-left-controls")[0]; | ||
youtubePlayer = document.getElementsByClassName('video-stream')[0]; | ||
|
||
youtubeLeftControls.appendChild(bookmarkBtn); | ||
bookmarkBtn.addEventListener("click", addNewBookmarkEventHandler); | ||
} | ||
}; | ||
|
||
chrome.runtime.onMessage.addListener((obj, sender, response) => { | ||
const { type, value, videoId } = obj; | ||
|
||
if (type === "NEW") { | ||
currentVideo = videoId; | ||
newVideoLoaded(); | ||
} else if (type === "PLAY") { | ||
youtubePlayer.currentTime = value; | ||
} else if ( type === "DELETE") { | ||
currentVideoBookmarks = currentVideoBookmarks.filter((b) => b.time != value); | ||
chrome.storage.sync.set({ [currentVideo]: JSON.stringify(currentVideoBookmarks) }); | ||
|
||
response(currentVideoBookmarks); | ||
} | ||
}); | ||
|
||
newVideoLoaded(); | ||
})(); | ||
|
||
const getTime = t => { | ||
var date = new Date(0); | ||
date.setSeconds(t); | ||
|
||
return date.toISOString().substr(11, 8); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "youtube Bookmarks", | ||
"version": "1.0.0", | ||
"description": "Saving timestamps in YouTube videos", | ||
"permissions": ["storage", "tabs"], | ||
"host_permissions": ["https://*.youtube.com/*"], | ||
"background": { | ||
"service_worker": "background.js" | ||
}, | ||
"content_scripts": [ | ||
{ | ||
"matches": ["https://*.youtube.com/*"], | ||
"js": ["contentScript.js"] | ||
} | ||
], | ||
"web_accessible_resources": [ | ||
{ | ||
"resources": [ | ||
"assets/bookmark.png", | ||
"assets/play.png", | ||
"assets/delete.png", | ||
"assets/save.png" | ||
], | ||
"matches": ["https://*.youtube.com/*"] | ||
} | ||
], | ||
"action": { | ||
"default_icon": { | ||
"16": "assets/ext-icon.png", | ||
"24": "assets/ext-icon.png", | ||
"32": "assets/ext-icon.png" | ||
}, | ||
"default_title": "My YT Bookmarks", | ||
"default_popup": "popup.html" | ||
}, | ||
"manifest_version": 3 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
.container { | ||
width: 280px; | ||
color: #314d3e; | ||
} | ||
|
||
.title { | ||
font-size: 14px; | ||
font-weight: bold; | ||
padding: 8px; | ||
} | ||
|
||
.textbox { | ||
width: 100%; | ||
font-size: 12px; | ||
margin: 0; | ||
padding: 0px 2px; | ||
} | ||
|
||
.textbox:focus { | ||
outline: 0; | ||
border-color: #66afe9; | ||
} | ||
|
||
.bookmarks { | ||
margin: 5px 5px; | ||
padding: 3px; | ||
} | ||
|
||
.bookmark { | ||
display: flex; | ||
border-bottom-color: #00254d; | ||
border-bottom-width: 1px; | ||
border-bottom-style: solid; | ||
border-radius: 0.8rem; | ||
padding: 3px; | ||
padding-bottom: 7px; | ||
margin-bottom: 7px; | ||
} | ||
|
||
.bookmark-title { | ||
padding-left: 2px; | ||
} | ||
|
||
.bookmark-controls img { | ||
margin: 0 4px; | ||
width: 18px; | ||
height: 18px; | ||
cursor: pointer; | ||
} | ||
.bookmark-controls { | ||
flex: auto; | ||
text-align: right; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<link href="popup.css" rel="stylesheet" type="text/css" /> | ||
<script type="module" src="popup.js"></script> | ||
|
||
<div class="container"> | ||
<div> | ||
<div class="title">Your bookmarks for this video</div> | ||
|
||
<div class="bookmarks" id="bookmarks"></div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { getActiveTabURL } from "./utils.js"; | ||
|
||
const addNewBookmark = (bookmarks, bookmark) => { | ||
const bookmarkTitleElement = document.createElement("div"); | ||
const controlsElement = document.createElement("div"); | ||
const newBookmarkElement = document.createElement("div"); | ||
|
||
bookmarkTitleElement.textContent = bookmark.desc; | ||
bookmarkTitleElement.className = "bookmark-title"; | ||
controlsElement.className = "bookmark-controls"; | ||
|
||
setBookmarkAttributes("play", onPlay, controlsElement); | ||
setBookmarkAttributes("delete", onDelete, controlsElement); | ||
|
||
newBookmarkElement.id = "bookmark-" + bookmark.time; | ||
newBookmarkElement.className = "bookmark"; | ||
newBookmarkElement.setAttribute("timestamp", bookmark.time); | ||
|
||
newBookmarkElement.appendChild(bookmarkTitleElement); | ||
newBookmarkElement.appendChild(controlsElement); | ||
bookmarks.appendChild(newBookmarkElement); | ||
}; | ||
|
||
const viewBookmarks = (currentBookmarks=[]) => { | ||
const bookmarksElement = document.getElementById("bookmarks"); | ||
bookmarksElement.innerHTML = ""; | ||
|
||
if (currentBookmarks.length > 0) { | ||
for (let i = 0; i < currentBookmarks.length; i++) { | ||
const bookmark = currentBookmarks[i]; | ||
addNewBookmark(bookmarksElement, bookmark); | ||
} | ||
} else { | ||
bookmarksElement.innerHTML = '<i class="row">No bookmarks to show</i>'; | ||
} | ||
|
||
return; | ||
}; | ||
|
||
const onPlay = async e => { | ||
const bookmarkTime = e.target.parentNode.parentNode.getAttribute("timestamp"); | ||
const activeTab = await getActiveTabURL(); | ||
|
||
chrome.tabs.sendMessage(activeTab.id, { | ||
type: "PLAY", | ||
value: bookmarkTime, | ||
}); | ||
}; | ||
|
||
const onDelete = async e => { | ||
const activeTab = await getActiveTabURL(); | ||
const bookmarkTime = e.target.parentNode.parentNode.getAttribute("timestamp"); | ||
const bookmarkElementToDelete = document.getElementById( | ||
"bookmark-" + bookmarkTime | ||
); | ||
|
||
bookmarkElementToDelete.parentNode.removeChild(bookmarkElementToDelete); | ||
|
||
chrome.tabs.sendMessage(activeTab.id, { | ||
type: "DELETE", | ||
value: bookmarkTime, | ||
}, viewBookmarks); | ||
}; | ||
|
||
const setBookmarkAttributes = (src, eventListener, controlParentElement) => { | ||
const controlElement = document.createElement("img"); | ||
|
||
controlElement.src = "assets/" + src + ".png"; | ||
controlElement.title = src; | ||
controlElement.addEventListener("click", eventListener); | ||
controlParentElement.appendChild(controlElement); | ||
}; | ||
|
||
document.addEventListener("DOMContentLoaded", async () => { | ||
const activeTab = await getActiveTabURL(); | ||
const queryParameters = activeTab.url.split("?")[1]; | ||
const urlParameters = new URLSearchParams(queryParameters); | ||
|
||
const currentVideo = urlParameters.get("v"); | ||
|
||
if (activeTab.url.includes("youtube.com/watch") && currentVideo) { | ||
chrome.storage.sync.get([currentVideo], (data) => { | ||
const currentVideoBookmarks = data[currentVideo] ? JSON.parse(data[currentVideo]) : []; | ||
|
||
viewBookmarks(currentVideoBookmarks); | ||
}); | ||
} else { | ||
const container = document.getElementsByClassName("container")[0]; | ||
|
||
container.innerHTML = '<div class="title">This is not a youtube video page.</div>'; | ||
} | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export async function getActiveTabURL() { | ||
const tabs = await chrome.tabs.query({ | ||
currentWindow: true, | ||
active: true | ||
}); | ||
|
||
return tabs[0]; | ||
} | ||
|