Skip to content

Commit

Permalink
Check for updates and update public calendars
Browse files Browse the repository at this point in the history
Fetch the open calendars every 20 seconds
and check if they have changed since they were loaded.

If a calendar changed remove all it's data from the store
and thereby effectively trigger a reload.

This is a fairly brute force approach as it drops all known data
rather than fetching only the data that changed via the caldav sync API.

However Caldav sync is yet to be implemented. (nextcloud/cdav-library#9)
So this serves as a workaround for the time being.

See #31.

Signed-off-by: Azul <[email protected]>
  • Loading branch information
azul committed Feb 26, 2021
1 parent 85f82bd commit f52f6e5
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
68 changes: 68 additions & 0 deletions src/store/calendars.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,17 @@ const getters = {
return true
})
},

/**
* Gets all calendarObjects for a given calendar.
*
* @param {Object} state the store data
* @param {String} calendarId the id of the calendar
* @returns {function({String}): {Object}}
*/
getAllCalendarObjectsForCalendar: (state) => (calendarId) =>
state.calendarsById[calendarId].calendarObjects
,
}

const actions = {
Expand Down Expand Up @@ -469,6 +480,32 @@ const actions = {
return calendarObjects
},

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

/**
* Fetch all public calendars from the server and return those
* that have changed compared to those currently in state.
*
* @param {Object} vuex The destructuring object for vuex
* @param {Object} vuex.getters The Vuex getters Object
* @param {Object} data The data destructuring object
* @param {String[]} data.tokens The tokens to load
* @returns {Promise<Object[]>}
*/
async getUpdatedPublicCalendars({ getters }, { tokens }) {
const calendars = await findPublicCalendarsByTokens(tokens)
return calendars.map(mapDavCollectionToCalendar)
.filter(retrieved => {
const stored = getters.getCalendarById(retrieved.id)
return (stored.dav.syncToken !== retrieved.dav.syncToken)
})
},

/**
* Append a new calendar to array of existing calendars
*
Expand Down Expand Up @@ -567,6 +604,37 @@ const actions = {
context.commit('renameCalendar', { calendar, newName })
},

/**
* Update a calendar to a new state as fetched from the server
*
* This will primarily update the syncToken of the calendar
* and clear all cached data so that the calendar effectively
* reloads.
*
* @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} 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 })
commit('addCalendar', { calendar })
commit('markCalendarAsNotLoading', { calendar })
},

/**
* Change a calendar's color
*
Expand Down
4 changes: 2 additions & 2 deletions src/store/fetchedTimeRanges.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const mutations = {
},

/**
* Adds a calendar-object-id to all time-ranges of a given caloendar
* Adds a calendar-object-id to all time-ranges of a given calendar
*
* @param {Object} state The vuex state
* @param {Object} data The destructuring object
Expand All @@ -171,7 +171,7 @@ const mutations = {
},

/**
* Removes a calendar-object-id to all time-ranges of a given caloendar
* Removes a calendar-object-id from all time-ranges of a given calendar
*
* @param {Object} state The vuex state
* @param {Object} data The destructuring object
Expand Down
10 changes: 10 additions & 0 deletions src/views/Calendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default {
updateTodayJob: null,
updateTodayJobPreviousDate: null,
showEmptyCalendarScreen: false,
checkForUpdatesJob: null,
}
},
computed: {
Expand Down Expand Up @@ -183,6 +184,15 @@ export default {
})
}
}, 1000 * 60)
this.checkForUpdatesJob = setInterval(async() => {
const tokens = this.$route.params.tokens.split('-')
await this.$store.dispatch('syncCalendars', { tokens })
}, 1000 * 20)
},
destroy() {
clearInterval(this.timeFrameCacheExpiryJob)
clearInterval(this.checkForUpdatesJob)
},
async beforeMount() {
this.$store.commit('loadSettingsFromServer', {
Expand Down

0 comments on commit f52f6e5

Please sign in to comment.