From 0a77a4b8f999fcb6f34155246638255048a551d4 Mon Sep 17 00:00:00 2001 From: Rafael Araujo Lehmkuhl Date: Tue, 23 Jan 2024 17:07:03 -0300 Subject: [PATCH 01/10] alert-store: Create abstracted functions for pushing specific alert levels --- src/stores/alert.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/stores/alert.ts b/src/stores/alert.ts index 737ad28f9..2dc818d67 100644 --- a/src/stores/alert.ts +++ b/src/stores/alert.ts @@ -48,6 +48,22 @@ export const useAlertStore = defineStore('alert', () => { } } + const pushSuccessAlert = (message: string, time_created: Date = new Date()): void => { + pushAlert(new Alert(AlertLevel.Success, message, time_created)) + } + const pushErrorAlert = (message: string, time_created: Date = new Date()): void => { + pushAlert(new Alert(AlertLevel.Error, message, time_created)) + } + const pushInfoAlert = (message: string, time_created: Date = new Date()): void => { + pushAlert(new Alert(AlertLevel.Info, message, time_created)) + } + const pushWarningAlert = (message: string, time_created: Date = new Date()): void => { + pushAlert(new Alert(AlertLevel.Warning, message, time_created)) + } + const pushCriticalAlert = (message: string, time_created: Date = new Date()): void => { + pushAlert(new Alert(AlertLevel.Critical, message, time_created)) + } + // Alert speech syntesis routine const synth = window.speechSynthesis @@ -135,5 +151,10 @@ export const useAlertStore = defineStore('alert', () => { availableAlertSpeechVoiceNames, sortedAlerts, pushAlert, + pushSuccessAlert, + pushErrorAlert, + pushInfoAlert, + pushWarningAlert, + pushCriticalAlert, } }) From 134ce700f40ec9fd73783fb32ebcd5c99f97bd77 Mon Sep 17 00:00:00 2001 From: Rafael Araujo Lehmkuhl Date: Tue, 23 Jan 2024 17:32:29 -0300 Subject: [PATCH 02/10] composables: Create `useBlueOsStorage` The `useBlueOsStorage` composable will keep a setting in sync between local storage and BlueOS. The initial value will be the one stored on BlueOS. If we fail to get the value from BlueOS on the first seconds after boot, we will ask the user if they prefer to use the value stored locally or the value stored on BlueOS. Once everything is in sync, if the local value changes, it will update the value on BlueOS. In resume, the initial source of truth is BlueOS, and once everything is in sync, the source of truth is the local value. --- src/composables/settingsSyncer.ts | 193 ++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/composables/settingsSyncer.ts diff --git a/src/composables/settingsSyncer.ts b/src/composables/settingsSyncer.ts new file mode 100644 index 000000000..9afd3c74e --- /dev/null +++ b/src/composables/settingsSyncer.ts @@ -0,0 +1,193 @@ +import { type RemovableRef, useStorage, watchThrottled } from '@vueuse/core' +import { type MaybeRef, onMounted, ref, unref } from 'vue' + +import { + getKeyDataFromCockpitVehicleStorage, + NoPathInBlueOsErrorName, + setKeyDataOnCockpitVehicleStorage, +} from '@/libs/blueos' +import { isEqual } from '@/libs/utils' +import { useAlertStore } from '@/stores/alert' +import { useMainVehicleStore } from '@/stores/mainVehicle' + +import { useInteractionDialog } from './interactionDialog' + +/** + * This composable will keep a setting in sync between the browser's local storage and BlueOS. + * + * When initialized, it will try to get the value from BlueOS. While BlueOS does not connect, it will use the local + * stored value and keep trying to communicate with BlueOS to get it's value. + * + * Once the connection is stablished, if BlueOS doesn't have a value, it will use the local stored one and update + * BlueOS with it. On the other hand, if BlueOS has a value, it will ask the user if they want to use the value from + * BlueOS or the local one. Depending on the user's choice, it will update the local value or BlueOS. + * + * Once everything is in sync, if the local value changes, it will update the value on BlueOS. + * In resume, the initial source of truth is decided by the user, and once everything is in sync, the source of truth + * is the local value. + * @param { string } key + * @param { T } defaultValue + * @returns { RemovableRef } + */ +export function useBlueOsStorage(key: string, defaultValue: MaybeRef): RemovableRef { + const { showDialog, closeDialog } = useInteractionDialog() + + const primitiveDefaultValue = unref(defaultValue) + const currentValue = useStorage(key, primitiveDefaultValue) + const finishedInitialFetch = ref(false) + let initialSyncTimeout: ReturnType | undefined = undefined + let blueOsUpdateTimeout: ReturnType | undefined = undefined + + const getVehicleAddress = async (): Promise => { + const vehicleStore = useMainVehicleStore() + + while (vehicleStore.globalAddress === undefined) { + console.debug('Waiting for vehicle global address on BlueOS sync routine.') + await new Promise((r) => setTimeout(r, 1000)) + // Wait until we have a global address + } + + return vehicleStore.globalAddress + } + + const askIfUserWantsToUseBlueOsValue = async (): Promise => { + let useBlueOsValue = true + + const preferBlueOs = (): void => { + useBlueOsValue = true + } + + const preferCockpit = (): void => { + useBlueOsValue = false + } + + await showDialog({ + title: 'Conflict with BlueOS', + message: ` + The value for '${key}' that is currently used in Cockpit differs from the one stored in BlueOS. What do you + want to do? + `, + variant: 'warning', + actions: [ + { text: 'Use the value from BlueOS', action: preferBlueOs }, + { text: "Keep Cockpit's value", action: preferCockpit }, + ], + }) + + closeDialog() + + return useBlueOsValue + } + + const updateValueOnBlueOS = async (newValue: T): Promise => { + const vehicleAddress = await getVehicleAddress() + const alertStore = useAlertStore() + + alertStore.pushInfoAlert(`Updating '${key}' on BlueOS.`) + + let timesTriedBlueOsUpdate = 0 + const tryToUpdateBlueOsValue = async (): Promise => { + // Clear update routine if there's one left, as we are going to start a new one + clearTimeout(blueOsUpdateTimeout) + + timesTriedBlueOsUpdate++ + try { + await setKeyDataOnCockpitVehicleStorage(vehicleAddress, key, newValue) + alertStore.pushSuccessAlert(`Success updating '${key}' on BlueOS.`) + } catch (fetchError) { + const errorMessage = `Failed updating '${key}' on BlueOS. Will keep trying.` + if (timesTriedBlueOsUpdate > 1) { + alertStore.pushErrorAlert(errorMessage) + } else { + console.error(errorMessage) + } + console.error(fetchError) + + // If we can't update the value on BlueOS, try again in 10 seconds + blueOsUpdateTimeout = setTimeout(tryToUpdateBlueOsValue, 10000) + } + } + + // Start BlueOS value update routine + tryToUpdateBlueOsValue() + } + + onMounted(async () => { + const vehicleAddress = await getVehicleAddress() + const alertStore = useAlertStore() + + alertStore.pushInfoAlert(`Started syncing '${key}' with BlueOS.`) + + let timesTriedInitialSync = 0 + const tryToDoInitialSync = async (): Promise => { + // Clear initial sync routine if there's one left, as we are going to start a new one + clearTimeout(initialSyncTimeout) + + timesTriedInitialSync++ + + try { + const valueOnBlueOS = await getKeyDataFromCockpitVehicleStorage(vehicleAddress, key) + console.log(`Success getting value of '${key}' from BlueOS:`, valueOnBlueOS) + + // If the value on BlueOS is the same as the one we have locally, we don't need to bother the user + if (isEqual(currentValue.value, valueOnBlueOS)) { + console.debug(`Value for '${key}' on BlueOS is the same as the local one. No need to update.`) + finishedInitialFetch.value = true + return + } + + // If Cockpit has a different value than BlueOS, ask the user if they want to use the value from BlueOS or + // if they want to update BlueOS with the value from Cockpit. + + const useBlueOsValue = await askIfUserWantsToUseBlueOsValue() + + if (useBlueOsValue) { + currentValue.value = valueOnBlueOS as T + } else { + updateValueOnBlueOS(currentValue.value) + } + + alertStore.pushSuccessAlert(`Success syncing '${key}' with BlueOS.`) + + finishedInitialFetch.value = true + } catch (initialSyncError) { + // If the initial sync fails because there's no value for the key on BlueOS, we can just use the current value + if ((initialSyncError as Error).name === NoPathInBlueOsErrorName) { + console.debug(`No value for '${key}' on BlueOS. Using current value.`) + updateValueOnBlueOS(currentValue.value) + finishedInitialFetch.value = true + return + } + + // If the initial sync fails because we can't connect to BlueOS, try again in 10 seconds + initialSyncTimeout = setTimeout(tryToDoInitialSync, 10000) + + const errorMessage = `Failed syncing '${key}' with BlueOS. Will keep trying.` + if (timesTriedInitialSync > 1) { + alertStore.pushErrorAlert(errorMessage) + } else { + console.error(errorMessage) + } + console.error(`Not able to get current value of '${key}' on BlueOS. ${initialSyncError}`) + } + } + + // Start initial sync routine + tryToDoInitialSync() + }) + + // Update BlueOS value when local value changes. + // Throttle to avoid spamming BlueOS with requests while the user is updating the value. + watchThrottled( + currentValue, + async (newValue) => { + // Don't update the value on BlueOS if we haven't finished the initial fetch, so we don't overwrite the value there without user consent + if (!finishedInitialFetch.value) return + + updateValueOnBlueOS(newValue) + }, + { throttle: 3000, deep: true } + ) + + return currentValue +} From e9826a3ab14fb9c52bfa91f5e959e08cbacda4cb Mon Sep 17 00:00:00 2001 From: Rafael Araujo Lehmkuhl Date: Tue, 23 Jan 2024 17:38:24 -0300 Subject: [PATCH 03/10] vehicle-settings: Store vehicle settings inside it (instead of local browser storage) --- src/libs/sensors-logging.ts | 12 ++++++------ src/stores/alert.ts | 12 ++++++++---- src/stores/controller.ts | 15 ++++++++------- src/stores/development.ts | 5 +++-- src/stores/mainVehicle.ts | 11 ++++++----- src/stores/mission.ts | 14 ++++++-------- src/stores/video.ts | 14 +++++++++----- src/stores/widgetManager.ts | 13 +++++++------ src/views/ConfigurationLogsView.vue | 26 +++++++++++++------------- 9 files changed, 66 insertions(+), 56 deletions(-) diff --git a/src/libs/sensors-logging.ts b/src/libs/sensors-logging.ts index 9b3e65090..cd295f892 100644 --- a/src/libs/sensors-logging.ts +++ b/src/libs/sensors-logging.ts @@ -1,8 +1,8 @@ -import { useStorage } from '@vueuse/core' import { differenceInMilliseconds, differenceInSeconds, format, intervalToDuration } from 'date-fns' import localforage from 'localforage' import Swal from 'sweetalert2' +import { useBlueOsStorage } from '@/composables/settingsSyncer' import { useMainVehicleStore } from '@/stores/mainVehicle' import { useMissionStore } from '@/stores/mission' @@ -199,7 +199,7 @@ class DataLogger { currentCockpitLog: CockpitStandardLog = [] variablesBeingUsed: DatalogVariable[] = [] veryGenericIndicators: VeryGenericData[] = [] - telemetryDisplayData = useStorage('cockpit-datalogger-overlay-grid', { + telemetryDisplayData = useBlueOsStorage('cockpit-datalogger-overlay-grid', { LeftTop: [], CenterTop: [], RightTop: [], @@ -210,7 +210,7 @@ class DataLogger { CenterBottom: [], RightBottom: [], }) - telemetryDisplayOptions = useStorage('cockpit-datalogger-overlay-options', { + telemetryDisplayOptions = useBlueOsStorage('cockpit-datalogger-overlay-options', { fontSize: 30, fontColor: '#FFFFFFFF', backgroundColor: '#000000FF', @@ -223,7 +223,7 @@ class DataLogger { fontUnderline: false, fontStrikeout: false, }) - logInterval = useStorage('cockpit-datalogger-log-interval', 1000) + logInterval = useBlueOsStorage('cockpit-datalogger-log-interval', 1000) cockpitLogsDB = localforage.createInstance({ driver: localforage.INDEXEDDB, name: 'Cockpit - Sensor Logs', @@ -476,7 +476,7 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text` return `&H${invertedAlpha}${blue}${green}${red}` } - + log.forEach((logPoint, index) => { // Don't deal with the last log point, as it has no next point to compare to if (index === log.length - 1) return @@ -521,7 +521,7 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text` const millisNextPoint = differenceInMilliseconds(new Date(log[index + 1].epoch), new Date(videoStartEpoch)) const remainingMillisNextPoint = millisNextPoint - roundedMillisNextPoint const remainingCentisNextPoint = Math.floor(remainingMillisNextPoint / 10).toString().padStart(2, '0') - + const timeThis = `${durationHoursThisPoint}:${durationMinutesThisPoint}:${durationSecondsThisPoint}.${remainingCentisThisPoint}` const timeNext = `${durationHoursNextPoint}:${durationMinutesNextPoint}:${durationSecondsNextPoint}.${remainingCentisNextPoint}` diff --git a/src/stores/alert.ts b/src/stores/alert.ts index 2dc818d67..ff3a332e0 100644 --- a/src/stores/alert.ts +++ b/src/stores/alert.ts @@ -1,16 +1,20 @@ -import { useStorage } from '@vueuse/core' import { defineStore } from 'pinia' import { computed, reactive, watch } from 'vue' +import { useBlueOsStorage } from '@/composables/settingsSyncer' + import { Alert, AlertLevel } from '../types/alert' export const useAlertStore = defineStore('alert', () => { const alerts = reactive([new Alert(AlertLevel.Success, 'Cockpit started')]) - const enableVoiceAlerts = useStorage('cockpit-enable-voice-alerts', true) + const enableVoiceAlerts = useBlueOsStorage('cockpit-enable-voice-alerts', true) // eslint-disable-next-line jsdoc/require-jsdoc const availableAlertSpeechVoices = reactive([]) - const selectedAlertSpeechVoiceName = useStorage('cockpit-selected-alert-speech-voice', undefined) - const enabledAlertLevels = useStorage('cockpit-enabled-alert-levels', [ + const selectedAlertSpeechVoiceName = useBlueOsStorage( + 'cockpit-selected-alert-speech-voice', + undefined + ) + const enabledAlertLevels = useBlueOsStorage('cockpit-enabled-alert-levels', [ { level: AlertLevel.Success, enabled: true }, { level: AlertLevel.Error, enabled: true }, { level: AlertLevel.Info, enabled: false }, diff --git a/src/stores/controller.ts b/src/stores/controller.ts index 5e408cb6d..7aecc35ad 100644 --- a/src/stores/controller.ts +++ b/src/stores/controller.ts @@ -1,4 +1,4 @@ -import { useDocumentVisibility, useStorage } from '@vueuse/core' +import { useDocumentVisibility } from '@vueuse/core' import { saveAs } from 'file-saver' import { defineStore } from 'pinia' import Swal from 'sweetalert2' @@ -10,6 +10,7 @@ import { cockpitStandardToProtocols, defaultProtocolMappingVehicleCorrespondency, } from '@/assets/joystick-profiles' +import { useBlueOsStorage } from '@/composables/settingsSyncer' import { getKeyDataFromCockpitVehicleStorage, setKeyDataOnCockpitVehicleStorage } from '@/libs/blueos' import { MavType } from '@/libs/connection/m2r/messages/mavlink2rest-enum' import { type JoystickEvent, EventType, joystickManager, JoystickModel } from '@/libs/joystick/manager' @@ -45,19 +46,19 @@ export const useControllerStore = defineStore('controller', () => { const alertStore = useAlertStore() const joysticks = ref>(new Map()) const updateCallbacks = ref([]) - const protocolMappings = useStorage(protocolMappingsKey, cockpitStandardToProtocols) - const protocolMappingIndex = useStorage(protocolMappingIndexKey, 0) - const cockpitStdMappings = useStorage(cockpitStdMappingsKey, availableGamepadToCockpitMaps) + const protocolMappings = useBlueOsStorage(protocolMappingsKey, cockpitStandardToProtocols) + const protocolMappingIndex = useBlueOsStorage(protocolMappingIndexKey, 0) + const cockpitStdMappings = useBlueOsStorage(cockpitStdMappingsKey, availableGamepadToCockpitMaps) const availableAxesActions = allAvailableAxes const availableButtonActions = allAvailableButtons const enableForwarding = ref(false) - const holdLastInputWhenWindowHidden = useStorage('cockpit-hold-last-joystick-input-when-window-hidden', false) - const vehicleTypeProtocolMappingCorrespondency = useStorage( + const holdLastInputWhenWindowHidden = useBlueOsStorage('cockpit-hold-last-joystick-input-when-window-hidden', false) + const vehicleTypeProtocolMappingCorrespondency = useBlueOsStorage( 'cockpit-default-vehicle-type-protocol-mappings', defaultProtocolMappingVehicleCorrespondency ) // Confirmation per joystick action required currently is only available for cockpit actions - const actionsJoystickConfirmRequired = useStorage( + const actionsJoystickConfirmRequired = useBlueOsStorage( 'cockpit-actions-joystick-confirm-required', {} as Record ) diff --git a/src/stores/development.ts b/src/stores/development.ts index 278c47b79..92ee3aef7 100644 --- a/src/stores/development.ts +++ b/src/stores/development.ts @@ -1,12 +1,13 @@ -import { useStorage } from '@vueuse/core' import { defineStore } from 'pinia' import { ref } from 'vue' +import { useBlueOsStorage } from '@/composables/settingsSyncer' + export const systemLoggingEnablingKey = 'cockpit-enable-system-logging' export const useDevelopmentStore = defineStore('development', () => { const developmentMode = ref(false) const widgetDevInfoBlurLevel = ref(3) - const enableSystemLogging = useStorage(systemLoggingEnablingKey, true) + const enableSystemLogging = useBlueOsStorage(systemLoggingEnablingKey, true) return { developmentMode, widgetDevInfoBlurLevel, enableSystemLogging } }) diff --git a/src/stores/mainVehicle.ts b/src/stores/mainVehicle.ts index cf8b72b43..6b5f3f134 100644 --- a/src/stores/mainVehicle.ts +++ b/src/stores/mainVehicle.ts @@ -1,8 +1,9 @@ -import { useStorage, useTimestamp, watchThrottled } from '@vueuse/core' +import { useTimestamp, watchThrottled } from '@vueuse/core' import { defineStore } from 'pinia' import { computed, reactive, ref, watch } from 'vue' import { defaultGlobalAddress } from '@/assets/defaults' +import { useBlueOsStorage } from '@/composables/settingsSyncer' import { altitude_setpoint } from '@/libs/altitude-slider' import { getCpuTempCelsius, getStatus } from '@/libs/blueos' import * as Connection from '@/libs/connection/connection' @@ -63,19 +64,19 @@ export const useMainVehicleStore = defineStore('main-vehicle', () => { const ws_protocol = location?.protocol === 'https:' ? 'wss' : 'ws' const cpuLoad = ref() - const globalAddress = useStorage('cockpit-vehicle-address', defaultGlobalAddress) + const globalAddress = useBlueOsStorage('cockpit-vehicle-address', defaultGlobalAddress) const defaultMainConnectionURI = ref(`${ws_protocol}://${globalAddress.value}/mavlink2rest/ws/mavlink`) const defaultWebRTCSignallingURI = ref(`${ws_protocol}://${globalAddress.value}:6021/`) - const customMainConnectionURI = useStorage('cockpit-vehicle-custom-main-connection-uri', { + const customMainConnectionURI = useBlueOsStorage('cockpit-vehicle-custom-main-connection-uri', { data: defaultMainConnectionURI.value, enabled: false, } as CustomParameter) - const customWebRTCSignallingURI = useStorage('cockpit-vehicle-custom-webrtc-signalling-uri', { + const customWebRTCSignallingURI = useBlueOsStorage('cockpit-vehicle-custom-webrtc-signalling-uri', { data: defaultWebRTCSignallingURI.value, enabled: false, } as CustomParameter) - const customWebRTCConfiguration = useStorage('cockpit-custom-rtc-config', { + const customWebRTCConfiguration = useBlueOsStorage('cockpit-custom-rtc-config', { data: defaultRtcConfiguration, enabled: false, }) diff --git a/src/stores/mission.ts b/src/stores/mission.ts index aab1f174d..7401faab2 100644 --- a/src/stores/mission.ts +++ b/src/stores/mission.ts @@ -1,21 +1,19 @@ -import { useStorage } from '@vueuse/core' import { defineStore } from 'pinia' import { reactive, ref, watch } from 'vue' +import { useBlueOsStorage } from '@/composables/settingsSyncer' import { eventCategoriesDefaultMapping } from '@/libs/slide-to-confirm' import type { Waypoint, WaypointCoordinates } from '@/types/mission' export const useMissionStore = defineStore('mission', () => { const missionName = ref('') - const lastMissionName = useStorage('cockpit-last-mission-name', '') - const missionStartTime = useStorage('cockpit-mission-start-time', new Date()) - const slideEventsEnabled = useStorage('cockpit-slide-events-enabled', true) - const slideEventsCategoriesRequired = useStorage( + const slideEventsEnabled = useBlueOsStorage('cockpit-slide-events-enabled', true) + const slideEventsCategoriesRequired = useBlueOsStorage( 'cockpit-slide-events-categories-required', - eventCategoriesDefaultMapping, - localStorage, - { mergeDefaults: true } + eventCategoriesDefaultMapping ) + const lastMissionName = useBlueOsStorage('cockpit-last-mission-name', '') + const missionStartTime = useBlueOsStorage('cockpit-mission-start-time', new Date()) watch(missionName, () => (lastMissionName.value = missionName.value)) diff --git a/src/stores/video.ts b/src/stores/video.ts index a1f733678..754ec93a2 100644 --- a/src/stores/video.ts +++ b/src/stores/video.ts @@ -1,4 +1,4 @@ -import { useDebounceFn, useStorage, useThrottleFn, useTimestamp } from '@vueuse/core' +import { useDebounceFn, useThrottleFn, useTimestamp } from '@vueuse/core' import { BlobReader, BlobWriter, ZipWriter } from '@zip.js/zip.js' import { differenceInSeconds, format } from 'date-fns' import { saveAs } from 'file-saver' @@ -11,6 +11,7 @@ import fixWebmDuration from 'webm-duration-fix' import adapter from 'webrtc-adapter' import { useInteractionDialog } from '@/composables/interactionDialog' +import { useBlueOsStorage } from '@/composables/settingsSyncer' import { WebRTCManager } from '@/composables/webRTC' import { getIpsInformationFromVehicle } from '@/libs/blueos' import { availableCockpitActions, registerActionCallback } from '@/libs/joystick/protocols/cockpit-actions' @@ -40,13 +41,16 @@ export const useVideoStore = defineStore('video', () => { const { globalAddress, rtcConfiguration, webRTCSignallingURI } = useMainVehicleStore() console.debug('[WebRTC] Using webrtc-adapter for', adapter.browserDetails) - const allowedIceIps = useStorage('cockpit-allowed-stream-ips', []) - const allowedIceProtocols = useStorage('cockpit-allowed-stream-protocols', []) - const jitterBufferTarget = useStorage('cockpit-jitter-buffer-target', 0) + const allowedIceIps = useBlueOsStorage('cockpit-allowed-stream-ips', []) + const allowedIceProtocols = useBlueOsStorage('cockpit-allowed-stream-protocols', []) + const jitterBufferTarget = useBlueOsStorage('cockpit-jitter-buffer-target', 0) const activeStreams = ref<{ [key in string]: StreamData | undefined }>({}) const mainWebRTCManager = new WebRTCManager(webRTCSignallingURI, rtcConfiguration) const availableIceIps = ref([]) - const unprocessedVideos = useStorage<{ [key in string]: UnprocessedVideoInfo }>('cockpit-unprocessed-video-info', {}) + const unprocessedVideos = useBlueOsStorage<{ [key in string]: UnprocessedVideoInfo }>( + 'cockpit-unprocessed-video-info', + {} + ) const timeNow = useTimestamp({ interval: 500 }) const namesAvailableStreams = computed(() => mainWebRTCManager.availableStreams.value.map((stream) => stream.name)) diff --git a/src/stores/widgetManager.ts b/src/stores/widgetManager.ts index a4ab95979..e7f2d5691 100644 --- a/src/stores/widgetManager.ts +++ b/src/stores/widgetManager.ts @@ -1,6 +1,6 @@ import '@/libs/cosmos' -import { useDebounceFn, useStorage, useWindowSize } from '@vueuse/core' +import { useDebounceFn, useWindowSize } from '@vueuse/core' import { saveAs } from 'file-saver' import { defineStore } from 'pinia' import Swal from 'sweetalert2' @@ -9,6 +9,7 @@ import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue' import { defaultProfileVehicleCorrespondency, defaultWidgetManagerVars, widgetProfiles } from '@/assets/defaults' import { miniWidgetsProfile } from '@/assets/defaults' +import { useBlueOsStorage } from '@/composables/settingsSyncer' import { getKeyDataFromCockpitVehicleStorage, setKeyDataOnCockpitVehicleStorage } from '@/libs/blueos' import { MavType } from '@/libs/connection/m2r/messages/mavlink2rest-enum' import * as Words from '@/libs/funny-name/words' @@ -32,14 +33,14 @@ export const useWidgetManagerStore = defineStore('widget-manager', () => { const editingMode = ref(false) const snapToGrid = ref(true) const gridInterval = ref(0.01) - const currentMiniWidgetsProfile = useStorage('cockpit-mini-widgets-profile-v4', miniWidgetsProfile) - const savedProfiles = useStorage(savedProfilesKey, []) - const currentViewIndex = useStorage('cockpit-current-view-index', 0) - const currentProfileIndex = useStorage('cockpit-current-profile-index', 0) + const currentMiniWidgetsProfile = useBlueOsStorage('cockpit-mini-widgets-profile-v4', miniWidgetsProfile) + const savedProfiles = useBlueOsStorage(savedProfilesKey, []) + const currentViewIndex = useBlueOsStorage('cockpit-current-view-index', 0) + const currentProfileIndex = useBlueOsStorage('cockpit-current-profile-index', 0) const desiredTopBarHeightPixels = ref(48) const desiredBottomBarHeightPixels = ref(48) const visibleAreaMinClearancePixels = ref(20) - const vehicleTypeProfileCorrespondency = useStorage( + const vehicleTypeProfileCorrespondency = useBlueOsStorage( 'cockpit-default-vehicle-type-profiles', defaultProfileVehicleCorrespondency ) diff --git a/src/views/ConfigurationLogsView.vue b/src/views/ConfigurationLogsView.vue index 2c641381a..ecc608e75 100644 --- a/src/views/ConfigurationLogsView.vue +++ b/src/views/ConfigurationLogsView.vue @@ -7,7 +7,7 @@