From ba41c8dae5e82bd1f39fb9a6cd8518e25dcdb894 Mon Sep 17 00:00:00 2001 From: 4gray <4gray@users.noreply.github.com> Date: Tue, 28 Feb 2023 22:16:14 +0100 Subject: [PATCH] feat: draggable channels in favorites list --- .../channel-list-container.component.html | 36 +++++++++---------- .../channel-list-container.component.ts | 21 ++++++++--- .../channel-list-item.component.scss | 5 +++ .../channel-list-item.component.ts | 11 ++++++ src/app/services/playlists.service.ts | 11 ++++++ src/app/shared/shared.module.ts | 1 + src/app/state/actions.ts | 5 +++ src/app/state/effects.ts | 18 ++++++++++ src/app/state/reducers.ts | 16 +++++++++ 9 files changed, 101 insertions(+), 23 deletions(-) diff --git a/src/app/player/components/channel-list-container/channel-list-container.component.html b/src/app/player/components/channel-list-container/channel-list-container.component.html index cae62441d..ed17752f3 100644 --- a/src/app/player/components/channel-list-container/channel-list-container.component.html +++ b/src/app/player/components/channel-list-container/channel-list-container.component.html @@ -98,28 +98,28 @@ - - - + - this.channelList.filter((channel) => - favorites.includes(channel.id) + map((favoriteChannelIds) => + favoriteChannelIds.map((favoriteChannelId) => + this.channelList.find( + (channel) => channel.id === favoriteChannelId + ) ) ) ); constructor( - private playlistService: PlaylistsService, private readonly store: Store, private snackBar: MatSnackBar, private translateService: TranslateService @@ -119,4 +120,14 @@ export class ChannelListContainerComponent { trackByFn(index: number, channel: Channel): string { return channel.id; } + + drop(event: CdkDragDrop, favorites: Channel[]) { + moveItemInArray(favorites, event.previousIndex, event.currentIndex); + console.log(favorites); + this.store.dispatch( + PlaylistActions.setFavorites({ + channelIds: favorites.map((item) => item.id), + }) + ); + } } diff --git a/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.scss b/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.scss index b4f916cc1..80e7e5204 100644 --- a/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.scss +++ b/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.scss @@ -24,3 +24,8 @@ } } } + +.drag-icon { + cursor: move; + margin-left: -20px; +} diff --git a/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.ts b/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.ts index 1682c97aa..ae2587088 100644 --- a/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.ts +++ b/src/app/player/components/channel-list-container/channel-list-item/channel-list-item.component.ts @@ -4,10 +4,20 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; selector: 'app-channel-list-item', styleUrls: ['./channel-list-item.component.scss'], template: ` + drag_indicator @@ -27,6 +37,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; >`, }) export class ChannelListItemComponent { + @Input() isDraggable = false; @Input() logo!: string; @Input() name = ''; @Input() showFavoriteButton = false; diff --git a/src/app/services/playlists.service.ts b/src/app/services/playlists.service.ts index ff14a543b..dddc92e1e 100644 --- a/src/app/services/playlists.service.ts +++ b/src/app/services/playlists.service.ts @@ -180,4 +180,15 @@ export class PlaylistsService { }) ); } + + setFavorites(playlistId: string, favorites: string[]) { + return this.getPlaylistById(playlistId).pipe( + switchMap((playlist) => + this.dbService.update(DbStores.Playlists, { + ...playlist, + favorites, + }) + ) + ); + } } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index fba8db075..0c1c4490e 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -34,6 +34,7 @@ import { MomentDatePipe } from './pipes/moment-date.pipe'; }), ], exports: [ + DragDropModule, FilterPipe, FormsModule, HeaderComponent, diff --git a/src/app/state/actions.ts b/src/app/state/actions.ts index dd5a62a10..b9c5e6b40 100644 --- a/src/app/state/actions.ts +++ b/src/app/state/actions.ts @@ -66,6 +66,11 @@ export const updateFavorites = createAction( props<{ channel: Channel }>() ); +export const setFavorites = createAction( + `${STORE_KEY} Set favorites`, + props<{ channelIds: string[] }>() +); + export const setActiveChannel = createAction( `${STORE_KEY} Set active channel`, props<{ channel: Channel }>() diff --git a/src/app/state/effects.ts b/src/app/state/effects.ts index 6e02750af..e4346b9b0 100644 --- a/src/app/state/effects.ts +++ b/src/app/state/effects.ts @@ -35,6 +35,24 @@ export class PlaylistEffects { { dispatch: false } ); + setFavorites$ = createEffect( + () => { + return this.actions$.pipe( + ofType(PlaylistActions.setFavorites), + combineLatestWith(this.store.select(selectActivePlaylistId)), + switchMap(([action, playlistId]) => + this.playlistsService.setFavorites( + playlistId, + action.channelIds + ) + ) + ); + }, + { + dispatch: false, + } + ); + setActiveChannel$ = createEffect(() => { return this.actions$.pipe( ofType(PlaylistActions.setActiveChannel), diff --git a/src/app/state/reducers.ts b/src/app/state/reducers.ts index b4c76a26f..cb99c3b4c 100644 --- a/src/app/state/reducers.ts +++ b/src/app/state/reducers.ts @@ -79,6 +79,22 @@ export const playlistReducer = createReducer( }, }; }), + on(PlaylistActions.setFavorites, (state, action): PlaylistState => { + const { channelIds } = action; + return { + ...state, + playlists: { + ...state.playlists, + entities: { + ...state.playlists.entities, + [state.playlists.selectedId]: { + ...state.playlists.entities[state.playlists.selectedId], + favorites: channelIds, + }, + }, + }, + }; + }), on(PlaylistActions.loadPlaylistsSuccess, (state, action): PlaylistState => { return { ...state,