Skip to content

jekkilekki/app-kotesol-natcon-2019

Repository files navigation

2019 KOTESOL National Conference App

React Native Mobile App v1.1.1

cover-android

KNC 2019 is the mobile app & conference booklet for the 2019 KOTESOL National Conference. It is a React Native mobile app built in Expo. It utilizes:

  1. Redux to manage application state
  2. React Navigation for Switch, Stacked, Tabbed, and Modal Navigation
  3. AsyncStorage for maintaining app changes

This project was bootstrapped with Create React Native App.

Table of Contents

Overview

This app was designed with 2 primary goals in mind.

  1. To provide instant access to the Conference schedule, talks, speakers, attendees, and venue information in a mobile app that is downloadable from both the Google Play and Apple App Stores.
  2. To allow Users to store personalized data with a login. Personalized data includes:
    • a personalized "My Schedule" of favorite talks that they can easily review
    • a personalized "My Places" list of local businesses and restaurants to try out
    • a list of "My Friends" (other users of the app) who attendeed the Conference)
    • their own profile information - including a profile photo

iOS vs Android

Devices tested

  • iOS emulator (Xcode 10.2 + iOS 12.1, 12.2)
    • iPad Pro
    • iPhone XR
  • Android emulator (Android Studio)
    • Nexus 5X
    • Pixel 3
  • LG G6 (real device)

Installation

Current version: 1.1.1

This app is available to download from:

Run in an Emulator

If you wish to download and run the source code on your local machine, you'll need a mobile device with Expo installed, or an iOS or Android emulator (requires more setup). To run this app on a mobile device with Expo, clone this directory to your computer with:

git clone https://github.com/jekkilekki/app-kotesol-natcon-2019

Then, navigate to the newly created directory in your Terminal and run:

npm install
npm start

You may also replace npm with yarn if you have Yarn installed.

Be sure the Expo app is installed on your mobile device. Then, open the Expo app and scan the QR code from your Terminal (after running npm start).

More detailed instructions can be found in the official Create React Native App GitHub repository or the Expo Installation documentation.


App Functionality

List of Screens

The following is a list of Screens that the User has access to in this app.

  1. WelcomeScreen (3-4 screen introductory slideshow)
  2. ScheduleScreen
    • MyScheduleScreen
    • SpeakerSingleScreen (individual speakers abstracts and bios, also linked in the SpeakerScreen)
  3. SpeakerScreen
  4. MapScreen
    • MyPlacesScreen
    • PlaceSingleScreen (individual place data - address, phone number, map, image)
  5. AboutScreen
    • ConductScreen
    • PrivacyScreen

WelcomeScreen

Tutorial Drawer Menu
welcome-android drawer-android

The WelcomeScreen is presented automatically on the FIRST app load only. Subsequent lauches of the app will take users directly to the Schedule (main) screen, but users always have the option to review the Welcome tutorial from the Drawer menu ("How to Use this App").

Android: requires sliding of the screen to view. Last screen doesn't skip automatically to the Schedule screen when pulled. User must click the "Skip" button.

iOS: left/right buttons work as buttons, and sliding also works. The last screen skips automatically to the Schedule screen when pulled or the button is pressed.

ScheduleScreen

Schedule Search Single
schedule-android search-android myschedule-android

The ScheduleScreen sorts all presentations by time and groups them accordingly. This screen also displays non-speaker events such as Registration, Lunch, and the Closing Ceremony. Clicking one of the non-speaker event cards redirects users to the MapScreen.

Speaker Cards are contracted by default on the ScheduleScreen. Only the plenary session is expanded.

Functionality

  • Search: Dynamically search by speaker name or presentation title
  • Filter: Click the colored bar to the left of any Speaker Card to filter by that conference track (Poster session, Plenary session, etc).
    • iOS also includes a filtering menu to the right of the Search bar (but it is overlapped by the cards on Android so removed)
  • Expand/Contract: Click the arrow in the upper-right corner of a Speaker Card to expand the card and display more details, or contract it (current view is contracted)
  • Like: Click the heart in the lower-right corner to "Like" a presentation and add it to the "My Schedule" screen
  • View Speaker Details: Click any Speaker Card to be taken to a Single Detail view for that speaker to read their presentation abstract and bio

SpeakerScreen

Speakers Speaker Detail
speakers-android speaker-single-android

The SpeakerScreen functions in much the same way as the ScheduleScreen with a few notable differences:

  • All Cards are expanded by default
  • Only Speaker Cards are shown (no non-speaker event cards like Registration, Lunch, etc)
  • Filtering works by clicking the colored Track button (rather than the colored bar like on the ScheduleScreen). The expanded view of the Speaker Cards shows the Track button, but the contracted view only shows a colored bar

MapScreen

Venue Maps Single Place MyPlaces
map-android mapview-android map-single-android myplaces-android

The MapScreen displays venue information at the top and interactive maps at the bottom of the screen.

Functionality

  • Change location: Clicking any of the four location buttons on the Map will center the map on that location
  • Filter places: Users may filter places by type: cafe, food, drinks, hotels, or "all"
  • View details: Clicking one of the map pins displays a popup with address and phone details. Clicking on the card takes users to a Single Place View that includes a photo of the building, contact info, a map, and a "Like" heart
  • Favorites: Clicking the "Like" heart on a Single Place screen adds that place to the MyPlaces screen which can be directly accessed and reviewed from the Drawer menu or the MapScreen

*iOS note: The MapView Component was crashing on iOS 12.3 (not 12.2 or 12.1), so was removed for distribution to the App store. In its place, there is a button to view the Conference website which also includes this location data.

AboutScreen

About Conduct Privacy
about-android conduct-android privacy-android

The AboutScreen contains all the conference details including separate Code of Conduct and Privacy Policy screens.

The main About screen includes a "stats bar" that shows how many Talks and Places have been "Liked" on this device. Clicking either of these will take users directly to either the MySchedule or MyPlaces screens.

The About screen also contains sponsor and development information.


List of Removed Screens

The following is a list of Screens that were developed for the app, but ultimately removed for the public release of the app. In a later version of the app, these may be revisited and further developed.

  1. AuthScreen
    • ProfileScreen
  2. AttendeesScreen
    • MyFriendsScreen
    • AttendeeSingleScreen

*Note: These screens were removed from the public distribution of the app in order to streamline the app approval process. Since these screens all deal with (potentially private) user data, they were removed in favor of device-specific data.

AuthScreen

See Authentication Flow below for details on how the authentication process works.

The AuthScreen originally would appear as the final "slide" in the Welcome tutorial on initial app load, or in place of the ProfileScreen if users were not logged in. It allows login with Facebook OR an email address and creates and stores user data in Firebase.

The ProfileScreen loads a user's personal data (originally pulled into the app's local data from Firebase). The user can optionally update their profile data in two ways (with two different modals):

  1. Profile Modal: Allows a user to update their name, email, affiliation, and short biography. Updated data is saved to Firebase. Canceling the update restores the original user data.
  2. Photo Modal: Allows a user to update their photo in one of three ways:
    1. Image URL: This can be copy-pasted from the Internet
    2. Camera button: The app requests access to the user's Camera and if granted, allows the user to capture a new photo for their profile photo. The photo is then uploaded to, and referenced from, Firebase.
    3. Gallery button: The app requests access to the user's Camera Roll and if granted, allows the user to select a photo from their Gallery to use as their profile photo. The photo again is stored in and accessed from Firebase.

AttendeesScreen

The AttendeesScreen has the same design, layout, and functionality as the MyPlaces screen. It initially pulls the current user's profile out to the top - like KakaoTalk and other chat apps do. Then, it (conditionally) lists all the remaining users that Firebase has a record of.

Conditions

  1. Show data: Each profile screen Profile Modal contains a checkbox that allows the user to selectively display their data (or not) among other Conference attendees.
  2. Password: In order to prevent outside entities from adding their names to the attendees list (if not truly attendees), the second conditional checks that the password provided to allow the display of user data matches that password determined by the app (this will be stored separately in Firebase)

User data will ONLY be displayed in the Attendees screen if BOTH the "show data" checkbox is checked AND the "password" is correct.


Authentication Flow

The Authentication Flow is closely coupled with the app's initialization flow with multiple calls to Redux actions that determine the state of the user and the app. Therefore, Authentication Flow can best be understood in the greater context of app initialization flow as presented below:

Redux actions

  1. assets_loaded: Preloads necessary app assets like fonts, icons, and some images
  2. app_check_auth_status:
    • Firebase: Determines if the user is already logged into Firebase through this app (currently removed)
    • AsyncStorage: Determines if a User Object is present in the device's AsyncStorage
  3. app_user_logged_out: Fires if the device indicates the user IS NOT currently logged into Firebase, OR if there is no User Object present in AsyncStorage. This action will cause the WelcomeScreen tutorial to display.
    • AsyncStorage: With the current (v.1.1.1) configuration that utilizes device data rather than personal data, if the user is "logged out" on the first run of the app, then a default user account is created immediately and the next action ("logged in") is run
  4. app_user_logged_in: Fires if the device determines that the user IS logged into Firebase, OR if there is a User Object present in AsyncStorage. If this action is fired INSTEAD OF the previous "logged out" action, the app will bypass the WelcomeScreen tutorial and go straight to the main ScheduleScreen
  5. profile_save: This action takes a received User Object - either through Facebook or Firebase authentication, or AsyncStorage - and "saves" the User data to the Redux state from which it can be used within the app.
    • Firebase: If the app is using Firebase, every time this action is fired, the app saves User data to that user's entry in the Firebase database

Firebase Authentication Flow - Detailed (removed)

The AuthScreen (and authentication flow) will be bypassed altogether if the device's AsyncStorage already contains a User Object - or if Firebase is enabled and the user is logged in.

Firebase: There are two possible ways to login to the app:

  1. Facebook
  2. Email & Password

Both methods utilize Firebase to create and manage user accounts. Authentication looks like this:

0. Check Authentication

  • When the App first loads, check the status of firebase.auth()
    • If logged in
      • WelcomeScreen and AuthScreen are bypassed, (AuthScreen will be bypassed when clicking the Profile Button as well)
      • User data is fetched from Firebase,
      • Stored in the profile slice of Redux state,
      • and user is taken directly to the main App (ScheduleScreen)
    • If NOT logged in
      • load WelcomeScreen which leads to AuthScreen
      • or if "Skipped" to the Schedule, when clicking the Profile Button and not logged in, continue with authentication flow

1A. Facebook

  1. User clicks Facebook button, and App asks for permissions
  2. User confirms and logs in
  3. App receives a token and user credentials from Facebook
    • App then creates a new Firebase user with this data
    • The newly created Firebase user's data is then used throughout the app
  4. Continue "Joint Authentication Flow" (below)

1B. Email & Password

  1. User enters an email and password combination
  2. App attempts to log user into Firebase
    • If email exists, check the password
      • If password is incorrect, return Authentication error
      • If password is correct, Login
    • If email doesn't exist, create a new user with this email / password combination
      • The newly created Firebase user's data is then used throughout the app
  3. Continue "Joint Authentication Flow" (below)

2. Joint Authentication Flow

  1. User data from Firebase is saved into the profile slice of Redux state
  2. App loads ScheduleScreen
    • When clicking on the Profile button, User is transported to the ProfileScreen to update their profile data
    • User can update or change any of their profile data
      • "Save" stores new data in Firebase
      • Clicking out or canceling the save reloads the previous copy of Redux's profile data

3. Logout

When a user wants to logout, we need to reset the App to its original state (in case someone else wants to use the same device to login)

  1. Logout button is pressed (on ProfileScreen)
  2. Log user out of Firebase
  3. Reset Redux profile state to INITIAL_STATE

Architecture

KNC 2019 is a React Native mobile app built in Expo which utilizes Redux to manage application state.

App updates are triggered by dispatching action creators to Redux reducers which return updated state information to the app. Components read the necessary state from the Redux store and there are no direct API calls in the components' lifecycle methods. Application level state-based props are mapped from the store rather than stored as component state.

Folder Structure

After cloning the GitHub repository, the project directory includes the following folders:

app-kotesol-natcon-2019/
  .expo/
  .vscode/
  actions/
  assets/
  Components/
    navigation/
    screens/
    shared/
      buttons/
      layout/
      text/
    views/
      speaker/
      user/
  middleware/
  reducers/
  store/
  utils/

For future development, I'm planning to restructure some of these folders:

  • to reorganize shared Components
  • to remove unused Components
  • to pull the data files out of utils/ and into a data/ folder

Redux Details

  • middleware
  • actions
  • reducers

Future Development

Version 1.1.1 of this app is available on the Google Play and Apple App Stores. For future KOTESOL conferences, it's just a matter of swapping out the LocationsList.json and SpeakersList.json data files and changing colors to be able to utilize it for different events.

That being said, here's an additional list of further future enhancements that should be updated or built out.

  • Fix MapView bugs in iOS 12.3 to reinstate it into the iOS app
  • Fix Filter menu bug in Android that causes the dropdown to render under screen content
  • Push Notifications for Plenary (or possibly "Liked") sessions
  • ...

Contributing

The best way to Contribute to this app is to open an Issue on GitHub.

Pull Requests are welcome especially if they help fix an Issue or solve a Problem listed in the Future Development section. I want to continue development on this project and make it a viable flashcard app for learning Korean. But I may not be very responsive due to other life obligations.

License

The KNC 2019 app is licensed under the MIT open source license and built with React Native, Expo, and Redux and uses the following third-party resources and node modules:

Troubleshooting

Available Scripts

If Yarn was installed when the project was initialized, then dependencies will have been installed via Yarn, and you should probably use it to run these commands as well. Unlike dependency installation, command running syntax is identical for Yarn and NPM at the time of this writing.

npm start

Runs your app in development mode.

Open it in the Expo app on your phone to view it. It will reload if you save edits to your files, and you will see build errors and logs in the terminal.

Sometimes you may need to reset or clear the React Native packager's cache. To do so, you can pass the --reset-cache flag to the start script:

npm start --reset-cache
# or
yarn start --reset-cache

npm test

Runs the jest test runner on your tests.

npm run ios

Like npm start, but also attempts to open your app in the iOS Simulator if you're on a Mac and have it installed.

npm run android

Like npm start, but also attempts to open your app on a connected Android device or emulator. Requires an installation of Android build tools (see React Native docs for detailed setup). We also recommend installing Genymotion as your Android emulator. Once you've finished setting up the native build environment, there are two options for making the right copy of adb available to Create React Native App:

Using Android Studio's adb
  1. Make sure that you can run adb from your terminal.
  2. Open Genymotion and navigate to Settings -> ADB. Select “Use custom Android SDK tools” and update with your Android SDK directory.
Using Genymotion's adb
  1. Find Genymotion’s copy of adb. On macOS for example, this is normally /Applications/Genymotion.app/Contents/MacOS/tools/.
  2. Add the Genymotion tools directory to your path (instructions for Mac, Linux, and Windows).
  3. Make sure that you can run adb from your terminal.

npm run eject

This will start the process of "ejecting" from Create React Native App's build scripts. You'll be asked a couple of questions about how you'd like to build your project.

Warning: Running eject is a permanent action (aside from whatever version control system you use). An ejected app will require you to have an Xcode and/or Android Studio environment set up.

Networking

If you're unable to load your app on your phone due to a network timeout or a refused connection, a good first step is to verify that your phone and computer are on the same network and that they can reach each other. Create React Native App needs access to ports 19000 and 19001 so ensure that your network and firewall settings allow access from your device to your computer on both of these ports.

Try opening a web browser on your phone and opening the URL that the packager script prints, replacing exp:// with http://. So, for example, if underneath the QR code in your terminal you see:

exp://192.168.0.1:19000

Try opening Safari or Chrome on your phone and loading

http://192.168.0.1:19000

and

http://192.168.0.1:19001

If this works, but you're still unable to load your app by scanning the QR code, please open an issue on the Create React Native App repository with details about these steps and any other error messages you may have received.

If you're not able to load the http URL in your phone's web browser, try using the tethering/mobile hotspot feature on your phone (beware of data usage, though), connecting your computer to that WiFi network, and restarting the packager. If you are using a VPN you may need to disable it.

iOS Simulator won't open

If you're on a Mac, there are a few errors that users sometimes see when attempting to npm run ios:

  • "non-zero exit code: 107"
  • "You may need to install Xcode" but it is already installed
  • and others

There are a few steps you may want to take to troubleshoot these kinds of errors:

  1. Make sure Xcode is installed and open it to accept the license agreement if it prompts you. You can install it from the Mac App Store.
  2. Open Xcode's Preferences, the Locations tab, and make sure that the Command Line Tools menu option is set to something. Sometimes when the CLI tools are first installed by Homebrew this option is left blank, which can prevent Apple utilities from finding the simulator. Make sure to re-run npm/yarn run ios after doing so.
  3. If that doesn't work, open the Simulator, and under the app menu select Reset Contents and Settings.... After that has finished, quit the Simulator, and re-run npm/yarn run ios.

QR Code does not scan

If you're not able to scan the QR code, make sure your phone's camera is focusing correctly, and also make sure that the contrast on the two colors in your terminal is high enough. For example, WebStorm's default themes may not have enough contrast for terminal QR codes to be scannable with the system barcode scanners that the Expo app uses.

If this causes problems for you, you may want to try changing your terminal's color theme to have more contrast, or running Create React Native App from a different terminal. You can also manually enter the URL printed by the packager script in the Expo app's search bar to load it manually.

Changelog

1.1.1 - 2019.05.24

  • Added MySchedule, MyPlaces, and ability to Like presentations and places
  • Fixed rendering styles for iPad device width
  • Initial Release to Apple App store

1.0.1 - 2019.05.23

  • Fixed MapView scrolling and zooming bugs in Android

1.0.0 - 2019.05.22

  • Initial Release to Google Play store

About

Mobile app & conference booklet for the 2019 KOTESOL National Conference.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published