diff --git a/android/src/main/java/com/facebook/flipper/plugins/inspector/InspectorFlipperPlugin.java b/android/src/main/java/com/facebook/flipper/plugins/inspector/InspectorFlipperPlugin.java index d1925a631..95d6a0187 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/inspector/InspectorFlipperPlugin.java +++ b/android/src/main/java/com/facebook/flipper/plugins/inspector/InspectorFlipperPlugin.java @@ -37,6 +37,12 @@ public class InspectorFlipperPlugin implements FlipperPlugin { private @Nullable List mExtensionCommands; private boolean mShowLithoAccessibilitySettings; + public enum IDE { + diffusion, + AS, + VSCode + } + /** An interface for extensions to the Inspector Flipper plugin */ public interface ExtensionCommand { /** The command to respond to */ @@ -419,6 +425,23 @@ public class InspectorFlipperPlugin implements FlipperPlugin { } }; + public boolean openInIDE( + String fileName, String className, String dirRoot, String repo, int lineNumber, IDE ide) { + if (mConnection == null) return false; + + mConnection.send( + "openInIDE", + new FlipperObject.Builder() + .put("fileName", fileName) + .put("className", className) + .put("dirRoot", dirRoot) + .put("repo", repo) + .put("lineNumber", lineNumber) + .put("ide", ide) + .build()); + return true; + } + private void setHighlighted( final String id, final boolean highlighted, final boolean isAlignmentMode) throws Exception { final Object obj = mObjectTracker.get(id); diff --git a/desktop/plugins/layout/index.tsx b/desktop/plugins/layout/index.tsx index 04e298cf6..591f97581 100644 --- a/desktop/plugins/layout/index.tsx +++ b/desktop/plugins/layout/index.tsx @@ -31,6 +31,12 @@ import ProxyArchiveClient from './ProxyArchiveClient'; import React from 'react'; import {VisualizerPortal} from 'flipper'; import {getFlipperMediaCDN} from 'flipper'; +import { + resolveFullPathsFromMyles, + getBestPath, + IDE, + openInIDE, +} from '../../app/src/fb-stubs/FileResolver'; type State = { init: boolean; @@ -57,6 +63,15 @@ export type PersistedState = { type ClientGetNodesCalls = 'getNodes' | 'getAXNodes'; type ClientMethodCalls = 'getRoot' | 'getAXRoot' | ClientGetNodesCalls; +type ClassFileParams = { + fileName: string; + className: string; + dirRoot: string; + repo: string; + lineNumber: number; + ide: IDE; +}; + export default class LayoutPlugin extends FlipperPlugin< State, any, @@ -205,6 +220,10 @@ export default class LayoutPlugin extends FlipperPlugin< } }); + this.client.subscribe('openInIDE', (params: ClassFileParams) => { + this.openInIDE(params); + }); + if (this.props.isArchivedDevice) { this.getDevice() .then((d) => { @@ -229,6 +248,19 @@ export default class LayoutPlugin extends FlipperPlugin< }); } + openInIDE = async (params: ClassFileParams) => { + const paths = await resolveFullPathsFromMyles( + params.fileName, + params.dirRoot, + ); + const selectedPath = getBestPath(paths, params.className); + let ide: IDE = Number(IDE[params.ide]); + if (Number.isNaN(ide)) { + ide = IDE.AS; // default value + } + openInIDE(selectedPath, ide, params.repo, params.lineNumber); + }; + onToggleTargetMode = () => { const inTargetMode = !this.state.inTargetMode; this.setState({inTargetMode});