Move home view to separate view and add tabs

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent e721344d07
commit 5b0769dcd2

@ -28,6 +28,8 @@ import {MatChipsModule} from "@angular/material/chips";
import {MatIconModule} from "@angular/material/icon";
import {MatAutocompleteModule} from "@angular/material/autocomplete";
import { FileSearchComponent } from './components/file-search/file-search.component';
import {MatTabsModule} from "@angular/material/tabs";
import { SearchPageComponent } from './pages/home/search-page/search-page.component';
@NgModule({
declarations: [
@ -39,29 +41,31 @@ import { FileSearchComponent } from './components/file-search/file-search.compon
FileGridComponent,
FileGridEntryComponent,
FileSearchComponent,
SearchPageComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatCardModule,
MatListModule,
MatButtonModule,
MatToolbarModule,
MatSnackBarModule,
MatFormFieldModule,
MatInputModule,
ReactiveFormsModule,
MatSidenavModule,
MatGridListModule,
MatProgressBarModule,
MatPaginatorModule,
ScrollingModule,
LightboxModule,
MatChipsModule,
MatIconModule,
MatAutocompleteModule,
MatTabsModule
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatCardModule,
MatListModule,
MatButtonModule,
MatToolbarModule,
MatSnackBarModule,
MatFormFieldModule,
MatInputModule,
ReactiveFormsModule,
MatSidenavModule,
MatGridListModule,
MatProgressBarModule,
MatPaginatorModule,
ScrollingModule,
LightboxModule,
MatChipsModule,
MatIconModule,
MatAutocompleteModule
],
providers: [],
bootstrap: [AppComponent]
})

@ -15,7 +15,7 @@ import {Observable} from "rxjs";
})
export class FileSearchComponent {
public searchInputSeparators = [ENTER, COMMA];
public searchInputSeparators = [COMMA];
public formControl = new FormControl();
public searchTags: string[] = [];
public suggestionTags: Observable<string[]>;

@ -2,25 +2,9 @@
<mat-toolbar color="primary">
<h1>Files</h1>
</mat-toolbar>
<mat-drawer-container>
<mat-drawer mode="side" opened>
<div class="drawer-sidebar-inner">
<app-file-search #filesearch></app-file-search>
<div id="file-tag-list">
<h1>Selection Tags</h1>
<mat-selection-list [multiple]="false" *ngIf="tags.length > 0" (selectionChange)="addSearchTagFromList($event)">
<mat-list-option
*ngFor="let tag of tags" [value]="tag.getNormalizedOutput()">{{tag.getNormalizedOutput()}}</mat-list-option>
</mat-selection-list>
</div>
</div>
</mat-drawer>
<mat-drawer-content>
<app-file-grid (fileDblClickEvent)="openFile($event)" [files]="files"
(fileSelectEvent)="onFileSelect($event)"
(fileMultiselectEvent)="onFileMultiSelect($event)"
></app-file-grid>
</mat-drawer-content>
</mat-drawer-container>
<mat-tab-group>
<mat-tab label="Search">
<app-search-page></app-search-page>
</mat-tab>
</mat-tab-group>
</div>

@ -8,33 +8,12 @@
overflow: hidden
}
#file-tag-list {
height: calc(100% - 8em);
overflow: auto;
}
.drawer-sidebar-inner {
height: 100%;
mat-tab-group {
height: calc(100% - 64px);
width: 100%;
display: block;
}
mat-drawer {
height: 100%;
width: 25%;
overflow: hidden;
}
mat-drawer-content {
overflow-x: hidden;
overflow-y: auto;
::ng-deep .mat-tab-body-wrapper {
height: 100%;
}
mat-drawer-container {
height: calc(100% - 64px);
}
app-file-grid {
padding: 0;
width: 100%;
}

@ -19,92 +19,8 @@ import {FileSearchComponent} from "../../components/file-search/file-search.comp
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
export class HomeComponent {
tags: Tag[] = [];
files: File[] = [];
private openingLightbox = false;
@ViewChild('filesearch') fileSearch!: FileSearchComponent;
constructor(
private errorBroker: ErrorBrokerService,
private fileService: FileService,
private tagService: TagService,
private lightbox: Lightbox,
private lightboxEvent: LightboxEvent) {
}
async ngOnInit() {
this.fileService.displayedFiles.subscribe((files) => this.files = files);
}
async onFileMultiSelect(files: File[]) {
if (files.length === 0) {
this.clearFileDetails();
}
}
async onFileSelect(file: File | undefined) {
if (file) {
await this.showFileDetails(file);
} else {
this.clearFileDetails();
}
}
clearFileDetails() {
this.tags = [];
}
async showFileDetails(file: File) {
this.tags = await this.tagService.getTagsForFile(file.hash);
}
async addSearchTagFromList(event: MatSelectionListChange) {
if (event.options.length > 0) {
const tag = event.options[0].value;
this.fileSearch.addSearchTag(tag);
await this.fileSearch.searchForFiles();
}
event.source.deselectAll();
}
async openFile(file: File) {
if (this.openingLightbox) {
return;
}
this.openingLightbox = true;
try {
await this.openLightbox(file);
} catch (err) {
this.errorBroker.showError(err);
}
this.openingLightbox = false;
}
private async openLightbox(file: File): Promise<void> {
let url = await this.fileService.readFile(file);
let albums = [
{
src: url as string,
caption: file.name ?? file.comment,
thumb: url as string,
}
];
this.lightbox.open(albums, 0, {
disableScrolling: true,
showImageNumberLabel: false,
showDownloadButton: true,
centerVertically: true,
});
const lighboxSubscription = this.lightboxEvent.lightboxEvent$.subscribe(
(event: any) => {
if (event?.id == LIGHTBOX_EVENT.CLOSE) {
lighboxSubscription.unsubscribe();
URL?.revokeObjectURL(url as string);
}
})
}
constructor() {}
}

@ -0,0 +1,22 @@
<mat-drawer-container class="page">
<mat-drawer mode="side" opened>
<div class="drawer-sidebar-inner">
<app-file-search #filesearch></app-file-search>
<div id="file-tag-list">
<h1>Selection Tags</h1>
<mat-selection-list [multiple]="false" *ngIf="tags.length > 0"
(selectionChange)="addSearchTagFromList($event)">
<mat-list-option
*ngFor="let tag of tags"
[value]="tag.getNormalizedOutput()">{{tag.getNormalizedOutput()}}</mat-list-option>
</mat-selection-list>
</div>
</div>
</mat-drawer>
<mat-drawer-content>
<app-file-grid (fileDblClickEvent)="openFile($event)" [files]="files"
(fileSelectEvent)="onFileSelect($event)"
(fileMultiselectEvent)="onFileMultiSelect($event)"
></app-file-grid>
</mat-drawer-content>
</mat-drawer-container>

@ -0,0 +1,35 @@
#file-tag-list {
height: calc(100% - 8em);
overflow: auto;
}
.drawer-sidebar-inner {
height: 100%;
width: 100%;
display: block;
}
mat-drawer {
height: 100%;
width: 25%;
overflow: hidden;
}
mat-drawer-content {
overflow-x: hidden;
overflow-y: auto;
height: 100%;
}
mat-drawer-container {
height: 100%;
}
app-file-grid {
padding: 0;
}
.page {
height: 100%;
width: 100%;
}

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

@ -0,0 +1,119 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {Tag} from "../../../models/Tag";
import {File} from "../../../models/File";
import {FileSearchComponent} from "../../../components/file-search/file-search.component";
import {ErrorBrokerService} from "../../../services/error-broker/error-broker.service";
import {FileService} from "../../../services/file/file.service";
import {TagService} from "../../../services/tag/tag.service";
import {Lightbox, LIGHTBOX_EVENT, LightboxEvent} from "ngx-lightbox";
import {MatSelectionListChange} from "@angular/material/list";
@Component({
selector: 'app-search-page',
templateUrl: './search-page.component.html',
styleUrls: ['./search-page.component.scss']
})
export class SearchPageComponent implements OnInit {
tags: Tag[] = [];
files: File[] = [];
private openingLightbox = false;
@ViewChild('filesearch') fileSearch!: FileSearchComponent;
constructor(
private errorBroker: ErrorBrokerService,
private fileService: FileService,
private tagService: TagService,
private lightbox: Lightbox,
private lightboxEvent: LightboxEvent) {
}
async ngOnInit() {
this.fileService.displayedFiles.subscribe((files) => this.files = files);
}
async onFileMultiSelect(files: File[]) {
await this.showFileDetails(files);
}
async onFileSelect(file: File | undefined) {
if (file) {
await this.showFileDetails([file]);
} else {
this.tags = [];
}
}
async showFileDetails(files: File[]) {
this.tags = [];
for (const file of files) {
const fileTags = await this.tagService.getTagsForFile(file.hash)
for (const tag of fileTags) {
if (this.tags.findIndex((t) => t.getNormalizedOutput() === tag.getNormalizedOutput()) < 0) {
this.tags.push(tag);
}
}
}
this.tags = this.tags.sort((a, b) => {
const aNorm = a.getNormalizedOutput();
const bNorm = b.getNormalizedOutput();
if (aNorm > bNorm) {
return 1
} else if (bNorm > aNorm) {
return -1;
} else {
return 0;
}
});
}
async addSearchTagFromList(event: MatSelectionListChange) {
if (event.options.length > 0) {
const tag = event.options[0].value;
this.fileSearch.addSearchTag(tag);
await this.fileSearch.searchForFiles();
}
event.source.deselectAll();
}
async openFile(file: File) {
if (this.openingLightbox) {
return;
}
this.openingLightbox = true;
try {
await this.openLightbox(file);
} catch (err) {
this.errorBroker.showError(err);
}
this.openingLightbox = false;
}
private async openLightbox(file: File): Promise<void> {
let url = await this.fileService.readFile(file);
let albums = [
{
src: url as string,
caption: file.name ?? file.comment,
thumb: url as string,
}
];
this.lightbox.open(albums, 0, {
disableScrolling: true,
showImageNumberLabel: false,
showDownloadButton: true,
centerVertically: true,
});
const lighboxSubscription = this.lightboxEvent.lightboxEvent$.subscribe(
(event: any) => {
if (event?.id == LIGHTBOX_EVENT.CLOSE) {
lighboxSubscription.unsubscribe();
URL?.revokeObjectURL(url as string);
}
})
}
}
Loading…
Cancel
Save