Skip to content

Commit

Permalink
feat: caldav push sync poc
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Steinmetz <[email protected]>
  • Loading branch information
st3iny committed Sep 15, 2024
1 parent 70c292e commit b34d696
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
82 changes: 82 additions & 0 deletions src/services/pushService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { getBaseUrl } from '@nextcloud/router'
import useCalendarsStore from '../store/calendars.js'
import useCalendarObjectsStore from '../store/calendarObjects.js'
import useFetchedTimeRangesStore from '../store/fetchedTimeRanges.js'

import logger from '../utils/logger.js'

function getWsBaseUrl() {
const url = new URL(getBaseUrl())
url.protocol = 'wss:'
return url.toString() + '/php-push'

Check warning on line 11 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L8-L11

Added lines #L8 - L11 were not covered by tests
}

export function registerPushListener(endpoint, action, { onMessage }) {
const serverUrl = getWsBaseUrl() + endpoint
const socket = new WebSocket(serverUrl)

Check warning on line 16 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L14-L16

Added lines #L14 - L16 were not covered by tests

if (onMessage) {
socket.onmessage = (msg) => {
const response = JSON.parse(msg.data)
logger.debug(`Received message on ${endpoint}: action=${response.action}`, {

Check warning on line 21 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L19-L21

Added lines #L19 - L21 were not covered by tests
response,
})

if (response.action !== action) {
return

Check warning on line 26 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L26

Added line #L26 was not covered by tests
}

onMessage(response)

Check warning on line 29 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L29

Added line #L29 was not covered by tests
}
}
}

export function registerSyncListener() {
const calendarsStore = useCalendarsStore()

Check warning on line 35 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L34-L35

Added lines #L34 - L35 were not covered by tests

registerPushListener('/dav', 'sync', {
onMessage: (msg) => {
const { calendarUrl } = msg.data
const calendar = calendarsStore.getCalendarByUrl(calendarUrl)

Check warning on line 40 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L37-L40

Added lines #L37 - L40 were not covered by tests
if (!calendar) {
logger.info(`No such calendar: ${calendarUrl}`)
return

Check warning on line 43 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L42-L43

Added lines #L42 - L43 were not covered by tests
}

logger.info(`Syncing calendar ${calendarUrl} (requested by push)`)
syncCalendar(calendar)

Check warning on line 47 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L46-L47

Added lines #L46 - L47 were not covered by tests
},
})
}

function syncCalendar(calendar) {
const calendarsStore = useCalendarsStore()
const calendarObjectsStore = useCalendarObjectsStore()
const fetchedTimeRangesStore = useFetchedTimeRangesStore()

Check warning on line 55 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L52-L55

Added lines #L52 - L55 were not covered by tests

const existingSyncToken = calendarsStore.getCalendarSyncToken(calendar)

Check warning on line 57 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L57

Added line #L57 was not covered by tests
if (!existingSyncToken && !calendarsStore.getCalendarById(calendar.id)) {
// New calendar!
logger.debug(`Adding new calendar ${calendar.url}`)
this.calendarsStore.addCalendarMutation({ calendar })
return

Check warning on line 62 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L60-L62

Added lines #L60 - L62 were not covered by tests
}

logger.debug(`Refetching calendar ${calendar.url} (syncToken changed)`)
const fetchedTimeRanges = fetchedTimeRangesStore.getAllTimeRangesForCalendar(calendar.id)
for (const timeRange of fetchedTimeRanges) {
fetchedTimeRangesStore.removeTimeRange({

Check warning on line 68 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L65-L68

Added lines #L65 - L68 were not covered by tests
timeRangeId: timeRange.id,
})
calendarsStore.deleteFetchedTimeRangeFromCalendarMutation({

Check warning on line 71 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L71

Added line #L71 was not covered by tests
calendar,
fetchedTimeRangeId: timeRange.id,
})
}

calendarsStore.updateCalendarSyncToken({

Check warning on line 77 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L77

Added line #L77 was not covered by tests
calendar,
syncToken: calendar.dav.syncToken,
})
calendarObjectsStore.modificationCount++

Check warning on line 81 in src/services/pushService.js

View check run for this annotation

Codecov / codecov/patch

src/services/pushService.js#L81

Added line #L81 was not covered by tests
}
3 changes: 3 additions & 0 deletions src/views/Calendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import {
initializeClientForPublicView,
initializeClientForUserView,
} from '../services/caldavService.js'
import { registerSyncListener } from '../services/pushService.js'

// Import others
import { uidToHexColor } from '../utils/color.js'
Expand Down Expand Up @@ -210,6 +211,8 @@ export default {
},
},
created() {
registerSyncListener()

this.backgroundSyncJob = setInterval(async () => {
const currentUserPrincipal = this.principalsStore.getCurrentUserPrincipal
const calendars = (await findAllCalendars())
Expand Down

0 comments on commit b34d696

Please sign in to comment.