12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049 |
- let songIndex = 0;
- let songsToDelete = [];
- let playlistToRemove = "";
- let deleteAll = false;
- let db;
- // Cached DOM elements
- const returnToMainFrameButton = document.getElementById('return-to-main-frame');
- const addPlaylistButton = document.getElementById('add-new-playlist-button');
- const deleteAllButton = document.getElementById('delete-all-button');
- const saveButton = document.getElementById('save-button');
- const exportButton = document.getElementById('export-button');
- const openImportMenuButton = document.getElementById('open-import-menu-button');
- const inputPlaylistName = document.getElementById('input-playlist-name');
- const playlistsContainer = document.getElementById('playlists');
- const songContainer = document.getElementById('songs');
- const optionsButton = document.getElementById("options-button");
- const playerSelect = document.getElementById("player-select");
- const themeSelect = document.getElementById("theme-select");
- const fontSelect = document.getElementById("font-select");
- const styleSelect = document.getElementById("style-select");
- const saveOptionsButton = document.getElementById('save-button-options-panel');
- const closeOptionsButton = document.getElementById('close-button-options-panel');
- const importButton = document.getElementById("import-button");
- const closeImportButton = document.getElementById("close-import-menu");
- // Add event listeners
- returnToMainFrameButton.addEventListener('click', ReturnToMainFrame);
- addPlaylistButton.addEventListener('click', CreateNewPlaylist);
- deleteAllButton.addEventListener('click', MarkTotalDeletion);
- saveButton.addEventListener('click', SaveChangesToPlaylist);
- exportButton.addEventListener('click', ExportDatabaseToFile);
- openImportMenuButton.addEventListener('click', OpenImportMenu);
- optionsButton.addEventListener('click', OpenOptionMenu);
- playerSelect.addEventListener('change', ChangePlayer);
- themeSelect.addEventListener('change', ChangeTheme);
- fontSelect.addEventListener('change', ChangeFont);
- styleSelect.addEventListener('change', ChangeStyle);
- saveOptionsButton.addEventListener('click', SaveOptionsPanel);
- closeOptionsButton.addEventListener('click', CloseOptionsPanel);
- importButton.addEventListener('click', ImportData);
- closeImportButton.addEventListener('click', CloseImportPanel);
- Initialize();
- // Load user preferences
- function Initialize() {
- ConnectDatabase().then((db) => {
- songsToDelete = [];
- playlistToRemove = "";
- deleteAll = false;
- // Load preferred player
- RetrieveDataFromDatabase('preferredPlayer').then((preferredPlayer) => {
- if (preferredPlayer !== null && preferredPlayer !== undefined) {
- // Set player
- playerSelect.value = preferredPlayer;
- } else {
- // Set default player
- playerSelect.value = "youtube-player";
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- // Load preferred theme
- RetrieveDataFromDatabase('preferredTheme').then((preferredTheme) => {
- if (preferredTheme !== null && preferredTheme !== undefined) {
- // Set theme
- themeSelect.value = preferredTheme;
- ChangeTheme();
- } else {
- // Set default theme
- themeSelect.value = "white-theme";
- ChangeTheme();
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- // Load preferred font
- RetrieveDataFromDatabase('preferredFont').then((preferredFont) => {
- if (preferredFont !== null && preferredFont !== undefined) {
- // Set font
- fontSelect.value = preferredFont;
- ChangeFont();
- } else {
- // Set default font
- fontSelect.value = "barlow-font";
- ChangeFont();
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- // Load preferred style
- RetrieveDataFromDatabase('preferredStyle').then((preferredStyle) => {
- if (preferredStyle !== null && preferredStyle !== undefined) {
- // Set style
- styleSelect.value = preferredStyle;
- ChangeStyle();
- } else {
- // Set default style
- styleSelect.value = "sharp-style";
- ChangeStyle();
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- LoadPlaylists();
- // Remove text from input field
- const inputInsertBackup = document.getElementById('input-insert-backup');
- inputInsertBackup.value = '';
- })
- .catch((error) => {
- // Connection error
- });
- }
- // Function to load playlists from localStorage
- function LoadPlaylists() {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- savedPlaylists.playlists.forEach(function (playlist) {
- AddPlaylist(playlist.playlistId, playlist.name);
- });
- localStorage.setItem("savedPlaylists", JSON.stringify(savedPlaylists));
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to create a new playlist
- function CreateNewPlaylist() {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- const newRandomId = GenerateRandomId();
- const newPlaylist = {
- "playlistId": newRandomId,
- "name": "New Playlist",
- "songs": []
- };
- savedPlaylists.playlists.push(newPlaylist);
- savedPlaylistsString = JSON.stringify(savedPlaylists);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", savedPlaylistsString);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
- AddPlaylist(newRandomId, "New Playlist");
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to add a playlist to the UI
- function AddPlaylist(id, name) {
- const playlistContainer = document.createElement('div');
- playlistContainer.className = 'playlist';
- playlistContainer.classList.add('playlist', 'list-objects-theme', 'borders-theme');
- const playlistName = document.createElement('div');
- playlistName.classList.add('playlist-name', 'text-theme', 'font-type');
- playlistName.textContent = name || 'New Playlist';
- const playButton = document.createElement('button');
- playButton.classList.add('playlist-play-button', 'borders-theme');
- playButton.addEventListener('click', () => {PlaySongs(id);});
- const editButton = document.createElement('button');
- editButton.classList.add('playlist-edit-button', 'borders-theme');
- editButton.addEventListener('click', () => {ToggleEditPlaylist(id);});
- playlistContainer.appendChild(playlistName);
- playlistContainer.appendChild(playButton);
- playlistContainer.appendChild(editButton);
- playlistsContainer.appendChild(playlistContainer);
- }
- // Function to toggle between edit and main frames
- function ToggleEditPlaylist(playlistId) {
- const playlistMainFrame = document.getElementById('playlist-main-window');
- const editMainFrame = document.getElementById('edit-playlist-main-window');
- editMainFrame.style.display = 'flex';
- playlistMainFrame.style.display = 'none';
- LoadSongs(playlistId);
- ModifyAddSongButton(playlistId);
- ModifyEditPlaylistName(playlistId);
- ModifyInputPlaylistName(playlistId);
- ModifyDeletePlaylistButton(playlistId);
- const inputInsertURL = document.getElementById("input-insert-url");
- inputInsertURL.value = "";
- inputInsertURL.addEventListener("keyup", function(event) {
- if (event.key === "Enter") {
- AddSong(playlistId);
- inputInsertURL.value = "";
- }
- });
- const inputPlaylistName = document.getElementById('input-playlist-name');
- // Load the name of a playlist
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
- inputPlaylistName.value = playlist ? playlist.name : "";
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- function GetPlaylistsFromDatabase() {
- return new Promise((resolve, reject) => {
- RetrieveDataFromDatabase('savedPlaylists')
- .then((value) => {
- if (value === null || value === undefined) {
- CreateNewLocalStorageStructure();
- const newStructure = {"playlists": []};
- return newStructure;
- } else {
- resolve(JSON.parse(value));
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- reject(error);
- });
- });
- }
- // Function to remove all playlists from the UI
- function DestroyPlaylists() {
- const playlistElements = document.querySelectorAll(".playlist");
- playlistElements.forEach(playlist => {
- playlist.remove();
- });
- }
- // Function to create a new localStorage structure
- function CreateNewLocalStorageStructure() {
- const newStructure = {
- "playlists": []
- };
- AddOrUpdateDataInDatabase('savedPlaylists', JSON.stringify(newStructure)).then(() => {
- return;
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to load songs for a playlist
- function LoadSongs(playlistId) {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
- if (playlist) {
- songIndex = 0;
- playlist.songs.forEach(function (song) {
- songIndex += 1;
- AddSongElement(song.songId, song.name, playlistId);
- });
- }
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to add a song element to the UI
- function AddSongElement(songId, name, playlistId) {
- const songContainer = document.createElement('div');
- songContainer.classList.add('song', 'list-objects-theme', 'borders-theme');
- const songNumber = document.createElement('div');
- songNumber.classList.add('song-number', 'text-theme', 'borders-theme', 'font-type');
- songNumber.textContent = songIndex;
- const inputSongName = document.createElement("input");
- inputSongName.classList.add('input-song-name', 'text-theme', 'font-type');
- inputSongName.setAttribute("type", "text");
- inputSongName.setAttribute("value", name);
- inputSongName.setAttribute("disabled", "true");
- inputSongName.addEventListener("keydown", (event) => {
- if (event.key === "Enter") {
- event.preventDefault();
- inputSongName.setAttribute("disabled", "true");
- inputSongName.setSelectionRange(0, 0);
- inputSongName.focus();
- ChangeSongName(playlistId, songId, inputSongName.value);
- }
- });
- const editSongNameButton = document.createElement('button');
- editSongNameButton.classList.add('edit-song-name-button', 'borders-theme');
- editSongNameButton.addEventListener('click', function () {
- ToggleEditSongName(playlistId, songId, inputSongName);
- });
- const removeSongButton = document.createElement('button');
- removeSongButton.classList.add('remove-song-button', 'borders-theme');
- removeSongButton.addEventListener('click', function () {
- ToggleSongDeletion(songContainer, playlistId, songId);
- });
- songContainer.appendChild(songNumber);
- songContainer.appendChild(inputSongName);
- songContainer.appendChild(editSongNameButton);
- songContainer.appendChild(removeSongButton);
- const songParent = document.getElementById('songs');
- songParent.appendChild(songContainer);
- }
- // Function to toggle editing of song name
- function ToggleEditSongName(playlistId, songId, inputSongName) {
- if (inputSongName.disabled) {
- inputSongName.removeAttribute("disabled");
- } else {
- inputSongName.setAttribute("disabled", "true");
- inputSongName.setSelectionRange(0, 0);
- inputSongName.focus();
- ChangeSongName(playlistId, songId, inputSongName.value);
- }
- }
- // Function to toggle song deletion
- function ToggleSongDeletion(songContainer, playlistId, songId) {
- const updatedArray = songsToDelete.filter(innerArray => !innerArray.includes(songId));
- if (updatedArray.length === songsToDelete.length) {
- const songToRemove = [playlistId, songId];
- songsToDelete.push(songToRemove);
- songContainer.classList.add('marked-for-deletion');
- } else {
- songsToDelete = updatedArray;
- songContainer.classList.remove('marked-for-deletion');
- }
- }
- // Function to modify the "add-song-button" button
- function ModifyAddSongButton(playlistId) {
- const addSongButton = document.getElementById('add-song-button');
- addSongButton.addEventListener('click', function () {
- AddSong(playlistId);
- const inputField = document.getElementById("input-insert-url");
- inputField.value = "";
- });
- }
- // Function to modify the "playlist-change-name-button" button
- function ModifyEditPlaylistName(playlistId) {
- const editPlaylistNameButton = document.getElementById('playlist-change-name-button');
- const inputPlaylistName = document.getElementById('input-playlist-name');
- editPlaylistNameButton.addEventListener('click', function () {
- ToggleEditPlaylistName(playlistId, inputPlaylistName);
- });
- }
- // Function to toggle editing of playlist name
- function ToggleEditPlaylistName(playlistId, inputPlaylistName) {
- if (inputPlaylistName.disabled) {
- inputPlaylistName.removeAttribute("disabled");
- } else {
- inputPlaylistName.setAttribute("disabled", "true");
- inputPlaylistName.setSelectionRange(0, 0);
- inputPlaylistName.focus();
- RenamePlaylist(playlistId, inputPlaylistName.value);
- }
- }
- // Function to remove all events from the "playlist-change-name-button" button
- function RemoveAllEventsFromEditPlaylistNameButton() {
- const renamePlaylistButton = document.getElementById("playlist-change-name-button");
- const newButton = renamePlaylistButton.cloneNode(true);
- renamePlaylistButton.parentNode.replaceChild(newButton, renamePlaylistButton);
- }
- // Function to remove all events from the input playlist name field
- function RemoveAllEventsFromInputPlaylistName() {
- const inputPlaylistName = document.getElementById("input-playlist-name");
- const newInput = inputPlaylistName.cloneNode(true);
- inputPlaylistName.parentNode.replaceChild(newInput, inputPlaylistName);
- }
- // Function to rename a playlist
- function RenamePlaylist(playlistId, newName) {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
- if (playlist) {
- playlist.name = newName;
- }
- savedPlaylistsString = JSON.stringify(savedPlaylists);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", savedPlaylistsString);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
- return;
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to remove all events from the "add-song-button" button
- function RemoveAllEventsFromAddSongButton() {
- const addSongButton = document.getElementById("add-song-button");
- const newButton = addSongButton.cloneNode(true);
- addSongButton.parentNode.replaceChild(newButton, addSongButton);
- }
- // Function to remove all events from the "playlist-delete-button" button
- function RemoveAllEventsFromPlaylistDeleteButton() {
- const deletePlaylistButton = document.getElementById("playlist-delete-button");
- const newButton = deletePlaylistButton.cloneNode(true);
- deletePlaylistButton.parentNode.replaceChild(newButton, deletePlaylistButton);
- // Remove playlist to be deleted in case there is one and change the field color
- playlistToRemove = "";
- const parent = document.getElementById('playlist-name-parent');
- parent.classList.remove('marked-for-deletion');
- }
- // Mark all playlists for deletion
- function MarkTotalDeletion() {
- if(deleteAll) {
- deleteAll = false;
- // Change button color
- deleteAllButton.classList.remove('total-delete');
- } else {
- deleteAll = true;
- // Change button color
- deleteAllButton.classList.add('total-delete');
- }
- }
- // Function to add a song to a playlist
- function AddSong(playlistId) {
- const inputURL = ExtractVideoId(document.getElementById("input-insert-url").value);
- if (inputURL) {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- const newRandomId = GenerateRandomId();
- const newSong = {
- "songId": newRandomId,
- "name": "New Song",
- "url": inputURL
- };
- const playlistToUpdate = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
- playlistToUpdate.songs.push(newSong);
- savedPlaylistsString = JSON.stringify(savedPlaylists);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", savedPlaylistsString);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
- songIndex += 1;
- AddSongElement(newRandomId, "New Song", playlistId);
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- }
- // Function to remove all song elements from the UI
- function DestroyAllSongs() {
- const songElements = document.querySelectorAll(".song");
- songElements.forEach(song => {
- song.remove();
- });
- }
- // Function to generate a random ID
- function GenerateRandomId() {
- const timestamp = new Date().getTime();
- const random = Math.random().toString(36).substring(2, 10);
- return `${timestamp}_${random}`;
- }
- // Function to save changes to playlists
- function SaveChangesToPlaylist() {
- if (playlistToRemove !== "") {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- // Filter out the playlist with the specified ID
- const updatedPlaylists = savedPlaylists.playlists.filter(playlist => playlist.playlistId !== playlistToRemove);
- // Update the JSON data with the filtered playlists
- savedPlaylists.playlists = updatedPlaylists;
- playlistToRemove = "";
- savedPlaylistsString = JSON.stringify(savedPlaylists);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", savedPlaylistsString);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
- ReturnToMainFrame();
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- if (songsToDelete.length > 0) {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- let playlistIdToFind = "";
- for (const item of songsToDelete) {
- playlistIdToFind = item[0];
- const songIdToRemove = item[1];
- const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistIdToFind);
- if (playlist) {
- playlist.songs = playlist.songs.filter(song => song.songId !== songIdToRemove);
- const index = savedPlaylists.playlists.findIndex(p => p.playlistId === playlistIdToFind);
- if (index !== -1) {
- savedPlaylists.playlists[index] = playlist;
- }
- }
- }
- songsToDelete = [];
- savedPlaylistsString = JSON.stringify(savedPlaylists);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", savedPlaylistsString);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
- DestroyAllSongs();
- LoadSongs(playlistIdToFind);
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- }
- // Function to change the name of a song
- function ChangeSongName(playlistId, songId, newName) {
- GetPlaylistsFromDatabase().then((savedPlaylists) => {
- if (savedPlaylists !== null && savedPlaylists !== undefined) {
- const playlist = savedPlaylists.playlists.find(playlist => playlist.playlistId === playlistId);
- if (playlist) {
- const song = playlist.songs.find(song => song.songId === songId);
- if (song) {
- song.name = newName;
- }
- }
- savedPlaylistsString = JSON.stringify(savedPlaylists);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", savedPlaylistsString);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', savedPlaylistsString).then(() => {
- return;
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to play songs in a playlist
- function PlaySongs(playlistId) {
- let savedPlaylists = JSON.parse(localStorage.getItem('savedPlaylists'));
- let songUrls = "";
- for (const playlist of savedPlaylists.playlists) {
- if (playlist.playlistId === playlistId) {
- for (const song of playlist.songs) {
- songUrls += song.url + ",";
- }
- break;
- }
- }
- if (songUrls) {
- if(playerSelect.value === 'youtube-player')
- {
- window.open("http://www.youtube.com/watch_videos?video_ids=" + songUrls);
- }
- else
- {
- window.open("http://yewtu.be/watch_videos?video_ids=" + songUrls);
- }
- }
- }
- // Function to clean up and return to main menu
- function ReturnToMainFrame() {
- // Get DOM elements
- const playlistMainFrame = document.getElementById('playlist-main-window');
- const editMainFrame = document.getElementById('edit-playlist-main-window');
- const inputPlaylistName = document.getElementById("input-playlist-name");
- // Disable input playlist name
- inputPlaylistName.setAttribute("disabled", "true");
- // Show the main frame and hide the edit frame
- playlistMainFrame.style.display = 'grid';
- editMainFrame.style.display = 'none';
- // Reset and clean up
- DestroyAllSongs();
- RemoveAllEventsFromAddSongButton();
- RemoveAllEventsFromEditPlaylistNameButton();
- RemoveAllEventsFromInputPlaylistName();
- RemoveAllEventsFromPlaylistDeleteButton();
- songsToDelete = [];
- DestroyPlaylists();
- LoadPlaylists();
- }
- // Function to close options panel
- function CloseOptionsPanel() {
- // Unmark delition
- deleteAll = false;
- // Change button color
- deleteAllButton.classList.remove('total-delete');
- // Reload playlists
- DestroyPlaylists();
- LoadPlaylists();
- // Show main menu
- const playlistMainFrame = document.getElementById('playlist-main-window');
- const optionsMenu = document.getElementById("options-main-window");
- optionsMenu.style.display = 'none';
- playlistMainFrame.style.display = 'grid';
- }
- // Function to modify input field for playlist name
- function ModifyInputPlaylistName(playlistId) {
- const inputPlaylistName = document.getElementById('input-playlist-name');
- inputPlaylistName.addEventListener("keydown", (event) => {
- if (event.key === "Enter") {
- event.preventDefault();
- ToggleEditPlaylistName(playlistId, inputPlaylistName);
- }
- });
- }
- // Function to modify playlist-delete-button
- function ModifyDeletePlaylistButton(playlistId) {
- // Add listener to delete playlist button
- const deletePlaylistButton = document.getElementById('playlist-delete-button');
- deletePlaylistButton.addEventListener('click', function () {
- const parent = document.getElementById('playlist-name-parent');
- if (playlistToRemove !== "") { // There alrady is a playlsit marked for deletion, unmart it
- playlistToRemove = "";
- parent.classList.remove('marked-for-deletion');
- } else { // Mark playlist for deletion
- playlistToRemove = playlistId;
- parent.classList.add('marked-for-deletion');
- }
- });
- }
- // Export the saved playlists to a json file
- function ExportDatabaseToFile() {
- GetPlaylistsFromDatabase().then((jsonData) => {
- if (jsonData !== null && jsonData !== undefined) {
- let data = "";
- jsonData.playlists.forEach((playlist, index) => {
- // Convert the playlistData to a JSON string
- data += JSON.stringify(playlist) + ",";
- });
- data = data.substring(0, data.length -1); // Removes the last extra comma
- data = "[" + data + "]"; // Add [] brackets so it can be parsed back into JSON
- const blob = new Blob([data], { type: 'text/plain' });
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.style.display = 'none';
- a.href = url;
- a.setAttribute('download', "Playlist");
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to assign new playlistId values
- function AssignNewPlaylistIds(data) {
- data.playlists.forEach((playlist) => {
- playlist.playlistId = GenerateRandomId();
- });
- }
- // Change the player
- function ChangePlayer() {
- playerName = playerSelect.value;
- // Update database with preferred player
- AddOrUpdateDataInDatabase('preferredPlayer', playerName)
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Change the visual themes
- function ChangeTheme() {
- themeName = themeSelect.value;
- // Remove existing theme classes
- const themes = ['white-theme', 'black-theme', 'neon-pink-theme', 'matrix-theme', 'huwhite-theme', 'blue-theme', 'coffee-theme', 'night-theme', 'forest-theme'];
- const body = document.body;
- body.classList.remove(...themes);
- // Add the selected theme class
- body.classList.add(themeName);
- // Update database with preferred theme
- AddOrUpdateDataInDatabase('preferredTheme', themeName)
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Change font
- function ChangeFont() {
- fontName = fontSelect.value;
- // Remove existing font classes
- const fonts = ['barlow-font', 'cormorant-unicase-font', 'exo2-font', 'gemunu-libre-font', 'josefin-sans-font', 'oswald-font', 'roboto-condensed-font', 'roboto-font', 'roboto-slab-font', 'space-grotesk-font', 'zilla-slab-font'];
- const body = document.body;
- body.classList.remove(...fonts);
- // Add the selected font class
- body.classList.add(fontName);
- // Update database with preferred font
- AddOrUpdateDataInDatabase('preferredFont', fontName)
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Change style
- function ChangeStyle() {
- styleName = styleSelect.value;
- // Remove existing style classes
- const styles = ['sharp-style', 'round-style', 'leviosa-style'];
- const body = document.body;
- body.classList.remove(...styles);
- // Add the selected font class
- body.classList.add(styleName);
- // Update database with preferred style
- AddOrUpdateDataInDatabase('preferredStyle', styleName)
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to call the options menu and hide the main frame
- function OpenOptionMenu() {
- const playlistMainFrame = document.getElementById('playlist-main-window');
- const optionsMenu = document.getElementById("options-main-window");
- optionsMenu.style.display = 'flex';
- playlistMainFrame.style.display = 'none';
- }
- // Function to destroy all playlists and return to main manu
- function SaveOptionsPanel() {
- if (deleteAll) {
- // Destroy all playlists
- CreateNewLocalStorageStructure();
- // Unmark delition
- deleteAll = false;
- // Change button color
- deleteAllButton.classList.remove('total-delete');
- }
- }
- // Function that opens a specific menu dedicated to importing new data
- function OpenImportMenu() {
- const optionsMenu = document.getElementById('options-main-window');
- const importMenu = document.getElementById("import-main-window");
- importMenu.style.display = 'flex';
- optionsMenu.style.display = 'none';
- }
- // Function to close import panel
- function CloseImportPanel() {
- // Unmark delition
- deleteAll = false;
- // Change button color
- deleteAllButton.classList.remove('total-delete');
- // Remove text from input field
- const inputInsertBackup = document.getElementById('input-insert-backup');
- inputInsertBackup.value = '';
- // Reset status
- const statusText = document.getElementById('status-message');
- statusText.textContent = 'Status: no data.';
- // Reload playlists
- DestroyPlaylists();
- LoadPlaylists();
- // Show main menu
- const playlistMainFrame = document.getElementById('playlist-main-window');
- const importMenu = document.getElementById("import-main-window");
- importMenu.style.display = 'none';
- playlistMainFrame.style.display = 'grid';
- }
- // Function to merge data inserted by the user with already existing data
- function ImportData() {
- GetPlaylistsFromDatabase().then((existingData) => {
- if (existingData !== null && existingData !== undefined) {
- try {
- const inputInsertBackup = document.getElementById('input-insert-backup');
- const newData = JSON.parse(inputInsertBackup.value);
- if (typeof newData === 'object' && newData !== null)
- {
- // Merge the new JSON data into existing data
- existingData.playlists = existingData.playlists.concat(newData);
- // Assign new IDs to every playlist to avoid conflicts
- AssignNewPlaylistIds(existingData);
- mergedData = JSON.stringify(existingData);
- // Save data to localStorage for functions that must be 'user-initiated' and don't work with async (like opening a new tab in the browser)
- localStorage.setItem("savedPlaylists", mergedData);
- // Save to database
- AddOrUpdateDataInDatabase('savedPlaylists', mergedData)
- .catch((error) => {
- console.error('Error:', error);
- });
- // Clean input field
- inputInsertBackup.value = '';
- // change status to success
- const statusText = document.getElementById('status-message');
- statusText.textContent = 'Status: Data imported.';
- }
- } catch (error) {
- // change status to error
- const statusText = document.getElementById('status-message');
- statusText.textContent = 'Status: Data is not valid.';
- console.error(error);
- }
- }
- })
- .catch((error) => {
- console.error('Error:', error);
- });
- }
- // Function to extract video ID from url string
- function ExtractVideoId(input) {
- // Check if the input is a full YouTube URL
- if (input.includes('youtube.com/watch?v=')) {
- const match = input.match(/[?&]v=([^&]+)/);
- if (match) {
- return match[1]; // Extracted video ID
- }
- } else if (input.includes('youtu.be/')) {
- // Handle youtu.be short URLs
- const match = input.match(/youtu.be\/([^?]+)/);
- if (match) {
- return match[1]; // Extracted video ID
- }
- }
- // Check if the input is a full yewtu URL
- else if (input.includes('yewtu.be/watch?v=')) {
- const match = input.match(/[?&]v=([^&]+)/);
- if (match) {
- return match[1]; // Extracted video ID
- }
- }
- // If it's not a full URL or the pattern doesn't match, assume it's already a video ID
- return input;
- }
- function ConnectDatabase() {
- return new Promise((resolve, reject) => {
- // Open database
- const DBOpenRequest = window.indexedDB.open('userData', 1);
- DBOpenRequest.onerror = (event) => {
- reject(new Error('Error loading database.'));
- };
- DBOpenRequest.onsuccess = (event) => {
- db = DBOpenRequest.result;
- resolve(db);
- };
- DBOpenRequest.onupgradeneeded = (event) => {
- db = event.target.result;
- db.onerror = (event) => {
- reject(new Error('Error loading database.'));
- };
- const objectStore = db.createObjectStore('userData', { keyPath: 'key' });
- };
- });
- }
- function AddOrUpdateDataInDatabase(key, value) {
- return new Promise((resolve, reject) => {
- const data = { key: key, value: value };
- // Open a read/write DB transaction, ready for adding or updating the data
- const transaction = db.transaction(['userData'], 'readwrite');
- // Report on the success of the transaction completing, when everything is done
- transaction.oncomplete = () => {
- //console.log('Transaction completed: database modification finished.');
- resolve(); // Resolve the Promise when the transaction is complete
- };
- // Handler for any unexpected error
- transaction.onerror = (event) => {
- //console.log(`Transaction not opened due to error: ${transaction.error}`);
- reject(transaction.error); // Reject the Promise with the error
- };
- // Call an object store that's already been added to the database
- const objectStore = transaction.objectStore('userData');
- // Use the put method to either add or update data
- const objectStoreRequest = objectStore.put(data);
- objectStoreRequest.onsuccess = (event) => {
- //console.log('Request successful.');
- };
- });
- }
- function RetrieveDataFromDatabase(key) {
- return new Promise((resolve, reject) => {
- // Open our object store and then get a cursor list of all the different data items in the IDB to iterate through
- const objectStore = db.transaction('userData').objectStore('userData');
- const request = objectStore.get(key); // Get the value associated with the key
- request.onsuccess = (event) => {
- const storedKey = request.result;
- if (storedKey) {
- resolve(storedKey.value); // Resolve the Promise with the retrieved value
- } else {
- //console.log("No data found for the key.");
- resolve(null); // Resolve with null if no data is found
- }
- };
- request.onerror = (event) => {
- //console.error("Error retrieving 'font' value:", event.target.error);
- reject(event.target.error); // Reject the Promise with the error
- };
- });
- }
- // In case of data corruption, this function can be used to clear the database
- function DeleteFromDatabase(key) {
- return new Promise((resolve, reject) => {
- // Open a read/write DB transaction for deleting data
- const transaction = db.transaction(['userData'], 'readwrite');
- const objectStore = transaction.objectStore('userData');
- const deleteRequest = objectStore.delete(key);
- deleteRequest.onsuccess = (event) => {
- console.log('Deleted the preference successfully.');
- resolve(); // Resolve the Promise when deletion is successful
- };
- deleteRequest.onerror = (event) => {
- console.error('Error deleting the preference:', event.target.error);
- reject(new Error('Error deleting preference')); // Reject the Promise on error
- };
- });
- }
|