|
|
@@ -25,10 +25,12 @@ document.addEventListener("alpine:init", () => {
|
|
|
history: {},
|
|
|
sortedHistory: [],
|
|
|
openMenus: new Set(), // Track which menus are open
|
|
|
+ moveSubmenuOpenFor: null, // Track which video has the move-to submenu open (menuId or null)
|
|
|
currentView: "playlists", // Track current view: 'playlists', 'history', 'playlist', 'saveChannel', or 'wikiInsp'
|
|
|
currentPlaylistName: "", // Track which playlist is being viewed
|
|
|
playlistsForDisplay: [], // Computed array for display
|
|
|
currentPlaylistVideos: [], // Videos for current playlist view
|
|
|
+ otherPlaylists: [], // Playlist names (with display labels) other than currentPlaylistName
|
|
|
currentTab: null, // Current active tab info
|
|
|
isCurrentTabYoutube: false, // Whether current tab is YouTube
|
|
|
isCurrentTabChannelPage: false, // Whether current tab is YouTube videos page
|
|
|
@@ -146,6 +148,7 @@ document.addEventListener("alpine:init", () => {
|
|
|
!this.playlists[this.currentPlaylistName]
|
|
|
) {
|
|
|
this.currentPlaylistVideos = [];
|
|
|
+ this.otherPlaylists = [];
|
|
|
} else {
|
|
|
this.currentPlaylistVideos = this.playlists[
|
|
|
this.currentPlaylistName
|
|
|
@@ -158,6 +161,9 @@ document.addEventListener("alpine:init", () => {
|
|
|
index,
|
|
|
),
|
|
|
}));
|
|
|
+ this.otherPlaylists = Object.keys(this.playlists)
|
|
|
+ .filter((name) => name !== this.currentPlaylistName)
|
|
|
+ .map((name) => ({ name, display: this.formatPlaylistName(name) }));
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -657,6 +663,20 @@ document.addEventListener("alpine:init", () => {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ async moveVideoToPlaylist(fromPlaylistName, videoIndex, toPlaylistName) {
|
|
|
+ const playlists = JSON.parse(JSON.stringify(this.playlists));
|
|
|
+ const video = playlists[fromPlaylistName].splice(videoIndex, 1)[0];
|
|
|
+ playlists[toPlaylistName].push(video);
|
|
|
+ try {
|
|
|
+ await browser.storage.local.set({ playlists });
|
|
|
+ this.playlists = playlists;
|
|
|
+ this.updatePlaylistsForDisplay();
|
|
|
+ this.updateCurrentPlaylistVideos();
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Error moving video to playlist:", error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
findTopPosition(playlistName) {
|
|
|
const playlist = this.playlists[playlistName];
|
|
|
if (!playlist) return 0;
|
|
|
@@ -942,6 +962,33 @@ document.addEventListener("alpine:init", () => {
|
|
|
},
|
|
|
},
|
|
|
|
|
|
+ moveToSubmenuButton: {
|
|
|
+ ["@click.stop"]() {
|
|
|
+ const playlistName = this.$el.dataset.playlistName;
|
|
|
+ const index = parseInt(this.$el.dataset.playlistIndex);
|
|
|
+ const menuId = this.getMenuId(playlistName, index);
|
|
|
+ this.moveSubmenuOpenFor = this.moveSubmenuOpenFor === menuId ? null : menuId;
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ moveToSubmenu: {
|
|
|
+ ["x-show"]() {
|
|
|
+ const playlistName = this.$el.dataset.playlistName;
|
|
|
+ const index = parseInt(this.$el.dataset.playlistIndex);
|
|
|
+ return this.moveSubmenuOpenFor === this.getMenuId(playlistName, index);
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ moveToPlaylistButton: {
|
|
|
+ ["@click"]() {
|
|
|
+ const fromPlaylistName = this.$el.dataset.fromPlaylistName;
|
|
|
+ const videoIndex = parseInt(this.$el.dataset.playlistIndex);
|
|
|
+ const toPlaylistName = this.$el.dataset.toPlaylistName;
|
|
|
+ this.moveVideoToPlaylist(fromPlaylistName, videoIndex, toPlaylistName);
|
|
|
+ this.closeAllMenus();
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
exportButton: {
|
|
|
["@click"]() {
|
|
|
this.exportPlaylists();
|
|
|
@@ -1089,14 +1136,15 @@ document.addEventListener("alpine:init", () => {
|
|
|
if (this.openMenus.has(menuId)) {
|
|
|
this.openMenus.delete(menuId);
|
|
|
} else {
|
|
|
- // Close all other menus first
|
|
|
this.openMenus.clear();
|
|
|
this.openMenus.add(menuId);
|
|
|
}
|
|
|
+ this.moveSubmenuOpenFor = null;
|
|
|
},
|
|
|
|
|
|
closeAllMenus() {
|
|
|
this.openMenus.clear();
|
|
|
+ this.moveSubmenuOpenFor = null;
|
|
|
},
|
|
|
|
|
|
moreMenuButton: {
|