Skip to content

Commit

Permalink
feat: rearrange the display order of playlists
Browse files Browse the repository at this point in the history
this commit closes #77
  • Loading branch information
4gray committed Sep 17, 2021
1 parent 4d2e175 commit 757c739
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 7 deletions.
15 changes: 14 additions & 1 deletion api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
PLAYLIST_PARSE_RESPONSE,
PLAYLIST_UPDATE,
PLAYLIST_UPDATE_RESPONSE,
PLAYLIST_UPDATE_POSITIONS,
} from './shared/ipc-commands';

const fs = require('fs');
Expand Down Expand Up @@ -205,6 +206,17 @@ export class Api {
}
);

ipcMain.on(
PLAYLIST_UPDATE_POSITIONS,
(event, playlists: Partial<Playlist[]>) =>
playlists.forEach((list, index) => {
this.updatePlaylistById(list._id, {
...list,
position: index,
});
})
);

this.refreshPlaylists();
}

Expand Down Expand Up @@ -261,8 +273,9 @@ export class Api {
autoRefresh: 1,
updateDate: 1,
updateState: 1,
position: 1,
})
.sort({ importDate: -1 });
.sort({ position: 1, importDate: -1 });
}

/**
Expand Down
1 change: 1 addition & 0 deletions shared/ipc-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const PLAYLIST_PARSE = 'PLAYLIST:PARSE_PLAYLIST';
export const PLAYLIST_PARSE_RESPONSE = 'PLAYLIST:PARSE_PLAYLIST_RESPONSE';
export const PLAYLIST_UPDATE = 'PLAYLIST:UPDATE';
export const PLAYLIST_UPDATE_RESPONSE = 'PLAYLIST:UPDATE_RESPONSE';
export const PLAYLIST_UPDATE_POSITIONS = 'PLAYLIST:UPDATE_POSITIONS';

// General
export const SHOW_WHATS_NEW = 'SHOW_WHATS_NEW';
Expand Down
1 change: 1 addition & 0 deletions shared/playlist.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export interface Playlist {
autoRefresh: boolean;
updateDate?: number;
updateState?: PlaylistUpdateState;
position?: number;
}
1 change: 1 addition & 0 deletions src/app/home/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type PlaylistMeta = Pick<
| 'filePath'
| 'updateDate'
| 'updateState'
| 'position'
>;

@Component({
Expand Down
9 changes: 8 additions & 1 deletion src/app/home/home.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import { RecentPlaylistsComponent } from './recent-playlists/recent-playlists.co
import { HomeRoutingModule } from './home.routing';
import { NgxUploaderModule } from 'ngx-uploader';
import { PlaylistInfoComponent } from './recent-playlists/playlist-info/playlist-info.component';
import { DragDropModule } from '@angular/cdk/drag-drop';

@NgModule({
imports: [CommonModule, HomeRoutingModule, NgxUploaderModule, SharedModule],
imports: [
CommonModule,
HomeRoutingModule,
NgxUploaderModule,
SharedModule,
DragDropModule,
],
declarations: [
HomeComponent,
FileUploadComponent,
Expand Down
11 changes: 7 additions & 4 deletions src/app/home/recent-playlists/recent-playlists.component.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<mat-nav-list>
<mat-nav-list cdkDropList (cdkDropListDropped)="drop($event)">
<mat-list-item *ngIf="playlists.length === 0">
<mat-icon mat-list-icon>cloud</mat-icon>
<div mat-line>{{ 'HOME.PLAYLISTS.NO_PLAYLISTS' | translate }}</div>
<div mat-line class="meta">
{{ 'HOME.PLAYLISTS.ADD_FIRST' | translate }}
</div>
</mat-list-item>
<a
mat-list-item
<mat-list-item
cdkDrag
*ngFor="let item of playlists; last as last"
(click)="playlistClicked.emit(item._id)"
>
<mat-icon mat-list-icon cdkDragHandle class="drag-icon"
>drag_indicator</mat-icon
>
<mat-icon
mat-list-icon
*ngIf="item?.url"
Expand Down Expand Up @@ -72,5 +75,5 @@
<mat-icon>delete</mat-icon>
</button>
<mat-divider *ngIf="!last"></mat-divider>
</a>
</mat-list-item>
</mat-nav-list>
41 changes: 41 additions & 0 deletions src/app/home/recent-playlists/recent-playlists.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,51 @@ mat-list-item {
mat-nav-list {
height: calc(100vh - 192px);
overflow: auto;
width: 100%;
}

.meta {
font-size: 12px !important;
color: #666;
margin-top: 2px !important;
}

::ng-deep .cdk-drag-preview .mat-list-item-content {
display: flex;
flex-direction: row;
align-items: center;
box-sizing: border-box;
padding: 0 16px;
position: relative;
height: inherit;
width: 100%;
justify-content: space-between;

.mat-list-text {
display: flex;
flex-direction: column;
flex: auto;
box-sizing: border-box;
overflow: hidden;
padding-left: 16px;
}
}

.cdk-drag-preview {
box-sizing: border-box;
border-radius: 4px;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
}

.cdk-drag-placeholder {
opacity: 0;
}

.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

.drag-icon {
cursor: move;
margin-left: -20px;
}
78 changes: 78 additions & 0 deletions src/app/home/recent-playlists/recent-playlists.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { MockModule, MockPipe, MockProvider } from 'ng-mocks';
import { ElectronService } from '../../services/electron.service';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { RecentPlaylistsComponent } from './recent-playlists.component';
import { PlaylistMeta } from '../home.component';
import { MatListModule } from '@angular/material/list';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatIconModule } from '@angular/material/icon';

export class ElectronServiceStub {
sendIpcEvent(): void {}
}

describe('RecentPlaylistsComponent', () => {
let component: RecentPlaylistsComponent;
let fixture: ComponentFixture<RecentPlaylistsComponent>;
let electronService: ElectronService;
let dialog: MatDialog;

beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [
RecentPlaylistsComponent,
MockPipe(TranslatePipe),
],
imports: [
MockModule(MatDialogModule),
MockModule(MatListModule),
MockModule(MatIconModule),
MockModule(MatTooltipModule),
],
providers: [
{ provide: ElectronService, useClass: ElectronServiceStub },
MockProvider(TranslateService),
],
}).compileComponents();
})
);

beforeEach(() => {
fixture = TestBed.createComponent(RecentPlaylistsComponent);
component = fixture.componentInstance;
component.playlists = [];
dialog = TestBed.inject(MatDialog);
electronService = TestBed.inject(ElectronService);
TestBed.inject(ElectronService);
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should open the info dialog', () => {
spyOn(dialog, 'open');
component.openInfoDialog({} as PlaylistMeta);
expect(dialog.open).toHaveBeenCalledTimes(1);
});

it('should send an ipc event after drop event', () => {
const event = {
previousIndex: 0,
currentIndex: 1,
item: undefined,
container: undefined,
previousContainer: undefined,
isPointerOverContainer: true,
distance: { x: 0, y: 0 },
dropPoint: { x: 0, y: 0 },
};
spyOn(electronService, 'sendIpcEvent');
component.drop(event);
expect(electronService.sendIpcEvent).toHaveBeenCalledTimes(1);
});
});
25 changes: 24 additions & 1 deletion src/app/home/recent-playlists/recent-playlists.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { PLAYLIST_UPDATE_POSITIONS } from './../../../../shared/ipc-commands';
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { PlaylistInfoComponent } from './playlist-info/playlist-info.component';
import { PlaylistMeta } from './../home.component';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { ElectronService } from '../../services/electron.service';

@Component({
selector: 'app-recent-playlists',
Expand All @@ -24,8 +27,12 @@ export class RecentPlaylistsComponent {
/**
* Creates an instance of the component
* @param dialog angular material dialog reference
* @param electronService electron service
*/
constructor(public dialog: MatDialog) {}
constructor(
public dialog: MatDialog,
private electronService: ElectronService
) {}

/**
* Opens the details dialog with the information about the provided playlist
Expand All @@ -36,4 +43,20 @@ export class RecentPlaylistsComponent {
data,
});
}

/**
* Drop event handler - applies the new sort order to the playlists array
* @param event drop event
*/
drop(event: CdkDragDrop<PlaylistMeta[]>): void {
moveItemInArray(
this.playlists,
event.previousIndex,
event.currentIndex
);
this.electronService.sendIpcEvent(
PLAYLIST_UPDATE_POSITIONS,
this.playlists
);
}
}
9 changes: 9 additions & 0 deletions src/app/services/electron.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,13 @@ export class ElectronService {
getAppVersion(): string {
return this.remote.app.getVersion();
}

/**
* Sends an IPC event from render to the main process
* @param type event type
* @param payload data payload
*/
sendIpcEvent(type: string, payload: unknown): void {
this.ipcRenderer.send(type, payload);
}
}

0 comments on commit 757c739

Please sign in to comment.