folder增加项目启动器入口,优化窗口跳转
This commit is contained in:
@@ -610,13 +610,22 @@ pub async fn open_push_window(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn open_project_boot_window(app: AppHandle) -> Result<(), AppCommandError> {
|
||||
pub async fn open_project_boot_window(
|
||||
app: AppHandle,
|
||||
source: Option<String>,
|
||||
) -> Result<(), AppCommandError> {
|
||||
if let Some(existing) = app.get_webview_window("project-boot") {
|
||||
ensure_windows_undecorated(&existing);
|
||||
let _ = existing.unminimize();
|
||||
existing.set_focus().map_err(|e| {
|
||||
AppCommandError::window("Failed to focus project boot window", e.to_string())
|
||||
})?;
|
||||
// Close welcome if opened from welcome
|
||||
if source.as_deref() == Some("welcome") {
|
||||
if let Some(w) = app.get_webview_window("welcome") {
|
||||
let _ = w.close();
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -633,5 +642,12 @@ pub async fn open_project_boot_window(app: AppHandle) -> Result<(), AppCommandEr
|
||||
})?;
|
||||
ensure_windows_undecorated(&window);
|
||||
|
||||
// Close welcome if opened from welcome
|
||||
if source.as_deref() == Some("welcome") {
|
||||
if let Some(w) = app.get_webview_window("welcome") {
|
||||
let _ = w.close();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -140,6 +140,24 @@ pub fn run() {
|
||||
});
|
||||
}
|
||||
|
||||
if label == "project-boot"
|
||||
&& matches!(
|
||||
event,
|
||||
tauri::WindowEvent::CloseRequested { .. } | tauri::WindowEvent::Destroyed
|
||||
)
|
||||
{
|
||||
let app = window.app_handle();
|
||||
if !APP_QUITTING.load(Ordering::Relaxed) {
|
||||
let has_other = app
|
||||
.webview_windows()
|
||||
.keys()
|
||||
.any(|l| *l != label && *l != "settings");
|
||||
if !has_other {
|
||||
let _ = windows::open_welcome_window(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let tauri::WindowEvent::CloseRequested { .. } = event {
|
||||
if label.starts_with("folder-") {
|
||||
let app = window.app_handle();
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { ChevronDown, Folder, FolderOpen, GitBranch } from "lucide-react"
|
||||
import {
|
||||
ChevronDown,
|
||||
Folder,
|
||||
FolderOpen,
|
||||
GitBranch,
|
||||
Rocket,
|
||||
} from "lucide-react"
|
||||
import { useTranslations } from "next-intl"
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -16,6 +22,7 @@ import {
|
||||
listOpenFolders,
|
||||
loadFolderHistory,
|
||||
openFolderWindow,
|
||||
openProjectBootWindow,
|
||||
} from "@/lib/api"
|
||||
import { openFileDialog } from "@/lib/platform"
|
||||
import { useFolderContext } from "@/contexts/folder-context"
|
||||
@@ -87,6 +94,10 @@ export function FolderNameDropdown() {
|
||||
<GitBranch className="h-3.5 w-3.5 shrink-0" />
|
||||
{t("cloneRepository")}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onSelect={() => openProjectBootWindow()}>
|
||||
<Rocket className="h-3.5 w-3.5 shrink-0" />
|
||||
{t("projectBoot")}
|
||||
</DropdownMenuItem>
|
||||
{openFolders.length > 0 && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
@@ -302,9 +302,7 @@ export function FolderTitleBar() {
|
||||
<span
|
||||
className={cn(
|
||||
"grid transition-[grid-template-columns] duration-300",
|
||||
isActive
|
||||
? "grid-cols-[1fr]"
|
||||
: "grid-cols-[0fr]"
|
||||
isActive ? "grid-cols-[1fr]" : "grid-cols-[0fr]"
|
||||
)}
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
"use client"
|
||||
|
||||
import { useTranslations } from "next-intl"
|
||||
import {
|
||||
Tabs,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
TabsContent,
|
||||
} from "@/components/ui/tabs"
|
||||
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
|
||||
import { ShadcnLauncher } from "./shadcn/shadcn-launcher"
|
||||
|
||||
export function ProjectBootWorkspace() {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
// ── Preset encoding/decoding (matches shadcn v2 format) ─────────────
|
||||
|
||||
const PRESET_STYLES = [
|
||||
"nova",
|
||||
"vega",
|
||||
"maia",
|
||||
"lyra",
|
||||
"mira",
|
||||
] as const
|
||||
const PRESET_STYLES = ["nova", "vega", "maia", "lyra", "mira"] as const
|
||||
|
||||
const PRESET_BASE_COLORS = [
|
||||
"neutral",
|
||||
@@ -84,13 +78,7 @@ const PRESET_FONTS = [
|
||||
|
||||
const PRESET_FONT_HEADINGS = ["inherit", ...PRESET_FONTS] as const
|
||||
|
||||
const PRESET_RADII = [
|
||||
"default",
|
||||
"none",
|
||||
"small",
|
||||
"medium",
|
||||
"large",
|
||||
] as const
|
||||
const PRESET_RADII = ["default", "none", "small", "medium", "large"] as const
|
||||
|
||||
const PRESET_MENU_ACCENTS = ["subtle", "bold"] as const
|
||||
|
||||
@@ -115,8 +103,7 @@ const PRESET_FIELDS_V2 = [
|
||||
{ key: "fontHeading", values: PRESET_FONT_HEADINGS, bits: 5 },
|
||||
] as const
|
||||
|
||||
const BASE62 =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
function toBase62(num: number): string {
|
||||
if (num === 0) return "0"
|
||||
|
||||
@@ -14,12 +14,7 @@ import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Switch } from "@/components/ui/switch"
|
||||
import {
|
||||
Tabs,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
TabsContent,
|
||||
} from "@/components/ui/tabs"
|
||||
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
import {
|
||||
Field,
|
||||
|
||||
@@ -52,7 +52,11 @@ const CONFIG_FIELDS: {
|
||||
options: { value: string; label: string }[]
|
||||
}[] = [
|
||||
{ key: "style", i18nKey: "config.style", options: STYLE_OPTIONS },
|
||||
{ key: "baseColor", i18nKey: "config.baseColor", options: BASE_COLOR_OPTIONS },
|
||||
{
|
||||
key: "baseColor",
|
||||
i18nKey: "config.baseColor",
|
||||
options: BASE_COLOR_OPTIONS,
|
||||
},
|
||||
{ key: "theme", i18nKey: "config.theme", options: THEME_OPTIONS },
|
||||
{ key: "chartColor", i18nKey: "config.chartColor", options: THEME_OPTIONS },
|
||||
{
|
||||
@@ -66,8 +70,16 @@ const CONFIG_FIELDS: {
|
||||
i18nKey: "config.fontHeading",
|
||||
options: FONT_HEADING_OPTIONS,
|
||||
},
|
||||
{ key: "menuAccent", i18nKey: "config.menuAccent", options: MENU_ACCENT_OPTIONS },
|
||||
{ key: "menuColor", i18nKey: "config.menuColor", options: MENU_COLOR_OPTIONS },
|
||||
{
|
||||
key: "menuAccent",
|
||||
i18nKey: "config.menuAccent",
|
||||
options: MENU_ACCENT_OPTIONS,
|
||||
},
|
||||
{
|
||||
key: "menuColor",
|
||||
i18nKey: "config.menuColor",
|
||||
options: MENU_COLOR_OPTIONS,
|
||||
},
|
||||
{ key: "radius", i18nKey: "config.radius", options: RADIUS_OPTIONS },
|
||||
{ key: "template", i18nKey: "config.template", options: TEMPLATE_OPTIONS },
|
||||
]
|
||||
|
||||
@@ -56,7 +56,7 @@ export function FolderActions() {
|
||||
className="justify-start gap-2 h-9"
|
||||
onClick={async () => {
|
||||
try {
|
||||
await openProjectBootWindow()
|
||||
await openProjectBootWindow("welcome")
|
||||
} catch (err) {
|
||||
console.error("[FolderActions] failed to open project boot:", err)
|
||||
toast.error(t("toasts.openProjectBootFailed"))
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "مجلد",
|
||||
"openFolder": "فتح مجلد",
|
||||
"cloneRepository": "استنساخ المستودع",
|
||||
"projectBoot": "مُنشئ المشروع",
|
||||
"opened": "مفتوح",
|
||||
"recentOpen": "المفتوح مؤخرًا"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "Ordner",
|
||||
"openFolder": "Ordner öffnen",
|
||||
"cloneRepository": "Repository klonen",
|
||||
"projectBoot": "Projekt-Boot",
|
||||
"opened": "Geöffnet",
|
||||
"recentOpen": "Zuletzt geöffnet"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "Folder",
|
||||
"openFolder": "Open Folder",
|
||||
"cloneRepository": "Clone Repository",
|
||||
"projectBoot": "Project Boot",
|
||||
"opened": "Opened",
|
||||
"recentOpen": "Recently Opened"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "Carpeta",
|
||||
"openFolder": "Abrir carpeta",
|
||||
"cloneRepository": "Clonar repositorio",
|
||||
"projectBoot": "Inicializador de proyecto",
|
||||
"opened": "Abierto",
|
||||
"recentOpen": "Abiertos recientemente"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "Dossier",
|
||||
"openFolder": "Ouvrir le dossier",
|
||||
"cloneRepository": "Cloner le dépôt",
|
||||
"projectBoot": "Lanceur de projet",
|
||||
"opened": "Ouvert",
|
||||
"recentOpen": "Ouvert récemment"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "フォルダ",
|
||||
"openFolder": "フォルダを開く",
|
||||
"cloneRepository": "リポジトリをクローン",
|
||||
"projectBoot": "プロジェクトブート",
|
||||
"opened": "開いているフォルダ",
|
||||
"recentOpen": "最近開いたフォルダ"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "폴더",
|
||||
"openFolder": "폴더 열기",
|
||||
"cloneRepository": "리포지토리 클론",
|
||||
"projectBoot": "프로젝트 부트",
|
||||
"opened": "열린 항목",
|
||||
"recentOpen": "최근 연 항목"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "Pasta",
|
||||
"openFolder": "Abrir pasta",
|
||||
"cloneRepository": "Clonar repositório",
|
||||
"projectBoot": "Inicializador de projeto",
|
||||
"opened": "Aberto",
|
||||
"recentOpen": "Abertos recentemente"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "文件夹",
|
||||
"openFolder": "打开文件夹",
|
||||
"cloneRepository": "克隆仓库",
|
||||
"projectBoot": "项目启动器",
|
||||
"opened": "已打开",
|
||||
"recentOpen": "最近打开"
|
||||
},
|
||||
|
||||
@@ -856,6 +856,7 @@
|
||||
"fallbackFolderName": "資料夾",
|
||||
"openFolder": "打開資料夾",
|
||||
"cloneRepository": "複製倉庫",
|
||||
"projectBoot": "專案啟動器",
|
||||
"opened": "已打開",
|
||||
"recentOpen": "最近打開"
|
||||
},
|
||||
|
||||
@@ -952,9 +952,9 @@ export async function openSettingsWindow(
|
||||
window.open(result.path, `settings-${section ?? "general"}`)
|
||||
}
|
||||
|
||||
export async function openProjectBootWindow(): Promise<void> {
|
||||
export async function openProjectBootWindow(source?: string): Promise<void> {
|
||||
if (getTransport().isDesktop()) {
|
||||
return getTransport().call("open_project_boot_window")
|
||||
return getTransport().call("open_project_boot_window", { source })
|
||||
}
|
||||
window.open("/project-boot", "project-boot")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user