Add about dialog

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/16/head
trivernis 3 years ago
parent bb2a63c703
commit 77d288d905
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,7 +1,7 @@
<div id="content"> <div id="content">
<mat-tab-group #tabGroup (selectedTabChange)="this.onTabSelectionChange($event)" animationDuration="0" <mat-tab-group #tabGroup (selectedTabChange)="this.onTabSelectionChange($event)" animationDuration="0"
class="main-tab-group"> class="main-tab-group">
<mat-tab [label]="this.selectedRepository? 'RepositoryData' : 'Repositories'"> <mat-tab [label]="this.selectedRepository? 'Repository' : 'Repositories'">
<app-repositories-tab></app-repositories-tab> <app-repositories-tab></app-repositories-tab>
</mat-tab> </mat-tab>
<mat-tab *ngFor="let tab of tabs; trackBy: trackByTabId"> <mat-tab *ngFor="let tab of tabs; trackBy: trackByTabId">

@ -41,6 +41,7 @@ import {
} from "./repositories-tab/repository-details-view/repository-details-view.component"; } from "./repositories-tab/repository-details-view/repository-details-view.component";
import { EmptyTabComponent } from './empty-tab/empty-tab.component'; import { EmptyTabComponent } from './empty-tab/empty-tab.component';
import { RepositoryOverviewComponent } from './repositories-tab/repository-overview/repository-overview.component'; import { RepositoryOverviewComponent } from './repositories-tab/repository-overview/repository-overview.component';
import { AboutDialogComponent } from './repositories-tab/repository-overview/about-dialog/about-dialog.component';
@NgModule({ @NgModule({
@ -56,6 +57,7 @@ import { RepositoryOverviewComponent } from './repositories-tab/repository-overv
RepositoryDetailsViewComponent, RepositoryDetailsViewComponent,
EmptyTabComponent, EmptyTabComponent,
RepositoryOverviewComponent, RepositoryOverviewComponent,
AboutDialogComponent,
], ],
exports: [ exports: [
CoreComponent, CoreComponent,

@ -0,0 +1,24 @@
<h1 class="title" mat-dialog-title>
About mediarepo
</h1>
<div class="content" mat-dialog-content>
<app-metadata-entry attributeName="Version" display="line">
{{version | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="Tauri Version" display="line">
{{tauriVersion | async}}
</app-metadata-entry>
<br>
<mat-divider></mat-divider>
<h2>Built with</h2>
<div class="lib-list">
<b *ngFor="let lib of usedLibs">
<app-external-url [href]="lib[1]">{{lib[0]}}</app-external-url>
</b>
</div>
</div>
<div class="actions" mat-dialog-actions>
<button (click)="this.dialogRef.close(true)" color="primary" mat-stroked-button>
Close
</button>
</div>

@ -0,0 +1,20 @@
.title {
text-align: center;
}
.actions {
display: block;
button {
float: right;
}
}
.content {
text-align: center;
}
.lib-list {
display: flex;
flex-direction: column;
}

@ -0,0 +1,25 @@
import {ComponentFixture, TestBed} from "@angular/core/testing";
import {AboutDialogComponent} from "./about-dialog.component";
describe("AboutDialogComponent", () => {
let component: AboutDialogComponent;
let fixture: ComponentFixture<AboutDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AboutDialogComponent]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AboutDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,31 @@
import {ChangeDetectionStrategy, Component, OnInit} from "@angular/core";
import {MatDialogRef} from "@angular/material/dialog";
import {app} from "@tauri-apps/api";
import {Subject} from "rxjs";
@Component({
selector: "app-about-dialog",
templateUrl: "./about-dialog.component.html",
styleUrls: ["./about-dialog.component.scss"],
changeDetection: ChangeDetectionStrategy.Default
})
export class AboutDialogComponent implements OnInit {
public version = new Subject<string>();
public tauriVersion = new Subject<string>();
public usedLibs = [
["Tauri", "https://tauri.studio"],
["Angular", "https://angular.io/"],
["SeaORM", "https://www.sea-ql.org"],
["Tokio", "https://tokio.rs/"],
["bromine", "https://github.com/Trivernis/bromine"]
];
constructor(public dialogRef: MatDialogRef<AboutDialogComponent>) {
}
public async ngOnInit() {
this.version.next(await app.getVersion());
this.tauriVersion.next(await app.getTauriVersion());
}
}

@ -1,7 +1,10 @@
<mat-toolbar>
<h1 class="page-title">All Repositories</h1>
<button (click)="openAddRepositoryDialog()" class="add-repo-button" color="primary" mat-flat-button>Add Repository
</button>
<button (click)="openAboutDialog()" class="about-button" mat-stroked-button>About</button>
</mat-toolbar>
<div class="repo-page-content"> <div class="repo-page-content">
<div class="add-repo-tools">
<button (click)="openAddRepositoryDialog()" color="primary" mat-flat-button>Add Repository</button>
</div>
<div class="repository-list"> <div class="repository-list">
<div *ngFor="let repository of repositories" class="repository-container"> <div *ngFor="let repository of repositories" class="repository-container">
<app-repository-card (openEvent)="this.onOpenRepository($event)" <app-repository-card (openEvent)="this.onOpenRepository($event)"

@ -40,3 +40,22 @@ app-repository-card {
border-radius: 0.5em; border-radius: 0.5em;
} }
} }
mat-toolbar {
position: relative;
overflow: hidden;
.add-repo-button {
margin: 0 auto 0 0;
}
.about-button {
margin: 0 0 0 auto;
}
.page-title {
position: absolute;
width: calc(100% - 32px);
text-align: center;
}
}

@ -11,6 +11,7 @@ import {
import {BehaviorSubject} from "rxjs"; import {BehaviorSubject} from "rxjs";
import {BusyDialogComponent} from "../../../shared/app-common/busy-dialog/busy-dialog.component"; import {BusyDialogComponent} from "../../../shared/app-common/busy-dialog/busy-dialog.component";
import {DownloadDaemonDialogComponent} from "../download-daemon-dialog/download-daemon-dialog.component"; import {DownloadDaemonDialogComponent} from "../download-daemon-dialog/download-daemon-dialog.component";
import {AboutDialogComponent} from "./about-dialog/about-dialog.component";
type BusyDialogContext = { message: BehaviorSubject<string>, dialog: MatDialogRef<BusyDialogComponent> }; type BusyDialogContext = { message: BehaviorSubject<string>, dialog: MatDialogRef<BusyDialogComponent> };
@ -94,6 +95,13 @@ export class RepositoryOverviewComponent implements OnInit, AfterViewInit {
} }
} }
public openAboutDialog(): void {
this.dialog.open(AboutDialogComponent, {
minWidth: "30%",
minHeight: "50%",
});
}
private async forceCloseRepository() { private async forceCloseRepository() {
try { try {
await this.repoService.closeSelectedRepository(); await this.repoService.closeSelectedRepository();

@ -25,6 +25,7 @@ import {MatRippleModule} from "@angular/material/core";
import {FlapButtonComponent} from "./flap-button/flap-button.component"; import {FlapButtonComponent} from "./flap-button/flap-button.component";
import {MiddleCenteredComponent} from "./middle-centered/middle-centered.component"; import {MiddleCenteredComponent} from "./middle-centered/middle-centered.component";
import {FormatBytesPipe} from "./pipes/format-bytes.pipe"; import {FormatBytesPipe} from "./pipes/format-bytes.pipe";
import {ExternalUrlComponent} from "./external-url/external-url.component";
@NgModule({ @NgModule({
@ -44,6 +45,7 @@ import {FormatBytesPipe} from "./pipes/format-bytes.pipe";
FlapButtonComponent, FlapButtonComponent,
MiddleCenteredComponent, MiddleCenteredComponent,
FormatBytesPipe, FormatBytesPipe,
ExternalUrlComponent,
], ],
exports: [ exports: [
ConfirmDialogComponent, ConfirmDialogComponent,
@ -60,6 +62,7 @@ import {FormatBytesPipe} from "./pipes/format-bytes.pipe";
FlapButtonComponent, FlapButtonComponent,
MiddleCenteredComponent, MiddleCenteredComponent,
FormatBytesPipe, FormatBytesPipe,
ExternalUrlComponent,
], ],
imports: [ imports: [
CommonModule, CommonModule,

@ -0,0 +1,3 @@
<span (click)="this.openUrl()" class="highlight">
<ng-content></ng-content>
</span>

@ -0,0 +1,15 @@
@import "src/colors";
.highlight {
cursor: pointer;
color: $primary-lighter-20;
text-decoration: underline;
&:hover {
color: $primary-lighter-30;
}
&:active {
color: $accent;
}
}

@ -0,0 +1,25 @@
import {ComponentFixture, TestBed} from "@angular/core/testing";
import {ExternalUrlComponent} from "./external-url.component";
describe("ExternalUrlComponent", () => {
let component: ExternalUrlComponent;
let fixture: ComponentFixture<ExternalUrlComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ExternalUrlComponent]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ExternalUrlComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,31 @@
import {ChangeDetectionStrategy, Component, Input} from "@angular/core";
import {shell} from "@tauri-apps/api";
@Component({
selector: "app-external-url",
templateUrl: "./external-url.component.html",
styleUrls: ["./external-url.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ExternalUrlComponent {
@Input() href!: string;
private opening = false;
constructor() {
}
public async openUrl() {
if (this.opening) {
return;
}
this.opening = true;
try {
await shell.open(this.href);
} catch (err) {
console.error(err);
} finally {
this.opening = false;
}
}
}

@ -1,4 +1,6 @@
<div class="metadata-entry-inner"> <div [class.display-line]="this.display === 'line'"
[class.display-multiline]="this.display === 'multiline'"
class="metadata-entry-inner">
<span class="metadata-attribute">{{attributeName}}:</span> <span class="metadata-attribute">{{attributeName}}:</span>
<span class="metadata-value"> <span class="metadata-value">
<ng-content></ng-content> <ng-content></ng-content>

@ -1,8 +1,29 @@
.metadata-entry-inner { .metadata-entry-inner {
width: 100%; width: 100%;
display: flex; display: flex;
&.display-line {
display: flex;
flex-direction: row;
.metadata-attribute, .metadata-value {
width: 50%;
}
.metadata-attribute {
text-align: right;
}
.metadata-value {
text-align: left;
}
}
&.display-multiline {
flex-direction: column; flex-direction: column;
} }
}
.metadata-attribute { .metadata-attribute {
opacity: 0.8; opacity: 0.8;
@ -15,3 +36,4 @@
word-break: break-all; word-break: break-all;
user-select: text; user-select: text;
} }

@ -1,14 +1,15 @@
import {Component, Input} from "@angular/core"; import {ChangeDetectionStrategy, Component, Input} from "@angular/core";
@Component({ @Component({
selector: "app-metadata-entry", selector: "app-metadata-entry",
templateUrl: "./metadata-entry.component.html", templateUrl: "./metadata-entry.component.html",
styleUrls: ["./metadata-entry.component.scss"] styleUrls: ["./metadata-entry.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class MetadataEntryComponent { export class MetadataEntryComponent {
@Input() display: "multiline" | "line" = "multiline";
@Input() attributeName!: string; @Input() attributeName!: string;
@Input() value!: string;
constructor() { constructor() {
} }

Loading…
Cancel
Save