| /******************************************************************************** |
| * Copyright (c) 2020 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ********************************************************************************/ |
| |
| import {Component, OnDestroy, OnInit} from "@angular/core"; |
| import {Router} from "@angular/router"; |
| import {select, Store} from "@ngrx/store"; |
| import {combineLatest, Subject} from "rxjs"; |
| import {distinctUntilChanged, filter, map, takeUntil, withLatestFrom} from "rxjs/operators"; |
| import { |
| deleteEmailFromInboxAction, |
| downloadEmailAttachmentAction, |
| fetchEmailAction, |
| fetchEmailInboxAction |
| } from "../../../../store/mail/actions"; |
| import {getEmailInboxSelector, getEmailLoadingSelector, getSelectedEmailSelector} from "../../../../store/mail/selectors"; |
| import {queryParamsMailIdSelector} from "../../../../store/root/selectors"; |
| |
| @Component({ |
| selector: "app-mail", |
| templateUrl: "./mail.component.html", |
| styleUrls: ["./mail.component.scss"] |
| }) |
| export class MailComponent implements OnInit, OnDestroy { |
| |
| public loading$ = this.store.pipe(select(getEmailLoadingSelector)); |
| |
| public emailInbox$ = this.store.pipe(select(getEmailInboxSelector)); |
| |
| public selectedEmailId$ = this.store.pipe(select(queryParamsMailIdSelector)).pipe(distinctUntilChanged()); |
| |
| public selectedEmail$ = this.store.pipe(select(getSelectedEmailSelector)); |
| |
| private destroy$ = new Subject(); |
| |
| public constructor( |
| public store: Store, |
| public readonly router: Router |
| ) { |
| |
| } |
| |
| public ngOnInit() { |
| this.fetchInbox(); |
| |
| // Automatically fetch selected emails which are not part of the inbox |
| this.selectedEmailId$.pipe( |
| filter((mailId) => mailId != null), |
| withLatestFrom(this.emailInbox$), |
| filter(([mailId, inbox]) => !inbox.some((mail) => mail.identifier === mailId)), |
| takeUntil(this.destroy$) |
| ).subscribe(([mailId]) => this.fetch(mailId)); |
| |
| // Automatically navigate to the first inbox item if no email is selected |
| combineLatest([this.selectedEmailId$, this.emailInbox$]).pipe( |
| filter(([mailId]) => mailId == null), |
| map(([_, inbox]) => inbox[0]?.identifier), |
| filter((firstMailId) => firstMailId != null), |
| takeUntil(this.destroy$) |
| ).subscribe((firstMailId) => this.selectMail(firstMailId)); |
| } |
| |
| public ngOnDestroy() { |
| this.destroy$.next(); |
| this.destroy$.complete(); |
| } |
| |
| public fetchInbox() { |
| this.store.dispatch(fetchEmailInboxAction()); |
| } |
| |
| public fetch(mailId: string) { |
| this.store.dispatch(fetchEmailAction({mailId})); |
| } |
| |
| public downloadAttachment(mailId: string, name: string) { |
| this.store.dispatch(downloadEmailAttachmentAction({mailId, name})); |
| } |
| |
| public remove(mailId: string) { |
| this.store.dispatch(deleteEmailFromInboxAction({mailId})); |
| } |
| |
| public selectMail(mailId: string) { |
| return this.router.navigate([], {queryParams: {mailId}, replaceUrl: true}); |
| } |
| |
| } |