From 5317daa43e33b67550148bd53220faf20c2fa2de Mon Sep 17 00:00:00 2001
From: Baptiste Lyet <44911483+Babali42@users.noreply.github.com>
Date: Mon, 6 Jan 2025 23:38:50 +0100
Subject: [PATCH] Change tempo (#108)
* create bpm input component
* add style to the bpm input component and adjust sequencer
* modify input value with input or buttons
* change bpm while playing beat
---
.../bpm-input/bpm-input.component.html | 5 ++
.../bpm-input/bpm-input.component.scss | 39 +++++++++++++
.../bpm-input/bpm-input.component.spec.ts | 56 +++++++++++++++++++
.../bpm-input/bpm-input.component.ts | 37 ++++++++++++
.../sequencer/sequencer.component.html | 8 +--
.../sequencer/sequencer.component.scss | 4 ++
.../sequencer/sequencer.component.ts | 18 +++++-
.../src/app/services/sound/sound.service.ts | 19 ++++++-
8 files changed, 178 insertions(+), 8 deletions(-)
create mode 100644 frontend/src/app/components/bpm-input/bpm-input.component.html
create mode 100644 frontend/src/app/components/bpm-input/bpm-input.component.scss
create mode 100644 frontend/src/app/components/bpm-input/bpm-input.component.spec.ts
create mode 100644 frontend/src/app/components/bpm-input/bpm-input.component.ts
diff --git a/frontend/src/app/components/bpm-input/bpm-input.component.html b/frontend/src/app/components/bpm-input/bpm-input.component.html
new file mode 100644
index 0000000..5d0024d
--- /dev/null
+++ b/frontend/src/app/components/bpm-input/bpm-input.component.html
@@ -0,0 +1,5 @@
+
diff --git a/frontend/src/app/components/bpm-input/bpm-input.component.scss b/frontend/src/app/components/bpm-input/bpm-input.component.scss
new file mode 100644
index 0000000..d71e447
--- /dev/null
+++ b/frontend/src/app/components/bpm-input/bpm-input.component.scss
@@ -0,0 +1,39 @@
+/* From Uiverse.io by Cybercom682 */
+.number-control {
+ display: flex;
+ align-items: center;
+
+ .number-left::before,
+ .number-right::after {
+ content: attr(data-content);
+ background-color: var(--backgroundColor);;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid var(--borderColor);;
+ width: 20px;
+ color: var(--textColor);
+ cursor: pointer;
+ }
+
+ .number-left::before {
+ content: "-";
+ }
+
+ .number-right::after {
+ content: "+";
+ }
+
+ .number-quantity {
+ padding: 0.25rem;
+ width: 50px;
+ height: 12px;
+ -moz-appearance: textfield;
+ border: 0;
+ border-top: 1px solid var(--borderColor);
+ border-bottom: 1px solid var(--borderColor);
+ background-color: var(--backgroundColor);
+ color: var(--textColor);
+ }
+}
+
diff --git a/frontend/src/app/components/bpm-input/bpm-input.component.spec.ts b/frontend/src/app/components/bpm-input/bpm-input.component.spec.ts
new file mode 100644
index 0000000..e5a82e4
--- /dev/null
+++ b/frontend/src/app/components/bpm-input/bpm-input.component.spec.ts
@@ -0,0 +1,56 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BpmInputComponent } from './bpm-input.component';
+import {By} from "@angular/platform-browser";
+
+describe('BpmInputComponent', () => {
+ let component: BpmInputComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [BpmInputComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(BpmInputComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should increment the bpm in the desired range', () => {
+ component.maxBpm = 130;
+ component.bpm = 128;
+ component.incrementBpm();
+ component.incrementBpm();
+ component.incrementBpm();
+ expect(component.bpm).toEqual(component.maxBpm);
+ });
+
+ it('should decrement the bpm in the desired range', () => {
+ component.minBpm = 126;
+ component.bpm = 128;
+ component.decrementBpm();
+ component.decrementBpm();
+ component.decrementBpm();
+ expect(component.bpm).toEqual(component.minBpm);
+ });
+
+ it('should update the value', () => {
+ component.bpm = 128;
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ const inputElement = fixture.debugElement.query(By.css('.number-quantity')).nativeElement;
+
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ inputElement.value = '120';
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
+ inputElement.dispatchEvent(new Event('change'));
+ fixture.detectChanges();
+
+ expect(component.bpm).toBe(120);
+ });
+});
diff --git a/frontend/src/app/components/bpm-input/bpm-input.component.ts b/frontend/src/app/components/bpm-input/bpm-input.component.ts
new file mode 100644
index 0000000..c397536
--- /dev/null
+++ b/frontend/src/app/components/bpm-input/bpm-input.component.ts
@@ -0,0 +1,37 @@
+import {Component, EventEmitter, Input, Output} from '@angular/core';
+import {SoundService} from "../../services/sound/sound.service";
+
+@Component({
+ selector: 'app-bpm-input',
+ standalone: true,
+ imports: [],
+ templateUrl: './bpm-input.component.html',
+ styleUrl: './bpm-input.component.scss'
+})
+export class BpmInputComponent {
+ maxBpm = SoundService.maxBpm;
+ minBpm = SoundService.minBpm;
+ @Input() bpm : number = SoundService.minBpm;
+ @Output() bpmChange = new EventEmitter();
+
+ incrementBpm() {
+ this.updateBpm(Math.min(this.bpm+1, this.maxBpm));
+ }
+
+ decrementBpm() {
+ this.updateBpm(Math.max(this.bpm-1, this.minBpm));
+ }
+
+ updateNumber(event: Event): void {
+ const inputElement = event.target as HTMLInputElement;
+ let value = Number(inputElement.value);
+ value = Math.min(value, this.maxBpm);
+ value = Math.max(value, this.minBpm);
+ this.updateBpm(value);
+ }
+
+ private updateBpm(value: number): void {
+ this.bpm = value;
+ this.bpmChange.emit(this.bpm);
+ }
+}
diff --git a/frontend/src/app/components/sequencer/sequencer.component.html b/frontend/src/app/components/sequencer/sequencer.component.html
index b868802..e9300c5 100644
--- a/frontend/src/app/components/sequencer/sequencer.component.html
+++ b/frontend/src/app/components/sequencer/sequencer.component.html
@@ -4,8 +4,7 @@
{{ this.soundService.isPlaying ? "⏸" : "▶" }}
-