mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-15 00:30:02 +00:00
Update frontend to Angular v15 (#110)
* Update Typescript to 4.9.0 * Update Angular to v15 * Update Angular Flex Layout to v15 * Update Angular CDK to v15 * Update Angular CDK to v15 * Update Angular Material to v15 * WIP: Update Angular Material to v15 * Fix progress bar colors * Fix company logos size * Update angular minor version * Update mat-table-filter Update @angular/youtube-player * Update rxjs * Fix search-bar layout Fix autocomplete layout Change mat-icon-button to mat-fab in game-detail-view * Fix sort selector drop-down checkmark
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
|
||||
# For the full list of supported browsers by the Angular framework, please see:
|
||||
# https://angular.io/guide/browser-support
|
||||
|
||||
# You can see what browsers were selected by your queries by running:
|
||||
# npx browserslist
|
||||
|
||||
last 1 Chrome version
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
||||
last 2 Safari major versions
|
||||
last 2 iOS major versions
|
||||
Firefox ESR
|
||||
Generated
+3119
-11891
File diff suppressed because it is too large
Load Diff
+19
-19
@@ -10,27 +10,27 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^14.0.0",
|
||||
"@angular/cdk": "^14.1.0",
|
||||
"@angular/common": "^14.0.0",
|
||||
"@angular/compiler": "^14.0.0",
|
||||
"@angular/core": "^14.0.0",
|
||||
"@angular/flex-layout": "^14.0.0-beta.40",
|
||||
"@angular/forms": "^14.0.0",
|
||||
"@angular/material": "^14.1.0",
|
||||
"@angular/platform-browser": "^14.0.0",
|
||||
"@angular/platform-browser-dynamic": "^14.0.0",
|
||||
"@angular/router": "^14.0.0",
|
||||
"@angular/youtube-player": "^14.2.7",
|
||||
"mat-table-filter": "^10.2.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"@angular/animations": "^15.2.6",
|
||||
"@angular/cdk": "^15.2.6",
|
||||
"@angular/common": "^15.2.6",
|
||||
"@angular/compiler": "^15.2.6",
|
||||
"@angular/core": "^15.2.6",
|
||||
"@angular/flex-layout": "^15.0.0-beta.42",
|
||||
"@angular/forms": "^15.2.6",
|
||||
"@angular/material": "^15.2.6",
|
||||
"@angular/platform-browser": "^15.2.6",
|
||||
"@angular/platform-browser-dynamic": "^15.2.6",
|
||||
"@angular/router": "^15.2.6",
|
||||
"@angular/youtube-player": "^15.2.6",
|
||||
"mat-table-filter": "^15.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.11.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^14.0.7",
|
||||
"@angular/cli": "~14.0.7",
|
||||
"@angular/compiler-cli": "^14.0.0",
|
||||
"@angular-devkit/build-angular": "^15.2.5",
|
||||
"@angular/cli": "~15.2.5",
|
||||
"@angular/compiler-cli": "^15.2.6",
|
||||
"@types/jasmine": "~4.0.0",
|
||||
"jasmine-core": "~4.1.0",
|
||||
"karma": "~6.4.1",
|
||||
@@ -38,6 +38,6 @@
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-jasmine": "~5.1.0",
|
||||
"karma-jasmine-html-reporter": "~2.0.0",
|
||||
"typescript": "~4.7.2"
|
||||
"typescript": "^4.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,29 +3,31 @@
|
||||
<div fxLayout="column" fxFlex="0 1 75" fxLayoutGap="16px" fxFlex.lt-lg="95">
|
||||
<div fxLayout="row" fxLayout.lt-lg="column" fxLayoutGap="16px">
|
||||
|
||||
<mat-card fxFlex="100" fxLayout="row" fxLayout.lt-lg="column" fxLayoutGap="16px">
|
||||
<div fxLayoutAlign="start" fxLayoutAlign.lt-lg="center">
|
||||
<img src="v1/images/{{game.coverId}}" style="max-height: 352px" alt="Game cover">
|
||||
</div>
|
||||
|
||||
<div fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="space-between">
|
||||
<div fxLayoutGap="8px">
|
||||
<h1 style="display: inline-block">{{game.title}}</h1>
|
||||
<h3 style="display: inline-block; font-style: italic">{{game.releaseDate | date: 'yyyy'}}</h3>
|
||||
|
||||
<h2>Description</h2>
|
||||
<p>{{game.summary}}</p>
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="row" fxLayout.lt-lg="column" fxLayoutGap="16px">
|
||||
<div fxLayoutAlign="start" fxLayoutAlign.lt-lg="center">
|
||||
<img src="v1/images/{{game.coverId}}" style="max-height: 352px" alt="Game cover">
|
||||
</div>
|
||||
|
||||
<div *ngIf="companiesWithLogo.length > 0">
|
||||
<h2>Developed by</h2>
|
||||
<div fxLayout="row wrap" fxLayoutGap="8px grid">
|
||||
<div *ngFor="let company of companiesWithLogo" class="company-logos">
|
||||
<img src="v1/images/{{company.logoId}}" alt="{{company.name}}" [matTooltip]="company.name">
|
||||
<div fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="space-between">
|
||||
<div fxLayoutGap="8px">
|
||||
<h1 style="display: inline-block">{{game.title}}</h1>
|
||||
<h3 style="display: inline-block; font-style: italic">{{game.releaseDate | date: 'yyyy'}}</h3>
|
||||
|
||||
<h2>Description</h2>
|
||||
<p>{{game.summary}}</p>
|
||||
</div>
|
||||
|
||||
<div *ngIf="companiesWithLogo.length > 0">
|
||||
<h2>Developed by</h2>
|
||||
<div fxLayout="row wrap" fxLayoutGap="8px grid">
|
||||
<div *ngFor="let company of companiesWithLogo" class="company-logos">
|
||||
<img src="v1/images/{{company.logoId}}" alt="{{company.name}}" [matTooltip]="company.name">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<div fxFlex><!-- Spacer --></div>
|
||||
@@ -33,10 +35,10 @@
|
||||
<div fxLayout="column" fxFlex="40" fxLayoutGap="16px">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
|
||||
<button mat-raised-button color="secondary" (click)="refreshGame()" title="Refresh metadata">
|
||||
<button mat-fab color="secondary" (click)="refreshGame()" title="Refresh metadata">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
<button mat-raised-button color="primary" (click)="downloadGame()">
|
||||
<button mat-fab color="primary" (click)="downloadGame()">
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
<b style="font-size: 24px">Download ({{bytesAsHumanReadableString(game.diskSize)}})</b>
|
||||
@@ -45,26 +47,26 @@
|
||||
<div fxLayout="column" fxLayoutGap="24px">
|
||||
<div *ngIf="game.genres !== undefined && game.genres.length > 0">
|
||||
<h2>Genres</h2>
|
||||
<mat-chip-list>
|
||||
<mat-chip *ngFor="let genre of game.genres"
|
||||
(click)="goToLibraryWithFilter('genres', genre.slug)">{{genre.name}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-listbox>
|
||||
<mat-chip-option *ngFor="let genre of game.genres"
|
||||
(click)="goToLibraryWithFilter('genres', genre.slug)">{{genre.name}}</mat-chip-option>
|
||||
</mat-chip-listbox>
|
||||
</div>
|
||||
|
||||
<div *ngIf="game.themes !== undefined && game.themes.length > 0">
|
||||
<h2>Themes</h2>
|
||||
<mat-chip-list>
|
||||
<mat-chip *ngFor="let theme of game.themes"
|
||||
(click)="goToLibraryWithFilter('themes', theme.slug)">{{theme.name}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-listbox>
|
||||
<mat-chip-option *ngFor="let theme of game.themes"
|
||||
(click)="goToLibraryWithFilter('themes', theme.slug)">{{theme.name}}</mat-chip-option>
|
||||
</mat-chip-listbox>
|
||||
</div>
|
||||
|
||||
<div *ngIf="game.platforms !== undefined && game.platforms.length > 0">
|
||||
<h2>Platforms</h2>
|
||||
<mat-chip-list>
|
||||
<mat-chip *ngFor="let platform of game.platforms" [disabled]="game.library == undefined || !hasPlatform(game.library, platform)"
|
||||
(click)="goToLibraryWithFilter('platforms', platform.slug)">{{platform.name}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-listbox>
|
||||
<mat-chip-option *ngFor="let platform of game.platforms" [disabled]="game.library == undefined || !hasPlatform(game.library, platform)"
|
||||
(click)="goToLibraryWithFilter('platforms', platform.slug)">{{platform.name}}</mat-chip-option>
|
||||
</mat-chip-listbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
.mat-card {
|
||||
// min-height: max-content;
|
||||
|
||||
.company-logos img {
|
||||
max-height: 52px;
|
||||
max-width: 260px;
|
||||
}
|
||||
.company-logos img {
|
||||
max-height: 52px;
|
||||
max-width: 260px;
|
||||
}
|
||||
|
||||
@@ -26,34 +26,37 @@
|
||||
<div fxFlex.gt-md="0 1 15" fxLayout="column" fxLayoutGap="16px" fxLayoutAlign.lt-lg="start center"
|
||||
fxFlex.lt-lg="100" [ngClass.gt-md]="'sticky'">
|
||||
|
||||
<mat-card fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="6px" class="mat-card-48">
|
||||
<div fxLayout="row" fxLayoutAlign="start center">
|
||||
<button mat-icon-button *ngIf="searchTerm.length > 0" matTooltip="Clear search input"
|
||||
(click)="clearSearchTerm()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button *ngIf="searchTerm.length === 0" matTooltip="Search for games by title">
|
||||
<button mat-icon-button *ngIf="searchTerm.length === 0" matTooltip="Search for games by title"
|
||||
style="pointer-events: none">
|
||||
<mat-icon>search</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-form-field fxFlex>
|
||||
<input type="text" matInput [matAutocomplete]="librarySearchAutocomplete" [(ngModel)]="searchTerm"
|
||||
<mat-form-field appearance="outline" subscriptSizing="dynamic" fxFlex>
|
||||
<input matInput [matAutocomplete]="librarySearchAutocomplete" [(ngModel)]="searchTerm"
|
||||
(ngModelChange)="refreshLibraryView()">
|
||||
<mat-autocomplete #librarySearchAutocomplete="matAutocomplete">
|
||||
<mat-autocomplete #librarySearchAutocomplete="matAutocomplete" hideSingleSelectionIndicator panelWidth="auto">
|
||||
<mat-option *ngFor="let game of games" [value]="game.title">
|
||||
{{game.title}}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<mat-card fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="20px" class="mat-card-48">
|
||||
<h3 class="filter-category-title" style="white-space: nowrap; padding-left: 6px">Sort by: </h3>
|
||||
<mat-select [(value)]="selectedSortOption" (valueChange)="refreshLibraryView()">
|
||||
<mat-option *ngFor="let sortOption of sortOptions" [value]="sortOption">
|
||||
{{sortOption.title}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-card>
|
||||
<mat-card-content fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="20px">
|
||||
<h3 class="filter-category-title" style="white-space: nowrap; padding-left: 6px">Sort by: </h3>
|
||||
<mat-select [(value)]="selectedSortOption" (valueChange)="refreshLibraryView()" hideSingleSelectionIndicator>
|
||||
<mat-option *ngFor="let sortOption of sortOptions" [value]="sortOption">
|
||||
{{sortOption.title}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<mat-expansion-panel [expanded]="filterExpansionState.gamemodes">
|
||||
|
||||
@@ -38,16 +38,14 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mat-card-48 {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
::ng-deep .mat-checkbox-frame {
|
||||
/*TODO(mdc-migration): The following rule targets internal classes of checkbox that may no longer apply for the MDC version.*/
|
||||
::ng-deep .mat-mdc-text-field-wrapper {
|
||||
$config: mat.get-color-config($dark-theme);
|
||||
$primary-palette: map.get($config, 'primary');
|
||||
border-color: mat.get-color-from-palette($primary-palette, 500) !important;
|
||||
}
|
||||
|
||||
/*TODO(mdc-migration): The following rule targets internal classes of form-field that may no longer apply for the MDC version.*/
|
||||
::ng-deep .mat-form-field-underline {
|
||||
$config: mat.get-color-config($dark-theme);
|
||||
$primary-palette: map.get($config, 'primary');
|
||||
|
||||
+4
-2
@@ -1,10 +1,12 @@
|
||||
import {AfterViewInit, Component, Input, OnChanges, SimpleChanges, ViewChild} from '@angular/core';
|
||||
import {MatPaginator} from '@angular/material/paginator';
|
||||
import {MatSort} from '@angular/material/sort';
|
||||
import {MatTable, MatTableDataSource} from '@angular/material/table';
|
||||
import {
|
||||
MatTable,
|
||||
MatTableDataSource
|
||||
} from '@angular/material/table';
|
||||
import {LibraryDto} from "../../models/dtos/LibraryDto";
|
||||
import {LibraryScanRequestDto} from "../../models/dtos/LibraryScanRequestDto";
|
||||
import {GamesService} from "../../services/games.service";
|
||||
import {LibraryManagementService} from "../../services/library-management.service";
|
||||
import {DialogService} from "../../services/dialog.service";
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
|
||||
@@ -25,8 +25,12 @@ export class ProgressBarColorDirective implements OnChanges{
|
||||
updateColor(): void{
|
||||
// update dynamic style with the uniqueAttr
|
||||
this.styleEl.innerText = `
|
||||
[${this.uniqueAttr}] .mat-progress-bar-fill::after {
|
||||
background-color: ${this.progressBarColor};
|
||||
[${this.uniqueAttr}] .mdc-linear-progress__bar-inner {
|
||||
border-color: ${this.progressBarColor};
|
||||
}
|
||||
|
||||
[${this.uniqueAttr}] .mdc-linear-progress__buffer-bar {
|
||||
background-color: ${this.progressBarColor}55 !important;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,15 @@
|
||||
// Include the common styles for Angular Material. We include this here so that you only
|
||||
// have to load a single css file for Angular Material in your app.
|
||||
// Be sure that you only ever include this mixin once!
|
||||
// TODO(v15): As of v15 mat.legacy-core no longer includes default typography styles.
|
||||
// The following line adds:
|
||||
// 1. Default typography styles for all components
|
||||
// 2. Styles for typography hierarchy classes (e.g. .mat-headline-1)
|
||||
// If you specify typography styles for the components you use elsewhere, you should delete this line.
|
||||
// If you don't need the default component typographies but still want the hierarchy styles,
|
||||
// you can delete this line and instead use:
|
||||
// `@include mat.legacy-typography-hierarchy(mat.define-typography-config());`
|
||||
@include mat.all-component-typographies();
|
||||
@include mat.core();
|
||||
|
||||
// Include theme styles for core and each component used in your app.
|
||||
|
||||
@@ -7,20 +7,8 @@ import {
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
declare const require: {
|
||||
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||
<T>(id: string): T;
|
||||
keys(): string[];
|
||||
};
|
||||
};
|
||||
|
||||
// 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().forEach(context);
|
||||
|
||||
@@ -18,12 +18,13 @@
|
||||
"resolveJsonModule": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"importHelpers": true,
|
||||
"target": "es2020",
|
||||
"target": "ES2022",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
]
|
||||
],
|
||||
"useDefineForClassFields": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
|
||||
Reference in New Issue
Block a user