-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Farmer app audio support #290
base: main
Are you sure you want to change the base?
Changes from 6 commits
2bbe9f1
4ebd7e2
7968b53
af7ed64
39ca7f7
6eebe4a
f908426
1bdf8cb
04968f0
f524f58
79f5547
2447ca6
194febb
1b9eb91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<button (click)="togglePlayback()" class="audio-button"> | ||
<div *ngIf="isAudioPlaying; else playIcon"> | ||
<mat-icon>play_circle_outline</mat-icon> | ||
</div> | ||
<ng-template #playIcon> | ||
<mat-icon>headset</mat-icon> | ||
</ng-template> | ||
</button> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.audio-button{ | ||
outline: none; | ||
background-color: inherit; | ||
border: none; | ||
padding: 5px; | ||
.mat-icon{ | ||
color: #7292C7; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit(non-blocking): might be good to link the color to the primary/secondary pallette. You could use
The full list of colors that could be registered can be seen in |
||
font-size: 28px; | ||
height: 32px; | ||
width: 32px; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { AudioPlaybackComponent } from './audio-playback.component'; | ||
|
||
describe('AudioPlaybackComponent', () => { | ||
let component: AudioPlaybackComponent; | ||
let fixture: ComponentFixture<AudioPlaybackComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [AudioPlaybackComponent], | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(AudioPlaybackComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { Component, ViewChild, ElementRef, OnDestroy, Input } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { AudioService } from './audio-playback.service'; | ||
import { MatIconModule } from '@angular/material/icon'; | ||
|
||
@Component({ | ||
selector: 'picsa-audio-playback', | ||
standalone: true, | ||
imports:[CommonModule, MatIconModule], | ||
templateUrl: './audio-playback.component.html', | ||
styleUrls: ['./audio-playback.component.scss'], | ||
}) | ||
export class AudioPlaybackComponent implements OnDestroy { | ||
@Input() audioUrl: string; | ||
isAudioPlaying = false; | ||
|
||
constructor(private audioService: AudioService) {} | ||
|
||
togglePlayback(): void { | ||
if (this.audioService.isPlaying()) { | ||
this.audioService.pauseAudio(); | ||
this.isAudioPlaying = true; | ||
} else { | ||
this.audioService.playAudio(this.audioUrl); | ||
this.isAudioPlaying = false; | ||
} | ||
} | ||
|
||
isPlaying(): boolean { | ||
return this.audioService.isPlaying(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit(non-blocking): I like how you have linked the audio play detection to the service, as it's possible that the service will stop component playback (e.g. if the user tries to start a second audio while the first one is playing), however you might need to remove the |
||
} | ||
|
||
ngOnDestroy(): void { | ||
this.audioService.stop(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { Router, NavigationStart } from '@angular/router'; | ||
|
||
@Injectable({ | ||
providedIn: 'root', | ||
}) | ||
export class AudioService { | ||
private audio: HTMLAudioElement; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 - nice you were able to do get things working with the standard html audio api. In another project I've used HowlerJS, however it looks like the api should be sufficient for now |
||
|
||
constructor() { | ||
this.audio = new Audio(); | ||
} | ||
|
||
playAudio(url: string): void { | ||
if (this.audio.src !== url) { | ||
this.audio.src = url; | ||
} | ||
this.audio.play(); | ||
} | ||
|
||
pauseAudio(): void { | ||
this.audio.pause(); | ||
} | ||
|
||
isPlaying(): boolean { | ||
return !this.audio.paused; | ||
} | ||
|
||
stop(): void { | ||
if (this.audio) { | ||
this.audio.pause(); | ||
this.audio.currentTime = 0; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './audio-playback.component'; | ||
export * from './audio-playback.service'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit(non-blocking) - it would be good for the icon to change when play button first clicked (currently only changes when clicked twice, once to start and once to pause), so that the user gets feedback that the audio click was registered. Could also consider putting the icon in a
mat-button
to get a ripple effectnit(non-blocking) - feel free if you want to use the
@if(...)
and@else(...)
syntax. Can also probably just put the if/else around the icon and not need additional ng-template