Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/oca.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import './css/contacts.scss'
// Dialogs css
import '@nextcloud/dialogs/style.css'

const pinia = createPinia()

declare global {
interface Window {
OCA: {
Expand Down Expand Up @@ -42,7 +44,6 @@ window.OCA.Contacts = {
contactEmailAddress,
})

const pinia = createPinia()
app.use(pinia)
app.use(store)

Expand Down
44 changes: 44 additions & 0 deletions src/store/readOnlyContactDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { defineStore } from 'pinia'
import client from '../services/cdav.js'
import store from './index.js'
import usePrincipalsStore from './principals.js'

export default defineStore('readOnlyContactDetails', {
state: () => ({
promise: null,
fetched: false,
}),

actions: {
async init() {
if (this.fetched) {
return Promise.resolve()
}

if (this.promise) {
return this.promise
}

this.promise = (async () => {
await client.connect({ enableCardDAV: true })
Copy link
Contributor Author

@kesselb kesselb Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn’t exactly what Richard suggested, but I dropped that approach because I couldn’t get it to work. In hindsight, I think the idea itself was fine, but I realized too late that the Vuex store was already shared between components, while the Pinia instances were not. Since I created a new Pinia store for it, that was probably the issue I was running into.

const principalsStore = usePrincipalsStore()
principalsStore.setCurrentUserPrincipal(client)
await store.dispatch('getAddressbooks')
})()

try {
await this.promise
this.fetched = true
} finally {
this.promise = null
}

return this.promise
},
},
})
11 changes: 4 additions & 7 deletions src/views/ReadOnlyContactDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ import ContactDetailsProperty from '../components/ContactDetails/ContactDetailsP
import IsMobileMixin from '../mixins/IsMobileMixin.ts'
import Contact from '../models/contact.js'
import rfcProps from '../models/rfcProps.js'
import client from '../services/cdav.js'
import validate from '../services/validate.js'
import usePrincipalsStore from '../store/principals.js'
import useReadOnlyContactDetailsStore from '../store/readOnlyContactDetails.ts'

const { profileEnabled } = loadState('user_status', 'profileEnabled', false)

Expand Down Expand Up @@ -211,11 +210,9 @@ export default {
},

async beforeMount() {
// Init client and stores
await client.connect({ enableCardDAV: true })
const principalsStore = usePrincipalsStore()
principalsStore.setCurrentUserPrincipal(client)
await this.$store.dispatch('getAddressbooks')
// Init store
const store = useReadOnlyContactDetailsStore()
await store.init()

// Fetch contact
await this.fetchContact()
Expand Down
Loading