fix: 去除路由改为 Store 控制当前激活 Tab
This commit is contained in:
parent
cc3a8984c1
commit
ff35f5b105
|
|
@ -1,5 +1,3 @@
|
|||
import { useEffect } from "react";
|
||||
import { useLocation, useNavigate } from "react-router";
|
||||
import { X } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useProjectTabsStore } from "@/store/project-tabs-store";
|
||||
|
|
@ -10,16 +8,6 @@ export function ProjectTabsBar() {
|
|||
const activateTab = useProjectTabsStore((state) => state.activateTab);
|
||||
const activateHome = useProjectTabsStore((state) => state.activateHome);
|
||||
const closeTab = useProjectTabsStore((state) => state.closeTab);
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
const active = tabs.find((tab) => tab.id === activeTabId);
|
||||
if (!active) return;
|
||||
const targetPath = active.kind === "home" ? "/" : `/editor/${active.projectId}`;
|
||||
if (location.pathname === targetPath) return;
|
||||
navigate(targetPath);
|
||||
}, [activeTabId, tabs, location.pathname, navigate]);
|
||||
|
||||
function handleSelect(tabId: string, kind: "home" | "project") {
|
||||
if (kind === "home") activateHome();
|
||||
|
|
|
|||
26
src/main.tsx
26
src/main.tsx
|
|
@ -1,26 +1,26 @@
|
|||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { createHashRouter } from "react-router";
|
||||
import { RouterProvider } from "react-router/dom";
|
||||
import "./index.css";
|
||||
import Home from "./pages/home.tsx";
|
||||
import Editor from "./pages/editor.tsx";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { useProjectTabsStore } from "@/store/project-tabs-store";
|
||||
|
||||
const router = createHashRouter([
|
||||
{
|
||||
path: "/",
|
||||
element: <Home />,
|
||||
},
|
||||
{
|
||||
path: "/editor/:id",
|
||||
element: <Editor />,
|
||||
},
|
||||
]);
|
||||
function App() {
|
||||
const tabs = useProjectTabsStore((state) => state.tabs);
|
||||
const activeTabId = useProjectTabsStore((state) => state.activeTabId);
|
||||
const active = tabs.find((tab) => tab.id === activeTabId);
|
||||
|
||||
if (active?.kind === "project") {
|
||||
return <Editor projectId={active.projectId} />;
|
||||
}
|
||||
|
||||
return <Home />;
|
||||
}
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<RouterProvider router={router} />
|
||||
<App />
|
||||
<Toaster position="top-center" />
|
||||
</StrictMode>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import type React from "react";
|
||||
import { useParams, useNavigate } from "react-router";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
|
|
@ -18,7 +17,7 @@ import {
|
|||
updateProject,
|
||||
deleteProjectDeep,
|
||||
} from "@/lib/db";
|
||||
import { ArrowBigDownDash, ArrowBigUpDash, Brackets, CaseSensitive, Filter, FolderOpen, Languages, LocateFixed, MoreVertical, PencilLine, Reply, Save, Settings, Trash2 } from "lucide-react";
|
||||
import { ArrowBigDownDash, ArrowBigUpDash, Brackets, CaseSensitive, Filter, FolderOpen, Languages, LocateFixed, MoreVertical, PencilLine, Save, Settings, Trash2 } from "lucide-react";
|
||||
import { useTranslationInlineEdit } from "@/hooks/biz/use-translation-inline-edit";
|
||||
import { buildStructureFromObject, flattenEntries, flattenValues, type FlatEntry, insertEntrySibling, removeEntryAtPath, renameEntryAtPath, moveEntryByOffset } from "@/lib/i18n-structure";
|
||||
import { ImportLanguageModal } from "@/components/biz/import-language-modal";
|
||||
|
|
@ -51,9 +50,11 @@ import { loadNativeProjectSources, saveNativeLanguageFile, type LoadedProjectSou
|
|||
import { useProjectSourcesStore } from "@/store/sources-store";
|
||||
import CommonMenubar, { type CommonMenubarItem } from "@/components/biz/editor/common-menubar";
|
||||
|
||||
export default function Editor() {
|
||||
const { id: projectId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
type EditorProps = {
|
||||
projectId?: string;
|
||||
};
|
||||
|
||||
export default function Editor({ projectId }: EditorProps) {
|
||||
const [project, setProject] = useState<Project | null>(null);
|
||||
const [structure, setStructure] = useState<ProjectStructure | null>(null);
|
||||
const [languages, setLanguages] = useState<string[]>([]);
|
||||
|
|
@ -605,23 +606,6 @@ export default function Editor() {
|
|||
<CommonMenubar disabledItems={disabledItems} onClickItem={onClickItem} />
|
||||
<div className="flex items-center justify-end gap-2 text-foreground">
|
||||
<HeaderConnectionIndicator projectId={projectId ?? ""} />
|
||||
{!structure ? (
|
||||
<Button onClick={() => { setSourcesWizardOpen(true); }}>
|
||||
<FolderOpen />
|
||||
通过目录导入
|
||||
</Button>
|
||||
) : (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" onClick={() => { setSourcesWizardOpen(true); }}>
|
||||
<FolderOpen />
|
||||
目录导入
|
||||
</Button>
|
||||
<Button variant="outline" onClick={() => { setImportOpen(true); }}>
|
||||
<Reply />
|
||||
单文件导入
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{projectId && (
|
||||
<SyncFromFilesButton
|
||||
projectId={projectId ?? ""}
|
||||
|
|
@ -640,9 +624,9 @@ export default function Editor() {
|
|||
</Button>
|
||||
)}
|
||||
{project && (
|
||||
<Button variant="outline" onClick={() => setSettingsOpen(true)}>
|
||||
<Button variant="ghost" onClick={() => setSettingsOpen(true)}>
|
||||
<Settings />
|
||||
设置
|
||||
<span className="sr-only">设置</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -832,7 +816,6 @@ export default function Editor() {
|
|||
await deleteProjectDeep(projectId);
|
||||
forgetProjectInTabs(projectId);
|
||||
activateHomeTab();
|
||||
navigate("/");
|
||||
}}
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { createProject, deleteProjectDeep, listProjects, type Project, updateProject } from "@/lib/db";
|
||||
|
|
@ -26,7 +25,6 @@ function App() {
|
|||
const [error, setError] = useState<string | null>(null);
|
||||
const [settingsOpen, setSettingsOpen] = useState(false);
|
||||
const [currentProject, setCurrentProject] = useState<Project | null>(null);
|
||||
const navigate = useNavigate();
|
||||
const flags = useConnectionFlags();
|
||||
const activateHomeTab = useProjectTabsStore((state) => state.activateHome);
|
||||
const registerProjectsInTabs = useProjectTabsStore((state) => state.registerProjects);
|
||||
|
|
@ -119,14 +117,12 @@ function App() {
|
|||
className="relative cursor-pointer rounded-md border p-4 transition hover:shadow-sm"
|
||||
onClick={() => {
|
||||
openProjectTab(p);
|
||||
navigate(`/editor/${p.id}`);
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
openProjectTab(p);
|
||||
navigate(`/editor/${p.id}`);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -227,7 +227,8 @@ export const useProjectTabsStore = create<ProjectTabsStore>((set, get) => ({
|
|||
get().closeProjectTab(projectId);
|
||||
set((state) => {
|
||||
if (!state.projectIndex[projectId]) return state;
|
||||
const { [projectId]: _removed, ...rest } = state.projectIndex;
|
||||
|
||||
const { [projectId]: _removed, ...rest } = state.projectIndex; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
return {
|
||||
projectIndex: rest,
|
||||
lastActiveProjectId: state.lastActiveProjectId === projectId ? null : state.lastActiveProjectId,
|
||||
|
|
|
|||
Loading…
Reference in New Issue