refactor(tests): normalize recent project paths and improve readability

refactor(proposed-changes-panel): simplify JSX structure for added/removed indicators
refactor(pdf-viewer): format function parameters for better readability
fix(project-name): enhance validation for project names to prevent invalid characters
refactor(build): improve environment flag handling for better clarity
refactor(dev): streamline environment flag appending logic
This commit is contained in:
Gerard-Devlin 2026-06-12 22:34:42 +08:00
parent 3c5650b618
commit 65645394e6
6 changed files with 31 additions and 15 deletions

View file

@ -32,8 +32,12 @@ describe("useProjectStore", () => {
it("normalizes trailing separators when deduplicating", () => {
const store = useProjectStore.getState();
store.addRecentProject("C:\\Users\\Devlin\\Documents\\ClaudePrism\\paper\\");
store.addRecentProject("C:\\Users\\Devlin\\Documents\\ClaudePrism\\paper");
store.addRecentProject(
"C:\\Users\\Devlin\\Documents\\ClaudePrism\\paper\\",
);
store.addRecentProject(
"C:\\Users\\Devlin\\Documents\\ClaudePrism\\paper",
);
const { recentProjects } = useProjectStore.getState();
expect(recentProjects).toHaveLength(1);
expect(recentProjects[0]).toMatchObject({
@ -92,12 +96,12 @@ describe("useProjectStore", () => {
path: "/work/new",
name: "new",
});
expect(recentProjects.some((project) => project.path === "/work/old")).toBe(
false,
);
expect(recentProjects.some((project) => project.path === "/work/other")).toBe(
true,
);
expect(
recentProjects.some((project) => project.path === "/work/old"),
).toBe(false);
expect(
recentProjects.some((project) => project.path === "/work/other"),
).toBe(true);
});
it("matches renamed paths even when the old recent path has a trailing slash", () => {

View file

@ -62,9 +62,7 @@ export const ProposedChangesPanel: FC<ProposedChangesPanelProps> = ({
{change.toolName}
</span>
)}
{added > 0 && (
<span className="shrink-0 text-green-400">+{added}</span>
)}
{added > 0 && <span className="shrink-0 text-green-400">+{added}</span>}
{removed > 0 && (
<span className="shrink-0 text-red-400">-{removed}</span>
)}

View file

@ -87,7 +87,10 @@ function clampZoomFactor(factor: number, maxFactor: number): number {
return Math.max(1 / maxFactor, Math.min(maxFactor, factor));
}
function getWheelZoomFactor(event: WheelEvent, isTrackpadPinch: boolean): number {
function getWheelZoomFactor(
event: WheelEvent,
isTrackpadPinch: boolean,
): number {
if (event.deltaY === 0) return 1;
if (

View file

@ -8,7 +8,14 @@ export function getProjectNameError(name: string): string | null {
if (trimmed === "." || trimmed === "..") {
return "Project name cannot be . or ..";
}
if (/[\x00-\x1f\\/<>:"|?*]/.test(trimmed) || /[\s.]$/.test(trimmed)) {
const hasControlCharacter = Array.from(trimmed).some(
(char) => char.charCodeAt(0) < 32,
);
if (
hasControlCharacter ||
/[\\/<>:"|?*]/.test(trimmed) ||
/[\s.]$/.test(trimmed)
) {
return "Project name contains characters Windows cannot use";
}
return null;

View file

@ -5,7 +5,9 @@ const env = { ...process.env };
function appendEnvFlag(name, flag) {
const current = env[name] ?? "";
env[name] = current.includes(flag) ? current : [current, flag].filter(Boolean).join(" ");
env[name] = current.includes(flag)
? current
: [current, flag].filter(Boolean).join(" ");
}
if (process.platform === "win32") {

View file

@ -5,7 +5,9 @@ const env = { ...process.env };
function appendEnvFlag(name, flag) {
const current = env[name] ?? "";
env[name] = current.includes(flag) ? current : [current, flag].filter(Boolean).join(" ");
env[name] = current.includes(flag)
? current
: [current, flag].filter(Boolean).join(" ");
}
if (process.platform === "win32") {