diff --git a/package.json b/package.json index a692792..fcfa2d0 100644 --- a/package.json +++ b/package.json @@ -25,23 +25,23 @@ "tx": "node scripts/tx.js" }, "dependencies": { - "@angular/animations": "^17.3.6", - "@angular/cdk": "^17.3.6", - "@angular/common": "^17.3.6", - "@angular/compiler": "^17.3.6", - "@angular/core": "^17.3.6", - "@angular/forms": "^17.3.6", - "@angular/material": "^17.3.6", - "@angular/platform-browser": "^17.3.6", - "@angular/platform-browser-dynamic": "^17.3.6", - "@angular/router": "^17.3.6", + "@angular/animations": "^17.3.7", + "@angular/cdk": "^17.3.7", + "@angular/common": "^17.3.7", + "@angular/compiler": "^17.3.7", + "@angular/core": "^17.3.7", + "@angular/forms": "^17.3.7", + "@angular/material": "^17.3.7", + "@angular/platform-browser": "^17.3.7", + "@angular/platform-browser-dynamic": "^17.3.7", + "@angular/router": "^17.3.7", "@fontsource/roboto": "^5.0.13", "@ngx-translate/core": "^15.0.0", "@ngx-translate/http-loader": "^8.0.0", "core-js": "^3.37.0", "material-icons": "^1.13.12", "rxjs": "^7.8.1", - "zone.js": "^0.14.4" + "zone.js": "^0.14.5" }, "devDependencies": { "@angular-devkit/build-angular": "^17.3.6", @@ -51,16 +51,16 @@ "@angular-eslint/schematics": "^17.3.0", "@angular-eslint/template-parser": "^17.3.0", "@angular/cli": "~17.3.6", - "@angular/compiler-cli": "^17.3.6", - "@angular/language-service": "^17.3.6", + "@angular/compiler-cli": "^17.3.7", + "@angular/language-service": "^17.3.7", "@chiragrupani/karma-chromium-edge-launcher": "^2.3.1", "@transifex/api": "^7.1.0", "@types/jasmine": "~5.1.4", "@types/jasminewd2": "~2.0.13", "@types/jest": "^29.5.12", - "@types/node": "~20.12.7", - "@typescript-eslint/eslint-plugin": "7.7.1", - "@typescript-eslint/parser": "7.7.1", + "@types/node": "~20.12.8", + "@typescript-eslint/eslint-plugin": "7.8.0", + "@typescript-eslint/parser": "7.8.0", "axios": "^1.6.8", "browserslist": "^4.23.0", "browserslist-useragent-regexp": "^4.1.3", diff --git a/src/app/app.component.html b/src/app/app.component.html index 8ecd9c9..5e54725 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -3,13 +3,13 @@ - {{ pageTitle | translate }} + {{ pageTitle | translate | titlecase }} @if (showLogin) { } @if (webSocketOpen) { @@ -17,7 +17,7 @@ mat-icon-button (click)="forceWebSocketReconnection()" class="connection-status" - matTooltip="{{ 'CONNECTED_TO_OPENLP' | translate }}"> + matTooltip="{{ 'CONNECTED_TO_OPENLP' | translate | titlecase }}"> link } @@ -26,7 +26,7 @@ mat-icon-button (click)="forceWebSocketReconnection()" class="connection-status" - matTooltip="{{ 'DISCONNECTED' | translate }}"> + matTooltip="{{ 'DISCONNECTED' | translate | titlecase }}"> link_off } @@ -41,58 +41,58 @@ routerLink="/service" routerLinkActive #serviceRoute="routerLinkActive" [activated]="serviceRoute.isActive"> - list {{ 'SERVICE' | translate }} + list {{ 'SERVICE' | translate | titlecase }} - collections {{ 'SLIDES' | translate }} + collections {{ 'SLIDES' | translate | titlecase }} - error {{ 'ALERTS' | translate }} + error {{ 'ALERTS' | translate | titlecase }} - search {{ 'SEARCH' | translate }} + search {{ 'SEARCH' | translate | titlecase }} - image {{ 'THEMES' | translate }} + image {{ 'THEMES' | translate | titlecase }} - {{ 'MAIN_VIEW' | translate }} + {{ 'MAIN_VIEW' | translate | titlecase }} - {{ 'STAGE_VIEW' | translate }} + {{ 'STAGE_VIEW' | translate | titlecase }} - {{ 'CHORD_VIEW' | translate }} + {{ 'CHORD_VIEW' | translate | titlecase }} - settings {{ 'SETTINGS' | translate }} + settings {{ 'SETTINGS' | translate | titlecase }} @@ -113,28 +113,28 @@ @@ -143,7 +143,7 @@ #squashedDisplayButton (click)="openDisplayModeSelector()" class="squashed-display-button" - matTooltip="{{ 'CHANGE_DISPLAY_MODE' | translate }}" + matTooltip="{{ 'CHANGE_DISPLAY_MODE' | translate | titlecase }}" matTooltipPosition="above"> @if (state.blank) { videocam_off @@ -164,7 +164,7 @@ class="displayButton" [class.active]="state.blank" [disabled]="state.blank" - matTooltip="{{ 'SHOW_BLACK' | translate }}" + matTooltip="{{ 'SHOW_BLACK' | translate | titlecase }}" matTooltipPosition="above"> videocam_off @@ -174,7 +174,7 @@ class="displayButton" [class.active]="state.theme" [disabled]="state.theme" - matTooltip="{{ 'SHOW_BACKGROUND' | translate }}" + matTooltip="{{ 'SHOW_BACKGROUND' | translate | titlecase }}" matTooltipPosition="above"> wallpaper @@ -184,7 +184,7 @@ class="displayButton" [class.active]="state.display" [disabled]="state.display" - matTooltip="{{ 'SHOW_DESKTOP' | translate }}" + matTooltip="{{ 'SHOW_DESKTOP' | translate | titlecase }}" matTooltipPosition="above"> desktop_windows @@ -194,7 +194,7 @@ class="displayButton" [class.active]="state.display" [disabled]="state.live()" - matTooltip="{{ 'SHOW_PRESENTATION' | translate }}" + matTooltip="{{ 'SHOW_PRESENTATION' | translate | titlecase }}" matTooltipPosition="above"> videocam @@ -203,26 +203,26 @@ @@ -231,7 +231,7 @@ #squashedDisplayButton (click)="openDisplayModeSelector()" class="squashed-display-button" - matTooltip="{{ 'CHANGE_DISPLAY_MODE' | translate }}" + matTooltip="{{ 'CHANGE_DISPLAY_MODE' | translate | titlecase }}" matTooltipPosition="above"> @if (state.blank) { videocam_off @@ -251,7 +251,7 @@ class="displayButton" [class.active]="state.blank" [disabled]="state.blank" - matTooltip="{{ 'SHOW_BLACK' | translate }}" + matTooltip="{{ 'SHOW_BLACK' | translate | titlecase }}" matTooltipPosition="above"> videocam_off @@ -261,7 +261,7 @@ class="displayButton" [class.active]="state.theme" [disabled]="state.theme" - matTooltip="{{ 'SHOW_BACKGROUND' | translate }}" + matTooltip="{{ 'SHOW_BACKGROUND' | translate | titlecase }}" matTooltipPosition="above"> wallpaper @@ -270,7 +270,7 @@ class="displayButton" [class.active]="state.display" [disabled]="state.display" - matTooltip="{{ 'SHOW_DESKTOP' | translate }}" + matTooltip="{{ 'SHOW_DESKTOP' | translate | titlecase }}" matTooltipPosition="above"> desktop_windows @@ -279,7 +279,7 @@ class="displayButton" [class.active]="state.display" [disabled]="state.live()" - matTooltip="{{ 'SHOW_PRESENTATION' | translate }}" + matTooltip="{{ 'SHOW_PRESENTATION' | translate | titlecase }}" matTooltipPosition="above"> videocam diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 98890b3..a9d1191 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -13,7 +13,7 @@ import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { DisplayModeSelectorComponent } from './components/display-mode-selector/display-mode-selector.component'; import { Shortcuts, ShortcutsService } from './shortcuts.service'; -import { ShortcutPipe } from './components/shortcuts/shortcut.pipe'; +import { ShortcutPipe } from './components/pipes/shortcut.pipe'; import { SettingsService } from './settings.service'; import * as supportedBrowsers from '../assets/supportedBrowsers'; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f6f9613..79a8bce 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,6 +3,7 @@ import { BrowserModule, Title } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; +import { TitleCasePipe } from '@angular/common'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; @@ -38,9 +39,9 @@ import { SearchOptionsComponent } from './components/search/search-options/searc import { SlidesComponent } from './components/slides/slides.component'; import { ChordViewComponent } from './components/chord-view/chord-view.component'; import { StageViewComponent } from './components/stage-view/stage-view.component'; -import { Nl2BrPipe } from './components/stage-view/nl2br.pipe'; +import { Nl2BrPipe } from './components/pipes/nl2br.pipe'; import { MainViewComponent } from './components/main-view/main-view.component'; -import { ChordProPipe } from './components/chord-view/chordpro.pipe'; +import { ChordProPipe } from './components/pipes/chordpro.pipe'; import { LoginComponent } from './components/login/login.component'; import { ThemesComponent } from './components/themes/themes.component'; import { SlideListComponent } from './components/slides/slide-list/slide-list.component'; @@ -50,6 +51,7 @@ import { ServiceListComponent } from './components/service/service-list/service- import { ChordViewItemComponent } from './components/chord-view/chord-view-item/chord-view-item.component'; import { StageViewItemComponent } from './components/stage-view/stage-view-item/stage-view-item.component'; import { DisplayModeSelectorComponent } from './components/display-mode-selector/display-mode-selector.component'; +import { SentenceCasePipe } from './components/pipes/sentence-case.pipe'; import { SettingsComponent } from './components/settings/settings.component'; import { StageChordPreviewComponent } from './components/settings/stage-chord-preview/stage-chord-preview.component'; @@ -70,6 +72,7 @@ import { StageChordPreviewComponent } from './components/settings/stage-chord-pr AlertComponent, SearchComponent, SearchOptionsComponent, + SentenceCasePipe, SlidesComponent, SlideListComponent, SlideItemComponent, @@ -113,7 +116,9 @@ import { StageChordPreviewComponent } from './components/settings/stage-chord-pr PageTitleService, OpenLPService, TranslationService, + SentenceCasePipe, Title, + TitleCasePipe, WindowRef ], bootstrap: [AppComponent] diff --git a/src/app/components/alert/alert.component.html b/src/app/components/alert/alert.component.html index 7600af9..04f7b80 100644 --- a/src/app/components/alert/alert.component.html +++ b/src/app/components/alert/alert.component.html @@ -1,4 +1,4 @@ -

{{ 'SEND_AN_ALERT' | translate }}

+

{{ 'SEND_AN_ALERT' | translate | sentencecase }}

diff --git a/src/app/components/alert/alert.component.ts b/src/app/components/alert/alert.component.ts index 714c76f..0652a95 100644 --- a/src/app/components/alert/alert.component.ts +++ b/src/app/components/alert/alert.component.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; +import { TitleCasePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import { PageTitleService } from '../../page-title.service'; @@ -21,12 +22,13 @@ export class AlertComponent { private pageTitleService: PageTitleService, private openlpService: OpenLPService, private snackBar: MatSnackBar, + private titleCasePipe: TitleCasePipe, private translateService: TranslateService) { this.translateService.stream('ALERTS').subscribe(res => { this.pageTitleService.changePageTitle(res); }); this.translateService.stream('ALERT_SUBMITTED').subscribe(res => { - this.alertMessage = res; + this.alertMessage = this.titleCasePipe.transform(res); }); } diff --git a/src/app/components/chord-view/chord-view.component.html b/src/app/components/chord-view/chord-view.component.html index c4328e2..898349d 100644 --- a/src/app/components/chord-view/chord-view.component.html +++ b/src/app/components/chord-view/chord-view.component.html @@ -45,7 +45,7 @@ mat-mini-fab color="" class="back-button" routerLink="/" - matTooltip="{{ 'GO_BACK_TO_CONTROLLER' | translate }}"> + matTooltip="{{ 'GO_BACK_TO_CONTROLLER' | translate | titlecase }}"> arrow_back } @@ -65,7 +65,7 @@ @if (!embedded && activeSlide+1 === currentSlides.length) {
+ matTooltip="{{ 'NEXT_ITEM' | translate | titlecase }}"> {{ nextServiceItemTitle }}
} diff --git a/src/app/components/display-mode-selector/display-mode-selector.component.html b/src/app/components/display-mode-selector/display-mode-selector.component.html index ccf1a63..bebf5e6 100644 --- a/src/app/components/display-mode-selector/display-mode-selector.component.html +++ b/src/app/components/display-mode-selector/display-mode-selector.component.html @@ -13,7 +13,7 @@ -
{{ 'SHOW_BLACK' | translate }}
+
{{ 'SHOW_BLACK' | translate | titlecase }}
} diff --git a/src/app/components/login/login.component.html b/src/app/components/login/login.component.html index 01a094b..3e8df68 100644 --- a/src/app/components/login/login.component.html +++ b/src/app/components/login/login.component.html @@ -1,11 +1,11 @@ -

{{ 'LOGIN' | translate }}

+

{{ 'LOGIN' | translate | titlecase }}

@@ -13,7 +13,7 @@ - {{ 'LOGIN' | translate }} + {{ 'LOGIN' | translate | titlecase }}
diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts index d4369cc..e6f890b 100644 --- a/src/app/components/login/login.component.ts +++ b/src/app/components/login/login.component.ts @@ -1,6 +1,7 @@ import { Component } from '@angular/core'; import { MatDialogRef } from '@angular/material/dialog'; import { MatSnackBar } from '@angular/material/snack-bar'; +import { TitleCasePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import { OpenLPService } from '../../openlp.service'; @@ -20,12 +21,13 @@ export class LoginComponent { private dialogRef: MatDialogRef, private openlpService: OpenLPService, private snackBar: MatSnackBar, + private titleCasePipe: TitleCasePipe, private translateService: TranslateService) { this.translateService.stream('LOGIN_SUCCEEDED').subscribe(res => { - this.loginSucceededMessage = res; + this.loginSucceededMessage = this.titleCasePipe.transform(res); }); this.translateService.stream('LOGIN_FAILED').subscribe(res => { - this.loginFailedMessage = res; + this.loginFailedMessage = this.titleCasePipe.transform(res); }); } diff --git a/src/app/components/chord-view/chordpro.pipe.ts b/src/app/components/pipes/chordpro.pipe.ts similarity index 100% rename from src/app/components/chord-view/chordpro.pipe.ts rename to src/app/components/pipes/chordpro.pipe.ts diff --git a/src/app/components/stage-view/nl2br.pipe.ts b/src/app/components/pipes/nl2br.pipe.ts similarity index 91% rename from src/app/components/stage-view/nl2br.pipe.ts rename to src/app/components/pipes/nl2br.pipe.ts index 908a199..900ce3c 100644 --- a/src/app/components/stage-view/nl2br.pipe.ts +++ b/src/app/components/pipes/nl2br.pipe.ts @@ -5,7 +5,7 @@ import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; export class Nl2BrPipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) { } - transform(value: string): string|SafeHtml { + transform(value: string): string | SafeHtml { if (!value) { return value; } diff --git a/src/app/components/pipes/sentence-case.pipe.ts b/src/app/components/pipes/sentence-case.pipe.ts new file mode 100644 index 0000000..5f8e539 --- /dev/null +++ b/src/app/components/pipes/sentence-case.pipe.ts @@ -0,0 +1,17 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({name: 'sentencecase'}) +export class SentenceCasePipe implements PipeTransform { + transform(value: string): string { + if (!value) { + return value; + } + if (typeof value !== 'string') { + throw Error(`Invalid pipe argument: '${value}' for pipe 'SentenceCasePipe'`); + } + const sentenceEndMarker: string = '. ' + return value.split(sentenceEndMarker).map( + (sentence) => sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1).toLowerCase() + ).join(sentenceEndMarker); + } +} diff --git a/src/app/components/shortcuts/shortcut.pipe.ts b/src/app/components/pipes/shortcut.pipe.ts similarity index 100% rename from src/app/components/shortcuts/shortcut.pipe.ts rename to src/app/components/pipes/shortcut.pipe.ts diff --git a/src/app/components/search/search-options/search-options.component.ts b/src/app/components/search/search-options/search-options.component.ts index dfb1ce5..c6a65f1 100644 --- a/src/app/components/search/search-options/search-options.component.ts +++ b/src/app/components/search/search-options/search-options.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { TitleCasePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import { OpenLPService } from '../../../openlp.service'; @@ -17,6 +18,7 @@ export class SearchOptionsComponent { constructor( private openlpService: OpenLPService, + private titleCasePipe: TitleCasePipe, private translateService: TranslateService) { } // Used to display search-options for certain plugins @@ -24,7 +26,7 @@ export class SearchOptionsComponent { this.selectedPlugin = plugin; if (this.selectedPlugin === 'bibles') { this.translateService.stream('BIBLE_VERSION').subscribe(res => { - this.searchOptionsTitle = res + ':'; + this.searchOptionsTitle = this.titleCasePipe.transform(res) + ':'; }); this.getSearchOptions(); } diff --git a/src/app/components/search/search.component.html b/src/app/components/search/search.component.html index 946b6d5..1d43671 100644 --- a/src/app/components/search/search.component.html +++ b/src/app/components/search/search.component.html @@ -1,4 +1,4 @@ -

{{ 'SEARCH' | translate }}

+

{{ 'SEARCH' | translate | titlecase }}


@@ -34,12 +34,12 @@ color="primary" [disabled]="!searchForm.form.valid" (click)="onSubmit()"> - {{ 'SEARCH' | translate }} + {{ 'SEARCH' | translate | titlecase }}
@if (searchResults) {
-

{{ 'SEARCH_RESULTS' | translate }}:

+

{{ 'SEARCH_RESULTS' | translate | titlecase }}:

@if (searchResults.length) { @for (item of searchResults; track item) { @@ -49,14 +49,14 @@ @@ -65,7 +65,7 @@ } @else {
- {{ 'NO_SEARCH_RESULTS' | translate }}... + {{ 'NO_SEARCH_RESULTS' | translate | sentencecase }}...
} diff --git a/src/app/components/service/service-list/service-list.component.html b/src/app/components/service/service-list/service-list.component.html index d92f8f5..fa4323c 100644 --- a/src/app/components/service/service-list/service-list.component.html +++ b/src/app/components/service/service-list/service-list.component.html @@ -14,7 +14,7 @@
info - {{ 'NO_SERVICE_ITEMS' | translate }}. + {{ 'NO_SERVICE_ITEMS' | translate | sentencecase }}.
diff --git a/src/app/components/service/service-list/service-list.component.ts b/src/app/components/service/service-list/service-list.component.ts index 58b9c7d..8b0c1a1 100644 --- a/src/app/components/service/service-list/service-list.component.ts +++ b/src/app/components/service/service-list/service-list.component.ts @@ -7,7 +7,7 @@ import { ServiceItem } from '../../../responses'; @Component({ selector: 'openlp-service-list', templateUrl: './service-list.component.html', - styleUrls: ['./service-list.component.scss', '../../no-items.scss'], + styleUrls: ['./service-list.component.scss', '../../no-items.scss'] }) export class ServiceListComponent implements OnInit, OnDestroy { diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html index 7fcb8ee..7aff63f 100644 --- a/src/app/components/settings/settings.component.html +++ b/src/app/components/settings/settings.component.html @@ -1,7 +1,7 @@
- {{ 'USER_INTERFACE' | translate }} + {{ 'USER_INTERFACE' | translate | titlecase }}
@@ -9,7 +9,7 @@ color="primary" [checked]="settings.fastSwitching" (change)="setSetting('fastSwitching', $event.checked)"> - {{ 'ENABLE_FAST_SWITCHING_PANEL' | translate }} + {{ 'ENABLE_FAST_SWITCHING_PANEL' | translate | sentencecase }}
@@ -17,18 +17,18 @@ color="primary" [checked]="settings.bigDisplayButtons" (change)="setSetting('bigDisplayButtons', $event.checked)"> - {{ 'ENABLE_BIG_DISPLAY_BUTTONS' | translate }} + {{ 'ENABLE_BIG_DISPLAY_BUTTONS' | translate | sentencecase }}
- {{ 'STAGE_AND_CHORDS_APPEARANCE' | translate }} + {{ 'STAGE_AND_CHORDS_APPEARANCE' | translate | sentencecase }} - + @@ -38,7 +38,7 @@ - + @@ -55,7 +55,7 @@ let-prefix="prefix">
- +
info - {{ 'NO_SLIDE_ITEMS' | translate }}. + {{ 'NO_SLIDE_ITEMS' | translate | sentencecase }}.
diff --git a/src/app/components/stage-view/stage-view.component.html b/src/app/components/stage-view/stage-view.component.html index 9a16951..23e71ab 100644 --- a/src/app/components/stage-view/stage-view.component.html +++ b/src/app/components/stage-view/stage-view.component.html @@ -27,7 +27,7 @@ class="back-button" mat-mini-fab color="" routerLink="/" - matTooltip="{{ 'GO_BACK_TO_CONTROLLER' | translate }}"> + matTooltip="{{ 'GO_BACK_TO_CONTROLLER' | translate | titlecase }}"> arrow_back } @@ -35,7 +35,7 @@