How can I set a page in the shell flyout to only load once logged in?

696 views Asked by At

I am trying to create a flyout menu with the logged-in users profile picture in the header. I use an api to get the url to the profile pic, but this can't happen until the user is logged in.

Using AppShell, it seems the flyout content is created as soon as the app runs, so it can't get the data it would need for the profile picture. I tried binding to the IsLogged property (but not sure I implemented that correctly), but it seems it's still runs the code on the page even when IsLogged is false.

How can I get this header section to only try to get the picture if the user is logged in?

AppShell.xaml

<?xml version="1.0" encoding="UTF-8"?>
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:fontAwesome="clr-namespace:FontAwesome"
   xmlns:local="clr-namespace:DOTS.Views"
   xmlns:controls="clr-namespace:DOTS.Controls"
   xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
   Title="DOTS"
   x:Class="DOTS.AppShell">

<Shell.FlyoutHeader>
    <controls:FlyoutHeader IsVisible="{Binding IsLogged}"/>
</Shell.FlyoutHeader>

<!-- Login/Start Page -->
<ShellItem Route="LoginPage" FlyoutItemIsVisible="False">
    <ShellContent ContentTemplate="{DataTemplate local:LoginPage}"/>
</ShellItem>

AppShell.xaml.cs

public partial class AppShell : Shell
{
    
    public AppShell()
    {
        InitializeComponent();
        BindingContext = this;
    }

    public bool IsLogged
    {
        get => (bool)GetValue(IsLoggedProperty);
        set => SetValue(IsLoggedProperty, value);
    }

    public static readonly BindableProperty IsLoggedProperty =
BindableProperty.Create("IsLogged", typeof(bool), typeof(AppShell), false, propertyChanged: IsLogged_PropertyChanged);

    private static void IsLogged_PropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
      if ((bool) newValue)
   Shell.Current.GoToAsync($"//{nameof(MainPage)}");
else
  Shell.Current.GoToAsync($"//{nameof(LoginPage)}");

  }

FlyoutHeader.xaml

  <?xml version="1.0" encoding="UTF-8"?>
  <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="DOTS.Controls.FlyoutHeader">
  <ContentView.Content>
    <Grid BackgroundColor="White">
        <ImageButton x:Name="ProfilePic" WidthRequest="80" HeightRequest="80" CornerRadius="40"  HorizontalOptions ="Center" Clicked ="UpdateProfile_Clicked" />
    </Grid>
</ContentView.Content>

FlyoutHeader.xaml.cs

  namespace DOTS.Controls
  {
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FlyoutHeader : ContentView
    {
      public FlyoutHeader()
       {
        InitializeComponent();
        GetProfilePic();
      }

      public void GetProfilePic()
      {
        ProfilePic.Source = (string)Application.Current.Properties["picUrl"];
       //This value is set upon login
      }
    }
  }
1

There are 1 answers

7
Cfun On BEST ANSWER

In your AppShell, upon IsLogged value change to true, call the GetProfilePic() method:

public partial class AppShell : Shell
{
    public AppShell()
    {
        InitializeComponent();
        BindingContext = this;
    }

    public bool IsLogged
    {
        get => (bool)GetValue(IsLoggedProperty);
        set => SetValue(IsLoggedProperty, value);
    }

    public static readonly BindableProperty IsLoggedProperty =
BindableProperty.Create("IsLogged", typeof(bool), typeof(AppShell), false, propertyChanged: IsLogged_PropertyChanged);

    private static async void IsLogged_PropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
      if ((bool) newValue)
      {
         await Shell.Current.GoToAsync($"//{nameof(MainPage)}");
         (Current.FlyoutHeader as FlyoutHeader)?.GetProfilePic();
      }

      else
         await Shell.Current.GoToAsync($"//{nameof(LoginPage)}");
  }

In FlyoutHeader.xaml.cs do a test on IsLogged:

namespace DOTS.Controls
  {
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FlyoutHeader : ContentView
    {
      public FlyoutHeader()
       {
        InitializeComponent();
        GetProfilePic();
      }

      public void GetProfilePic()
      {
        if ( (Shell.Current as AppShell).IsLogged)
             ProfilePic.Source = (string)Application.Current.Properties["picUrl"];
       //This value is set upon login
      }
    }
  }