Last active
August 24, 2016 23:16
-
-
Save tnightingale/c6c0d9e28544d32456dfdd5f2f439127 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import StateProxy from "./state-proxy"; | |
const {params, dispatch, state} = this.props, | |
{organization, trip} = params; | |
// Proxy objects are light-weight & contain very little of own state. Just a mechanism for | |
// traversing a state tree. | |
// Only StateProxy instance holds reference to state tree. | |
// The idea is it would be created after memoized selectors are run in mapStateToProps() or render(). | |
let stateProxy = new StateProxy(dispatch, state), | |
tripProxy = stateProxy.trip(organization, trip), | |
// Traversing relationship; returns a RecordProxy object. | |
recordProxy = tripProxy.tripDetail(); | |
console.log(tripProxy.data(), recordProxy.data()); | |
for (tripProxy of stateProxy.trips(organization)) { | |
console.log(tripProxy.data(), tripProxy.tripDetail().data()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {saveRecord} from "./actions/r_record"; | |
export default class RecordsProxy { | |
constructor(state, organization) { | |
this._state = state; | |
this._organization = organization; | |
} | |
dispatch(action) { | |
return this._state.dispatch(action); | |
} | |
record(id) { | |
return new RecordProxy(this, id); | |
} | |
data(id) { | |
const data = this._state.recordsData().getIn([this._organization, id]); | |
if (!data) { | |
throw new Error(`Missing record ${this._id} in ${this._organization} organization.`); | |
} | |
return data; | |
} | |
save(data) { | |
return this.dispatch(saveRecord(this._organization, data)); | |
} | |
} | |
class RecordProxy { | |
constructor(records, id) { | |
this._records = records; | |
this._id = id; | |
} | |
data() { | |
return this._records.data(this._id); | |
} | |
save(data) { | |
return this._records.save(data); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {idFromParam} from "./util"; | |
import TripsProxy from "./trip-proxy"; | |
import RecordsProxy from "./record-proxy"; | |
export default class StateProxy { | |
constructor(dispatch, {records, trips, docsSyncStatus}) { | |
this._dispatch = dispatch; | |
this._records = records; | |
this._trips = trips; | |
this._docsSyncStatus = docsSyncStatus; | |
} | |
dispatch(action) { | |
return this._dispatch(action); | |
} | |
recordsData() { | |
return this._records; | |
} | |
tripsData() { | |
return this._trips; | |
} | |
records(organization) { | |
return new RecordsProxy(this, organization); | |
} | |
record(organization, id) { | |
return this.records(organization).record(id); | |
} | |
trips(organization) { | |
return new TripsProxy(this, organization); | |
} | |
trip(organization, id) { | |
return this.trips(organization).trip(id); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {saveTrip} from "./actions/trips"; | |
export default class TripsProxy { | |
constructor(state, organization) { | |
this._state = state; | |
this._organization = organization; | |
} | |
dispatch(action) { | |
return this._state.dispatch(action); | |
} | |
trip(id) { | |
return new TripProxy(this, id); | |
} | |
data(id) { | |
const data = this._state.tripsData().getIn([this._organization, id]); | |
if (!data) { | |
throw new Error(`Missing trip ${id} in ${this._organization} organization.`); | |
} | |
return data; | |
} | |
save(data) { | |
return this.dispatch(saveTrip(this._organization, data)); | |
} | |
tripDetail(id) { | |
const data = this.data(id), | |
tripDetailId = data.get('tripDetailId'); | |
return this._state.record(this._organization, tripDetailId); | |
} | |
[Symbol.iterator]() { | |
const data = this._state.tripsData(), | |
iterator = data.get(this._organization).values(); | |
return { | |
next: () => { | |
const {done, value: trip} = iterator.next(), | |
next = {done, value: undefined}; | |
if (trip) next.value = this.trip(trip.get('_id')); | |
return next; | |
} | |
}; | |
} | |
} | |
class TripProxy { | |
constructor(trips, id) { | |
this._trips = trips; | |
this._id = id; | |
} | |
data() { | |
return this._trips.data(this._id); | |
} | |
tripDetail() { | |
return this._trips.tripDetail(this._id); | |
} | |
save(data) { | |
return this.save(data); | |
} | |
async startTrip() { | |
const data = this.data(); | |
try { | |
await this.toggleTrackingEnabled(true); | |
this.save(data.merge({ | |
start: (new Date()).toISOString(), | |
active: true | |
})); | |
} catch (error) { | |
console.warn("There was a problem enabling background location tracking. This should be handled in an action so that the error can be correctly routed."); | |
} | |
} | |
async completeTrip() { | |
const data = this.data(); | |
try { | |
await this.toggleTrackingEnabled(false); | |
this.save(data.merge({ | |
end: (new Date()).toISOString(), | |
active: false | |
})); | |
} catch (error) { | |
console.warn("There was a problem disabling background location tracking. This should be handled in an action so that the error can be correctly routed."); | |
} | |
} | |
async toggleTrip() { | |
const data = this.data(), | |
active = data.get('active', false); | |
try { | |
await this.toggleTrackingEnabled(!active); | |
this.save(data.set('active', !active)); | |
} catch (error) { | |
console.warn("There was a problem toggling background location tracking. This should be handled in an action so that the error can be correctly routed."); | |
} | |
} | |
toggleTrackingEnabled(enable) { | |
return new Promise((resolve, reject) => { | |
const success = () => { | |
console.log(enable ? "Enabled!" : "Disabled"); | |
resolve(); | |
}, | |
error = (errorMessage) => { | |
console.warn("Could not toggle tracking:", errorMessage); | |
reject(errorMessage); | |
}; | |
if (!window.BackgroundGeolocation) { | |
console.warn("window.BackgroundGeolocation is undefined. Tracking enabled: ", enable); | |
return success(); | |
} | |
if (enable) { | |
window.BackgroundGeolocation.start(success, error); | |
} else { | |
window.BackgroundGeolocation.stop(success, error); | |
} | |
}); | |
} | |
submit() { | |
const data = this.data(), | |
tripDetail = this.tripDetail(); | |
// TODO: This should be wrapped up in a submit() method on RecordProxy. | |
const record = tripDetail.data(), | |
submitted = (new Date()).toISOString(); | |
tripDetail.save(record.set('submitted', submitted)); | |
this.save(data.set('submitted', submitted)); | |
} | |
delete() { | |
const data = this.data(), | |
tripDetail = this.tripDetail(); | |
// tripId = trip.get('_id'), | |
// tripDetail = tripDetails.get(tripId); | |
// TODO: This should be wrapped up in a delete() method on RecordProxy. | |
const record = tripDetail.data(); | |
if (record) { | |
tripDetail.save(record.set('_deleted', true)); | |
} else { | |
console.warn(`Missing trip details record for trip: ${this._id}.`); | |
} | |
this.save(data.set('_deleted', true)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment