The Jukebox UI

Implement the UI for the Ionic Jukebox application.

Let’s move on to the templating for the HomePage component.

The home page template

Changes to the template

Despite having the logic in place to manage audio playback and interaction, we haven’t yet implemented the actual UI for the application.

Let’s do that now by opening the src/app/home/home.page.html component view and making the following changes (changes are highlighted):

Press + to interact
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Ionic Jukebox
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<div class="wrapper">
<div class="playback">
<!-- Track loading animation -->
<span class="preloader" *ngIf="isLoading">
<img src="/assets/icon/preloader.gif">
</span>
<!-- Track name, artist name and playback time -->
<span class="playback__details">
<span class="playback__details--track">{{ trackName }}</span>
<span class="playback__details--artist">{{ artistName }}</span>
</span>
<span class="playback__time" *ngIf="isPlaying">{{ currentTime }}</span>
<!-- Playhead and track playback bar -->
<div class="progress" #track>
<div class="progress__scrubber" #scrubber (mousedown)="onDragDown($event)" (mousemove)="onDragMove($event)" (mouseout)="onDragMove($event)" (mouseup)="onDragRelease($event)"></div>
<div class="progress__bar" #progress></div>
</div>
</div>
<div class="buttons">
<!-- Play previous track -->
<ion-button
fill="clear"
(click)="previousTrack()"
[disabled]="currentTrack === 0">
<ion-icon slot="icon-only" name="play-back-circle-outline"></ion-icon>
</ion-button>
<!-- Stops playback of audio track currently playing -->
<ion-button
fill="clear"
display="block"
[disabled]="!isPlaying"
(click)="stopPlayback()">
<ion-icon slot="icon-only" name="stop-circle-outline"></ion-icon>
</ion-button>
<!-- Play next track -->
<ion-button
fill="clear"
(click)="nextTrack()"
[disabled]="!isPlaying || (currentTrack + 1) === tracks.length">
<ion-icon slot="icon-only" name="play-forward-circle-outline"></ion-icon>
</ion-button>
<div class="controls">
<!-- Enable/disable reverse playback of audio track -->
<div class="controls__control">
<ion-checkbox [(ngModel)]="isReversed" (ionChange)="isPlaybackReversed($event)"></ion-checkbox>
<ion-label>Reverse</ion-label>
</div>
<!-- Enable/disable continuous playback -->
<div class="controls__control">
<ion-checkbox [(ngModel)]="tracksAreLooped" (ionChange)="loopTracks($event)"></ion-checkbox>
<ion-label>Loop All</ion-label>
</div>
<!-- Shuffle track playlist -->
<div class="controls__control">
<ion-checkbox (ionChange)="shuffle($event)"></ion-checkbox>
<ion-label>Shuffle</ion-label>
</div>
<!-- Enable muting/non-muting of audio playback -->
<div class="controls__control">
<ion-checkbox (ionChange)="mute($event)" [disabled]="!isPlaying"></ion-checkbox>
<ion-label>Mute</ion-label>
</div>
</div>
</div>
<!-- Manage volume change of audio playback -->
<ion-item>
Volume:
<ion-range
pin = "true"
step="0.01"
snaps="false"
min="0"
value="1"
max="3.4"
[disabled]="!isPlaying"
[(ngModel)]="volume"
(ionChange)="changeVolume($event)">>
<ion-icon range-left small name="0"></ion-icon>
<ion-icon range-right name="1"></ion-icon>
</ion-range>
</ion-item>
<!-- Manage stereo balance of audio playback -->
<ion-item>
Balance:
<ion-range
pin = "true"
step="0.01"
snaps="false"
min="-1"
value="0"
max="1"
[disabled]="!isPlaying"
[(ngModel)]="panning"
(ionChange)="changePanning($event)">>
<ion-icon range-left small name="-1"></ion-icon>
<ion-icon range-right name="1"></ion-icon>
</ion-range>
</ion-item>
<!-- Iterate through audio tracks listed in component class, embed data in button and allow track to be selected/played -->
<ion-list>
<ion-item *ngFor="let track of tracks; let index = index"
(click)="loadSound(track.track, index)">
{{ track.artist}} - {{ track.name }}
</ion-item>
</ion-list>
</div>
</ion-content>

Explanation of the changes

Here, we see the familiar templating formula of ionic UI components ...