fix: 6 UX regressions — popups, themes, cursor, selection, status bar
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m14s
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 4m14s
Cursor blinking (ACTUALLY fixed this time): - handleFocus() was STILL missing due to botched duplicate removal in v1.12.1. Now defined once at line 80, no duplicates. - vue-tsc --noEmit now runs clean (was erroring with TS2393) Tool windows: - App.vue now has onErrorCaptured + error display overlay so tool window crashes show the error instead of silently closing - defineAsyncComponent uses object form with onError callback for logging Selection highlighting: - Changed from rgba(88,166,255,0.4) transparent to solid #264f78 (VS Code's selection color) — always visible on dark backgrounds - Applied to default theme, TerminalView applyTheme, LocalTerminalView CSP: - Simplified to 'self' 'unsafe-inline' asset: for default-src - Separate connect-src for IPC protocols Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2838af4ee7
commit
c4335e0b4f
36
src/App.vue
36
src/App.vue
@ -1,19 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, defineAsyncComponent } from "vue";
|
||||
import { ref, onMounted, onErrorCaptured, defineAsyncComponent } from "vue";
|
||||
import { useAppStore } from "@/stores/app.store";
|
||||
import UnlockLayout from "@/layouts/UnlockLayout.vue";
|
||||
|
||||
const MainLayout = defineAsyncComponent(
|
||||
() => import("@/layouts/MainLayout.vue")
|
||||
);
|
||||
const ToolWindow = defineAsyncComponent(
|
||||
() => import("@/components/tools/ToolWindow.vue")
|
||||
);
|
||||
const DetachedSession = defineAsyncComponent(
|
||||
() => import("@/components/session/DetachedSession.vue")
|
||||
);
|
||||
const MainLayout = defineAsyncComponent({
|
||||
loader: () => import("@/layouts/MainLayout.vue"),
|
||||
onError(error) { console.error("[App] MainLayout load failed:", error); },
|
||||
});
|
||||
const ToolWindow = defineAsyncComponent({
|
||||
loader: () => import("@/components/tools/ToolWindow.vue"),
|
||||
onError(error) { console.error("[App] ToolWindow load failed:", error); },
|
||||
});
|
||||
const DetachedSession = defineAsyncComponent({
|
||||
loader: () => import("@/components/session/DetachedSession.vue"),
|
||||
onError(error) { console.error("[App] DetachedSession load failed:", error); },
|
||||
});
|
||||
|
||||
const app = useAppStore();
|
||||
const appError = ref<string | null>(null);
|
||||
|
||||
// Tool window mode — detected from URL hash: #/tool/network-scanner?sessionId=abc
|
||||
const isToolMode = ref(false);
|
||||
@ -21,6 +25,12 @@ const isDetachedMode = ref(false);
|
||||
const toolName = ref("");
|
||||
const toolSessionId = ref("");
|
||||
|
||||
onErrorCaptured((err) => {
|
||||
appError.value = err instanceof Error ? err.message : String(err);
|
||||
console.error("[App] Uncaught error:", err);
|
||||
return false;
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const hash = window.location.hash;
|
||||
if (hash.startsWith("#/tool/")) {
|
||||
@ -38,8 +48,12 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Error display for debugging -->
|
||||
<div v-if="appError" class="fixed inset-0 z-50 flex items-center justify-center bg-[#0d1117] text-red-400 p-8 text-sm font-mono whitespace-pre-wrap">
|
||||
{{ appError }}
|
||||
</div>
|
||||
<!-- Detached session window mode -->
|
||||
<DetachedSession v-if="isDetachedMode" />
|
||||
<DetachedSession v-else-if="isDetachedMode" />
|
||||
<!-- Tool popup window mode -->
|
||||
<ToolWindow v-else-if="isToolMode" :tool="toolName" :session-id="toolSessionId" />
|
||||
<!-- Normal app mode -->
|
||||
|
||||
@ -33,9 +33,9 @@ function applyTheme(): void {
|
||||
foreground: theme.foreground,
|
||||
cursor: theme.cursor,
|
||||
cursorAccent: theme.background,
|
||||
selectionBackground: theme.selectionBackground ?? "rgba(88, 166, 255, 0.4)",
|
||||
selectionBackground: theme.selectionBackground ?? "#264f78",
|
||||
selectionForeground: theme.selectionForeground ?? "#ffffff",
|
||||
selectionInactiveBackground: theme.selectionBackground ?? "rgba(88, 166, 255, 0.2)",
|
||||
selectionInactiveBackground: theme.selectionBackground ?? "#264f78",
|
||||
black: theme.black,
|
||||
red: theme.red,
|
||||
green: theme.green,
|
||||
|
||||
@ -77,6 +77,10 @@ const containerRef = ref<HTMLElement | null>(null);
|
||||
const { terminal, searchAddon, mount, fit } = useTerminal(props.sessionId);
|
||||
let resizeDisposable: IDisposable | null = null;
|
||||
|
||||
function handleFocus(): void {
|
||||
terminal.focus();
|
||||
}
|
||||
|
||||
// --- Search state ---
|
||||
const searchVisible = ref(false);
|
||||
const searchQuery = ref("");
|
||||
@ -152,10 +156,6 @@ onMounted(() => {
|
||||
}, 50);
|
||||
});
|
||||
|
||||
function handleFocus(): void {
|
||||
terminal.focus();
|
||||
}
|
||||
|
||||
// Re-fit and focus terminal when switching back to this tab.
|
||||
// Must wait for the container to have real dimensions after becoming visible.
|
||||
watch(
|
||||
@ -190,9 +190,9 @@ function applyTheme(): void {
|
||||
foreground: theme.foreground,
|
||||
cursor: theme.cursor,
|
||||
cursorAccent: theme.background,
|
||||
selectionBackground: theme.selectionBackground ?? "rgba(88, 166, 255, 0.4)",
|
||||
selectionBackground: theme.selectionBackground ?? "#264f78",
|
||||
selectionForeground: theme.selectionForeground ?? "#ffffff",
|
||||
selectionInactiveBackground: theme.selectionBackground ?? "rgba(88, 166, 255, 0.2)",
|
||||
selectionInactiveBackground: theme.selectionBackground ?? "#264f78",
|
||||
black: theme.black,
|
||||
red: theme.red,
|
||||
green: theme.green,
|
||||
|
||||
@ -14,8 +14,9 @@ const defaultTheme = {
|
||||
foreground: "#e0e0e0",
|
||||
cursor: "#58a6ff",
|
||||
cursorAccent: "#0d1117",
|
||||
selectionBackground: "rgba(88, 166, 255, 0.4)",
|
||||
selectionBackground: "#264f78",
|
||||
selectionForeground: "#ffffff",
|
||||
selectionInactiveBackground: "#264f78",
|
||||
black: "#0d1117",
|
||||
red: "#f85149",
|
||||
green: "#3fb950",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user