Merge pull request #17 from Trivernis/develop

(Last?) Release Candidate before release
main v1.0.0-rc.4
Julius Riegel 2 years ago committed by GitHub
commit 84f36a6875
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,11 +19,6 @@ RUN apt-get install -y \
curl \
wget \
pkg-config \
libavutil-dev \
libavformat-dev \
libavcodec-dev \
libavfilter-dev \
libavdevice-dev \
clang \
nodejs \
npm \
@ -39,4 +34,4 @@ ENV PATH="/root/.cargo/bin:${PATH}"
RUN python3 scripts/clean.py
RUN python3 scripts/check.py --install
RUN python3 scripts/build.py all --verbose --ffmpeg
RUN python3 scripts/build.py all --verbose

@ -77,16 +77,14 @@ $ ./scripts/check.py --install
All Componens:
```sh
$ ./scripts/build.py all --ffmpeg
$ ./scripts/build.py all
```
Daemon only:
```sh
$ ./scripts/build.py daemon --ffmpeg
$ ./scripts/build.py daemon
```
If you don't want to build with ffmpeg support omit the `--ffmpeg` flag.
UI only:
```sh
$ ./scripts/build.py ui

File diff suppressed because it is too large Load Diff

@ -4,7 +4,7 @@ default-members = ["mediarepo-core", "mediarepo-database", "mediarepo-logic", "m
[package]
name = "mediarepo-daemon"
version = "1.0.0-rc.3"
version = "1.0.0-rc.4"
edition = "2018"
license = "gpl-3"
repository = "https://github.com/Trivernis/mediarepo-daemon"
@ -16,7 +16,7 @@ name = "mediarepo-daemon"
path = "src/main.rs"
[dependencies]
tracing = "0.1.30"
tracing = "0.1.31"
toml = "0.5.8"
structopt = "0.3.26"
glob = "0.3.0"
@ -25,7 +25,7 @@ tracing-appender = "0.2.0"
tracing-log = "0.1.2"
rolling-file = "0.1.0"
num-integer = "0.1.44"
console-subscriber = "0.1.1"
console-subscriber = "0.1.3"
log = "0.4.14"
[dependencies.mediarepo-core]
@ -38,13 +38,9 @@ path = "mediarepo-logic"
path = "./mediarepo-socket"
[dependencies.tokio]
version = "1.16.1"
version = "1.17.0"
features = ["macros", "rt-multi-thread", "io-std", "io-util"]
[dependencies.tracing-subscriber]
version= "0.3.8"
version= "0.3.9"
features = ["env-filter", "ansi", "json"]
[features]
default = ["ffmpeg"]
ffmpeg = ["mediarepo-core/ffmpeg", "mediarepo-logic/ffmpeg"]

@ -17,35 +17,28 @@ typemap_rev = "0.1.5"
futures = "0.3.21"
itertools = "0.10.3"
glob = "0.3.0"
tracing = "0.1.30"
tracing = "0.1.31"
data-encoding = "2.3.2"
tokio-graceful-shutdown = "0.4.3"
[dependencies.thumbnailer]
version = "0.3.0"
default-features = false
thumbnailer = "0.4.0"
[dependencies.sea-orm]
version = "0.6.0"
default-features = false
[dependencies.sqlx]
version = "0.5.10"
version = "0.5.11"
default-features = false
features = ["migrate"]
[dependencies.tokio]
version = "1.16.1"
version = "1.17.0"
features = ["fs", "io-util", "io-std"]
[dependencies.config]
version = "0.11.0"
version = "0.12.0"
features = ["toml"]
[dependencies.mediarepo-api]
path = "../../mediarepo-api"
features = ["bromine"]
[features]
default = []
ffmpeg = ["thumbnailer/ffmpeg"]
features = ["bromine"]

@ -25,17 +25,17 @@ pub struct Settings {
impl Settings {
pub fn read(root: &PathBuf) -> RepoResult<Self> {
let mut settings = Config::default();
settings
.merge(config::File::from_str(
let settings = Config::builder()
.add_source(config::File::from_str(
&*Settings::default().to_toml_string()?,
FileFormat::Toml,
))?
.merge(config::File::from(root.join("repo")))?
.merge(config::Environment::with_prefix("MEDIAREPO").separator("."))?;
))
.add_source(config::File::from(root.join("repo")))
.add_source(config::Environment::with_prefix("MEDIAREPO").separator("."))
.build()?;
tracing::debug!("Settings are: {:#?}", settings);
Ok(settings.try_into::<Settings>()?)
Ok(settings.try_deserialize()?)
}
/// Parses settings from a string
@ -50,16 +50,16 @@ impl Settings {
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|| String::from("./"));
let mut settings = Config::default();
settings
.merge(config::File::from_str(
let settings = Config::builder()
.add_source(config::File::from_str(
&*settings_main.to_toml_string()?,
FileFormat::Toml,
))?
.merge(config::Environment::with_prefix("MEDIAREPO"))?;
))
.add_source(config::Environment::with_prefix("MEDIAREPO"))
.build()?;
tracing::debug!("Settings are: {:#?}", settings);
Ok(settings.try_into::<Settings>()?)
Ok(settings.try_deserialize()?)
}
/// Converts the settings into a toml string

@ -8,13 +8,13 @@ workspace = ".."
[dependencies]
chrono = "0.4.19"
tracing = "0.1.30"
tracing = "0.1.31"
[dependencies.mediarepo-core]
path = "../mediarepo-core"
[dependencies.sqlx]
version = "0.5.10"
version = "0.5.11"
features = ["migrate"]
[dependencies.sea-orm]

@ -10,9 +10,9 @@ workspace = ".."
chrono = "0.4.19"
typemap_rev = "0.1.5"
serde = "1.0.136"
mime_guess = "2.0.3"
mime_guess = "2.0.4"
mime = "0.3.16"
tracing = "0.1.30"
tracing = "0.1.31"
async-trait = "0.1.52"
[dependencies.mediarepo-core]
@ -27,9 +27,6 @@ features = ["runtime-tokio-native-tls", "macros"]
default-features = false
[dependencies.tokio]
version = "1.16.1"
version = "1.17.0"
features = ["fs", "io-std", "io-util"]
[features]
ffmpeg = ["mediarepo-core/ffmpeg"]

@ -8,7 +8,7 @@ workspace = ".."
[dependencies]
serde = "1.0.136"
tracing = "0.1.30"
tracing = "0.1.31"
compare = "0.1.0"
port_check = "0.1.5"
rayon = "1.5.1"
@ -23,7 +23,7 @@ path = "../mediarepo-database"
path = "../mediarepo-logic"
[dependencies.tokio]
version = "1.16.1"
version = "1.17.0"
features = ["net"]
[dependencies.chrono]

@ -40,7 +40,9 @@
"src/styles.scss",
"src/material-theme-correction.scss"
],
"scripts": []
"scripts": [
"./node_modules/chart.js/dist/chart.js"
]
},
"configurations": {
"production": {
@ -114,7 +116,9 @@
"src/styles.scss",
"src/material-theme-correction.scss"
],
"scripts": []
"scripts": [
"./node_modules/chart.js/dist/chart.js"
]
}
},
"lint": {

@ -1,6 +1,6 @@
{
"name": "mediarepo-ui",
"version": "1.0.0-rc.3",
"version": "1.0.0-rc.4",
"scripts": {
"ng": "ng",
"start": "ng serve",
@ -28,6 +28,7 @@
"@ng-icons/feather-icons": "^13.2.1",
"@ng-icons/material-icons": "^13.2.1",
"@tauri-apps/api": "^1.0.0-beta.8",
"chart.js": "^3.7.1",
"primeicons": "^5.0.0",
"primeng": "^13.0.4",
"rxjs": "~7.5.2",
@ -59,4 +60,4 @@
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.5.4"
}
}
}

@ -40,7 +40,7 @@ checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
[[package]]
name = "app"
version = "1.0.0-rc.3"
version = "1.0.0-rc.4"
dependencies = [
"mediarepo-api",
"serde",

@ -1,6 +1,6 @@
[package]
name = "app"
version = "1.0.0-rc.3"
version = "1.0.0-rc.4"
description = "The UI for the mediarepo media management tool"
authors = ["you"]
license = ""

@ -89,7 +89,7 @@ import {AboutDialogComponent} from "./repositories-tab/repository-overview/about
MatInputModule,
TagModule,
RepositoryModule,
MatToolbarModule,
MatToolbarModule
]
})
export class CoreModule {

@ -1,6 +1,4 @@
<div *ngIf="!this.selectedRepository">
<app-repository-overview></app-repository-overview>
</div>
<div *ngIf="this.selectedRepository" class="repo-details">
<app-repository-details-view [repository]="this.selectedRepository"></app-repository-details-view>
</div>
<app-repository-overview *ngIf="!this.selectedRepository"></app-repository-overview>
<app-repository-details-view *ngIf="this.selectedRepository"
[repository]="this.selectedRepository"></app-repository-details-view>

@ -4,45 +4,56 @@
</button>
</mat-toolbar>
<div class="details-content" fxLayout="row">
<div class="repository-metadata" fxFlex="100%">
<h1>Stats</h1>
<app-metadata-entry *ngIf="repository.path" attributeName="Path">{{repository.path}}</app-metadata-entry>
<app-metadata-entry *ngIf="repository.address"
attributeName="Address">{{repository.address}}</app-metadata-entry>
<app-metadata-entry attributeName="File Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.file_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Tag Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.tag_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Namespace Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.namespace_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Mapping Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.mapping_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Total Size">
<mat-progress-bar *ngIf="(this.totalSize | async) === undefined" mode="indeterminate"></mat-progress-bar>
{{this.totalSize | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="File Folder Size">
<mat-progress-bar *ngIf="(this.fileFolderSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.fileFolderSize | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="Thumbnail Folder Size">
<mat-progress-bar *ngIf="(this.thumbFolderSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.thumbFolderSize | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="Database File Size">
<mat-progress-bar *ngIf="(this.databaseFileSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.databaseFileSize | async}}
</app-metadata-entry>
<div class="repository-metadata" fxFlex="50%">
<div class="stats-container">
<h1>Stats</h1>
<app-metadata-entry *ngIf="repository.path" attributeName="Path">{{repository.path}}</app-metadata-entry>
<app-metadata-entry *ngIf="repository.address"
attributeName="Address">{{repository.address}}</app-metadata-entry>
<app-metadata-entry attributeName="File Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.file_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Tag Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.tag_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Namespace Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.namespace_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Mapping Count">
<mat-progress-bar *ngIf="!metadata"></mat-progress-bar>
{{metadata ? metadata!.mapping_count.toString() : ''}}
</app-metadata-entry>
<app-metadata-entry attributeName="Total Size">
<mat-progress-bar *ngIf="(this.totalSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.totalSize | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="File Folder Size">
<mat-progress-bar *ngIf="(this.fileFolderSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.fileFolderSize | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="Thumbnail Folder Size">
<mat-progress-bar *ngIf="(this.thumbFolderSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.thumbFolderSize | async}}
</app-metadata-entry>
<app-metadata-entry attributeName="Database File Size">
<mat-progress-bar *ngIf="(this.databaseFileSize | async) === undefined"
mode="indeterminate"></mat-progress-bar>
{{this.databaseFileSize | async}}
</app-metadata-entry>
</div>
</div>
<div class="repository-charts" fxFlex="50%">
<app-chart *ngIf="this.chartData"
[datasets]="this.chartData"
[labels]="this.chartLabels"
chartType="doughnut"
class="size-chart"
title="Sizes"></app-chart>
</div>
</div>

@ -1,3 +1,10 @@
@import "src/colors";
:host {
height: 100%;
width: 100%;
}
.repository-name {
text-align: center;
align-self: center;
@ -12,16 +19,38 @@
padding: 1em 1em 1em 3em;
overflow-y: auto;
user-select: none;
margin-left: 20%;
margin-right: 20%;
margin-top: 4em;
margin-left: 2em;
display: flex;
app-metadata-entry {
margin-bottom: 0.5em;
display: block;
}
.stats-container {
margin-left: auto;
margin-right: auto;
}
}
.repository-charts {
margin-top: 4em;
margin-right: 2em;
height: 100%;
display: block;
}
.details-content {
height: calc(100% - 64px);
overflow: hidden;
width: 75%;
margin: auto;
background: $background-lighter-05;
}
.size-chart {
min-height: 50%;
max-width: 500px;
margin: auto;
}

@ -5,6 +5,7 @@ import {RepositoryMetadata} from "../../../../models/RepositoryMetadata";
import {BehaviorSubject} from "rxjs";
import {MatDialog} from "@angular/material/dialog";
import {BusyDialogComponent} from "../../../shared/app-common/busy-dialog/busy-dialog.component";
import {Dataset} from "../../../shared/app-common/chart/chart.component";
@Component({
selector: "app-repository-details-view",
@ -19,9 +20,14 @@ export class RepositoryDetailsViewComponent implements OnInit, OnChanges, OnDest
public fileFolderSize = new BehaviorSubject<string | undefined>(undefined);
public thumbFolderSize = new BehaviorSubject<string | undefined>(undefined);
public databaseFileSize = new BehaviorSubject<string | undefined>(undefined);
public chartData?: Dataset[];
public chartLabels = ["Files", "Thumbnails", "Database"];
private refreshMetadataInterval?: number;
constructor(private repoService: RepositoryService, public dialog: MatDialog) {
constructor(
private repoService: RepositoryService,
public dialog: MatDialog
) {
}
public async ngOnInit() {
@ -63,6 +69,11 @@ export class RepositoryDetailsViewComponent implements OnInit, OnChanges, OnDest
this.thumbFolderSize.next(this.formatByteSize(thumbSize.size));
const databaseSize = await this.repoService.getSize("DatabaseFile");
this.databaseFileSize.next(this.formatByteSize(databaseSize.size));
this.chartData = [
{
data: [fileSize.size, thumbSize.size, databaseSize.size],
},
];
}
public formatByteSize(size: number): string {

@ -1,10 +1,17 @@
:host {
height: 100%;
width: 100%;
display: block;
overflow: hidden;
}
.repository-container {
padding: 1em;
margin: auto;
display: block;
width: calc(600px - 2em);
float: left;
app-repository-card {
display: block;
position: relative;
@ -31,7 +38,8 @@
flex-wrap: wrap;
overflow-y: auto;
overflow-x: hidden;
height: calc(100% - 5em);
max-height: calc(100% - 2em);
padding-bottom: 2em;
}

@ -26,6 +26,8 @@ import {FlapButtonComponent} from "./flap-button/flap-button.component";
import {MiddleCenteredComponent} from "./middle-centered/middle-centered.component";
import {FormatBytesPipe} from "./pipes/format-bytes.pipe";
import {ExternalUrlComponent} from "./external-url/external-url.component";
import {ChartComponent} from "./chart/chart.component";
import {ChartModule} from "primeng/chart";
@NgModule({
@ -46,6 +48,7 @@ import {ExternalUrlComponent} from "./external-url/external-url.component";
MiddleCenteredComponent,
FormatBytesPipe,
ExternalUrlComponent,
ChartComponent,
],
exports: [
ConfirmDialogComponent,
@ -63,6 +66,7 @@ import {ExternalUrlComponent} from "./external-url/external-url.component";
MiddleCenteredComponent,
FormatBytesPipe,
ExternalUrlComponent,
ChartComponent,
],
imports: [
CommonModule,
@ -74,7 +78,8 @@ import {ExternalUrlComponent} from "./external-url/external-url.component";
MatProgressBarModule,
MatSidenavModule,
FlexLayoutModule,
MatRippleModule
MatRippleModule,
ChartModule
]
})
export class AppCommonModule {

@ -0,0 +1,2 @@
<h2 *ngIf="this.title" class="title">{{this.title}}</h2>
<p-chart [data]="data" [options]="this.options" [type]="this.chartType ?? ''"></p-chart>

@ -0,0 +1,15 @@
:host {
height: 100%;
width: 100%;
display: block;
}
.title {
width: 100%;
text-align: center;
}
p-chart {
height: 100%;
width: 100%;
}

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

@ -0,0 +1,86 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, SimpleChanges} from "@angular/core";
import {ChartOptions} from "chart.js";
export type ChartType = "doughnut";
export type Dataset = {
label?: string,
data: number[],
};
@Component({
selector: "app-chart",
templateUrl: "./chart.component.html",
styleUrls: ["./chart.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChartComponent implements OnChanges {
@Input() chartType?: ChartType;
@Input() title?: string;
@Input() labels: string[] = [];
@Input() datasets: Dataset[] = [];
public data: any = {};
public options: ChartOptions = {
responsive: true,
elements: {
arc: {
borderWidth: 0
}
},
plugins: {
legend: {
labels: {
color: "#FFF",
boxHeight: 20,
font: {
size: 16,
}
},
},
tooltip: {
titleFont: {
size: 16
},
bodyFont: {
size: 14
}
}
}
};
private readonly colors = [
"#771e86",
"#4650b5",
"#0073d0",
"#0091d6",
"#00aacb",
"#00c0b7"
];
constructor(private changeDetector: ChangeDetectorRef) {
}
public ngOnChanges(changes: SimpleChanges): void {
if (changes["labels"] || changes["dataset"]) {
this.generateData();
this.changeDetector.markForCheck();
}
if (changes["chartType"]) {
this.changeDetector.markForCheck();
}
}
private generateData() {
this.data = {
labels: this.labels,
datasets: this.datasets.map(set => {
return {
label: set.label,
data: set.data,
backgroundColor: this.colors,
hoverBackgroundColor: this.colors,
};
})
};
}
}

@ -8,12 +8,15 @@
minBufferPx="500">
<div *cdkVirtualFor="let rowEntry of partitionedGridEntries; trackBy: trackByFileRowId">
<div class="file-row">
<app-file-card
(clickEvent)="setSelectedFile($event.entry)"
(contextmenu)="this.selectEntryWhenNotSelected(gridEntry); fileContextMenu.onContextMenu($event, this.getSelectedFiles())"
(dblClickEvent)="fileOpen.emit($event.entry.data)"
*ngFor="let gridEntry of rowEntry; trackBy: trackByFileId"
[entry]="gridEntry" [fileChanged]="this.fileChanged"></app-file-card>
<ng-container *ngFor="let gridEntry of rowEntry; trackBy: trackByFileId">
<app-file-card
(clickEvent)="setSelectedFile($event.entry)"
(contextmenu)="this.selectEntryWhenNotSelected(gridEntry); fileContextMenu.onContextMenu($event, this.getSelectedFiles())"
(dblClickEvent)="fileOpen.emit($event.entry.data)"
*ngIf="gridEntry"
[entry]="gridEntry" [fileChanged]="this.fileChanged"></app-file-card>
<div *ngIf="!gridEntry" class="empty-grid-entry"></div>
</ng-container>
</div>
</div>
</cdk-virtual-scroll-viewport>

@ -6,6 +6,13 @@ app-file-card {
margin: 5px;
}
.empty-grid-entry {
width: 100%;
height: 250px;
margin: 5px;
display: block;
}
.file-scroll {
height: 100%;
width: 100%;

@ -43,7 +43,7 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
public fileChanged = new BehaviorSubject<void>(undefined);
public selectedEntries: Selectable<File>[] = [];
public partitionedGridEntries: Selectable<File>[][] = [];
public partitionedGridEntries: (Selectable<File> | undefined)[][] = [];
private columns = 6;
private entrySizePx = 260;
@ -187,12 +187,12 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
this.ctrlClicked = event.ctrlKey ? false : this.ctrlClicked;
}
public trackByFileRowId(index: number, item: Selectable<File>[]) {
return item.map(e => e.data.id).join("-");
public trackByFileRowId(index: number, item: (Selectable<File> | undefined)[]) {
return item.map(e => e?.data.id).join("-");
}
public trackByFileId(index: number, item: Selectable<File>) {
return item.data.id;
public trackByFileId(index: number, item: Selectable<File> | undefined) {
return item?.data.id;
}
public onFileStatusChange(): void {
@ -224,14 +224,18 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
for (let i = 0; i < (Math.ceil(
this.gridEntries.length / this.columns)); i++) {
const entries = this.gridEntries.slice(
const entries: (Selectable<File> | undefined)[] = this.gridEntries.slice(
i * this.columns,
Math.min(this.gridEntries.length, (i + 1) * this.columns)
);
const length = entries.length;
for (let i = 0; i < (this.columns - length); i++) {
entries.push(undefined);
}
this.partitionedGridEntries.push(entries);
const preselectedEntry = entries.find(
e => e.data.id == this.preselectedFile?.id);
e => e?.data.id == this.preselectedFile?.id);
if (preselectedEntry) {
scrollToIndex = i;
@ -256,7 +260,8 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
private scrollToSelection() {
const selected = this.selectedEntries[0];
if (this.virtualScroll && selected) {
const index = Math.floor(this.gridEntries.indexOf(selected) / this.columns);
const index = Math.floor(
this.gridEntries.indexOf(selected) / this.columns);
setTimeout(() => {
this.virtualScroll.scrollToIndex(index);
this.changeDetector.markForCheck();
@ -345,14 +350,17 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
if (this.virtualScroll) {
const viewportSize = this.virtualScroll.getViewportSize();
let offsetTop = this.virtualScroll.measureScrollOffset("top");
const contentOffset = Math.floor(selectedIndex / this.columns) * 260;
const contentOffset = Math.floor(
selectedIndex / this.columns) * 260;
if (contentOffset > offsetTop + viewportSize - 300 || contentOffset < offsetTop) {
this.virtualScroll.scrollToIndex(Math.floor(selectedIndex / this.columns));
this.virtualScroll.scrollToIndex(
Math.floor(selectedIndex / this.columns));
offsetTop = this.virtualScroll.measureScrollOffset("top");
if (contentOffset < offsetTop + (viewportSize / 2)) {
this.virtualScroll.scrollToOffset((offsetTop + 130) - viewportSize / 2);
this.virtualScroll.scrollToOffset(
(offsetTop + 130) - viewportSize / 2);
}
}
}
@ -361,14 +369,16 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
private pageDown() {
if (this.virtualScroll) {
const offsetTop = this.virtualScroll.measureScrollOffset("top");
this.virtualScroll.scrollToOffset(offsetTop + this.virtualScroll.getViewportSize());
this.virtualScroll.scrollToOffset(
offsetTop + this.virtualScroll.getViewportSize());
}
}
private pageUp() {
if (this.virtualScroll) {
const offsetTop = this.virtualScroll.measureScrollOffset("top");
this.virtualScroll.scrollToOffset(offsetTop - this.virtualScroll.getViewportSize());
this.virtualScroll.scrollToOffset(
offsetTop - this.virtualScroll.getViewportSize());
}
}
}

@ -34,8 +34,8 @@ app-content-aware-image {
position: absolute;
top: 0;
right: 0;
height: 18%;
width: 18%;
height: 2.5em;
width: 2.5em;
display: flex;
border-bottom-left-radius: 50%;
background-color: transparentize($background, .5);

@ -52,7 +52,7 @@ mat-option {
}
mat-toolbar.mat-toolbar {
background: $background-darker-05;
background: $background-darker-05 !important;
}
.mat-card {

@ -2776,6 +2776,11 @@ chardet@^0.7.0:
resolved "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
chart.js@^3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada"
integrity sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA==
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.1, chokidar@^3.5.2:
version "3.5.3"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"

@ -9,7 +9,6 @@ from typing import List
build_output = 'out'
verbose = False
ffmpeg = False
install_tooling = False
windows = os.name == 'nt'
@ -21,12 +20,10 @@ def main():
global install_tooling
global build_output
global verbose
global ffmpeg
global install_tooling
build_output = opts.output if opts.output else build_output
verbose = opts.verbose
ffmpeg = opts.ffmpeg
install_tooling = opts.install_tooling
build(opts.component, opts.bundles)
@ -41,8 +38,6 @@ def parse_args():
'--verbose', action='store_true', help='Verbose build')
parser.add_argument(
'--output', action='store', help='Build output directory')
parser.add_argument(
'--ffmpeg', action='store_true', help='Build with ffmpeg')
parser.add_argument('--install-tooling',
action='store_true', help='Install tooling')
parser.add_argument('--bundles', nargs='+',
@ -74,11 +69,7 @@ def build(component: str, bundles: List[str] = None):
def build_daemon():
'''Builds daemon'''
cargo('fetch', 'mediarepo-daemon')
if not ffmpeg:
cargo('build --release --frozen --no-default-features', 'mediarepo-daemon')
else:
cargo('build --release --frozen', 'mediarepo-daemon')
cargo('build --release --frozen', 'mediarepo-daemon')
if windows:
store_artifact('mediarepo-daemon/target/release/mediarepo-daemon.exe')

Loading…
Cancel
Save