adospace / reactorui-maui

MauiReactor is a MVU UI framework built on top of .NET MAUI
MIT License
568 stars 47 forks source link

Shell menu not render #105

Closed MattePozzy closed 1 year ago

MattePozzy commented 1 year ago

Hi, I have an application that has a login page without a menu that, after the login logic takes the user to a page with the side menu.

So I have created the first page like this:

return new Shell() {
                new ContentPage()
                {
                    new VStack {
                        new Button("go to shell").VCenter().HCenter().OnTapped(goToSecond)
                    }
                }
            }.BackButtonIsVisible(false);

and the second page:

public override VisualNode Render()
            => new Shell
            {
            new FlyoutItem("Page1")
            {
                new ContentPage("Page1")
                {
                    new Label("PAGE 1").VCenter().HCenter().FontSize(50)
                }
            },
            new FlyoutItem("Page2")
            {
                new ContentPage("Page2")
                {
                    new Label("PAGE 2").VCenter().HCenter().FontSize(50)
                }
            }
            }
            .BackButtonIsVisible(false)
            .ItemTemplate(RenderItemTemplate);

        static VisualNode RenderItemTemplate(MauiControls.BaseShellItem item)
            => new Grid("68", "*")
            {
            new Label(item.Title)
                .VCenter()
                .Margin(10,0)
            };

If I set the first page as "main page", then click on the button, the second page is open but without the shell side menu. If I set the second comage as "main page" the shell menu is rendered correctly.

How can I fix this?

Attached a sample.

Thank you MauiTest.zip

adospace commented 1 year ago

Well, it is more like a .NET MAUI issue, I mean, not an issue, probably more like which strategy to use to present a content page before a Shell. Surely there are more options but one could be using the Window, with a code like this (not tested):

public override VisualNode Render()
{
    return new Window
    {
        !State.LoggedIn ? 
        RenderLogin()
        :
        RenderShell()
    };
}

VisualNode RenderLogin()
{
      return new ContentPage()
      {
          new VStack {
              new Button("go to shell").VCenter().HCenter().OnClicked(()=>SetState(s => s.LoggedIn = true))
          }
      }
}

VisualNode RenderShell()
{
            return new Shell
            {
            new FlyoutItem("Page1")
            {
                new ContentPage("Page1")
                {
                    new Label("PAGE 1").VCenter().HCenter().FontSize(50)
                }
            },
            new FlyoutItem("Page2")
            {
                new ContentPage("Page2")
                {
                    new Label("PAGE 2").VCenter().HCenter().FontSize(50)
                }
            }
            }
            .BackButtonIsVisible(false)
            .ItemTemplate(RenderItemTemplate);
}

static VisualNode RenderItemTemplate(MauiControls.BaseShellItem item)
    => new Grid("68", "*")
    {
    new Label(item.Title)
        .VCenter()
        .Margin(10,0)
    };
}

Anyway I'll take a look at your sample to see if there is anything wrong with MauiReactor/.NET MAUI

MattePozzy commented 1 year ago

This is exactly what I was looking for! Now, however, I open a page with a state that is not reset until I log out (when I change the contents of the window by setting State.IsLogged = false).

I guess it's because the shell only passes the render method once.

Is there any way to reset the state of a state?

Thank you :)

Attached the modified sample. MauiTest.zip

adospace commented 1 year ago

I'm not sure I completely understand your question but you can't just set the LoggedIn to false in the shell when the user logs out?

MattePozzy commented 1 year ago

I'm not sure I completely understand your question but you can't just set the LoggedIn to false in the shell when the user logs out?

Sorry, I didn't explain myself well. The problem is not with "LoggedIn", but with the state of a page inside the shell.

I have attached a video of me logging in and switching to the shell. In the shell menu I go to page 2 which has a State with an INT that I change randomly on button click. I click the button a couple of times and the INT changes. I go to page 1 again using the Shell menu. I go back to page 2 and the State has not reset because being inside a shell I no longer pass in the render method of page 2. When I do this last step I expect to find the State of page 2 to its default state. How can I do?

The state only resets if I log out by setting "LoggedIn" to false.

Screen Recording 2023-06-26 at 09.06.57.mov.zip

adospace commented 1 year ago

It's an issue/feature of the shell control in MAUI. Pages are always cached (at least in current version) (https://github.com/dotnet/maui/issues/9300).

One solution could be handling the OnNavigated() event on the shell or the OnAppearing() event on child page and modify the page state accordly.

For example you could add .OnAppearing(()=> SetState(s => s.Title = 0)) on SecondPage

MattePozzy commented 1 year ago

It's an issue/feature of the shell control in MAUI. Pages are always cached (at least in current version) (dotnet/maui#9300).

One solution could be handling the OnNavigated() event on the shell or the OnAppearing() event on child page and modify the page state accordly.

For example you could add .OnAppearing(()=> SetState(s => s.Title = 0)) on SecondPage

Thank you, this solve my issue!