Skip to content

modal presentationStyle #1709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dottodot opened this issue Jan 30, 2019 · 13 comments
Closed

modal presentationStyle #1709

dottodot opened this issue Jan 30, 2019 · 13 comments
Assignees

Comments

@dottodot
Copy link
Contributor

Nativescript modals accept extra options for ios i.e presentationStyle

https://github.com/NativeScript/NativeScript/blob/408614dd4595ad8e752bc06334623289053b72a6/tns-core-modules/ui/core/view/view.ios.ts#L413

However when using Angular these options can't be used as the ModalDialogService doesn't have any means to pass these options to the modal view.

@NickIliev
Copy link

@dottodot indeed at this moment the feature is available only for NativeScript Core. Marking this one as a feature request.

@dottodot
Copy link
Contributor Author

@NickIliev OK I'm guessing that not going to happen any time soon. So do you know of any workarounds? I've been trying to use nativescript-popup but when I have a button in the popup that then opens another modal the modal doesn't load correctly. Not sure if it's a problem with the plugin or a limitation of popovers.

@larssn
Copy link

larssn commented Jan 31, 2019

@dottodot I suppose you could do a PR; sounds like a fairly simple problem to solve.

@dottodot
Copy link
Contributor Author

Yes I'd be happy to do that, the problem is though I don't understand how you would pass in UIModalPresentationStyle.Popover as an option i.e

const options = {
 ios: {
  presentationStyle: UIModalPresentationStyle.Popover
 }
}

@dottodot
Copy link
Contributor Author

Actually I've realised that part of the problem is the way they have implemented popover in the core modules. Not sure way they didn't make it so it was similar to the fullscreen option as it would make thing much simpler. Such as

const options = {
 ios: {
  popover: true
 }
}

So I'm going to do a pull request on that first in the hope it gets accepted, and then it should be a bit easier to update nativescript-angular to work with that.

@larssn
Copy link

larssn commented Jan 31, 2019

Good luck, I haven't looked into it myself.
Remember to keep your change backwards compatible though.

@dottodot
Copy link
Contributor Author

dottodot commented Feb 2, 2019

OK I have a solution that works probably not exactly right but at least shows it can be done.

So I've added 2 new options sourceView and ios

export interface ModalDialogOptions {
    context?: any;
    fullscreen?: boolean;
    animated?: boolean;
    stretched?: boolean;
    viewContainerRef?: ViewContainerRef;
    moduleRef?: NgModuleRef<any>;
    sourceView?: ElementRef;
    ios?: any;
}

source view allows you to pass in a child view i.e

  @ViewChild('modalButton') modalButton: ElementRef;
    const options: ModalDialogOptions = {
      viewContainerRef: this._vcRef,
      sourceView: this.modalButton, 
      context: {
        route: 'edit',
        id: this.project.id
      },
      ios: {
        presentationStyle: UIModalPresentationStyle.Popover
      }
    };

if the source is present this is used as the parentView i.e

let parentView = sourceView ? sourceView.nativeElement : viewContainerRef.element.nativeElement;

and finally if ios is present

            if (ios) {
                (<any>parentView).showModal(componentView, { context, closeCallback, fullscreen, animated, stretched, ios });
            } else {
                (<any>parentView).showModal(componentView, context, closeCallback, fullscreen, animated, stretched);
            }

So far I've not found any issues and even allows modals on routes so the action bar can be displayed.

I'm sure it's not perfect or exactly how you'd like it but shows it's pretty simple to implement. The only caveat is users will need to include tns-platform-declarations in their project to allow UIModalPresentationStyle.Popover being passed in.

@dottodot
Copy link
Contributor Author

dottodot commented Feb 2, 2019

Found one issue with the above. I've a button in the popover that opens a second modal. I have this working if I set a timeout. i.e

   this._modalService
      .showModal(MenuModalComponent, options)
      .then((id: string) => {
        if (id) {
          setTimeout(() => {
            this.editProject();
          }, 1000);
        }
      });

but if I close the popover by tapping somewhere else on the screen and then open and press the button the app crashes with the error.

JS ERROR Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'parentOutlet.peekState')

@edusperoni
Copy link
Collaborator

Maybe we should pass the options as they are received, something like adding options to ShowDialogOptions and moving elements from ShowModalOptions to it (except closecallback, which gets overriden). We then pass these options to showModal + closecallback. Should be futureproof enough.

Either that or keep adding options to ShowDialogOptions but use it as showModal(options) instead of showModal({ option1, option2}) and just strip angular specific options from the resulting object.

@NickIliev
Copy link

Hey, @edusperoni @dottodot seems like you guys are a step away from final implementation. Consider posting a PR if you have a working solution and becoming NativeScript contributors.

+1 for this feature from t.1400663

@dottodot
Copy link
Contributor Author

OK I've updated my fork with what I've done so far.

https://github.com/dottodot/nativescript-angular/tree/modal-options

Everything works as it should but think it could do with some refining.

I've also added a public closeModal option. I added this firstly as I found if you opened a popover the hit back the popover wasn't removed correctly then when you selected the popover again the app would crash. So in my app I'm currently doing the following to resolve that problem.

   this.location.onPopState((resp: any) => {
      if (resp.pop) {
        this._modalService.closeModal();
      }
    });

Also a similar thing happens when you click on the background and the popover closes so at the moment if it's a popover I'm first checking to see if any modals are currently open and if so closing them.

@VladimirAmiorkov
Copy link
Contributor

VladimirAmiorkov commented Mar 20, 2019

Hi @dottodot ,

I would be happy to assist you with your first PR into the nativescript-angular repository.

  • First can you make your PR so we can continue its discussion there and see what we are working with. You can take a look at this guidelines.
  • Second I am not sure about the onPopState solution you have implemented as it is best to be handled inside the nativescript-angular itself so that users can directly use this functionality without needed specific "workaround" code in their apps. We are happy to review it in the PR and start from there.

@VladimirAmiorkov
Copy link
Contributor

Closed in #1771

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants