mirror of
https://gitlab.com/openlp/web-remote.git
synced 2024-12-22 11:32:47 +00:00
Update dependencies
This commit is contained in:
parent
cde10571a7
commit
cec351f2fa
92
.eslintrc.json
Normal file
92
.eslintrc.json
Normal file
@ -0,0 +1,92 @@
|
||||
{
|
||||
"root": true,
|
||||
"ignorePatterns": [
|
||||
"projects/**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": [
|
||||
"tsconfig.json",
|
||||
"e2e/tsconfig.json"
|
||||
],
|
||||
"createDefaultProgram": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/ng-cli-compat",
|
||||
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/consistent-type-definitions": "error",
|
||||
"@typescript-eslint/dot-notation": "off",
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"off",
|
||||
{
|
||||
"accessibility": "explicit"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/member-ordering": [
|
||||
"error",
|
||||
{
|
||||
"default": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "element",
|
||||
"prefix": ["app", "openlp"],
|
||||
"style": "kebab-case"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "attribute",
|
||||
"prefix": ["app", "openlp"],
|
||||
"style": "camelCase"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/naming-convention": [
|
||||
"error",
|
||||
{
|
||||
"selector": ["variable"],
|
||||
"modifiers": ["readonly"],
|
||||
"format": ["UPPER_CASE"]
|
||||
}
|
||||
],
|
||||
"jsdoc/no-types": [
|
||||
"off"
|
||||
],
|
||||
"prefer-arrow/prefer-arrow-functions": [
|
||||
"off"
|
||||
],
|
||||
"brace-style": "off",
|
||||
"@typescript-eslint/brace-style": [
|
||||
"off"
|
||||
],
|
||||
"id-blacklist": "off",
|
||||
"id-match": "off",
|
||||
"no-underscore-dangle": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.html"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/template/recommended"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -33,6 +33,7 @@ npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
/.angular/cache
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
|
28
angular.json
28
angular.json
@ -9,9 +9,9 @@
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"styleext": "scss"
|
||||
}
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
"architect": {
|
||||
"build": {
|
||||
@ -86,14 +86,11 @@
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.html"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -111,16 +108,15 @@
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.html"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "@openlp/web-remote"
|
||||
}
|
||||
}
|
||||
|
74
package.json
74
package.json
@ -24,44 +24,52 @@
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "^11.0.5",
|
||||
"@angular/cdk": "^11.0.3",
|
||||
"@angular/common": "^11.0.5",
|
||||
"@angular/compiler": "^11.0.5",
|
||||
"@angular/core": "^11.0.5",
|
||||
"@angular/flex-layout": "^11.0.0-beta.33",
|
||||
"@angular/forms": "^11.0.5",
|
||||
"@angular/material": "^11.0.3",
|
||||
"@angular/platform-browser": "^11.0.5",
|
||||
"@angular/platform-browser-dynamic": "^11.0.5",
|
||||
"@angular/router": "^11.0.5",
|
||||
"@fontsource/roboto": "^4.4.5",
|
||||
"core-js": "^3.8.1",
|
||||
"@angular/animations": "^15.0.2",
|
||||
"@angular/cdk": "^15.0.2",
|
||||
"@angular/common": "^15.0.2",
|
||||
"@angular/compiler": "^15.0.2",
|
||||
"@angular/core": "^15.0.2",
|
||||
"@angular/forms": "^15.0.2",
|
||||
"@angular/material": "^15.0.2",
|
||||
"@angular/platform-browser": "^15.0.2",
|
||||
"@angular/platform-browser-dynamic": "^15.0.2",
|
||||
"@angular/router": "^15.0.2",
|
||||
"@fontsource/roboto": "^4.5.8",
|
||||
"core-js": "^3.26.1",
|
||||
"hammerjs": "^2.0.8",
|
||||
"material-icons": "^1.12.1",
|
||||
"rxjs": "^6.6.3",
|
||||
"zone.js": "^0.10.3"
|
||||
"material-icons": "^1.13.1",
|
||||
"rxjs": "^7.6.0",
|
||||
"zone.js": "^0.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1100.5",
|
||||
"@angular/cli": "~11.0.5",
|
||||
"@angular/compiler-cli": "^11.0.5",
|
||||
"@angular/language-service": "^11.0.5",
|
||||
"@types/jasmine": "~3.6.2",
|
||||
"@types/jasminewd2": "~2.0.8",
|
||||
"@types/node": "~14.14.16",
|
||||
"codelyzer": "~6.0.1",
|
||||
"jasmine-core": "~3.6.0",
|
||||
"jasmine-spec-reporter": "~6.0.0",
|
||||
"karma": "~5.2.3",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"@angular-devkit/build-angular": "^15.0.3",
|
||||
"@angular-eslint/builder": "^15.0.3",
|
||||
"@angular-eslint/eslint-plugin": "^15.1.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^15.1.0",
|
||||
"@angular-eslint/schematics": "^15.1.0",
|
||||
"@angular-eslint/template-parser": "^15.1.0",
|
||||
"@angular/cli": "~15.0.2",
|
||||
"@angular/compiler-cli": "^15.0.2",
|
||||
"@angular/language-service": "^15.0.2",
|
||||
"@types/jasmine": "~4.3.1",
|
||||
"@types/jasminewd2": "~2.0.10",
|
||||
"@types/node": "~18.11.13",
|
||||
"@typescript-eslint/eslint-plugin": "5.44.0",
|
||||
"@typescript-eslint/parser": "5.44.0",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-plugin-import": "~2.26.0",
|
||||
"eslint-plugin-jsdoc": "~39.6.4",
|
||||
"eslint-plugin-prefer-arrow": "~1.2.3",
|
||||
"jasmine-core": "~4.5.0",
|
||||
"jasmine-spec-reporter": "~7.0.0",
|
||||
"karma": "~6.4.1",
|
||||
"karma-chrome-launcher": "~3.1.1",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||
"karma-jasmine": "~4.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.5.4",
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "^2.0.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~9.1.1",
|
||||
"tslint": "~6.1.3",
|
||||
"typescript": "~4.0.5"
|
||||
"ts-node": "~10.9.1",
|
||||
"typescript": "~4.8.2"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
@ -40,28 +40,34 @@
|
||||
<mat-toolbar *ngIf="fastSwitching" class="toolbar-padding"></mat-toolbar>
|
||||
<footer>
|
||||
<mat-toolbar class="footer">
|
||||
<button mat-icon-button (click)="previousItem()" matTooltip="Previous item">
|
||||
<button mat-icon-button (click)="previousItem()" matTooltip="Previous item" matTooltipPosition="above">
|
||||
<mat-icon>first_page</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="nextItem()" matTooltip="Next item">
|
||||
<button mat-icon-button (click)="nextItem()" matTooltip="Next item" matTooltipPosition="above">
|
||||
<mat-icon>last_page</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="previousSlide()" matTooltip="Previous slide">
|
||||
<button mat-icon-button (click)="previousSlide()" matTooltip="Previous slide" matTooltipPosition="above">
|
||||
<mat-icon>navigate_before</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="nextSlide()" matTooltip="Next slide">
|
||||
<button mat-icon-button (click)="nextSlide()" matTooltip="Next slide" matTooltipPosition="above">
|
||||
<mat-icon>navigate_next</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="blankDisplay()" class="displayButton" [class.active]="state.blank" [disabled]="state.blank" matTooltip="Show black">
|
||||
<button mat-icon-button #squashedDisplayButton (click)="openDisplayModeSelector()" class="squashed-display-button" matTooltip="Change Display Mode" matTooltipPosition="above">
|
||||
<mat-icon *ngIf="state.blank">videocam_off</mat-icon>
|
||||
<mat-icon *ngIf="state.theme">wallpaper</mat-icon>
|
||||
<mat-icon *ngIf="state.display">desktop_windows</mat-icon>
|
||||
<mat-icon *ngIf="state.live()">videocam</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="blankDisplay()" class="displayButton" [class.active]="state.blank" [disabled]="state.blank" matTooltip="Show black" matTooltipPosition="above">
|
||||
<mat-icon>videocam_off</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="themeDisplay()" class="displayButton" [class.active]="state.theme" [disabled]="state.theme" matTooltip="Show background">
|
||||
<button mat-icon-button (click)="themeDisplay()" class="displayButton" [class.active]="state.theme" [disabled]="state.theme" matTooltip="Show background" matTooltipPosition="above">
|
||||
<mat-icon>wallpaper</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="desktopDisplay()" class="displayButton" [class.active]="state.display" [disabled]="state.display" matTooltip="Show Desktop">
|
||||
<button mat-icon-button (click)="desktopDisplay()" class="displayButton" [class.active]="state.display" [disabled]="state.display" matTooltip="Show Desktop" matTooltipPosition="above">
|
||||
<mat-icon>desktop_windows</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button (click)="showDisplay()" class="displayButton" [class.active]="state.display" [disabled]="state.live()" matTooltip="Show Presentation">
|
||||
<button mat-icon-button (click)="showDisplay()" class="displayButton" [class.active]="state.display" [disabled]="state.live()" matTooltip="Show Presentation" matTooltipPosition="above">
|
||||
<mat-icon>videocam</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar>
|
||||
|
@ -1,3 +1,5 @@
|
||||
$small-toolbar-breakpoint: 500px;
|
||||
|
||||
// To allow the inner overlay (and other items) to use z-indexes greater than 1
|
||||
.mat-sidenav {
|
||||
&-container, &-content {
|
||||
@ -10,6 +12,11 @@ mat-toolbar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1020;
|
||||
|
||||
/* Fix icon button alignment on some firefox configurations */
|
||||
[mat-icon-button] {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
mat-divider {
|
||||
@ -32,7 +39,12 @@ mat-sidenav-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
mat-slide-toggle {
|
||||
/* Align icons with text */
|
||||
mat-sidenav-container .mat-icon {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
.mat-mdc-slide-toggle {
|
||||
margin-top: 0.8rem;
|
||||
margin-left: 1rem;
|
||||
font-size: 80%;
|
||||
@ -50,7 +62,7 @@ mat-slide-toggle {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
.fast-switcher a.mat-tab-link > span.text {
|
||||
.fast-switcher a.mat-mdc-tab-link > span.text {
|
||||
margin-left: 0.3rem;
|
||||
}
|
||||
|
||||
@ -60,6 +72,19 @@ mat-slide-toggle {
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.displayButton {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media screen and (min-width: $small-toolbar-breakpoint) {
|
||||
.squashed-display-button {
|
||||
display: none;
|
||||
}
|
||||
.displayButton {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the Component injected by Router Outlet full height:
|
||||
*/
|
||||
|
@ -1,14 +1,16 @@
|
||||
import { Component, HostListener, OnInit } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
||||
import { MatBottomSheet } from '@angular/material/bottom-sheet';
|
||||
|
||||
import { State } from './responses';
|
||||
import { State, DisplayMode } from './responses';
|
||||
import { OpenLPService, WebSocketStatus } from './openlp.service';
|
||||
import { WindowRef } from './window-ref.service';
|
||||
import { PageTitleService } from './page-title.service';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
import { DisplayModeSelectorComponent } from './components/display-mode-selector/display-mode-selector.component';
|
||||
// import { version } from '../../package.json';
|
||||
|
||||
@Component({
|
||||
@ -17,6 +19,9 @@ import { debounceTime } from 'rxjs/operators';
|
||||
styleUrls: ['./app.component.scss']
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
// Make DisplayMode enum visible to html code
|
||||
DisplayMode = DisplayMode;
|
||||
|
||||
private _fastSwitching = false;
|
||||
state = new State();
|
||||
showLogin = false;
|
||||
@ -25,7 +30,7 @@ export class AppComponent implements OnInit {
|
||||
webSocketOpen = false;
|
||||
|
||||
constructor(private pageTitleService: PageTitleService, private openlpService: OpenLPService,
|
||||
private dialog: MatDialog, private windowRef: WindowRef) {
|
||||
private dialog: MatDialog, private bottomSheet: MatBottomSheet, private windowRef: WindowRef) {
|
||||
pageTitleService.pageTitleChanged$.subscribe(pageTitle => this.pageTitle = pageTitle);
|
||||
openlpService.stateChanged$.subscribe(item => this.state = item);
|
||||
openlpService.webSocketStateChanged$.subscribe(status => this.webSocketOpen = status === WebSocketStatus.Open);
|
||||
@ -54,6 +59,16 @@ export class AppComponent implements OnInit {
|
||||
localStorage.setItem('OpenLP-fastSwitching', JSON.stringify(value));
|
||||
}
|
||||
|
||||
openDisplayModeSelector(): void {
|
||||
const selectorRef = this.bottomSheet.open(DisplayModeSelectorComponent, {data: this.state.displayMode});
|
||||
selectorRef.afterDismissed().subscribe(result => {
|
||||
if (result === DisplayMode.Blank) {this.blankDisplay();}
|
||||
else if (result === DisplayMode.Desktop) {this.desktopDisplay();}
|
||||
else if (result === DisplayMode.Theme) {this.themeDisplay();}
|
||||
else if (result === DisplayMode.Presentation) {this.showDisplay();}
|
||||
});
|
||||
}
|
||||
|
||||
login() {
|
||||
const dialogRef = this.dialog.open(LoginComponent, {
|
||||
width: '250px'
|
||||
|
@ -4,7 +4,6 @@ import { FormsModule } from '@angular/forms';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
@ -21,6 +20,7 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { PageTitleService } from './page-title.service';
|
||||
@ -43,6 +43,7 @@ import { SlideListComponent } from './components/slides/slide-list/slide-list.co
|
||||
import { SlideItemComponent } from './components/slides/slide-item/slide-item.component';
|
||||
import { ServiceItemComponent } from './components/service/service-item/service-item.component';
|
||||
import { ServiceListComponent } from './components/service/service-list/service-list.component';
|
||||
import { DisplayModeSelectorComponent } from './components/display-mode-selector/display-mode-selector.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
@ -63,7 +64,8 @@ import { ServiceListComponent } from './components/service/service-list/service-
|
||||
SlidesComponent,
|
||||
SlideListComponent,
|
||||
SlideItemComponent,
|
||||
ThemesComponent
|
||||
ThemesComponent,
|
||||
DisplayModeSelectorComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -87,7 +89,7 @@ import { ServiceListComponent } from './components/service/service-list/service-
|
||||
MatTabsModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
FlexLayoutModule
|
||||
MatBottomSheetModule
|
||||
],
|
||||
providers: [
|
||||
PageTitleService,
|
||||
|
@ -4,7 +4,7 @@
|
||||
<span *ngFor="let tag of tags" [class.active]="tag.active">{{ tag.text }}</span>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="slide currentSlide song mat-display-3" [innerHTML]="chordproFormatted(currentSlides[activeSlide])|chordpro"></div>
|
||||
<div class="slide currentSlide song mat-headline-2" [innerHTML]="chordproFormatted(currentSlides[activeSlide])|chordpro"></div>
|
||||
<div class="nextSlides">
|
||||
<div
|
||||
class="slide song"
|
||||
|
@ -62,6 +62,7 @@ export class ChordProPipe implements PipeTransform {
|
||||
|
||||
/**
|
||||
* Pipe transformation for ChordPro-formatted song texts.
|
||||
*
|
||||
* @param {string} song
|
||||
* @param {number} nHalfSteps
|
||||
* @returns {string}
|
||||
@ -108,15 +109,16 @@ export class ChordProPipe implements PipeTransform {
|
||||
|
||||
/**
|
||||
* Transpose the given chord the given (positive or negative) number of half steps.
|
||||
*
|
||||
* @param {string} chordRoot
|
||||
* @param {number} nHalfSteps
|
||||
* @returns {string}
|
||||
*/
|
||||
transposeChord(chordRoot, nHalfSteps) {
|
||||
let pos = -1;
|
||||
for (let i = 0; i < this.keys.length; i++) {
|
||||
if (this.keys[i].name === chordRoot) {
|
||||
pos = this.keys[i].value;
|
||||
for (const key of this.keys) {
|
||||
if (key.name === chordRoot) {
|
||||
pos = key.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -128,9 +130,9 @@ export class ChordProPipe implements PipeTransform {
|
||||
else if (pos > this.MAX_HALF_STEPS) {
|
||||
pos -= this.MAX_HALF_STEPS + 1;
|
||||
}
|
||||
for (let i = 0; i < this.keys.length; i++) {
|
||||
if (this.keys[i].value === pos) {
|
||||
return this.keys[i].name;
|
||||
for (const key of this.keys) {
|
||||
if (key.value === pos) {
|
||||
return key.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,7 +227,13 @@ export class ChordProPipe implements PipeTransform {
|
||||
chord += ' ';
|
||||
}
|
||||
|
||||
return `<span data-chord="${chord}" class="${chordClass}"><span class="chord">${chord}</span><span class="text ${fillHtml ? 'with-fill' : ''}"><span class="first-letter">${textFirstLetter}</span>${fillHtml}</span></span>${textRest}`;
|
||||
return `<span data-chord="${chord}" class="${chordClass}">` +
|
||||
`<span class="chord">${chord}</span>` +
|
||||
`<span class="text ${fillHtml ? 'with-fill' : ''}">` +
|
||||
`<span class="first-letter">${textFirstLetter}</span>` +
|
||||
`${fillHtml}` +
|
||||
`</span>` +
|
||||
`</span>${textRest}`;
|
||||
} else {
|
||||
return `${lastPart}`;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
<mat-action-list>
|
||||
<button mat-list-item (click)="setMode(DisplayMode.Blank)" class="display-button" [disabled]="displayMode === DisplayMode.Blank">
|
||||
<mat-icon>videocam_off</mat-icon>
|
||||
Show black
|
||||
</button>
|
||||
<button mat-list-item (click)="setMode(DisplayMode.Theme)" class="display-button" [disabled]="displayMode === DisplayMode.Theme">
|
||||
<mat-icon>wallpaper</mat-icon>
|
||||
Show background
|
||||
</button>
|
||||
<button mat-list-item (click)="setMode(DisplayMode.Desktop)" class="display-button" [disabled]="displayMode === DisplayMode.Desktop">
|
||||
<mat-icon>desktop_windows</mat-icon>
|
||||
Show Desktop
|
||||
</button>
|
||||
<button mat-list-item (click)="setMode(DisplayMode.Presentation)" class="display-button" [disabled]="displayMode === DisplayMode.Presentation">
|
||||
<mat-icon>videocam</mat-icon>
|
||||
Show Presentation
|
||||
</button>
|
||||
</mat-action-list>
|
||||
|
@ -0,0 +1,4 @@
|
||||
.mat-icon {
|
||||
vertical-align: text-top;
|
||||
padding-right: 10px;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatBottomSheetRef, MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';
|
||||
import { DisplayMode } from 'src/app/responses';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'openlp-display-mode-sheet',
|
||||
templateUrl: 'display-mode-selector.component.html',
|
||||
styleUrls: ['./display-mode-selector.component.scss']
|
||||
})
|
||||
export class DisplayModeSelectorComponent {
|
||||
// Make DisplayMode enum visible to html code
|
||||
DisplayMode = DisplayMode;
|
||||
|
||||
constructor(private bottomSheetRef: MatBottomSheetRef<DisplayModeSelectorComponent>,
|
||||
@Inject(MAT_BOTTOM_SHEET_DATA) public displayMode: DisplayMode) {}
|
||||
|
||||
setMode(mode: DisplayMode): void {
|
||||
this.bottomSheetRef.dismiss(mode);
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ export class SearchOptionsComponent {
|
||||
public selectedPlugin: string;
|
||||
public searchOptions: Array<string>;
|
||||
public selectedSearchOption: string;
|
||||
public searchOptionsTitle: String = '';
|
||||
public searchOptionsTitle = '';
|
||||
|
||||
constructor(private openlpService: OpenLPService) {}
|
||||
|
||||
|
@ -17,7 +17,7 @@ export class SearchComponent implements OnInit, AfterViewInit {
|
||||
public searchResults = null;
|
||||
public selectedPlugin: string;
|
||||
public currentPlugin: string;
|
||||
public displaySearchOptions: Boolean = false;
|
||||
public displaySearchOptions = false;
|
||||
@ViewChild(SearchOptionsComponent, {static: false}) searchOptions: SearchOptionsComponent;
|
||||
|
||||
constructor(private pageTitleService: PageTitleService, private openlpService: OpenLPService,
|
||||
|
@ -1,3 +1,5 @@
|
||||
<mat-card (click)="onItemSelected(item)" class="service-item no-select" [class.selected]="selected">
|
||||
<mat-icon>{{ getIcon(item) }}</mat-icon> {{ item.title }}
|
||||
<mat-card-content>
|
||||
<mat-icon>{{ getIcon(item) }}</mat-icon> {{ item.title }}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
@ -0,0 +1,9 @@
|
||||
.selected {
|
||||
background-color: rgb(235, 235, 235);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Align icons with text */
|
||||
.mat-icon {
|
||||
line-height: inherit !important;
|
||||
}
|
@ -12,10 +12,10 @@ import { ServiceItem } from '../../../responses';
|
||||
export class ServiceItemComponent {
|
||||
@Input() item: ServiceItem;
|
||||
@Input() selected = false;
|
||||
@Output() select = new EventEmitter<ServiceItem>();
|
||||
@Output() selectItem = new EventEmitter<ServiceItem>();
|
||||
|
||||
onItemSelected(item: ServiceItem) {
|
||||
this.select.emit(item);
|
||||
this.selectItem.emit(item);
|
||||
}
|
||||
|
||||
getIcon(item: ServiceItem): string {
|
||||
|
@ -2,6 +2,6 @@
|
||||
*ngFor="let item of items"
|
||||
[item]="item"
|
||||
[selected]="item.selected"
|
||||
(select)="onItemSelected($event)"
|
||||
(selectItem)="onItemSelected($event)"
|
||||
[tabindex]="item.id"
|
||||
></openlp-service-item>
|
||||
|
@ -1,13 +1,15 @@
|
||||
<mat-card class="slide no-select" mat-list-item (click)="onSlideSelected(slide)" [class.selected]="selected">
|
||||
<div class="verse-tag">{{ slide?.tag }}</div>
|
||||
<div *ngIf="slide?.img; else onlySlideText" class="verse-img-container">
|
||||
<img src="{{ slide?.img }}" />
|
||||
<div class="img-verse-text">
|
||||
{{ slide?.text }}
|
||||
<mat-card-content>
|
||||
<div class="verse-tag">{{ slide?.tag }}</div>
|
||||
<div *ngIf="slide?.img; else onlySlideText" class="verse-img-container">
|
||||
<img src="{{ slide?.img }}" />
|
||||
<div class="img-verse-text">
|
||||
{{ slide?.text }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #onlySlideText>
|
||||
<div class="verse-text">{{ slide?.text }}</div>
|
||||
</ng-template>
|
||||
<ng-template #onlySlideText>
|
||||
<div class="verse-text">{{ slide?.text }}</div>
|
||||
</ng-template>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
mat-card {
|
||||
.slide {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -11,10 +11,10 @@ import { Slide } from '../../../responses';
|
||||
export class SlideItemComponent {
|
||||
@Input() slide: Slide;
|
||||
@Input() selected = false;
|
||||
@Output() select = new EventEmitter<Slide>();
|
||||
@Output() selectSlide = new EventEmitter<Slide>();
|
||||
|
||||
onSlideSelected(slide: Slide) {
|
||||
this.select.emit(slide);
|
||||
this.selectSlide.emit(slide);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
<openlp-slide-item *ngFor="let slide of slides; let index = index" [slide]="slide" [tabindex]="counter" [selected]="slide.selected" (select)="onSlideSelected($event, index)"></openlp-slide-item>
|
||||
<openlp-slide-item *ngFor="let slide of slides; let index = index" [slide]="slide" [tabindex]="counter" [selected]="slide.selected" (selectSlide)="onSlideSelected($event, index)"></openlp-slide-item>
|
@ -4,7 +4,7 @@
|
||||
<span *ngFor="let tag of tags" [class.active]="tag.active">{{ tag.text }}</span>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="slide currentSlide mat-display-3">
|
||||
<div class="slide currentSlide mat-headline-2">
|
||||
<div *ngIf="currentSlides[activeSlide]?.img; else elseActiveSlideText">
|
||||
<img src="{{currentSlides[activeSlide]?.img}}" class="active-slide-img" />
|
||||
<div class="active-slide-img-text">{{ currentSlides[activeSlide]?.text }}</div>
|
||||
@ -14,7 +14,7 @@
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="nextSlides">
|
||||
<div class="slide mat-display-1" [class.first]="slide.first_slide_of_tag" *ngFor="let slide of nextSlides">
|
||||
<div class="slide mat-headline-4" [class.first]="slide.first_slide_of_tag" *ngFor="let slide of nextSlides">
|
||||
<div *ngIf="slide.img; else elseNextSlidesText">
|
||||
<img src="{{slide.img}}" class="next-slides-img" />
|
||||
<div class="next-slides-text">{{ slide.text }}</div>
|
||||
|
@ -15,10 +15,12 @@
|
||||
<div class="theme-container content" *ngIf="isThemeLevelSupported()">
|
||||
<div *ngFor="let theme of themeList;">
|
||||
<mat-card class="theme-card" (click)='setTheme(theme.name)' [class.selected]="theme.selected">
|
||||
<img [src]="theme.thumbnail"/>
|
||||
<div class="theme-title">{{ theme.name }}</div>
|
||||
<mat-card-content>
|
||||
<img [src]="theme.thumbnail"/>
|
||||
<div class="theme-title">{{ theme.name }}</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
<mat-error *ngIf="!isThemeLevelSupported()">Song level theme changing not yet supported. Change your theme level to Global or Service</mat-error>
|
||||
<mat-error *ngIf="!isThemeLevelSupported()">Song level theme changing not supported. Change your theme level to Global or Service</mat-error>
|
||||
</form>
|
@ -1,17 +1,4 @@
|
||||
mat-card {
|
||||
cursor: pointer;
|
||||
justify-content: center;
|
||||
}
|
||||
mat-divider {
|
||||
border-color: #afafaf;
|
||||
}
|
||||
mat-button-toggle-group {
|
||||
margin-left: 10px;
|
||||
}
|
||||
mat-slide-toggle {
|
||||
margin-left: auto;
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
@ -29,7 +16,8 @@ img {
|
||||
}
|
||||
|
||||
.theme-card {
|
||||
|
||||
cursor: pointer;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.theme-title {
|
||||
|
@ -98,7 +98,7 @@ export class OpenLPService {
|
||||
}
|
||||
|
||||
setSearchOption(plugin, option, value): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/plugins/${plugin}/search-options`, {'option': option, 'value': value});
|
||||
return this.doPost(`${this.apiURL}/plugins/${plugin}/search-options`, {option, value});
|
||||
}
|
||||
|
||||
getServiceItems(): Observable<ServiceItem[]> {
|
||||
@ -106,15 +106,15 @@ export class OpenLPService {
|
||||
}
|
||||
|
||||
setServiceItem(id: any): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/service/show`, {'id': id});
|
||||
return this.doPost(`${this.apiURL}/service/show`, {id});
|
||||
}
|
||||
|
||||
nextItem(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/service/progress`, {'action': 'next'});
|
||||
return this.doPost(`${this.apiURL}/service/progress`, {action: 'next'});
|
||||
}
|
||||
|
||||
previousItem(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/service/progress`, {'action': 'previous'});
|
||||
return this.doPost(`${this.apiURL}/service/progress`, {action: 'previous'});
|
||||
}
|
||||
|
||||
getServiceItem(): Observable<any> {
|
||||
@ -126,15 +126,15 @@ export class OpenLPService {
|
||||
}
|
||||
|
||||
setSlide(id: any): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/controller/show`, {'id': id});
|
||||
return this.doPost(`${this.apiURL}/controller/show`, {id});
|
||||
}
|
||||
|
||||
nextSlide(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/controller/progress`, {'action': 'next'});
|
||||
return this.doPost(`${this.apiURL}/controller/progress`, {action: 'next'});
|
||||
}
|
||||
|
||||
previousSlide(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/controller/progress`, {'action': 'previous'});
|
||||
return this.doPost(`${this.apiURL}/controller/progress`, {action: 'previous'});
|
||||
}
|
||||
|
||||
getThemeLevel(): Observable<any> {
|
||||
@ -146,7 +146,7 @@ export class OpenLPService {
|
||||
}
|
||||
|
||||
setThemeLevel(level): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/controller/theme-level`, {'level': level});
|
||||
return this.doPost(`${this.apiURL}/controller/theme-level`, {level});
|
||||
}
|
||||
|
||||
getTheme(): Observable<any> {
|
||||
@ -154,35 +154,35 @@ export class OpenLPService {
|
||||
}
|
||||
|
||||
setTheme(theme: string): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/controller/theme`, {'theme': theme});
|
||||
return this.doPost(`${this.apiURL}/controller/theme`, {theme});
|
||||
}
|
||||
|
||||
blankDisplay(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/core/display`, {'display': 'blank'});
|
||||
return this.doPost(`${this.apiURL}/core/display`, {display: 'blank'});
|
||||
}
|
||||
|
||||
themeDisplay(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/core/display`, {'display': 'theme'});
|
||||
return this.doPost(`${this.apiURL}/core/display`, {display: 'theme'});
|
||||
}
|
||||
|
||||
desktopDisplay(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/core/display`, {'display': 'desktop'});
|
||||
return this.doPost(`${this.apiURL}/core/display`, {display: 'desktop'});
|
||||
}
|
||||
|
||||
showDisplay(): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/core/display`, {'display': 'show'});
|
||||
return this.doPost(`${this.apiURL}/core/display`, {display: 'show'});
|
||||
}
|
||||
|
||||
showAlert(text): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/plugins/alerts`, {'text': text});
|
||||
return this.doPost(`${this.apiURL}/plugins/alerts`, {text});
|
||||
}
|
||||
|
||||
sendItemLive(plugin, id): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/plugins/${plugin}/live`, {'id': id});
|
||||
return this.doPost(`${this.apiURL}/plugins/${plugin}/live`, {id});
|
||||
}
|
||||
|
||||
addItemToService(plugin, id): Observable<any> {
|
||||
return this.doPost(`${this.apiURL}/plugins/${plugin}/add`, {'id': id});
|
||||
return this.doPost(`${this.apiURL}/plugins/${plugin}/add`, {id});
|
||||
}
|
||||
|
||||
transposeSong(transpose_value): Observable<any> {
|
||||
@ -257,7 +257,7 @@ export class OpenLPService {
|
||||
this.webSocketTimeoutHandle = setTimeout(() => {
|
||||
this.createWebSocket();
|
||||
}, WEBSOCKET_RECONNECT_TIMEOUT);
|
||||
}
|
||||
};
|
||||
|
||||
private clearWebSocketTimeoutHandle() {
|
||||
if (this.webSocketTimeoutHandle) {
|
||||
@ -272,7 +272,7 @@ export class OpenLPService {
|
||||
this.handleStateChange(state);
|
||||
};
|
||||
reader.readAsText(event.data);
|
||||
}
|
||||
};
|
||||
|
||||
handleStateChange(state: State) {
|
||||
this.isTwelveHourTime = state.twelve;
|
||||
|
@ -14,6 +14,25 @@ export class State {
|
||||
theme: boolean;
|
||||
|
||||
live = () => !(this.blank || this.display || this.theme);
|
||||
|
||||
get displayMode() {
|
||||
if (this.blank) {
|
||||
return DisplayMode.Blank;
|
||||
} else if (this.display) {
|
||||
return DisplayMode.Desktop;
|
||||
} else if (this.theme) {
|
||||
return DisplayMode.Theme;
|
||||
} else {
|
||||
return DisplayMode.Presentation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export enum DisplayMode {
|
||||
Blank,
|
||||
Theme,
|
||||
Desktop,
|
||||
Presentation
|
||||
}
|
||||
|
||||
export interface Slide {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
@import '~@angular/material/theming';
|
||||
@import '@angular/material/theming';
|
||||
|
||||
@include mat-core();
|
||||
$primary: mat-palette($mat-indigo);
|
||||
@ -36,12 +36,12 @@ mat-sidenav {
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
mat-card {
|
||||
.mat-mdc-card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
mat-card.service-item,
|
||||
mat-card.slide {
|
||||
.mat-mdc-card.service-item,
|
||||
.mat-mdc-card.slide {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@ -103,3 +103,7 @@ footer {
|
||||
.no-select {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.mat-mdc-tooltip {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
@ -7,14 +7,8 @@ import {
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: any;
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"extends": "../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
["app", "openlp"],
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
["app", "openlp"],
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
127
tslint.json
127
tslint.json
@ -1,127 +0,0 @@
|
||||
{
|
||||
"rulesDirectory": [
|
||||
"node_modules/codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"arrow-return-shorthand": true,
|
||||
"callable-types": true,
|
||||
"class-name": true,
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": true,
|
||||
"deprecation": {
|
||||
"severity": "warn"
|
||||
},
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"import-spacing": true,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces"
|
||||
],
|
||||
"interface-over-type-literal": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-super": true,
|
||||
"no-empty": false,
|
||||
"no-empty-interface": true,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-misused-new": true,
|
||||
"no-non-null-assertion": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": false,
|
||||
"no-string-throw": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unnecessary-initializer": true,
|
||||
"no-unused-expression": true,
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-whitespace"
|
||||
],
|
||||
"prefer-const": true,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}
|
||||
],
|
||||
"unified-signatures": true,
|
||||
"variable-name": false,
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
],
|
||||
"no-output-on-prefix": true,
|
||||
"no-inputs-metadata-property": true,
|
||||
"no-outputs-metadata-property": true,
|
||||
"no-host-metadata-property": true,
|
||||
"no-input-rename": true,
|
||||
"no-output-rename": true,
|
||||
"use-lifecycle-interface": true,
|
||||
"use-pipe-transform-interface": true,
|
||||
"component-class-suffix": true,
|
||||
"directive-class-suffix": true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user