mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-09 17:53:45 +08:00
uno mas lil dip
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user