|
@@ -10,10 +10,11 @@ document.addEventListener("alpine:init", () => {
|
|
|
// - include currently open tabs in export
|
|
// - include currently open tabs in export
|
|
|
// - support playlist management (add, remove, rename playlists)
|
|
// - support playlist management (add, remove, rename playlists)
|
|
|
// - support input text box for adding to playlist (how to handle title?)
|
|
// - support input text box for adding to playlist (how to handle title?)
|
|
|
- // - option (probably a button) to add current page (url, title) to playlist
|
|
|
|
|
|
|
+ // X option (probably a button) to add current page (url, title) to playlist
|
|
|
|
|
+ // X align with addLinkToPlaylist in background.js (no repeated videos)
|
|
|
// - button to add channel to youtube page (copy gql mutation to clipboard) (like the automa version)
|
|
// - button to add channel to youtube page (copy gql mutation to clipboard) (like the automa version)
|
|
|
// - long-term: replace youtube page? rss feeds? need server?
|
|
// - long-term: replace youtube page? rss feeds? need server?
|
|
|
- // - add personal rating feature ("enjoyed", "this was important", etc)
|
|
|
|
|
|
|
+ // X add personal rating feature ("enjoyed", "this was important", etc)
|
|
|
Alpine.data("playlistManager", () => ({
|
|
Alpine.data("playlistManager", () => ({
|
|
|
playlists: {},
|
|
playlists: {},
|
|
|
currentIndices: {},
|
|
currentIndices: {},
|
|
@@ -24,10 +25,14 @@ document.addEventListener("alpine:init", () => {
|
|
|
currentPlaylistName: '', // Track which playlist is being viewed
|
|
currentPlaylistName: '', // Track which playlist is being viewed
|
|
|
playlistsForDisplay: [], // Computed array for display
|
|
playlistsForDisplay: [], // Computed array for display
|
|
|
currentPlaylistVideos: [], // Videos for current playlist view
|
|
currentPlaylistVideos: [], // Videos for current playlist view
|
|
|
|
|
+ currentTab: null, // Current active tab info
|
|
|
|
|
+ isCurrentTabYoutube: false, // Whether current tab is YouTube
|
|
|
|
|
+ addCurrentPageButtonText: 'Add Current Page', // Button text
|
|
|
|
|
|
|
|
init() {
|
|
init() {
|
|
|
this.loadPlaylists();
|
|
this.loadPlaylists();
|
|
|
this.loadHistory();
|
|
this.loadHistory();
|
|
|
|
|
+ this.getCurrentTab();
|
|
|
// Add document click handler to close menus
|
|
// Add document click handler to close menus
|
|
|
document.addEventListener('click', (e) => {
|
|
document.addEventListener('click', (e) => {
|
|
|
// If click is not on a more button or menu, close all menus
|
|
// If click is not on a more button or menu, close all menus
|
|
@@ -109,6 +114,33 @@ document.addEventListener("alpine:init", () => {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
+ async getCurrentTab() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
|
|
|
|
+ if (tabs.length > 0) {
|
|
|
|
|
+ this.currentTab = tabs[0];
|
|
|
|
|
+ const url = new URL(this.currentTab.url);
|
|
|
|
|
+ this.isCurrentTabYoutube = url.hostname === 'www.youtube.com';
|
|
|
|
|
+ this.updateAddCurrentPageButtonText();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("Error getting current tab:", error);
|
|
|
|
|
+ this.currentTab = null;
|
|
|
|
|
+ this.isCurrentTabYoutube = false;
|
|
|
|
|
+ this.updateAddCurrentPageButtonText();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ updateAddCurrentPageButtonText() {
|
|
|
|
|
+ if (!this.currentTab) {
|
|
|
|
|
+ this.addCurrentPageButtonText = 'Unable to get current page';
|
|
|
|
|
+ } else if (!this.isCurrentTabYoutube) {
|
|
|
|
|
+ this.addCurrentPageButtonText = 'Add Current Page (YouTube only)';
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.addCurrentPageButtonText = 'Add Current Page to Playlist';
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
sortHistoryByRecentInteraction() {
|
|
sortHistoryByRecentInteraction() {
|
|
|
// Convert history object to array with video ID and sort by most recent interaction
|
|
// Convert history object to array with video ID and sort by most recent interaction
|
|
|
this.sortedHistory = Object.entries(this.history)
|
|
this.sortedHistory = Object.entries(this.history)
|
|
@@ -311,6 +343,30 @@ document.addEventListener("alpine:init", () => {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
+ async addCurrentPageToPlaylist() {
|
|
|
|
|
+ if (!this.currentTab || !this.isCurrentTabYoutube || !this.currentPlaylistName) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Create video object using current tab info
|
|
|
|
|
+ const video = {
|
|
|
|
|
+ url: this.currentTab.url,
|
|
|
|
|
+ title: this.currentTab.title,
|
|
|
|
|
+ status: "new"
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // Use shared utility function to add video (handles duplicate checking)
|
|
|
|
|
+ const wasAdded = await PlaylistUtils.addVideoToPlaylist(this.currentPlaylistName, video);
|
|
|
|
|
+
|
|
|
|
|
+ if (wasAdded) {
|
|
|
|
|
+ // Refresh displays only if video was actually added
|
|
|
|
|
+ this.loadPlaylists(); // This will update both display arrays
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Could show user feedback that video already exists
|
|
|
|
|
+ console.log("Video already exists in a playlist");
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
async exportPlaylists() {
|
|
async exportPlaylists() {
|
|
|
try {
|
|
try {
|
|
|
// Get current playlists
|
|
// Get current playlists
|
|
@@ -748,5 +804,20 @@ document.addEventListener("alpine:init", () => {
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
|
|
+ // Add current page button binding
|
|
|
|
|
+ addCurrentPageButton: {
|
|
|
|
|
+ ["@click"]() {
|
|
|
|
|
+ this.addCurrentPageToPlaylist();
|
|
|
|
|
+ },
|
|
|
|
|
+ [":disabled"]() {
|
|
|
|
|
+ return !this.currentTab || !this.isCurrentTabYoutube || !this.currentPlaylistName;
|
|
|
|
|
+ },
|
|
|
|
|
+ [":class"]() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ 'disabled': !this.currentTab || !this.isCurrentTabYoutube || !this.currentPlaylistName
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
}));
|
|
}));
|
|
|
});
|
|
});
|