mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-22 16:48:30 +02:00
Change curl import to post-toast
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import React, { memo, useCallback, useMemo, useState } from 'react';
|
||||||
import { createGlobalState } from 'react-use';
|
import { createGlobalState } from 'react-use';
|
||||||
import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse';
|
import { useCancelHttpResponse } from '../hooks/useCancelHttpResponse';
|
||||||
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
||||||
@@ -39,7 +39,8 @@ import { HeadersEditor } from './HeadersEditor';
|
|||||||
import { UrlBar } from './UrlBar';
|
import { UrlBar } from './UrlBar';
|
||||||
import { UrlParametersEditor } from './UrlParameterEditor';
|
import { UrlParametersEditor } from './UrlParameterEditor';
|
||||||
import { useCurlToRequest } from '../hooks/useCurlToRequest';
|
import { useCurlToRequest } from '../hooks/useCurlToRequest';
|
||||||
import { useConfirm } from '../hooks/useConfirm';
|
import { useToast } from './ToastContext';
|
||||||
|
import { Icon } from './core/Icon';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
style: CSSProperties;
|
style: CSSProperties;
|
||||||
@@ -230,7 +231,7 @@ export const RequestPane = memo(function RequestPane({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const importCurl = useCurlToRequest();
|
const importCurl = useCurlToRequest();
|
||||||
const confirm = useConfirm();
|
const toast = useToast();
|
||||||
|
|
||||||
const isLoading = useIsResponseLoading(activeRequestId ?? null);
|
const isLoading = useIsResponseLoading(activeRequestId ?? null);
|
||||||
const { updateKey } = useRequestUpdateKey(activeRequestId ?? null);
|
const { updateKey } = useRequestUpdateKey(activeRequestId ?? null);
|
||||||
@@ -250,15 +251,15 @@ export const RequestPane = memo(function RequestPane({
|
|||||||
if (!command.startsWith('curl ')) {
|
if (!command.startsWith('curl ')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const confirmed = await confirm({
|
importCurl.mutate({ requestId: activeRequestId, command });
|
||||||
id: 'paste-curl',
|
toast.show({
|
||||||
title: 'Import from Curl?',
|
render: () => [
|
||||||
description: 'Do you want to overwrite the current request with the Curl command?',
|
<>
|
||||||
confirmText: 'Overwrite',
|
<Icon icon="info" />
|
||||||
|
<span>Curl command imported</span>
|
||||||
|
</>,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
if (confirmed) {
|
|
||||||
importCurl.mutate({ requestId: activeRequestId, command });
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
onSend={handleSend}
|
onSend={handleSend}
|
||||||
onCancel={handleCancel}
|
onCancel={handleCancel}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {
|
|||||||
MouseEvent as ReactMouseEvent,
|
MouseEvent as ReactMouseEvent,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useWindowSize } from 'react-use';
|
import { useWindowSize } from 'react-use';
|
||||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||||
@@ -34,7 +34,7 @@ import { Sidebar } from './Sidebar';
|
|||||||
import { SidebarActions } from './SidebarActions';
|
import { SidebarActions } from './SidebarActions';
|
||||||
import { WorkspaceHeader } from './WorkspaceHeader';
|
import { WorkspaceHeader } from './WorkspaceHeader';
|
||||||
import { useClipboardText } from '../hooks/useClipboardText';
|
import { useClipboardText } from '../hooks/useClipboardText';
|
||||||
import { Portal } from './Portal';
|
import { useToast } from './ToastContext';
|
||||||
|
|
||||||
const side = { gridArea: 'side' };
|
const side = { gridArea: 'side' };
|
||||||
const head = { gridArea: 'head' };
|
const head = { gridArea: 'head' };
|
||||||
@@ -56,7 +56,24 @@ export default function Workspace() {
|
|||||||
const moveState = useRef<{ move: (e: MouseEvent) => void; up: (e: MouseEvent) => void } | null>(
|
const moveState = useRef<{ move: (e: MouseEvent) => void; up: (e: MouseEvent) => void } | null>(
|
||||||
null,
|
null,
|
||||||
);
|
);
|
||||||
const isCurlInClipboard = !!useClipboardText()?.startsWith('curl ');
|
const clipboardText = useClipboardText();
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const isCurlInClipboard = clipboardText?.startsWith('curl ');
|
||||||
|
if (!isCurlInClipboard) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.show({
|
||||||
|
render: () => (
|
||||||
|
<div>
|
||||||
|
<p>Curl command detected?</p>
|
||||||
|
<Button color="primary">Import</Button>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}, [clipboardText, toast]);
|
||||||
|
|
||||||
const unsub = () => {
|
const unsub = () => {
|
||||||
if (moveState.current !== null) {
|
if (moveState.current !== null) {
|
||||||
@@ -127,88 +144,83 @@ export default function Workspace() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div
|
||||||
<Portal name="toast">
|
style={styles}
|
||||||
{isCurlInClipboard && <div className="static right-0 left-0 w-32 h-10">Import</div>}
|
className={classNames(
|
||||||
</Portal>
|
'grid w-full h-full',
|
||||||
<div
|
// Animate sidebar width changes but only when not resizing
|
||||||
style={styles}
|
// because it's too slow to animate on mouse move
|
||||||
className={classNames(
|
!isResizing && 'transition-all',
|
||||||
'grid w-full h-full',
|
)}
|
||||||
// Animate sidebar width changes but only when not resizing
|
>
|
||||||
// because it's too slow to animate on mouse move
|
{floating ? (
|
||||||
!isResizing && 'transition-all',
|
<Overlay
|
||||||
)}
|
open={!floatingSidebarHidden}
|
||||||
>
|
portalName="sidebar"
|
||||||
{floating ? (
|
onClose={() => setFloatingSidebarHidden(true)}
|
||||||
<Overlay
|
>
|
||||||
open={!floatingSidebarHidden}
|
<motion.div
|
||||||
portalName="sidebar"
|
initial={{ opacity: 0, x: -20 }}
|
||||||
onClose={() => setFloatingSidebarHidden(true)}
|
animate={{ opacity: 1, x: 0 }}
|
||||||
|
className={classNames(
|
||||||
|
'absolute top-0 left-0 bottom-0 bg-gray-100 border-r border-highlight w-[14rem]',
|
||||||
|
'grid grid-rows-[auto_1fr]',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<motion.div
|
<HeaderSize className="border-transparent">
|
||||||
initial={{ opacity: 0, x: -20 }}
|
<SidebarActions />
|
||||||
animate={{ opacity: 1, x: 0 }}
|
</HeaderSize>
|
||||||
className={classNames(
|
<Sidebar />
|
||||||
'absolute top-0 left-0 bottom-0 bg-gray-100 border-r border-highlight w-[14rem]',
|
</motion.div>
|
||||||
'grid grid-rows-[auto_1fr]',
|
</Overlay>
|
||||||
)}
|
) : (
|
||||||
>
|
<>
|
||||||
<HeaderSize className="border-transparent">
|
<div style={side} className={classNames('overflow-hidden bg-gray-100')}>
|
||||||
<SidebarActions />
|
<Sidebar className="border-r border-highlight" />
|
||||||
</HeaderSize>
|
|
||||||
<Sidebar />
|
|
||||||
</motion.div>
|
|
||||||
</Overlay>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div style={side} className={classNames('overflow-hidden bg-gray-100')}>
|
|
||||||
<Sidebar className="border-r border-highlight" />
|
|
||||||
</div>
|
|
||||||
<ResizeHandle
|
|
||||||
className="-translate-x-3"
|
|
||||||
justify="end"
|
|
||||||
side="right"
|
|
||||||
isResizing={isResizing}
|
|
||||||
onResizeStart={handleResizeStart}
|
|
||||||
onReset={resetWidth}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<HeaderSize data-tauri-drag-region style={head}>
|
|
||||||
<WorkspaceHeader className="pointer-events-none" />
|
|
||||||
</HeaderSize>
|
|
||||||
{activeWorkspace == null ? (
|
|
||||||
<div className="m-auto">
|
|
||||||
<Banner color="warning" className="max-w-[30rem]">
|
|
||||||
The active workspace{' '}
|
|
||||||
<InlineCode className="text-orange-800">{activeWorkspaceId}</InlineCode> was not
|
|
||||||
found. Select a workspace from the header menu or report this bug to <FeedbackLink />
|
|
||||||
</Banner>
|
|
||||||
</div>
|
</div>
|
||||||
) : activeRequest == null ? (
|
<ResizeHandle
|
||||||
<HotKeyList
|
className="-translate-x-3"
|
||||||
hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']}
|
justify="end"
|
||||||
bottomSlot={
|
side="right"
|
||||||
<HStack space={1} justifyContent="center" className="mt-3">
|
isResizing={isResizing}
|
||||||
<Button variant="border" size="sm" onClick={() => importData.mutate()}>
|
onResizeStart={handleResizeStart}
|
||||||
Import
|
onReset={resetWidth}
|
||||||
</Button>
|
|
||||||
<CreateDropdown hideFolder>
|
|
||||||
<Button variant="border" forDropdown size="sm">
|
|
||||||
New Request
|
|
||||||
</Button>
|
|
||||||
</CreateDropdown>
|
|
||||||
</HStack>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
) : activeRequest.model === 'grpc_request' ? (
|
</>
|
||||||
<GrpcConnectionLayout style={body} />
|
)}
|
||||||
) : (
|
<HeaderSize data-tauri-drag-region style={head}>
|
||||||
<HttpRequestLayout activeRequest={activeRequest} style={body} />
|
<WorkspaceHeader className="pointer-events-none" />
|
||||||
)}
|
</HeaderSize>
|
||||||
</div>
|
{activeWorkspace == null ? (
|
||||||
</>
|
<div className="m-auto">
|
||||||
|
<Banner color="warning" className="max-w-[30rem]">
|
||||||
|
The active workspace{' '}
|
||||||
|
<InlineCode className="text-orange-800">{activeWorkspaceId}</InlineCode> was not found.
|
||||||
|
Select a workspace from the header menu or report this bug to <FeedbackLink />
|
||||||
|
</Banner>
|
||||||
|
</div>
|
||||||
|
) : activeRequest == null ? (
|
||||||
|
<HotKeyList
|
||||||
|
hotkeys={['http_request.create', 'sidebar.toggle', 'settings.show']}
|
||||||
|
bottomSlot={
|
||||||
|
<HStack space={1} justifyContent="center" className="mt-3">
|
||||||
|
<Button variant="border" size="sm" onClick={() => importData.mutate()}>
|
||||||
|
Import
|
||||||
|
</Button>
|
||||||
|
<CreateDropdown hideFolder>
|
||||||
|
<Button variant="border" forDropdown size="sm">
|
||||||
|
New Request
|
||||||
|
</Button>
|
||||||
|
</CreateDropdown>
|
||||||
|
</HStack>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
) : activeRequest.model === 'grpc_request' ? (
|
||||||
|
<GrpcConnectionLayout style={body} />
|
||||||
|
) : (
|
||||||
|
<HttpRequestLayout activeRequest={activeRequest} style={body} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ import { readText } from '@tauri-apps/plugin-clipboard-manager';
|
|||||||
export function useClipboardText() {
|
export function useClipboardText() {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: [],
|
queryKey: [],
|
||||||
queryFn: async () => {
|
queryFn: () => readText(),
|
||||||
const text = await readText();
|
|
||||||
console.log('READ CLIPBOARD', text);
|
|
||||||
return text;
|
|
||||||
},
|
|
||||||
}).data;
|
}).data;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user