Skip to content

Commit

Permalink
Check for new and updated non-public calendars
Browse files Browse the repository at this point in the history
* Add new calendars to the list as they show up.
* Reload non-public calendars if they are updated on the server.

Fixes #31.

This works but it is not an optimal solution:
* If a calendar changes it reloads the current view
  no matter wether anyting in the view changed or not.
* If a calendar changes it drops all cached events
  even if they did not change.
* If an event is added to the calendar or moved
  this calendar will also be reloaded because the new event
  changed the syncToken on the server.
* If a calendar changed
  it will be added to the bottom of the list of calendars.

I would be fine with most of these but the last one needs to be fixed.

Signed-off-by: Azul <[email protected]>
  • Loading branch information
azul committed Feb 26, 2021
1 parent a8a5112 commit a1a7333
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 22 deletions.
79 changes: 59 additions & 20 deletions src/store/calendars.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,32 @@ const actions = {
return state.calendars
},

async syncCalendars({ getters, dispatch }) {
const calendars = await dispatch('getNewAndUpdatedCalendars')
calendars.forEach(calendar => dispatch('updateCalendar', { calendar }))
},

/**
* Fetch calendars from the server and return the new ones and
* those that have changed compared to those currently in state.
*
* @param {Object} context the store mutations
* @returns {Promise<Array>} the calendars
*/
async getNewAndUpdatedCalendars({ commit, state, getters }) {
const calendars = await findAllCalendars()
const principal = getters.getCurrentUserPrincipal
return calendars
.map((calendar) => mapDavCollectionToCalendar(calendar, principal))
.filter(retrieved => {
const stored = getters.getCalendarById(retrieved.id)
const updated = stored && (stored.dav.syncToken !== retrieved.dav.syncToken)
return !stored || updated
})
},

/**
* Retrieve and commit public calendars by token
*
* @param {Object} vuex The destructuring object for vuex
* @param {Function} vuex.commit The Vuex commit function
Expand All @@ -480,11 +505,9 @@ const actions = {
return calendarObjects
},

async syncCalendars({ getters, dispatch }, { tokens }) {
async syncPublicCalendars({ getters, dispatch }, { tokens }) {
const updated = await dispatch('getUpdatedPublicCalendars', { tokens })
updated.forEach(calendar => {
dispatch('updateCalendar', { calendar })
})
updated.forEach(calendar => dispatch('updateCalendar', { calendar }))
},

/**
Expand Down Expand Up @@ -613,26 +636,42 @@ const actions = {
*
* @param {Object} vuex The destructuring object for vuex
* @param {Function} vuex.commit The Vuex commit function
* @param {Object} vuex.getters The Vuex getters Object
* @param {Object} context the store mutations Current context
* @param {Object} vuex.dispatch The Vuex dispatch
* @param {Object} data destructuring object
* @param {Object} data.calendar the calendar to delete
* @returns {Promise}
*/
async updateCalendar({ commit, getters }, { calendar }) {
commit('markCalendarAsLoading', { calendar })
getters.getAllTimeRangesForCalendar(calendar.id)
.forEach(timeRange => {
commit('removeTimeRange', { timeRangeId: timeRange.id })
})
getters.getAllCalendarObjectsForCalendar(calendar.id)
.forEach(id => {
const calendarObject = { id }
commit('deleteCalendarObject', { calendarObject })
})
commit('deleteCalendar', { calendar })
updateCalendar({ commit, dispatch }, { calendar }) {
dispatch('cleanupCalendar', calendar)
commit('addCalendar', { calendar })
commit('markCalendarAsNotLoading', { calendar })
},

/**
* Cleanup a calendar if it exists
*
* Remove the calendar from the current state including
* all cached data (TimeRanges and calendarObjects).
*
* @param {Object} vuex The destructuring object for vuex
* @param {Function} vuex.commit The Vuex commit function
* @param {Object} vuex.dispatch The Vuex dispatch
* @param {Object} calendar destructuring object
* @param {Object} calendar.id the id of the calendar to delete
*/
cleanupCalendar({ commit, getters }, { id }) {
const calendar = getters.getCalendarById(id)
if (calendar) {
commit('markCalendarAsLoading', { calendar })
getters.getAllTimeRangesForCalendar(calendar.id)
.forEach(timeRange => {
commit('removeTimeRange', { timeRangeId: timeRange.id })
})
getters.getAllCalendarObjectsForCalendar(calendar.id)
.forEach(id => {
const calendarObject = { id }
commit('deleteCalendarObject', { calendarObject })
})
commit('deleteCalendar', { calendar })
}
},

/**
Expand Down
8 changes: 6 additions & 2 deletions src/views/Calendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,12 @@ export default {
}
}, 1000 * 60)
this.checkForUpdatesJob = setInterval(async() => {
const tokens = this.$route.params.tokens.split('-')
await this.$store.dispatch('syncCalendars', { tokens })
if (this.$route.name.startsWith('Public') || this.$route.name.startsWith('Embed')) {
const tokens = this.$route.params.tokens.split('-')
await this.$store.dispatch('syncPublicCalendars', { tokens })
} else {
await this.$store.dispatch('syncCalendars')
}
}, 1000 * 20)
},
Expand Down

0 comments on commit a1a7333

Please sign in to comment.