import { Component, OnInit, Input, CUSTOM_ELEMENTS_SCHEMA, Output, EventEmitter, ElementRef, ViewChild, OnDestroy, AfterViewInit } from '@angular/core'; import { AlertController, ToastController, IonicModule, ActionSheetController, ActionSheetButton, AlertOptions, ModalController, ModalOptions, LoadingController, Platform, IonBackButtonDelegate, NavController } from '@ionic/angular'; import { FileOpener } from '@awesome-cordova-plugins/file-opener/ngx'; import { StoragehubService } from '../storagehub.service'; import { CommonModule } from '@angular/common'; import { MatIconModule } from '@angular/material/icon'; import { WSItem } from '../model/ws-item'; import { Action } from '../model/actions/action'; import { CreateFolderAction } from '../model/actions/create-folder'; import { Actions } from '../model/actions/actions'; import { ItemsListComponent } from '../items-list/items-list.component'; import { Sorting, SortName, SortType } from '../model/sorting'; import { UploaderInfoService } from '../uploader-info.service'; import { EventService } from '../event.service'; import { OpenFile } from '../model/actions/open-file'; import { presentConnectionAlert } from '../_helper/utils'; import { Subscription } from 'rxjs'; @Component({ standalone: true, selector: 'show-folder', providers: [FileOpener, StoragehubService, UploaderInfoService], templateUrl: './show-folder.component.html', styleUrls: ['./show-folder.component.scss'], schemas: [CUSTOM_ELEMENTS_SCHEMA], imports: [ CommonModule, IonicModule, MatIconModule, ItemsListComponent ] }) export class ShowFolderComponent implements OnInit, OnDestroy, AfterViewInit { @Output() folderClickedEvent = new EventEmitter(); filteredBySegmentItems: WSItem[] | undefined; filtereBySearchItems: WSItem[] | undefined; _items: WSItem[] | undefined; currentSortName = SortName.Name; currentSortType = SortType.Asc; @Input() set items(items: WSItem[] | undefined) { this._items = items?.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); this.filteredBySegmentItems = this._items; this.filtereBySearchItems = this._items } @Input() parentItem: WSItem | undefined = undefined; @Input() title: string | undefined; @Input() root: boolean = false; @Input() enableCreateOperations = false; searchenabled = false; selectedSegment = "all"; public get sortName(): typeof SortName { return SortName; } underUpload: string[]; currentSearch: string = ""; @ViewChild('filepicker') uploader!: ElementRef; customSortAlertOptions = { header: 'Sort by', translucent: true, }; constructor( private actionSheetCtrl: ActionSheetController, private storagehub: StoragehubService, private alertCtrl: AlertController, private modalCtrl: ModalController, private toastController: ToastController, private uploaderInfo: UploaderInfoService, private event: EventService, private fileOpener: FileOpener, private loadingCtrl: LoadingController, private navController: NavController ) { this.underUpload = this.getUnderUploadItems(); } ngAfterViewInit(): void { } backButtonSubscription: Subscription | undefined; reloadSubscription: Subscription | undefined; ngOnInit(): void { this.reloadSubscription = this.event.ReloadEvent.subscribe((val) => { console.log(`event received with value ${val} in item ${this.parentItem?.item.id}`); if (val === this.parentItem?.item.id) this.loadDocuments(); }); this.backButtonSubscription = this.event.BackButtonEvent.subscribe(() => this.onbackButtonPressed()); } ngOnDestroy(): void { var p: IonBackButtonDelegate this.reloadSubscription?.unsubscribe(); this.backButtonSubscription?.unsubscribe(); } getUnderUploadItems(): string[] { const parentId = this.parentItem?.item.id; return parentId ? this.uploaderInfo.getUnderUpload(parentId) : []; } loadDocuments() { this.filtereBySearchItems = undefined; if (this.parentItem) { this.storagehub.getChildren(this.parentItem.item.id).then((obs) => obs.subscribe({ next: (res) => { const tmpItems$: WSItem[] = [] const tmpFilteredBySegment$: WSItem[] = [] var segmentFilterFunction = this.getSegmentFilterFunction(); res.forEach(i => { var localItem = new WSItem(i); tmpItems$.push(localItem); if (segmentFilterFunction(localItem)) { tmpFilteredBySegment$.push(localItem); } }); this._items = tmpItems$.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); this.filteredBySegmentItems = tmpFilteredBySegment$.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); this.filtereBySearchItems = tmpFilteredBySegment$.filter(d => d.getTitle().toLowerCase().indexOf(this.currentSearch) > -1) this.underUpload = this.getUnderUploadItems(); }, error: err => presentConnectionAlert(err, this.alertCtrl) }) ) } } changeSearchEnabled() { this.searchenabled = !this.searchenabled; if (!this.searchenabled) this.searchCleared() } onbackButtonPressed() { if (!this.root) { console.log("back clicked (not root)"); this.navController.pop(); } else console.log("back clicked (root)"); } getSegmentFilterFunction(): (value: WSItem) => boolean { var filterItemFunction; switch (this.selectedSegment) { case "shared": filterItemFunction = (value: WSItem) => value.type == "SharedFolder"; break; case "folders": filterItemFunction = (value: WSItem) => value.isFolder(); break; case "files": filterItemFunction = (value: WSItem) => value.isFile(); break; default: filterItemFunction = (value: WSItem) => true; } return filterItemFunction; } filterBy(value: string) { if (value == this.selectedSegment) return; this.filtereBySearchItems = undefined; this.selectedSegment = value; if (this.selectedSegment == "all") this.filteredBySegmentItems = this._items; else this.filteredBySegmentItems = this._items?.filter(this.getSegmentFilterFunction()); if (this.currentSearch.length != 0) this.filtereBySearchItems = this.filteredBySegmentItems?.filter(d => d.getTitle().toLowerCase().indexOf(this.currentSearch) > -1); else this.filtereBySearchItems = this.filteredBySegmentItems; } changeSortType() { if (this.currentSortType == SortType.Asc) this.currentSortType = SortType.Desc; else this.currentSortType = SortType.Asc; this.updateSort(); } changeSortName($event: any) { var sort: SortName = $event.target.value; if (this.currentSortName != sort) { this.currentSortName = sort; this.updateSort(); } } updateSort() { this._items = this._items?.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); if (this.selectedSegment == "all") this.filteredBySegmentItems = this._items; else this.filteredBySegmentItems = this.filteredBySegmentItems?.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); if (this.currentSearch.length != 0) this.filtereBySearchItems = this.filtereBySearchItems?.sort(Sorting.getSortFunction(this.currentSortName, this.currentSortType)); else this.filtereBySearchItems = this.filteredBySegmentItems; } searchItems(event: any) { const query: string = event.target.value.toLowerCase(); this.currentSearch = query; this.filtereBySearchItems = this.filteredBySegmentItems?.filter(d => d.getTitle().toLowerCase().indexOf(query) > -1); } searchCleared() { this.currentSearch = ""; this.filtereBySearchItems = this.filteredBySegmentItems } itemClicked(item: WSItem) { if (item.isFolder()) this.folderClickedEvent.emit(item); else if (item.isFile()) { new OpenFile(item).open(this.storagehub, this.fileOpener, this.loadingCtrl, this.alertCtrl); } } addFile() { this.uploader.nativeElement.click(); } async fileSelected($event: any) { const selected = $event.target.files[0]; if (selected && this.parentItem) { const parentId: string = this.parentItem?.item?.id; this.uploaderInfo.uploadStarted(parentId, selected.name); const upload$ = this.storagehub.uploadFile(parentId, selected.name, selected); var first = true; upload$.then((obs) => obs.subscribe({ next: () => { if (first) { this.loadDocuments(); first = false; } }, error: () => this.uploaderInfo.uploadFinished(parentId, selected.name), complete: () => { console.log this.uploaderInfo.uploadFinished(parentId, selected.name); this.loadDocuments(); } }) ); } } async createFolder() { var createFolderAction: CreateFolderAction = new CreateFolderAction(); if (this.parentItem) this.actionHandler(createFolderAction, this.parentItem); } async presentActionSheet(item: WSItem) { var buttons: ActionSheetButton[] = []; Actions.getActionsPerType(item.type).forEach(action => buttons.push({ text: action.getName(), data: { action: action.getName(), }, role: action.getActionType(), handler: () => this.actionHandler(action, item) })); buttons.push({ text: 'Cancel', role: 'cancel', data: { action: 'cancel', }, }); const actionSheet = await this.actionSheetCtrl.create({ header: `${item.item.title}`, mode: 'ios', translucent: true, buttons: buttons, cssClass: 'my-custom-class' }); await actionSheet.present(); const result = await actionSheet.onDidDismiss(); } async presentAlertControl(options: AlertOptions) { let alert = await this.alertCtrl.create(options); await alert.present(); } async presentModal(options: ModalOptions) { let modal = await this.modalCtrl.create(options); await modal.present(); } async presentToast(text: string) { const toast = await this.toastController.create({ message: text, duration: 1500 }); await toast.present(); } async actionHandler(action: Action, item: WSItem) { var alertOptions: undefined | AlertOptions = action.getAlertOptions(item, this.storagehub, () => this.loadDocuments()); if (alertOptions) { await this.presentAlertControl(alertOptions); } else { var modalOptions: undefined | ModalOptions = action.getModalOptions(item, this.storagehub, (itemId: string) => this.event.ReloadEvent.emit(itemId), (text: string) => this.presentToast(text)); if (modalOptions) await this.presentModal(modalOptions); else action.actionHandler(item, this.storagehub); } } }