Skip to content
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

All Platforms: Modally presented popover server driven components. #1838

Closed
bradleysmaskell opened this issue Jan 19, 2023 · 4 comments
Closed

Comments

@bradleysmaskell
Copy link

Use case

For context our BFF is written in Kotlin using Quarkus, client apps are written in Kotlin/Swift/reactJS.

In one of our server-driven screens we have a ListView component. One of the Templates has a Touchable component. When pressed we want to modally present a popover ViewController/Dialog which contains a ServerDrivenComponent and a Context so that selections made in the popover update the parent Activity/ViewControllers context.

Issues

  • there is no Navigate.PresentModalView action on Navigate in Beagle and Navigate is not extendable.
  • While you can create a custom action that stores a ServerDrivenComponent, there's no way to render the component.
    • on iOS in func execute(controller: BeagleController, origin: UIView) the renderer on BeagleController is private and the BeagleEnvironment.renderer is internal.
    • on Android in fun execute(rootView: RootView, origin: View) it's not clear what we need to call on RootView to render a ServerDrivenComponent

Because of these issues, we had to just create a custom action that presents/shows a preexisting client-driven view and have our custom action listen for events so that we can execute/handle cancellation/apply actions. After those actions are completed, to update the parent Activity/ViewController we had to do the following on both platforms.

Android

  1. Cast the RootView to a FragmentRootView/ActivityRootView and cast the fragment.activity or activity to BeagleActivity
  2. Since fetch is internal to BeagleActivity and there's no way to refresh the screens content from the BFF or context we had to call finish() and startActivity() to get the updates from the popover screen, which causes the screen to disappear and be recreated which isn't the best user experience.

iOS

  1. Cast the BeagleController to a BeagleScreenViewController
  2. Since there is no obvious way to refresh the BeagleScreenViewController we have to call reloadScreen(with screenType: ScreenType) which doesn't deallocate and recreate the VC as it does on Android, but still causes the parent VC to flicker while it fetches it's data and presents it again.

There's not really a lot of helpful documentation around this use case, so any advice would be really helpful.

Proposal

  1. Provide a path to extend Navigate in the BFF and client SDKs and add documentation.
  2. Provide renderers that are publicly available so integrators can render ServerDrivenComponents both from a custom action as well as a custom widget.
  3. Provide a way to refresh the data of an activity/VC, or a way to update the ServerDrivenComponents context from a custom widget/action.
@Tiagoperes
Copy link
Contributor

Hello @bradleysmaskell

This is a very interesting feature request. Implementing this is indeed harder than we'd like and it would be in our interest to create something to make it easier. Having said this, I think there might be an easier way to achieve this result.

Have you tried the following?

  1. Create a native modal view in Android and iOS that loads a server driven view with a given URL;
  2. Create a custom action that receives the URL as parameter and opens up the modal;
  3. Use a global context to store the data that must be shared between the screen with the ListView and the modal screen.

By using the Global Context, when you update it from the modal, it should automatically update the other view.

A native support in Beagle

To implement a native support for this in Beagle, we need:

  • A modal view in the navigator and actions to open and close it;
  • A way for updating the state (context) of the screen from the modal.

We're developing a "version of Beagle" for SwiftUI and Compose called "Nimbus". We do have this feature there. Can you take a look at the implementation in Nimbus and tell us if it would work for you? If it does work for you, we can consider bringing it to Beagle.

Link to this feature in nimbus: https://github.com/ZupIT/nimbus-docs/blob/main/specification/default-actions/navigation.md#more-on-states-and-events

The example above navigates to a new screen. But, in Nimbus, we have the action "present", that works the same way, but opens a modal view instead.

Summary

  1. I think there's a simpler way to implement this in Beagle without any update to the library. It consists on using the global context to share a state between the screens and custom actions to open a modal. Can you check if this works for you?
  2. In the long term, I propose a native implementation that works just like Nimbus. What do you think about this?

@Tiagoperes
Copy link
Contributor

Hi, I'm passing here just to let you know that the Beagle team is taking some vacation time.

We'll take 2 weeks off and be back at Feb 06. Feel free to keep commenting in this issue and we'll address it as soon as we're back.

@bradleysmaskell
Copy link
Author

Thanks @Tiagoperes. We will try this approach and report back.

@Tiagoperes
Copy link
Contributor

Closing this due to inactivity.

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

No branches or pull requests

2 participants