mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
style: improve settings layout
This commit is contained in:
1 parent
f70d875b88
commit
c53520ea00
3 files changed
+227
-183
No files matched your search
@@ -1,166 +1,187 @@
|
||||
<app-header
|
||||
[title]="'SETTINGS.TITLE' | translate"
|
||||
[subtitle]="'SETTINGS.SUBTITLE' | translate"
|
||||
></app-header>
|
||||
<form [formGroup]="settingsForm" (ngSubmit)="onSubmit()" novalidate>
|
||||
<mat-card>
|
||||
<mat-card-header class="card-header">
|
||||
<div mat-card-subtitle>
|
||||
{{ 'SETTINGS.DESCRIPTION' | translate }}
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<mat-list>
|
||||
<mat-list-item *ngIf="isElectron">
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>{{ 'SETTINGS.EPG_URL_LABEL' | translate }}</p>
|
||||
<p fxFlex fxLayoutAlign="start center">
|
||||
<mat-form-field class="full-width">
|
||||
<input
|
||||
[placeholder]="
|
||||
'SETTINGS.EPG_URL_PLACEHOLDER'
|
||||
<div class="main-container">
|
||||
<app-header
|
||||
[title]="'SETTINGS.TITLE' | translate"
|
||||
[subtitle]="
|
||||
('SETTINGS.SUBTITLE' | translate) +
|
||||
'. ' +
|
||||
('SETTINGS.DESCRIPTION' | translate)
|
||||
"
|
||||
></app-header>
|
||||
|
||||
<div class="settings-container">
|
||||
<form [formGroup]="settingsForm" (ngSubmit)="onSubmit()" novalidate>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<mat-list>
|
||||
<mat-list-item *ngIf="isElectron">
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{ 'SETTINGS.EPG_URL_LABEL' | translate }}
|
||||
</p>
|
||||
<p fxFlex fxLayoutAlign="start center">
|
||||
<mat-form-field class="full-width">
|
||||
<input
|
||||
[placeholder]="
|
||||
'SETTINGS.EPG_URL_PLACEHOLDER'
|
||||
| translate
|
||||
"
|
||||
matInput
|
||||
type="url"
|
||||
formControlName="epgUrl"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
*ngIf="
|
||||
(epgAvailable$ | async) &&
|
||||
settingsForm.value.epgUrl
|
||||
"
|
||||
mat-icon-button
|
||||
color="accent"
|
||||
[matTooltip]="
|
||||
'SETTINGS.REFRESH_EPG' | translate
|
||||
"
|
||||
type="button"
|
||||
(click)="fetchEpg()"
|
||||
>
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
<p matLine></p>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{
|
||||
'SETTINGS.VIDEO_PLAYER_LABEL'
|
||||
| translate
|
||||
"
|
||||
matInput
|
||||
type="url"
|
||||
formControlName="epgUrl"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<button
|
||||
*ngIf="
|
||||
(epgAvailable$ | async) &&
|
||||
settingsForm.value.epgUrl
|
||||
"
|
||||
mat-icon-button
|
||||
color="primary"
|
||||
[matTooltip]="
|
||||
'SETTINGS.REFRESH_EPG' | translate
|
||||
"
|
||||
type="button"
|
||||
(click)="fetchEpg()"
|
||||
>
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
<p matLine></p>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{ 'SETTINGS.VIDEO_PLAYER_LABEL' | translate }}
|
||||
</p>
|
||||
<p fxFlex fxLayoutAlign="start center">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{
|
||||
'SETTINGS.VIDEO_PLAYER_PLACEHOLDER'
|
||||
| translate
|
||||
}}</mat-label>
|
||||
<mat-select formControlName="player">
|
||||
<mat-option
|
||||
*ngFor="let player of players"
|
||||
[value]="player.id"
|
||||
>{{ player.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{ 'SETTINGS.LANGUAGE' | translate }}
|
||||
</p>
|
||||
<p fxFlex fxLayoutAlign="start center">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{
|
||||
'SETTINGS.VIDEO_PLAYER_PLACEHOLDER'
|
||||
| translate
|
||||
}}</mat-label>
|
||||
<mat-select formControlName="language">
|
||||
<mat-option
|
||||
*ngFor="
|
||||
let language of languageEnum
|
||||
| keyvalue
|
||||
"
|
||||
[value]="language.value"
|
||||
>{{
|
||||
'LANGUAGES.' + language.key
|
||||
}}
|
||||
</p>
|
||||
<p fxFlex fxLayoutAlign="start center">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{
|
||||
'SETTINGS.VIDEO_PLAYER_PLACEHOLDER'
|
||||
| translate
|
||||
}}</mat-option
|
||||
>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>{{ 'SETTINGS.THEME' | translate }}</p>
|
||||
<p fxFlex>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{
|
||||
'SETTINGS.VIDEO_PLAYER_PLACEHOLDER'
|
||||
| translate
|
||||
}}</mat-label>
|
||||
<mat-select formControlName="theme">
|
||||
<mat-option
|
||||
*ngFor="
|
||||
let theme of themeEnum | keyvalue
|
||||
"
|
||||
[value]="theme.value"
|
||||
>{{
|
||||
'THEMES.' + theme.value | translate
|
||||
}}</mat-option
|
||||
>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>{{ 'SETTINGS.SHOW_CAPTIONS' | translate }}</p>
|
||||
<p fxFlex>
|
||||
<mat-checkbox
|
||||
formControlName="showCaptions"
|
||||
></mat-checkbox>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>{{ 'SETTINGS.VERSION' | translate }}</p>
|
||||
<p fxFlex>
|
||||
{{ version }} <br />
|
||||
{{ updateMessage }}
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item *ngIf="!isElectron">EPG is available in electron-based version of IPTVnator. Check it <a href="https://github.com/4gray/iptvnator/releases">here</a></mat-list-item>
|
||||
</mat-list>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button
|
||||
mat-button
|
||||
color="accent"
|
||||
type="submit"
|
||||
[disabled]="settingsForm.pristine"
|
||||
>
|
||||
<mat-icon>save</mat-icon>
|
||||
{{ 'SETTINGS.SAVE_CHANGES' | translate }}
|
||||
</button>
|
||||
<div fxFlex></div>
|
||||
<button
|
||||
mat-button
|
||||
color="accent"
|
||||
type="reset"
|
||||
(click)="backToHome()"
|
||||
>
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
{{ 'SETTINGS.BACK_TO_HOME' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</form>
|
||||
}}</mat-label>
|
||||
<mat-select formControlName="player">
|
||||
<mat-option
|
||||
*ngFor="let player of players"
|
||||
[value]="player.id"
|
||||
>{{ player.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{ 'SETTINGS.LANGUAGE' | translate }}
|
||||
</p>
|
||||
<p fxFlex fxLayoutAlign="start center">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{
|
||||
'SETTINGS.VIDEO_PLAYER_PLACEHOLDER'
|
||||
| translate
|
||||
}}</mat-label>
|
||||
<mat-select formControlName="language">
|
||||
<mat-option
|
||||
*ngFor="
|
||||
let language of languageEnum
|
||||
| keyvalue
|
||||
"
|
||||
[value]="language.value"
|
||||
>{{
|
||||
'LANGUAGES.' + language.key
|
||||
| translate
|
||||
}}</mat-option
|
||||
>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>{{ 'SETTINGS.THEME' | translate }}</p>
|
||||
<p fxFlex>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>{{
|
||||
'SETTINGS.VIDEO_PLAYER_PLACEHOLDER'
|
||||
| translate
|
||||
}}</mat-label>
|
||||
<mat-select formControlName="theme">
|
||||
<mat-option
|
||||
*ngFor="
|
||||
let theme of themeEnum
|
||||
| keyvalue
|
||||
"
|
||||
[value]="theme.value"
|
||||
>{{
|
||||
'THEMES.' + theme.value
|
||||
| translate
|
||||
}}</mat-option
|
||||
>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{ 'SETTINGS.SHOW_CAPTIONS' | translate }}
|
||||
</p>
|
||||
<p fxFlex>
|
||||
<mat-checkbox
|
||||
formControlName="showCaptions"
|
||||
></mat-checkbox>
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
<div matLine fxLayout="row">
|
||||
<p fxFlex>
|
||||
{{ 'SETTINGS.VERSION' | translate }}
|
||||
</p>
|
||||
<p fxFlex>
|
||||
{{ version }} <br />
|
||||
{{ updateMessage }}
|
||||
</p>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item *ngIf="!isElectron"
|
||||
>EPG is available in electron-based version of
|
||||
IPTVnator. Check it <a
|
||||
href="https://github.com/4gray/iptvnator/releases"
|
||||
>here</a
|
||||
></mat-list-item
|
||||
>
|
||||
</mat-list>
|
||||
</mat-card-content>
|
||||
<mat-divider></mat-divider>
|
||||
<mat-card-actions align="end">
|
||||
<button
|
||||
mat-button
|
||||
color="accent"
|
||||
type="reset"
|
||||
(click)="backToHome()"
|
||||
>
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
{{ 'SETTINGS.BACK_TO_HOME' | translate }}
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
color="accent"
|
||||
type="submit"
|
||||
[disabled]="settingsForm.pristine"
|
||||
>
|
||||
<mat-icon>save</mat-icon>
|
||||
{{ 'SETTINGS.SAVE_CHANGES' | translate }}
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,4 +1,5 @@
|
||||
.card-header {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
@@ -14,3 +15,23 @@ button {
|
||||
.mat-list-item {
|
||||
height: 70px !important;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
display: grid;
|
||||
grid-template-rows: 105px auto;
|
||||
height: calc(100vh - 105px);
|
||||
}
|
||||
|
||||
.settings-container {
|
||||
overflow: auto;
|
||||
height: calc(100vh - 140px);
|
||||
|
||||
.mat-card {
|
||||
box-shadow: none;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -1,29 +1,30 @@
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { Router } from '@angular/router';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { StorageMap } from '@ngx-pwa/local-storage';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import { MockComponent, MockModule, MockPipe } from 'ng-mocks';
|
||||
import { of } from 'rxjs';
|
||||
import { EPG_FETCH } from '../../../shared/ipc-commands';
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
import { DataService } from '../services/data.service';
|
||||
import { ElectronServiceStub } from '../services/electron.service.stub';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { HeaderComponent } from './../shared/components/header/header.component';
|
||||
import { TranslateServiceStub } from './../../testing/translate.stub';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { SettingsComponent } from './settings.component';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { MockModule, MockPipe, MockComponent } from 'ng-mocks';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { EPG_FETCH } from '../../../shared/ipc-commands';
|
||||
import { Router } from '@angular/router';
|
||||
import { of } from 'rxjs';
|
||||
import { VideoPlayer } from './settings.interface';
|
||||
import { HeaderComponent } from './../shared/components/header/header.component';
|
||||
import { Language } from './language.enum';
|
||||
import { SettingsComponent } from './settings.component';
|
||||
import { VideoPlayer } from './settings.interface';
|
||||
import { Theme } from './theme.enum';
|
||||
|
||||
class MatSnackBarStub {
|
||||
@@ -86,6 +87,7 @@ describe('SettingsComponent', () => {
|
||||
MockModule(MatListModule),
|
||||
MockModule(MatFormFieldModule),
|
||||
MockModule(MatCheckboxModule),
|
||||
MockModule(MatDividerModule),
|
||||
],
|
||||
}).compileComponents();
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user