Skip to content

Commit 468ada6

Browse files
authored
Merge pull request #44 from byrdsandbytes/feature/sc-2149-finish-soundcard-picker
Feature/sc 2149 finish soundcard picker
2 parents a97fa37 + a438874 commit 468ada6

File tree

12 files changed

+208
-118
lines changed

12 files changed

+208
-118
lines changed

src/app/components/camilla-dsp/camilla-dsp.component.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
// text-transform: uppercase;
3232
letter-spacing: 2px;
3333
margin-bottom: 1.5rem;
34-
color: #ccc;
34+
// color: #ccc;
3535
text-align: center;
36-
text-shadow: 0 2px 4px rgba(0, 0, 0, 1);
36+
// text-shadow: 0 2px 4px rgba(0, 0, 0, 1);
3737
// background-color: #111;
3838
display: inline-block;
3939
padding: 4px 12px;

src/app/components/camilla-dsp/camilla-dsp.component.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export class CamillaDspComponent implements OnInit, OnDestroy {
7979

8080

8181

82-
connect() {
82+
connect() {
8383
return this.camillaService.connect(this.url);
8484
}
8585

@@ -164,4 +164,9 @@ export class CamillaDspComponent implements OnInit, OnDestroy {
164164
this.camillaService.stopLevelUpdates();
165165
this.camillaService.disconnect();
166166
}
167+
168+
ionViewWillLeave() {
169+
console.log('CamillaDspComponent: Leaving page, cleaning up resources if needed');
170+
this.ngOnDestroy();
171+
}
167172
}
Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,47 @@
11
<ion-header>
22
<ion-toolbar color="light">
33
<ion-title>Soundcard Picker</ion-title>
4+
<ion-buttons slot="start">
5+
<!-- cllose modal -->
6+
<ion-button (click)="dismiss()">
7+
Cancel
8+
</ion-button>
9+
</ion-buttons>
10+
<ion-buttons slot="end">
11+
<ion-button (click)="dismiss()" [disabled]="!selectedHatId">
12+
Select
13+
</ion-button>
14+
</ion-buttons>
415
</ion-toolbar>
516
<ion-toolbar color="light">
617
<ion-searchbar (ionInput)="filterHats($event.target.value)"></ion-searchbar>
718

819
</ion-toolbar>
920
</ion-header>
1021
<ion-content>
22+
<div class="container">
23+
<div class="row">
24+
<div class="col-6" [class.selected]="selectedHatId == hat.id" *ngFor="let hat of filteredHats"
25+
(click)="selectedHatId = hat.id">
26+
<!-- checkmark -->
27+
<div class="checkmark">
28+
<ion-icon *ngIf="selectedHatId == hat.id" name="checkmark-circle" color="primary"></ion-icon>
29+
</div>
30+
<img [src]="'assets/soundcards/' + hat.id + '.webp'" #myImage
31+
(error)="myImage.src = 'assets/placeholder/audio_board_placeholder.webp'" />
32+
<ion-card-header>
33+
<ion-card-subtitle>{{ hat.name }}</ion-card-subtitle>
34+
</ion-card-header>
35+
<ion-card-content>
36+
<ion-badge color="primary" *ngIf="hat.testedbyBeatnik">Tested by Beatnik</ion-badge>
37+
<ion-badge color="secondary" *ngIf="hat.testedByCommunity">Tested by Community</ion-badge>
38+
<p>ID: {{ hat.id }}</p>
39+
<p>dt Overlay: {{ hat.overlay}}</p>
40+
<p>Format: {{hat.camilla.format}}</p>
41+
</ion-card-content>
1142

43+
</div>
1244

13-
<div class="row">
14-
<div class="col-6" *ngFor="let hat of filteredHats">
15-
16-
<ion-img [src]="'assets/soundcards/' + hat.id + '.webp'" />
17-
<!-- make sure image source is valid -->
18-
<ion-card-header>
19-
<ion-card-subtitle>{{ hat.name }}</ion-card-subtitle>
20-
21-
</ion-card-header>
22-
<ion-card-content>
23-
<ion-badge color="primary" *ngIf="hat.testedbyBeatnik">Tested by Beatnik</ion-badge>
24-
<ion-badge color="secondary" *ngIf="hat.testedByCommunity">Tested by Community</ion-badge>
25-
<p>ID: {{ hat.id }}</p>
26-
<p>dt Overlay: {{ hat.overlay}}</p>
27-
<p>Format: {{hat.camilla.format}}</p>
28-
</ion-card-content>
2945
</div>
30-
3146
</div>
3247
</ion-content>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.selected {
2+
border: 2px solid var(--ion-color-primary);
3+
border-radius: 8px 8px 0 0;
4+
}
5+
6+
.checkmark {
7+
margin: 8px;
8+
height: 40px;
9+
text-align: end;
10+
}
11+
12+
ion-badge{
13+
font-size:12px;
14+
}

src/app/components/soundcard-picker/soundcard-picker.component.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import { Component, Input, OnInit } from '@angular/core';
2+
import { ModalController } from '@ionic/angular';
23
import { SUPPORTED_HATS } from 'src/app/constant/hat.constant';
34

45
@Component({
@@ -8,11 +9,15 @@ import { SUPPORTED_HATS } from 'src/app/constant/hat.constant';
89
standalone: false
910
})
1011
export class SoundcardPickerComponent implements OnInit {
12+
@Input() clientId: string = '';
13+
@Input() selectedHatId: string = '';
1114

1215
hats = Object.values(SUPPORTED_HATS);
1316
filteredHats = this.hats;
1417

15-
constructor() { }
18+
constructor(
19+
private modalCtrl: ModalController
20+
) { }
1621

1722
ngOnInit() {
1823
this.initAndSortHats();
@@ -45,4 +50,12 @@ export class SoundcardPickerComponent implements OnInit {
4550
this.filteredHats = this.hats;
4651
}
4752

53+
dismiss() {
54+
// Pass the selected hat ID back to the parent component
55+
console.log('Selected Hat ID:', this.selectedHatId);
56+
57+
this.modalCtrl.dismiss({
58+
selectedHatId: this.selectedHatId
59+
});}
60+
4861
}

src/app/pages/clients/client-details/client-details.page.html

Lines changed: 54 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,32 @@
1414
</ion-toolbar>
1515
</ion-header>
1616
<!-- <ion-toolbar class="ion-no-padding ion-no-margin" color="light"> -->
17-
<ion-segment color="primary" [(ngModel)]="segment" [scrollable]="true">
18-
<ion-segment-button value="camilla-dsp">
19-
<ion-label>Camilla DSP</ion-label>
20-
</ion-segment-button>
17+
<ion-segment color="primary" [(ngModel)]="segment" [scrollable]="true">
18+
<ion-segment-button value="camilla-dsp">
19+
<ion-label>Camilla DSP</ion-label>
20+
</ion-segment-button>
2121

22-
<ion-segment-button value="soundcard">
23-
<ion-label>
24-
Soundcard</ion-label>
25-
</ion-segment-button>
22+
<ion-segment-button value="soundcard">
23+
<ion-label>
24+
Soundcard</ion-label>
25+
</ion-segment-button>
2626

2727

28-
<ion-segment-button value="details">
29-
<ion-label>Info</ion-label>
30-
</ion-segment-button>
28+
<ion-segment-button value="details">
29+
<ion-label>Info</ion-label>
30+
</ion-segment-button>
3131

32-
<ion-segment-button value="settings">
33-
<ion-label>Settings</ion-label>
34-
</ion-segment-button>
35-
</ion-segment>
32+
<ion-segment-button value="settings">
33+
<ion-label>Settings</ion-label>
34+
</ion-segment-button>
35+
</ion-segment>
3636
<!-- </ion-toolbar> -->
3737

3838
<ng-container *ngIf="segment === 'details'">
3939
<ion-list *ngIf="serverState | async as state">
40+
<ion-item *ng>
41+
42+
</ion-item>
4043
<ion-item>
4144
<ion-label>
4245
<h2>Snap Client Information</h2>
@@ -84,47 +87,50 @@ <h2>Camilla DSP Information</h2> -->
8487
</ng-container>
8588

8689
<ng-container *ngIf="segment === 'soundcard'">
87-
<ion-button expand="full" color="primary" (click)="getHardwareInfo()">
88-
Refresh Soundcard Info
89-
</ion-button>
90+
9091
<ion-list *ngIf="hardwareStatus$ | async as hardwareStatus">
91-
<ion-item>
92+
<ion-card>
9293
<ion-label>
9394
<h2>Soundcard Information</h2>
9495
<hr />
95-
<h3>Detected Hardware </h3>
96-
<ng-container *ngIf="hardwareStatus.detectedHardware; else noHardware">
9796

98-
<p>Name: {{ hardwareStatus.detectedHardware.name}}</p>
99-
<p>Id: {{ hardwareStatus.detectedHardware.id}}</p>
100-
<p>isMatched: {{ hardwareStatus.isMatch}}</p>
101-
</ng-container>
102-
<ng-template #noHardware>
103-
<p>No hardware detected.</p>
104-
</ng-template>
10597
<ng-container *ngIf="hardwareStatus.currentConfig; else noConfig">
10698
<hr />
10799
<h3>Config Status </h3>
100+
<img [src]="'assets/soundcards/' + hardwareStatus.currentConfig.id + '.webp'" #myImage
101+
(error)="myImage.src = 'assets/placeholder/audio_board_placeholder.webp'" />
108102
<p>Name: {{ hardwareStatus.currentConfig.name}}</p>
109103
<p>Id: {{ hardwareStatus.currentConfig.id}}</p>
110104
<p>isMatched: {{ hardwareStatus.isMatch}}</p>
111105
</ng-container>
106+
<ion-button expand="full" color="primary" (click)="openSoundcardPicker()">
107+
<ion-icon name="create" slot="start"></ion-icon>
108+
Choose Soundcard
109+
</ion-button>
112110
<ng-template #noConfig>
113111
<p>No current configuration available.</p>
114112
</ng-template>
113+
<!-- <h3>Detected Hardware </h3>
114+
<ng-container *ngIf="hardwareStatus.detectedHardware; else noHardware">
115+
116+
<p>Name: {{ hardwareStatus.detectedHardware.name}}</p>
117+
<p>Id: {{ hardwareStatus.detectedHardware.id}}</p>
118+
<p>isMatched: {{ hardwareStatus.isMatch}}</p>
119+
</ng-container>
120+
<ng-template #noHardware>
121+
<p>No hardware detected.</p>
122+
</ng-template> -->
123+
115124

116-
<ion-button expand="full" color="tertiary"
117-
(click)="openSoundcardPicker()">
118-
Open Soundcard Picker
119-
</ion-button>
120125

121-
<ion-button expand="full" color="secondary"
126+
127+
<!-- <ion-button expand="full" color="secondary"
122128
(click)="applySoundcardConfig(hardwareStatus.detectedHardware.id)">
123129
Apply Detected Soundcard Config
124-
</ion-button>
130+
</ion-button> -->
125131
</ion-label>
126-
</ion-item>
127-
<ion-item>
132+
</ion-card>
133+
<!-- <ion-item>
128134
Manual Soundcard Config ID:
129135
<ion-select placeholder="Select Soundcard" [(ngModel)]="manualHatId">
130136
<ion-select-option *ngFor="let hat of hats" [value]="hat.id">
@@ -135,8 +141,11 @@ <h3>Config Status </h3>
135141
</ion-item>
136142
<ion-button expand="full" color="secondary" (click)="applySoundcardConfig(manualHatId)">
137143
Apply Manual Soundcard Config
138-
</ion-button>
144+
</ion-button> -->
139145
</ion-list>
146+
<ion-button fill="clear" expand="full" color="primary" (click)="getHardwareInfo()">
147+
<u>Refresh Soundcard Info</u>
148+
</ion-button>
140149
</ng-container>
141150

142151
<ng-container *ngIf="segment === 'settings'">
@@ -160,63 +169,25 @@ <h3>Snapcast Server Status</h3>
160169
Enable Snapcast Server
161170
</ion-button>
162171

172+
<!-- <ion-button expand="full" color="primary" (click)="chooseSpeakers()">
173+
Choose Speakers
174+
</ion-button> -->
175+
176+
163177
</div>
164178
</ng-container>
165179
<ng-container *ngIf="segment === 'camilla-dsp'">
166180
<app-camilla-dsp *ngIf="camillaDspUrl" [url]="camillaDspUrl"></app-camilla-dsp>
167181
</ng-container>
168182

169183

170-
<!-- <ion-list *ngIf="serverState | async as state">
171-
<ion-item>
172-
<ion-label>
173-
<h2>Connection Status</h2>
174-
<p>Last Seen: {{ client.lastSeen.sec * 1000 | date: 'long' }}</p>
175-
<p>Status: {{ client.connected ? 'Connected' : 'Disconnected' }}</p>
176-
<p>Id: {{ client.id }}</p>
177-
178-
<ng-container *ngIf="state.server.groups">
179-
<ng-container *ngFor="let group of state.server.groups">
180-
<ng-container *ngFor="let client of group.clients">
181-
<p *ngIf="client.id === id">Group: {{ group.name }}</p>
182-
</ng-container>
183-
</ng-container>
184-
184+
185185

186-
</ng-container>
187-
</ion-label>
188-
<ion-button fill="outline" slot="end" (click)="refreshClient()">
189-
<ion-icon name="refresh"></ion-icon>
190-
Refresh
191-
</ion-button>
192-
</ion-item>
193-
194-
<ion-item>
195-
<ion-input label="Name" labelPlacement="floating" type="text" placeholder="Enter client name"
196-
[(ngModel)]="client.config.name" (ngModelChange)="setClientName()"></ion-input>
197-
</ion-item>
198-
<ion-item>
199-
<ion-input label="Latency (in ms)" labelPlacement="floating" type="number" placeholder="Enter latency in ms"
200-
[(ngModel)]="client.config.latency" (ngModelChange)="setClientLatency()"></ion-input>
201-
</ion-item>
202-
<ion-item lines="none">
203-
<ion-input label="Volume (0-100%)" labelPlacement="floating" type="number" placeholder="Enter volume percentage"
204-
[(ngModel)]="client.config.volume.percent" (ngModelChange)="setClientVolume()"></ion-input>
205-
</ion-item>
206-
<ion-item>
207-
<ion-range [(ngModel)]="client.config.volume.percent" (ngModelChange)="setClientVolume()">
208-
209-
<ion-icon slot="start" name="volume-low"></ion-icon>
210-
<ion-icon slot="end" name="volume-high"></ion-icon>
211-
</ion-range>
212-
</ion-item>
213-
214-
<ion-button expand="full" color="primary" (click)="chooseSpeakers()">
186+
<!-- <ion-button expand="full" color="primary" (click)="chooseSpeakers()">
215187
Choose Speakers
216-
</ion-button>
188+
</ion-button> -->
217189

218190

219-
</ion-list> -->
220191

221192

222193
</ion-content>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ion-card {
2+
box-shadow: none;
3+
}

0 commit comments

Comments
 (0)