feat(13-02): add library filter dropdown and wire all views to respect active filter
- Add selectedLibraryId state + ByLibrary conditional calls to library-store - Add library filter pass-through methods to library-controller - Create library-filter dropdown component in top bar - Wire genre-details, cover-grid, artists-view, genres-view to use ByLibrary queries - Update album-selection helper to respect library filter - Regenerate Wails bindings for new ByLibrary methods - Search remains client-side (automatically filtered by loaded data) - Playlists remain unfiltered (use separate playlist store)
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<h1 class="title">YellowJacket</h1>
|
||||
<h3 class="subtitle">Music how it was meant to bee.</h3>
|
||||
</hgroup>
|
||||
<library-filter></library-filter>
|
||||
<search-bar></search-bar>
|
||||
</header>
|
||||
<div class="sidebar">
|
||||
|
||||
@@ -12,6 +12,7 @@ import '@components/genres-view/genres-view.ts';
|
||||
import '@components/genre-details/genre-details.ts';
|
||||
import '@components/playlist-details/playlist-details.ts';
|
||||
import '@components/search-bar/search-bar.ts';
|
||||
import '@components/library-filter/library-filter.ts';
|
||||
import '@components/track-details/track-details.ts';
|
||||
import '@awesome.me/webawesome/dist/styles/themes/default.css';
|
||||
import '@awesome.me/webawesome/dist/components/icon/icon.js';
|
||||
|
||||
@@ -13,6 +13,8 @@ import { grid } from '@lit-labs/virtualizer/layouts/grid.js';
|
||||
import {
|
||||
GetAlbumsByArtist,
|
||||
GetAlbumTracks,
|
||||
GetAlbumsByArtistByLibrary,
|
||||
GetAlbumTracksByLibrary,
|
||||
} from '@go/library/Library';
|
||||
import { library } from '@go/models';
|
||||
import { LibraryController } from '@store/controllers/library-controller';
|
||||
@@ -927,20 +929,31 @@ export class ArtistsView
|
||||
/**
|
||||
* Fetches all file paths for an artist by
|
||||
* loading their albums, then each album's
|
||||
* tracks.
|
||||
* tracks. Respects the active library filter.
|
||||
*/
|
||||
private async getArtistFilePaths(
|
||||
artist: library.Artist,
|
||||
): Promise<string[]> {
|
||||
try {
|
||||
const albums =
|
||||
await GetAlbumsByArtist(artist.ID);
|
||||
const libId =
|
||||
this.libraryCtrl.selectedLibraryId;
|
||||
|
||||
const albums = libId !== null
|
||||
? await GetAlbumsByArtistByLibrary(
|
||||
artist.ID,
|
||||
libId,
|
||||
)
|
||||
: await GetAlbumsByArtist(artist.ID);
|
||||
|
||||
const allPaths: string[] = [];
|
||||
|
||||
for (const album of albums) {
|
||||
const tracks =
|
||||
await GetAlbumTracks(album.ID);
|
||||
const tracks = libId !== null
|
||||
? await GetAlbumTracksByLibrary(
|
||||
album.ID,
|
||||
libId,
|
||||
)
|
||||
: await GetAlbumTracks(album.ID);
|
||||
|
||||
for (const t of tracks) {
|
||||
allPaths.push(t.FilePath);
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { GetAlbumTracks } from '@go/library/Library';
|
||||
import {
|
||||
GetAlbumTracks,
|
||||
GetAlbumTracksByLibrary,
|
||||
} from '@go/library/Library';
|
||||
import { libraryStore } from '@store/library-store';
|
||||
import type { library } from '@go/models';
|
||||
import type { CoverArtUrls } from '@components/track-details/track-details.js';
|
||||
|
||||
@@ -43,6 +47,21 @@ export class AlbumSelectionManager {
|
||||
this.albumFilePathCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch album tracks respecting the active
|
||||
* library filter.
|
||||
*/
|
||||
private fetchAlbumTracks(
|
||||
albumId: number,
|
||||
): Promise<library.Track[]> {
|
||||
const libId =
|
||||
libraryStore.getSelectedLibraryId();
|
||||
|
||||
return libId !== null
|
||||
? GetAlbumTracksByLibrary(albumId, libId)
|
||||
: GetAlbumTracks(albumId);
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// Album selection helpers
|
||||
// ================================================================
|
||||
@@ -134,9 +153,8 @@ export class AlbumSelectionManager {
|
||||
album: library.Album,
|
||||
): Promise<string[]> {
|
||||
try {
|
||||
const tracks = await GetAlbumTracks(
|
||||
album.ID,
|
||||
);
|
||||
const tracks =
|
||||
await this.fetchAlbumTracks(album.ID);
|
||||
|
||||
return tracks.map((t) => t.FilePath);
|
||||
} catch (error) {
|
||||
@@ -174,9 +192,10 @@ export class AlbumSelectionManager {
|
||||
if (!album) continue;
|
||||
|
||||
try {
|
||||
const tracks = await GetAlbumTracks(
|
||||
album.ID,
|
||||
);
|
||||
const tracks =
|
||||
await this.fetchAlbumTracks(
|
||||
album.ID,
|
||||
);
|
||||
|
||||
// Only store if still selected.
|
||||
if (selectedAlbums.has(album.ID)) {
|
||||
|
||||
@@ -11,7 +11,10 @@ import type {
|
||||
VisibilityChangedEvent,
|
||||
} from '@lit-labs/virtualizer';
|
||||
import { grid } from '@lit-labs/virtualizer/layouts/grid.js';
|
||||
import { GetAlbumTracks } from '@go/library/Library';
|
||||
import {
|
||||
GetAlbumTracks,
|
||||
GetAlbumTracksByLibrary,
|
||||
} from '@go/library/Library';
|
||||
import { library } from '@go/models';
|
||||
import { LibraryController } from '@store/controllers/library-controller';
|
||||
import { SearchController } from '@store/controllers/search-controller';
|
||||
@@ -973,9 +976,15 @@ export class CoverGrid
|
||||
this.lastSelectedTrackIndex = null;
|
||||
|
||||
try {
|
||||
const tracks = await GetAlbumTracks(
|
||||
album.ID,
|
||||
);
|
||||
const libId =
|
||||
this.libraryCtrl.selectedLibraryId;
|
||||
|
||||
const tracks = libId !== null
|
||||
? await GetAlbumTracksByLibrary(
|
||||
album.ID,
|
||||
libId,
|
||||
)
|
||||
: await GetAlbumTracks(album.ID);
|
||||
|
||||
if (this.expandedAlbumId === album.ID) {
|
||||
this.expandedTracks = tracks;
|
||||
|
||||
@@ -5,9 +5,13 @@ import {
|
||||
state,
|
||||
} from 'lit/decorators.js';
|
||||
import { library } from '@go/models';
|
||||
import { GetTracksByGenre } from '@go/library/Library';
|
||||
import {
|
||||
GetTracksByGenre,
|
||||
GetTracksByGenreByLibrary,
|
||||
} from '@go/library/Library';
|
||||
import { EventsOn } from '@runtime/runtime';
|
||||
import { Events } from '../../events';
|
||||
import { libraryStore } from '@store/library-store';
|
||||
import '@awesome.me/webawesome/dist/components/icon/icon.js';
|
||||
import '@components/track-list/track-list.js';
|
||||
import { designTokens } from '../../styles/tokens.css';
|
||||
@@ -176,9 +180,17 @@ export class GenreDetails extends LitElement {
|
||||
if (!this.genreName) return;
|
||||
|
||||
try {
|
||||
this.tracks = await GetTracksByGenre(
|
||||
this.genreName,
|
||||
);
|
||||
const libId =
|
||||
libraryStore.getSelectedLibraryId();
|
||||
|
||||
this.tracks = libId !== null
|
||||
? await GetTracksByGenreByLibrary(
|
||||
this.genreName,
|
||||
libId,
|
||||
)
|
||||
: await GetTracksByGenre(
|
||||
this.genreName,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Error loading genre tracks:',
|
||||
|
||||
@@ -10,7 +10,10 @@ import type {
|
||||
VisibilityChangedEvent,
|
||||
} from '@lit-labs/virtualizer';
|
||||
import { grid } from '@lit-labs/virtualizer/layouts/grid.js';
|
||||
import { GetTracksByGenre } from '@go/library/Library';
|
||||
import {
|
||||
GetTracksByGenre,
|
||||
GetTracksByGenreByLibrary,
|
||||
} from '@go/library/Library';
|
||||
import type { library } from '@go/models';
|
||||
import { LibraryController } from '@store/controllers/library-controller';
|
||||
import { SearchController } from '@store/controllers/search-controller';
|
||||
@@ -723,16 +726,25 @@ export class GenresView
|
||||
/**
|
||||
* Fetch file paths for a set of genre names by
|
||||
* querying the backend for each genre.
|
||||
* Respects the active library filter.
|
||||
*/
|
||||
private async getFilePathsForGenres(
|
||||
genreNames: Iterable<string>,
|
||||
): Promise<string[]> {
|
||||
const seen = new Set<string>();
|
||||
const allPaths: string[] = [];
|
||||
const libId =
|
||||
this.libraryCtrl.selectedLibraryId;
|
||||
|
||||
const promises = Array.from(
|
||||
genreNames,
|
||||
(name) => GetTracksByGenre(name),
|
||||
(name) =>
|
||||
libId !== null
|
||||
? GetTracksByGenreByLibrary(
|
||||
name,
|
||||
libId,
|
||||
)
|
||||
: GetTracksByGenre(name),
|
||||
);
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
import { LitElement, html, css } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { LibraryController } from '@store/controllers/library-controller';
|
||||
import type { library } from '@go/models';
|
||||
import { designTokens } from '../../styles/tokens.css';
|
||||
|
||||
/**
|
||||
* Compact dropdown in the top bar for filtering all
|
||||
* browse views to a specific library. "All Libraries"
|
||||
* (value = null) shows the unified merged view.
|
||||
*/
|
||||
@customElement('library-filter')
|
||||
export class LibraryFilter extends LitElement {
|
||||
private libraryCtrl = new LibraryController(this);
|
||||
|
||||
@state()
|
||||
private libraries: library.Info[] = [];
|
||||
|
||||
static override styles = [designTokens, css`
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
select {
|
||||
height: 32px;
|
||||
padding: 0 8px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid
|
||||
var(--yj-border-subtle, #555);
|
||||
background: var(--yj-bg-surface, #212529);
|
||||
color: var(--yj-text-primary, #fff);
|
||||
font-size: var(--yj-text-md);
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
min-width: 120px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
option {
|
||||
background: var(--yj-bg-surface, #212529);
|
||||
color: var(--yj-text-primary, #fff);
|
||||
}
|
||||
`];
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.loadLibraries();
|
||||
}
|
||||
|
||||
private async loadLibraries() {
|
||||
try {
|
||||
this.libraries =
|
||||
await this.libraryCtrl.getLibraries();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Error loading libraries:',
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private handleChange = (e: Event) => {
|
||||
const select = e.target as HTMLSelectElement;
|
||||
const value = select.value;
|
||||
const id = value === ''
|
||||
? null
|
||||
: Number(value);
|
||||
|
||||
this.libraryCtrl.setSelectedLibrary(id);
|
||||
};
|
||||
|
||||
override render() {
|
||||
const selected =
|
||||
this.libraryCtrl.selectedLibraryId;
|
||||
const selectValue =
|
||||
selected === null ? '' : String(selected);
|
||||
|
||||
return html`
|
||||
<select
|
||||
.value=${selectValue}
|
||||
@change=${this.handleChange}
|
||||
aria-label="Library filter"
|
||||
>
|
||||
<option value="">All Libraries</option>
|
||||
${this.libraries.map(
|
||||
(lib) => html`
|
||||
<option value=${lib.id}>
|
||||
${lib.name}
|
||||
</option>
|
||||
`,
|
||||
)}
|
||||
</select>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'library-filter': LibraryFilter;
|
||||
}
|
||||
}
|
||||
@@ -129,6 +129,22 @@ export class LibraryController implements ReactiveController {
|
||||
libraryStore.setScrollPosition(view, offset);
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// LIBRARY FILTER
|
||||
// ===================================================================
|
||||
|
||||
get selectedLibraryId(): number | null {
|
||||
return libraryStore.getSelectedLibraryId();
|
||||
}
|
||||
|
||||
setSelectedLibrary(id: number | null): void {
|
||||
libraryStore.setSelectedLibrary(id);
|
||||
}
|
||||
|
||||
async getLibraries(): Promise<library.Info[]> {
|
||||
return libraryStore.getLibraries();
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// COVER SIZE
|
||||
// ===================================================================
|
||||
|
||||
@@ -5,6 +5,12 @@ import {
|
||||
GetAllArtists,
|
||||
GetAllGenresWithCounts,
|
||||
GetAlbumsByArtist,
|
||||
GetAllTracksByLibrary,
|
||||
GetAllAlbumsByLibrary,
|
||||
GetAllArtistsByLibrary,
|
||||
GetAllGenresWithCountsByLibrary,
|
||||
GetAlbumsByArtistByLibrary,
|
||||
GetAllLibrariesWithTrackCounts,
|
||||
} from '@go/library/Library';
|
||||
import type { library } from '@go/models';
|
||||
import { Events } from '../events';
|
||||
@@ -30,6 +36,9 @@ class LibraryStore {
|
||||
private albums: library.Album[] | null = null;
|
||||
private artists: library.Artist[] | null = null;
|
||||
private genres: library.GenreWithCount[] | null = null;
|
||||
private libraries: library.Info[] | null = null;
|
||||
|
||||
private selectedLibraryIdValue: number | null = null;
|
||||
|
||||
private tracksLoading = false;
|
||||
private albumsLoading = false;
|
||||
@@ -60,8 +69,19 @@ class LibraryStore {
|
||||
this.invalidate();
|
||||
});
|
||||
EventsOn(Events.LibraryRemoved, () => {
|
||||
this.libraries = null;
|
||||
this.invalidate();
|
||||
});
|
||||
EventsOn(Events.LibraryAdded, () => {
|
||||
this.libraries = null;
|
||||
this.changeGen++;
|
||||
this.notify();
|
||||
});
|
||||
EventsOn(Events.LibraryRenamed, () => {
|
||||
this.libraries = null;
|
||||
this.changeGen++;
|
||||
this.notify();
|
||||
});
|
||||
|
||||
this.loadCoverSize();
|
||||
this.deferEagerFetch();
|
||||
@@ -110,7 +130,11 @@ class LibraryStore {
|
||||
this.notify();
|
||||
|
||||
try {
|
||||
const tracks = await GetAllTracks();
|
||||
const id = this.selectedLibraryIdValue;
|
||||
const tracks = id !== null
|
||||
? await GetAllTracksByLibrary(id)
|
||||
: await GetAllTracks();
|
||||
|
||||
this.tracks = tracks;
|
||||
this.changeGen++;
|
||||
|
||||
@@ -134,7 +158,11 @@ class LibraryStore {
|
||||
this.notify();
|
||||
|
||||
try {
|
||||
const albums = await GetAllAlbums();
|
||||
const id = this.selectedLibraryIdValue;
|
||||
const albums = id !== null
|
||||
? await GetAllAlbumsByLibrary(id)
|
||||
: await GetAllAlbums();
|
||||
|
||||
this.albums = albums;
|
||||
this.changeGen++;
|
||||
|
||||
@@ -158,7 +186,11 @@ class LibraryStore {
|
||||
this.notify();
|
||||
|
||||
try {
|
||||
const artists = await GetAllArtists();
|
||||
const id = this.selectedLibraryIdValue;
|
||||
const artists = id !== null
|
||||
? await GetAllArtistsByLibrary(id)
|
||||
: await GetAllArtists();
|
||||
|
||||
this.artists = artists;
|
||||
this.changeGen++;
|
||||
|
||||
@@ -182,7 +214,11 @@ class LibraryStore {
|
||||
this.notify();
|
||||
|
||||
try {
|
||||
const genres = await GetAllGenresWithCounts();
|
||||
const id = this.selectedLibraryIdValue;
|
||||
const genres = id !== null
|
||||
? await GetAllGenresWithCountsByLibrary(id)
|
||||
: await GetAllGenresWithCounts();
|
||||
|
||||
this.genres = genres;
|
||||
this.changeGen++;
|
||||
|
||||
@@ -196,7 +232,11 @@ class LibraryStore {
|
||||
async getAlbumsByArtist(
|
||||
artistID: number,
|
||||
): Promise<library.Album[]> {
|
||||
return GetAlbumsByArtist(artistID);
|
||||
const id = this.selectedLibraryIdValue;
|
||||
|
||||
return id !== null
|
||||
? GetAlbumsByArtistByLibrary(artistID, id)
|
||||
: GetAlbumsByArtist(artistID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,10 +246,20 @@ class LibraryStore {
|
||||
* result when the all-albums list has already
|
||||
* been loaded (e.g. the user visited the albums
|
||||
* view first).
|
||||
*
|
||||
* Returns null when a library filter is active
|
||||
* because the cached albums are already filtered
|
||||
* by library — the client-side ArtistName match
|
||||
* is correct but forcing a backend query ensures
|
||||
* consistency.
|
||||
*/
|
||||
getAlbumsByArtistNameCached(
|
||||
artistName: string,
|
||||
): library.Album[] | null {
|
||||
if (this.selectedLibraryIdValue !== null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.albums === null) return null;
|
||||
|
||||
return this.albums.filter(
|
||||
@@ -265,6 +315,34 @@ class LibraryStore {
|
||||
return this.changeGen;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// LIBRARY FILTER
|
||||
// ===================================================================
|
||||
|
||||
getSelectedLibraryId(): number | null {
|
||||
return this.selectedLibraryIdValue;
|
||||
}
|
||||
|
||||
setSelectedLibrary(id: number | null): void {
|
||||
if (id === this.selectedLibraryIdValue) return;
|
||||
|
||||
this.selectedLibraryIdValue = id;
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
async getLibraries(): Promise<library.Info[]> {
|
||||
if (this.libraries !== null) {
|
||||
return this.libraries;
|
||||
}
|
||||
|
||||
const libs =
|
||||
await GetAllLibrariesWithTrackCounts();
|
||||
|
||||
this.libraries = libs;
|
||||
|
||||
return libs;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// SCROLL POSITION
|
||||
// ===================================================================
|
||||
|
||||
+16
@@ -16,24 +16,38 @@ export function FullRescan():Promise<library.ScanMetrics>;
|
||||
|
||||
export function GetAlbumTracks(arg1:number):Promise<Array<library.Track>>;
|
||||
|
||||
export function GetAlbumTracksByLibrary(arg1:number,arg2:number):Promise<Array<library.Track>>;
|
||||
|
||||
export function GetAlbumsByArtist(arg1:number):Promise<Array<library.Album>>;
|
||||
|
||||
export function GetAlbumsByArtistByLibrary(arg1:number,arg2:number):Promise<Array<library.Album>>;
|
||||
|
||||
export function GetAllAlbums():Promise<Array<library.Album>>;
|
||||
|
||||
export function GetAllAlbumsByLibrary(arg1:number):Promise<Array<library.Album>>;
|
||||
|
||||
export function GetAllArtists():Promise<Array<library.Artist>>;
|
||||
|
||||
export function GetAllArtistsByLibrary(arg1:number):Promise<Array<library.Artist>>;
|
||||
|
||||
export function GetAllGenresWithCounts():Promise<Array<library.GenreWithCount>>;
|
||||
|
||||
export function GetAllGenresWithCountsByLibrary(arg1:number):Promise<Array<library.GenreWithCount>>;
|
||||
|
||||
export function GetAllLibrariesWithTrackCounts():Promise<Array<library.Info>>;
|
||||
|
||||
export function GetAllTracks():Promise<Array<library.Track>>;
|
||||
|
||||
export function GetAllTracksByLibrary(arg1:number):Promise<Array<library.Track>>;
|
||||
|
||||
export function GetRemovalImpact(arg1:number):Promise<library.RemovalImpact>;
|
||||
|
||||
export function GetScanQueueLength():Promise<number>;
|
||||
|
||||
export function GetTracksByGenre(arg1:string):Promise<Array<library.Track>>;
|
||||
|
||||
export function GetTracksByGenreByLibrary(arg1:string,arg2:number):Promise<Array<library.Track>>;
|
||||
|
||||
export function IsScanActive():Promise<boolean>;
|
||||
|
||||
export function IsScanPaused():Promise<boolean>;
|
||||
@@ -54,6 +68,8 @@ export function ScanLibrary(arg1:number):Promise<void>;
|
||||
|
||||
export function SearchTracks(arg1:string):Promise<Array<library.Track>>;
|
||||
|
||||
export function SearchTracksByLibrary(arg1:string,arg2:number):Promise<Array<library.Track>>;
|
||||
|
||||
export function SetContext(arg1:context.Context):Promise<void>;
|
||||
|
||||
export function SetRemovalHooks(arg1:library.RemovalHooks):Promise<void>;
|
||||
|
||||
@@ -26,22 +26,42 @@ export function GetAlbumTracks(arg1) {
|
||||
return window['go']['library']['Library']['GetAlbumTracks'](arg1);
|
||||
}
|
||||
|
||||
export function GetAlbumTracksByLibrary(arg1, arg2) {
|
||||
return window['go']['library']['Library']['GetAlbumTracksByLibrary'](arg1, arg2);
|
||||
}
|
||||
|
||||
export function GetAlbumsByArtist(arg1) {
|
||||
return window['go']['library']['Library']['GetAlbumsByArtist'](arg1);
|
||||
}
|
||||
|
||||
export function GetAlbumsByArtistByLibrary(arg1, arg2) {
|
||||
return window['go']['library']['Library']['GetAlbumsByArtistByLibrary'](arg1, arg2);
|
||||
}
|
||||
|
||||
export function GetAllAlbums() {
|
||||
return window['go']['library']['Library']['GetAllAlbums']();
|
||||
}
|
||||
|
||||
export function GetAllAlbumsByLibrary(arg1) {
|
||||
return window['go']['library']['Library']['GetAllAlbumsByLibrary'](arg1);
|
||||
}
|
||||
|
||||
export function GetAllArtists() {
|
||||
return window['go']['library']['Library']['GetAllArtists']();
|
||||
}
|
||||
|
||||
export function GetAllArtistsByLibrary(arg1) {
|
||||
return window['go']['library']['Library']['GetAllArtistsByLibrary'](arg1);
|
||||
}
|
||||
|
||||
export function GetAllGenresWithCounts() {
|
||||
return window['go']['library']['Library']['GetAllGenresWithCounts']();
|
||||
}
|
||||
|
||||
export function GetAllGenresWithCountsByLibrary(arg1) {
|
||||
return window['go']['library']['Library']['GetAllGenresWithCountsByLibrary'](arg1);
|
||||
}
|
||||
|
||||
export function GetAllLibrariesWithTrackCounts() {
|
||||
return window['go']['library']['Library']['GetAllLibrariesWithTrackCounts']();
|
||||
}
|
||||
@@ -50,6 +70,10 @@ export function GetAllTracks() {
|
||||
return window['go']['library']['Library']['GetAllTracks']();
|
||||
}
|
||||
|
||||
export function GetAllTracksByLibrary(arg1) {
|
||||
return window['go']['library']['Library']['GetAllTracksByLibrary'](arg1);
|
||||
}
|
||||
|
||||
export function GetRemovalImpact(arg1) {
|
||||
return window['go']['library']['Library']['GetRemovalImpact'](arg1);
|
||||
}
|
||||
@@ -62,6 +86,10 @@ export function GetTracksByGenre(arg1) {
|
||||
return window['go']['library']['Library']['GetTracksByGenre'](arg1);
|
||||
}
|
||||
|
||||
export function GetTracksByGenreByLibrary(arg1, arg2) {
|
||||
return window['go']['library']['Library']['GetTracksByGenreByLibrary'](arg1, arg2);
|
||||
}
|
||||
|
||||
export function IsScanActive() {
|
||||
return window['go']['library']['Library']['IsScanActive']();
|
||||
}
|
||||
@@ -102,6 +130,10 @@ export function SearchTracks(arg1) {
|
||||
return window['go']['library']['Library']['SearchTracks'](arg1);
|
||||
}
|
||||
|
||||
export function SearchTracksByLibrary(arg1, arg2) {
|
||||
return window['go']['library']['Library']['SearchTracksByLibrary'](arg1, arg2);
|
||||
}
|
||||
|
||||
export function SetContext(arg1) {
|
||||
return window['go']['library']['Library']['SetContext'](arg1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user