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

Login screen to TabBasedApp and then log out back to Login screen #2310

Closed
dadewoyin opened this issue Dec 10, 2017 · 7 comments
Closed

Login screen to TabBasedApp and then log out back to Login screen #2310

dadewoyin opened this issue Dec 10, 2017 · 7 comments
Assignees

Comments

@dadewoyin
Copy link

dadewoyin commented Dec 10, 2017

Issue Description

I haven't found a proper solution for displaying a login screen before a TabBasedApp. I haven't found a way to switch between a single screen app and a tab based one, which would be the most ideal way so I could have the login/signup process as a "single screen app" and after logging in, switch to a tab based app. I've tried having a modal show before the tabs show, but have had no luck. I've also tried having a conditional for if the user is logged in, show tabs & if not, then show single app login. However, there's no way to log in or out, which would require switching between the two app types. Maybe I'm missing something, but if someone can give a concrete example, that would be great. I've only found open ended answers in past issue #'s or answers that don't solve logging in and out.

Steps to Reproduce / Code Snippets / Screenshots

I've tried:

if (!isLoggedIn) {
    Navigation.showModal({
        screen: "example.Login",
    });
} else {
    Navigation.startTabBasedApp({
        tabs: []
    })
}

Something like this was suggested in #1442, but if someone is not logged in and brought to the example.Login, there is no way to switch to the tabs after logging in and after logging out, no way to go back to the example.Login.


Environment

  • React Native Navigation version: 1.1.300
  • React Native version: 0.49.2
  • Platform(s) (iOS, Android, or both?): Both
  • Device info (Simulator/Device? OS version? Debug/Release?): iPhone 8 iOS 11.1 Simulator
@dadewoyin dadewoyin changed the title Login screen to TabBasedApp and then log out BACK to Login screen Login screen to TabBasedApp and then log out back to Login screen Dec 10, 2017
@pqkluan
Copy link
Contributor

pqkluan commented Dec 11, 2017

Why don't you do the following?

// For Authentication
export function startLogin(){
  Navigation.startSingleScreenApp(...);
}

// Main app
export function startMainApp(){
  Navigation.startTabBasedApp(...);
}

// call from index.js
function init(){
  const isUserExists = /** magic */;

  if(!isUserExists){
    startLogin();
  } else {
    startMainApp();
  }
}

// Handle login logic
function login(){
  // bla bla bla
  if(everything_is_good){
    startMainApp();
  }
}

// handle logout logic
function logout(){
  // remove user data
  startLogin();
}

@pqkluan pqkluan self-assigned this Dec 11, 2017
@simonedavico
Copy link

This is a basic example inspired from my setup (keeps in sync with redux store):

class App {

  appRoot = 'loading';
  store = {};

  constructor() {
    init()
      .then(this.attachToStore)
      .then(this.startApp)
      .catch(err => console.log('App init error', err.message))
  }

  onStoreUpdate = () => {
    const { sessionToken } = this.store.getState().login;
    // this can be complex business logic depending on requirements
    const newAppRoot = !!sessionToken ? 'app' : 'login';
    if(newAppRoot !== this.appRoot) {
      this.appRoot = newAppRoot;
      this.startApp();
    }
  }

  attachToStore = store => {
    const { sessionToken } = store.getState().login;
    // keep store ref, but it could also be passed to onStoreUpdate somehow?
    this.store = store;
    // this can be complex business logic depending on requirements
    this.appRoot = !!sessionToken ? 'app' : 'login';
    store.subscribe(this.onStoreUpdate);
  }

  startApp = () => {
    switch(this.appRoot) {
      case 'app': {
        Navigation.startTabBasedApp({
          tabs: [
            {
              label: 'Feed',
              screen: 'myApp.Feed',
              title: 'Feed',
              icon: appIcons['trending-up'],
              navigatorStyle,
            },
            {
              label: 'Profile',
              screen: 'myApp.Profile',
              title: 'Profile',
              icon: appIcons['face'],
              navigatorStyle
            },
            {
              label: 'More',
              screen: 'myApp.Settings',
              title: 'More',
              icon: appIcons['menu'],
              navigatorStyle
            }
          ],
          animationType: 'slide-down',
          appStyle: {
            forceTitlesDisplay: true,
            tabBarButtonColor: color.divider,
            tabBarSelectedButtonColor: color.primary
          }
        });
        break;
      }

      case 'login': {
        Navigation.startSingleScreenApp({
          screen: {
            screen: 'myApp.Login',
            title: 'Login',
            navigatorStyle: {
              navBarHidden: true
            }
          }
        });
        break;
      }

      default: {
        console.error('Aww, snap! App init went wrong :(');
      }
    }
  }
}

export default App;

@pqkluan
Copy link
Contributor

pqkluan commented Dec 19, 2017

Been a week since last response from OP. I'll assume the problem resolved.

@pqkluan pqkluan closed this as completed Dec 19, 2017
@witalobenicio
Copy link

@simonedavico how do you get your store in app.js? I thought it has to be registered in Navigation.registerComponent()

@simonedavico
Copy link

simonedavico commented Jan 29, 2018

@witalobenicio I have it as the resolved value of the promise I return from the init function:

export const init = async (): Promise<AppStore> => {
  const provider: AppProvider = (Provider: any);
  const store: AppStore = configureStore();

  enableAndroidAnimations();

  const allResolved: [
    AppStore,
    boolean,
    { [string]: string }
  ] = await Promise.all([store, registerScreens(store, provider), loadIcons()]);

  return allResolved[0];
};

init calls configureStore:

export const configureStore = (
  initialState: AppState = appInitialState
): AppStore => {
  const enhancer: StoreEnhancer<*, *> = composeEnhancers(
    applyMiddleware(...middleware),
    ...enhancers,
    devToolsWorkaroundEnhancer
  );

  return createStore(rootReducer, initialState, enhancer);
};

@abhishekp8003
Copy link

how to add skip button in login

@chrise86
Copy link

how to add skip button in login

@abhishekp8003 I think what you've got to remember is that the actual login functionality is outside of the scope of this library, and so how you achieve this is really up to you.

If you're using a setup similar to the solutions posted above, then you can just call your function that starts the tab based app when pressing the "skip" button on your login screen, assuming that's what you're asking.

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

No branches or pull requests

6 participants