|
|
@@ -127,5 +127,110 @@ document.addEventListener("alpine:init", () => {
|
|
|
this.exportPlaylists();
|
|
|
},
|
|
|
},
|
|
|
+
|
|
|
+ importButton: {
|
|
|
+ ["@click"]() {
|
|
|
+ document.getElementById("import-file-input").click();
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ importFile(event) {
|
|
|
+ const file = event.target.files[0];
|
|
|
+ if (!file) return;
|
|
|
+
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = (e) => {
|
|
|
+ try {
|
|
|
+ const importedData = JSON.parse(e.target.result);
|
|
|
+ this.validateAndImportPlaylists(importedData);
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Error parsing JSON file:", error);
|
|
|
+ alert(
|
|
|
+ "Invalid JSON file. Please select a valid playlist export file.",
|
|
|
+ );
|
|
|
+ } finally {
|
|
|
+ // Reset the file input so the same file can be selected again
|
|
|
+ event.target.value = "";
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ reader.readAsText(file);
|
|
|
+ },
|
|
|
+
|
|
|
+ validateAndImportPlaylists(data) {
|
|
|
+ // Validate the playlists structure
|
|
|
+ if (!data.playlists || typeof data.playlists !== "object") {
|
|
|
+ alert("Invalid file format: Missing or invalid 'playlists' property");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Validate each playlist
|
|
|
+ const validPlaylists = {};
|
|
|
+ let hasErrors = false;
|
|
|
+
|
|
|
+ for (const [playlistName, videos] of Object.entries(data.playlists)) {
|
|
|
+ // Check if videos is an array
|
|
|
+ if (!Array.isArray(videos)) {
|
|
|
+ console.error(
|
|
|
+ `Playlist '${playlistName}' does not contain a valid array of videos`,
|
|
|
+ );
|
|
|
+ hasErrors = true;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Validate each video in the playlist
|
|
|
+ const validVideos = videos.filter((video) => {
|
|
|
+ if (!video || typeof video !== "object") {
|
|
|
+ console.error(`Invalid video object in '${playlistName}'`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ !video.url ||
|
|
|
+ typeof video.url !== "string" ||
|
|
|
+ !video.title ||
|
|
|
+ typeof video.title !== "string"
|
|
|
+ ) {
|
|
|
+ console.error(
|
|
|
+ `Video in '${playlistName}' missing required properties (url, title)`,
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ // Add the validated playlist if it has valid videos
|
|
|
+ if (validVideos.length > 0) {
|
|
|
+ validPlaylists[playlistName] = validVideos;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Object.keys(validPlaylists).length === 0) {
|
|
|
+ alert("No valid playlists found in the import file");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hasErrors) {
|
|
|
+ const confirmImport = confirm(
|
|
|
+ "Some playlists or videos were invalid and will be skipped. Do you want to continue with the import?",
|
|
|
+ );
|
|
|
+ if (!confirmImport) return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Update storage and state
|
|
|
+ this.updatePlaylists(validPlaylists);
|
|
|
+ },
|
|
|
+
|
|
|
+ async updatePlaylists(playlists) {
|
|
|
+ try {
|
|
|
+ await browser.storage.local.set({ playlists });
|
|
|
+ this.playlists = playlists;
|
|
|
+ alert("Playlists imported successfully!");
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Error updating playlists:", error);
|
|
|
+ alert("Error importing playlists: " + error.message);
|
|
|
+ }
|
|
|
+ },
|
|
|
}));
|
|
|
});
|