mukaschultze / nativescript-windowed-modal

Consistent modals for Android and iOS
https://www.npmjs.com/package/nativescript-windowed-modal
Apache License 2.0
47 stars 18 forks source link

ViewHierarchy: Parent is already presenting view controller #21

Closed Rav-Naz closed 4 years ago

Rav-Naz commented 4 years ago

Which platform(s) does your issue occur on?

Please, provide the following version numbers that your issue occurs with:

Please, tell us how to recreate the issue in as much detail as possible.

Describe the steps to reproduce it.

The problem only appear in some components. In "ustaweinia.component" work as expected but in "wiadomosci.component" after invoke showModal(), this error is occurring: ViewHierarchy: Parent is already presenting view controller. Close the current modal page before showing another one! Both components are in Tab component. There is no other modals which is opened. Only difference is that in "wiadomosci.component" (broken) method is invoked by longPress method on component.

Is there any code involved?

wiadomosci.component.ts (broken)

`import { Component, OnInit, ViewChild, ElementRef, ViewContainerRef } from '@angular/core'; import { Page } from 'tns-core-modules/ui/page/page'; import { Wiadomosc } from '~/app/serwisy/wiadomosci.model'; import { Subscription } from 'rxjs'; import { WiadomosciService } from '~/app/serwisy/wiadomosci.service'; import { TextField } from 'tns-core-modules/ui/text-field/text-field'; import { getFile } from 'tns-core-modules/http'; import as fileSystem from "tns-core-modules/file-system"; import { isAndroid} from "tns-core-modules/platform"; import as permission from 'nativescript-permissions' import { PotwierdzenieModalComponent } from '~/app/shared/modale/potwierdzenie-modal/potwierdzenie-modal.component'; import { ModalDialogService } from 'nativescript-angular/modal-dialog'; import { ExtendedShowModalOptions } from 'nativescript-windowed-modal-updated'; import { UiService } from '~/app/serwisy/ui.service';

declare var android

@Component({ selector: 'ns-wiadomosci-o', templateUrl: './wiadomosci-o.component.html', styleUrls: ['./wiadomosci-o.component.css'], moduleId: module.id, }) export class WiadomosciOComponent implements OnInit {

wiadomosci: Array<Wiadomosc> = [];
wiadomosciSub: Subscription;

tresc: string = '';

pisanieWiadomosci: boolean = false;

@ViewChild('textview', { static: false }) textviewRef: ElementRef<TextField>;

constructor(private page: Page, private wiadosciService: WiadomosciService, private modal: ModalDialogService, private vcRef: ViewContainerRef, public ui: UiService) {}

ngOnInit() {
    this.ui.zmienStan(2, true)
    this.page.actionBarHidden = true;
    this.wiadosciService.pobierzWiadomosci();
    this.wiadomosciSub = this.wiadosciService.Wiadomosci.subscribe(wiadomosci => {
        this.wiadomosci = [];
        if (wiadomosci === null) {
            return;
        }
        else {
            this.wiadomosci = wiadomosci
        }
        this.ui.zmienStan(2, false)
    });
}

dataFormat(wiadomosc: Wiadomosc) {
    let data = new Date(wiadomosc.data)
    let dzien = data.getDate();
    let miesiac = data.getMonth() + 1;

    let dzienStr = dzien.toString();
    let miesiacStr = miesiac.toString();

    if (dzien < 10) {
        dzienStr = '0' + dzienStr;
    }

    if (miesiac < 10) {
        miesiacStr = '0' + miesiacStr;
    }

    return dzienStr + '/' + miesiacStr + '/' + data.getFullYear();
}

wyslij() {
    if (this.tresc.length >= 1) {
        this.pisanieWiadomosci = false;
        this.ui.zmienStan(2, true)
        this.textviewRef.nativeElement.dismissSoftInput();
        this.wiadosciService.nowaWiadomosc(this.tresc).then(res => {
            switch (res) {
                case 0:
                    this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                    break;
                case 1:
                    this.wiadosciService.pobierzWiadomosci().then(() => {
                        this.tresc = '';
                        setTimeout(() => {
                            this.ui.showFeedback('succes',"Wysłano wiadomość",3)
                        }, 400)
                    });
                    break;
                case 404:
                    this.ui.zmienStan(2, false)
                    this.ui.sesjaWygasla()
                    break;
                default:
                    this.ui.zmienStan(2, false)
                    this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                    break;
            }
        });
    }
    else {
        this.pisanieWiadomosci = false;
    }
}

otworz() {
    this.pisanieWiadomosci = true;
}

pobierzObraz(url: string) {
    let pociety = url.split("/")

    let nazwaPliku = pociety[pociety.length - 1].toString();

    let sciezka: string;

    if (isAndroid) {
        permission.requestPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE).then(() => {
            sciezka = fileSystem.path.join(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), nazwaPliku)
            getFile(url, sciezka).then((result) => {
                setTimeout(() => {
                    this.ui.showFeedback('succes', "Obraz pobrano do: " + result.path,3)
                }, 200)
            })
        }).catch(() => {
            setTimeout(() => {
                this.ui.zmienStan(2, false)
                this.ui.showFeedback('error',"Bez Twojej zgody nie możemy nic zrobić :(",3)
            }, 200)
        })
    }
    else {
        sciezka = fileSystem.path.join(fileSystem.knownFolders.ios.downloads().path, nazwaPliku);
        getFile(url, sciezka).then((result) => {
            setTimeout(() => {
                this.ui.showFeedback('succes', "Obraz pobrano do: " + result.path,3)
            }, 200)
        });
    }

}

async usunWiadomosc(wiadomosc: Wiadomosc) {
    if (wiadomosc.autor_id !== 0) {
        await this.czyKontynuowac(true).then((kontynuowac) => {
            if (!kontynuowac) {
                this.ui.zmienStan(2, true)
                this.tresc = ''
                this.wiadosciService.usunWiadomosc(wiadomosc).then(res => {
                    if(res === 1)
                    {
                        this.ui.showFeedback('succes', "Usunięto wiadomość",3)
                    }
                    else if(res === 404)
                    {
                        this.ui.sesjaWygasla()
                        this.ui.zmienStan(2, false)
                    }
                    else
                    {
                        this.ui.zmienStan(2, false)
                        this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                    }
                });
            }
        });

    }
    else {
        this.ui.zmienStan(2, false)
        this.ui.showFeedback('error',"Nie możesz usunąć wiadomości od ADMINISTRATORA",3)
    }
}

private czyKontynuowac(zmiana: boolean) {
    return new Promise<boolean>((resolve) => {
        if (zmiana === true) {
            this.modal.showModal(PotwierdzenieModalComponent, {
                context: "Wiadomość zostanie usunięta dla Ciebie i ministrantów.\nCzy chcesz kontynuować?",
                viewContainerRef: this.vcRef,
                fullscreen: false,
                stretched: false,
                animated: false,
                closeCallback: null,
                dimAmount: 0.8 // Sets the alpha of the background dim,

            } as ExtendedShowModalOptions).then((wybor) => {
                if (wybor === true) {
                    resolve(false);
                }
                else {
                    resolve(true);
                }
            })
        }
        else {
            resolve(false)
        }
    })
}

dismiss()
{
    if(this.pisanieWiadomosci)
    {
        this.textviewRef.nativeElement.dismissSoftInput()
    }
}

}`

ustawienia.component.ts

`import { Component, OnInit, ViewContainerRef } from '@angular/core'; import { Page } from 'tns-core-modules/ui/page/page'; import { RouterExtensions } from 'nativescript-angular/router'; import as utils from "tns-core-modules/utils/utils"; import as email from "nativescript-email"; import { UserService } from '~/app/serwisy/user.service'; import { TabindexService } from '~/app/serwisy/tabindex.service'; import { Subscription } from 'rxjs'; import { ActivatedRoute } from '@angular/router'; import { HttpService } from '~/app/serwisy/http.service'; import { ParafiaService } from '~/app/serwisy/parafia.service'; import { WiadomosciService } from '~/app/serwisy/wiadomosci.service'; import { WydarzeniaService } from '~/app/serwisy/wydarzenia.service'; import { SecureStorage } from 'nativescript-secure-storage'; import { ModalDialogService } from 'nativescript-angular/common'; import { PotwierdzenieModalComponent } from '~/app/shared/modale/potwierdzenie-modal/potwierdzenie-modal.component'; import { ExtendedShowModalOptions } from 'nativescript-windowed-modal-updated'; import { UiService } from '~/app/serwisy/ui.service';

@Component({ selector: 'ns-ustawienia-o', templateUrl: './ustawienia-o.component.html', styleUrls: ['./ustawienia-o.component.css'], moduleId: module.id, }) export class UstawieniaOComponent implements OnInit {

secureStorage: SecureStorage;

constructor(private page: Page, private router: RouterExtensions, private userService: UserService,
    private tabIndexService: TabindexService, private active: ActivatedRoute, private http: HttpService,
    public parafiaService: ParafiaService, private wiadomosciService: WiadomosciService, private wydarzeniaService: WydarzeniaService,
    private modal: ModalDialogService, private vcRef: ViewContainerRef, private ui: UiService) {}

wersja = this.userService.wersja;
PROSub: Subscription;
PROLista: Array<string>;

ngOnInit() {
    this.PROSub = this.tabIndexService.PRO.subscribe(listaOutletow => {
        this.PROLista = listaOutletow;
    })

    this.secureStorage = new SecureStorage;

    this.page.actionBarHidden = true;
}

nawigujDo(sciezka: string) {
    if ((sciezka === "edytuj-msze" || sciezka === "punktacja") && this.PROLista[4] === "ministrant-dyzury") {
        this.ui.showFeedback('warning',"Aby skorzystać z tego widoku musisz zamknąć panel Edytuj dyżury",3)
        return;
    }
    this.tabIndexService.nowyOutlet(6, sciezka);
    this.router.navigate(['../' + sciezka], { relativeTo: this.active, transition: { name: 'slideLeft' } });
}

otworzLink(link: string) {
    utils.openUrl(link);
}

wyloguj() {
    this.secureStorage.removeAll().then(() => {
        this.http.wyczysc()
        this.parafiaService.wyczysc()
        this.tabIndexService.wyczysc()
        this.userService.wyczysc()
        this.wiadomosciService.wyczysc()
        this.wydarzeniaService.wyczysc()
        this.router.navigate([""], { clearHistory: true, transition: { name: 'slideBottom' } }).then(() => {
            setTimeout(() => {
                this.ui.showFeedback('succes',"Pomyślnie wylogowano",3)
            }, 400)
        });
    })
}

wyzerujPunkty() {
    if (this.PROLista[4] === "ministrant-szczegoly" || this.PROLista[4] === 'ministrant-dyzury' || this.PROLista[4] === 'aktywacja-konta') {
        this.ui.showFeedback('warning',"Aby skorzystać z tej funkcji musisz zamknąć panel Szczegóły Ministranta",3)
        return;
    }

    this.modal.showModal(PotwierdzenieModalComponent, {
        context: 'Czy jesteś pewny, że chcesz wyzerować punkty WSZYSTKIM ministrantom w swojej parafii? Ta funkcja jest zalecana przy rozpoczęciu nowego roku liturgicznego.',
        viewContainerRef: this.vcRef,
        fullscreen: false,
        stretched: false,
        animated: false,
        closeCallback: null,
        dimAmount: 0.8

    } as ExtendedShowModalOptions).then((wybor) => {
        if (wybor) {
            this.ui.zmienStan(4, true)
            this.ui.zmienStan(1, true)
            this.parafiaService.wyzerujPunkty().then(res => {
                this.ui.zmienStan(4, false)
                this.ui.zmienStan(1, false)
                switch (res) {
                    case 0:
                        this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                        break;
                    case 1:
                        this.ui.showFeedback('succes',"Pomyślnie wyzerowano punkty",2)
                        break;
                    case 404:
                        this.ui.sesjaWygasla()
                        break;
                    default:
                        this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                        break;
                }
            })
        }
    })
}

usunDyzury() {

    if (this.PROLista[4] === "ministrant-szczegoly" || this.PROLista[4] === 'ministrant-dyzury' || this.PROLista[4] === 'aktywacja-konta') {
        this.ui.showFeedback('warning',"Aby skorzystać z tej funkcji musisz zamknąć panel Szczegóły Ministranta",3)
        return;
    }

    this.modal.showModal(PotwierdzenieModalComponent, {
        context: 'Czy jesteś pewny, że chcesz usunąć WSZYSTKIE dyżury ministrantów w swojej parafii? Ta funkcja jest zalecana przy rozpoczęciu nowego roku liturgicznego.',
        viewContainerRef: this.vcRef,
        fullscreen: false,
        stretched: false,
        animated: false,
        closeCallback: null,
        dimAmount: 0.8

    } as ExtendedShowModalOptions).then((wybor) => {
        if (wybor) {
            this.ui.zmienStan(4, true)
            this.ui.zmienStan(0, true)
            this.parafiaService.usunWszystkieDyzury().then(res => {
                this.ui.zmienStan(4, false)
                this.ui.zmienStan(0, false)
                switch (res) {
                    case 0:
                       this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                        break;
                    case 1:
                        this.ui.showFeedback('succes',"Pomyślnie usunięto dyżury",2)
                        break;
                    case 404:
                        this.ui.sesjaWygasla()
                        break;
                    default:
                            this.ui.showFeedback('error',"Sprawdź swoje połączenie z internetem i spróbuj ponownie ",3)
                        break;
                }
            })
        }
    })
}

kontakt() {
    email.available().then(avail => {
        if (avail) {
            email.compose({ to: ["kontakt@lsoapp.pl"] });
        }
        else {
            this.nawigujDo('info');
        }
    });
}

}`

Thanks in advance for any help !

Rav-Naz commented 4 years ago

I resolve my problem by simply change (longPress) to other Gesture Event like (tap) or (doubleTap)