feat(ui): add remote-control URLs + fix header typos and env

Add support for displaying local remote-control URLs and QR code in the
Settings UI, including styles for URL list, row layout, monospaced links,
and a QR container. Expose a new global API signature getLocalIpAddresses
for retrieving local IPs.

Fix several UI issues:
- Correct typo in header method name (opedAddPlaylistDialog -> openAddPlaylistDialog).
- Fix malformed GitHub URL and collapse img tag formatting.
- Reformat imports and viewChild usage for readability.

Change local development backend URL to localhost:3000 in the local
environment to point to the running local API during development.

These changes improve developer ergonomics (local backend), add a remote
control discovery UX for users on the same network, and tidy up header
bugs and formatting.
This commit is contained in:
4gray committed 2025-12-06 21:46:35 +01:00
1 parent 7e4732a1bf
commit 3e2afe11e3
11 files changed
+171 -18

No files matched your search

@@ -7,6 +7,7 @@ import {
Input,
OnInit,
Optional,
signal,
} from '@angular/core';
import {
FormArray,
@@ -32,6 +33,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { QRCodeComponent } from 'angularx-qrcode';
import { DialogService } from 'components';
import * as PlaylistActions from 'm3u-state';
import { selectIsEpgAvailable } from 'm3u-state';
@@ -65,6 +67,7 @@ import { SettingsService } from './../services/settings.service';
ReactiveFormsModule,
TranslateModule,
MatDialogModule,
QRCodeComponent,
],
})
export class SettingsComponent implements OnInit {
@@ -158,6 +161,12 @@ export class SettingsComponent implements OnInit {
/** Form array with epg sources */
epgUrl = this.settingsForm.get('epgUrl') as FormArray;
/** Local IP addresses for remote control URL display */
localIpAddresses = signal<string[]>([]);
/** Currently visible QR code IP (null = none visible) */
visibleQrCodeIp = signal<string | null>(null);
private settingsStore = inject(SettingsStore);
constructor(
@@ -175,6 +184,28 @@ export class SettingsComponent implements OnInit {
await this.settingsStore.loadSettings();
this.setSettings();
this.checkAppVersion();
this.fetchLocalIpAddresses();
}
/**
* Fetches local IP addresses for remote control URL display
*/
async fetchLocalIpAddresses(): Promise<void> {
if (window.electron?.getLocalIpAddresses) {
const addresses = await window.electron.getLocalIpAddresses();
this.localIpAddresses.set(addresses);
}
}
/**
* Toggle QR code visibility for a given IP address
*/
toggleQrCode(ip: string): void {
if (this.visibleQrCodeIp() === ip) {
this.visibleQrCodeIp.set(null);
} else {
this.visibleQrCodeIp.set(ip);
}
}
/**