Skip to content

Commit

Permalink
Composables: Add dialog queue composable
Browse files Browse the repository at this point in the history
Signed-off-by: Arturo Manzoli <arturomanzoli@gmail.com>
  • Loading branch information
ArturoManzoli committed Feb 18, 2025
1 parent 0349e2a commit 7a381f4
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,11 @@
</v-main>
</v-app>
<About v-if="showAboutDialog" @update:show-about-dialog="showAboutDialog = $event" />
<Tutorial v-if="interfaceStore.isTutorialVisible" />
<VideoLibraryModal v-if="interfaceStore.isVideoLibraryVisible" />
<VehicleDiscoveryDialog v-model="showDiscoveryDialog" show-auto-search-option />
<UpdateNotification v-if="isElectron()" />
<Tutorial :model-value="interfaceStore.isTutorialVisible" />
<div v-if="WrappedDialog">
<component :is="WrappedDialog" />
</div>
<SnackbarContainer />
</template>

Expand All @@ -336,6 +337,7 @@ import Tutorial from '@/components/Tutorial.vue'
import UpdateNotification from '@/components/UpdateNotification.vue'
import VehicleDiscoveryDialog from '@/components/VehicleDiscoveryDialog.vue'
import VideoLibraryModal from '@/components/VideoLibraryModal.vue'
import { useDialogQueue } from '@/composables/dialogQueue'
import { useInteractionDialog } from '@/composables/interactionDialog'
import {
availableCockpitActions,
Expand Down Expand Up @@ -366,6 +368,8 @@ import ConfigurationUIView from './views/ConfigurationUIView.vue'
import ConfigurationVideoView from './views/ConfigurationVideoView.vue'
import ToolsDataLakeView from './views/ToolsDataLakeView.vue'
import ToolsMAVLinkView from './views/ToolsMAVLinkView.vue'
const { enqueueDialog, WrappedDialog } = useDialogQueue()
const { showDialog, closeDialog } = useInteractionDialog()
const { openSnackbar } = useSnackbar()
Expand Down Expand Up @@ -760,23 +764,27 @@ onBeforeUnmount(() => {
const currentTopBarHeightPixels = computed(() => `${widgetStore.currentTopBarHeightPixels}px`)
const currentBottomBarHeightPixels = computed(() => `${widgetStore.currentBottomBarHeightPixels}px`)
const showDiscoveryDialog = ref(false)
const preventAutoSearch = useStorage('cockpit-prevent-auto-vehicle-discovery-dialog', false)
onMounted(() => {
if (isElectron() && !preventAutoSearch.value) {
if (!interfaceStore.userHasSeenTutorial) {
enqueueDialog({
component: Tutorial,
})
}
if (isElectron()) {
enqueueDialog({
component: UpdateNotification,
})
// Wait 5 seconds to check if we're connected to a vehicle
setTimeout(() => {
if (vehicleStore.isVehicleOnline) return
showDiscoveryDialog.value = true
if (vehicleStore.isVehicleOnline || preventAutoSearch.value) return
enqueueDialog({
component: VehicleDiscoveryDialog,
props: { showAutoSearchOption: true },
})
}, 5000)
}
if (!interfaceStore.userHasSeenTutorial) {
setTimeout(() => {
interfaceStore.isTutorialVisible = true
}, 6000)
}
})
</script>

Expand Down
96 changes: 96 additions & 0 deletions src/composables/dialogQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Component, computed, defineComponent, h, Ref, ref } from 'vue'

/**
* Queued component to be displayed. Usually a dialog.
*/
export interface QueuedDialog {
/**
* The component reference (e.g. Tutorial or VehicleDiscoveryDialog)
*/
component: Component
/**
* Optional props to pass into the component
*/
props?: Record<string, unknown>
}

/**
* Component queue to manage the order of components to be displayed.
*/
export interface DialogQueue {
/**
* Enqueue a dialog to be displayed.
*/
enqueueDialog: (item: QueuedDialog) => void
/**
* Clear the queue.
*/
clear: () => void
/**
* The queue itself.
*/
queue: Ref<QueuedDialog[]>
/**
* The current dialog to be displayed.
*/
currentDialog: Ref<QueuedDialog | null>
/**
* Whether the dialog is visible or not.
*/
isDialogVisible: Ref<boolean>
/**
* The wrapped dialog component.
*/
WrappedDialog: Ref<Component | null>
}

export const useDialogQueue = (): DialogQueue => {
const queue: Ref<QueuedDialog[]> = ref([])
const isDialogVisible: Ref<boolean> = ref(true)

const enqueueDialog = (item: QueuedDialog): void => {
queue.value.push(item)
}

const clear = (): void => {
queue.value = []
}

const currentDialog = computed(() => queue.value[0] || null)

const closeCurrentDialog = (): void => {
queue.value.shift()
isDialogVisible.value = true
}

const WrappedDialog = computed(() => {
if (!currentDialog.value) return null

return defineComponent({
name: 'WrappedDialog',
setup() {
const handleUpdate = (value: boolean): void => {
if (!value) {
closeCurrentDialog()
}
}

return () =>
h(currentDialog.value!.component, {
...currentDialog.value!.props,
'modelValue': isDialogVisible.value,
'onUpdate:modelValue': handleUpdate,
})
},
})
})

return {
enqueueDialog,
clear,
queue,
currentDialog,
isDialogVisible,
WrappedDialog,
}
}

0 comments on commit 7a381f4

Please sign in to comment.