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
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Changelog

## [0.2.2] - 2025-08-12

### Added
- Add missing android icon
- Add Android assets
- Add terms of service
- Add privacy policy

### Fixed
- Fix navigation for iPad
- Adapt device detail navigation to prevent screen squeeze
- Fix navigation issues resulting in cropped of screens
- Hide modal when user leaves tab view
- Fix webview serving over https while snapcast websocket is not served over wss

### Changed
- Make "stream" routing standalone
- Adapt client navigation
- Format changelog

### Removed
- Remove deprecated getclient func
- Remove codeql.yml workflow

## [0.2.1] - 2025-08-01

### Added
Expand Down
File renamed without changes
File renamed without changes
Binary file added assets/icon-foreground_512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
16 changes: 15 additions & 1 deletion capacitor.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import type { CapacitorConfig } from '@capacitor/cli';
import { KeyboardResize, KeyboardStyle } from '@capacitor/keyboard';


const config: CapacitorConfig = {
appId: 'ch.byrds.beatnik',
appName: 'Beatnik',
webDir: 'www'
webDir: 'www',
// handle insecure websocket connections
server: {
androidScheme: 'http',
cleartext: true
},
plugins: {
Keyboard: {
resize: KeyboardResize.Body,
style: KeyboardStyle.Dark,
resizeOnFullScreen: true,
},
},
};

export default config;
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "beatnik",
"version": "0.2.1",
"version": "0.2.2",
"author": "byrds & bytes gmbh",
"homepage": "https://beatnik.ch",
"scripts": {
Expand Down
87 changes: 60 additions & 27 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,73 @@ const routes: Routes = [
path: '',
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
},
// {
// path: 'streams',
// loadChildren: () => import('./pages/streams/streams.module').then( m => m.StreamsPageModule)
// },
// {
// path: 'dashboard',
// loadChildren: () => import('./pages/dashboard/dashboard.module').then( m => m.DashboardPageModule)
// },
{
path: 'server-status',
loadChildren: () => import('./pages/server-status/server-status.module').then( m => m.ServerStatusPageModule)
loadChildren: () => import('./pages/server-status/server-status.module').then(m => m.ServerStatusPageModule)
},
// {
// path: 'client-details',
// loadChildren: () => import('./pages/client-details/client-details.module').then( m => m.ClientDetailsPageModule)
// },
// {
// path: 'settings',
// loadChildren: () => import('./pages/settings/settings.module').then( m => m.SettingsPageModule)
// },
// {
// path: 'stream-details',
// loadChildren: () => import('./pages/streams/stream-details/stream-details.module').then( m => m.StreamDetailsPageModule)
// },
// {
// path: 'menu',
// loadChildren: () => import('./pages/menu/menu.module').then( m => m.MenuPageModule)
// },

{
path: 'devices',
children: [
{
path: '',
loadChildren: () => import('./pages/devices/devices.module').then(m => m.DevicesPageModule)
},
{
path: ':id',
loadChildren: () => import('./pages/devices/device-details/device-details.module').then(m => m.DeviceDetailsPageModule)
}
]
},
{
path: 'clients',
children: [
{
path: ':id',
loadChildren: () => import('./pages/clients/client-details/client-details.module').then(m => m.ClientDetailsPageModule)
}
]
},
{
path: 'streams',
children: [
{
path: '',
loadChildren: () => import('./pages/streams/streams.module').then(m => m.StreamsPageModule)
},
{
path: ':id',
loadChildren: () => import('./pages/streams/stream-details/stream-details.module').then(m => m.StreamDetailsPageModule)
}
]
},
{
path: 'menu',
children: [
{
path: '',
loadChildren: () => import('./pages/menu/menu.module').then(m => m.MenuPageModule)
},



// {
// path: 'about',
// loadChildren: () => import('./pages/about/about.module').then(m => m.AboutPageModule)
// }

]
},
{
path: 'settings',
loadChildren: () => import('./pages/settings/settings.module').then(m => m.SettingsPageModule)
},


];
@NgModule({
imports: [
RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
export class AppRoutingModule { }
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<ion-content color="dark">
<ion-toolbar class="play-toolbar" color="dark">
<ng-container *ngIf="(displayState$|async) as state ">
<ng-container *ngFor="let stream of state.server.streams">
Expand Down Expand Up @@ -46,4 +47,5 @@ <h2> {{ stream.properties.metadata.title }}</h2>
</ng-container>
</ng-container>

</ion-toolbar>
</ion-toolbar>
</ion-content>
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class SnapcastGroupPreviewComponent implements OnInit, OnChanges {
}
// Navigate to the group details page using the group's ID
// Assuming you have a route set up for group details like '/group-details/:id'
this.router.navigate(['tabs/dashboard/devices', this.group.id]);
this.router.navigate(['devices', this.group.id]);
}

checkClientOnlineState(client: any): string {
Expand Down
3 changes: 3 additions & 0 deletions src/app/pages/clients/client-details/client-details.page.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs"></ion-back-button>
</ion-buttons>
<ion-title>client-details</ion-title>
</ion-toolbar>
</ion-header>
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/dashboard/dashboard.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<div class="fab-label">{{numberOfPlayingClients +"/"+ totalClients}} Client(s) playing</div>
</div>
<div class="col col-4 col-lg-2 fab-container">
<ion-fab-button class="custom-fab-button" color="light" [routerLink]="'/tabs/menu/server-status'">
<ion-fab-button class="custom-fab-button" color="light" [routerLink]="'/server-status'">
<ion-icon [name]="lastServerResponseDeltaInSeconds < 2400?'wifi':'wifi-outline'"></ion-icon>
</ion-fab-button>
<div class="fab-label">{{lastServerResponseDeltaInSeconds < 240?'Online':'Offline'}}: {{lastServerResponseTime |
Expand Down
4 changes: 2 additions & 2 deletions src/app/pages/devices/devices.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<ion-list-header>
<ion-label>Device Groups</ion-label>
</ion-list-header>
<ion-item *ngFor="let group of state.server.groups" [routerLink]="['/tabs/devices', group.id]">
<ion-item *ngFor="let group of state.server.groups" [routerLink]="['/devices', group.id]">
<ion-label>
<h2>{{ group.name || group.id }}</h2>
<p>Clients: {{ group.clients.length }}</p>
Expand All @@ -27,7 +27,7 @@ <h2>{{ group.name || group.id }}</h2>
</ion-list-header>
<ng-container *ngFor="let group of state.server.groups">
<ng-container *ngFor="let client of group.clients">
<ion-item [routerLink]="['/tabs/clients', client.id]">
<ion-item [routerLink]="['/clients', client.id]">
<ion-label>
<h2> {{ client.config.name || client.id }}
</h2>
Expand Down
8 changes: 0 additions & 8 deletions src/app/pages/menu/menu-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ const routes: Routes = [
{
path: '',
component: MenuPage
},
{
path: 'settings',
loadChildren: () => import('../settings/settings.module').then(m => m.SettingsPageModule)
},
{
path: 'server-status',
loadChildren: () => import('../server-status/server-status.module').then(m => m.ServerStatusPageModule)
}
];

Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/menu/menu.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ion-toolbar>
</ion-header>
<ion-list>
<ion-item button routerLink="settings">
<ion-item button routerLink="/settings">
<ion-icon slot="start" name="settings"></ion-icon>
<ion-label>Settings</ion-label>
</ion-item>
Expand Down
3 changes: 3 additions & 0 deletions src/app/pages/server-status/server-status.page.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs"></ion-back-button>
</ion-buttons>
<ion-title>Snapcast Server Status</ion-title>
</ion-toolbar>
</ion-header>
Expand Down
9 changes: 7 additions & 2 deletions src/app/pages/settings/settings.page.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs"></ion-back-button>
</ion-buttons>
<ion-title>Settings</ion-title>
</ion-toolbar>
</ion-header>
Expand All @@ -14,10 +17,12 @@
</ion-header>
<ion-list>
<ion-item>
<ion-input labelPlacement="floating" label="Username" (ionInput)="setUserName()" type="text" placeholder="Enter your name" [(ngModel)]="userName"></ion-input>
<ion-input labelPlacement="floating" label="Username" (ionInput)="setUserName()" type="text"
placeholder="Enter your name" [(ngModel)]="userName"></ion-input>
</ion-item>
<ion-item>
<ion-input labelPlacement="floating" label="Server Url" (ionInput)="setServerUrl()" type="text" placeholder="Enter server URL" [(ngModel)]="serverUrl"></ion-input>
<ion-input labelPlacement="floating" label="Server Url" (ionInput)="setServerUrl()" type="text"
placeholder="Enter server URL" [(ngModel)]="serverUrl"></ion-input>
</ion-item>

</ion-list>
Expand Down
3 changes: 3 additions & 0 deletions src/app/pages/streams/stream-details/stream-details.page.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button defaultHref="/tabs"></ion-back-button>
</ion-buttons>
<ion-title>stream-details</ion-title>
</ion-toolbar>
</ion-header>
Expand Down
6 changes: 3 additions & 3 deletions src/app/pages/streams/streams.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
</ion-header>

<ion-list *ngIf="displayState | async as state">
<div *ngFor="let stream of state.server.streams" [routerLink]="['/tabs/streams', stream.id]">

<div *ngFor="let stream of state.server.streams" [routerLink]="['/streams', stream.id]">
<app-snapcast-stream-preview *ngIf="stream.status != 'idle'" [stream]="stream"></app-snapcast-stream-preview>
</div>
<ion-list-header>
<ion-label>Inactive Streams</ion-label>
</ion-list-header>
<div *ngFor="let stream of state.server.streams" [routerLink]="['/tabs/streams', stream.id]">
<div *ngFor="let stream of state.server.streams" [routerLink]="['/streams', stream.id]">
<app-snapcast-stream-preview *ngIf="stream.status == 'idle'" [stream]="stream"></app-snapcast-stream-preview>
</div>
</ion-list>
Expand Down
24 changes: 12 additions & 12 deletions src/app/tabs/tabs-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ const routes: Routes = [
path: '',
loadChildren: () => import('../pages/streams/streams.module').then(m => m.StreamsPageModule)
},
{
path: ':id',
loadChildren: () => import('../pages/streams/stream-details/stream-details.module').then(m => m.StreamDetailsPageModule)
}
// {
// path: ':id',
// loadChildren: () => import('../pages/streams/stream-details/stream-details.module').then(m => m.StreamDetailsPageModule)
// }
]
},

Expand All @@ -42,10 +42,10 @@ const routes: Routes = [
path: '',
loadChildren: () => import('../pages/devices/devices.module').then(m => m.DevicesPageModule)
},
{
path: ':id',
loadChildren: () => import('../pages/devices/device-details/device-details.module').then(m => m.DeviceDetailsPageModule)
}
// {
// path: ':id',
// loadChildren: () => import('../pages/devices/device-details/device-details.module').then(m => m.DeviceDetailsPageModule)
// }
]
},
{
Expand All @@ -54,10 +54,10 @@ const routes: Routes = [
// { path: '',
// loadChildren: () => import('../pages/clients/clients.module').then(m => m.ClientsPageModule)
// },
{
path: ':id',
loadChildren: () => import('../pages/clients/client-details/client-details.module').then(m => m.ClientDetailsPageModule)
}
// {
// path: ':id',
// loadChildren: () => import('../pages/clients/client-details/client-details.module').then(m => m.ClientDetailsPageModule)
// }
]
},
{
Expand Down
17 changes: 0 additions & 17 deletions src/app/tabs/tabs.page.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,6 @@
<ion-tabs>
<!-- <div class="bottom-sheet" *ngIf="isModalOpen" #bottomSheet>
<div class="drag-handle"></div>
<div class="modal-content">
<app-player-toolbar class="player-toolbar"></app-player-toolbar>
</div>
</div> -->
<div class="page-padding-bottom">
</div>

<ion-modal #modal trigger="open-modal" [isOpen]="true" [initialBreakpoint]="0.25"
[breakpoints]="[0.05,0.25, 0.5, 0.75]" [backdropDismiss]="false" [backdropBreakpoint]="0.5"
[cssClass]="'player-modal'" [animated]="true" [keyboardClose]="true" [showBackdrop]="true">
<ng-template>
<ion-content color="dark" [fullscreen]="true">
<app-player-toolbar class="player-toolbar"></app-player-toolbar>
</ion-content>
</ng-template>
</ion-modal>

<ion-tab-bar class="tabbar" slot="bottom" color="dark">
<ion-tab-button tab="dashboard" href="/tabs/dashboard">
<ion-icon aria-hidden="true" name="home-outline"></ion-icon>
Expand Down
Loading