Last active
April 25, 2018 15:27
-
-
Save mattduggan/847aa249750341d3ce8819e55bbc8805 to your computer and use it in GitHub Desktop.
Activity Notifications
This file contains hidden or 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
const ACTIVITY_INTERACTION = "ACTIVITY_INTERACTION"; | |
// defined action to change AITs | |
function createActivityInteraction(interactionTime) { | |
return { type: ACTIVITY_INTERACTION, payload: { interactionTime } }; | |
} | |
// define initial state of AITs | |
const INITIAL_STATE = { | |
previousInteraction: localstorage.getItem("[email protected]_interaction") || new Date(0).getTime(); // last time or epoch | |
currentInteraction: new Date().getTime() | |
} | |
// define epic (middleware) to handle the side effect of calculating NN from service response and store | |
// then pushing it over a channel | |
function activityEpic(action, store) { | |
action.ofType(GET_ACTIVITIES) | |
.switchMap(() => getActivities() | |
.map(data => { | |
getActivitiesSuccess(data); | |
// determine net new | |
const netNew = Object.values(store.activity.activities) | |
.reduce((sum, activity) => { | |
return activity.event_happened_at > store.previousInteraction; | |
}, 0); | |
// push NN | |
chrome.runtime.sendMessage("id", { type: NET_NEW, payload: netNew }); | |
}) | |
.catch(response => getActivitiesError(response.status)) | |
); | |
} | |
// define case to handle AIT state changes from new action | |
// essentially, current -> previous, new -> current | |
function activityReducer(state = INITIAL_STATE, action) { | |
switch(action.type) { | |
case ACTIVITY_INTERACTION: | |
return { | |
previousInteraction: state.currentInteraction, | |
currentInteraction: action.payload.interactionTime | |
}; | |
default: | |
return state; | |
} | |
} | |
// the view should subscribe to the AIT previous state to determine if they should show the indicator | |
class ContainerView { | |
@select(["activity", "activities"]); | |
readonly activities$: Observable<Array<IActivity>>; | |
@select(["activity", "previousInteraction"]) | |
readonly previousInteraction$: Observable<String>; | |
ngOnInit() { | |
// trigger action to get activities | |
activityActions.getActivities(); | |
// trigger action to set AIT when the user focuses on the window | |
window.addEventListener("focus", (event) => { | |
const currentInteraction = new Date().getTime(); | |
localStorage.setItem("[email protected]_interaction", currentInteraction)); | |
dispatch(createActivityInteraction(currentInteraction)); | |
}); | |
// for other documents which may have loaded the activity app to keep them in sync | |
// does not fire on the current document | |
window.addEventListener("storage", (event) => { | |
if (event.key === "[email protected]_interaction") { | |
dispatch(createActivityInteraction(event.newValue)); | |
} | |
}); | |
} | |
} | |
class PresentationView { | |
@Input() interactionTime: string; | |
@Input() activity: IActivity; | |
public isNetNew: boolean = false; | |
// listen for when the interaction time changes | |
ngOnChanges(changes) { | |
// net new if the activity happened sooner than the previous interaction | |
this.isNetNew = this.activity.event_happened_at > changes.interactionTime; | |
} | |
} | |
` | |
<container-view> | |
<presentation-view | |
*ngFor="let activity of activities$ | async" | |
[activity]="activity" | |
[interactionTime]="previousInteraction$"></presentation-view> | |
</container-view> | |
` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment