Skip to content

Commit

Permalink
Webapp: add support for Video Source setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
bennettpeter committed Sep 28, 2022
1 parent c7738b8 commit d21470b
Show file tree
Hide file tree
Showing 16 changed files with 757 additions and 15 deletions.
32 changes: 31 additions & 1 deletion mythtv/html/assets/i18n/en_US.json
Expand Up @@ -506,7 +506,37 @@
"deleted": "(Deleted)",
"new": "(New)"
},
"ru_sure": "Are you sure ?"
"ru_sure": "Are you sure ?",
"vsource": {
"title": "Video Sources",
"new_video_source": "New Video Source",
"delete_all": "Delete All Video Sources",
"delete_this": "Delete this Video Source",
"delete_details": "This will delete {{DisplayName}} ({{Grabber}})",
"item_title": "Video Source",
"source_label": "Video Source Name",
"source_desc": "This name is used for the xmltv configuration file. This is a required field.",
"grabber_label": "Listings grabber",
"grabber_desc": "Select the listings source. Some sources require you to have a subscription.",
"freqtable_label": "Channel Frequency Table",
"freqtable_desc": "Use default unless this source uses a different frequency table than the system wide table defined in the General settings.",
"scanfreq_label": "Scan Frequency",
"scanfreq_desc": "The frequency to start scanning this video source. This is then default for 'Full Scan (Tuned)' channel scanning. Frequency value in Hz for DVB-T/T2/C, in kHz for DVB-S/S2. Leave at 0 if not known.",
"netid_label": "Network ID",
"netid_desc": "If your provider has asked you to configure a specific network identifier (Network_ID), enter it here. Leave it at -1 otherwise.",
"bouquet_label": "Bouquet ID",
"bouquet_desc": "Bouquet ID for Freesat or Sky on satellite Astra-2 28.2E. Leave this at 0 if you do not receive this satellite. This is needed to get the Freesat and Sky channel numbers. Value 272 selects Freesat bouquet 'England HD'. See the MythTV Wiki <a href=\"https://www.mythtv.org/wiki/DVB_UK\" target=\"_blank\">https://www.mythtv.org/wiki/DVB_UK</a>.",
"region_label": "Region ID",
"region_desc": "Region ID for Freesat or Sky on satellite Astra-2 28.2E. Leave this at 0 you do not receive this satellite. This is needed to get the Freesat and Sky channel numbers. Value 1 selects region London. See the MythTV Wiki <a href=\"https://www.mythtv.org/wiki/DVB_UK\" target=\"_blank\">https://www.mythtv.org/wiki/DVB_UK</a>.",
"lcnoffset_label": "Logical Channel Number Offset",
"lcnoffset_desc": "The offset is added to each logical channel number found during a scan of a DVB video source. This makes it possible to give different video sources a non-overlapping range of channel numbers. Leave at 0 if you have only one video source or if the video sources do not have DVB logical channel numbers.",
"nameInUse": "ERROR: This name is already in use.",
"nameRequired": "Name is required.",
"grabberconfig_label": "Configure Grabber",
"grabberconfig_desc": "Configure the grabber by running this command using ssh or terminal logged into the backend:",
"eit_label": "Perform EIT scan",
"eit_desc": "If enabled, program guide data for channels on this source will be updated with data provided by the channels themselves 'Over-the-Air'."
}
},
"sidenav": {
"settingsmenu": {
Expand Down
17 changes: 13 additions & 4 deletions mythtv/html/backend/src/app/app-routing.module.ts
Expand Up @@ -8,15 +8,24 @@ import { TestbedComponent } from './testbed/testbed.component';
import { SettingsComponent } from './config/settings/general/general-settings.component';
import { CanDeactivateGuardService } from './can-deactivate-guard.service';
import { CaptureCardsComponent } from './config/settings/capture-cards/capture-cards.component';
import { VideoSourcesComponent } from './config/settings/video-sources/video-sources.component';

const routes: Routes = [
{ path: '', component: DashboardComponent },
{ path: 'status', component: StatusComponent },
{ path: 'setupwizard', component: SetupWizardComponent },
{ path: 'settings/general', component: SettingsComponent,
canDeactivate: [CanDeactivateGuardService] },
{ path: 'settings/capture-cards', component: CaptureCardsComponent,
canDeactivate: [CanDeactivateGuardService] },
{
path: 'settings/general', component: SettingsComponent,
canDeactivate: [CanDeactivateGuardService]
},
{
path: 'settings/capture-cards', component: CaptureCardsComponent,
canDeactivate: [CanDeactivateGuardService]
},
{
path: 'settings/video-sources', component: VideoSourcesComponent,
canDeactivate: [CanDeactivateGuardService]
},
{ path: 'testbed', component: TestbedComponent },
{ path: 'guide', component: GuideComponent },
];
Expand Down
4 changes: 4 additions & 0 deletions mythtv/html/backend/src/app/app.module.ts
Expand Up @@ -58,6 +58,8 @@ import { HdhomerunComponent } from './config/settings/capture-cards/hdhomerun/hd
import { IptvComponent } from './config/settings/capture-cards/iptv/iptv.component';
import { ImportComponent } from './config/settings/capture-cards/import/import.component';
import { DemoComponent } from './config/settings/capture-cards/demo/demo.component';
import { VideoSourcesComponent } from './config/settings/video-sources/video-sources.component';
import { VsourceComponent } from './config/settings/video-sources/vsource/vsource.component';

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
Expand Down Expand Up @@ -112,6 +114,8 @@ export function HttpLoaderFactory(http: HttpClient) {
IptvComponent,
ImportComponent,
DemoComponent,
VideoSourcesComponent,
VsourceComponent,
],
imports: [
BrowserModule,
Expand Down
Empty file.
@@ -0,0 +1,72 @@
<div class="block card w-full">
<h3>{{ 'settings.vsource.title' | translate }}</h3>

<p-button label="{{ 'settings.vsource.new_video_source' | translate }}" (onClick)="newSource();"
icon="pi pi-plus-circle" styleClass="p-button-plain"></p-button>
&nbsp;
<p-button styleClass="p-button-danger" label="{{ 'settings.vsource.delete_all' | translate }}"
(click)="displayDeleteAll=true" icon="pi pi-trash" iconPos="left">
</p-button>
<p-dialog header="{{ 'settings.vsource.delete_all' | translate }}" [(visible)]="displayDeleteAll" [modal]="true"
[style]="{width: '50vw'}" [draggable]="false" [resizable]="false">
<h2>{{ 'settings.ru_sure' | translate }}</h2>
<ng-template pTemplate="footer">
<p-button icon="pi pi-times-circle" (click)="displayDeleteAll=false" label="{{ 'common.no' | translate }}"
styleClass="p-button-plain">
</p-button>
<p-button icon="pi pi-check-circle" (click)="deleteAllSources()" label="{{ 'common.yes' | translate }}"
styleClass="p-button-plain"></p-button>
</ng-template>
</p-dialog>
<br>
<div class="grid nogutter">
<div class="col-12" *ngIf="this.expectedCount && this.successCount == this.expectedCount">
<br>
<p-message severity="success" text="{{ 'settings.common.successful_delete' | translate }}">
</p-message>
<br>
</div>
<div class="col-12" *ngIf="this.errorCount > 0">
<br>
<p-message severity="error" text="{{ 'common.networkfail' | translate }}">
</p-message>
<br>
</div>
</div>
<p-accordion class="col-12 w-full" (onClose)="onTabClose($event)" (onOpen)="onTabOpen($event)">
<p-accordionTab *ngFor="let source of videoSourceList.VideoSourceList.VideoSources; index as ix; first as isFirst"
[disabled]="disabledTab[ix]" [(selected)]="activeTab[ix]">
<ng-template pTemplate="header">
<div class="grid w-full">
<div class="col-9 pr-1">
{{videoSourceList.VideoSourceList.VideoSources[ix].SourceName}}
({{videoSourceList.VideoSourceList.VideoSources[ix].Grabber}})
<b>&nbsp;{{ dirtyMessages[ix] }}</b>
</div>
</div>
</ng-template>
<ng-template pTemplate="content">
<p-button styleClass="p-button-warning" label="{{ 'settings.vsource.delete_this' | translate }}"
icon="pi pi-trash" (onClick)="displayDeleteThis[ix]=true"
[disabled]="(!this.videoSourceList.VideoSourceList.VideoSources[ix].Id)">
</p-button>
<p-dialog header="{{ 'settings.vsource.delete_this' | translate }}" [(visible)]="displayDeleteThis[ix]"
[modal]="true" [style]="{width: '50vw'}" [draggable]="false" [resizable]="false">
<h2>{{ 'settings.ru_sure' | translate }}</h2>
<p>{{ 'settings.vsource.delete_details' |
translate: {Grabber: videoSourceList.VideoSourceList.VideoSources[ix].Grabber,
DisplayName: videoSourceList.VideoSourceList.VideoSources[ix].SourceName} }}</p>
<ng-template pTemplate="footer">
<p-button icon="pi pi-times-circle" (click)="displayDeleteThis[ix]=false"
label="{{ 'common.no' | translate }}" styleClass="p-button-plain">
</p-button>
<p-button icon="pi pi-check-circle" (click)="deleteThis(ix)"
label="{{ 'common.yes' | translate }}" styleClass="p-button-plain"></p-button>
</ng-template>
</p-dialog>
<app-vsource [videoSource]="videoSourceList.VideoSourceList.VideoSources[ix]"
[videoSourceList]="videoSourceList"></app-vsource>
</ng-template>
</p-accordionTab>
</p-accordion>
</div>
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { VideoSourcesComponent } from './video-sources.component';

describe('VideoSourcesComponent', () => {
let component: VideoSourcesComponent;
let fixture: ComponentFixture<VideoSourcesComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ VideoSourcesComponent ]
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(VideoSourcesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

0 comments on commit d21470b

Please sign in to comment.