Browse Source

added (untested) playlists import button

Brandon Wong 1 year ago
parent
commit
ffb020e635
3 changed files with 297 additions and 1 deletions
  1. 181 0
      2025-04-09-9-claude-export-button.md
  2. 11 1
      popup/popup.html
  3. 105 0
      popup/popup.js

File diff suppressed because it is too large
+ 181 - 0
2025-04-09-9-claude-export-button.md


+ 11 - 1
popup/popup.html

@@ -58,11 +58,21 @@
         </template>
       </div>
 
-      <!-- Export button -->
+      <!-- Export/Import buttons -->
       <div class="export-container">
         <button class="export-btn" x-bind="exportButton">
           Export Playlists
         </button>
+        <button class="import-btn" x-bind="importButton">
+          Import Playlists
+        </button>
+        <input
+          type="file"
+          id="import-file-input"
+          accept=".json"
+          style="display: none"
+          @change="importFile($event)"
+        />
       </div>
     </div>
   </body>

+ 105 - 0
popup/popup.js

@@ -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);
+      }
+    },
   }));
 });