Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/app/common/io/file-access.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export abstract class FileAccessBase {
public abstract getDateModifiedInTicks(fileOrDirectory: string): number;
public abstract getDateCreatedInTicks(fileOrDirectory: string): number;
public abstract pathExists(pathToCheck: string): boolean;
public abstract pathExistsAsync(pathToCheck: string): Promise<boolean>;
public abstract getFileSizeInBytes(filePath: string): number;
public abstract createFullDirectoryPathIfDoesNotExist(directoryPath: string): void;
public abstract createFile(filePath: string): void;
Expand Down
9 changes: 9 additions & 0 deletions src/app/common/io/file-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ export class FileAccess implements FileAccessBase {
return fs.existsSync(pathToCheck);
}

public async pathExistsAsync(pathToCheck: string): Promise<boolean> {
try {
await fs.promises.access(pathToCheck, fs.promises.constants.F_OK);
return true;
} catch (err) {
return false;
}
}

public getFileSizeInBytes(filePath: string): number {
const stats = fs.statSync(filePath);
return stats.size;
Expand Down
14 changes: 14 additions & 0 deletions src/app/common/validation/file-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ import { FileAccessBase } from '../io/file-access.base';
export class FileValidator {
public constructor(private fileAccess: FileAccessBase) {}

public async isPlayableAudioFileAsync(filePath: string): Promise<boolean> {
if (!await this.fileAccess.pathExistsAsync(filePath)) {
return false;
}

const fileExtension: string = this.fileAccess.getFileExtension(filePath);

if (!FileFormats.supportedAudioExtensions.includes(fileExtension.toLowerCase())) {
return false;
}

return true;
}

public isPlayableAudioFile(filePath: string): boolean {
if (!this.fileAccess.pathExists(filePath)) {
return false;
Expand Down
7 changes: 3 additions & 4 deletions src/app/services/playlist/playlist.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { Constants } from '../../common/application/constants';
import { PlaylistUpdateInfo } from './playlist-update-info';
import { PromiseUtils } from '../../common/utils/promise-utils';
import {SettingsBase} from "../../common/settings/settings.base";
import { SettingsBase } from '../../common/settings/settings.base';

@Injectable()
export class PlaylistService implements PlaylistServiceBase {
Expand Down Expand Up @@ -283,12 +283,11 @@ export class PlaylistService implements PlaylistServiceBase {
this.logger.error(e, `Could not decode playlist with path='${playlistPath}'`, 'PlaylistService', 'decodePlaylistAsync');
throw new Error(e instanceof Error ? e.message : 'Unknown error');
}



const albumKeyIndex = this.settings.albumKeyIndex;

for (const playlistEntry of playlistEntries) {
if (this.fileValidator.isPlayableAudioFile(playlistEntry.decodedPath)) {
if (await this.fileValidator.isPlayableAudioFileAsync(playlistEntry.decodedPath)) {
const track: TrackModel = await this.trackModelFactory.createFromFileAsync(playlistEntry.decodedPath, albumKeyIndex);
tracks.push(track);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { SettingsBase } from '../../../../common/settings/settings.base';
})
export class CollectionPlaylistsComponent implements OnInit, OnDestroy {
private subscription: Subscription = new Subscription();
private static gettingTracksFlag = false;

public constructor(
public searchService: SearchServiceBase,
Expand Down Expand Up @@ -129,14 +130,36 @@ export class CollectionPlaylistsComponent implements OnInit, OnDestroy {
this.playlists = await this.playlistService.getPlaylistsAsync(playlistFolders);
}

private async waitForPrevGetTracks(): Promise<void> {
return new Promise((resolve, reject) => {
const checkGettingTracks = (x: number) => {
if (x >= 10) { reject(); }

if(CollectionPlaylistsComponent.gettingTracksFlag) {
setTimeout(() => { checkGettingTracks(x + 1); }, 500);
} else {
resolve();
}
};

checkGettingTracks(0);
});
}

private async getTracksAsync(): Promise<void> {
await this.waitForPrevGetTracks();

CollectionPlaylistsComponent.gettingTracksFlag = true;

const selectedPlaylists: PlaylistModel[] = this.playlistsPersister.getSelectedPlaylists(this.playlists);

if (selectedPlaylists.length > 0) {
this.tracks = await this.playlistService.getTracksAsync(selectedPlaylists);
} else {
this.tracks = new TrackModels();
}

CollectionPlaylistsComponent.gettingTracksFlag = false;
}

private async getPlaylistsForPlaylistFoldersAndGetTracksAsync(playlistFolders: PlaylistFolderModel[]): Promise<void> {
Expand Down