feat: import playlist as text

This commit is contained in:
4gray committed 2022-08-07 20:04:36 +02:00
1 parent 37f71c631e
commit 6676fa0a42
12 files changed
+153 -3

No files matched your search

+22
View File
@@ -19,6 +19,7 @@ import {
PLAYLIST_PARSE,
PLAYLIST_PARSE_BY_URL,
PLAYLIST_PARSE_RESPONSE,
PLAYLIST_PARSE_TEXT,
PLAYLIST_REMOVE_BY_ID,
PLAYLIST_REMOVE_BY_ID_RESPONSE,
PLAYLIST_SAVE_DETAILS,
@@ -91,6 +92,27 @@ export class Api {
}
});
ipcMain.on(PLAYLIST_PARSE_TEXT, (event, args) => {
try {
const parsedPlaylist = this.parsePlaylist(
args.text.split('\n')
);
const playlistObject = this.createPlaylistObject(
'Imported as text',
parsedPlaylist
);
this.insertToDb(playlistObject);
event.sender.send(PLAYLIST_PARSE_RESPONSE, {
payload: playlistObject,
});
} catch (err) {
event.sender.send(ERROR, {
message: err.response.statusText,
status: err.response.status,
});
}
});
ipcMain.on(PLAYLIST_PARSE, (event, args) => {
const parsedPlaylist = this.parsePlaylist(args.playlist);
const playlistObject = this.createPlaylistObject(
+1
View File
@@ -14,6 +14,7 @@ export const PLAYLIST_GET_BY_ID = 'PLAYLIST:GET_BY_ID';
export const PLAYLIST_SAVE_DETAILS = 'PLAYLIST:SAVE_DETAILS';
export const PLAYLIST_PARSE = 'PLAYLIST:PARSE_PLAYLIST';
export const PLAYLIST_PARSE_BY_URL = 'PLAYLIST:PARSE_PLAYLIST_BY_URL';
export const PLAYLIST_PARSE_TEXT = 'PLAYLIST:PLAYLIST_PARSE_TEXT';
export const PLAYLIST_PARSE_RESPONSE = 'PLAYLIST:PARSE_PLAYLIST_RESPONSE';
export const PLAYLIST_UPDATE = 'PLAYLIST:UPDATE';
export const PLAYLIST_UPDATE_RESPONSE = 'PLAYLIST:UPDATE_RESPONSE';
+11
View File
@@ -43,6 +43,17 @@
></app-url-upload>
</ng-template>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon class="tab-icon">text_format</mat-icon>
{{ 'HOME.TABS.TEXT_IMPORT' | translate }}
</ng-template>
<ng-template matTabContent>
<app-text-import
(textAdded)="uploadAsText($event)"
></app-text-import>
</ng-template>
</mat-tab>
</mat-tab-group>
<!-- Loading spinner -->
+12
View File
@@ -7,6 +7,7 @@ import {
PLAYLIST_PARSE,
PLAYLIST_PARSE_BY_URL,
PLAYLIST_PARSE_RESPONSE,
PLAYLIST_PARSE_TEXT,
PLAYLIST_UPDATE_RESPONSE,
} from '../../../shared/ipc-commands';
import { Playlist } from '../../../shared/playlist.interface';
@@ -154,6 +155,17 @@ export class HomeComponent {
});
}
/**
* Sends IPC event to the renderer process to parse playlist
* @param text playlist as string
*/
uploadAsText(text: string): void {
this.isLoading = true;
this.electronService.sendIpcEvent(PLAYLIST_PARSE_TEXT, {
text,
});
}
/**
* Returns last segment (part after last slash "/") of the given URL
* @param value URL as string
+2
View File
@@ -6,6 +6,7 @@ import { FileUploadComponent } from './file-upload/file-upload.component';
import { HomeComponent } from './home.component';
import { HomeRoutingModule } from './home.routing';
import { PlaylistInfoComponent } from './recent-playlists/playlist-info/playlist-info.component';
import { TextImportComponent } from './text-import/text-import.component';
import { UrlUploadComponent } from './url-upload/url-upload.component';
@NgModule({
@@ -14,6 +15,7 @@ import { UrlUploadComponent } from './url-upload/url-upload.component';
HomeComponent,
FileUploadComponent,
PlaylistInfoComponent,
TextImportComponent,
UrlUploadComponent,
],
})
@@ -11,9 +11,11 @@
(click)="getPlaylist('GLOBAL_FAVORITES')"
>
<mat-icon class="favorites-icon" mat-list-icon>star</mat-icon>
<div mat-line>Global favorites</div>
<div mat-line>
{{ 'HOME.PLAYLISTS.GLOBAL_FAVORITES_DESCRIPTION' | translate }}
</div>
<div mat-line class="meta">
Auto-generated playlist with aggregated favorites from all playlists
{{ 'HOME.PLAYLISTS.GLOBAL_FAVORITES' | translate }}
</div>
<mat-divider></mat-divider>
</mat-list-item>
@@ -0,0 +1,18 @@
<form (ngSubmit)="textAdded.emit(textForm.value.text)" [formGroup]="textForm">
<mat-form-field class="full-width" appearance="fill">
<mat-label>{{ 'HOME.TEXT_IMPORT.LABEL' | translate }}</mat-label>
<textarea
formControlName="text"
matInput
placeholder="#EXTM3U url-tvg=..."
></textarea>
</mat-form-field>
<button
mat-flat-button
color="primary"
type="submit"
[disabled]="!textForm.valid"
>
{{ 'HOME.TEXT_IMPORT.BUTTON_LABEL' | translate }}
</button>
</form>
@@ -0,0 +1,8 @@
button {
margin: 15px;
text-transform: uppercase;
}
textarea {
height: calc(100vh - 300px);
}
@@ -0,0 +1,30 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MatInputModule } from '@angular/material/input';
import { TranslatePipe } from '@ngx-translate/core';
import { MockModule, MockPipe } from 'ng-mocks';
import { TextImportComponent } from './text-import.component';
describe('TextImportComponent', () => {
let component: TextImportComponent;
let fixture: ComponentFixture<TextImportComponent>;
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [TextImportComponent, MockPipe(TranslatePipe)],
imports: [MockModule(MatInputModule)],
}).compileComponents();
})
);
beforeEach(() => {
fixture = TestBed.createComponent(TextImportComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,15 @@
import { Component, EventEmitter, Output } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-text-import',
templateUrl: './text-import.component.html',
styleUrls: ['./text-import.component.scss'],
})
export class TextImportComponent {
@Output() textAdded = new EventEmitter<string>();
textForm = new FormGroup({
text: new FormControl('', Validators.required),
});
}
@@ -28,7 +28,7 @@
{{ playlistTitle$ | async }}
</ng-container>
<ng-template #allPlaylists>
My Playlists
{{ 'HOME.PLAYLISTS.MY_PLAYLISTS' | translate }}
</ng-template>
</div>
<div class="channels-count">
+29
View File
@@ -13,6 +13,7 @@ import {
PLAYLIST_PARSE,
PLAYLIST_PARSE_BY_URL,
PLAYLIST_PARSE_RESPONSE,
PLAYLIST_PARSE_TEXT,
PLAYLIST_REMOVE_BY_ID,
PLAYLIST_REMOVE_BY_ID_RESPONSE,
PLAYLIST_SAVE_DETAILS,
@@ -150,6 +151,34 @@ export class PwaService extends DataService {
payload: playlist,
});
});
} else if (type === PLAYLIST_PARSE_TEXT) {
try {
const parsedPlaylist = this.parsePlaylist(
payload.text.split('\n')
);
const playlistObject = this.createPlaylistObject(
'Imported as text',
parsedPlaylist
);
// save to db
this.dbService
.add(DbStores.Playlists, playlistObject)
.subscribe(() => {
console.log('playlist was saved to db...');
});
window.postMessage({
type: PLAYLIST_PARSE_RESPONSE,
payload: playlistObject,
});
} catch (error) {
window.postMessage({
type: ERROR,
status: '',
message: 'Validation error - invalid playlist',
});
}
} else if (type === PLAYLIST_GET_ALL) {
this.dbService
.getAll(DbStores.Playlists)