uno mas lil dip

This commit is contained in:
firestar5683
2026-09-08 21:15:21 -05:00
parent ca3d8a3816
commit a33bec1ca4
6 changed files with 67 additions and 53 deletions
@@ -1,15 +1,35 @@
import { BluetoothPanel } from "../components/BluetoothPanel.js"
import { WheelControls } from "../components/WheelControls.js"
import { GalaxySection } from "../components/GalaxySection.js"
import { GalaxyTabs } from "../components/GalaxyTabs.js"
import { useTabRouting } from "../composables.js"
const TABS = {
bluetooth: "Bluetooth",
controllers: "Controllers",
}
export const Bluetooth = {
name: "Bluetooth",
components: { BluetoothPanel, GalaxySection },
components: { BluetoothPanel, WheelControls, GalaxySection, GalaxyTabs },
setup() {
return useTabRouting("/bluetooth", { bluetooth: "bluetooth", controllers: "controllers" })
},
data() { return { TABS } },
template: `
<div class="gx-view">
<h2 style="margin-top:0;">Bluetooth</h2>
<GalaxySection title="Bluetooth Devices" icon="bi-bluetooth" :collapsible="false">
<BluetoothPanel />
</GalaxySection>
<GalaxyTabs :items="TABS" :active="tab" @select="selectTab" />
<template v-if="tab === 'bluetooth'">
<GalaxySection title="Bluetooth Devices" icon="bi-bluetooth" :collapsible="false">
<BluetoothPanel />
</GalaxySection>
</template>
<template v-else>
<WheelControls />
</template>
</div>
`,
}
@@ -4,11 +4,11 @@ import { PwaInstallSection, isFirestarOrigin } from "../components/PwaInstallSec
const isTunnel = () => isFirestarOrigin()
function localDeviceUrl(ip) {
function localDeviceUrl(ip, route = "/") {
const raw = String(ip || "").trim()
if (!raw || raw === "unknown") return ""
const host = raw.includes(":") && !raw.startsWith("[") ? `[${raw}]` : raw
return `http://${host}:8082`
return `http://${host}:8082/#${route}`
}
export const Galaxy = {
@@ -28,7 +28,7 @@ export const Galaxy = {
if (this.isTunnel) {
try {
const status = await api.getDeviceStatus()
this.localUrl = localDeviceUrl(status?.lanIp)
this.localUrl = localDeviceUrl(status?.lanIp, "/galaxy")
} catch (e) {}
return
}
@@ -92,7 +92,10 @@ export const Galaxy = {
<strong>Galaxy Pairing Unavailable via Galaxy</strong>
<span>
Galaxy pairing requires a direct connection. If you are on the same local network, connect here:
<a v-if="localUrl" :href="localUrl" style="color:inherit; font-weight:var(--fw-bold); overflow-wrap:anywhere;">{{ localUrl }}</a>
<br />
<a v-if="localUrl" class="gx-btn gx-btn--tonal" :href="localUrl" style="margin-top:var(--sp-3);">
<i class="bi bi-box-arrow-up-right"></i> Open Galaxy Locally
</a>
<span v-else>your device's local IP on port 8082.</span>
</span>
</div>
@@ -52,11 +52,11 @@ function normalizeRoute(r) {
}
}
function localDeviceUrl(ip) {
function localDeviceUrl(ip, route = "/") {
const raw = String(ip || "").trim()
if (!raw || raw === "unknown") return ""
const host = raw.includes(":") && !raw.startsWith("[") ? `[${raw}]` : raw
return `http://${host}:8082`
return `http://${host}:8082/#${route}`
}
export const Recordings = {
@@ -346,7 +346,7 @@ export const Recordings = {
if (this.onFirestar) {
try {
const status = await api.getDeviceStatus()
this.localUrl = localDeviceUrl(status?.lanIp)
this.localUrl = localDeviceUrl(status?.lanIp, "/recordings")
} catch (e) {}
return
}
@@ -520,7 +520,10 @@ export const Recordings = {
<GxNotice v-else tone="info" icon="bi-satellite" title="Recordings unavailable via Galaxy">
Recordings are unavailable via Galaxy for bandwidth reasons. If you are on the same local network, connect here:
<a v-if="localUrl" :href="localUrl" style="color:inherit; font-weight:var(--fw-bold); overflow-wrap:anywhere;">{{ localUrl }}</a>
<br />
<a v-if="localUrl" class="gx-btn gx-btn--tonal" :href="localUrl" style="margin-top:var(--sp-3);">
<i class="bi bi-box-arrow-up-right"></i> Open Recordings Locally
</a>
<span v-else>your device's local IP on port 8082.</span>
</GxNotice>
</div>
@@ -11,7 +11,7 @@ const TOOLS = [
{ name: "System Tools", link: "/system", icon: "bi-arrow-repeat", desc: "Backup, restore, updates" },
{ name: "Theme Maker", link: "/theme_maker", icon: "bi-palette-fill", desc: "Customize the look" },
{ name: "Tuning, Plots & Testing", link: "/tuning", icon: "bi-sign-turn-right", desc: "Steering & speed tuning, live plots, testing grounds" },
{ name: "Vehicle Controls", link: "/vehicle", icon: "bi-car-front", desc: "Controllers & vehicle features" },
{ name: "Vehicle Controls", link: "/vehicle", icon: "bi-car-front", desc: "Vehicle features" },
].sort((a, b) => a.name.localeCompare(b.name))
export const Tools = {
@@ -1,34 +1,22 @@
import { api, showSnackbar } from "../api.js"
import { navigate, toolHref } from "../store.js"
import { WheelControls } from "../components/WheelControls.js"
import { GalaxySection } from "../components/GalaxySection.js"
import { GalaxyTabs } from "../components/GalaxyTabs.js"
import { useTabRouting } from "../composables.js"
const FEATURES = [
{ key: "doors", name: "Lock/Unlock Doors", icon: "bi-door-closed", desc: "Send lock or unlock commands remotely to your vehicle.", embed: "/manage_doors" },
{ key: "tsk", name: "Toyota Security Keys", icon: "bi-key-fill", desc: "Manage and apply security keys for secOC protected devices.", embed: "/manage_tsk" },
]
const TABS = {
controllers: "Controllers",
features: "Vehicle Features",
}
export const Vehicle = {
name: "Vehicle",
components: { WheelControls, GalaxySection, GalaxyTabs },
components: { GalaxySection },
data() {
return {
TABS,
features: FEATURES,
featureStatus: {},
busy: "",
}
},
setup() {
return useTabRouting("/vehicle", { controllers: "controllers", features: "features" })
},
computed: {
featureList() { return this.features },
},
@@ -63,30 +51,22 @@ export const Vehicle = {
<div class="gx-view">
<h2 style="margin-top:0;">Vehicle Controls</h2>
<GalaxyTabs :items="TABS" :active="tab" @select="selectTab" />
<template v-if="tab === 'controllers'">
<WheelControls />
</template>
<template v-else>
<GalaxySection title="Vehicle Features" icon="bi-check2-square">
<div style="padding: var(--sp-3); display:grid; gap:8px;">
<button v-for="f in featureList" :key="f.key" type="button"
class="gx-row" style="width:100%; border:none; background:transparent; color:inherit; cursor:pointer; text-align:left;"
@click="openFeature(f)">
<div class="gx-row__info">
<span class="gx-row__label"><i class="bi" :class="f.icon" style="margin-right:6px; color:var(--primary);"></i>{{ f.name }}</span>
<span class="gx-row__desc">{{ f.desc }}</span>
</div>
<span v-if="busy === f.key" class="gx-chip" style="background:var(--surface-variant);">Checking...</span>
<span v-else-if="statusOf(f.key) === 'denied'" class="gx-chip" style="background:var(--error);">Not supported</span>
<i v-else class="bi bi-chevron-right" style="color:var(--text-muted);"></i>
</button>
<p style="color:var(--text-muted); margin:0;">These features verify vehicle compatibility when launched.</p>
</div>
</GalaxySection>
</template>
<GalaxySection title="Vehicle Features" icon="bi-check2-square">
<div style="padding: var(--sp-3); display:grid; gap:8px;">
<button v-for="f in featureList" :key="f.key" type="button"
class="gx-row" style="width:100%; border:none; background:transparent; color:inherit; cursor:pointer; text-align:left;"
@click="openFeature(f)">
<div class="gx-row__info">
<span class="gx-row__label"><i class="bi" :class="f.icon" style="margin-right:6px; color:var(--primary);"></i>{{ f.name }}</span>
<span class="gx-row__desc">{{ f.desc }}</span>
</div>
<span v-if="busy === f.key" class="gx-chip" style="background:var(--surface-variant);">Checking...</span>
<span v-else-if="statusOf(f.key) === 'denied'" class="gx-chip" style="background:var(--error);">Not supported</span>
<i v-else class="bi bi-chevron-right" style="color:var(--text-muted);"></i>
</button>
<p style="color:var(--text-muted); margin:0;">These features verify vehicle compatibility when launched.</p>
</div>
</GalaxySection>
</div>
`,
}
@@ -126,8 +126,8 @@ def test_ui_ports_all_tool_views():
assert ep in src, f"{rel} should use api.{ep}"
vehicle = _read("js/views/Vehicle.js")
bluetooth = _read("js/views/Bluetooth.js")
assert "WheelControls" in vehicle and "BluetoothPanel" not in vehicle and "carFeaturesCheck" in vehicle
assert "BluetoothPanel" in bluetooth
assert "WheelControls" not in vehicle and "BluetoothPanel" not in vehicle and "carFeaturesCheck" in vehicle
assert "BluetoothPanel" in bluetooth and "WheelControls" in bluetooth
def test_ui_routes_ported_views_natively_no_classic_fallback():
@@ -233,9 +233,13 @@ def test_ui_schema_driven_param_engine_reused():
assert "GalaxyEmbed" not in tuning and 'src="/tuning"' not in tuning, "Tuning must be native, not a classic embed"
assert "LateralTuningPanel" in tuning and "LongitudinalManeuvers" not in tuning
vehicle = _read("js/views/Vehicle.js")
bluetooth = _read("js/views/Bluetooth.js")
assert "ParamSections" not in vehicle, "Vehicle must not render redundant toggles"
assert "WheelControls" in vehicle and "BluetoothPanel" not in vehicle
assert "WheelControls" not in vehicle and "BluetoothPanel" not in vehicle
assert "GalaxySection" in vehicle
assert "WheelControls" in bluetooth and "BluetoothPanel" in bluetooth
assert bluetooth.index('bluetooth: "Bluetooth"') < bluetooth.index('controllers: "Controllers"')
assert 'useTabRouting("/bluetooth"' in bluetooth
engine = _read("js/components/ParamSections.js")
assert "SettingTree" in engine
assert "isSettingVisible" in engine
@@ -517,6 +521,10 @@ def test_ui_mobile_polish_regressions():
assert "bandwidth reasons" in recordings and "status?.lanIp" in recordings
assert "status?.lanIp" in galaxy
assert ':href="localUrl"' in recordings and ':href="localUrl"' in galaxy
assert 'localDeviceUrl(status?.lanIp, "/recordings")' in recordings
assert 'localDeviceUrl(status?.lanIp, "/galaxy")' in galaxy
assert "gx-btn gx-btn--tonal" in recordings and "Open Recordings Locally" in recordings
assert "gx-btn gx-btn--tonal" in galaxy and "Open Galaxy Locally" in galaxy
home = _read("js/views/Home.js")
home_css = _read("css/home.css")