Skip to content

Commit

Permalink
Add noises
Browse files Browse the repository at this point in the history
  • Loading branch information
thefactus committed Feb 1, 2025
1 parent cdf53d8 commit f24d7d5
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 5 deletions.
2 changes: 1 addition & 1 deletion app/components/forward-button.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<button
type="button"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors cursor-pointer"
{{on "click" @onClick}}
aria-label="Next"
>
Expand Down
20 changes: 20 additions & 0 deletions app/components/noise-button.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<button
type="button"
class="p-2 rounded-full hover:bg-white/10 transition-colors cursor-pointer"
aria-label="Noises"
>
{{#if true}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" data-darkreader-inline-stroke="" style="--darkreader-inline-stroke: currentColor;" width="24" height="24" stroke-width="2">
<path d="M3 7c3 -2 6 -2 9 0s6 2 9 0"></path>
<path d="M3 17c3 -2 6 -2 9 0s6 2 9 0"></path>
<path d="M3 12c3 -2 6 -2 9 0s6 2 9 0"></path>
</svg>
{{else}}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" data-darkreader-inline-stroke="" style="--darkreader-inline-stroke: currentColor;" width="24" height="24" stroke-width="2">
<path d="M3 7c.915 -.61 1.83 -1.034 2.746 -1.272m4.212 .22c.68 .247 1.361 .598 2.042 1.052c3 2 6 2 9 0"></path>
<path d="M3 17c3 -2 6 -2 9 0c2.092 1.395 4.184 1.817 6.276 1.266"></path>
<path d="M3 12c3 -2 6 -2 9 0m5.482 1.429c1.173 -.171 2.345 -.647 3.518 -1.429"></path>
<path d="M3 3l18 18"></path>
</svg>
{{/if}}
</button>
27 changes: 27 additions & 0 deletions app/components/noise-dropdown.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="mt-2 bg-stone-500/20 backdrop-blur-sm p-4 rounded-xl shadow-lg">
<div class="grid grid-cols-3 gap-2">
<button type="button"
class="p-2 rounded hover:bg-white/10 transition-colours cursor-pointer {{if this.noises.brown.active 'bg-white/20'}}"
{{on "click" (fn this.toggleNoise "brown")}}>
Brown
</button>
<button type="button"
class="p-2 rounded hover:bg-white/10 transition-colours cursor-pointer {{if this.noises.green.active 'bg-white/20'}}"
{{on "click" (fn this.toggleNoise "green")}}>
Green
</button>
<button type="button"
class="p-2 rounded hover:bg-white/10 transition-colours cursor-pointer {{if this.noises.white.active 'bg-white/20'}}"
{{on "click" (fn this.toggleNoise "white")}}>
White
</button>
</div>
<div class="mt-4 flex justify-center">
<VolumeControl
@volume={{this.volume}}
@isMuted={{this.isMuted}}
@onToggleMute={{this.toggleMute}}
@onVolumeChange={{this.updateVolume}}
/>
</div>
</div>
90 changes: 90 additions & 0 deletions app/components/noise-dropdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

// Use a type alias instead of an empty interface to avoid ESLint warnings.
type NoiseDropdownArgs = Record<string, never>;

type NoiseType = 'brown' | 'green' | 'white';

interface Noise {
active: boolean;
audio: HTMLAudioElement;
}

export default class NoiseDropdownComponent extends Component<NoiseDropdownArgs> {
@tracked volume = 1;
private previousVolume = 1;

// Each noise is mapped to an audio element; note that the green noise plays blue_noise.mp3.
noises: Record<NoiseType, Noise> = {
brown: {
active: false,
audio: new Audio('/brown_noise.mp3'),
},
green: {
active: false,
audio: new Audio('/blue_noise.mp3'),
},
white: {
active: false,
audio: new Audio('/white_noise.mp3'),
},
};

constructor(owner: unknown, args: NoiseDropdownArgs) {
super(owner, args);
// Set each audio element to loop and initialise its volume.
Object.values(this.noises).forEach((noise) => {
noise.audio.loop = true;
noise.audio.volume = this.volume;
});
}

// Computed property to indicate whether the volume is muted.
get isMuted(): boolean {
return this.volume === 0;
}

// Toggle the given noise on or off.
@action
toggleNoise(noiseType: NoiseType) {
const noise = this.noises[noiseType];
if (noise.active) {
noise.audio.pause();
noise.active = false;
} else {
noise.audio.currentTime = 0;
noise.audio.play().catch((err) => {
console.error(`Failed to play ${noiseType} noise:`, err);
});
noise.active = true;
}
// Reassign to trigger reactivity.
this.noises = { ...this.noises };
}

// Update the volume for all noise audio elements.
@action
updateVolume(event: Event) {
const target = event.target as HTMLInputElement;
this.volume = parseFloat(target.value);
Object.values(this.noises).forEach((noise) => {
noise.audio.volume = this.volume;
});
}

// Toggle mute by setting the volume to zero or restoring the previous volume.
@action
toggleMute() {
if (this.volume === 0) {
this.volume = this.previousVolume;
} else {
this.previousVolume = this.volume;
this.volume = 0;
}
Object.values(this.noises).forEach((noise) => {
noise.audio.volume = this.volume;
});
}
}
2 changes: 1 addition & 1 deletion app/components/play-pause-button.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<button
type="button"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors cursor-pointer"
{{on "click" @onClick}}
aria-label={{if @isPlaying "Pause" "Play"}}
>
Expand Down
2 changes: 1 addition & 1 deletion app/components/player.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- lofi/app/components/player.hbs -->
<div class="z-20 fixed bottom-4 left-1/2 -translate-x-1/2 bg-white/10 backdrop-blur-sm p-4 rounded-xl shadow-lg flex items-center w-[calc(100vw-2rem)] md:w-1/2 lg:w-2/5 xl:w-1/3">
<div class="z-20 fixed border border-transparent hover:border-white/10 bottom-4 left-1/2 -translate-x-1/2 bg-stone-500/20 backdrop-blur-sm p-4 rounded-xl shadow-lg flex items-center w-[calc(100vw-2rem)] md:w-1/2 lg:w-2/5 xl:w-1/3">

<div class="flex flex-col w-full">
<div class="flex justify-between items-center mb-2">
Expand Down
12 changes: 12 additions & 0 deletions app/components/pomodoro-button.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<button
type="button"
class="p-2 rounded-full hover:bg-white/10 transition-colors cursor-pointer"
aria-label="Pomodoro"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" width="24" height="24" stroke-width="2">
<path d="M5 13a7 7 0 1 0 14 0a7 7 0 0 0 -14 0z"></path>
<path d="M14.5 10.5l-2.5 2.5"></path>
<path d="M17 8l1 -1"></path>
<path d="M14 3h-4"></path>
</svg>
</button>
2 changes: 1 addition & 1 deletion app/components/previous-track-button.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<button
type="button"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors cursor-pointer"
{{on "click" @onClick}}
aria-label={{@label}}
disabled={{@isDisabled}}
Expand Down
11 changes: 11 additions & 0 deletions app/components/top.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="flex flex-col items-end">
<div class="z-20 flex space-x-2">
<button {{on "click" this.toggleNoiseDropdown}}>
<NoiseButton />
</button>
<PomodoroButton />
</div>
<div class="{{if this.showNoiseDropdown 'mt-2 z-20' 'hidden'}}" {{on "mouseleave" this.hideNoiseDropdown}}>
<NoiseDropdown />
</div>
</div>
19 changes: 19 additions & 0 deletions app/components/top.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

type TopArgs = Record<string, never>;

export default class TopComponent extends Component<TopArgs> {
@tracked showNoiseDropdown = false;

@action
toggleNoiseDropdown() {
this.showNoiseDropdown = !this.showNoiseDropdown;
}

@action
hideNoiseDropdown() {
this.showNoiseDropdown = false;
}
}
2 changes: 1 addition & 1 deletion app/components/volume-control.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="flex items-center gap-2">
<button
type="button"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors"
class="p-2 rounded-full hover:backdrop-blur-sm transition-colors cursor-pointer"
{{on "click" @onToggleMute}}
aria-label={{if @isMuted "Unmute" "Mute"}}
>
Expand Down
3 changes: 3 additions & 0 deletions app/templates/application.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

<main class="flex-grow p-4 overflow-hidden">
{{outlet}}

<Top />

<Player />
</main>
</div>
Expand Down

0 comments on commit f24d7d5

Please sign in to comment.