Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
trivernis | db01332c15 | 4 months ago |
trivernis | 7047dc7903 | 4 months ago |
Julius Riegel | 3a25a8b812 | 2 years ago |
trivernis | d83f211ceb | 2 years ago |
trivernis | 5dd8eefdcc | 2 years ago |
trivernis | 6dfefe01c2 | 2 years ago |
trivernis | 99c224586a | 2 years ago |
trivernis | 8256751a6f | 2 years ago |
trivernis | 580c27bbd1 | 2 years ago |
trivernis | 37f7a2c82f | 2 years ago |
trivernis | 89e9e182dd | 2 years ago |
Julius Riegel | 75bc9821b1 | 2 years ago |
trivernis | e7f09dd2b5 | 2 years ago |
trivernis | 49c41ce127 | 2 years ago |
Julius Riegel | af28527f36 | 2 years ago |
trivernis | b4e52b0db0 | 2 years ago |
trivernis | 146088e747 | 2 years ago |
@ -0,0 +1,11 @@
|
||||
[language-server.rust-analyzer]
|
||||
command = "rust-analyzer"
|
||||
|
||||
[language-server.rust-analyzer.config]
|
||||
inlayHints.bindingModeHints.enable = false
|
||||
inlayHints.closingBraceHints.minLines = 10
|
||||
inlayHints.closureReturnTypeHints.enable = "with_block"
|
||||
inlayHints.discriminantHints.enable = "fieldless"
|
||||
inlayHints.lifetimeElisionHints.enable = "skip_trivial"
|
||||
inlayHints.typeHints.hideClosureInitialization = false
|
||||
cargo.features = "all"
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +0,0 @@
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait AsyncTryFrom<T> {
|
||||
type Error;
|
||||
fn async_try_from(other: T) -> Result<Self, Self::Error>;
|
||||
}
|
@ -1,66 +1,57 @@
|
||||
{
|
||||
"root": true,
|
||||
"ignorePatterns": [
|
||||
"projects/**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": [
|
||||
"tsconfig.json"
|
||||
],
|
||||
"createDefaultProgram": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/recommended",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "attribute",
|
||||
"prefix": "app",
|
||||
"style": "camelCase"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "element",
|
||||
"prefix": "app",
|
||||
"style": "kebab-case"
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"warn",
|
||||
"double",
|
||||
{
|
||||
"avoidEscape": true
|
||||
}
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"no-unused-expressions": "warn",
|
||||
"semi": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.html"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/template/recommended"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
"root": true,
|
||||
"ignorePatterns": ["projects/**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"parserOptions": {
|
||||
"project": ["tsconfig.json"],
|
||||
"createDefaultProgram": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/recommended",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "attribute",
|
||||
"prefix": "app",
|
||||
"style": "camelCase"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "element",
|
||||
"prefix": "app",
|
||||
"style": "kebab-case"
|
||||
}
|
||||
],
|
||||
"quotes": [
|
||||
"warn",
|
||||
"double",
|
||||
{
|
||||
"avoidEscape": true
|
||||
}
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"no-unused-expressions": "warn",
|
||||
"no-extraneous-class": "off",
|
||||
"semi": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"extends": ["plugin:@angular-eslint/template/recommended"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
[language-server.biome]
|
||||
command = "biome"
|
||||
args = ["lsp-proxy"]
|
||||
|
||||
[[language]]
|
||||
name = "typescript"
|
||||
language-servers = ["typescript-language-server"]
|
||||
auto-format = true
|
||||
formatter = { command = "biome" , args = ["format", "--stdin-file-path=file.ts"] }
|
||||
|
||||
[[language]]
|
||||
name = "javascript"
|
||||
language-servers = ["typescript-language-server", "biome"]
|
||||
auto-format = true
|
||||
formatter = { command = "biome" , args = ["format", "--stdin-file-path=file.js"] }
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.3.3/schema.json",
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"complexity": {
|
||||
"noStaticOnlyClass": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +1,64 @@
|
||||
{
|
||||
"name": "mediarepo-ui",
|
||||
"version": "1.0.1",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"watch-prod": "ng build --watch --configuration production",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~13.3.2",
|
||||
"@angular/cdk": "^13.3.2",
|
||||
"@angular/common": "~13.3.2",
|
||||
"@angular/compiler": "~13.3.2",
|
||||
"@angular/core": "~13.3.2",
|
||||
"@angular/flex-layout": "^13.0.0-beta.36",
|
||||
"@angular/forms": "~13.3.2",
|
||||
"@angular/material": "^13.3.2",
|
||||
"@angular/platform-browser": "~13.3.2",
|
||||
"@angular/platform-browser-dynamic": "~13.3.2",
|
||||
"@angular/router": "~13.3.2",
|
||||
"@ng-icons/core": "^15.1.0",
|
||||
"@ng-icons/feather-icons": "^15.1.0",
|
||||
"@ng-icons/material-icons": "^15.1.0",
|
||||
"@tauri-apps/api": "^1.0.0-rc.3",
|
||||
"chart.js": "^3.7.1",
|
||||
"primeicons": "^5.0.0",
|
||||
"primeng": "^13.3.2",
|
||||
"rxjs": "~7.5.5",
|
||||
"tslib": "^2.3.1",
|
||||
"w3c-keys": "^1.0.3",
|
||||
"zone.js": "~0.11.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~13.3.2",
|
||||
"@angular-eslint/builder": "^13.2.0",
|
||||
"@angular-eslint/eslint-plugin": "^13.2.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^13.2.0",
|
||||
"@angular-eslint/schematics": "^13.2.0",
|
||||
"@angular-eslint/template-parser": "^13.2.0",
|
||||
"@angular/cli": "~13.3.2",
|
||||
"@angular/compiler-cli": "~13.3.2",
|
||||
"@tauri-apps/cli": "^1.0.0-rc.8",
|
||||
"@types/file-saver": "^2.0.4",
|
||||
"@types/jasmine": "~4.0.2",
|
||||
"@types/node": "^17.0.23",
|
||||
"@typescript-eslint/eslint-plugin": "5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"eslint": "^8.12.0",
|
||||
"jasmine-core": "~4.0.0",
|
||||
"karma": "~6.3.10",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-jasmine": "~4.0.2",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.6.3"
|
||||
}
|
||||
"name": "mediarepo-ui",
|
||||
"version": "1.0.5",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"watch-prod": "ng build --watch --configuration production",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~13.3.2",
|
||||
"@angular/cdk": "^13.3.2",
|
||||
"@angular/common": "~13.3.2",
|
||||
"@angular/compiler": "~13.3.2",
|
||||
"@angular/core": "~13.3.2",
|
||||
"@angular/flex-layout": "^13.0.0-beta.36",
|
||||
"@angular/forms": "~13.3.2",
|
||||
"@angular/material": "^13.3.2",
|
||||
"@angular/platform-browser": "~13.3.2",
|
||||
"@angular/platform-browser-dynamic": "~13.3.2",
|
||||
"@angular/router": "~13.3.2",
|
||||
"@ng-icons/core": "^15.1.0",
|
||||
"@ng-icons/feather-icons": "^15.1.0",
|
||||
"@ng-icons/material-icons": "^15.1.0",
|
||||
"@tauri-apps/api": "^1.5.3",
|
||||
"chart.js": "^3.7.1",
|
||||
"primeicons": "^5.0.0",
|
||||
"primeng": "^13.3.2",
|
||||
"rxjs": "~7.5.5",
|
||||
"tslib": "^2.3.1",
|
||||
"w3c-keys": "^1.0.3",
|
||||
"zone.js": "~0.11.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~13.3.2",
|
||||
"@angular-eslint/builder": "^13.2.0",
|
||||
"@angular-eslint/eslint-plugin": "^13.2.0",
|
||||
"@angular-eslint/eslint-plugin-template": "^13.2.0",
|
||||
"@angular-eslint/schematics": "^13.2.0",
|
||||
"@angular-eslint/template-parser": "^13.2.0",
|
||||
"@angular/cli": "~13.3.2",
|
||||
"@angular/compiler-cli": "~13.3.2",
|
||||
"@angular/language-service": "^17.1.1",
|
||||
"@tauri-apps/cli": "^1.5.4",
|
||||
"@types/file-saver": "^2.0.4",
|
||||
"@types/jasmine": "~4.0.2",
|
||||
"@types/node": "^17.0.23",
|
||||
"@typescript-eslint/eslint-plugin": "5.19.0",
|
||||
"@typescript-eslint/parser": "^5.19.0",
|
||||
"eslint": "^8.13.0",
|
||||
"jasmine-core": "~4.0.0",
|
||||
"karma": "~6.3.10",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage": "~2.2.0",
|
||||
"karma-jasmine": "~4.0.2",
|
||||
"karma-jasmine-html-reporter": "~1.7.0",
|
||||
"typescript": "~4.6.3"
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,76 +1,74 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "mediarepo-ui",
|
||||
"version": "1.0.1"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist/mediarepo-ui",
|
||||
"devPath": "http://localhost:4200",
|
||||
"beforeDevCommand": "yarn start",
|
||||
"beforeBuildCommand": "yarn build"
|
||||
},
|
||||
"tauri": {
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "net.trivernis.mediarepo",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/64x64.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.ico",
|
||||
"icons/icon.icns"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "",
|
||||
"category": "Productivity",
|
||||
"shortDescription": "A media management tool",
|
||||
"longDescription": "",
|
||||
"deb": {
|
||||
"depends": [],
|
||||
"useBootstrapper": false
|
||||
},
|
||||
"macOS": {
|
||||
"frameworks": [],
|
||||
"minimumSystemVersion": "",
|
||||
"useBootstrapper": false,
|
||||
"exceptionDomain": "",
|
||||
"signingIdentity": null,
|
||||
"entitlements": null
|
||||
},
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
}
|
||||
},
|
||||
"updater": {
|
||||
"active": false
|
||||
},
|
||||
"allowlist": {
|
||||
"dialog": {
|
||||
"all": true
|
||||
},
|
||||
"shell": {
|
||||
"all": true
|
||||
},
|
||||
"path": {
|
||||
"all": true
|
||||
}
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "mediarepo",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"resizable": true,
|
||||
"fullscreen": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self' once: thumb: content:"
|
||||
}
|
||||
}
|
||||
"package": {
|
||||
"productName": "mediarepo-ui",
|
||||
"version": "1.0.4"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist/mediarepo-ui",
|
||||
"devPath": "http://localhost:4200",
|
||||
"beforeDevCommand": "yarn start",
|
||||
"beforeBuildCommand": "yarn build"
|
||||
},
|
||||
"tauri": {
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": ["msi", "app", "dmg", "updater"],
|
||||
"identifier": "net.trivernis.mediarepo",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/64x64.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.ico",
|
||||
"icons/icon.icns"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "",
|
||||
"category": "Productivity",
|
||||
"shortDescription": "A media management tool",
|
||||
"longDescription": "",
|
||||
"deb": {
|
||||
"depends": []
|
||||
},
|
||||
"macOS": {
|
||||
"frameworks": [],
|
||||
"minimumSystemVersion": "",
|
||||
"exceptionDomain": "",
|
||||
"signingIdentity": null,
|
||||
"entitlements": null
|
||||
},
|
||||
"windows": {
|
||||
"certificateThumbprint": null,
|
||||
"digestAlgorithm": "sha256",
|
||||
"timestampUrl": ""
|
||||
}
|
||||
},
|
||||
"updater": {
|
||||
"active": false
|
||||
},
|
||||
"allowlist": {
|
||||
"dialog": {
|
||||
"all": true
|
||||
},
|
||||
"shell": {
|
||||
"all": true
|
||||
},
|
||||
"path": {
|
||||
"all": true
|
||||
}
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"title": "mediarepo",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"resizable": true,
|
||||
"fullscreen": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {Component, Inject, ViewChild} from "@angular/core";
|
||||
import {RepositoryFormComponent} from "../repository-form/repository-form.component";
|
||||
import {RepositoryService} from "../../../../../services/repository/repository.service";
|
||||
import {LoggingService} from "../../../../../services/logging/logging.service";
|
||||
import {RepositoryService} from "../../../../services/repository/repository.service";
|
||||
import {LoggingService} from "../../../../services/logging/logging.service";
|
||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||
import {Repository} from "../../../../../../api/models/Repository";
|
||||
import {Repository} from "../../../../../api/models/Repository";
|
||||
|
||||
@Component({
|
||||
selector: "app-edit-repository-dialog",
|
@ -1,7 +1,7 @@
|
||||
import {Component, Input, OnInit, Output} from "@angular/core";
|
||||
import {AbstractControl, FormControl, FormGroup, ValidationErrors, Validators} from "@angular/forms";
|
||||
import {Repository} from "../../../../../../api/models/Repository";
|
||||
import {RepositoryService} from "../../../../../services/repository/repository.service";
|
||||
import {Repository} from "../../../../../api/models/Repository";
|
||||
import {RepositoryService} from "../../../../services/repository/repository.service";
|
||||
import {dialog} from "@tauri-apps/api";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
|
@ -0,0 +1,29 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>
|
||||
<h1>Maintenance</h1></mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<div class="button-list">
|
||||
<button (click)="this.runJob('CheckIntegrity', false)" color="primary" mat-flat-button>Check Integrity
|
||||
</button>
|
||||
<button (click)="this.runJob('Vacuum', false)" color="primary" mat-flat-button>Optimize Database</button>
|
||||
<button (click)="this.runJob('GenerateThumbnails', true)"
|
||||
[disabled]="this.jobState.GenerateThumbnails"
|
||||
color="primary"
|
||||
mat-flat-button>Generate missing
|
||||
Thumbnails
|
||||
<mat-progress-bar *ngIf="this.jobState.GenerateThumbnails" color="primary"
|
||||
mode="indeterminate"></mat-progress-bar>
|
||||
</button>
|
||||
<button (click)="this.runJob('CalculateSizes', true)"
|
||||
[disabled]="this.jobState.CalculateSizes"
|
||||
color="primary"
|
||||
mat-flat-button>Recalculate Repository
|
||||
Size
|
||||
<mat-progress-bar *ngIf="this.jobState.CalculateSizes" color="primary"
|
||||
mode="indeterminate"></mat-progress-bar>
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
@ -0,0 +1,18 @@
|
||||
mat-card-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
mat-card-title h1 {
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.button-list {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
display: block;
|
||||
margin: 2em auto;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import {ComponentFixture, TestBed} from "@angular/core/testing";
|
||||
|
||||
import {RepositoryMaintenanceComponent} from "./repository-maintenance.component";
|
||||
|
||||
describe("RepositoryMaintenanceComponent", () => {
|
||||
let component: RepositoryMaintenanceComponent;
|
||||
let fixture: ComponentFixture<RepositoryMaintenanceComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [RepositoryMaintenanceComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(RepositoryMaintenanceComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it("should create", () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,85 @@
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit} from "@angular/core";
|
||||
import {JobService} from "../../../../services/job/job.service";
|
||||
import {JobType} from "../../../../../api/api-types/job";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {BusyDialogComponent, BusyDialogData} from "../../app-common/busy-dialog/busy-dialog.component";
|
||||
import {LoggingService} from "../../../../services/logging/logging.service";
|
||||
import {BehaviorSubject} from "rxjs";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: "app-repository-maintenance",
|
||||
templateUrl: "./repository-maintenance.component.html",
|
||||
styleUrls: ["./repository-maintenance.component.scss"],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class RepositoryMaintenanceComponent implements OnInit, OnDestroy {
|
||||
public jobState: { [Property in JobType]?: boolean } = {
|
||||
CalculateSizes: false,
|
||||
GenerateThumbnails: false,
|
||||
};
|
||||
private jobStatusInterval: any;
|
||||
|
||||
constructor(
|
||||
private changeDetector: ChangeDetectorRef,
|
||||
private jobService: JobService,
|
||||
private dialog: MatDialog,
|
||||
private logger: LoggingService
|
||||
) {
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
clearInterval(this.jobStatusInterval);
|
||||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
await this.updateJobStatus();
|
||||
this.jobStatusInterval = setInterval(() => this.updateJobStatus(), 10000);
|
||||
}
|
||||
|
||||
public async runJob(jobType: JobType, runAsync: boolean) {
|
||||
if (runAsync) {
|
||||
this.jobState[jobType] = true;
|
||||
this.jobService.runJob(jobType).then(() => this.delay(1000)).catch(this.logger.error).finally(() => {
|
||||
this.jobState[jobType] = false;
|
||||
this.changeDetector.markForCheck();
|
||||
});
|
||||
this.changeDetector.markForCheck();
|
||||
} else {
|
||||
const dialog = this.dialog.open<BusyDialogComponent, BusyDialogData>(BusyDialogComponent, {
|
||||
disableClose: true,
|
||||
minWidth: "30%",
|
||||
minHeight: "30%",
|
||||
data: {
|
||||
title: "Synchronous Job",
|
||||
message: new BehaviorSubject(`Running Job ${jobType}`),
|
||||
allowCancel: false,
|
||||
}
|
||||
});
|
||||
try {
|
||||
this.changeDetector.markForCheck();
|
||||
await this.jobService.runJob(jobType);
|
||||
} catch (err: any) {
|
||||
this.logger.error(err);
|
||||
} finally {
|
||||
dialog.close();
|
||||
this.changeDetector.markForCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async delay(ms: number) {
|
||||
return new Promise((res, _) => setTimeout(
|
||||
res,
|
||||
ms
|
||||
));
|
||||
}
|
||||
|
||||
private async updateJobStatus() {
|
||||
const indexedTypes: JobType[] = ["CalculateSizes", "GenerateThumbnails"];
|
||||
for (const jobType of indexedTypes) {
|
||||
this.jobState[jobType] = await this.jobService.isJobRunning(jobType);
|
||||
}
|
||||
this.changeDetector.markForCheck();
|
||||
}
|
||||
}
|
@ -1,65 +1,71 @@
|
||||
import {downloadDir} from "@tauri-apps/api/path";
|
||||
import {dialog} from "@tauri-apps/api";
|
||||
import {File} from "../../../api/models/File";
|
||||
import { downloadDir } from "@tauri-apps/api/path";
|
||||
import { dialog } from "@tauri-apps/api";
|
||||
import type { File } from "../../../api/models/File";
|
||||
|
||||
export class FileHelper {
|
||||
/**
|
||||
* Opens a dialog to get a download location for the given file
|
||||
* @param {File} file
|
||||
*/
|
||||
public static async getFileDownloadLocation(
|
||||
file: File,
|
||||
): Promise<string | null> {
|
||||
let extension = FileHelper.getExtensionForMime(file.mimeType);
|
||||
|
||||
/**
|
||||
* Opens a dialog to get a download location for the given file
|
||||
* @param {File} file
|
||||
*/
|
||||
public static async getFileDownloadLocation(file: File): Promise<string | undefined> {
|
||||
let extension = FileHelper.getExtensionForMime(file.mimeType);
|
||||
const downloadDirectory = await downloadDir();
|
||||
const suggestionPath = downloadDirectory + file.cd + "." + extension;
|
||||
|
||||
const downloadDirectory = await downloadDir();
|
||||
const suggestionPath = downloadDirectory + file.cd + "." + extension;
|
||||
return await dialog.save({
|
||||
defaultPath: suggestionPath,
|
||||
filters: [
|
||||
{
|
||||
name: file.mimeType,
|
||||
extensions: [extension ?? "*"],
|
||||
},
|
||||
{ name: "All", extensions: ["*"] },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return await dialog.save({
|
||||
defaultPath: suggestionPath,
|
||||
filters: [{
|
||||
name: file.mimeType,
|
||||
extensions: [extension ?? "*"]
|
||||
}, { name: "All", extensions: ["*"] }]
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Parses a mime into its two components
|
||||
* @param {string | undefined} mimeType
|
||||
* @returns {[string, string] | undefined}
|
||||
*/
|
||||
public static parseMime(
|
||||
mimeType: string | undefined,
|
||||
): [string, string] | undefined {
|
||||
if (!mimeType) {
|
||||
return undefined;
|
||||
}
|
||||
let mimeParts = mimeType.split("/");
|
||||
if (mimeParts.length < 2) {
|
||||
return undefined;
|
||||
}
|
||||
const type = mimeParts[0];
|
||||
const subtype = mimeParts[1];
|
||||
|
||||
/**
|
||||
* Parses a mime into its two components
|
||||
* @param {string | undefined} mimeType
|
||||
* @returns {[string, string] | undefined}
|
||||
*/
|
||||
public static parseMime(mimeType: string | undefined): [string, string] | undefined {
|
||||
if (!mimeType) {
|
||||
return undefined;
|
||||
}
|
||||
let mimeParts = mimeType.split("/");
|
||||
if (mimeParts.length < 2) {
|
||||
return undefined;
|
||||
}
|
||||
const type = mimeParts[0];
|
||||
const subtype = mimeParts[1];
|
||||
return [type, subtype];
|
||||
}
|
||||
|
||||
return [type, subtype];
|
||||
}
|
||||
/**
|
||||
* Returns the extension for a mime type
|
||||
* @param {string} mime
|
||||
* @returns {string | undefined}
|
||||
* @private
|
||||
*/
|
||||
public static getExtensionForMime(mime: string): string | undefined {
|
||||
let parts = mime.split("/");
|
||||
|
||||
/**
|
||||
* Returns the extension for a mime type
|
||||
* @param {string} mime
|
||||
* @returns {string | undefined}
|
||||
* @private
|
||||
*/
|
||||
public static getExtensionForMime(mime: string): string | undefined {
|
||||
let parts = mime.split("/");
|
||||
if (parts.length === 2) {
|
||||
const type = parts[0];
|
||||
const subtype = parts[1];
|
||||
return FileHelper.convertMimeSubtypeToExtension(subtype);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (parts.length === 2) {
|
||||
const type = parts[0];
|
||||
const subtype = parts[1];
|
||||
return FileHelper.convertMimeSubtypeToExtension(subtype);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private static convertMimeSubtypeToExtension(subtype: string): string {
|
||||
return subtype;
|
||||
}
|
||||
private static convertMimeSubtypeToExtension(subtype: string): string {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue