Skip to content

Commit

Permalink
feat(item): add play and download button in the item page
Browse files Browse the repository at this point in the history
  • Loading branch information
davinkevin committed May 31, 2018
1 parent 170c416 commit 3de5b2d
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 10 deletions.
8 changes: 7 additions & 1 deletion frontend-angular/src/app/app.actions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {Action} from '@ngrx/store';
import { uuid } from '#app/shared/entity';

export enum AppAction {
OPEN_SIDE_NAV = '[SideNav] Open SideNav',
CLOSE_SIDE_NAV = '[SideNav] Close SideNav'
CLOSE_SIDE_NAV = '[SideNav] Close SideNav',
DOWNLOAD_ITEM = '[Download] Download item',
}

export class OpenSideNavAction implements Action {
Expand All @@ -11,6 +13,10 @@ export class OpenSideNavAction implements Action {
export class CloseSideNavAction implements Action {
readonly type = AppAction.CLOSE_SIDE_NAV;
}
export class DownloadItemAction implements Action {
readonly type = AppAction.DOWNLOAD_ITEM;
constructor(public itemId: uuid, public podcastId: uuid) {}
}

export type AppActions
= OpenSideNavAction
Expand Down
12 changes: 10 additions & 2 deletions frontend-angular/src/app/app.effects.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { map } from 'rxjs/operators';
import { concatMap, map, switchMap } from 'rxjs/operators';
import { CloseSideNavAction } from './app.actions';
import { ROUTER_NAVIGATION } from '@ngrx/router-store';
import { AppAction, DownloadItemAction } from '#app/app.actions';
import { ItemService } from '#app/shared/service/item/item.service';

@Injectable()
export class AppEffects {
Expand All @@ -13,5 +15,11 @@ export class AppEffects {
map(() => new CloseSideNavAction())
);

constructor(private actions$: Actions) {}
@Effect({ dispatch: false })
downloadItem = this.actions$.pipe(
ofType(AppAction.DOWNLOAD_ITEM),
concatMap(({itemId, podcastId}: DownloadItemAction) => this.itemService.download(itemId, podcastId)),
);

constructor(private actions$: Actions, private itemService: ItemService) {}
}
14 changes: 14 additions & 0 deletions frontend-angular/src/app/item/item.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@
</div>
</div>

<div class="item__actions_button">
<button mat-raised-button color="primary" (click)="play()" *ngIf="isPlayable(item)">
<mat-icon>play_arrow</mat-icon>
Play
</button>
<button mat-raised-button color="primary" (click)="download()" *ngIf="isDownloadable(item)" >
<mat-icon>file_download</mat-icon>
Download
</button>

</div>

<mat-divider></mat-divider>

<p class="item__description">
{{item.description}}
</p>
Expand Down
12 changes: 11 additions & 1 deletion frontend-angular/src/app/item/item.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@
& mat-icon {
cursor: pointer;
}
}}
}
}

.item__actions_button {
padding: 16px;
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
align-content: center;
}

.item__description {
text-align: justify;
Expand Down
18 changes: 15 additions & 3 deletions frontend-angular/src/app/item/item.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { select, Store } from '@ngrx/store';

import { AppState } from '../app.reducer';
import { Item } from '../shared/entity';
import { CompanionComponent } from '@davinkevin/companion-component';
import { item } from '#app/item/item.reducer';
import { LocationBackAction } from '@davinkevin/router-store-helper';
import { PlayAction } from '#app/floating-player/floating-player.actions';
import { DownloadItemAction } from '#app/app.actions';
import { isDownloadable as IsDownloadable, isPlayable as IsPlayable } from '#app/shared/service/item/item.service';

@Component({
selector: 'ps-item',
Expand All @@ -15,6 +17,8 @@ import { LocationBackAction } from '@davinkevin/router-store-helper';
})
export class ItemComponent implements OnInit, OnDestroy {
item: Item;
isDownloadable: (item: Item) => boolean = IsDownloadable;
isPlayable: (item: Item) => boolean = IsPlayable;

private companion = new CompanionComponent();

Expand All @@ -26,9 +30,17 @@ export class ItemComponent implements OnInit, OnDestroy {
this.store.pipe(select(item), untilDestroy()).subscribe(v => (this.item = v));
}

play(): void {
this.store.dispatch(new PlayAction(this.item));
}

download(): void {
this.store.dispatch(new DownloadItemAction(this.item.id, this.item.podcastId));
}

back(): void {
this.store.dispatch(new LocationBackAction());
}
this.store.dispatch(new LocationBackAction());
}

ngOnDestroy(): void {
this.companion.destroy();
Expand Down
7 changes: 5 additions & 2 deletions frontend-angular/src/app/item/item.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatDividerModule, MatIconModule, MatListModule } from '@angular/material';
import { MatButtonModule, MatDividerModule, MatIconModule, MatListModule } from '@angular/material';
import { RouterModule, Routes } from '@angular/router';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
Expand All @@ -18,7 +18,10 @@ const routes: Routes = [{ path: 'podcasts/:podcastId/items/:id', component: Item
imports: [
CommonModule,
RouterModule.forChild(routes),
MatIconModule, MatDividerModule, MatListModule,
MatIconModule,
MatDividerModule,
MatListModule,
MatButtonModule,
SharedModule,

StoreModule.forFeature('item', itemReducer),
Expand Down
17 changes: 16 additions & 1 deletion frontend-angular/src/app/shared/service/item/item.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Direction, Item, Page, Pageable, SearchItemPageRequest, uuid } from '../../entity';
import { Direction, Item, Page, Pageable, SearchItemPageRequest, Status, uuid } from '../../entity';
import { HttpClient, HttpParams } from '@angular/common/http';

@Injectable()
Expand All @@ -20,6 +20,10 @@ export class ItemService {
findById(itemId: uuid, podcastId: uuid): Observable<Item> {
return this.http.get<Item>(`/api/podcasts/${podcastId}/items/${itemId}`);
}

download(itemId: uuid, podcastId: uuid): Observable<void> {
return this.http.get<void>(`/api/podcasts/${podcastId}/items/${itemId}/addtoqueue`);
}
}

function toSearchParams(request: SearchItemPageRequest): HttpParams {
Expand Down Expand Up @@ -51,3 +55,14 @@ export const defaultSearch: SearchItemPageRequest = {
tags: [],
sort: [{ property: 'pubDate', direction: Direction.DESC }]
};

export function isDownloadable(item: Item): boolean {
return item.status === Status.NOT_DOWNLOADED
|| item.status === Status.DELETED
|| item.status === Status.STOPPED
|| item.status === Status.FAILED
}

export function isPlayable(item: Item): boolean {
return item.status === Status.FINISH;
}

0 comments on commit 3de5b2d

Please sign in to comment.