Skip to content

Commit

Permalink
libs: slide-to-confirm: Add hold to confirm
Browse files Browse the repository at this point in the history
* Add hold to confirm action to map action from controller to percentage
  of complete confirm action
  • Loading branch information
JoaoMario109 committed Mar 18, 2024
1 parent 731da53 commit 80ec876
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/components/SlideToConfirm.vue
Expand Up @@ -3,6 +3,7 @@
<div class="flex items-center space-x-4 mb-3">
<slide-unlock
ref="vueslideunlock"
:position="sliderPercentage"
:auto-width="false"
:circle="true"
:disabled="false"
Expand All @@ -25,7 +26,13 @@
<script setup lang="ts">
import SlideUnlock from '@j2only/slide-unlock'
import { confirmationSliderText, confirmed, showSlideToConfirm, sliderText } from '@/libs/slide-to-confirm'
import {
confirmationSliderText,
confirmed,
showSlideToConfirm,
sliderPercentage,
sliderText,
} from '@/libs/slide-to-confirm'
const onSlideConfirmed = (): void => {
confirmed.value = true
Expand Down
48 changes: 48 additions & 0 deletions src/libs/slide-to-confirm.ts
Expand Up @@ -2,8 +2,15 @@ import { ref, watch } from 'vue'

import { useMissionStore } from '@/stores/mission'

import {
availableCockpitActions,
registerActionCallback,
unregisterActionCallback,
} from './joystick/protocols/cockpit-actions'

export const showSlideToConfirm = ref(false)
export const sliderText = ref('Slide to Confirm')
export const sliderPercentage = ref(0)
export const confirmationSliderText = ref('Action Confirm')
export const confirmed = ref(false)

Expand Down Expand Up @@ -38,6 +45,19 @@ export const eventCategoriesDefaultMapping: Record<string, boolean> = Object.val
{}
)

/**
* The maximum interval in milliseconds between the last call from a joystick action
* to be considered as a repeat action
* @type {number}
*/
const maxRepeatIntervalMs = 50

/**
* Time interval in ms needed to keep a repeat action pressed to be considered as a hold action
* @type {number}
*/
const holdActionTimeMs = 2000

/**
* Waits for user confirmation through the slide-to-confirm component.
* @param {EventCategory} category - The category of the event that requires confirmation.
Expand All @@ -55,6 +75,30 @@ export function slideToConfirm(category: EventCategory, text: string, confirmati
return resolve(true)
}

let holdToConfirmCallbackId: string | undefined

if (missionStore.holdToConfirmEnabled) {
let lastConfirmCall = 0
let totalPressedTime = 0

const onHoldConfirmCallback = (): void => {
const dt = Date.now() - lastConfirmCall

// Reset total pressed time if user releases the button
if (dt > maxRepeatIntervalMs) {
totalPressedTime = 0
sliderPercentage.value = 0
} else {
totalPressedTime += dt
sliderPercentage.value = Math.min((totalPressedTime / holdActionTimeMs) * 100, 100)
}

lastConfirmCall = Date.now()
}

holdToConfirmCallbackId = registerActionCallback(availableCockpitActions.hold_to_confirm, onHoldConfirmCallback)
}

sliderText.value = text
confirmationSliderText.value = confirmationText
showSlideToConfirm.value = true
Expand All @@ -68,6 +112,10 @@ export function slideToConfirm(category: EventCategory, text: string, confirmati
stopWatching()
resolve(false)
}

if (holdToConfirmCallbackId) {
unregisterActionCallback(holdToConfirmCallbackId)
}
})
})
}

0 comments on commit 80ec876

Please sign in to comment.