use shared composable for subscription (#6390)

Refactor global composable to use useSharedComposable.

- Makes it obvious that subscription status is shared globally across
all components, rather than relying on implicit module-level refs
- Eliminates manual `isWatchSetup` flag and conditional watch setup
logic that was needed to prevent duplicate watchers
- Uses well-established VueUse pattern that other developers will
immediately recognize and understand

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6390-use-shared-composable-for-subscription-29c6d73d36508185a5c2e0b467549432)
by [Unito](https://www.unito.io)
This commit is contained in:
Christian Byrne
2025-10-29 20:08:33 -07:00
committed by GitHub
parent 09143c05c1
commit 331372df44

View File

@@ -1,4 +1,5 @@
import { computed, ref, watch } from 'vue'
import { createSharedComposable } from '@vueuse/core'
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
@@ -25,17 +26,14 @@ type CloudSubscriptionStatusResponse = {
end_date?: string | null
}
const subscriptionStatus = ref<CloudSubscriptionStatusResponse | null>(null)
function useSubscriptionInternal() {
const subscriptionStatus = ref<CloudSubscriptionStatusResponse | null>(null)
const isSubscribedOrIsNotCloud = computed(() => {
if (!isCloud || !window.__CONFIG__?.subscription_required) return true
const isSubscribedOrIsNotCloud = computed(() => {
if (!isCloud || !window.__CONFIG__?.subscription_required) return true
return subscriptionStatus.value?.is_active ?? false
})
let isWatchSetup = false
export function useSubscription() {
return subscriptionStatus.value?.is_active ?? false
})
const { reportError, accessBillingPortal } = useFirebaseAuthActions()
const dialogService = useDialogService()
@@ -161,20 +159,17 @@ export function useSubscription() {
return statusData
}
if (!isWatchSetup) {
isWatchSetup = true
watch(
() => isLoggedIn.value,
async (loggedIn) => {
if (loggedIn) {
await fetchSubscriptionStatus()
} else {
subscriptionStatus.value = null
}
},
{ immediate: true }
)
}
watch(
() => isLoggedIn.value,
async (loggedIn) => {
if (loggedIn) {
await fetchSubscriptionStatus()
} else {
subscriptionStatus.value = null
}
},
{ immediate: true }
)
const initiateSubscriptionCheckout =
async (): Promise<CloudSubscriptionCheckoutResponse> => {
@@ -227,3 +222,5 @@ export function useSubscription() {
handleInvoiceHistory
}
}
export const useSubscription = createSharedComposable(useSubscriptionInternal)