-
Notifications
You must be signed in to change notification settings - Fork 1.6k
feat:Export playlist metadata #3983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
eslint
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
const playlistData = queue.map((song: any) => ({ |
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any
value.
title: song.videoDetails?.title, |
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .videoDetails on an any
value.
title: song.videoDetails?.title, |
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any
value.
artist: song.videoDetails?.author, |
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .videoDetails on an any
value.
artist: song.videoDetails?.author, |
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any
value.
album: song.videoDetails?.album, |
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .videoDetails on an any
value.
album: song.videoDetails?.album, |
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any
value.
durationSeconds: song.videoDetails?.lengthSeconds, |
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .videoDetails on an any
value.
durationSeconds: song.videoDetails?.lengthSeconds, |
🚫 [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog 🐶
Unsafe assignment of an any
value.
videoId: song.videoDetails?.videoId, |
🚫 [eslint] <@typescript-eslint/no-unsafe-member-access> reported by reviewdog 🐶
Unsafe member access .videoDetails on an any
value.
videoId: song.videoDetails?.videoId, |
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ⏎
}; |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
|
||
import type { BackendContext } from '../../types/contexts'; | ||
|
||
const convertToCSV = (data: any[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
|
||
const convertToCSV = (data: any[]) => { | ||
if (data.length === 0) return ''; | ||
const header = Object.keys(data[0]).join(','); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <@typescript-eslint/no-unsafe-argument> reported by reviewdog 🐶
Unsafe argument of type any
assigned to a parameter of type {}
.
const convertToCSV = (data: any[]) => { | ||
if (data.length === 0) return ''; | ||
const header = Object.keys(data[0]).join(','); | ||
const rows = data.map(row => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace row
with (row)
const rows = data.map(row => | |
const rows = data.map((row) => |
const convertToCSV = (data: any[]) => { | ||
if (data.length === 0) return ''; | ||
const header = Object.keys(data[0]).join(','); | ||
const rows = data.map(row => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <stylistic/arrow-parens> reported by reviewdog 🐶
Expected parentheses around arrow function argument.
const rows = data.map(row => | |
const rows = data.map((row) => |
if (data.length === 0) return ''; | ||
const header = Object.keys(data[0]).join(','); | ||
const rows = data.map(row => | ||
Object.values(row).map(value => `"${String(value).replace(/"/g, '""')}"`).join(',') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <@typescript-eslint/no-unsafe-argument> reported by reviewdog 🐶
Unsafe argument of type any
assigned to a parameter of type ArrayLike<unknown> | { [s: string]: unknown; }
.
if (data.length === 0) return ''; | ||
const header = Object.keys(data[0]).join(','); | ||
const rows = data.map(row => | ||
Object.values(row).map(value => `"${String(value).replace(/"/g, '""')}"`).join(',') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Replace .map(value·=>·
"${String(value).replace(/"/g,·'""')}").join(',')
with ⏎······.map((value)·=>·
"${String(value).replace(/"/g,·'""')}")⏎······.join(','),
Object.values(row).map(value => `"${String(value).replace(/"/g, '""')}"`).join(',') | |
Object.values(row) | |
.map((value) => `"${String(value).replace(/"/g, '""')}"`) | |
.join(','), |
if (data.length === 0) return ''; | ||
const header = Object.keys(data[0]).join(','); | ||
const rows = data.map(row => | ||
Object.values(row).map(value => `"${String(value).replace(/"/g, '""')}"`).join(',') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <stylistic/arrow-parens> reported by reviewdog 🐶
Expected parentheses around arrow function argument.
Object.values(row).map(value => `"${String(value).replace(/"/g, '""')}"`).join(',') | |
Object.values(row).map((value) => `"${String(value).replace(/"/g, '""')}"`).join(',') |
|
||
// Add the config type to BackendContext | ||
export const backend = ({ ipc }: BackendContext<{ enabled: true }>) => { | ||
ipc.on('save-playlist-data', async (_: any, data: any[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
|
||
// Add the config type to BackendContext | ||
export const backend = ({ ipc }: BackendContext<{ enabled: true }>) => { | ||
ipc.on('save-playlist-data', async (_: any, data: any[]) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <@typescript-eslint/no-explicit-any> reported by reviewdog 🐶
Unexpected any. Specify a different type.
await fs.writeFile(filePath, csvData); | ||
} | ||
}); | ||
}; No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Insert ⏎
}; | |
}; | |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
import { createPlugin } from '../../utils'; | ||
|
||
import { backend } from './backend'; | ||
import { renderer } from './renderer'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶../../utils
import should occur after import of ./renderer
import { createPlugin } from '../../utils'; | |
import { backend } from './backend'; | |
import { renderer } from './renderer'; | |
import { backend } from './backend'; | |
import { renderer } from './renderer'; | |
import { createPlugin } from '../../utils'; |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@@ -0,0 +1,35 @@ | |||
import { promises as fs } from 'fs'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <importPlugin/order> reported by reviewdog 🐶
There should be at least one empty line between import groups
import { promises as fs } from 'fs'; | |
import { promises as fs } from 'fs'; | |
|
||
import type { BackendContext } from '../../types/contexts'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚫 [eslint] <prettier/prettier> reported by reviewdog 🐶
Delete ⏎
import type { BackendContext } from '../../types/contexts'; | |
import type { BackendContext } from '../../types/contexts'; |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Title: feat(plugins): Add Playlist Exporter
Description:
This pull request introduces a new plugin, Playlist Exporter, which allows users to export their current song queue to a CSV file.
Motivation
Currently, there is no easy way to get a structured list of songs from a playlist or queue out of the application. This plugin solves that problem by providing a simple, one-click solution to export the current queue's metadata (including title, artist, album, duration, and video ID) into a universally compatible CSV format.
This addresses the user need to manage, archive, or share playlist data without cumbersome manual effort, as requested in issue #[issue number].
Implementation
Adds a new plugin in src/plugins/playlist-exporter.
The plugin was built following the official guide in the README.md, with separate backend.ts and renderer.ts files for a clean separation of concerns.
An "Export Current Queue to CSV" option is added to the main application menu.
Uses Electron's dialog for a native "Save File" experience.
How to Test
Enable the "Playlist Exporter" plugin in the options.
Play any song to populate the song queue.
From the top menu, select "Export Current Queue to CSV".
A save dialog should appear. Choose a location to save the playlist.csv file.
Open the saved file and verify that the song data is accurate and correctly formatted.
Resolves #3972