mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat: implement file title normalization and path handling in playlist upload
Entire-Checkpoint: c6e522b4276c
This commit is contained in:
1 parent
1870ce2aea
commit
1d340c08b8
3 files changed
+55
-5
No files matched your search
+30
-3
@@ -3,6 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PlaylistActions } from 'm3u-state';
|
||||
import { DataService } from 'services';
|
||||
import { PLAYLIST_PARSE_BY_URL } from 'shared-interfaces';
|
||||
import { AddPlaylistDialogComponent } from './add-playlist-dialog.component';
|
||||
@@ -11,6 +12,7 @@ describe('AddPlaylistDialogComponent', () => {
|
||||
let component: AddPlaylistDialogComponent;
|
||||
let dataService: { sendIpcEvent: jest.Mock };
|
||||
let dialogRef: { close: jest.Mock };
|
||||
let store: { dispatch: jest.Mock };
|
||||
|
||||
beforeEach(() => {
|
||||
dataService = {
|
||||
@@ -19,6 +21,9 @@ describe('AddPlaylistDialogComponent', () => {
|
||||
dialogRef = {
|
||||
close: jest.fn(),
|
||||
};
|
||||
store = {
|
||||
dispatch: jest.fn(),
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
@@ -32,9 +37,7 @@ describe('AddPlaylistDialogComponent', () => {
|
||||
},
|
||||
{
|
||||
provide: Store,
|
||||
useValue: {
|
||||
dispatch: jest.fn(),
|
||||
},
|
||||
useValue: store,
|
||||
},
|
||||
{
|
||||
provide: MatSnackBar,
|
||||
@@ -102,4 +105,28 @@ describe('AddPlaylistDialogComponent', () => {
|
||||
);
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('strips playlist extensions from uploaded file titles', () => {
|
||||
component.handlePlaylist({
|
||||
uploadEvent: {
|
||||
target: {
|
||||
result: '#EXTM3U',
|
||||
},
|
||||
} as unknown as Event,
|
||||
file: {
|
||||
name: 'Local Source.m3u',
|
||||
path: '/tmp/Local Source.m3u',
|
||||
} as File,
|
||||
});
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
PlaylistActions.parsePlaylist({
|
||||
uploadType: 'FILE',
|
||||
playlist: '#EXTM3U',
|
||||
title: 'Local Source',
|
||||
path: '/tmp/Local Source.m3u',
|
||||
})
|
||||
);
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
+13
-1
@@ -122,7 +122,7 @@ export class AddPlaylistDialogComponent {
|
||||
PlaylistActions.parsePlaylist({
|
||||
uploadType: 'FILE',
|
||||
playlist,
|
||||
title: payload.file.name,
|
||||
title: this.normalizeImportedFileTitle(payload.file.name),
|
||||
path: (payload.file as File & { path?: string }).path,
|
||||
})
|
||||
);
|
||||
@@ -181,4 +181,16 @@ export class AddPlaylistDialogComponent {
|
||||
const normalizedValue = value?.trim();
|
||||
return normalizedValue ? normalizedValue : undefined;
|
||||
}
|
||||
|
||||
private normalizeImportedFileTitle(filename: string): string {
|
||||
const normalizedFilename = filename.trim();
|
||||
if (!normalizedFilename) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
return (
|
||||
normalizedFilename.replace(/\.(m3u8?|pls|txt)$/i, '') ||
|
||||
normalizedFilename
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -38,10 +38,21 @@ export class FileUploadComponent {
|
||||
}
|
||||
|
||||
onPicked(input: HTMLInputElement): void {
|
||||
const file = input.files?.[0];
|
||||
const file = input.files?.[0] as (File & { path?: string }) | undefined;
|
||||
const pathOverride = input.dataset['filePathOverride'];
|
||||
|
||||
if (file && !file.path && pathOverride) {
|
||||
Object.defineProperty(file, 'path', {
|
||||
configurable: true,
|
||||
value: pathOverride,
|
||||
});
|
||||
}
|
||||
|
||||
if (file) {
|
||||
this.setFile(file);
|
||||
}
|
||||
|
||||
delete input.dataset['filePathOverride'];
|
||||
input.value = '';
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user