* fix(app): open chat file links at referenced lines Pass chat file locations through the editable CodeMirror path so opening a reference selects and scrolls to its requested line. Cover the real assistant-link flow with a browser regression. * fix(app): repeat chat file navigation Track file navigation separately from stable tab identity so reopening the same path and line recenters both editable and read-only panes. Extend the browser regression to cover moving away and clicking the same link again. * test(app): stabilize repeated file link navigation
58 lines
1.7 KiB
TypeScript
58 lines
1.7 KiB
TypeScript
import { Text, View } from "react-native";
|
|
import { useMemo } from "react";
|
|
import invariant from "tiny-invariant";
|
|
import { useTranslation } from "react-i18next";
|
|
import { FilePane } from "@/file-pane/pane";
|
|
import { usePaneContext } from "@/panels/pane-context";
|
|
import type { PanelRegistration } from "@/panels/panel-registry";
|
|
import { useWorkspaceDirectory } from "@/stores/session-store-hooks";
|
|
import { createMaterialFileIcon } from "@/components/material-file-icon";
|
|
|
|
const CENTERED_PADDED_STYLE = {
|
|
flex: 1,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
padding: 16,
|
|
} as const;
|
|
|
|
function useFilePanelDescriptor(target: { kind: "file"; path: string }) {
|
|
const fileName = target.path.split("/").findLast(Boolean) ?? target.path;
|
|
const icon = useMemo(() => createMaterialFileIcon(fileName), [fileName]);
|
|
return {
|
|
label: fileName,
|
|
subtitle: target.path,
|
|
tooltip: target.path,
|
|
titleState: "ready" as const,
|
|
icon,
|
|
statusBucket: null,
|
|
};
|
|
}
|
|
|
|
function FilePanel() {
|
|
const { t } = useTranslation();
|
|
const { serverId, workspaceId, target, fileNavigationRevision } = usePaneContext();
|
|
const workspaceDirectory = useWorkspaceDirectory(serverId, workspaceId);
|
|
invariant(target.kind === "file", "FilePanel requires file target");
|
|
if (!workspaceDirectory) {
|
|
return (
|
|
<View style={CENTERED_PADDED_STYLE}>
|
|
<Text>{t("panels.file.directoryMissing")}</Text>
|
|
</View>
|
|
);
|
|
}
|
|
return (
|
|
<FilePane
|
|
serverId={serverId}
|
|
workspaceRoot={workspaceDirectory}
|
|
location={target}
|
|
navigationRevision={fileNavigationRevision ?? 0}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export const filePanelRegistration: PanelRegistration<"file"> = {
|
|
kind: "file",
|
|
component: FilePanel,
|
|
useDescriptor: useFilePanelDescriptor,
|
|
};
|