Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
commit
03634b1ca3
11340 files changed
+3442369
No files matched your search
@@ -0,0 +1,129 @@
|
||||
import type { HapticInput, TriggerOptions } from 'web-haptics'
|
||||
|
||||
import { $hapticsMuted } from '@/store/haptics'
|
||||
|
||||
export type HapticIntent =
|
||||
| 'cancel'
|
||||
| 'close'
|
||||
| 'crisp'
|
||||
| 'error'
|
||||
| 'open'
|
||||
| 'selection'
|
||||
| 'streamDone'
|
||||
| 'streamStart'
|
||||
| 'submit'
|
||||
| 'success'
|
||||
| 'tap'
|
||||
| 'warning'
|
||||
|
||||
interface HapticConfig {
|
||||
options?: TriggerOptions
|
||||
pattern: HapticInput
|
||||
}
|
||||
|
||||
const airyTap = [{ duration: 16, intensity: 0.52 }]
|
||||
|
||||
const crispTap = [{ duration: 10, intensity: 0.92 }]
|
||||
|
||||
const friendlySuccess = [
|
||||
{ duration: 28, intensity: 0.5 },
|
||||
{ delay: 42, duration: 30, intensity: 0.68 },
|
||||
{ delay: 48, duration: 38, intensity: 0.86 }
|
||||
]
|
||||
|
||||
const softArrive = [
|
||||
{ duration: 18, intensity: 0.42 },
|
||||
{ delay: 36, duration: 22, intensity: 0.66 }
|
||||
]
|
||||
|
||||
const softLeave = [
|
||||
{ duration: 22, intensity: 0.58 },
|
||||
{ delay: 32, duration: 16, intensity: 0.34 }
|
||||
]
|
||||
|
||||
const HAPTIC_INTENTS: Record<HapticIntent, HapticConfig> = {
|
||||
cancel: {
|
||||
pattern: [
|
||||
{ duration: 34, intensity: 0.72 },
|
||||
{ delay: 54, duration: 26, intensity: 0.38 }
|
||||
]
|
||||
},
|
||||
close: { pattern: softLeave },
|
||||
crisp: { pattern: crispTap },
|
||||
error: {
|
||||
pattern: [
|
||||
{ duration: 34, intensity: 0.82 },
|
||||
{ delay: 42, duration: 34, intensity: 0.72 },
|
||||
{ delay: 58, duration: 44, intensity: 0.86 }
|
||||
]
|
||||
},
|
||||
open: { pattern: softArrive },
|
||||
selection: { pattern: airyTap },
|
||||
streamDone: { pattern: friendlySuccess },
|
||||
streamStart: { pattern: [{ duration: 10, intensity: 0.32 }] },
|
||||
submit: {
|
||||
pattern: [
|
||||
{ duration: 24, intensity: 0.58 },
|
||||
{ delay: 48, duration: 36, intensity: 0.82 }
|
||||
]
|
||||
},
|
||||
success: { pattern: friendlySuccess },
|
||||
tap: {
|
||||
pattern: [
|
||||
{ duration: 14, intensity: 0.58 },
|
||||
{ delay: 30, duration: 12, intensity: 0.42 }
|
||||
]
|
||||
},
|
||||
warning: {
|
||||
pattern: [
|
||||
{ duration: 34, intensity: 0.64 },
|
||||
{ delay: 84, duration: 42, intensity: 0.5 }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export type HapticTrigger = (input?: HapticInput, options?: TriggerOptions) => Promise<void> | undefined
|
||||
|
||||
let registeredTrigger: HapticTrigger | null = null
|
||||
let lastSelectionAt = 0
|
||||
|
||||
// Global rolling rate-limit. A runaway upstream loop (auth-expiry error-toast
|
||||
// storms, reconnect flaps) can request dozens of haptics a second, which the
|
||||
// trackpad actuator renders as a frantic "clickity" buzz. Cap firings to
|
||||
// RATE_LIMIT per RATE_WINDOW so no source can machine-gun the actuator;
|
||||
// intentional UI haptics are human-paced and never approach the ceiling.
|
||||
const RATE_WINDOW = 1000
|
||||
const RATE_LIMIT = 5
|
||||
let recentFires: number[] = []
|
||||
|
||||
export function registerHapticTrigger(trigger: HapticTrigger | null) {
|
||||
registeredTrigger = trigger
|
||||
}
|
||||
|
||||
export function triggerHaptic(intent: HapticIntent = 'selection') {
|
||||
if ($hapticsMuted.get() || !registeredTrigger) {
|
||||
return
|
||||
}
|
||||
|
||||
const now = performance.now()
|
||||
|
||||
if (intent === 'selection') {
|
||||
if (now - lastSelectionAt < 50) {
|
||||
return
|
||||
}
|
||||
|
||||
lastSelectionAt = now
|
||||
}
|
||||
|
||||
recentFires = recentFires.filter(t => now - t < RATE_WINDOW)
|
||||
|
||||
if (recentFires.length >= RATE_LIMIT) {
|
||||
return
|
||||
}
|
||||
|
||||
recentFires.push(now)
|
||||
|
||||
const config = HAPTIC_INTENTS[intent]
|
||||
|
||||
void registeredTrigger(config.pattern, config.options)?.catch(() => undefined)
|
||||
}
|
||||
Reference in new issue
Block a user