Skip to content

yonureker/Bart-X

Repository files navigation

Bart X

BartX is a mobile app that displays real-time BART departures with the data received from BART API.

iPhone Screenshots

Station List Real Time Departures Map View System Alerts
Image Image Image Image

Android Screenshots

Station List Real Time Departures Map View System Alerts
Image Image Image Image

Technologies:

Functionality

Redux

The combination of Redux + React Navigation makes things very easy. Rather than passing params around with () => props.navigation.navigate('MyScreen', params: {}), using useSelector hook is a great way to pull whatever is needed from state.

User location and search bar related data are saved in Redux store.

import { combineReducers } from "redux";
import userLocationReducer from "./userLocationReducer";
import searchBarReducer from "./searchBarReducer";

const rootReducer = combineReducers({
  userLocation: userLocationReducer,
  searchBar: searchBarReducer
});

export default rootReducer;

Navigation

Using React Navigation for the first time, it was challenging to combine multiple navigations; but I am happy with the final product. The bottom navigator is setup in App.js file:

const TabNavigator = createBottomTabNavigator(
  {
    "Station List": {
      screen: AllStationsScreen,
      navigationOptions: {
        //...
      }
    },
    "Live Map": {
      screen: LiveMapScreen,
      navigationOptions: {
        //...
      }
    },
    "System Map": {
      screen: SystemScreen,
      navigationOptions: {
        //...
      }
    },
    "About": {
      screen: AboutScreen,
      navigationOptions: {
        //...
      }
    }
  },
  {
    initialRouteName: "Station List"
  }
);

const AppContainer = createAppContainer(TabNavigator);

The app also has a stack navigator to display train details screen after pressing on a station from the list:

const AllStationsScreen = createStackNavigator(
  {
    StationList: StationListScreen,
    StationDetails: StationDetailsScreen
  },
  {
    initialRouteName: "StationList"
  }
);

System Map Tab features a top tab navigator for weekday vs. weekend maps:

const SystemMapNavigator = createMaterialTopTabNavigator(
  {
    "Weekday & Saturday": {
      screen: WeekAndSatScreen,
      navigationOptions: {
        swipeEnabled: false
      }
    },
    Sunday: {
      screen: SundayScreen,
      navigationOptions: {
        swipeEnabled: false
      }
    }
  },
  {
    tabBarComponent: SafeAreaMaterialTopTabBar
  }
);

User Location

  • The app asks for user permission to track their location. The location is then dispatched to Redux store to be used for the calculation of closest stations and centering the map view around the coordinates.
const getLocation = async () => {
    let { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status !== "granted") {
      dispatch({
        type: "RECEIVE_USER_LOCATION",
        payload: { coords: { latitude: 37.792874, longitude: -122.39703 } }
      });
    }

    let location = await Location.getCurrentPositionAsync({
      accuracy: Location.Accuracy.High
    });

    dispatch({
      type: "RECEIVE_USER_LOCATION",
      payload: location
    });
  };

Real Time BART data

  • Receiving the real time data is done by a simple fetch function. The response is then dispatched to Redux store.
const fetchTrainDepartures = () => {
    // setStationList(responseJson.root.station);
    // setLastUpdate(responseJson.root.time);)
    // call BART API
    fetch(
      "http://api.bart.gov/api/etd.aspx?cmd=etd&orig=ALL&key=MW9S-E7SL-26DU-VV8V&json=y"
    )
      .then(response => response.json())
      .then(responseJson =>
        dispatch({
          type: "RECEIVE_TRAIN_DEPARTURE_DATA",
          payload: responseJson.root.station
        })
      )
      .catch(error => {
        console.log(error);
      });
  };

The app receives new data every 5 seconds.

useEffect(() => {
    const intervalId = setInterval(fetchTrainDepartures, 5000);
    return () => clearInterval(intervalId);
  });

Closest Stations

After receiving user location and station locations and dispatching them to redux store; the calculation is done with the help of geolib library.

const calculateDistance = () => {
    // const userLocation = useSelector(state => state.userLocation);
    // const stations = useSelector(state => state.stationLocations);
    return stations.map(station => {
      return {
        ...station,
        distance: convertDistance(
          getDistance(
            {
              latitude: station.gtfs_latitude,
              longitude: station.gtfs_longitude
            },
            {
              latitude: String(userLocation.coords.latitude),
              longitude: String(userLocation.coords.longitude)
            }
          ),
          "mi"
        )
      };
    });
  };

Author

Built with ❤️ by Onur Eker - 2019.

About

A mobile app that shows real-time departure data of BART stations. Written in React Native.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published