Merge branch 'release/v0.18'

This commit is contained in:
Fergal Moran
2018-03-16 18:41:08 +00:00
241 changed files with 771 additions and 159 deletions

2
.gitignore vendored Normal file → Executable file
View File

@@ -5,3 +5,5 @@ promotion
.working .working
extension extension
client/tags client/tags
NYoutubeDL
tags

0
client/.angular-cli.json Normal file → Executable file
View File

0
client/.editorconfig Normal file → Executable file
View File

0
client/.gitignore vendored Normal file → Executable file
View File

0
client/.npmrc Normal file → Executable file
View File

0
client/.vscode/launch.json vendored Normal file → Executable file
View File

0
client/README.md Normal file → Executable file
View File

13
client/package-lock.json generated Normal file → Executable file
View File

@@ -1,6 +1,6 @@
{ {
"name": "pod-noms.web", "name": "pod-noms.web",
"version": "0.16.0", "version": "0.17.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -309,6 +309,12 @@
} }
} }
}, },
"@types/applicationinsights-js": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/applicationinsights-js/-/applicationinsights-js-1.0.5.tgz",
"integrity": "sha512-/obMaLeIWrL6FDYJC8v9VE2BrQJ2Y6iHgT/9UI6Xd30S/x0uDkJv/DGt1wMMJEmu+ShkR2KiR9L9OaJ1d91uoA==",
"dev": true
},
"@types/jasmine": { "@types/jasmine": {
"version": "2.8.6", "version": "2.8.6",
"resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz", "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz",
@@ -568,6 +574,11 @@
"default-require-extensions": "1.0.0" "default-require-extensions": "1.0.0"
} }
}, },
"applicationinsights-js": {
"version": "1.0.15",
"resolved": "https://registry.npmjs.org/applicationinsights-js/-/applicationinsights-js-1.0.15.tgz",
"integrity": "sha512-lxO7LOIkK38q3VE8covJMsGS3O04hPGgPaA8BmGyR3SYQhuIYX9qy14KMojqx239TlPR9YuPexVXTHdrGBATow=="
},
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",

4
client/package.json Normal file → Executable file
View File

@@ -1,6 +1,6 @@
{ {
"name": "pod-noms.web", "name": "pod-noms.web",
"version": "0.17.0", "version": "0.18.0",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
@@ -31,6 +31,7 @@
"@qontu/ngx-inline-editor": "^0.2.0-alpha.12", "@qontu/ngx-inline-editor": "^0.2.0-alpha.12",
"angular2-jwt": "^0.2.3", "angular2-jwt": "^0.2.3",
"angular2-moment": "^1.8.0", "angular2-moment": "^1.8.0",
"applicationinsights-js": "^1.0.15",
"auth0": "^2.9.1", "auth0": "^2.9.1",
"auth0-lock": "^11.3.1", "auth0-lock": "^11.3.1",
"bootstrap": "4.0.0", "bootstrap": "4.0.0",
@@ -54,6 +55,7 @@
"@angular/cli": "1.6.8", "@angular/cli": "1.6.8",
"@angular/compiler-cli": "^5.2.6", "@angular/compiler-cli": "^5.2.6",
"@angular/language-service": "^5.2.6", "@angular/language-service": "^5.2.6",
"@types/applicationinsights-js": "^1.0.5",
"@types/jasmine": "^2.8.6", "@types/jasmine": "^2.8.6",
"@types/node": "~9.4.6", "@types/node": "~9.4.6",
"codelyzer": "^4.2.1", "codelyzer": "^4.2.1",

0
client/src/app/actions/entries.actions.ts Normal file → Executable file
View File

0
client/src/app/actions/podcast.actions.ts Normal file → Executable file
View File

0
client/src/app/actions/profile.actions.ts Normal file → Executable file
View File

0
client/src/app/app.component.css Normal file → Executable file
View File

0
client/src/app/app.component.html Normal file → Executable file
View File

3
client/src/app/app.component.ts Normal file → Executable file
View File

@@ -2,6 +2,7 @@ import { GlobalsService } from './services/globals.service';
import { Component, HostBinding } from '@angular/core'; import { Component, HostBinding } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AuthService } from 'app/services/auth.service'; import { AuthService } from 'app/services/auth.service';
import { AppInsightsService } from 'app/services/app-insights.service';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@@ -9,7 +10,7 @@ import { AuthService } from 'app/services/auth.service';
styleUrls: ['./app.component.css'] styleUrls: ['./app.component.css']
}) })
export class AppComponent { export class AppComponent {
constructor(private _authService: AuthService) { constructor(private _authService: AuthService, _appInsights: AppInsightsService) {
_authService.handleAuthentication(); _authService.handleAuthentication();
_authService.scheduleRenewal(); _authService.scheduleRenewal();
} }

2
client/src/app/app.module.ts Normal file → Executable file
View File

@@ -49,6 +49,7 @@ import { ProfileComponent } from './components/profile/profile.component';
import { AboutComponent } from './components/about/about.component'; import { AboutComponent } from './components/about/about.component';
import { FooterComponent } from './components/footer/footer.component'; import { FooterComponent } from './components/footer/footer.component';
import { JobsService } from 'app/services/jobs.service'; import { JobsService } from 'app/services/jobs.service';
import { AppInsightsService } from 'app/services/app-insights.service';
export function authHttpServiceFactory(http: Http, options: RequestOptions) { export function authHttpServiceFactory(http: Http, options: RequestOptions) {
return new AuthHttp( return new AuthHttp(
@@ -123,6 +124,7 @@ export function authHttpServiceFactory(http: Http, options: RequestOptions) {
PodcastService, PodcastService,
ImageService, ImageService,
DebugService, DebugService,
AppInsightsService,
JobsService, JobsService,
GlobalsService GlobalsService
], ],

0
client/src/app/app.router.ts Normal file → Executable file
View File

0
client/src/app/components/about/about.component.css Normal file → Executable file
View File

0
client/src/app/components/about/about.component.html Normal file → Executable file
View File

0
client/src/app/components/about/about.component.ts Normal file → Executable file
View File

View File

View File

View File

0
client/src/app/components/debug/debug.component.css Normal file → Executable file
View File

4
client/src/app/components/debug/debug.component.html Normal file → Executable file
View File

@@ -28,6 +28,10 @@
<div class="block-content"> <div class="block-content">
<button class="btn btn-primary" <button class="btn btn-primary"
(click)="processOrphans()">Process Orphans</button> (click)="processOrphans()">Process Orphans</button>
<button class="btn btn-primary"
(click)="processPlaylists()">Process Playlists</button>
<button class="btn btn-primary"
(click)="updateYouTubeDl()">Update Youtube Downloader</button>
</div> </div>
</div> </div>
</div> </div>

64
client/src/app/components/debug/debug.component.ts Normal file → Executable file
View File

@@ -1,14 +1,14 @@
import { Observable } from 'rxjs/Observable'; import { Observable } from "rxjs/Observable";
import { SignalRService } from 'app/services/signalr.service'; import { SignalRService } from "app/services/signalr.service";
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from "@angular/core";
import { DebugService } from 'app/services/debug.service'; import { DebugService } from "app/services/debug.service";
import { environment } from 'environments/environment'; import { environment } from "environments/environment";
import { JobsService } from 'app/services/jobs.service'; import { JobsService } from "app/services/jobs.service";
@Component({ @Component({
selector: 'app-debug', selector: "app-debug",
templateUrl: './debug.component.html', templateUrl: "./debug.component.html",
styleUrls: ['./debug.component.css'] styleUrls: ["./debug.component.css"]
}) })
export class DebugComponent implements OnInit { export class DebugComponent implements OnInit {
realtimeMessage: string; realtimeMessage: string;
@@ -17,35 +17,59 @@ export class DebugComponent implements OnInit {
debugInfo$: Observable<string>; debugInfo$: Observable<string>;
apiHost = environment.API_HOST; apiHost = environment.API_HOST;
signalrHost = environment.SIGNALR_HOST; signalrHost = environment.SIGNALR_HOST;
pingPong = ''; pingPong = "";
constructor(private _debugService: DebugService, private _jobsService: JobsService, constructor(
private _signalrService: SignalRService) {} private _debugService: DebugService,
private _jobsService: JobsService,
private _signalrService: SignalRService
) {}
ngOnInit() { ngOnInit() {
this._signalrService this._signalrService
.init(`${environment.SIGNALR_HOST}hubs/debug`) .init(`${environment.SIGNALR_HOST}hubs/debug`)
.then(() => { .then(() => {
this._signalrService.connection.on('Send', data => { this._signalrService.connection.on("Send", data => {
console.log('DebugService', 'signalr', data); console.log("DebugService", "signalr", data);
this.messagesReceived.push(data); this.messagesReceived.push(data);
this.realtimeMessage = ''; this.realtimeMessage = "";
}); });
this.debugInfo$ = this._debugService.getDebugInfo(); this.debugInfo$ = this._debugService.getDebugInfo();
}) })
.catch(err => console.error('debug.component.ts', '_signalrService.init', err)); .catch(err =>
console.error("debug.component.ts", "_signalrService.init", err)
);
this._debugService.ping().subscribe(r => (this.pingPong = r)); this._debugService.ping().subscribe(r => (this.pingPong = r));
} }
sendMessage() { sendMessage() {
this._debugService.sendRealtime(this.realtimeMessage).subscribe(r => console.log(r)); this._debugService
.sendRealtime(this.realtimeMessage)
.subscribe(r => console.log(r));
} }
doSomething() { doSomething() {
alert('doSomething was did'); alert("doSomething was did");
} }
processOrphans() { processOrphans() {
this._jobsService.processOrphans() this._jobsService
.subscribe(e => console.log('debug.component.ts', 'processOrphans', e)); .processOrphans()
.subscribe(e =>
console.log("debug.component.ts", "processOrphans", e)
);
}
processPlaylists() {
this._jobsService
.processPlaylists()
.subscribe(e =>
console.log("debug.component.ts", "processPlaylists", e)
);
}
updateYouTubeDl() {
this._jobsService
.updateYouTubeDl()
.subscribe(e =>
console.log("debug.component.ts", "updateYouTubeDl", e)
);
} }
} }

0
client/src/app/components/footer/footer.component.css Normal file → Executable file
View File

0
client/src/app/components/footer/footer.component.html Normal file → Executable file
View File

0
client/src/app/components/footer/footer.component.ts Normal file → Executable file
View File

0
client/src/app/components/home/home.component.css Normal file → Executable file
View File

0
client/src/app/components/home/home.component.html Normal file → Executable file
View File

0
client/src/app/components/home/home.component.ts Normal file → Executable file
View File

0
client/src/app/components/login/login.component.css Normal file → Executable file
View File

0
client/src/app/components/login/login.component.html Normal file → Executable file
View File

0
client/src/app/components/login/login.component.ts Normal file → Executable file
View File

0
client/src/app/components/navbar/navbar.component.css Normal file → Executable file
View File

0
client/src/app/components/navbar/navbar.component.html Normal file → Executable file
View File

0
client/src/app/components/navbar/navbar.component.ts Normal file → Executable file
View File

View File

@@ -8,6 +8,7 @@ import {
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import { PodcastService } from 'app/services/podcast.service'; import { PodcastService } from 'app/services/podcast.service';
import { debounceTime } from 'rxjs/operator/debounceTime';
@Component({ @Component({
selector: 'app-podcast-add-url-form', selector: 'app-podcast-add-url-form',
@@ -41,7 +42,7 @@ export class PodcastAddUrlFormComponent implements AfterViewInit {
this._service.addEntry(entry).subscribe( this._service.addEntry(entry).subscribe(
e => { e => {
if (e) { if (e) {
if (e.ProcessingStatus == 6) { if (e.processingStatus == 6) {
this.onUploadDeferred.emit(e); this.onUploadDeferred.emit(e);
} else { } else {
this.onUrlAddComplete.emit(e); this.onUrlAddComplete.emit(e);

View File

View File

@@ -1,89 +1,68 @@
<div class="content" <div class="content" *ngIf="selectedPodcast$ | async; let podcast; else empty">
*ngIf="selectedPodcast$ | async; let podcast; else empty">
<div class="block"> <div class="block">
<div class="block-header block-header-default"> <div class="block-header block-header-default">
<h3 class="block-title">{{podcast.title}}</h3> <h3 class="block-title">{{podcast.title}}</h3>
<div class="block-options"> <div class="block-options">
<div class="btn-group" <div class="btn-group" role="group" aria-label="Podcast actions">
role="group" <a [routerLink]="['/podcasts', podcast.slug, 'edit']" class="btn btn-secondary btn-outline">
aria-label="Podcast actions"> <i class="icon-pencil" aria-hidden="true"></i> Edit
<a [routerLink]="['/podcasts', podcast.slug, 'edit']"
class="btn btn-secondary btn-outline">
<i class="icon-pencil"
aria-hidden="true"></i> Edit
</a> </a>
<a (click)="podcastDeleteDialog.show()" <a (click)="podcastDeleteDialog.show()" class="btn btn-secondary btn-outline-danger">
class="btn btn-secondary btn-outline-danger"> <i class="icon-close" aria-hidden="true"></i> Delete
<i class="icon-close"
aria-hidden="true"></i> Delete
</a> </a>
<a class="btn btn-secondary" <a class="btn btn-secondary" (click)="startAddEntry()">
(click)="startAddEntry()"><i class="icon-plus"></i> Add (from URL)</a> <i class="icon-plus"></i> Add (from URL)</a>
<a class="btn btn-secondary" <a class="btn btn-secondary" (click)="startUpload()">
(click)="startUpload()"><i class="icon-cloud-upload"></i> Upload (from computer)</a> <i class="icon-cloud-upload"></i> Upload (from computer)</a>
</div> </div>
<div class="btn-group" <div class="btn-group" role="group" aria-label="Podcast actions">
role="group" <a class="btn btn-secondary btn-outline-warning" [href]="podcast.rssUrl" target="_blank">
aria-label="Podcast actions">
<a class="btn btn-secondary btn-outline-warning"
[href]="podcast.rssUrl"
target="_blank">
<i class="text-warning fa fa-rss"></i> Rss Url <i class="text-warning fa fa-rss"></i> Rss Url
</a> </a>
<button class="btn btn-secondary btn-outline-warning" <button class="btn btn-secondary btn-outline-warning" ngxClipboard [cbContent]="podcast.rssUrl">
ngxClipboard
[cbContent]="podcast.rssUrl">
<i class="fa fa-copy"></i> <i class="fa fa-copy"></i>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<div class="block-content"> <div class="block-content">
<app-podcast-upload-form *ngIf="uploadMode" <app-podcast-upload-form *ngIf="uploadMode" [podcast]="podcast" (onUploadComplete)="onEntryUploadComplete($event)">
[podcast]="podcast"
(onUploadComplete)="onEntryUploadComplete($event)">
</app-podcast-upload-form> </app-podcast-upload-form>
<app-podcast-add-url-form *ngIf="urlMode" <app-podcast-add-url-form *ngIf="urlMode" [podcast]="podcast" (onUrlAddComplete)="onUrlAddComplete($event)" (onUploadDeferred)="onEntryUploadDeferred($event)">
[podcast]="podcast"
(onUrlAddComplete)="onUrlAddComplete($event)"
(onUploadDeferred)="onEntryUploadDeferred($event)">
</app-podcast-add-url-form> </app-podcast-add-url-form>
<div class="block block-themed" *ngIf="pendingEntry">
<div class="block-header bg-danger">
<h3 class="block-title">This looks like a playlist? Shall we add all items (please note, this may result in a lot of episodes being downloaded to your device).</h3>
<div class="block-options">
<button type="button" class="btn-block-option" (click)="processPlaylist()">
<i class="fa fa-check"></i>Yes
</button>
<button type="button" class="btn-block-option" (click)="dismissPlaylist()">
<i class="fa fa-times"></i>No
</button>
</div>
</div>
</div>
<table class="js-table-checkable table table-hover js-table-checkable-enabled"> <table class="js-table-checkable table table-hover js-table-checkable-enabled">
<tbody> <tbody>
<tr *ngFor="let e of entries$ | async | orderBy : '-id'" <tr *ngFor="let e of entries$ | async | orderBy : '-id'" app-entry-list-item (entryRemoved)='deleteEntry(e)' [entry]="e">
app-entry-list-item
(entryRemoved)='deleteEntry(e)'
[entry]="e">
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div class="modal fade" <div class="modal fade" bsModal #podcastDeleteDialog="bs-modal" tabindex="-1" role="dialog" aria-hidden="true">
bsModal
#podcastDeleteDialog="bs-modal"
tabindex="-1"
role="dialog"
aria-hidden="true">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title pull-left">Delete this podcast?</h4> <h4 class="modal-title pull-left">Delete this podcast?</h4>
<button type="button" <button type="button" class="close pull-right" aria-label="Close" (click)="podcastDeleteDialog.hide()">
class="close pull-right"
aria-label="Close"
(click)="podcastDeleteDialog.hide()">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<button type="button" <button type="button" class="btn btn-primary pull-right" (click)="podcastDeleteDialog.hide()">No
class="btn btn-primary pull-right"
(click)="podcastDeleteDialog.hide()">No
</button> </button>
<button type="button" <button type="button" class="btn btn-danger pull-right" (click)="deletePodcast(podcast); podcastDeleteDialog.hide()">Yes
class="btn btn-danger pull-right"
(click)="deletePodcast(podcast); podcastDeleteDialog.hide()">Yes
</button> </button>
</div> </div>
</div> </div>
@@ -98,8 +77,7 @@
</div> </div>
<div class="font-size-h4 font-w600">It's looking a bit empty here?</div> <div class="font-size-h4 font-w600">It's looking a bit empty here?</div>
<div class="pt-20"> <div class="pt-20">
<a class="btn btn-rounded btn-alt-primary" <a class="btn btn-rounded btn-alt-primary" [routerLink]="['/add']">
[routerLink]="['/add']">
<i class="fa fa-cog mr-5"></i> Add my first podcast <i class="fa fa-cog mr-5"></i> Add my first podcast
</a> </a>
</div> </div>

22
client/src/app/components/podcast/podcast.component.ts Normal file → Executable file
View File

@@ -13,6 +13,7 @@ import { UpdateAction, AddAction } from 'app/actions/entries.actions';
import * as fromPodcast from 'app/reducers'; import * as fromPodcast from 'app/reducers';
import * as fromPodcastActions from 'app/actions/podcast.actions'; import * as fromPodcastActions from 'app/actions/podcast.actions';
import * as fromEntriesActions from 'app/actions/entries.actions'; import * as fromEntriesActions from 'app/actions/entries.actions';
import { PodcastService } from 'app/services/podcast.service';
@Component({ @Component({
selector: 'app-podcast', selector: 'app-podcast',
@@ -21,6 +22,7 @@ import * as fromEntriesActions from 'app/actions/entries.actions';
}) })
export class PodcastComponent { export class PodcastComponent {
selectedPodcast$: Observable<PodcastModel>; selectedPodcast$: Observable<PodcastModel>;
pendingEntry: PodcastEntryModel = null;
entries$: Observable<PodcastEntryModel[]>; entries$: Observable<PodcastEntryModel[]>;
uploadMode = false; uploadMode = false;
urlMode = false; urlMode = false;
@@ -36,6 +38,8 @@ export class PodcastComponent {
constructor( constructor(
private _store: Store<ApplicationState>, private _store: Store<ApplicationState>,
private _service: PodcastService,
private _toasty: ToastyService,
route: ActivatedRoute, route: ActivatedRoute,
private _location: Location private _location: Location
) { ) {
@@ -88,11 +92,25 @@ export class PodcastComponent {
this._store.dispatch(new fromEntriesActions.AddSuccessAction(entry)); this._store.dispatch(new fromEntriesActions.AddSuccessAction(entry));
this._store.dispatch(new fromEntriesActions.UpdateAction(entry)); this._store.dispatch(new fromEntriesActions.UpdateAction(entry));
} }
onEntryUploadDeferred($event) { onEntryUploadDeferred(entry: PodcastEntryModel) {
this.pendingEntry = entry;
} }
onUrlAddComplete(entry: PodcastEntryModel) { onUrlAddComplete(entry: PodcastEntryModel) {
this.urlMode = false; this.urlMode = false;
this._store.dispatch(new fromEntriesActions.AddSuccessAction(entry)); this._store.dispatch(new fromEntriesActions.AddSuccessAction(entry));
} }
processPlaylist() {
if (this.pendingEntry) {
this._service.addPlaylist(this.pendingEntry)
.subscribe(e => {
if (e) {
this._toasty.info('Playlist added, check back here (and on your device) for new episodes');
}
});
}
}
dismissPlaylist() {
this.urlMode = false;
this.pendingEntry = null;
}
} }

View File

View File

0
client/src/app/components/profile/profile.component.ts Normal file → Executable file
View File

View File

View File

View File

0
client/src/app/components/reset/reset.component.css Normal file → Executable file
View File

0
client/src/app/components/reset/reset.component.html Normal file → Executable file
View File

0
client/src/app/components/reset/reset.component.ts Normal file → Executable file
View File

View File

View File

View File

View File

View File

View File

View File

View File

0
client/src/app/components/sidebar/sidebar.component.ts Normal file → Executable file
View File

0
client/src/app/effects/entries.effects.ts Normal file → Executable file
View File

0
client/src/app/effects/podcast.effects.ts Normal file → Executable file
View File

0
client/src/app/effects/profile.effects.ts Normal file → Executable file
View File

0
client/src/app/models/podcasts.models.ts Normal file → Executable file
View File

0
client/src/app/models/profile.model.ts Normal file → Executable file
View File

0
client/src/app/pipes/filter-entry.pipe.ts Normal file → Executable file
View File

0
client/src/app/pipes/order-by.pipe.ts Normal file → Executable file
View File

0
client/src/app/pipes/pretty-print.pipe.ts Normal file → Executable file
View File

0
client/src/app/pipes/safe.util.ts Normal file → Executable file
View File

0
client/src/app/reducers/entries.reducer.ts Normal file → Executable file
View File

0
client/src/app/reducers/index.ts Normal file → Executable file
View File

0
client/src/app/reducers/podcasts.reducer.ts Normal file → Executable file
View File

0
client/src/app/reducers/profile.reducer.ts Normal file → Executable file
View File

View File

@@ -0,0 +1,16 @@
import { Injectable } from '@angular/core';
import { AppInsights } from 'applicationinsights-js';
import { environment } from 'environments/environment';
@Injectable()
export class AppInsightsService {
private config: Microsoft.ApplicationInsights.IConfig = {
instrumentationKey: environment.appInsights.instrumentationKey
};
constructor() {
if (!AppInsights.config){
AppInsights.downloadAndSetup(this.config);
}
}
}

0
client/src/app/services/auth.guard.ts Normal file → Executable file
View File

0
client/src/app/services/auth.service.ts Normal file → Executable file
View File

0
client/src/app/services/debug.service.ts Normal file → Executable file
View File

0
client/src/app/services/entries.service.ts Normal file → Executable file
View File

0
client/src/app/services/globals.service.ts Normal file → Executable file
View File

0
client/src/app/services/image.service.ts Normal file → Executable file
View File

7
client/src/app/services/jobs.service.ts Normal file → Executable file
View File

@@ -11,4 +11,11 @@ export class JobsService {
processOrphans(): Observable<Response> { processOrphans(): Observable<Response> {
return this._http.get(environment.API_HOST + '/job/processorphans'); return this._http.get(environment.API_HOST + '/job/processorphans');
} }
processPlaylists(): Observable<Response> {
return this._http.get(environment.API_HOST + '/job/processplaylists');
}
updateYouTubeDl(): Observable<Response> {
return this._http.get(environment.API_HOST + '/job/updateyoutubedl');
}
} }

8
client/src/app/services/podcast.service.ts Normal file → Executable file
View File

@@ -72,4 +72,12 @@ export class PodcastService {
.map(res => res.json()); .map(res => res.json());
} }
//#endregion //#endregion
//#region Playlists
addPlaylist(entry: PodcastEntryModel) {
return this._http
.post(environment.API_HOST + '/playlist', JSON.stringify(entry))
.map(res => res.json());
}
//#endregion
} }

0
client/src/app/services/profile.service.ts Normal file → Executable file
View File

0
client/src/app/services/pusher.service.ts Normal file → Executable file
View File

0
client/src/app/services/signalr.service.ts Normal file → Executable file
View File

0
client/src/app/store/index.ts Normal file → Executable file
View File

0
client/src/assets/.gitkeep Normal file → Executable file
View File

0
client/src/assets/css/style.css Normal file → Executable file
View File

0
client/src/assets/img/logo-icon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Some files were not shown because too many files have changed in this diff Show More