Skip to content

Commit

Permalink
web-app: Support scheduling recordings from program guide
Browse files Browse the repository at this point in the history
From program guide you can schedule a recoording by clicking the program
in the grid. All of the options provided by mythfrontend are available,
except the auto extend option, because the API does not yet support that.
  • Loading branch information
bennettpeter committed May 30, 2023
1 parent cc0db03 commit 4e6df85
Show file tree
Hide file tree
Showing 19 changed files with 1,010 additions and 80 deletions.
67 changes: 66 additions & 1 deletion mythtv/html/assets/i18n/en_US.json
Expand Up @@ -53,7 +53,8 @@
"season": "Season",
"episode": "Episode",
"canundel": "You can reverse this by using Undelete.",
"alreadydel": "Already Deleted"
"alreadydel": "Already Deleted",
"edit_metadata": "Edit Metadata"
},
"upcoming": {
"heading": "Upcoming",
Expand All @@ -62,6 +63,70 @@
"status": "Status",
"showall": "Show All",
"encoder": "Encoder"
},
"sched": {
"type": {
"del_template": "Delete this recording rule template",
"mod_template": "Modify this recording rule template",
"del_override": "Record this showing with normal options",
"rec_override": "Record this showing with override options",
"dont_rec_override": "Do not record this showing",
"not": "Do Not Record This Program",
"this": "Record Only This Showing",
"one": "Record Only One Showing",
"weekly": "Record one showing every week",
"daily": "Record one showing every day",
"all": "Record All Showings"
},
"type_label": "Schedule Type",
"recgroup_label": "Recording Group",
"active_label": "Recording Rule is Active",
"playgroup_label": "Playback Group",
"newepis_label": "Record New Episodes Only",
"startoffset_label": "Number of Extra Minutes to Record at Start",
"endoffset_label": "Number of Extra Minutes to Record at End",
"priority_label": "Recording Priority",
"input_any": "Any Input",
"prefinput_label": "Preferred Input",
"dupmethod": {
"none": "Don't Match Duplicates",
"s_and_d": "Match Using Subtitle & Description",
"s_then_d": "Match Using Subtitle Then Description",
"s": "Match Duplicates Using Subtitle",
"d": "Match Duplicates Using Description"
},
"dupmethod_label": "Duplicate Match Method",
"dupin": {
"both": "Current and Previous Recordings",
"curr": "Current Recordings Only",
"prev": "Previous Recordings Only"
},
"dupin_label": "Duplicate Search Scope",
"filters_label": "Filter Options",
"recprof": {
"default": "Default",
"livetv": "Live TV",
"highq": "High Quality",
"lowq": "Low Quality"
},
"recprofile_label": "Recording Profile",
"sgroup_label": "Storage Group",
"maxeps_label": "Maximum Number of Episodes to Keep",
"maxnewest_label": "Deletion on Maximum Episodes",
"maxnewest_desc": "If unchecked, stop recording when maximum episodes are reached.",
"autoexpire_label": "Auto Expire",
"postproc": {
"autocommflag": "Commercial Flag Recordings",
"autometalookup": "Look up MetaData",
"autotranscode": "Transcode Recordings"
},
"postproc_label": "Post Processing Options",
"inetref_label": "Metadata Lookup Id (InetRef)",
"inetref_desc": "Use TheTVDB, TVmaze or TMDB to look up recording metadata. Select a radio button above and use the link to search the web site. Once you find the correct series on the web page, select it and copy the numeric id from the URL, or from the web page in the case of thetvdb.com. Enter that in the input box immediately after the prefix xxxx.py_",
"template_label": "Use Template",
"template_apply": "Apply Template Change",
"isearch": "Search",
"heading": "Schedule recording"
}
},
"navbar": {
Expand Down
Expand Up @@ -322,13 +322,11 @@ export class ChannelEditorComponent implements OnInit {
);
}

// Since the dialog is modal we may not actually need this function
confirm(message?: string): Observable<boolean> {
const confirmation = window.confirm(message);
return of(confirmation);
};

// Since the dialog is modal we may not actually need this function
canDeactivate(): Observable<boolean> | boolean {
if (this.currentForm && this.currentForm.dirty)
return this.confirm(this.warningText);
Expand Down
Expand Up @@ -72,7 +72,7 @@ <h2>{{ 'dashboard.recordings.heading' | translate }}</h2>
</ng-template>
</p-table>

<p-dialog header="Edit Metadata" [(visible)]="displayMetadataDlg" [modal]="true"
<p-dialog header="{{ 'dashboard.recordings.edit_metadata' | translate }}" [(visible)]="displayMetadataDlg" [modal]="true"
[style]="{height: '75vw', width: '50vw'}" [closable]="false" [closeOnEscape]="false">

<div class="form-group field">
Expand Down
@@ -1,4 +1,4 @@
<div class="programBox cursor-pointer" [style.width.%]=durationToWidth() (click)="showDetailsDialog()">
<div class="programBox cursor-pointer" [style.width.%]=durationToWidth() (click)="openDialog()">
<div class="programTitle">{{ program.Title }}</div>
<div class="programBody">
<div *ngIf="program.SubTitle.length != 0">
Expand All @@ -12,10 +12,10 @@
<div class="programDescription">{{ program.Description }}</div>
</div>
</div>
<p-dialog header=" {{ program.Title }} : {{ program.SubTitle }}" [(visible)]="editSchedule" [modal]="true"
<!-- <p-dialog header=" {{ program.Title }} : {{ program.SubTitle }}" [(visible)]="editSchedule" [modal]="true"
[style]="{height: '75vw', width: '50vw'}" [closable]="false" [closeOnEscape]="false">
<app-schedule></app-schedule>
<ng-template pTemplate="footer">
<p-button icon="pi pi-check" (click)="editSchedule=false" label="Ok" styleClass="p-button-text"></p-button>
</ng-template>
</p-dialog>
</p-dialog> -->
Expand Up @@ -2,6 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { ScheduleOrProgram } from 'src/app/services/interfaces/program.interface';
import { GuideComponent } from '../../guide.component';
import { DataService } from 'src/app/services/data.service';
import { Channel } from 'src/app/services/interfaces/channel.interface';

@Component({
selector: 'app-guide-programentry',
Expand All @@ -10,8 +11,10 @@ import { DataService } from 'src/app/services/data.service';
})
export class ProgramEntryComponent implements OnInit {
@Input() program!: ScheduleOrProgram;
@Input() channel!: Channel;
@Input() guideStartTime!: string;
@Input() guideEndTime!: string;
@Input() guideComponent!: GuideComponent;

editSchedule: boolean = false;

Expand All @@ -36,8 +39,8 @@ export class ProgramEntryComponent implements OnInit {
return program_width;
}


showDetailsDialog() {
this.editSchedule = true;
openDialog() {
if (this.guideComponent.inter.sched)
this.guideComponent.inter.sched.open(this.program, this.channel);
}
}
4 changes: 3 additions & 1 deletion mythtv/html/backend/src/app/guide/guide.component.html
Expand Up @@ -31,7 +31,8 @@ <h2>{{ 'dashboard.programguide' | translate }} </h2>
<ng-container *ngIf="!refreshing && inDisplayWindow(program.StartTime, program.EndTime)">
<app-guide-programentry [program]="program"
[guideStartTime]="m_programGuide.ProgramGuide.StartTime"
[guideEndTime]="m_programGuide.ProgramGuide.EndTime">
[guideEndTime]="m_programGuide.ProgramGuide.EndTime"
[guideComponent]="this" [channel]="channelrow">
</app-guide-programentry>
</ng-container>
</ng-container>
Expand All @@ -41,6 +42,7 @@ <h2>{{ 'dashboard.programguide' | translate }} </h2>
</ng-template>
</p-dataView>
</div>
<app-schedule [inter]="inter"></app-schedule>
<ng-template #loading>
<p-progressSpinner></p-progressSpinner>
</ng-template>
12 changes: 10 additions & 2 deletions mythtv/html/backend/src/app/guide/guide.component.ts
Expand Up @@ -5,6 +5,7 @@ import { GuideService } from 'src/app/services/guide.service';
import { Channel } from '../services/interfaces/channel.interface';
import { ProgramGuide } from 'src/app/services/interfaces/programguide.interface';
import { TranslateService, TranslationChangeEvent } from '@ngx-translate/core';
import { ScheduleLink } from '../schedule/schedule.component';

@Component({
selector: 'app-guide',
Expand All @@ -25,6 +26,7 @@ export class GuideComponent implements OnInit {
m_programGuide!: ProgramGuide;
loaded = false;
refreshing = false;
inter: ScheduleLink = { guide: this };

constructor(private guideService: GuideService,
private translate: TranslateService) {
Expand Down Expand Up @@ -86,7 +88,13 @@ export class GuideComponent implements OnInit {
else
this.m_startDate = new Date();
console.log("New time is " + this.m_startDate);
this.fetchData(this.m_startDate);
this.refreshing = true;
this.refresh(true);
}

refresh(hide: boolean) {
if (this.m_startDate){
this.fetchData(this.m_startDate);
this.refreshing = hide;
}
}
}
4 changes: 3 additions & 1 deletion mythtv/html/backend/src/app/primeng.module.ts
Expand Up @@ -30,6 +30,7 @@ import { RadioButtonModule } from 'primeng/radiobutton';
import { ProgressBarModule } from 'primeng/progressbar';
import { ScrollPanelModule } from 'primeng/scrollpanel';
import { TabMenuModule } from 'primeng/tabmenu';
import {MultiSelectModule} from 'primeng/multiselect';

@NgModule({
exports: [
Expand Down Expand Up @@ -62,7 +63,8 @@ import { TabMenuModule } from 'primeng/tabmenu';
RadioButtonModule,
ProgressBarModule,
ScrollPanelModule,
TabMenuModule
TabMenuModule,
MultiSelectModule
]
})

Expand Down

0 comments on commit 4e6df85

Please sign in to comment.