Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion apps/mobile/src/features/threads/NewTaskRouteScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import { useWorkspaceState } from "../../state/workspace";
import { useAdaptiveWorkspaceLayout } from "../layout/AdaptiveWorkspaceLayout";
import { useIncomingShare } from "../sharing/IncomingShareProvider";
import { useNewTaskFlow } from "./new-task-flow-provider";
import { getProjectScopeSelectionTarget } from "./new-task-project-selection";
import {
getProjectScopeAccessibilityLabel,
getProjectScopeSelectionTarget,
} from "./new-task-project-selection";

type NewTaskRouteParams = {
readonly incomingShareId?: string | string[];
Expand Down Expand Up @@ -217,6 +220,7 @@ export function NewTaskRouteScreen({ route }: StaticScreenProps<NewTaskRoutePara
) : null}
{catalogState.hasReadyEnvironment ? (
<NativeHeaderToolbar.Button
accessibilityLabel="Add project"
icon="plus"
onPress={() => navigation.dispatch(StackActions.push("AddProject"))}
separateBackground
Expand Down Expand Up @@ -250,6 +254,7 @@ export function NewTaskRouteScreen({ route }: StaticScreenProps<NewTaskRoutePara
</Text>
{!catalogState.hasReadyEnvironment ? (
<Pressable
accessibilityRole="button"
className="mt-1 rounded-full bg-primary px-4 py-2.5 active:opacity-70"
onPress={() => navigation.navigate("ConnectionsNew")}
>
Expand All @@ -259,6 +264,7 @@ export function NewTaskRouteScreen({ route }: StaticScreenProps<NewTaskRoutePara
</Pressable>
) : (
<Pressable
accessibilityRole="button"
className="mt-1 rounded-full bg-primary px-4 py-2.5 active:opacity-70"
onPress={() => navigation.dispatch(StackActions.push("AddProject"))}
>
Expand All @@ -279,6 +285,10 @@ export function NewTaskRouteScreen({ route }: StaticScreenProps<NewTaskRoutePara
className={cn(scopeIndex > 0 && "border-t border-border-subtle")}
>
<Pressable
accessible
accessibilityLabel={getProjectScopeAccessibilityLabel(scope, selectionTarget)}
accessibilityRole="button"
accessibilityState={{ disabled: reservedDestinationProject !== null }}
disabled={reservedDestinationProject !== null}
onPress={() => void selectProject(selectionTarget)}
className="flex-row items-center gap-3 bg-card px-4 py-3.5"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { describe, expect, it } from "vite-plus/test";
import type { EnvironmentProject } from "@t3tools/client-runtime/state/shell";
import type { HomeProjectScope } from "../home/homeThreadList";
import {
getProjectScopeAccessibilityLabel,
getProjectScopeSelectionTarget,
resolveDraftProjectSelection,
resolveEnvironmentProjectMatch,
Expand Down Expand Up @@ -53,6 +54,21 @@ function makeScope(projects: ReadonlyArray<EnvironmentProject>): HomeProjectScop
};
}

describe("getProjectScopeAccessibilityLabel", () => {
it("formats single-workspace project scopes with title and root", () => {
const project = makeProject("pylon", "mac", { workspaceRoot: "/Users/alice/pylon" });
const scope = makeScope([project]);
expect(getProjectScopeAccessibilityLabel(scope, project)).toBe("T3 Code, /Users/alice/pylon");
});

it("formats multi-workspace project scopes with count", () => {
const project1 = makeProject("pylon-mac", "mac");
const project2 = makeProject("pylon-server", "server");
const scope = makeScope([project1, project2]);
expect(getProjectScopeAccessibilityLabel(scope, project1)).toBe("T3 Code, 2 workspaces");
});
});

describe("getProjectScopeSelectionTarget", () => {
it("keeps the current environment when it hosts the selected logical project", () => {
const projects = [makeProject("t3code-mac", "mac"), makeProject("t3code-server", "server")];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ export function getProjectScopeSelectionTarget(
);
}

export function getProjectScopeAccessibilityLabel(
scope: HomeProjectScope,
selectionTarget: EnvironmentProject,
): string {
return scope.projects.length > 1
? `${scope.title}, ${scope.projects.length} workspaces`
: `${scope.title}, ${selectionTarget.workspaceRoot}`;
}

function getOnlySelectableProject(
projectScopes: ReadonlyArray<HomeProjectScope>,
): EnvironmentProject | null {
Expand Down
3 changes: 2 additions & 1 deletion patches/@react-native-menu__menu@2.0.0.patch
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ index 5c4e0da4292b15d3a27b5ea1555f11452a470815..4d8abe3c4fc45bda48c2958bc9ca933c
func setup () {
let menu = UIMenu(title: _title,
identifier: nil,
@@ -86,8 +115,98 @@ public class MenuViewImplementation: UIButton {
@@ -86,8 +115,99 @@ public class MenuViewImplementation: UIButton {
}
}

Expand All @@ -247,6 +247,7 @@ index 5c4e0da4292b15d3a27b5ea1555f11452a470815..4d8abe3c4fc45bda48c2958bc9ca933c
+ // long-press and pointer secondary-click still present the menu, with
+ // the wrapped content as the zoom preview.
+ self.isUserInteractionEnabled = !shouldOpenOnLongPress
+ self.isAccessibilityElement = !shouldOpenOnLongPress
+ self.updateLongPressInteraction()
+ }
+
Expand Down
38 changes: 10 additions & 28 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading