Skip to content

Commit

Permalink
Fixes #489: [Enhancement] Opening explorer from the folders page
Browse files Browse the repository at this point in the history
  • Loading branch information
digimezzo committed Dec 31, 2023
1 parent 388eb02 commit 73d8e58
Show file tree
Hide file tree
Showing 24 changed files with 136 additions and 27 deletions.
9 changes: 9 additions & 0 deletions src/app/services/folder/subfolder-model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ describe('SubfolderModel', () => {
expect(subfolderModel).toBeDefined();
});

it('should define isSelected', () => {
// Arrange

// Act

// Assert
expect(subfolderModel.isSelected).toBeDefined();
});

it('should initialize isPlaying as false', () => {
// Arrange

Expand Down
10 changes: 8 additions & 2 deletions src/app/services/folder/subfolder-model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
export class SubfolderModel {
public constructor(public path: string, public isGoToParent: boolean) {}
import { ISelectable } from '../../ui/interfaces/i-selectable';

export class SubfolderModel implements ISelectable {
public constructor(
public path: string,
public isGoToParent: boolean,
) {}

public isSelected: boolean = false;
public isPlaying: boolean = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
</div>
<cdk-virtual-scroll-viewport *ngIf="folders.length > 0" class="mt-3 folder-browser__list" itemSize="28">
<div
*cdkVirtualFor="let subfolder of subfolders | subfoldersFilter : this.searchService.delayedSearchText"
*cdkVirtualFor="let subfolder of subfolders | subfoldersFilter: this.searchService.delayedSearchText"
matRipple
(mousedown)="setSelectedSubfolder(subfolder)"
(dblclick)="setOpenedSubfolderAsync(subfolder)"
(contextmenu)="onSubfolderContextMenu($event, subfolder)"
>
<div
class="subfolder d-flex flex-row align-items-center flex-grow p-1"
Expand Down Expand Up @@ -75,10 +76,25 @@
</mat-chip-listbox>
<app-track-browser
class="fill"
[tracks]="this.tracks | tracksFilter : this.searchService.delayedSearchText"
[tracks]="this.tracks | tracksFilter: this.searchService.delayedSearchText"
[(tracksPersister)]="this.tracksPersister"
></app-track-browser>
</div>
</as-split-area>
</as-split>
</div>

<div
#subfolderContextMenuAnchor
style="visibility: hidden; position: fixed"
[style.left]="contextMenuOpener.positionX"
[style.top]="contextMenuOpener.positionY"
[matMenuTriggerFor]="subfolderContextMenu"
></div>
<mat-menu #subfolderContextMenu="matMenu">
<ng-template matMenuContent let-subfolder="data">
<button mat-menu-item (click)="onOpenSubfolderAsync(subfolder)">
<span>{{ 'open-folder' | translate }}</span>
</button>
</ng-template>
</mat-menu>
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { TrackModel } from '../../../../services/track/track-model';
import { TrackModels } from '../../../../services/track/track-models';
import { Folder } from '../../../../data/entities/folder';
import { Constants } from '../../../../common/application/constants';
import { DesktopBase } from '../../../../common/io/desktop.base';
import { TrackBrowserComponent } from '../track-browser/track-browser.component';

describe('CollectionFoldersComponent', () => {
let settingsStub: any;
Expand All @@ -53,6 +55,7 @@ describe('CollectionFoldersComponent', () => {
let addToPlaylistMenuMock: IMock<AddToPlaylistMenu>;
let dateTimeMock: IMock<DateTime>;
let folderTracksPersisterMock: IMock<FolderTracksPersister>;
let desktopMock: IMock<DesktopBase>;

let playbackServicePlaybackStartedMock: Subject<PlaybackStarted>;
let playbackServicePlaybackStoppedMock: Subject<void>;
Expand Down Expand Up @@ -82,7 +85,7 @@ describe('CollectionFoldersComponent', () => {
const flushPromises = () => new Promise(process.nextTick);

function createComponent(): CollectionFoldersComponent {
const component: CollectionFoldersComponent = new CollectionFoldersComponent(
return new CollectionFoldersComponent(
searchServiceMock.object,
appearanceServiceMock.object,
folderServiceMock.object,
Expand All @@ -101,9 +104,8 @@ describe('CollectionFoldersComponent', () => {
schedulerMock.object,
loggerMock.object,
hacksMock.object,
desktopMock.object,
);

return component;
}

beforeEach(() => {
Expand All @@ -128,6 +130,7 @@ describe('CollectionFoldersComponent', () => {
addToPlaylistMenuMock = Mock.ofType<AddToPlaylistMenu>();
dateTimeMock = Mock.ofType<DateTime>();
folderTracksPersisterMock = Mock.ofType<FolderTracksPersister>();
desktopMock = Mock.ofType<DesktopBase>();

folder1 = new FolderModel(new Folder('/home/user/Music'));
folder2 = new FolderModel(new Folder('/home/user/Downloads'));
Expand Down Expand Up @@ -318,6 +321,16 @@ describe('CollectionFoldersComponent', () => {
// Assert
expect(component.addToPlaylistMenu).toBeDefined();
});

it('should declare subfolderContextMenu', () => {
// Arrange

// Act
const component: CollectionFoldersComponent = createComponent();

// Assert
expect(component.subfolderContextMenu).toBeUndefined();
});
});

describe('splitDragEnd', () => {
Expand Down Expand Up @@ -788,4 +801,33 @@ describe('CollectionFoldersComponent', () => {
mouseSelectionWatcherMock.verify((x) => x.initialize(component.tracks.tracks, false), Times.exactly(1));
});
});

describe('onSubfolderContextMenu', () => {
it('should open the context menu', () => {
// Arrange
const component: CollectionFoldersComponent = createComponent();
const event: MouseEvent = new MouseEvent('contextmenu');
const subfolder: SubfolderModel = subfolder1;

// Act
component.onSubfolderContextMenu(event, subfolder);

// Assert
contextMenuOpenerMock.verify((x) => x.open(component.subfolderContextMenu, event, subfolder), Times.exactly(1));
});
});

describe('onOpenSubfolderAsync', () => {
it('should open the given folder in the desktop', async () => {
// Arrange
const component: CollectionFoldersComponent = createComponent();
desktopMock.setup((x) => x.openPathAsync(subfolder1.path)).returns(() => Promise.resolve());

// Act
await component.onOpenSubfolderAsync(subfolder1);

// Assert
desktopMock.verify((x) => x.openPathAsync(subfolder1.path), Times.exactly(1));
});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { IOutputData } from 'angular-split';
import { Subscription } from 'rxjs';
import { Constants } from '../../../../common/application/constants';
Expand All @@ -25,6 +25,8 @@ import { SettingsBase } from '../../../../common/settings/settings.base';
import { MouseSelectionWatcher } from '../../mouse-selection-watcher';
import { ContextMenuOpener } from '../../context-menu-opener';
import { SchedulerBase } from '../../../../common/scheduling/scheduler.base';
import { MatMenuTrigger } from '@angular/material/menu';
import { DesktopBase } from '../../../../common/io/desktop.base';

@Component({
selector: 'app-collection-folders',
Expand All @@ -35,6 +37,8 @@ import { SchedulerBase } from '../../../../common/scheduling/scheduler.base';
encapsulation: ViewEncapsulation.None,
})
export class CollectionFoldersComponent implements OnInit, OnDestroy {
private subscription: Subscription = new Subscription();

public constructor(
public searchService: SearchServiceBase,
public appearanceService: AppearanceServiceBase,
Expand All @@ -54,9 +58,11 @@ export class CollectionFoldersComponent implements OnInit, OnDestroy {
private scheduler: SchedulerBase,
private logger: Logger,
private hacks: Hacks,
private desktop: DesktopBase,
) {}

private subscription: Subscription = new Subscription();
@ViewChild('subfolderContextMenuAnchor', { read: MatMenuTrigger, static: false })
public subfolderContextMenu: MatMenuTrigger;

public leftPaneSize: number = this.settings.foldersLeftPaneWidthPercent;
public rightPaneSize: number = 100 - this.settings.foldersLeftPaneWidthPercent;
Expand Down Expand Up @@ -156,6 +162,14 @@ export class CollectionFoldersComponent implements OnInit, OnDestroy {
await this.navigationService.navigateToManageCollectionAsync();
}

public onSubfolderContextMenu(event: MouseEvent, subfolder: SubfolderModel): void {
this.contextMenuOpener.open(this.subfolderContextMenu, event, subfolder);
}

public async onOpenSubfolderAsync(subfolder: SubfolderModel): Promise<void> {
await this.desktop.openPathAsync(subfolder.path);
}

private async fillListsAsync(): Promise<void> {
await this.scheduler.sleepAsync(Constants.longListLoadDelayMilliseconds);
this.getFolders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { TrackModel } from '../../../services/track/track-model';
import { SchedulerBase } from '../../../common/scheduling/scheduler.base';
import { AudioVisualizer } from '../../../services/playback/audio-visualizer';
import { DocumentProxy } from '../../../common/io/document-proxy';
import { SettingsBase } from '../../../common/settings/settings.base';

describe('NowPlayingComponent', () => {
let appearanceServiceMock: IMock<AppearanceServiceBase>;
Expand All @@ -24,6 +25,7 @@ describe('NowPlayingComponent', () => {
let schedulerMock: IMock<SchedulerBase>;
let audioVisualizerMock: IMock<AudioVisualizer>;
let documentProxyMock: IMock<DocumentProxy>;
let settingsMock: IMock<SettingsBase>;

let playbackServicePlaybackStartedMock: Subject<PlaybackStarted>;
let playbackServicePlaybackStoppedMock: Subject<void>;
Expand All @@ -43,6 +45,7 @@ describe('NowPlayingComponent', () => {
schedulerMock.object,
audioVisualizerMock.object,
documentProxyMock.object,
settingsMock.object,
);
}

Expand All @@ -56,6 +59,7 @@ describe('NowPlayingComponent', () => {
schedulerMock = Mock.ofType<SchedulerBase>();
audioVisualizerMock = Mock.ofType<AudioVisualizer>();
documentProxyMock = Mock.ofType<DocumentProxy>();
settingsMock = Mock.ofType<SettingsBase>();

appearanceServiceMock.setup((x) => x.isUsingLightTheme).returns(() => false);

Expand Down
3 changes: 2 additions & 1 deletion src/assets/i18n/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Няма намерени текстове",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/cs.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Text skladby nenalezen",
"no-biography-found": "Biografie nenalezena",
"show-welcome-screen-now": "Zobrazit uvítací obrazovku nyní",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/el.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Aucune parole n'a été trouvée",
"no-biography-found": "Aucune biographie n'a été trouvée",
"show-welcome-screen": "Afficher l'écran d'accueil maintenant",
"keep-playback-controls-visible-on-now-playing-page": "Garder les commandes de lecture visibles sur la page 'Lecture en cours'"
"keep-playback-controls-visible-on-now-playing-page": "Garder les commandes de lecture visibles sur la page 'Lecture en cours'",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/hr.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/ku.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Er zijn geen songteksten gevonden",
"no-biography-found": "Er is geen biografie gevonden",
"show-welcome-screen-now": "Toon nu het welkomstscherm",
"keep-playback-controls-visible-on-now-playing-page": "Houd de afspeelknoppen zichtbaar op de 'Speel nu' pagina"
"keep-playback-controls-visible-on-now-playing-page": "Houd de afspeelknoppen zichtbaar op de 'Speel nu' pagina",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Текст песни не найден",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Inga låttexter hittades",
"no-biography-found": "Ingen biografi hittades",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "Không tìm thấy lời bài hát",
"no-biography-found": "Không tìm thấy tiểu sử",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}
3 changes: 2 additions & 1 deletion src/assets/i18n/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,6 @@
"no-lyrics-found": "No lyrics were found",
"no-biography-found": "No biography was found",
"show-welcome-screen-now": "Show welcome screen now",
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page"
"keep-playback-controls-visible-on-now-playing-page": "Keep playback controls visible on now playing page",
"open-folder": "Open folder"
}

0 comments on commit 73d8e58

Please sign in to comment.