Skip to content

Instantly share code, notes, and snippets.

@tim-rohrer
Last active May 10, 2020 01:55
Show Gist options
  • Save tim-rohrer/ae7d663932310dd8d9a77e6765280b0d to your computer and use it in GitHub Desktop.
Save tim-rohrer/ae7d663932310dd8d9a77e6765280b0d to your computer and use it in GitHub Desktop.
import { AppThunk } from "../configureStore"
import { RootState } from "./reducer"
// appStatus.js
const GOOGLE = "google"
const MAPBOX = "mapbox"
// App Status Actions
export const APP_IS_LOADED = 'mapping/app/isLoaded'
export const APP_IS_THINKING = 'mapping/app/appIsThinking'
export const APP_IS_NOT_THINKING = 'mapping/app/appIsNotThinking'
export const APP_MAPPING_SVC_AVAIL = 'mapping/app/mappingSvcAvailable'
export const APP_SELECTED_MAPPING_SERVICE_CHANGED = 'mapping/app/selectedMappingServiceChanged'
export const APP_MAPPING_SVC_RQST_INPROGRESS = 'mapping/app/mappingServiceRequestInProgress'
// Set up
export type MappingService = typeof GOOGLE | typeof MAPBOX
/** Our slice for tracking the status relevent for the App itself
* @typedef {Object} AppStatus - Slice for tracking relevant App status
* @property {boolean} appThinking - If App is thinking...or ready for use
*/
export type AppStatus = {
appThinking: boolean,
loaded: boolean,
mappingResources: {
google: boolean,
mapbox: boolean
},
appMappingService: MappingService,
mappingServiceRequestInProgress: boolean
}
// Initial State
export const initialState : AppStatus = {
appThinking: false,
loaded: false,
mappingResources: {
google: false,
mapbox: false
},
appMappingService: GOOGLE,
mappingServiceRequestInProgress: false
}
interface AppIsThinkingAction {
type: typeof APP_IS_THINKING
}
interface AppIsNotThinkingAction {
type: typeof APP_IS_NOT_THINKING
}
interface AppIsLoadedAction {
type: typeof APP_IS_LOADED
}
interface MappingServicesAvailableAction {
type: typeof APP_MAPPING_SVC_AVAIL,
payload: {
service: MappingService,
isAvailable: boolean
}
}
interface MappingServiceRequestInProgressAction {
type: typeof APP_MAPPING_SVC_RQST_INPROGRESS,
payload: boolean
}
export type AppStatusTypes =
| AppIsThinkingAction
| AppIsNotThinkingAction
| AppIsLoadedAction
| MappingServicesAvailableAction
| MappingServiceRequestInProgressAction
// Action Creators
export const appIsThinking = () : AppStatusTypes => {
return { type: APP_IS_THINKING }
}
export const appIsNotThinking = () : AppStatusTypes => {
return { type: APP_IS_NOT_THINKING }
}
export function appIsLoaded() : AppStatusTypes {
return { type: APP_IS_LOADED }
}
export const mappingServiceIsAvailable = (mappingService: MappingService, available: boolean) : AppStatusTypes => {
return { type: APP_MAPPING_SVC_AVAIL, payload: { service: mappingService, isAvailable: available }}
}
export function mappingServiceRequestInProgress(value: boolean) : AppStatusTypes {
return { type: APP_MAPPING_SVC_RQST_INPROGRESS, payload: value}
}
// export const mappingServiceSelected = (newMappingService: MappingService) : AppStatusTypes => {
// return {type: APP_SELECTED_MAPPING_SERVICE_CHANGED, payload: newMappingService}
// }
// // Thunks
// export const loadAppForUse = () => (dispatch: any) => {
// }
// export const mappingServiceRequested = (newMappingService: MappingService) : AppThunk => (dispatch, getState) => {
// let currentMappingService = getState().appStatus.appMappingService
// debugger
// if (newMappingService !== currentMappingService) {
// dispatch(mappingServiceSelected(newMappingService))
// }
// }
export const mappingServiceSetupRequested = (mappingService: MappingService) : AppThunk => (dispatch, getState) => {
let mappingServicesStatus = getState().appStatus.mappingResources
if (!mappingServicesStatus[mappingService]) {
if (mappingService === GOOGLE) {
dispatch(googleMappingRequested())
} else debugger
}
}
export const googleMappingRequested = () : AppThunk => (dispatch) => {
dispatch(mappingServiceRequestInProgress(true))
const onLoad = () => {
dispatch(mappingServiceIsAvailable(GOOGLE, true))
dispatch(mappingServiceRequestInProgress(false))
}
if (!window.google) {
const script = document.createElement('script')
script.type="text/javascript"
script.src =
"https://maps.googleapis.com/maps/api/js?key=" +
process.env.REACT_APP_GOOGLE_KEY + "&libraries=places,geometry"
const headScript: HTMLScriptElement | null = document.getElementsByTagName('script')[0]
if (headScript.parentNode != null) {
headScript.parentNode.insertBefore(script, headScript)
script.addEventListener('load', onLoad)
} else debugger
return () => script.removeEventListener('load', onLoad)
} else {
console.log("We shouldn't be here!")
}
}
// export const mapboxMappingRequested = () => (dispatch) => {
// alert("Setting up Mapbox")
// }
// Reducer
export const appStatusReducer = (
state: AppStatus = initialState,
action: AppStatusTypes
) : AppStatus => {
switch (action.type) {
case APP_IS_THINKING:
return {
...state,
appThinking: true
}
case APP_IS_NOT_THINKING:
return {
...state,
appThinking: false
}
case APP_IS_LOADED:
return {
...state,
loaded: true
}
case APP_MAPPING_SVC_AVAIL:
return {
...state,
mappingResources: {
...state.mappingResources,
[action.payload.service]: action.payload.isAvailable
}
}
case APP_MAPPING_SVC_RQST_INPROGRESS:
return {
...state,
mappingServiceRequestInProgress: action.payload
}
// case APP_SELECTED_MAPPING_SERVICE_CHANGED:
// return {
// ...state,
// appMappingService: action.newMappingService
// }
default:
return state
}
}
// Selectors
export const mappingServiceSelector = (state: RootState) => state.appStatus.appMappingService
export const mappingServiceResourceStatusSelector = ((state: RootState) => state.appStatus.mappingServiceRequestInProgress)
export const mappingResourcesSelector = ((state: RootState) => state.appStatus.mappingResources) // Gets the object of supported mapping resources
export const appIsLoadedSelector = ((state: RootState) => state.appStatus.loaded)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment