diff --git a/app/components/live-atc/cockpit/CockpitShell.vue b/app/components/live-atc/cockpit/CockpitShell.vue new file mode 100644 index 0000000..1c66a46 --- /dev/null +++ b/app/components/live-atc/cockpit/CockpitShell.vue @@ -0,0 +1,950 @@ + + + + + + + + + + mdi-radar + + + OpenSquawk + + + + Live ATC + mdi-chevron-down + + + + + mdi-school + + Classroom + Mission hub & drills + + + + mdi-radio-handheld + + Live ATC + Live radio with AI controllers + + mdi-check + + + + + + + {{ flightContext.callsign || 'N/A' }} + {{ flightContext.dep }} → {{ flightContext.dest }} + + + + + mdi-chevron-down + + + + + State + + {{ flags.in_air ? 'IN-AIR' : 'GROUND' }} + + + + Unit + {{ flags.current_unit }} + + + Emergency + + {{ flags.emergency_active ? 'ACTIVE' : 'NONE' }} + + + + Radio checks + {{ flags.radio_checks_done || 0 }} + + + Off-schema + {{ flags.off_schema_count || 0 }} + + + + + + + + + + + + mdi-bridge + Bridge + + + + + + + mdi-bridge + Connect simulator + + + + + + {{ bugReportCapturing ? 'mdi-loading mdi-spin' : 'mdi-bug-outline' }} + {{ bugReportCapturing ? '…' : 'Report issue' }} + + + mdi-cog + + + mdi-help-circle-outline + + + + mdi-logout + + + + + + + + + + + + + emit('apply-manual', target, close)" + /> + + + + + + + mdi-microphone + Voice + + + mdi-keyboard + Text + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ tab.icon }} + {{ tab.label }} + + + + + + + + + diff --git a/app/pages/live-atc.vue b/app/pages/live-atc.vue index 07dbf9c..423eae3 100644 --- a/app/pages/live-atc.vue +++ b/app/pages/live-atc.vue @@ -56,417 +56,164 @@ - - - - - - - mdi-radar - - - OpenSquawk - - - - Live ATC - mdi-chevron-down - - - - - mdi-school - - Classroom - Mission hub & drills - - - - mdi-radio-handheld - - Live ATC - Live radio with AI controllers - - mdi-check - - - + applyManualFrequency(target, close)" + @ptt-start="startRecording(false)" + @ptt-stop="stopRecording" + @request-mic="requestMicAccess" + @send-text="sendPilotText" + @flag-issue="startTransmissionIssueFlow" + @clear-transmission="clearLastTransmission" + @clear-log="clearLog" + > + + - - + + + + + + + + + + + Mark transmission as faulty + + + + Optionally leave a short note so the dev team can follow up on the transmission. + + + + + + Cancel + + - {{ flightContext.callsign || 'N/A' }} - {{ flightContext.dep }} → {{ flightContext.dest }} - - - - - mdi-chevron-down - - - - - State - - {{ flags.in_air ? 'IN-AIR' : 'GROUND' }} - - - - Unit - {{ flags.current_unit }} - - - Emergency - - {{ flags.emergency_active ? 'ACTIVE' : 'NONE' }} - - - - Radio checks - {{ flags.radio_checks_done || 0 }} - - - Off-schema - {{ flags.off_schema_count || 0 }} + Remove flag + + + Save + + + + + + + + + + {{ helpContent.title }} + + {{ helpLang === 'de' ? 'EN' : 'DE' }} + + + + {{ helpContent.intro }} + + + {{ step.icon }} + + {{ step.title }} + {{ step.text }} - - - - - - - - - - mdi-bridge - Bridge - - - - - - - mdi-bridge - Connect simulator - - - - - - {{ bugReportCapturing ? 'mdi-loading mdi-spin' : 'mdi-bug-outline' }} - {{ bugReportCapturing ? '…' : 'Report issue' }} - - - mdi-cog - - - mdi-help-circle-outline - - - - mdi-logout - - - - - - - - - - - - - applyManualFrequency(target, close)" - /> - - - - - - - mdi-microphone - Voice - - - mdi-keyboard - Text - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ tab.icon }} - {{ tab.label }} - - - - - - - - - - - - - - - - - Mark transmission as faulty - - - - Optionally leave a short note so the dev team can follow up on the transmission. - - - - - - Cancel - - - Remove flag - - - Save - - - - - - - - - - {{ helpContent.title }} - - {{ helpLang === 'de' ? 'EN' : 'DE' }} - - - - {{ helpContent.intro }} - - - {{ step.icon }} - - {{ step.title }} - {{ step.text }} - - - - - - - - {{ helpLang === 'de' ? 'Verstanden' : 'Got it' }} - - - - - + + + + + {{ helpLang === 'de' ? 'Verstanden' : 'Got it' }} + + + + + + @@ -479,12 +226,7 @@ import { useApi } from '~/composables/useApi' import { usePmTheme } from '~/composables/usePmTheme' import { normalizeManualFreq } from '../../shared/utils/frequency' import { useFrequencyPresets } from '~/composables/useFrequencyPresets' -import RadioPanel from '~/components/live-atc/cockpit/RadioPanel.vue' -import ExpectedCommStrip from '~/components/live-atc/cockpit/ExpectedCommStrip.vue' -import PttPad from '~/components/live-atc/cockpit/PttPad.vue' -import TextInputPanel from '~/components/live-atc/cockpit/TextInputPanel.vue' -import LastTransmissionCard from '~/components/live-atc/cockpit/LastTransmissionCard.vue' -import CommLogRail from '~/components/live-atc/cockpit/CommLogRail.vue' +import CockpitShell from '~/components/live-atc/cockpit/CockpitShell.vue' import { useAtisPlayback } from '~/composables/useAtisPlayback' import { usePttRecording } from '~/composables/usePttRecording' import { useBugReport } from '~/composables/useBugReport' @@ -648,35 +390,19 @@ const readbackEnabled = ref(false) const bugReport = useBugReport(engine, { activeScenario }) const { bugReportCapturing, openBugReport } = bugReport -// Layout / view state -const activeTab = ref<'funk' | 'log'>('funk') -const experienceMenu = ref(false) +// Layout / view state. The tab, HUD menu and mode-switch state live inside +// CockpitShell; `inputMode` stays here because a watcher below drives the +// pre-recording buffer off it. const inputMode = ref<'voice' | 'text'>('voice') const learningMode = ref(true) -const showExpectedComm = computed( - () => learningMode.value && Boolean(displayControllerSay.value || displayExpectedPhrase.value), -) // Overlays / sheets opened from HUD controls const showFlightSheet = ref(false) const showSettingsSheet = ref(false) -const hudStatusMenu = ref(false) /** The one gate for developer tooling: DebugPanel is not mounted while this is off. */ const debugMode = ref(true) -type PmTab = { - id: 'funk' | 'log' - label: string - icon: string - mobileOnly?: boolean -} -const TABS: PmTab[] = [ - { id: 'funk', label: 'Radio', icon: 'mdi-radio-handheld' }, - { id: 'log', label: 'Log', icon: 'mdi-format-list-bulleted', mobileOnly: true }, -] -const visibleTabs = computed(() => TABS) - // Send unauthenticated visitors to login while preserving where they were // headed (e.g. /live-atc?token=… so the bridge link survives the round-trip), // instead of dropping them on the classroom fallback after sign-in. @@ -944,31 +670,6 @@ onUnmounted(() => {
+ Optionally leave a short note so the dev team can follow up on the transmission. +
{{ helpContent.intro }}
- Optionally leave a short note so the dev team can follow up on the transmission. -