Skip to content

Commit

Permalink
Adjust stream constructions and remove most template function calls (#29
Browse files Browse the repository at this point in the history
)

* refactor: adjust stream constructions and remove most template call

* feat: update getPlaylistsWithRouteUrl selector

Co-authored-by: Trung Vo <[email protected]>
  • Loading branch information
nartc and trungvose authored Apr 2, 2021
1 parent 31e3efd commit aac5ad0
Show file tree
Hide file tree
Showing 18 changed files with 127 additions and 76 deletions.
18 changes: 9 additions & 9 deletions apps/angular-spotify/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { Component } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter } from 'rxjs/operators';
import { environment } from '../environments/environment';
import { GoogleAnalyticsService } from './google-analytics.service';

@Component({
selector: 'angular-spotify-root',
template: `<router-outlet></router-outlet>`,
template: ` <router-outlet></router-outlet>`,
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private router: Router, private googleAnalytics: GoogleAnalyticsService) {
if (environment.production) {
this.router.events.subscribe(this.handleGoogleAnalytics);
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd))
.subscribe((navigationEndEvent) => {
this.googleAnalytics.sendPageView(
(navigationEndEvent as NavigationEnd).urlAfterRedirects
);
});
}
}

handleGoogleAnalytics = (event: any): void => {
// eslint-disable-line
if (event instanceof NavigationEnd) {
this.googleAnalytics.sendPageView(event.urlAfterRedirects);
}
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AuthStore } from '@angular-spotify/web/auth/data-access';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { NzModalRef } from 'ng-zorro-antd/modal';
import { AuthStore } from '@angular-spotify/web/auth/data-access';

@Component({
templateUrl: './unauthorized-modal.component.html',
styleUrls: ['./unauthorized-modal.component.scss'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { RouteUtil } from '@angular-spotify/web/shared/utils';
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { featuredPlaylistsFeatureKey, FeaturePlaylistsState } from './feature-playlists.reducer';

Expand All @@ -8,3 +9,23 @@ export const getFeaturePlaylistsState = createFeatureSelector<FeaturePlaylistsSt
export const getFeaturedPlaylists = createSelector(getFeaturePlaylistsState, ({ data }) => {
return data;
});

export const getFeaturedPlaylistsWithRouteUrl = createSelector(
getFeaturedPlaylists,
(featuredPlaylists) => {
if (featuredPlaylists) {
return {
...featuredPlaylists,
playlists: {
...featuredPlaylists.playlists,
items: featuredPlaylists.playlists.items.map((item) => ({
...item,
routeUrl: RouteUtil.getPlaylistRouteUrl(item)
}))
}
};
}

return featuredPlaylists;
}
);
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<ng-container *ngIf="featuredPlaylists$ | async as data">
<h2 class="mt-8 mb-4 text-2xl text-white">{{ data.message }}</h2>
<div class="common-grid">
<as-media *ngFor="let playlist of data.playlists.items"
[title]="playlist.name"
[description]="playlist.description"
[imageUrl]="playlist.images[0]?.url!"
[uri]="playlist.uri"
[routerUrl]="getPlaylistRouteUrl(playlist)"
(togglePlay)="togglePlay($event, playlist.uri)">
<as-media
*ngFor="let playlist of data.playlists.items"
[title]="playlist.name"
[description]="playlist.description"
[imageUrl]="playlist.images[0]?.url!"
[uri]="playlist.uri"
[routerUrl]="playlist.routeUrl"
(togglePlay)="togglePlay($event, playlist.uri)"
>
</as-media>
</div>
</ng-container>
</ng-container>
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { getFeaturedPlaylists } from '@angular-spotify/web/home/data-access';
import { getFeaturedPlaylistsWithRouteUrl } from '@angular-spotify/web/home/data-access';
import { PlayerApiService } from '@angular-spotify/web/shared/data-access/spotify-api';
import { RouteUtil } from '@angular-spotify/web/shared/utils';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { select, Store } from '@ngrx/store';

Expand All @@ -11,20 +10,15 @@ import { select, Store } from '@ngrx/store';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class FeaturedPlaylistsComponent {
featuredPlaylists$ = this.store.pipe(select(getFeaturedPlaylists));
featuredPlaylists$ = this.store.pipe(select(getFeaturedPlaylistsWithRouteUrl));

constructor(private store: Store, private playerApi: PlayerApiService) {}


togglePlay(isPlaying: boolean, playlistUri: string) {
this.playerApi
.togglePlay(isPlaying, {
context_uri: playlistUri
})
.subscribe();
}

getPlaylistRouteUrl(playlist: SpotifyApi.PlaylistObjectSimplified) {
return RouteUtil.getPlaylistRouteUrl(playlist);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import { RouteUtil, SelectorUtil } from '@angular-spotify/web/shared/utils';
import { createFeatureSelector, createSelector } from '@ngrx/store';
import { SelectorUtil } from '@angular-spotify/web/shared/utils';
import { playlistsFeatureKey, PlaylistsState } from './playlists.reducer';

export const getPlaylistsState = createFeatureSelector<PlaylistsState>(playlistsFeatureKey);
export const getPlaylists = createSelector(getPlaylistsState, (state) => state.data);
export const getPlaylistsWithRouteUrl = createSelector(getPlaylists, (playlists) => {
if (playlists) {
return {
...playlists,
items: playlists.items.map((item) => ({
...item,
routeUrl: RouteUtil.getPlaylistRouteUrl(item)
}))
};
}
return playlists;
});
export const getPlaylistsLoading = createSelector(getPlaylistsState, SelectorUtil.isLoading);
export const getPlaylistsDone = createSelector(getPlaylistsState, SelectorUtil.isDone);
export const getPlaylistsMap = createSelector(getPlaylistsState, (state) => state.map);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[uri]="playlist.uri"
[description]="playlist.description"
[imageUrl]="playlist.images[0]?.url"
[routerUrl]="getPlaylistRouteUrl(playlist)"
[routerUrl]="playlist.routeUrl"
(togglePlay)="togglePlay($event, playlist.uri)"
>
</as-media>
Expand Down
10 changes: 3 additions & 7 deletions libs/web/playlist/feature/list/src/lib/playlists.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PlayerApiService } from '@angular-spotify/web/shared/data-access/spotif
import { RouteUtil } from '@angular-spotify/web/shared/utils';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { select, Store } from '@ngrx/store';
import { getPlaylists, getPlaylistsLoading } from '@angular-spotify/web/playlist/data-access';
import { getPlaylists, getPlaylistsLoading, getPlaylistsWithRouteUrl } from '@angular-spotify/web/playlist/data-access';

@Component({
selector: 'as-playlists',
Expand All @@ -11,14 +11,10 @@ import { getPlaylists, getPlaylistsLoading } from '@angular-spotify/web/playlist
changeDetection: ChangeDetectionStrategy.OnPush
})
export class PlaylistsComponent {
playlists$ = this.store.pipe(select(getPlaylists));
playlists$ = this.store.pipe(select(getPlaylistsWithRouteUrl));
isPlaylistsLoading$ = this.store.pipe(select(getPlaylistsLoading));

constructor(private store: Store, private playerApi: PlayerApiService) {
}

getPlaylistRouteUrl(playlist: SpotifyApi.PlaylistObjectSimplified) {
return RouteUtil.getPlaylistRouteUrl(playlist);
constructor(private store: Store, private playerApi: PlayerApiService) {
}

togglePlay(isPlaying: boolean, contextUri: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
<ng-container *ngrxLet="isTrackPlaying$ as isPlaying">
<as-media-order [index]="index" [isPlaying]="isPlaying!" (togglePlay)="togglePlayTrack($event)">
</as-media-order>
<as-track-main-info [track]="item.track" [isPlaying]="isPlaying"> </as-track-main-info>
<as-track-main-info [track]="item.track" [isPlaying]="isPlaying"></as-track-main-info>
</ng-container>
<a
class="text-description link-subtle hover:underline"
[routerLink]="getAlbumRouteUrl(item.track.album)"
>
<a class="text-description link-subtle hover:underline" [routerLink]="albumRouteUrl">
{{ item.track.album.name }}
</a>
<div class="text-description" [title]="item.added_at | date: 'medium'">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { Component, OnInit, ChangeDetectionStrategy, Input, ViewEncapsulation } from '@angular/core';
import { combineLatest, Observable, of } from 'rxjs';
import { PlayerApiService } from '@angular-spotify/web/shared/data-access/spotify-api';
import { PlaybackStore } from '@angular-spotify/web/shared/data-access/store';
import { RouteUtil, SelectorUtil } from '@angular-spotify/web/shared/utils';
import { PlayerApiService } from '@angular-spotify/web/shared/data-access/spotify-api';
import {
ChangeDetectionStrategy,
Component,
Input,
OnInit,
ViewEncapsulation
} from '@angular/core';
import { combineLatest, Observable, of } from 'rxjs';

@Component({
selector: 'as-playlist-track',
templateUrl: './playlist-track.component.html',
Expand All @@ -11,16 +18,31 @@ import { PlayerApiService } from '@angular-spotify/web/shared/data-access/spotif
encapsulation: ViewEncapsulation.None
})
export class PlaylistTrackComponent implements OnInit {
get item(): SpotifyApi.PlaylistTrackObject | undefined {
return this._item;
}

@Input()
set item(value: SpotifyApi.PlaylistTrackObject | undefined) {
this._item = value;
if (value?.track) {
this.albumRouteUrl = RouteUtil.getAlbumRouteUrl(value.track.album.id);
}
}

private _item: SpotifyApi.PlaylistTrackObject | undefined;

@Input() index!: number;
@Input() contextUri!: string | null;
@Input() item: SpotifyApi.PlaylistTrackObject | undefined;

isTrackPlaying$!: Observable<boolean>;
albumRouteUrl?: string;

constructor(private playbackStore: PlaybackStore, private playerApi: PlayerApiService) {}

ngOnInit(): void {
this.isTrackPlaying$ = SelectorUtil.getTrackPlayingState(
combineLatest([of(this.item?.track.id), this.playbackStore.playback$])
combineLatest([of(this._item?.track.id), this.playbackStore.playback$])
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="spotify-web-playback-sdk" />
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { RouteUtil, StringUtil } from '@angular-spotify/web/shared/utils';
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

@Component({
selector: 'as-track-current-info',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<div id="bg-overlay"
*ngIf="albumBackgroundImage$ | async as bgUrl"
[style.background-image]="bgUrl">
</div>
<div
id="bg-overlay"
*ngIf="albumBackgroundImage$ | async as bgUrl"
[style.background-image]="bgUrl"
></div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { PlaybackStore } from '@angular-spotify/web/shared/data-access/store';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { map } from 'rxjs/operators';

@Component({
Expand All @@ -15,10 +15,9 @@ export class AlbumArtOverlayComponent {
return null;
}
const imageUrl = track.album.images[0]?.url;
return imageUrl ? `url(${imageUrl})` : null
return imageUrl ? `url(${imageUrl})` : null;
})
);

constructor(private playbackStore: PlaybackStore) {
}
constructor(private playbackStore: PlaybackStore) {}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<a
[routerLink]="getPlaylistRouteUrl(playlist)"
[routerLink]="playlistWithRoute.routeUrl"
*ngrxLet="isPlaylistPlaying$ as isPlaying"
routerLinkActive="active"
[title]="playlist.name"
[title]="playlistWithRoute.name"
class="playlist-link link-subtle"
>
<span class="ellipsis-one-line">
{{ playlist.name }}
{{ playlistWithRoute.name }}
</span>
<as-play-button
*ngIf="isPlaying"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PlayerApiService } from '@angular-spotify/web/shared/data-access/spotify-api';
import { PlaybackStore } from '@angular-spotify/web/shared/data-access/store';
import { RouteUtil, SelectorUtil } from '@angular-spotify/web/shared/utils';
import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { combineLatest, Observable, of } from 'rxjs';

@Component({
Expand All @@ -11,25 +11,26 @@ import { combineLatest, Observable, of } from 'rxjs';
changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavPlaylistComponent implements OnInit {
@Input() playlist!: SpotifyApi.PlaylistObjectSimplified;
@Input()
set playlist(value: SpotifyApi.PlaylistObjectSimplified) {
this.playlistWithRoute = { ...value, routeUrl: RouteUtil.getPlaylistRouteUrl(value) };
}

playlistWithRoute!: SpotifyApi.PlaylistObjectSimplified & { routeUrl: string };
isPlaylistPlaying$!: Observable<boolean>;

constructor(private playbackStore: PlaybackStore, private playerApi: PlayerApiService) {}

ngOnInit(): void {
this.isPlaylistPlaying$ = SelectorUtil.getMediaPlayingState(
combineLatest([of(this.playlist?.uri), this.playbackStore.playback$])
combineLatest([of(this.playlistWithRoute?.uri), this.playbackStore.playback$])
);
}

getPlaylistRouteUrl(playlist: SpotifyApi.PlaylistObjectSimplified) {
return RouteUtil.getPlaylistRouteUrl(playlist);
}

togglePlaylist(isPlaying: boolean) {
this.playerApi
.togglePlay(isPlaying, {
context_uri: this.playlist?.uri
context_uri: this.playlistWithRoute?.uri
})
.subscribe(); //TODO: Refactor with component store live stream
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
VolumeHighIcon,

VolumeMediumIcon,
VolumeMuteIcon
} from '@angular-spotify/web/shared/data-access/models';
Expand All @@ -10,6 +9,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { NzSliderValue } from 'ng-zorro-antd/slider';
import { Subject } from 'rxjs';
import { debounceTime, map, switchMap } from 'rxjs/operators';

@UntilDestroy()
@Component({
selector: 'as-player-volume',
Expand All @@ -25,11 +25,11 @@ export class PlayerVolumeComponent {
map((volume) => {
if (volume >= 70) {
return new VolumeHighIcon(volume);
} else if (volume > 0) {
}
if (volume > 0) {
return new VolumeMediumIcon(volume);
} else {
return new VolumeMuteIcon();
}
return new VolumeMuteIcon();
})
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { UserDropdownStore } from './user-dropdown.store';
export class UserDropdownComponent {
userName$ = this.store.userName$;
userAvatar$ = this.store.userAvatar$;
constructor(private store: UserDropdownStore) {

}

constructor(private store: UserDropdownStore) {}
}
Loading

0 comments on commit aac5ad0

Please sign in to comment.