diff --git a/package-lock.json b/package-lock.json index 6b636794cfd..a45dee80577 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4298,19 +4298,6 @@ "license": "MIT", "peer": true }, - "node_modules/@mismerge/core": { - "version": "1.2.1", - "resolved": "https://registry.npmmirror.com/@mismerge/core/-/core-1.2.1.tgz", - "integrity": "sha512-Nn2KYl1PPE8pX53+WSLa1y+kiTZ39rd9O6419XttTFWgz7yDyNKgZg5hU9IMALEjp9S4jq5ihILs+7oRjUKcrQ==", - "license": "MIT", - "dependencies": { - "diff": "^5.1.0", - "nanoid": "^5.0.1" - }, - "peerDependencies": { - "svelte": "^4.0.0" - } - }, "node_modules/@mjackson/node-fetch-server": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mjackson/node-fetch-server/-/node-fetch-server-0.2.0.tgz", @@ -12496,16 +12483,6 @@ "follow-redirects": "^1.14.0" } }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmmirror.com/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/babel-dead-code-elimination": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/babel-dead-code-elimination/-/babel-dead-code-elimination-1.0.10.tgz", @@ -13804,37 +13781,6 @@ "node": ">= 0.12.0" } }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/code-red/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT", - "peer": true - }, - "node_modules/code-red/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, "node_modules/codemirror": { "version": "5.65.19", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.19.tgz", @@ -14989,6 +14935,12 @@ "node": ">=0.3.1" } }, + "node_modules/diff-match-patch-ts": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/diff-match-patch-ts/-/diff-match-patch-ts-0.6.0.tgz", + "integrity": "sha512-U0uPIJ+wJqgaBoVw2MFSFpGIk7q3mJJ+/sehbxDZFv4Gx6a1GOmrsSLmxVDDrGtRL4Q9de084aa5lVpCHn+eUw==", + "license": "MIT" + }, "node_modules/diff3": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", @@ -21548,13 +21500,6 @@ "immediate": "~3.0.5" } }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "license": "MIT", - "peer": true - }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -22558,6 +22503,7 @@ "version": "5.1.5", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.5.tgz", "integrity": "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==", + "devOptional": true, "funding": [ { "type": "github", @@ -24801,45 +24747,6 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "license": "MIT" }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/periscopic/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT", - "peer": true - }, - "node_modules/periscopic/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/periscopic/node_modules/is-reference": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.6" - } - }, "node_modules/pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", @@ -28095,100 +28002,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svelte": { - "version": "4.2.20", - "resolved": "https://registry.npmmirror.com/svelte/-/svelte-4.2.20.tgz", - "integrity": "sha512-eeEgGc2DtiUil5ANdtd8vPwt9AgaMdnuUFnPft9F5oMvU/FHu5IHFic+p1dR/UOB7XU2mX2yHW+NcTch4DCh5Q==", - "license": "MIT", - "peer": true, - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/svelte/node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT", - "peer": true - }, - "node_modules/svelte/node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/svelte/node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "license": "MIT", - "peer": true, - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/svelte/node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/svelte/node_modules/is-reference": { - "version": "3.0.3", - "resolved": "https://registry.npmmirror.com/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "license": "MIT", - "peer": true, - "dependencies": { - "@types/estree": "^1.0.6" - } - }, - "node_modules/svelte/node_modules/magic-string": { - "version": "0.30.18", - "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.18.tgz", - "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", - "license": "MIT", - "peer": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/svelte/node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "license": "CC0-1.0", - "peer": true - }, "node_modules/swagger-parser": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-10.0.3.tgz", @@ -30477,7 +30290,6 @@ "@getinsomnia/srp-js": "1.0.0-alpha.1", "@grpc/grpc-js": "^1.13.3", "@grpc/proto-loader": "^0.7.13", - "@mismerge/core": "^1.2.1", "@react-router/fs-routes": "^7.9.4", "@react-router/node": "^7.9.4", "@react-router/serve": "^7.9.4", @@ -30511,6 +30323,7 @@ "date-fns": "^3.6.0", "decompress": "^4.2.1", "deep-equal": "^1.1.2", + "diff-match-patch-ts": "^0.6.0", "dompurify": "^3.2.5", "electron-context-menu": "^3.6.1", "electron-updater": "^6.6.2", diff --git a/packages/insomnia/package.json b/packages/insomnia/package.json index 22759082a0a..81d6d5c5a31 100644 --- a/packages/insomnia/package.json +++ b/packages/insomnia/package.json @@ -54,15 +54,14 @@ "@getinsomnia/srp-js": "1.0.0-alpha.1", "@grpc/grpc-js": "^1.13.3", "@grpc/proto-loader": "^0.7.13", - "@mismerge/core": "^1.2.1", "@react-router/fs-routes": "^7.9.4", "@react-router/node": "^7.9.4", "@react-router/serve": "^7.9.4", - "@seald-io/nedb": "^4.1.1", - "@segment/analytics-node": "2.2.1", "@rjsf/core": "^6.0.0-beta.15", "@rjsf/utils": "^6.0.0-beta.15", "@rjsf/validator-ajv8": "^6.0.0-beta.15", + "@seald-io/nedb": "^4.1.1", + "@segment/analytics-node": "2.2.1", "@sentry/electron": "^6.5.0", "@stoplight/spectral-core": "^1.20.0", "@stoplight/spectral-formats": "^1.8.2", @@ -88,6 +87,7 @@ "date-fns": "^3.6.0", "decompress": "^4.2.1", "deep-equal": "^1.1.2", + "diff-match-patch-ts": "^0.6.0", "dompurify": "^3.2.5", "electron-context-menu": "^3.6.1", "electron-updater": "^6.6.2", @@ -149,8 +149,8 @@ }, "devDependencies": { "@develohpanda/fluent-builder": "^2.1.2", - "@react-router/dev": "^7.9.4", "@modelcontextprotocol/sdk": "^1.17.5", + "@react-router/dev": "^7.9.4", "@testing-library/dom": "^10.4.1", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", diff --git a/packages/insomnia/src/ui/components/.client/codemirror/base-imports.ts b/packages/insomnia/src/ui/components/.client/codemirror/base-imports.ts index fab95e23cf0..174ccf08222 100644 --- a/packages/insomnia/src/ui/components/.client/codemirror/base-imports.ts +++ b/packages/insomnia/src/ui/components/.client/codemirror/base-imports.ts @@ -33,6 +33,7 @@ import 'codemirror/addon/selection/active-line'; import 'codemirror/addon/selection/selection-pointer'; import 'codemirror/addon/display/placeholder'; import 'codemirror/addon/lint/lint'; +import 'codemirror/addon/merge/merge.js'; // for the code that uses this yaml parser, see https://github.com/codemirror/CodeMirror/blob/master/addon/lint/yaml-lint.js import * as jsyaml from 'js-yaml'; diff --git a/packages/insomnia/src/ui/components/.client/codemirror/merge-editor.tsx b/packages/insomnia/src/ui/components/.client/codemirror/merge-editor.tsx new file mode 100644 index 00000000000..e298f3e2f2e --- /dev/null +++ b/packages/insomnia/src/ui/components/.client/codemirror/merge-editor.tsx @@ -0,0 +1,86 @@ +import './base-imports'; + +import classnames from 'classnames'; +import CodeMirror from 'codemirror'; +import type { MergeView } from 'codemirror/addon/merge/merge'; +import { DiffMatchPatch, DiffOp } from 'diff-match-patch-ts'; +import React, { useEffect, useRef } from 'react'; + +import { debounce } from '~/common/misc'; +import { useIsLightTheme } from '~/ui/hooks/theme'; + +// these global variables are required by codemirror merge addon +window.diff_match_patch = DiffMatchPatch; +window.DIFF_DELETE = DiffOp.Delete; +window.DIFF_INSERT = DiffOp.Insert; +window.DIFF_EQUAL = DiffOp.Equal; + +interface Props { + leftContent: string; + rightContent: string; + centerContent: string; + onChange: (value: string) => void; +} + +export const MergeEditor = ({ leftContent, rightContent, centerContent, onChange }: Props) => { + const divRef = useRef(null); + const mergeViewRef = useRef(null); + + const leftContentRef = useRef(leftContent); + const rightContentRef = useRef(rightContent); + const centerContentRef = useRef(centerContent); + const onChangeRef = useRef<(value: string) => void>(onChange); + + useEffect(() => { + leftContentRef.current = leftContent; + rightContentRef.current = rightContent; + centerContentRef.current = centerContent; + onChangeRef.current = onChange; + }, [leftContent, rightContent, centerContent, onChange]); + + const isLightTheme = useIsLightTheme(); + const isLightThemeRef = useRef(isLightTheme); + + useEffect(() => { + const onChange = debounce((instance: CodeMirror.Editor) => { + onChangeRef.current(instance.getDoc().getValue()); + }, 300); + if (!divRef.current) { + return; + } + const div = divRef.current; + mergeViewRef.current = CodeMirror.MergeView(div, { + value: centerContentRef.current, + origLeft: leftContentRef.current, + origRight: rightContentRef.current, + lineNumbers: true, + mode: 'yaml', + theme: isLightThemeRef.current ? 'default' : 'base16-dark', + }); + mergeViewRef.current.editor().on('changes', onChange); + return () => { + if (mergeViewRef.current) { + mergeViewRef.current.editor().off('changes', onChange); + } + mergeViewRef.current = null; + if (div) { + div.innerHTML = ''; + } + }; + }, []); + + useEffect(() => { + if (mergeViewRef.current?.editor().getDoc().getValue() !== centerContent) { + mergeViewRef.current?.editor().getDoc().setValue(centerContent); + } + }, [centerContent]); + + return ( +
+ ); +}; diff --git a/packages/insomnia/src/ui/components/modals/git-project-branches-modal.tsx b/packages/insomnia/src/ui/components/modals/git-project-branches-modal.tsx index 24b49507c0a..a12f2c82f25 100644 --- a/packages/insomnia/src/ui/components/modals/git-project-branches-modal.tsx +++ b/packages/insomnia/src/ui/components/modals/git-project-branches-modal.tsx @@ -166,7 +166,13 @@ const LocalBranchItem = ({ onCancelUnresolved: () => { // user aborted merge window.main.git.abortMerge(); - reject(new Error('You aborted the merge, no changes were made to working tree.')); + // TODO: the abortMerge method provided by isomorphic-git is unreliable + // clean up any partial merges here + reject( + new Error( + 'You aborted the merge, some changes may be present in your working tree and staging area, please clean them up manually in the commit panel.', + ), + ); }, }); }); diff --git a/packages/insomnia/src/ui/components/modals/sync-merge-modal.tsx b/packages/insomnia/src/ui/components/modals/sync-merge-modal.tsx index 2dc7e6e8513..e84898024de 100644 --- a/packages/insomnia/src/ui/components/modals/sync-merge-modal.tsx +++ b/packages/insomnia/src/ui/components/modals/sync-merge-modal.tsx @@ -1,8 +1,5 @@ -import { DefaultDarkColors, DefaultLightColors } from '@mismerge/core/colors'; -import darkCssHref from '@mismerge/core/dark.css?url'; -import lightCssHref from '@mismerge/core/light.css?url'; import classNames from 'classnames'; -import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; +import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { Button, Dialog, @@ -18,13 +15,12 @@ import { parse, stringify } from 'yaml'; import { extractErrorMessages } from '~/common/import'; import { InsomniaFileSchema } from '~/common/import-v5-parser'; -import { getColorScheme } from '~/plugins/misc'; -import { useRootLoaderData } from '~/root'; import { showModal } from '~/ui/components/modals'; import { AlertModal } from '~/ui/components/modals/alert-modal'; import { type MergeConflict, RESOLUTION_SOURCE } from '../../../sync/types'; import { SegmentEvent } from '../../analytics'; +import { MergeEditor } from '../.client/codemirror/merge-editor'; import { DiffEditor } from '../diff-view-editor'; import { Icon } from '../icon'; @@ -172,45 +168,6 @@ export const SyncMergeModal = forwardRef((_, ref) => { [conflicts, selectedConflictKey], ); - const rootLoaderData = useRootLoaderData(); - const isLightTheme = useMemo(() => { - let isLightTheme = false; - if (rootLoaderData?.settings) { - const colorScheme = getColorScheme(rootLoaderData.settings); - if (colorScheme === 'light') { - isLightTheme = true; - } else if (colorScheme === 'dark') { - isLightTheme = false; - } else { - // check if user has selected a light theme - isLightTheme = rootLoaderData.settings.theme.includes('light'); - } - } - return isLightTheme; - }, [rootLoaderData?.settings]); - - // Switch theme for mismerge - useEffect(() => { - const id = 'mismerge-theme-style'; - let link = document.getElementById(id) as HTMLLinkElement | null; - - if (!link) { - link = document.createElement('link'); - link.rel = 'stylesheet'; - link.id = id; - document.head.appendChild(link); - } - - const nextHref = isLightTheme ? lightCssHref : darkCssHref; - if (link.href !== nextHref) link.href = nextHref; - }, [isLightTheme]); - - const misMergeRef = useRef(null); - useEffect(() => { - // @ts-expect-error No definitions provided for web components - import('@mismerge/core/web'); - }, []); - return ( <> ((_, ref) => {
- {/* Use mis-merge3 custom element directly instead of importing @mismerge/react, - because @mismerge/react does not support React 19 */} - { - onMergeEditorResultChange(misMergeRef.current.ctr); - }} - colors={JSON.stringify(isLightTheme ? DefaultLightColors : DefaultDarkColors)} - wrapLines - disableWordsCounter +
diff --git a/packages/insomnia/src/ui/css/lib/codemirror/merge-dark.css b/packages/insomnia/src/ui/css/lib/codemirror/merge-dark.css new file mode 100644 index 00000000000..353d7d1428d --- /dev/null +++ b/packages/insomnia/src/ui/css/lib/codemirror/merge-dark.css @@ -0,0 +1,59 @@ +/* +Some extral elements are added by the merge addon of codemirror, +but the addon only provides a light theme, so we add a dark theme here. +*/ +.dark-merge-editor .CodeMirror-merge { + border: 1px solid #444; +} +.dark-merge-editor .CodeMirror-merge-gap { + border-left: 1px solid #333; + border-right: 1px solid #333; + background: #252526; +} +.dark-merge-editor .CodeMirror-merge-scrolllock { + color: #888; +} +.dark-merge-editor .CodeMirror-merge-copy, +.dark-merge-editor .CodeMirror-merge-copy-reverse { + color: #5cb6ff; +} +.dark-merge-editor .CodeMirror-merge-r-chunk { + background: rgba(255, 255, 0, 0.1); +} +.dark-merge-editor .CodeMirror-merge-r-chunk-start { + border-top: 1px solid #c9b458; +} +.dark-merge-editor .CodeMirror-merge-r-chunk-end { + border-bottom: 1px solid #c9b458; +} +.dark-merge-editor .CodeMirror-merge-r-connect { + fill: rgba(255, 255, 0, 0.1); + stroke: #c9b458; +} +.dark-merge-editor .CodeMirror-merge-l-chunk { + background: rgba(100, 149, 237, 0.15); +} +.dark-merge-editor .CodeMirror-merge-l-chunk-start { + border-top: 1px solid #6495ed; +} +.dark-merge-editor .CodeMirror-merge-l-chunk-end { + border-bottom: 1px solid #6495ed; +} +.dark-merge-editor .CodeMirror-merge-l-connect { + fill: rgba(100, 149, 237, 0.15); + stroke: #6495ed; +} +.dark-merge-editor .CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { + background: rgba(76, 175, 80, 0.15); +} +.dark-merge-editor .CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { + border-top: 1px solid #4caf50; +} +.dark-merge-editor .CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { + border-bottom: 1px solid #4caf50; +} +.dark-merge-editor .CodeMirror-merge-collapsed-widget { + color: #aab; + background: #2a2d2e; + border: 1px solid #3a3d3e; +} diff --git a/packages/insomnia/src/ui/css/main.css b/packages/insomnia/src/ui/css/main.css index 0954f4aa8c3..3f9e1edfb35 100644 --- a/packages/insomnia/src/ui/css/main.css +++ b/packages/insomnia/src/ui/css/main.css @@ -3466,7 +3466,3 @@ input.editable { .pane-two { z-index: 0; } - -.mismerge { - height: 100% !important; -} diff --git a/packages/insomnia/src/ui/css/styles.css b/packages/insomnia/src/ui/css/styles.css index 56fb07638d6..b3ed95c92a1 100644 --- a/packages/insomnia/src/ui/css/styles.css +++ b/packages/insomnia/src/ui/css/styles.css @@ -5,10 +5,14 @@ @import 'codemirror/addon/search/matchesonscrollbar.css'; @import 'codemirror/addon/lint/lint.css'; @import 'codemirror/lib/codemirror.css'; +/* used by merge-editor */ +@import 'codemirror/addon/merge/merge.css'; +@import 'codemirror/theme/base16-dark.css'; +@import './lib/codemirror/merge-dark.css'; + @import './lib/codemirror/codemirror.css'; @import './lib/codemirror/material.css'; @import 'monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css'; -@import '@mismerge/core/styles.css'; @import './main.css'; @tailwind base; @@ -186,3 +190,13 @@ table.json-diff-viewer { opacity: 0; } } + +.CodeMirror-merge { + height: 100%; +} +.CodeMirror-merge .CodeMirror-merge-pane { + height: 100%; +} +.CodeMirror-merge .CodeMirror { + height: 100%; +} diff --git a/packages/insomnia/src/ui/hooks/theme.ts b/packages/insomnia/src/ui/hooks/theme.ts index aeded22f3b8..5d86d416aa4 100644 --- a/packages/insomnia/src/ui/hooks/theme.ts +++ b/packages/insomnia/src/ui/hooks/theme.ts @@ -1,11 +1,11 @@ -import { useCallback, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import * as reactUse from 'react-use'; import { useRootLoaderData } from '~/root'; import type { ThemeSettings } from '../../models/settings'; import { type ColorScheme, getThemes } from '../../plugins'; -import { applyColorScheme, type PluginTheme } from '../../plugins/misc'; +import { applyColorScheme, getColorScheme, type PluginTheme } from '../../plugins/misc'; import { useSettingsPatcher } from './use-request'; export const useThemes = () => { @@ -88,3 +88,23 @@ export const useThemes = () => { autoDetectColorScheme, }; }; + +export const useIsLightTheme = () => { + const rootLoaderData = useRootLoaderData(); + const isLightTheme = useMemo(() => { + let isLightTheme = false; + if (rootLoaderData?.settings) { + const colorScheme = getColorScheme(rootLoaderData.settings); + if (colorScheme === 'light') { + isLightTheme = true; + } else if (colorScheme === 'dark') { + isLightTheme = false; + } else { + // check if user has selected a light theme + isLightTheme = rootLoaderData.settings.theme.includes('light'); + } + } + return isLightTheme; + }, [rootLoaderData?.settings]); + return isLightTheme; +}; diff --git a/packages/insomnia/types/global.d.ts b/packages/insomnia/types/global.d.ts index 7dd60fb975f..0a987f74946 100644 --- a/packages/insomnia/types/global.d.ts +++ b/packages/insomnia/types/global.d.ts @@ -1,6 +1,7 @@ /// import type { HiddenBrowserWindowToMainBridgeAPI } from '../src/hidden-window-preload'; import type { RendererToMainBridgeAPI } from '../src/main/ipc/main'; +import type { DiffMatchPatch, DiffOp } from 'diff-match-patch-ts'; declare global { interface Window { @@ -14,12 +15,12 @@ declare global { showAlert: (options?: Record) => void; showWrapper: (options?: Record) => void; showPrompt: (options?: Record) => void; - } - namespace JSX { - interface IntrinsicElements { - 'mis-merge2': React.DetailedHTMLProps<>; - 'mis-merge3': React.DetailedHTMLProps<>; - } + + // Required by codemirror merge addon + diff_match_patch: typeof DiffMatchPatch; + DIFF_DELETE: DiffOp; + DIFF_INSERT: DiffOp; + DIFF_EQUAL: DiffOp; } }