Merge pull request #3802 from asgerf/asgerf/use-message-from-extension
Add useMessageFromExtension hook
This commit is contained in:
Коммит
ea45e389c4
|
@ -0,0 +1,27 @@
|
|||
import { useEffect } from "react";
|
||||
|
||||
/**
|
||||
* Invokes the given callback when a message is received from the extension.
|
||||
*/
|
||||
export function useMessageFromExtension<T>(
|
||||
onEvent: (event: T) => void,
|
||||
onEventDependencies: unknown[],
|
||||
): void {
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
onEvent(evt.data as T);
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, onEventDependencies);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { useState, useEffect, useRef } from "react";
|
||||
import { useState, useRef } from "react";
|
||||
import { styled } from "styled-components";
|
||||
|
||||
import type {
|
||||
|
@ -16,6 +16,7 @@ import CompareTable from "./CompareTable";
|
|||
|
||||
import "../results/resultsView.css";
|
||||
import { assertNever } from "../../common/helpers-pure";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
|
||||
const Header = styled.div`
|
||||
display: flex;
|
||||
|
@ -50,115 +51,101 @@ export function Compare(_: Record<string, never>): React.JSX.Element {
|
|||
comparison?.result &&
|
||||
(comparison.result.to.length || comparison.result.from.length);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToCompareViewMessage = evt.data;
|
||||
switch (msg.t) {
|
||||
case "setComparisonQueryInfo":
|
||||
setQueryInfo(msg);
|
||||
break;
|
||||
case "setComparisons":
|
||||
setComparison(msg);
|
||||
break;
|
||||
case "streamingComparisonSetup":
|
||||
setComparison(null);
|
||||
streamingComparisonRef.current = msg;
|
||||
break;
|
||||
case "streamingComparisonAddResults": {
|
||||
const prev = streamingComparisonRef.current;
|
||||
if (prev === null) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonAddResults" before "streamingComparisonSetup"',
|
||||
useMessageFromExtension<ToCompareViewMessage>((msg) => {
|
||||
switch (msg.t) {
|
||||
case "setComparisonQueryInfo":
|
||||
setQueryInfo(msg);
|
||||
break;
|
||||
case "setComparisons":
|
||||
setComparison(msg);
|
||||
break;
|
||||
case "streamingComparisonSetup":
|
||||
setComparison(null);
|
||||
streamingComparisonRef.current = msg;
|
||||
break;
|
||||
case "streamingComparisonAddResults": {
|
||||
const prev = streamingComparisonRef.current;
|
||||
if (prev === null) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonAddResults" before "streamingComparisonSetup"',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev.id !== msg.id) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonAddResults" with different id, ignoring',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
let result: QueryCompareResult;
|
||||
switch (prev.result.kind) {
|
||||
case "raw":
|
||||
if (msg.result.kind !== "raw") {
|
||||
throw new Error(
|
||||
"Streaming comparison: expected raw results, got interpreted results",
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev.id !== msg.id) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonAddResults" with different id, ignoring',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
let result: QueryCompareResult;
|
||||
switch (prev.result.kind) {
|
||||
case "raw":
|
||||
if (msg.result.kind !== "raw") {
|
||||
throw new Error(
|
||||
"Streaming comparison: expected raw results, got interpreted results",
|
||||
);
|
||||
}
|
||||
|
||||
result = {
|
||||
...prev.result,
|
||||
from: [...prev.result.from, ...msg.result.from],
|
||||
to: [...prev.result.to, ...msg.result.to],
|
||||
};
|
||||
break;
|
||||
case "interpreted":
|
||||
if (msg.result.kind !== "interpreted") {
|
||||
throw new Error(
|
||||
"Streaming comparison: expected interpreted results, got raw results",
|
||||
);
|
||||
}
|
||||
|
||||
result = {
|
||||
...prev.result,
|
||||
from: [...prev.result.from, ...msg.result.from],
|
||||
to: [...prev.result.to, ...msg.result.to],
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unexpected comparison result kind");
|
||||
}
|
||||
|
||||
streamingComparisonRef.current = {
|
||||
...prev,
|
||||
result,
|
||||
result = {
|
||||
...prev.result,
|
||||
from: [...prev.result.from, ...msg.result.from],
|
||||
to: [...prev.result.to, ...msg.result.to],
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
case "streamingComparisonComplete":
|
||||
if (streamingComparisonRef.current === null) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonComplete" before "streamingComparisonSetup"',
|
||||
case "interpreted":
|
||||
if (msg.result.kind !== "interpreted") {
|
||||
throw new Error(
|
||||
"Streaming comparison: expected interpreted results, got raw results",
|
||||
);
|
||||
setComparison(null);
|
||||
break;
|
||||
}
|
||||
|
||||
if (streamingComparisonRef.current.id !== msg.id) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonComplete" with different id, ignoring',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
setComparison({
|
||||
...streamingComparisonRef.current,
|
||||
t: "setComparisons",
|
||||
});
|
||||
streamingComparisonRef.current = null;
|
||||
break;
|
||||
case "setUserSettings":
|
||||
setUserSettings(msg.userSettings);
|
||||
result = {
|
||||
...prev.result,
|
||||
from: [...prev.result.from, ...msg.result.from],
|
||||
to: [...prev.result.to, ...msg.result.to],
|
||||
};
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
throw new Error("Unexpected comparison result kind");
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
streamingComparisonRef.current = {
|
||||
...prev,
|
||||
result,
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
case "streamingComparisonComplete":
|
||||
if (streamingComparisonRef.current === null) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonComplete" before "streamingComparisonSetup"',
|
||||
);
|
||||
setComparison(null);
|
||||
break;
|
||||
}
|
||||
|
||||
if (streamingComparisonRef.current.id !== msg.id) {
|
||||
console.warn(
|
||||
'Received "streamingComparisonComplete" with different id, ignoring',
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
setComparison({
|
||||
...streamingComparisonRef.current,
|
||||
t: "setComparisons",
|
||||
});
|
||||
streamingComparisonRef.current = null;
|
||||
break;
|
||||
case "setUserSettings":
|
||||
setUserSettings(msg.userSettings);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!queryInfo || !comparison) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import type { ToDataFlowPathsMessage } from "../../common/interface-types";
|
||||
import type { DataFlowPaths as DataFlowPathsDomainModel } from "../../variant-analysis/shared/data-flow-paths";
|
||||
import { DataFlowPaths } from "./DataFlowPaths";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
|
||||
export type DataFlowPathsViewProps = {
|
||||
dataFlowPaths?: DataFlowPathsDomainModel;
|
||||
|
@ -14,28 +15,12 @@ export function DataFlowPathsView({
|
|||
DataFlowPathsDomainModel | undefined
|
||||
>(initialDataFlowPaths);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToDataFlowPathsMessage = evt.data;
|
||||
if (msg.t === "setDataFlowPaths") {
|
||||
setDataFlowPaths(msg.dataFlowPaths);
|
||||
useMessageFromExtension<ToDataFlowPathsMessage>((msg) => {
|
||||
setDataFlowPaths(msg.dataFlowPaths);
|
||||
|
||||
// Scroll to the top of the page when we're rendering
|
||||
// new data flow paths.
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
// Scroll to the top of the page when we're rendering
|
||||
// new data flow paths.
|
||||
window.scrollTo(0, 0);
|
||||
}, []);
|
||||
|
||||
if (!dataFlowPaths) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useMemo, useState } from "react";
|
||||
import { MethodModeling } from "./MethodModeling";
|
||||
import { getModelingStatus } from "../../model-editor/shared/modeling-status";
|
||||
import type { Method } from "../../model-editor/method";
|
||||
|
@ -12,6 +12,7 @@ import { NoMethodSelected } from "./NoMethodSelected";
|
|||
import type { MethodModelingPanelViewState } from "../../model-editor/shared/view-state";
|
||||
import { MethodAlreadyModeled } from "./MethodAlreadyModeled";
|
||||
import { defaultModelConfig } from "../../model-editor/languages";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
|
||||
type Props = {
|
||||
initialViewState?: MethodModelingPanelViewState;
|
||||
|
@ -36,47 +37,33 @@ export function MethodModelingView({
|
|||
[modeledMethods, isMethodModified],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToMethodModelingMessage = evt.data;
|
||||
switch (msg.t) {
|
||||
case "setMethodModelingPanelViewState":
|
||||
setViewState(msg.viewState);
|
||||
break;
|
||||
case "setInModelingMode":
|
||||
setInModelingMode(msg.inModelingMode);
|
||||
break;
|
||||
case "setMultipleModeledMethods":
|
||||
setModeledMethods(msg.modeledMethods);
|
||||
break;
|
||||
case "setMethodModified":
|
||||
setIsMethodModified(msg.isModified);
|
||||
break;
|
||||
case "setNoMethodSelected":
|
||||
setMethod(undefined);
|
||||
setModeledMethods([]);
|
||||
setIsMethodModified(false);
|
||||
break;
|
||||
case "setSelectedMethod":
|
||||
setMethod(msg.method);
|
||||
setModeledMethods(msg.modeledMethods);
|
||||
setIsMethodModified(msg.isModified);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
useMessageFromExtension<ToMethodModelingMessage>((msg) => {
|
||||
switch (msg.t) {
|
||||
case "setMethodModelingPanelViewState":
|
||||
setViewState(msg.viewState);
|
||||
break;
|
||||
case "setInModelingMode":
|
||||
setInModelingMode(msg.inModelingMode);
|
||||
break;
|
||||
case "setMultipleModeledMethods":
|
||||
setModeledMethods(msg.modeledMethods);
|
||||
break;
|
||||
case "setMethodModified":
|
||||
setIsMethodModified(msg.isModified);
|
||||
break;
|
||||
case "setNoMethodSelected":
|
||||
setMethod(undefined);
|
||||
setModeledMethods([]);
|
||||
setIsMethodModified(false);
|
||||
break;
|
||||
case "setSelectedMethod":
|
||||
setMethod(msg.method);
|
||||
setModeledMethods(msg.modeledMethods);
|
||||
setIsMethodModified(msg.isModified);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!inModelingMode || !viewState?.language) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { styled } from "styled-components";
|
||||
import { ModelAlertsHeader } from "./ModelAlertsHeader";
|
||||
import type { ModelAlertsViewState } from "../../model-editor/shared/view-state";
|
||||
|
@ -18,6 +18,7 @@ import {
|
|||
} from "../../model-editor/shared/model-alerts-filter-sort";
|
||||
import type { ModelAlertsFilterSortState } from "../../model-editor/shared/model-alerts-filter-sort";
|
||||
import type { ModeledMethod } from "../../model-editor/modeled-method";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
|
||||
type Props = {
|
||||
initialViewState?: ModelAlertsViewState;
|
||||
|
@ -67,47 +68,33 @@ export function ModelAlerts({
|
|||
null,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToModelAlertsMessage = evt.data;
|
||||
switch (msg.t) {
|
||||
case "setModelAlertsViewState": {
|
||||
setViewState(msg.viewState);
|
||||
break;
|
||||
}
|
||||
case "setVariantAnalysis": {
|
||||
setVariantAnalysis(msg.variantAnalysis);
|
||||
break;
|
||||
}
|
||||
case "setRepoResults": {
|
||||
setRepoResults((oldRepoResults) => {
|
||||
const newRepoIds = msg.repoResults.map((r) => r.repositoryId);
|
||||
return [
|
||||
...oldRepoResults.filter(
|
||||
(v) => !newRepoIds.includes(v.repositoryId),
|
||||
),
|
||||
...msg.repoResults,
|
||||
];
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "revealModel": {
|
||||
setRevealedModel(msg.modeledMethod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
useMessageFromExtension<ToModelAlertsMessage>((msg) => {
|
||||
switch (msg.t) {
|
||||
case "setModelAlertsViewState": {
|
||||
setViewState(msg.viewState);
|
||||
break;
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
case "setVariantAnalysis": {
|
||||
setVariantAnalysis(msg.variantAnalysis);
|
||||
break;
|
||||
}
|
||||
case "setRepoResults": {
|
||||
setRepoResults((oldRepoResults) => {
|
||||
const newRepoIds = msg.repoResults.map((r) => r.repositoryId);
|
||||
return [
|
||||
...oldRepoResults.filter(
|
||||
(v) => !newRepoIds.includes(v.repositoryId),
|
||||
),
|
||||
...msg.repoResults,
|
||||
];
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "revealModel": {
|
||||
setRevealedModel(msg.modeledMethod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
const modelAlerts = useMemo(() => {
|
||||
|
|
|
@ -21,6 +21,7 @@ import { INITIAL_HIDE_MODELED_METHODS_VALUE } from "../../model-editor/shared/hi
|
|||
import type { AccessPathSuggestionOptions } from "../../model-editor/suggestions";
|
||||
import type { ModelEvaluationRunState } from "../../model-editor/shared/model-evaluation-run-state";
|
||||
import { ModelEvaluation } from "./ModelEvaluation";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
|
||||
const LoadingContainer = styled.div`
|
||||
text-align: center;
|
||||
|
@ -129,47 +130,33 @@ export function ModelEditor({
|
|||
AccessPathSuggestionOptions | undefined
|
||||
>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToModelEditorMessage = evt.data;
|
||||
switch (msg.t) {
|
||||
case "setModelEditorViewState":
|
||||
setViewState(msg.viewState);
|
||||
break;
|
||||
case "setMethods":
|
||||
setMethods(msg.methods);
|
||||
break;
|
||||
case "setModeledAndModifiedMethods":
|
||||
setModeledMethods(msg.methods);
|
||||
setModifiedSignatures(new Set(msg.modifiedMethodSignatures));
|
||||
break;
|
||||
case "setModifiedMethods":
|
||||
setModifiedSignatures(new Set(msg.methodSignatures));
|
||||
break;
|
||||
case "revealMethod":
|
||||
setRevealedMethodSignature(msg.methodSignature);
|
||||
break;
|
||||
case "setAccessPathSuggestions":
|
||||
setAccessPathSuggestions(msg.accessPathSuggestions);
|
||||
break;
|
||||
case "setModelEvaluationRun":
|
||||
setEvaluationRun(msg.run);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
useMessageFromExtension<ToModelEditorMessage>((msg) => {
|
||||
switch (msg.t) {
|
||||
case "setModelEditorViewState":
|
||||
setViewState(msg.viewState);
|
||||
break;
|
||||
case "setMethods":
|
||||
setMethods(msg.methods);
|
||||
break;
|
||||
case "setModeledAndModifiedMethods":
|
||||
setModeledMethods(msg.methods);
|
||||
setModifiedSignatures(new Set(msg.modifiedMethodSignatures));
|
||||
break;
|
||||
case "setModifiedMethods":
|
||||
setModifiedSignatures(new Set(msg.methodSignatures));
|
||||
break;
|
||||
case "revealMethod":
|
||||
setRevealedMethodSignature(msg.methodSignature);
|
||||
break;
|
||||
case "setAccessPathSuggestions":
|
||||
setAccessPathSuggestions(msg.accessPathSuggestions);
|
||||
break;
|
||||
case "setModelEvaluationRun":
|
||||
setEvaluationRun(msg.run);
|
||||
break;
|
||||
default:
|
||||
assertNever(msg);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -16,11 +16,12 @@ import {
|
|||
DEFAULT_USER_SETTINGS,
|
||||
GRAPH_TABLE_NAME,
|
||||
} from "../../common/interface-types";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
import { ResultTables } from "./ResultTables";
|
||||
import { onNavigation } from "./navigation";
|
||||
|
||||
import "./resultsView.css";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
/**
|
||||
* ResultsApp.tsx
|
||||
|
@ -113,8 +114,8 @@ export function ResultsApp() {
|
|||
[],
|
||||
);
|
||||
|
||||
const handleMessage = useCallback(
|
||||
(msg: IntoResultsViewMsg): void => {
|
||||
useMessageFromExtension<IntoResultsViewMsg>(
|
||||
(msg) => {
|
||||
switch (msg.t) {
|
||||
case "setUserSettings":
|
||||
setUserSettings(msg.userSettings);
|
||||
|
@ -189,26 +190,6 @@ export function ResultsApp() {
|
|||
[updateStateWithNewResultsInfo],
|
||||
);
|
||||
|
||||
const vscodeMessageHandler = useCallback(
|
||||
(evt: MessageEvent) => {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
if (evt.origin === window.origin) {
|
||||
handleMessage(evt.data as IntoResultsViewMsg);
|
||||
} else {
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
},
|
||||
[handleMessage],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("message", vscodeMessageHandler);
|
||||
return () => {
|
||||
window.removeEventListener("message", vscodeMessageHandler);
|
||||
};
|
||||
}, [vscodeMessageHandler]);
|
||||
|
||||
const { displayedResults, nextResultsInfo, isExpectingResultsUpdate } = state;
|
||||
if (
|
||||
displayedResults.results !== null &&
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
import type {
|
||||
VariantAnalysis as VariantAnalysisDomainModel,
|
||||
|
@ -13,6 +13,7 @@ import type { ToVariantAnalysisMessage } from "../../common/interface-types";
|
|||
import { vscode } from "../vscode-api";
|
||||
import { defaultFilterSortState } from "../../variant-analysis/shared/variant-analysis-filter-sort";
|
||||
import { sendTelemetry, useTelemetryOnChange } from "../common/telemetry";
|
||||
import { useMessageFromExtension } from "../common/useMessageFromExtension";
|
||||
|
||||
export type VariantAnalysisProps = {
|
||||
variantAnalysis?: VariantAnalysisDomainModel;
|
||||
|
@ -77,49 +78,31 @@ export function VariantAnalysis({
|
|||
debounceTimeoutMillis: 1000,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (evt: MessageEvent) => {
|
||||
if (evt.origin === window.origin) {
|
||||
const msg: ToVariantAnalysisMessage = evt.data;
|
||||
if (msg.t === "setVariantAnalysis") {
|
||||
setVariantAnalysis(msg.variantAnalysis);
|
||||
vscode.setState({
|
||||
variantAnalysisId: msg.variantAnalysis.id,
|
||||
});
|
||||
} else if (msg.t === "setFilterSortState") {
|
||||
setFilterSortState(msg.filterSortState);
|
||||
} else if (msg.t === "setRepoResults") {
|
||||
setRepoResults((oldRepoResults) => {
|
||||
const newRepoIds = msg.repoResults.map((r) => r.repositoryId);
|
||||
return [
|
||||
...oldRepoResults.filter(
|
||||
(v) => !newRepoIds.includes(v.repositoryId),
|
||||
),
|
||||
...msg.repoResults,
|
||||
];
|
||||
});
|
||||
} else if (msg.t === "setRepoStates") {
|
||||
setRepoStates((oldRepoStates) => {
|
||||
const newRepoIds = msg.repoStates.map((r) => r.repositoryId);
|
||||
return [
|
||||
...oldRepoStates.filter(
|
||||
(v) => !newRepoIds.includes(v.repositoryId),
|
||||
),
|
||||
...msg.repoStates,
|
||||
];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// sanitize origin
|
||||
const origin = evt.origin.replace(/\n|\r/g, "");
|
||||
console.error(`Invalid event origin ${origin}`);
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("message", listener);
|
||||
};
|
||||
useMessageFromExtension<ToVariantAnalysisMessage>((msg) => {
|
||||
if (msg.t === "setVariantAnalysis") {
|
||||
setVariantAnalysis(msg.variantAnalysis);
|
||||
vscode.setState({
|
||||
variantAnalysisId: msg.variantAnalysis.id,
|
||||
});
|
||||
} else if (msg.t === "setFilterSortState") {
|
||||
setFilterSortState(msg.filterSortState);
|
||||
} else if (msg.t === "setRepoResults") {
|
||||
setRepoResults((oldRepoResults) => {
|
||||
const newRepoIds = msg.repoResults.map((r) => r.repositoryId);
|
||||
return [
|
||||
...oldRepoResults.filter((v) => !newRepoIds.includes(v.repositoryId)),
|
||||
...msg.repoResults,
|
||||
];
|
||||
});
|
||||
} else if (msg.t === "setRepoStates") {
|
||||
setRepoStates((oldRepoStates) => {
|
||||
const newRepoIds = msg.repoStates.map((r) => r.repositoryId);
|
||||
return [
|
||||
...oldRepoStates.filter((v) => !newRepoIds.includes(v.repositoryId)),
|
||||
...msg.repoStates,
|
||||
];
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const copyRepositoryList = useCallback(() => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче