Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import { IonicModule, IonicRouteStrategy } from '@ionic/angular';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, IonicModule.forRoot(
imports: [BrowserModule, HttpClientModule, IonicModule.forRoot(
{
mode: 'ios', // Set the mode to 'ios' for iOS style

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ <h3>JSON Server Response:</h3>

<div *ngIf="(displayState |async) as state" class="key-value-container">

<pre>{{ state.server| json }}</pre>
<pre>{{ state| json }}</pre>

</div>

Expand Down
102 changes: 55 additions & 47 deletions src/app/pages/dashboard/dashboard.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,68 +28,71 @@
<ion-fab-button class="custom-fab-button" color="light" [routerLink]="'/tabs/menu/server-status'">
<ion-icon [name]="lastServerResponseDeltaInSeconds < 2400?'wifi':'wifi-outline'"></ion-icon>
</ion-fab-button>
<div class="fab-label">{{lastServerResponseDeltaInSeconds < 240?'Online':'Offline'}}: {{lastServerResponseTime | date: 'dd.MM.yy HH:mm'}}</div>
</div>
<div class="col">
<ion-fab-button class="custom-fab-button" color="light" (click)="getPlayerStatus()">
<ion-icon [name]="numberOfPlayingStreams>0?'musical-note':'musical-note-outline'"></ion-icon>
</ion-fab-button>
<div class="fab-label">{{numberOfPlayingStreams +"/"+ totalStreams}} Stream(s) playing</div>
<div class="fab-label">{{lastServerResponseDeltaInSeconds < 240?'Online':'Offline'}}: {{lastServerResponseTime |
date: 'dd.MM.yy HH:mm' }}</div>
</div>
<div class="col">
<ion-fab-button class="custom-fab-button" color="light" (click)="getPlayerStatus()">
<ion-icon [name]="numberOfPlayingStreams>0?'musical-note':'musical-note-outline'"></ion-icon>
</ion-fab-button>
<div class="fab-label">{{numberOfPlayingStreams +"/"+ totalStreams}} Stream(s) playing</div>

</div>

</div>

</div>


</div>

</div>
<ng-container *ngIf="(displayState|async) as state else noState">
<div class="container">
<ion-list-header>
<ion-label><span *ngIf="userPreeferenceUsername as name">{{name ? name+"s": 'Your'}}</span>
Devices</ion-label>
<ion-button size="small" fill="clear" (click)="openModal()">
<ion-icon slot="icon-only" name="add-circle-outline"></ion-icon>
</ion-button>
</ion-list-header>
</div>

<ng-container *ngIf="(displayState|async) as state else noState">
<div class="container">
<ion-list-header>
<ion-label><span *ngIf="userPreeferenceUsername as name">{{name ? name+"s": 'Your'}}</span> Devices</ion-label>
<ion-button size="small" fill="clear" (click)="openModal()">
<ion-icon slot="icon-only" name="add-circle-outline"></ion-icon>
</ion-button>
</ion-list-header>
</div>

<div class="container-fluid">
<swiper (swiper)="onSwiper($event)" (slideChange)="onSlideChange($event)" [config]="swiperConfig">
<ng-container *ngFor="let group of state.server.groups; let i = index">
<ng-template swiperSlide *ngIf="group.clients[0].connected">

<div class="container-fluid">
<swiper (swiper)="onSwiper($event)" (slideChange)="onSlideChange($event)" [config]="swiperConfig">
<ng-container *ngFor="let group of state.server.groups; let i = index">
<ng-template swiperSlide *ngIf="group.clients[0].connected">
<app-snapcast-group-preview [streams]="state.server.streams" [group]="group"></app-snapcast-group-preview>
</ng-template>

<app-snapcast-group-preview [streams]="state.server.streams" [group]="group"></app-snapcast-group-preview>
</ng-template>
</ng-container>
<ng-container *ngFor="let group of state.server.groups; let i = index">
<ng-template swiperSlide *ngIf="group.clients[0].connected === false">
<app-snapcast-group-preview class="disconnected" [streams]="state.server.streams"
[group]="group"></app-snapcast-group-preview>
</ng-template>

</ng-container>
<ng-container *ngFor="let group of state.server.groups; let i = index">
<ng-template swiperSlide *ngIf="group.clients[0].connected === false">
<app-snapcast-group-preview class="disconnected" [streams]="state.server.streams"
[group]="group"></app-snapcast-group-preview>
</ng-template>
</ng-container>
</swiper>
</div>
<div class="container">

</ng-container>
</swiper>
</div>
<div class="container">

<ion-list-header>
<ion-label><span *ngIf="userPreeferenceUsername as name">{{name ? name+"s": 'Your'}}</span>
Streams</ion-label>
</ion-list-header>
<swiper (swiper)="onSwiper($event)" (slideChange)="onSlideChange($event)" [config]="swiperConfig">
<ng-template swiperSlide *ngFor="let stream of state.server.streams; let i = index">
<app-snapcast-stream-preview [stream]="stream"></app-snapcast-stream-preview>
</ng-template>
</swiper>
</div>
</ng-container>

<ion-list-header>
<ion-label><span *ngIf="userPreeferenceUsername as name">{{name ? name+"s": 'Your'}}</span> Streams</ion-label>
</ion-list-header>
<swiper (swiper)="onSwiper($event)" (slideChange)="onSlideChange($event)" [config]="swiperConfig">
<ng-template swiperSlide *ngFor="let stream of state.server.streams; let i = index">
<app-snapcast-stream-preview [stream]="stream"></app-snapcast-stream-preview>
</ng-template>
</swiper>
<!-- <app-snapcast-status></app-snapcast-status> -->
<div class="page-padding-bottom">
</div>
</ng-container>

<!-- <app-snapcast-status></app-snapcast-status> -->
<div class="page-padding-bottom">
</div>

</ion-content>

Expand Down Expand Up @@ -117,8 +120,13 @@
Wanna use a different server? Go to the <a routerLink="/tabs/menu/settings">Settings</a> page and change the
Snapcast server URL.
<br>
Just wana test test? Enable the Demo mode:


</ion-card-content>
<ion-button fill="clear" color="primary" (click)="enableDemoMode()">
<ion-icon name="play"></ion-icon> Enable Demo Mode
</ion-button>
</div>
</ng-template>
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/app/pages/dashboard/dashboard.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ export class DashboardPage implements OnInit {

}

enableDemoMode(): void {
console.log('Enabling demo mode...');
this.snapcastService.mockServerState()
this.isLoading = false;
}




Expand Down
15 changes: 15 additions & 0 deletions src/app/services/snapcast.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
import { environment } from 'src/environments/environment';
import { Preferences } from '@capacitor/preferences';
import { UserPreference } from '../enum/user-preference.enum';
import { HttpClient } from '@angular/common/http';

// --- Type Definitions ---
interface JsonRpcBaseRequest { jsonrpc: '2.0'; id: number; method: string; }
Expand Down Expand Up @@ -74,6 +75,7 @@ export class SnapcastService implements OnDestroy {
public readonly isConnected$ = new BehaviorSubject<boolean>(false).asObservable();

constructor(
private http: HttpClient
) {

this.state$ = this.stateSubject$.asObservable().pipe(
Expand Down Expand Up @@ -386,6 +388,19 @@ export class SnapcastService implements OnDestroy {
return this.state$.pipe(map(state => state?.server?.groups.flatMap(g => g.clients).find(c => c.id === clientId)));
}

public mockServerState(): void {
const url = "assets/mock/json/server-state.json"
this.http.get<SnapCastServerStatusResponse>(url).subscribe({
next: (data) => {
console.log('Mock server state loaded:', data);
this.stateSubject$.next(data);
},
error: (err) => {
console.error('Failed to load mock server state:', err);
}
});
}

// TODO: ... other get methods ...


Expand Down
173 changes: 173 additions & 0 deletions src/assets/mock/json/server-state.json

Large diffs are not rendered by default.