|
|
@@ -9,6 +9,7 @@ document.addEventListener("alpine:init", () => {
|
|
|
// X view playback history (?)
|
|
|
// X include currently open tabs in export
|
|
|
// - support playlist management (add, remove, rename playlists)
|
|
|
+ // - support dynamic (on-demand) playlists
|
|
|
// - support input text box for adding to playlist (how to handle title?)
|
|
|
// - or raw json editing
|
|
|
// X option (probably a button) to add current page (url, title) to playlist
|
|
|
@@ -60,6 +61,9 @@ document.addEventListener("alpine:init", () => {
|
|
|
currentVideoTimestamp: "", // Current video timestamp
|
|
|
includeTimestamp: true, // Whether to include timestamp line
|
|
|
|
|
|
+ // Import properties
|
|
|
+ importText: "", // Text area content for import
|
|
|
+
|
|
|
init() {
|
|
|
this.loadPlaylists();
|
|
|
this.loadHistory();
|
|
|
@@ -333,6 +337,10 @@ document.addEventListener("alpine:init", () => {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ showImport() {
|
|
|
+ this.currentView = "import";
|
|
|
+ },
|
|
|
+
|
|
|
async refreshVideoTimestamp() {
|
|
|
if (this.isCurrentVideoYoutube) {
|
|
|
await this.getVideoTimestamp();
|
|
|
@@ -847,37 +855,26 @@ document.addEventListener("alpine:init", () => {
|
|
|
|
|
|
importButton: {
|
|
|
["@click"]() {
|
|
|
- document.getElementById("import-file-input").click();
|
|
|
- },
|
|
|
- },
|
|
|
-
|
|
|
- importFileInput: {
|
|
|
- ["@change"]() {
|
|
|
- this.importFile(this.$event);
|
|
|
+ this.showImport();
|
|
|
},
|
|
|
},
|
|
|
|
|
|
- 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 = "";
|
|
|
- }
|
|
|
- };
|
|
|
+ async handleImport() {
|
|
|
+ if (!this.importText.trim()) {
|
|
|
+ alert("Please paste your JSON export data");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- reader.readAsText(file);
|
|
|
+ try {
|
|
|
+ const importedData = JSON.parse(this.importText);
|
|
|
+ this.validateAndImportPlaylists(importedData);
|
|
|
+ this.importText = "";
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Error parsing JSON:", error);
|
|
|
+ alert(
|
|
|
+ "Invalid JSON format. Please paste valid playlist export data.",
|
|
|
+ );
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
validateAndImportPlaylists(data) {
|
|
|
@@ -1138,6 +1135,12 @@ document.addEventListener("alpine:init", () => {
|
|
|
},
|
|
|
},
|
|
|
|
|
|
+ importHeader: {
|
|
|
+ ["x-show"]() {
|
|
|
+ return this.currentView === "import";
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
playlistsContainer: {
|
|
|
["x-show"]() {
|
|
|
return this.currentView === "playlists";
|
|
|
@@ -1168,6 +1171,12 @@ document.addEventListener("alpine:init", () => {
|
|
|
},
|
|
|
},
|
|
|
|
|
|
+ importContainer: {
|
|
|
+ ["x-show"]() {
|
|
|
+ return this.currentView === "import";
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
exportContainer: {
|
|
|
["x-show"]() {
|
|
|
return this.currentView === "playlists";
|
|
|
@@ -1297,5 +1306,21 @@ document.addEventListener("alpine:init", () => {
|
|
|
};
|
|
|
},
|
|
|
},
|
|
|
+
|
|
|
+ // Import view bindings
|
|
|
+ importTextarea: {
|
|
|
+ [":value"]() {
|
|
|
+ return this.importText;
|
|
|
+ },
|
|
|
+ ["@input"]() {
|
|
|
+ this.importText = this.$el.value;
|
|
|
+ },
|
|
|
+ },
|
|
|
+
|
|
|
+ importSubmitButton: {
|
|
|
+ ["@click"]() {
|
|
|
+ this.handleImport();
|
|
|
+ },
|
|
|
+ },
|
|
|
}));
|
|
|
});
|